2023-07-30 19:18:50 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
2023-10-07 17:34:09 +00:00
|
|
|
// semantic versioning in a single byte (octal)
|
2023-07-30 19:18:50 +00:00
|
|
|
// - rlyeh, public domain.
|
|
|
|
//
|
2023-10-07 17:34:09 +00:00
|
|
|
// - single octal byte that represents semantic versioning (major.minor.patch).
|
|
|
|
// - allowed range [0000..0377] ( <-> [0..255] decimal )
|
|
|
|
// - comparison checks only major.minor tuple as per convention.
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
API int semver( int major, int minor, int patch );
|
|
|
|
API int semvercmp( int v1, int v2 );
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
#define SEMVER(major,minor,patch) (0100 * (major) + 010 * (minor) + (patch))
|
|
|
|
#define SEMVERCMP(v1,v2) (((v1) & 0110) - ((v2) & 0110))
|
|
|
|
#define SEMVERFMT "%03o"
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// autorun initializers for C
|
|
|
|
// - rlyeh, public domain
|
|
|
|
//
|
|
|
|
// note: based on code by Joe Lowe (public domain).
|
|
|
|
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#define AUTORUN \
|
|
|
|
static void AUTORUN_U(f)(void); \
|
|
|
|
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
|
|
|
static void AUTORUN_U(f)(void)
|
|
|
|
#elif _MSC_VER
|
|
|
|
#define AUTORUN \
|
|
|
|
static void AUTORUN_U(f)(void); \
|
|
|
|
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
|
|
|
__pragma(section(".CRT$XIU", long, read)) \
|
|
|
|
__declspec(allocate(".CRT$XIU")) \
|
|
|
|
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
|
|
|
static void AUTORUN_U(f)(void)
|
|
|
|
#else
|
|
|
|
#define AUTORUN \
|
|
|
|
__attribute__((constructor)) \
|
|
|
|
static void AUTORUN_U(f)(void)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// join + unique macro utils
|
|
|
|
|
|
|
|
#define AUTORUN_j(a, b) a##b
|
|
|
|
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
|
|
|
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
|
|
|
|
|
|
|
#if 0 // autorun demo
|
|
|
|
void byebye(void) { puts("seen after main()"); }
|
|
|
|
AUTORUN { puts("seen before main()"); }
|
|
|
|
AUTORUN { puts("seen before main() too"); atexit( byebye ); }
|
|
|
|
#endif
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// storage types. refer to vec2i/3i, vec2/3/4 if you plan to do math operations
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
typedef struct byte2 { uint8_t x,y; } byte2;
|
|
|
|
typedef struct byte3 { uint8_t x,y,z; } byte3;
|
|
|
|
typedef struct byte4 { uint8_t x,y,z,w; } byte4;
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
typedef struct int2 { int x,y; } int2;
|
|
|
|
typedef struct int3 { int x,y,z; } int3;
|
|
|
|
typedef struct int4 { int x,y,z,w; } int4;
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
typedef struct uint2 { unsigned int x,y; } uint2;
|
|
|
|
typedef struct uint3 { unsigned int x,y,z; } uint3;
|
|
|
|
typedef struct uint4 { unsigned int x,y,z,w; } uint4;
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
typedef struct float2 { float x,y; } float2;
|
|
|
|
typedef struct float3 { float x,y,z; } float3;
|
|
|
|
typedef struct float4 { float x,y,z,w; } float4;
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
typedef struct double2 { double x,y; } double2;
|
|
|
|
typedef struct double3 { double x,y,z; } double3;
|
|
|
|
typedef struct double4 { double x,y,z,w; } double4;
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
#define byte2(x,y) M_CAST(byte2, (uint8_t)(x), (uint8_t)(y) )
|
|
|
|
#define byte3(x,y,z) M_CAST(byte3, (uint8_t)(x), (uint8_t)(y), (uint8_t)(z) )
|
|
|
|
#define byte4(x,y,z,w) M_CAST(byte4, (uint8_t)(x), (uint8_t)(y), (uint8_t)(z), (uint8_t)(w) )
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
#define int2(x,y) M_CAST(int2, (int)(x), (int)(y) )
|
|
|
|
#define int3(x,y,z) M_CAST(int3, (int)(x), (int)(y), (int)(z) )
|
|
|
|
#define int4(x,y,z,w) M_CAST(int4, (int)(x), (int)(y), (int)(z), (int)(w) )
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
#define uint2(x,y) M_CAST(uint2, (unsigned)(x), (unsigned)(y) )
|
|
|
|
#define uint3(x,y,z) M_CAST(uint3, (unsigned)(x), (unsigned)(y), (unsigned)(z) )
|
|
|
|
#define uint4(x,y,z,w) M_CAST(uint4, (unsigned)(x), (unsigned)(y), (unsigned)(z), (unsigned)(w) )
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
#define float2(x,y) M_CAST(float2, (float)(x), (float)(y) )
|
|
|
|
#define float3(x,y,z) M_CAST(float3, (float)(x), (float)(y), (float)(z) )
|
|
|
|
#define float4(x,y,z,w) M_CAST(float4, (float)(x), (float)(y), (float)(z), (float)(w) )
|
2023-07-30 19:18:50 +00:00
|
|
|
|
2023-10-07 17:34:09 +00:00
|
|
|
#define double2(x,y) M_CAST(double2, (double)(x), (double)(y) )
|
|
|
|
#define double3(x,y,z) M_CAST(double3, (double)(x), (double)(y), (double)(z) )
|
|
|
|
#define double4(x,y,z,w) M_CAST(double4, (double)(x), (double)(y), (double)(z), (double)(w) )
|