v4k-git-backup/engine/split/v4k_config.h

406 lines
14 KiB
C
Raw Normal View History

// -----------------------------------------------------------------------------
// config directives
#ifndef ENABLE_FASTCALL_LUA
#define ENABLE_FASTCALL_LUA 1 ///+
#endif
#ifndef ENABLE_PROFILER
#define ENABLE_PROFILER ifdef(debug, 1, 0) ///+
#endif
#ifndef ENABLE_SELFIES
#define ENABLE_SELFIES 0 ///+
#endif
#ifndef ENABLE_MEMORY_POISON
#define ENABLE_MEMORY_POISON ifdef(debug, 1, 0) ///+
#endif
#ifndef ENABLE_MEMORY_LEAKS
#define ENABLE_MEMORY_LEAKS 0 ///+
#endif
#ifndef ENABLE_LINUX_CALLSTACKS
#define ENABLE_LINUX_CALLSTACKS 0 ///+
#endif
2023-10-14 19:47:24 +00:00
#ifndef ENABLE_AUTOTESTS
2023-10-14 20:20:34 +00:00
#define ENABLE_AUTOTESTS ifdef(debug, ifndef(ems, 1, 0), 0) ///+
2023-10-11 19:01:06 +00:00
#endif
2023-10-13 12:07:53 +00:00
#ifndef ENABLE_RETAIL
2023-10-13 16:20:20 +00:00
#define ENABLE_RETAIL 0 // ifdef(retail, 1, 0) ///+
#endif
#ifndef COOK_DISABLED
#define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+
2023-10-13 12:07:53 +00:00
#endif
// -----------------------------------------------------------------------------
// if/n/def hell
#define ifdef(macro, yes, /*no*/...) ifdef_##macro(yes, __VA_ARGS__)
#define ifndef(macro, yes, /*no*/...) ifdef_##macro(__VA_ARGS__, yes)
#define is(macro) ifdef_##macro(1,0)
#define isnt(macro) ifdef_##macro(0,1)
#define ifdef_true(yes, /*no*/...) yes
#define ifdef_false(yes, /*no*/...) __VA_ARGS__
#ifdef _MSC_VER
#define ifdef_gcc ifdef_false
#define ifdef_mingw ifdef_false
#define ifdef_tcc ifdef_false
#define ifdef_cl ifdef_true
#elif defined __TINYC__
#define ifdef_gcc ifdef_false
#define ifdef_mingw ifdef_false
#define ifdef_tcc ifdef_true
#define ifdef_cl ifdef_false
#elif defined __MINGW64__ || defined __MINGW32__
#define ifdef_gcc ifdef_true
#define ifdef_mingw ifdef_true
#define ifdef_tcc ifdef_false
#define ifdef_cl ifdef_false
#else // also __clang__
#define ifdef_gcc ifdef_true
#define ifdef_mingw ifdef_false
#define ifdef_tcc ifdef_false
#define ifdef_cl ifdef_false
#endif
#ifdef __cplusplus
#define ifdef_cpp ifdef_true
#define ifdef_c ifdef_false
#else
#define ifdef_c ifdef_true
#define ifdef_cpp ifdef_false
#endif
#if defined _WIN32
#define ifdef_win32 ifdef_true
#define ifdef_linux ifdef_false
#define ifdef_osx ifdef_false
#define ifdef_bsd ifdef_false
#define ifdef_ems ifdef_false
#elif defined __linux__
#define ifdef_win32 ifdef_false
#define ifdef_linux ifdef_true
#define ifdef_osx ifdef_false
#define ifdef_bsd ifdef_false
#define ifdef_ems ifdef_false
#elif defined __APPLE__
#define ifdef_win32 ifdef_false
#define ifdef_linux ifdef_false
#define ifdef_osx ifdef_true
#define ifdef_bsd ifdef_false
#define ifdef_ems ifdef_false
#elif defined __EMSCRIPTEN__
#define ifdef_win32 ifdef_false
#define ifdef_linux ifdef_false
#define ifdef_osx ifdef_false
#define ifdef_bsd ifdef_false
#define ifdef_ems ifdef_true
#else // __FreeBSD__ || @todo: __ANDROID_API__
#define ifdef_win32 ifdef_false
#define ifdef_linux ifdef_false
#define ifdef_osx ifdef_false
#define ifdef_bsd ifdef_true
#define ifdef_ems ifdef_false
#endif
#ifdef NDEBUG // rely on NDEBUG as the official/portable way to disable asserts
#define ifdef_debug ifdef_false
#define ifdef_release ifdef_true
#else
#define ifdef_debug ifdef_true
#define ifdef_release ifdef_false
#endif
2023-10-13 16:13:52 +00:00
#if ENABLE_RETAIL
2023-10-13 15:56:26 +00:00
#define ifdef_retail ifdef_true
#else
#define ifdef_retail ifdef_false
#endif
2023-10-13 16:20:20 +00:00
#if COOK_DISABLED
#define ifdef_nocook ifdef_true
#else
#define ifdef_nocook ifdef_false
#endif
2023-10-14 19:47:24 +00:00
#if defined NDEBUG && NDEBUG >= 3 // we use NDEBUG=[0,1,2,3] to signal the compiler optimization flags O0,O1,O2,O3
#define ifdef_O3 ifdef_true
#define ifdef_O2 ifdef_false
#define ifdef_O1 ifdef_false
#define ifdef_O0 ifdef_false
#elif defined NDEBUG && NDEBUG >= 2
#define ifdef_O3 ifdef_false
#define ifdef_O2 ifdef_true
#define ifdef_O1 ifdef_false
#define ifdef_O0 ifdef_false
#elif defined NDEBUG && NDEBUG >= 1
#define ifdef_O3 ifdef_false
#define ifdef_O2 ifdef_false
#define ifdef_O1 ifdef_true
#define ifdef_O0 ifdef_false
#else
#define ifdef_O3 ifdef_false
#define ifdef_O2 ifdef_false
#define ifdef_O1 ifdef_false
#define ifdef_O0 ifdef_true
#endif
#include <stdint.h>
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
#define ifdef_64 ifdef_true
#define ifdef_32 ifdef_false
#else
#define ifdef_64 ifdef_false
#define ifdef_32 ifdef_true
#endif
// -----------------------------------------------------------------------------
// new C keywords
#define countof(x) (int)(sizeof (x) / sizeof 0[x])
#define concat(a,b) conc4t(a,b)
2023-10-07 17:34:09 +00:00
#define conc4t(a,b) a##b ///-
#define macro(name) concat(name, __LINE__)
#define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1))
#define scope(end) defer((void)0, end)
2023-10-11 19:01:06 +00:00
#define benchmark for(double macro(i) = 1, macro(t) = -time_ss(); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 ))
#define do_once static int macro(once) = 0; for(;!macro(once);macro(once)=1)
#if is(cl)
#define __thread __declspec(thread)
#elif is(tcc) && is(win32)
2023-10-11 19:01:06 +00:00
#define __thread __declspec(thread) // compiles fine apparently, but does not work
#elif is(tcc)
#define __thread
#endif
// usage: bool static(audio_is_init) = audio_init();
//#define static(var) static var; do_once var
//-----------------------------------------------------------------------------
// new C macros
2023-10-14 19:47:24 +00:00
#if ENABLE_RETAIL
#define ASSERT(expr, ...) (void)0
#define ASSERT_ONCE(expr, ...) (void)0
#else
#define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
#define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
2023-10-14 19:47:24 +00:00
#endif
#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_)
#define FILELINE __FILE__ ":" STRINGIZE(__LINE__)
#define STRINGIZE(x) STRINGIZ3(x)
2023-10-07 17:34:09 +00:00
#define STRINGIZ3(x) #x ///-
#define EXPAND(name, ...) EXPAND_QUOTE(EXPAND_JOIN(name, EXPAND_COUNT_ARGS(__VA_ARGS__)), (__VA_ARGS__))
2023-10-07 17:34:09 +00:00
#define EXPAND_QUOTE(x, y) x y ///-
#define EXPAND_JOIN(name, count) EXPAND_J0IN(name, count) ///-
#define EXPAND_J0IN(name, count) EXPAND_J01N(name, count) ///-
#define EXPAND_J01N(name, count) name##count ///-
#define EXPAND_COUNT_ARGS(...) EXPAND_ARGS((__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) ///-
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
2023-10-16 15:15:59 +00:00
// expands to the first argument
#define VA_FIRST(...) VA_F1RST(__VA_ARGS__, throwaway)
#define VA_F1RST(first, ...) first ///-
// if there's only one argument, expands to nothing. if there is more
// than one argument, expands to a comma followed by everything but
// the first argument. only supports up to 9 arguments but can be expanded.
#define VA_REST(...) VA_R3ST(VA_NUM(__VA_ARGS__), __VA_ARGS__)
#define VA_R3ST(qty, ...) VA_R3S7(qty, __VA_ARGS__) ///-
#define VA_R3S7(qty, ...) VA_R3S7_##qty(__VA_ARGS__) ///-
#define VA_R3S7_ONE(first) ///-
#define VA_R3S7_TWOORMORE(first, ...) , __VA_ARGS__ ///-
#define VA_NUM(...) VA_SELECT_10TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) ///-
#define VA_SELECT_10TH(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10
// VA_SPLIT() expands to A) 1 item OR B) 1 item + ',' + va_args[1..N]
#define VA_SPLIT(...) VA_FIRST(__VA_ARGS__) VA_REST(__VA_ARGS__)
#if is(cl) && !is(cpp)
#define INLINE __inline
#else
#define INLINE inline
#endif
#if is(cl)
#define FORCE_INLINE __forceinline
#elif is(gcc)
#define FORCE_INLINE __attribute__((always_inline)) inline
#else
#define FORCE_INLINE INLINE
#endif
#if is(cl) && (_MSC_VER <= 1700)
#define FINITE _finite
#else
#define FINITE isfinite
#endif
// usage: #define vec2(...) C_CAST(vec2, __VA_ARGS__)
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
2023-10-07 17:34:09 +00:00
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
2023-10-16 15:15:59 +00:00
// create a WARNING(...) macro
// usage: WARNING("this is displayed at compile time")
#if is(gcc)
# define WARNING(msg) WARN1NG( message( msg ) )
# define WARN1NG(msg) _Pragma(#msg)
#elif is(cl)
# define WARNING(msg) __pragma( message( msg ) )
#else
# define WARNING(msg)
#endif
// document todos and fixmes via compiler warnings
#define TODO(str) ifdef(debug,WARNING("TO DO: " str " (" FILELINE ")"))
#define FIXME(str) ifdef(debug,WARNING("FIXME: " str " (" FILELINE ")"))
2023-10-11 19:01:06 +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
2023-10-16 15:15:59 +00:00
#define AUTORUN_(fn) \
static void fn(void); \
static const int concat(fn,__1) = (fn(), 1); \
static void fn(void)
2023-10-11 19:01:06 +00:00
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
2023-10-16 15:15:59 +00:00
#define AUTORUN_(fn) \
static void fn(void); \
static int concat(fn,__1) (){ fn(); return 0; } \
2023-10-11 19:01:06 +00:00
__pragma(section(".CRT$XIU", long, read)) \
__declspec(allocate(".CRT$XIU")) \
2023-10-16 15:15:59 +00:00
static int(* concat(fn,__2) )() = concat(fn,__1); \
static void fn(void)
2023-10-11 19:01:06 +00:00
#else // gcc,tcc,clang,clang-cl...
2023-10-16 15:15:59 +00:00
#define AUTORUN_(fn) \
2023-10-11 19:01:06 +00:00
__attribute__((constructor)) \
2023-10-16 15:15:59 +00:00
static void fn(void)
2023-10-11 19:01:06 +00:00
#endif
2023-10-16 15:15:59 +00:00
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
2023-10-11 19:01:06 +00:00
#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-10-07 17:34:09 +00:00
// -----------------------------------------------------------------------------
// build info
#ifndef BUILD_VERSION
#define BUILD_VERSION ""
#endif
// -----------------------------------------------------------------------------
// visibility
2023-08-10 14:30:56 +00:00
// win32 users would need to -DAPI=IMPORT/EXPORT as needed when using/building V4K as DLL.
2023-10-07 17:34:09 +00:00
#define IMPORT ifdef(win32, ifdef(gcc, __attribute__ ((dllimport)), __declspec(dllimport)))
#define EXPORT ifdef(win32, ifdef(gcc, __attribute__ ((dllexport)), __declspec(dllexport)))
#define STATIC
#ifndef API
#define API STATIC
#endif
// -----------------------------------------------------------------------------
// system headers
#ifndef _GNU_SOURCE
2023-09-27 06:49:59 +00:00
#define _GNU_SOURCE ///- for linux
#endif
#if is(cl) && is(win32) // for VC IDE
2023-09-27 06:49:59 +00:00
#define _CRT_SECURE_NO_WARNINGS ///-
#define _CRT_NONSTDC_NO_DEPRECATE ///-
#define _WINSOCK_DEPRECATED_NO_WARNINGS ///-
#define _WIN32_WINNT 0x0600 ///- 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86
#endif
#if is(cl)
#include <omp.h> // compile with /openmp to speed up some computations
#endif
#include <assert.h>
//#include <float.h>
//#include <limits.h>
#include <math.h> // NAN
#include <stdarg.h> // va_*(), ...
#include <stdbool.h> // bool,true,false
#include <stdint.h> // u/int8/16/32/64_t
#include <stdio.h> // FILE,NULL
#include <stdlib.h> // malloc,free,exit,
#include <string.h> // strlen,memset,memcpy,
#if is(tcc) && is(win32) && defined(__x86_64)
#include <tgmath.h>
// @fixme workarounds on `tcc0.9.27 -m64` (win) for fmod()/trunc() functions. test: 00-easing broken otherwise
//#define trunc(x) ((double)(int64_t)(x))
//#define fmod(x,y) ((x) - trunc((x) / (y)) * (y))
// @fixme workarounds on `tcc0.9.27 -m64` (win) for all functions with ending bool argument. test: 00-anims crashes otherwise
#undef bool
typedef char bool;
// missing libm symbols on tinycc HEAD repo (tcc-x64 pre-0.9.28)
//#define fabsf fabs
#define sqrtf sqrt
#define sinf sin
#define asinf asin
#define cosf cos
#define acosf acos
#define tanf tan
#define atan2f atan2
#define powf pow
#define floorf floor
#define logf log
#define ceilf ceil
#define copysignf copysign
//#define ldexpf ldexp
#define expf exp
//#define frexpf frexp
#define fmodf fmod
#define log10f log10
//#define logf log
#define hypotf hypot
#endif
// -----------------------------------------------------------------------------
// pragma libs
#if is(win32) && (is(cl) || is(tcc))
#pragma comment(lib, "advapi32")
#pragma comment(lib, "comdlg32")
#pragma comment(lib, "dbghelp")
#pragma comment(lib, "gdi32")
#pragma comment(lib, "ole32")
#pragma comment(lib, "shell32")
#pragma comment(lib, "user32")
#pragma comment(lib, "winmm")
2023-09-21 10:45:42 +00:00
#pragma comment(lib, "wininet")
#pragma comment(lib, "ws2_32")
#endif
#if is(linux) && is(tcc)
#pragma comment(lib, "dl")
#pragma comment(lib, "m")
#pragma comment(lib, "pthread")
#endif