medfall

A super great game engine
Log | Files | Refs

intrinsics.h (6114B)


      1 #pragma once
      2 
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <stdint.h>
      6 #include <string.h>
      7 
      8 #include "platform.h"
      9 #include "platform_backtrace.h"
     10 
     11 typedef int8_t s8;
     12 typedef int16_t s16;
     13 typedef int32_t s32;
     14 typedef int64_t s64;
     15 
     16 typedef uint8_t u8;
     17 typedef uint16_t u16;
     18 typedef uint32_t u32;
     19 typedef uint64_t u64;
     20 
     21 typedef intptr_t sptr;
     22 typedef uintptr_t uptr;
     23 
     24 #define S8_MAX s8( INT8_MAX )
     25 #define S16_MAX s16( INT16_MAX )
     26 #define S32_MAX s32( INT32_MAX )
     27 #define S64_MAX s64( INT64_MAX )
     28 #define S8_MIN s8( INT8_MIN )
     29 #define S16_MIN s16( INT16_MIN )
     30 #define S32_MIN s32( INT32_MIN )
     31 #define S64_MIN s64( INT64_MIN )
     32 
     33 #define U8_MAX u8( UINT8_MAX )
     34 #define U16_MAX u16( UINT16_MAX )
     35 #define U32_MAX u32( UINT32_MAX )
     36 #define U64_MAX u64( UINT64_MAX )
     37 
     38 #define S8 INT8_C
     39 #define S16 INT16_C
     40 #define S32 INT32_C
     41 #define S64 INT64_C
     42 #define U8 UINT8_C
     43 #define U16 UINT16_C
     44 #define U32 UINT32_C
     45 #define U64 UINT64_C
     46 
     47 #define PI 3.14159265359f
     48 #define TAU 6.28318530717958647692f
     49 
     50 #define STRINGIFY_HELPER( x ) #x
     51 #define STRINGIFY( x ) STRINGIFY_HELPER( x )
     52 
     53 #define CONCAT_HELPER( a, b ) a##b
     54 #define CONCAT( a, b ) CONCAT_HELPER( a, b )
     55 #define COUNTER_NAME( x ) CONCAT( x, __COUNTER__ )
     56 #define LINE_NAME( x ) CONCAT( x, __LINE__ )
     57 
     58 inline void assert_impl( const bool predicate, const char * message ) {
     59 	if( !predicate ) {
     60 		puts( message );
     61 		print_backtrace_and_abort();
     62 	}
     63 }
     64 
     65 #define ASSERT( predicate ) assert_impl( predicate, "\x1b[1;31massertion failed at " __FILE__ " line " STRINGIFY( __LINE__ ) ": \x1b[0;1m" #predicate "\x1b[0m" )
     66 
     67 #define STATIC_ASSERT( p ) static_assert( p, #p )
     68 
     69 template< typename T, size_t N >
     70 char ( &ArrayCountObj( const T ( & )[ N ] ) )[ N ];
     71 #define ARRAY_COUNT( arr ) ( sizeof( ArrayCountObj( arr ) ) )
     72 
     73 #define is_power_of_2( n ) ( ( ( n ) & ( ( n ) - 1 ) ) == 0 )
     74 
     75 #define align_power_of_2( n, alignment ) ( ( ( n ) + ( alignment ) - 1 ) & ~( ( alignment ) - 1 ) )
     76 #define align2( n ) align_power_of_2( n, 2 )
     77 #define align4( n ) align_power_of_2( n, 4 )
     78 #define align8( n ) align_power_of_2( n, 8 )
     79 #define align16( n ) align_power_of_2( n, 16 )
     80 #define align_arbitrary( n, alignment ) ( ( ( n ) + ( alignment ) - 1 ) / ( alignment ) * ( alignment ) )
     81 
     82 #define kilobytes( kb ) ( size_t( kb ) * size_t( 1024 ) )
     83 #define megabytes( mb ) ( kilobytes( mb ) * size_t( 1024 ) )
     84 #define gigabytes( gb ) ( megabytes( gb ) * size_t( 1024 ) )
     85 
     86 template< typename T >
     87 void swap2( T & a, T & b ) {
     88 	T t = a;
     89 	a = b;
     90 	b = t;
     91 }
     92 
     93 template< typename T >
     94 constexpr T min( T a, T b ) {
     95 	return a < b ? a : b;
     96 }
     97 
     98 template< typename T >
     99 constexpr T min( T a, T b, T c ) {
    100 	return min( min( a, b ), c );
    101 }
    102 
    103 template< typename T >
    104 constexpr T min( T a, T b, T c, T d ) {
    105 	return min( min( min( a, b ), c ), d );
    106 }
    107 
    108 template< typename T >
    109 constexpr T max( T a, T b ) {
    110 	return a > b ? a : b;
    111 }
    112 
    113 template< typename T >
    114 constexpr T max( T a, T b, T c ) {
    115 	return max( max( a, b ), c );
    116 }
    117 
    118 template< typename T >
    119 constexpr T max( T a, T b, T c, T d ) {
    120 	return max( max( max( a, b ), c ), d );
    121 }
    122 
    123 template< typename T >
    124 constexpr T abs( T x ) {
    125 	return x > 0 ? x : -x;
    126 }
    127 
    128 template< typename T >
    129 constexpr T clamp( T x, T lo, T hi ) {
    130 	return x < lo ? lo : ( x > hi ? hi : x );
    131 }
    132 
    133 template< typename T >
    134 constexpr T saturate( T x ) {
    135 	return clamp( x, T( 0 ), T( 1 ) );
    136 }
    137 
    138 template< typename T >
    139 constexpr T clamp11( T x ) {
    140 	return clamp( x, T( -1 ), T( 1 ) );
    141 }
    142 
    143 #define slots_required( data_size, slot_size ) ( ( data_size ) / ( slot_size ) + ( ( data_size ) % ( slot_size ) != 0 ) )
    144 
    145 #define AT_STARTUP( code ) \
    146 	namespace COUNTER_NAME( StartupCode ) { \
    147 		static struct AtStartup { \
    148 			AtStartup() { code; } \
    149 		} AtStartupInstance; \
    150 	}
    151 
    152 #if !PLATFORM_RELACY
    153 #define NONCOPYABLE( T ) T( const T & ) = delete; void operator=( const T & ) = delete;
    154 #else
    155 #define NONCOPYABLE( T )
    156 #endif
    157 
    158 template< typename F >
    159 struct ScopeExit {
    160 	ScopeExit( F f_ ) : f( f_ ) { }
    161 	~ScopeExit() { f(); }
    162 	F f;
    163 };
    164 
    165 struct DeferHelper {
    166 	template< typename F >
    167 	ScopeExit< F > operator+( F f ) { return f; }
    168 };
    169 
    170 #define defer const auto & COUNTER_NAME( DEFER_ ) = DeferHelper() + [&]()
    171 
    172 template< typename S, typename T >
    173 struct SameType {
    174 	enum { value = false };
    175 };
    176 template< typename T >
    177 struct SameType< T, T > {
    178 	enum { value = true };
    179 };
    180 
    181 #define SAME_TYPE( S, T ) SameType< S, T >::value
    182 
    183 template< typename To, typename From >
    184 inline To checked_cast( const From & from ) {
    185 	To result = To( from );
    186 	ASSERT( From( result ) == from );
    187 	return result;
    188 }
    189 
    190 // TODO: this sucks
    191 inline u8 * file_get_contents( const char * path, size_t * out_len = NULL ) {
    192 	FILE * file = fopen( path, "rb" );
    193 	ASSERT( file != NULL );
    194 
    195 	fseek( file, 0, SEEK_END );
    196 	size_t len = checked_cast< size_t >( ftell( file ) );
    197 	ASSERT( len < SIZE_MAX );
    198 	fseek( file, 0, SEEK_SET );
    199 
    200 	u8 * contents = ( u8 * ) malloc( len + 1 );
    201 	size_t bytes_read = fread( contents, 1, len, file );
    202 	contents[ len ] = '\0';
    203 	ASSERT( bytes_read == len );
    204 
    205 	if( out_len ) *out_len = len;
    206 
    207 	fclose( file );
    208 
    209 	return contents;
    210 }
    211 
    212 #define DEF_VISIT( T ) \
    213 	template< typename F > inline void visit( T & x, F f ) { f( x ); } \
    214 	template< typename F > inline void visit( const T & x, F f ) { f( x ); }
    215 
    216 DEF_VISIT( u8 )
    217 DEF_VISIT( u16 )
    218 DEF_VISIT( u32 )
    219 DEF_VISIT( u64 )
    220 DEF_VISIT( s8 )
    221 DEF_VISIT( s16 )
    222 DEF_VISIT( s32 )
    223 DEF_VISIT( s64 )
    224 DEF_VISIT( float )
    225 DEF_VISIT( double )
    226 
    227 #undef DEF_VISIT
    228 
    229 template< typename T >
    230 inline T * malloc_array( size_t count ) {
    231 	ASSERT( SIZE_MAX / count >= sizeof( T ) );
    232 	return ( T * ) malloc( count * sizeof( T ) );
    233 }
    234 
    235 template< typename T >
    236 inline T * realloc_array( T * old, size_t count ) {
    237 	ASSERT( SIZE_MAX / count >= sizeof( T ) );
    238 	return ( T * ) realloc( old, count * sizeof( T ) );
    239 }
    240 
    241 template< typename T >
    242 static T lerp( T a, float t, T b ) {
    243 	ASSERT( t >= 0.0f && t <= 1.0f );
    244 	return a * ( 1.0f - t ) + b * t;
    245 }
    246 
    247 template< typename T >
    248 static T unlerp( T lo, T x, T hi ) {
    249 	return ( x - lo ) / ( hi - lo );
    250 }
    251 
    252 /*
    253  * these are meant to be used for breaking deep in leaf code on keypresses etc
    254  * defined in breakbools.cc
    255  */
    256 extern bool break1;
    257 extern bool break2;
    258 extern bool break3;
    259 extern bool break4;