diff --git a/src/ase/ase.lay b/src/ase/ase.lay index 2b3367e8..4c4f9b94 100644 --- a/src/ase/ase.lay +++ b/src/ase/ase.lay @@ -1,7 +1,6 @@ @Layer ase //- Dependencies -@Dep base @Dep bitbuff //- Api diff --git a/src/asset_cache/asset_cache.lay b/src/asset_cache/asset_cache.lay index ddc4b364..98eadf13 100644 --- a/src/asset_cache/asset_cache.lay +++ b/src/asset_cache/asset_cache.lay @@ -1,7 +1,6 @@ @Layer asset_cache //- Dependencies -@Dep base @Dep platform //- Api diff --git a/src/base/base_core.h b/src/base/base.h similarity index 97% rename from src/base/base_core.h rename to src/base/base.h index 2d2fbf98..3e48b81a 100644 --- a/src/base/base_core.h +++ b/src/base/base.h @@ -1,6 +1,10 @@ //////////////////////////////// //~ Compiler flag checks +#ifndef IsConsoleApp +# error Missing compile time definition for 'IsConsoleApp' +#endif + #ifndef RtcIsEnabled # error Missing compile time definition for 'RtcIsEnabled' #endif @@ -573,7 +577,7 @@ ForceInline void UnlockTicketMutex(TicketMutex *tm) #endif //////////////////////////////// -//~ String utils +//~ String types #define STRING(size, data) ((String) { (size), (data) }) #define Lit(cstr_lit) (String) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) } @@ -607,38 +611,44 @@ Struct(String32) u32 *text; }; -//////////////////////////////// -//~ Fibers - -#define MaxFibers 1024 - -#if LanguageIsC -# if PlatformIsWindows -ForceInline i16 FiberId(void) +Struct(StringArray) { - i16 *v = (void *)(u64)__readgsqword(32); - return *v; -} -# else -# error FiberId not implemented -# endif -StaticAssert(MaxFibers < I16Max); /* Fiber id type should fit max fibers */ -#endif + u64 count; + String *strings; +}; + +Struct(StringListNode) +{ + String s; + StringListNode *next; + StringListNode *prev; +}; + +Struct(StringList) +{ + StringListNode *first; + StringListNode *last; + u64 count; +}; //////////////////////////////// //~ @hookdecl Core hooks void StartupBase(void); +StringList GetCommandLineArgs(void); b32 Panic(String msg); b32 IsRunningInDebugger(void); -i16 ThreadId(void); void TrueRand(String buffer); +i16 FiberId(void); +i16 ThreadId(void); #define MaxThreads 1024 +#define MaxFibers 1024 StaticAssert(MaxThreads < I16Max); /* Thread id type should fit max threads */ +StaticAssert(MaxFibers < I16Max); /* Fiber id type should fit max threads */ //////////////////////////////// -//~ @hookdecl Layer startup hook (defined by meta program) +//~ @hookdecl Layer startup hook (defined by metaprogram) void StartupLayers(void); diff --git a/src/base/base.lay b/src/base/base.lay deleted file mode 100644 index 767a0cec..00000000 --- a/src/base/base.lay +++ /dev/null @@ -1,37 +0,0 @@ -@Layer base - -//- Api -@IncludeC base_core.h -@IncludeC base_intrinsics.h -@IncludeC base_memory.h -@IncludeC base_arena.h -@IncludeC base_snc.h -@IncludeC base_job.h -@IncludeC base_uid.h -@IncludeC base_string.h -@IncludeC base_uni.h -@IncludeC base_gstat.h -@IncludeC base_buddy.h -@IncludeC base_math.h -@IncludeC base_rand.h -@IncludeC base_util.h -@IncludeC base_incbin.h -@IncludeC base_entry.h -@IncludeGpu base_core.h -@IncludeGpu base_math_gpu.h - -//- Impl -@IncludeC base_memory.c -@IncludeC base_arena.c -@IncludeC base_snc.c -@IncludeC base_uid.c -@IncludeC base_string.c -@IncludeC base_uni.c -@IncludeC base_gstat.c -@IncludeC base_buddy.c -@IncludeC base_math.c -@IncludeC base_rand.c -@IncludeC base_incbin.c - -//- Win32 impl -@DefaultWindowsImpl base_win32 diff --git a/src/base/base_arena.h b/src/base/base_arena.h index 9a2fca12..e881935e 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -57,6 +57,9 @@ extern SharedArenaCtx shared_arena_ctx; #define PopStruct(a, type, dst) PopBytes((a), sizeof(type), dst) #define PopStructs(a, type, n, dst) PopBytes((a), sizeof(type) * (n), dst) +#define PopStructNoCopy(a, type) PopBytesNoCopy((a), sizeof(type)) +#define PopStructsNoCopy(a, type, n) PopBytesNoCopy((a), sizeof(type) * (n)) + /* Returns a pointer to where the next push would be (at alignment of type). * Equivalent to PushStruct but without actually allocating anything or modifying the arena. */ #define PushDry(a, type) (type *)(_PushDry((a), alignof(type))) @@ -84,6 +87,15 @@ Inline void PopTo(Arena *arena, u64 pos) arena->pos = pos; } +Inline void PopBytesNoCopy(Arena *arena, u64 size) +{ + Assert(arena->pos >= size); + Assert(!arena->readonly); + u64 new_pos = arena->pos - size; + AsanPoison(ArenaBase(arena) + new_pos, arena->pos - new_pos); + arena->pos = new_pos; +} + Inline void PopBytes(Arena *arena, u64 size, void *copy_dst) { Assert(arena->pos >= size); diff --git a/src/base/base_entry.h b/src/base/base_entry.h index c33b9713..7cab32e5 100644 --- a/src/base/base_entry.h +++ b/src/base/base_entry.h @@ -8,7 +8,8 @@ typedef ExitFuncDef(ExitFunc); //~ @hookdecl Exit operations void OnExit(ExitFunc *func); -void Exit(void); +void SignalExit(i32 code); +void ExitNow(i32 code); //////////////////////////////// //~ @hookdecl Application defined hooks diff --git a/src/base/base_inc.h b/src/base/base_inc.h new file mode 100644 index 00000000..ae054fb5 --- /dev/null +++ b/src/base/base_inc.h @@ -0,0 +1,45 @@ +// This is the includable header version of the base layer manifest. +// The base layer uses an includable header file rather than a '.lay' file so +// that it may be depended on by the metaprogram. + +//- Api +#include "base.h" +#if LanguageIsC +# include "base_intrinsics.h" +# include "base_memory.h" +# include "base_arena.h" +# include "base_snc.h" +# include "base_job.h" +# include "base_uid.h" +# include "base_string.h" +# include "base_uni.h" +# include "base_gstat.h" +# include "base_buddy.h" +# include "base_math.h" +# include "base_rand.h" +# include "base_util.h" +# include "base_incbin.h" +# include "base_entry.h" +#elif LanguageIsGpu +# include "base_math_gpu.h" +#endif + +//- Impl +#if LanguageIsC +# include "base_memory.c" +# include "base_arena.c" +# include "base_snc.c" +# include "base_uid.c" +# include "base_string.c" +# include "base_uni.c" +# include "base_gstat.c" +# include "base_buddy.c" +# include "base_math.c" +# include "base_rand.c" +# include "base_incbin.c" +#endif + +//- Win32 impl +#if LanguageIsC && PlatformIsWindows +# include "base_win32/base_win32_inc.h" +#endif diff --git a/src/base/base_string.h b/src/base/base_string.h index 80f80631..de4aa4f3 100644 --- a/src/base/base_string.h +++ b/src/base/base_string.h @@ -1,26 +1,3 @@ -//////////////////////////////// -//~ String types - -Struct(StringArray) -{ - u64 count; - String *strings; -}; - -Struct(StringListNode) -{ - String s; - StringListNode *next; - StringListNode *prev; -}; - -Struct(StringList) -{ - StringListNode *first; - StringListNode *last; - u64 count; -}; - //////////////////////////////// //~ Formatting types diff --git a/src/base/base_win32/base_win32.c b/src/base/base_win32/base_win32.c index 71422e6f..1fcc86ee 100644 --- a/src/base/base_win32/base_win32.c +++ b/src/base/base_win32/base_win32.c @@ -1,8 +1,9 @@ W32_SharedState W32_shared_state = ZI; //////////////////////////////// -//~ @hookdef OS startup hook +//~ @hookdef Core hooks +//- Startup void StartupBase(void) { W32_SharedState *g = &W32_shared_state; @@ -10,12 +11,14 @@ void StartupBase(void) TlsSetValue(g->tls_index, 0); } -//////////////////////////////// -//~ @hookdef Panic hooks - -/* TODO: Remove stdio & printf */ -#include +//- Command line args +StringList GetCommandLineArgs(void) +{ + StringList result = ZI; + return result; +} +//- Panic b32 Panic(String msg) { char msg_cstr[4096]; @@ -26,33 +29,38 @@ b32 Panic(String msg) } HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE); WriteConsoleA(console_handle, msg.text, msg.len, 0, 0); - if ((1)) /* Supress unreachable code warning */ + if (IsRunningInDebugger()) + { + Assert(0); + } + else { ExitProcess(1); } return 0; } -//////////////////////////////// -//~ @hookdef Debugger hooks - +//- Debugger check b32 IsRunningInDebugger(void) { return IsDebuggerPresent(); } -//////////////////////////////// -//~ @hookdef Thread hooks +//- Fiber id +ForceInline i16 FiberId(void) +{ + i16 *v = (void *)(u64)__readgsqword(32); + return *v; +} +//- Thread id i16 ThreadId(void) { W32_SharedState *g = &W32_shared_state; return (i16)(i64)TlsGetValue(g->tls_index); } -//////////////////////////////// -//~ @hookdef Randomness hooks - +//- True randomness void TrueRand(String buffer) { BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (u8 *)buffer.text, buffer.len, 0); diff --git a/src/base/base_win32/base_win32.h b/src/base/base_win32/base_win32.h index 5eb5cea8..73baace1 100644 --- a/src/base/base_win32/base_win32.h +++ b/src/base/base_win32/base_win32.h @@ -16,6 +16,7 @@ u32 BCryptGenRandom(void *algorithm, u8 *buffer, u32 buffer_size, u32 flags); Struct(W32_SharedState) { DWORD tls_index; + Atomic32 exit_code; }; extern W32_SharedState W32_shared_state; diff --git a/src/base/base_win32/base_win32.lay b/src/base/base_win32/base_win32.lay deleted file mode 100644 index f42bdb3d..00000000 --- a/src/base/base_win32/base_win32.lay +++ /dev/null @@ -1,11 +0,0 @@ -@Layer base_win32 - -//- Api -@IncludeC base_win32.h -@IncludeC base_win32_entry.h -@IncludeC base_win32_job.h - -//- Impl -@IncludeC base_win32.c -@IncludeC base_win32_entry.c -@IncludeC base_win32_job.c diff --git a/src/base/base_win32/base_win32_entry.c b/src/base/base_win32/base_win32_entry.c index e19ab75e..03e8dc0d 100644 --- a/src/base/base_win32/base_win32_entry.c +++ b/src/base/base_win32/base_win32_entry.c @@ -42,22 +42,23 @@ void OnExit(ExitFunc *func) g->exit_funcs[index] = func; } -void Exit(void) +void SignalExit(i32 code) { W32_SharedEntryCtx *g = &W32_shared_entry_ctx; + Atomic32FetchSet(&g->exit_code, code); SetEvent(g->exit_begin_event); } -//////////////////////////////// -//~ Winmain - -int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, _In_ LPWSTR cmdline_wstr, _In_ int show_code) +void ExitNow(i32 code) { - LAX instance; - LAX prev_instance; - LAX cmdline_wstr; - LAX show_code; + ExitProcess(code); +} +//////////////////////////////// +//~ Main + +i32 W32_Main(void) +{ __profthread("Main thread", PROF_THREAD_GROUP_MAIN); W32_SharedEntryCtx *g = &W32_shared_entry_ctx; @@ -141,10 +142,6 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, g->exit_begin_event = CreateEventW(0, 1, 0, 0); g->exit_end_event = CreateEventW(0, 1, 0, 0); - u64 cmdline_len = WstrLen(cmdline_wstr, countof(g->cmdline_args_wstr) - 1); - CopyBytes(g->cmdline_args_wstr, cmdline_wstr, cmdline_len * sizeof(*cmdline_wstr)); - g->cmdline_args_wstr[cmdline_len] = 0; - g->main_thread_id = GetCurrentThreadId(); SetThreadDescription(GetCurrentThread(), L"Main thread"); @@ -199,16 +196,38 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } /* Exit */ - i32 exit_code = 0; if (Atomic32Fetch(&g->panicking)) { WaitForSingleObject(g->panic_event, INFINITE); MessageBoxExW(0, g->panic_wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); - exit_code = 1; + Atomic32FetchTestSet(&g->exit_code, 0, 1); } - return exit_code; + return Atomic32Fetch(&g->exit_code); } +//////////////////////////////// +//~ Crt main + +#if CrtlibIsEnabled +# if IsConsoleApp +int main(char **argc, int argv) +{ + LAX argc; + LAX argv; + return W32_Main(); +} +# else +int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, _In_ LPWSTR cmdline_wstr, _In_ int show_code) +{ + LAX instance; + LAX prev_instance; + LAX cmdline_wstr; + LAX show_code; + return W32_Main(); +} +# endif /* IsConsoleApp */ +#endif /* CrtlibIsEnabled */ + //////////////////////////////// //~ Crt stub @@ -225,7 +244,7 @@ int _fltused; __attribute((used)) void __stdcall wWinMainCRTStartup(void) { - int result = wWinMain(GetModuleHandle(0), 0, GetCommandLineW(), 0); + i32 result = W32_Main(); ExitProcess(result); } diff --git a/src/base/base_win32/base_win32_entry.h b/src/base/base_win32/base_win32_entry.h index e6c172c8..ca098d59 100644 --- a/src/base/base_win32/base_win32_entry.h +++ b/src/base/base_win32/base_win32_entry.h @@ -8,8 +8,7 @@ Struct(W32_SharedEntryCtx) SYSTEM_INFO info; u32 main_thread_id; Atomic32 shutdown; - - wchar_t cmdline_args_wstr[8192]; + Atomic32 exit_code; //- Application control flow Atomic32 panicking; @@ -31,3 +30,8 @@ extern W32_SharedEntryCtx W32_shared_entry_ctx; JobDecl(W32_StartupLayersJob, EmptySig); JobDecl(W32_ShutdownLayersJob, EmptySig); + +//////////////////////////////// +//~ Main + +i32 W32_Main(void); diff --git a/src/base/base_win32/base_win32_inc.h b/src/base/base_win32/base_win32_inc.h new file mode 100644 index 00000000..82da26b5 --- /dev/null +++ b/src/base/base_win32/base_win32_inc.h @@ -0,0 +1,9 @@ +//- Api +#include "base_win32.h" +#include "base_win32_entry.h" +#include "base_win32_job.h" + +//- Impl +#include "base_win32.c" +#include "base_win32_entry.c" +#include "base_win32_job.c" diff --git a/src/bitbuff/bitbuff.lay b/src/bitbuff/bitbuff.lay index ee8ecaef..5f9c9e3d 100644 --- a/src/bitbuff/bitbuff.lay +++ b/src/bitbuff/bitbuff.lay @@ -1,8 +1,5 @@ @Layer bitbuff -//- Dependencies -@Dep base - //- Api @IncludeC bitbuff_core.h diff --git a/src/collider/collider.lay b/src/collider/collider.lay index 4adee776..5cd03534 100644 --- a/src/collider/collider.lay +++ b/src/collider/collider.lay @@ -1,8 +1,5 @@ @Layer collider -//- Dependencies -@Dep base - //- Api @IncludeC collider_core.h diff --git a/src/font/font.lay b/src/font/font.lay index 1c27b4a0..08759abd 100644 --- a/src/font/font.lay +++ b/src/font/font.lay @@ -1,7 +1,6 @@ @Layer font //- Dependencies -@Dep base @Dep ttf @Dep gpu @Dep resource diff --git a/src/gpu/gpu.lay b/src/gpu/gpu.lay index d351487e..cb71ba31 100644 --- a/src/gpu/gpu.lay +++ b/src/gpu/gpu.lay @@ -1,7 +1,6 @@ @Layer gpu //- Dependencies -@Dep base @Dep platform //- Api diff --git a/src/inc/inc.lay b/src/inc/inc.lay index 335c9b18..abcfedb2 100644 --- a/src/inc/inc.lay +++ b/src/inc/inc.lay @@ -1,8 +1,5 @@ @Layer inc -//- Dependencies -@Dep base - //- Api @IncludeC inc_core.h diff --git a/src/meta/meta.c b/src/meta/meta.c index 071b5baa..89865ae9 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -5,6 +5,10 @@ //////////////////////////////// //~ Metaprogram default compiler definitions +#ifndef IsConsoleApp +# define IsConsoleApp 1 +#endif + #ifndef RtcIsEnabled # define RtcIsEnabled 1 #endif @@ -48,7 +52,7 @@ //////////////////////////////// //~ Includes -#include "meta_base/meta_base_inc.h" +#include "../base/base_inc.h" #include "meta_os/meta_os_inc.h" #include "meta_file/meta_file_inc.h" #include "meta.h" @@ -737,20 +741,18 @@ Error *PushError(Arena *arena, ErrorList *list, String file, i64 pos, String s) //////////////////////////////// //~ Entry point -i32 main(i32 argc, u8 **argv) +void StartupMeta(void) { - //- Startup - StartupBase(); - OS_Startup(); Arena *arena = AcquireArena(Gibi(64)); i32 ret = 0; ErrorList errors = ZI; //- Unpack args - for (i32 i = 1; i < argc; ++i) + StringList args = GetCommandLineArgs(); + for (StringListNode *n = args.first; n; n = n->next) { - String arg = StringFromCstrNoLimit(argv[i]); + String arg = n->s; } //- Return if metaprogram is dirty @@ -771,8 +773,9 @@ i32 main(i32 argc, u8 **argv) u64 new_metahash = 0; { StringList check_files = ZI; - F_FilesFromDir(arena, &check_files, Lit("../src/meta"), F_IterFlag_Recurse); F_FilesFromDir(arena, &check_files, Lit("../src/prof"), F_IterFlag_Recurse); + F_FilesFromDir(arena, &check_files, Lit("../src/base"), F_IterFlag_Recurse); + F_FilesFromDir(arena, &check_files, Lit("../src/meta"), F_IterFlag_Recurse); PushStringToList(arena, &check_files, Lit("../src/config.h")); for (StringListNode *n = check_files.first; n; n = n->next) { @@ -789,7 +792,7 @@ i32 main(i32 argc, u8 **argv) else { Echo(Lit("Metaprogram is dirty")); - return MetaRebuildCode; + ExitNow(MetaRebuildCode); } } @@ -815,11 +818,19 @@ i32 main(i32 argc, u8 **argv) if (errors.count <= 0) { StringList c_out_lines = ZI; - /* Includes */ + PushStringToList(arena, &c_out_lines, Lit("// Auto generated file")); + /* Include base layer */ { - PushStringToList(arena, &c_out_lines, Lit("// Auto generated file")); + String base_inc_path = F_GetFull(arena, Lit("../src/base/base_inc.h")); PushStringToList(arena, &c_out_lines, Lit("")); - PushStringToList(arena, &c_out_lines, Lit("//- Includes")); + PushStringToList(arena, &c_out_lines, Lit("//- Include base layer")); + String line = StringF(arena, "#include \"%F\"", FmtString(base_inc_path)); + PushStringToList(arena, &c_out_lines, line); + } + /* Include dependency layers */ + { + PushStringToList(arena, &c_out_lines, Lit("")); + PushStringToList(arena, &c_out_lines, Lit("//- Include dependencies")); for (L_TopoItem *item = topo.c_includes.first; item; item = item->next) { String parent = F_GetParentDir(item->token_file); @@ -837,7 +848,7 @@ i32 main(i32 argc, u8 **argv) } } } - /* StartupLayers definition */ + /* Define StartupLayers */ { PushStringToList(arena, &c_out_lines, Lit("")); PushStringToList(arena, &c_out_lines, Lit("//- Startup")); @@ -886,6 +897,7 @@ i32 main(i32 argc, u8 **argv) StringList clang_compiler_flags = ZI; { //- Shared + PushStringToList(arena, &shared_compiler_flags, Lit("-DIsConsoleApp=0")); PushStringToList(arena, &shared_compiler_flags, Lit("-DRtcIsEnabled=1")); PushStringToList(arena, &shared_compiler_flags, Lit("-DAsanIsEnabled=0")); PushStringToList(arena, &shared_compiler_flags, Lit("-DCrtlibIsEnabled=1")); @@ -963,5 +975,15 @@ i32 main(i32 argc, u8 **argv) } } - return ret != 0 ? ret : errors.count > 0; + ExitNow(ret != 0 ? ret : errors.count > 0); +} + +//////////////////////////////// +//~ @hookdef Startup + +void StartupLayers(void) +{ + StartupBase(); + OS_Startup(); + StartupMeta(); } diff --git a/src/meta/meta.h b/src/meta/meta.h index 44700c99..e69de29b 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -1 +0,0 @@ -i32 main(i32 argc, u8 **argv); diff --git a/src/meta/meta_base/meta_base.h b/src/meta/meta_base/meta_base.h deleted file mode 100644 index 2d2fbf98..00000000 --- a/src/meta/meta_base/meta_base.h +++ /dev/null @@ -1,653 +0,0 @@ -//////////////////////////////// -//~ Compiler flag checks - -#ifndef RtcIsEnabled -# error Missing compile time definition for 'RtcIsEnabled' -#endif - -#ifndef AsanIsEnabled -# error Missing compile time definition for 'AsanIsEnabled' -#endif - -#ifndef CrtlibIsEnabled -# error Missing compile time definition for 'CrtlibIsEnabled' -#endif - -#ifndef DebinfoEnabled -# error Missing compile time definition for 'DebinfoEnabled' -#endif - -#ifndef DeveloperIsEnabled -# error Missing compile time definition for 'DeveloperIsEnabled' -#endif - -#ifndef ProfilingIsEnabled -# error Missing compile time definition for 'ProfilingIsEnabled' -#endif - -#ifndef UnoptimizedIsEnabled -# error Missing compile time definition for 'UnoptimizedIsEnabled' -#endif - -#ifndef TestsAreEnabled -# error Missing compile time definition for 'TestsAreEnabled' -#endif - -#ifndef IncbinRawDir -# error Missing compile time definition for 'IncbinRawDir' -#else -# define IncbinDir Stringize(IncbinRawDir) -#endif - -//////////////////////////////// -//~ Machine context - -//- Compiler -#if defined(__clang__) -# define CompilerIsClang 1 -# define CompilerIsMsvc 0 -#elif defined(_MSC_VER) -# define CompilerIsClang 0 -# define CompilerIsMsvc 1 -#else -# error Unknown compiler -#endif - -//- Language -#if defined(__HLSL_VERSION) -# define LanguageIsC 0 -# define LanguageIsGpu 1 -#else -# define LanguageIsC 1 -# define LanguageIsGpu 0 -#endif - -//- Platform system -#if defined(_WIN32) -# define PlatformIsWindows 1 -# define PlatformIsMac 0 -# define PlatformIsLinux 0 -#elif defined(__APPLE__) && defined(__MACH__) -# define PlatformIsWindows 0 -# define PlatformIsMac 1 -# define PlatformIsLinux 0 -#elif defined(__gnu_linux__) -# define PlatformIsWindows 0 -# define PlatformIsMac 0 -# define PlatformIsLinux 1 -#elif LanguageIsGpu -# define PlatformIsWindows 0 -# define PlatformIsMac 0 -# define PlatformIsLinux 0 -#else -# error Unknown platform -#endif - -//- Windows NTDDI version -/* FIXME: Remove this */ -#if 0 -#if CompilerIsMsvc -# define NTDDI_WIN11_DT 0x0C0A0000 -# define NTDDI_VERSION 0x0A000000 -# if RtcIsEnabled -# define _ALLOW_RTCc_IN_STL 1 -# endif -#endif -#endif - -//- Windows defines -#if PlatformIsWindows -# define COBJMACROS -# define WIN32_LEAN_AND_MEAN -# define UNICODE -# pragma warning(push, 0) -# include -# pragma warning(pop) -#endif - -//////////////////////////////// -//~ Debug - -//- Static assert -#if LanguageIsC -# define StaticAssert2(cond, line, counter) struct STATIC_ASSERT_____##line##counter {int foo[(cond) ? 1 : -1];} -# define StaticAssert1(cond, line, counter) StaticAssert2(cond, line, counter) -# define StaticAssert(cond) StaticAssert1(cond, __LINE__, __COUNTER__) -#else -# define StaticAssert(cond) static_assert(cond, "") -#endif - -//- Debug assert -#if RtcIsEnabled -# if CompilerIsMsvc -// # define Assert(cond) ((cond) ? 1 : (IsRunningInDebugger() ? (*(volatile i32 *)0 = 0) : Panic(Lit("Assert(" #cond ") failed at " __FILE__ ":" Stringize(__LINE__))))) -# define Assert(cond) ((cond) ? 1 : (IsRunningInDebugger() ? (*(volatile i32 *)0 = 0) : Panic(Lit(__FILE__ "(" Stringize(__LINE__) "): error Assert("#cond")")))) -# define DEBUGBREAK __debugbreak -# else -# define Assert(cond) ((cond) ? 1 : (__builtin_trap(), 0)) -# define DEBUGBREAK __builtin_debugtrap() -# endif -# define DEBUGBREAKABLE { volatile i32 __DEBUGBREAKABLE_VAR = 0; LAX __DEBUGBREAKABLE_VAR; } (void)0 -#else -# define Assert(cond) (void)(0) -#endif - -//- Root constant assert -#define AssertRootConst(s, n) StaticAssert((sizeof(s) % 16 == 0) && /* Root constant struct should pad to 16 byte alignment */ \ - ((sizeof(s) / 4) == n) && /* Root constant struct size should match the specified 32-bit-constant count */ \ - (sizeof(s) <= 256)) /* Root constant struct can only fit 64 DWORDS */ - -//- Debug alias -/* TODO: Remove this */ -#if CompilerIsMsvc -# if DebinfoEnabled -# define DebugAlias(var, alias) *(alias) = &(var) -# else -# define DebugAlias(var, alias) *(alias) = &(var) -# endif -#else -# if DebinfoEnabled -# define DebugAlias(var, alias) __attribute((used)) *(alias) = &(var) -# else -# define DebugAlias(var, alias) __attribute((unused)) *(alias) = &(var) -# endif -#endif - -//- Address sanitization -#if AsanIsEnabled -void __asan_poison_memory_region(void const volatile *, size_t); -void __asan_unpoison_memory_region(void const volatile *add, size_t); -# define AsanPoison(addr, size) __asan_poison_memory_region((addr), (size)) -# define AsanUnpoison(addr, size) __asan_unpoison_memory_region((addr), (size)) -#else -# define AsanPoison(addr, size) -# define AsanUnpoison(addr, size) -#endif - -//////////////////////////////// -//~ Common utility macros - -//- ZeroStruct initialization macro -#if LanguageIsC -# define ZI { 0 } -#else -# define ZI { } -#endif - -//- Inline -#define Inline static inline - -#if CompilerIsMsvc -# define ForceInline Inline __forceinline -#else -# define ForceInline Inline __attribute((always_inline)) -#endif - -#if CompilerIsMsvc -# define ForceNoInline __declspec(noinline) -#else -# define ForceNoInline __attribute__((noinline)) -#endif - -//- Static -#define LocalPersist static -#define Global static -/* TODO: Remove this */ -#define internal static - -//- Read-only -#if PlatformIsWindows -# if CompilerIsMsvc -# pragma section(".rdata$", read) -# define Readonly __declspec(allocate(".rdata$")) -# else -# define Readonly __declspec(allocate(".rdata")) -# endif -#elif PlatformIsMac -# define Readonly __attribute((section("__TEXT,__const"))) -#else -# define Readonly __attribute((section(".rodata"))) -#endif - -//- Barriers -#if CompilerIsMsvc -# define WriteBarrier() _WriteBarrier() -# define ReadBarrier() _ReadBarrier() -#elif defined(__x86_64) || defined(__i386__) -# define WriteBarrier() __asm__ volatile("" ::: "memory") -# define ReadBarrier() __asm__ volatile("" ::: "memory") -#elif LanguageIsGpu -# define WriteBarrier() -# define ReadBarrier() -#else -# error Memory barriers not implemented -#endif - -//- Unused markup -/* Strict unused markup */ -#if CompilerIsClang -# define UNUSED __attribute((unused)) -#else -# define UNUSED -#endif - -/* Relaxed unused markup */ -#define LAX (void) - -//- Fallthrough -#if CompilerIsClang -# define FALLTHROUGH __attribute((fallthrough)) -#else -# define FALLTHROUGH -#endif - -//- Preprocessor concatenation -#define Cat1(a, b) a ## b -#define Cat(a, b) Cat1(a, b) - -//- Preprocessor stringization -#define Stringize1(x) #x -#define Stringize(x) Stringize1(x) - -//- Sizes -#define Kibi(n) (n*1024ULL) -#define Mebi(n) (n*Kibi(1024ULL)) -#define Gibi(n) (n*Mebi(1024ULL)) -#define Tebi(n) (n*Gibi(1024ULL)) - -//- Time -#define NsFromSeconds(s) ((i64)((s) * 1000000000.0)) -#define SecondsFromNs(ns) ((f64)(ns) / 1000000000.0) - -//////////////////////////////// -//~ Linked list helper macros - -/* Taken from the rad debugger - * https://github.com/EpicGamesExt/raddebugger/blob/be5634c44867a2e31f6a109df5e574930992df01/src/base/base_core.h#L239 - */ - -#define CheckNil(nil,p) ((p) == 0 || (p) == nil) -#define SetNil(nil,p) ((p) = nil) - -//- Singly linked list stack (first & next pointers) -#define SllStackPush_N(f,n,next) ((n)->next=(f), (f)=(n)) -#define SllStackPop_N(f,next) ((f)=(f)->next) -#define SllStackPush(f,n) SllStackPush_N(f,n,next) -#define SllStackPop(f) SllStackPop_N(f,next) - -//- Singly linked list queue (first, last, & next pointers) -#define SllQueuePush_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\ - ((f)=(l)=(n),SetNil(nil,(n)->next)):\ - ((l)->next=(n),(l)=(n),SetNil(nil,(n)->next))) -#define SllQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\ - ((f)=(l)=(n),SetNil(nil,(n)->next)):\ - ((n)->next=(f),(f)=(n))) -#define SllQueuePop_NZ(nil,f,l,next) ((f)==(l)?\ - (SetNil(nil,f),SetNil(nil,l)):\ - ((f)=(f)->next)) -#define SllQueuePush_N(f,l,n,next) SllQueuePush_NZ(0,f,l,n,next) -#define SllQueuePushFront_N(f,l,n,next) SllQueuePushFront_NZ(0,f,l,n,next) -#define SllQueuePop_N(f,l,next) SllQueuePop_NZ(0,f,l,next) -#define SllQueuePush(f,l,n) SllQueuePush_NZ(0,f,l,n,next) -#define SllQueuePushFront(f,l,n) SllQueuePushFront_NZ(0,f,l,n,next) -#define SllQueuePop(f,l) SllQueuePop_NZ(0,f,l,next) - -//- Doubly linked list (first, last, next, & prev pointers) -#define DllInsert_NPZ(nil,f,l,p,n,next,prev) (CheckNil(nil,f) ? \ - ((f) = (l) = (n), SetNil(nil,(n)->next), SetNil(nil,(n)->prev)) :\ - CheckNil(nil,p) ? \ - ((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil,(n)->prev)) :\ - ((p)==(l)) ? \ - ((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) :\ - (((!CheckNil(nil,p) && CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p)))) -#define DllPushBack_NPZ(nil,f,l,n,next,prev) DllInsert_NPZ(nil,f,l,l,n,next,prev) -#define DllPushFront_NPZ(nil,f,l,n,next,prev) DllInsert_NPZ(nil,l,f,f,n,prev,next) -#define DllRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\ - ((n) == (l) ? (l) = (l)->prev : (0)),\ - (CheckNil(nil,(n)->prev) ? (0) :\ - ((n)->prev->next = (n)->next)),\ - (CheckNil(nil,(n)->next) ? (0) :\ - ((n)->next->prev = (n)->prev))) -#define DllInsert_NP(f,l,p,n,next,prev) DllInsert_NPZ(0,f,l,p,n,next,prev) -#define DllPushBack_NP(f,l,n,next,prev) DllPushBack_NPZ(0,f,l,n,next,prev) -#define DllPushFront_NP(f,l,n,next,prev) DllPushFront_NPZ(0,f,l,n,next,prev) -#define DllRemove_NP(f,l,n,next,prev) DllRemove_NPZ(0,f,l,n,next,prev) -#define DllInsert(f,l,p,n) DllInsert_NPZ(0,f,l,p,n,next,prev) -#define DllPushBack(f,l,n) DllPushBack_NPZ(0,f,l,n,next,prev) -#define DllPushFront(f,l,n) DllPushFront_NPZ(0,f,l,n,next,prev) -#define DllRemove(f,l,n) DllRemove_NPZ(0,f,l,n,next,prev) - -//////////////////////////////// -//~ Struct alignment / padding macros - -//- Pack -#if CompilerIsMsvc -# define Packed(s) __pragma(pack(push, 1)) s __pragma(pack(pop)) -#elif CompilerIsClang -# define Packed(s) s __attribute((__packed__)) -#elif LanguageIsGpu -# define Packed(s) s -#endif - -//- alignas -#if (CompilerIsMsvc && LanguageIsC) || (LanguageIsC && __STDC_VERSION__ < 202311L) -# if CompilerIsMsvc -# define alignas(n) __declspec(align(n)) -# else -# define alignas(n) __attribute__((aligned(n))) -# endif -#endif - -//////////////////////////////// -//~ Color helper macros - -//- Rgba 32 bit helpers -#define Rgb32(r, g, b) Rgba32((r), (g), (b), 0xFF) -#define Rgba32(r, g, b, a) (u32)((u32)(r) | ((u32)(g) << 8) | ((u32)(b) << 16) | ((u32)(a) << 24)) -#define Bgr32(rgb) ((((rgb >> 0) & 0xFF) << 16) | (((rgb >> 8) & 0xFF) << 8) | (((rgb >> 16) & 0xFF) << 0)) - -//- Rgba 32 bit float float helpers -#define _Rgb32U8FromF(fl) ((u8)((fl * 255.0) + 0.5)) -#define Rgba32F(r, g, b, a) Rgba32(_Rgb32U8FromF((r)), _Rgb32U8FromF((g)), _Rgb32U8FromF((b)), _Rgb32U8FromF((a))) -#define Rgb32F(r, g, b) Rgba32F((r), (g), (b), 1.f) - -#define Alpha32F(color, a) ((color) & 0x00FFFFFF) | (_Rgb32U8FromF((a)) << 24) - -//- Pre-defined colors -#define ColorWhite Rgb32(0xFF, 0xFF, 0xFF) -#define ColorBlack Rgb32(0x00, 0x00, 0x00) -#define ColorRed Rgb32(0xFF, 0x00, 0x00) -#define ColorGreen Rgb32(0x00, 0xFF, 0x00) -#define ColorBlue Rgb32(0x00, 0x00, 0xFF) -#define ColorYellow Rgb32(0xFF, 0xFF, 0x00) -#define ColorOrange Rgb32(0xFF, 0xA5, 0x00) -#define ColorPurple Rgb32(0xFF, 0x00, 0XFF) - -//////////////////////////////// -//~ Gpu helpers - -#if LanguageIsGpu -//- Resource heap index -# define GpuResourceFromUrid(urid) ResourceDescriptorHeap[urid] -# define GpuResourceFromNurid(nurid) ResourceDescriptorHeap[NonUniformResourceIndex(nurid)] - -//- Semantic declaration -# define Semantic(t, n) t n : n -#endif - -//////////////////////////////// -//~ Intrinsic headers - -#if LanguageIsC -/* Intrinsic header info: - * field) - -//- countof -#define countof(a) (sizeof(a) / sizeof((a)[0])) - -//- IsArray -#define IsIndexable(a) (sizeof(a[0]) != 0) -#define IsArray(a) (IsIndexable(a) && (((void *)&a) == ((void *)a))) - -//- offsetof -#if 0 -#if !CompilerIsMsvc -# if !defined _CRT_USE_BUILTIN_OFFSETOF -# define offsetof(type, field) ((u64)&(((type *)0)->field)) -# else -# define offsetof(type, field) __builtin_offsetof(type, field) -# endif -#endif -#endif - -//////////////////////////////// -//~ Scalar types - -#if LanguageIsC -//- Cpu scalar types -#include "stdint.h" -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef float f32; -typedef double f64; -typedef i8 b8; -typedef u32 b32; -#else -//- Gpu scalar types -typedef int i32; -typedef uint u32; -typedef float f32; -typedef uint b32; -#endif - -//- Min / max constants -#define U8Max (0xFF) -#define U16Max (0xFFFF) -#define U32Max (0xFFFFFFFF) -#define U64Max (0xFFFFFFFFFFFFFFFFULL) - -#define I8Max (0x7F) -#define I16Max (0x7FFF) -#define I32Max (0x7FFFFFFF) -#define I64Max (0x7FFFFFFFFFFFFFFFLL) - -#define I8Min ((i8)-0x80) -#define I16Min ((i16)0x8000) -#define I32Min ((i32)0x80000000) -#define I64Min ((i64)0x8000000000000000LL) - -//- Float infinity / nan constants -#if LanguageIsC -Global const u32 _f32_infinity_u32 = 0x7f800000; -Global const f32 *_f32_infinity = (f32 *)&_f32_infinity_u32; -#define F32Infinity (*_f32_infinity) - -Global const u64 _f64_infinity_u64 = 0x7ff0000000000000ULL; -Global const f64 *_f64_infinity = (f64 *)&_f64_infinity_u64; -#define F64Infinity (*_f64_infinity) - -Global const u32 _f32_nan_u32 = 0x7f800001; -Global const f32 *_f32_nan = (f32 *)&_f32_nan_u32; -#define F32Nan (*_f32_nan) - -Global const u64 _f64_nan_u64 = 0x7ff8000000000001; -Global const f64 *_f64_nan = (f64 *)&_f64_nan_u64; -#define F64Nan (*_f64_nan) - -#define IsF32Nan(x) (x != x) -#define IsF64Nan(x) (x != x) -#endif - -//////////////////////////////// -//~ Atomics - -#if LanguageIsC - -//- Atomic types -Struct(Atomic8) { volatile i8 _v; }; -Struct(Atomic16) { volatile i16 _v; }; -Struct(Atomic32) { volatile i32 _v; }; -Struct(Atomic64) { volatile i64 _v; }; - -//- Cache-line isolated aligned atomic types -AlignedStruct(Atomic8Padded, 64) { Atomic8 v; u8 _pad[63]; }; -AlignedStruct(Atomic16Padded, 64) { Atomic16 v; u8 _pad[62]; }; -AlignedStruct(Atomic32Padded, 64) { Atomic32 v; u8 _pad[60]; }; -AlignedStruct(Atomic64Padded, 64) { Atomic64 v; u8 _pad[56]; }; -StaticAssert(sizeof(Atomic8Padded) == 64 && alignof(Atomic8Padded) == 64); -StaticAssert(sizeof(Atomic16Padded) == 64 && alignof(Atomic16Padded) == 64); -StaticAssert(sizeof(Atomic32Padded) == 64 && alignof(Atomic32Padded) == 64); -StaticAssert(sizeof(Atomic64Padded) == 64 && alignof(Atomic64Padded) == 64); - -#if PlatformIsWindows -//- 8 bit atomic operations -ForceInline i8 Atomic8Fetch(Atomic8 *x) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, 0, 0); } -ForceInline i8 Atomic8FetchSet(Atomic8 *x, i8 e) { return (i8)_InterlockedExchange8((char *)&x->_v, e); } -ForceInline i8 Atomic8FetchTestSet(Atomic8 *x, i8 c, i8 e) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, e, c); } -ForceInline i8 Atomic8FetchXor(Atomic8 *x, i8 c) { return (i8)_InterlockedXor8((char *)&x->_v, c); } -ForceInline i8 Atomic8FetchAdd(Atomic8 *x, i8 a) { return (i8)_InterlockedExchangeAdd8((char *)&x->_v, a); } -//- 16 bit atomic operations -ForceInline i16 Atomic16Fetch(Atomic16 *x) { return (i16)_InterlockedCompareExchange16(&x->_v, 0, 0); } -ForceInline i16 Atomic16FetchSet(Atomic16 *x, i16 e) { return (i16)_InterlockedExchange16(&x->_v, e); } -ForceInline i16 Atomic16FetchTestSet(Atomic16 *x, i16 c, i16 e) { return (i16)_InterlockedCompareExchange16(&x->_v, e, c); } -ForceInline i16 Atomic16FetchTestXor(Atomic16 *x, i16 c) { return (i16)_InterlockedXor16(&x->_v, c); } -ForceInline i16 Atomic16FetchTestAdd(Atomic16 *x, i16 a) { return (i16)_InterlockedExchangeAdd16(&x->_v, a); } -//- 32 bit atomic operations -ForceInline i32 Atomic32Fetch(Atomic32 *x) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, 0, 0); } -ForceInline i32 Atomic32FetchSet(Atomic32 *x, i32 e) { return (i32)_InterlockedExchange((volatile long *)&x->_v, e); } -ForceInline i32 Atomic32FetchTestSet(Atomic32 *x, i32 c, i32 e) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, e, c); } -ForceInline i32 Atomic32FetchXor(Atomic32 *x, i32 c) { return (i32)_InterlockedXor((volatile long *)&x->_v, c); } -ForceInline i32 Atomic32FetchAdd(Atomic32 *x, i32 a) { return (i32)_InterlockedExchangeAdd((volatile long *)&x->_v, a); } -//- 64 bit atomic operations -ForceInline i64 Atomic64Fetch(Atomic64 *x) { return (i64)_InterlockedCompareExchange64(&x->_v, 0, 0); } -ForceInline i64 Atomic64FetchSet(Atomic64 *x, i64 e) { return (i64)_InterlockedExchange64(&x->_v, e); } -ForceInline i64 Atomic64FetchTestSet(Atomic64 *x, i64 c, i64 e) { return (i64)_InterlockedCompareExchange64(&x->_v, e, c); } -ForceInline i64 Atomic64FetchXor(Atomic64 *x, i64 c) { return (i64)_InterlockedXor64(&x->_v, c); } -ForceInline i64 Atomic64FetchAdd(Atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_v, a); } -#else -# error Atomics not implemented -#endif - -#endif - -//////////////////////////////// -//~ Ticket mutex - -#if LanguageIsC -Struct(TicketMutex) -{ - Atomic64Padded ticket; - Atomic64Padded serving; -}; - -ForceInline void LockTicketMutex(TicketMutex *tm) -{ - i64 ticket = Atomic64FetchAdd(&tm->ticket.v, 1); - while (Atomic64Fetch(&tm->serving.v) != ticket) - { - _mm_pause(); - } -} - -ForceInline void UnlockTicketMutex(TicketMutex *tm) -{ - Atomic64FetchAdd(&tm->serving.v, 1); -} -#endif - -//////////////////////////////// -//~ String utils - -#define STRING(size, data) ((String) { (size), (data) }) -#define Lit(cstr_lit) (String) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) } -#define LitNoCast(cstr_lit) { .len = (sizeof((cstr_lit)) - 1), .text = (u8 *)(cstr_lit) } -#define StringFromPointers(p0, p1) ((String) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 }) -#define StringFromStruct(ptr) ((String) { sizeof(*(ptr)), (u8 *)(ptr) }) -#define StringFromArena(arena) (STRING((arena)->pos, ArenaBase(arena))) - -/* String from static array */ -#define StringFromArray(a) \ - ( \ - Assert(IsArray(a)), \ - ((String) { .len = sizeof(a), .text = (u8 *)(a) }) \ - ) - -Struct(String) -{ - u64 len; - u8 *text; -}; - -Struct(String16) -{ - u64 len; - u16 *text; -}; - -Struct(String32) -{ - u64 len; - u32 *text; -}; - -//////////////////////////////// -//~ Fibers - -#define MaxFibers 1024 - -#if LanguageIsC -# if PlatformIsWindows -ForceInline i16 FiberId(void) -{ - i16 *v = (void *)(u64)__readgsqword(32); - return *v; -} -# else -# error FiberId not implemented -# endif -StaticAssert(MaxFibers < I16Max); /* Fiber id type should fit max fibers */ -#endif - -//////////////////////////////// -//~ @hookdecl Core hooks - -void StartupBase(void); -b32 Panic(String msg); -b32 IsRunningInDebugger(void); -i16 ThreadId(void); -void TrueRand(String buffer); - -#define MaxThreads 1024 -StaticAssert(MaxThreads < I16Max); /* Thread id type should fit max threads */ - -//////////////////////////////// -//~ @hookdecl Layer startup hook (defined by meta program) - -void StartupLayers(void); - -//////////////////////////////// -//~ Prof - -#include "../prof/prof_tracy.h" - -//////////////////////////////// -//~ Config - -#include "../config.h" diff --git a/src/meta/meta_base/meta_base_arena.c b/src/meta/meta_base/meta_base_arena.c deleted file mode 100644 index 4efc4226..00000000 --- a/src/meta/meta_base/meta_base_arena.c +++ /dev/null @@ -1,139 +0,0 @@ -SharedArenaCtx shared_arena_ctx = ZI; - -/* NOTE: Application will exit if arena fails to reserve or commit initial memory. */ -Arena *AcquireArena(u64 reserve) -{ - __prof; - reserve += ArenaHeaderSize; - - /* Round up to nearest block size */ - u64 block_remainder = reserve % ArenaBlockSize; - if (block_remainder > 0) - { - reserve += ArenaBlockSize - block_remainder; - } - - u8 *base = ReserveMemory(reserve); - if (!base) - { - /* Hard fail on memory reserve failure for now */ - Panic(Lit("Failed to reserve memory")); - } - u64 reserved = reserve; - - /* Commit initial block */ - base = CommitMemory(base, ArenaBlockSize); - if (!base) - { - /* Hard fail on commit failure */ - Panic(Lit("Failed to commit initial memory block: System may be out of memory")); - } - - Assert(((u64)base & 0xFFF) == 0); /* Base should be 4k aligned */ - StaticAssert(ArenaHeaderSize <= ArenaBlockSize); /* Header must fit in first block */ - StaticAssert(sizeof(Arena) <= ArenaHeaderSize); /* Arena struct must fit in header */ - - __profalloc(base, ArenaBlockSize); - AsanPoison(base + sizeof(Arena), ArenaBlockSize - sizeof(Arena)); - - /* Create & return arena header at beginning of block */ - Arena *arena = (Arena *)base; - ZeroStruct(arena); - arena->committed = ArenaBlockSize - ArenaHeaderSize; - arena->reserved = reserved; - return arena; -} - -void ReleaseArena(Arena *arena) -{ - AsanUnpoison(arena, arena->committed + ArenaHeaderSize); - __prof; - __proffree(arena); - ReleaseMemory(arena); -} - -/* NOTE: Application will exit if arena fails to commit memory */ -void *PushBytesNoZero(Arena *arena, u64 size, u64 align) -{ - Assert(align > 0); - Assert(!arena->readonly); - - void *ptr = 0; - u8 *base = ArenaBase(arena); - - /* Check to avoid aligning when size = 0 */ - if (size > 0) - { - u64 aligned_start_pos = (arena->pos + (align - 1)); - aligned_start_pos -= aligned_start_pos % align; - - u64 new_pos = aligned_start_pos + size; - if (new_pos > arena->committed) - { - __profn("Arena commit"); - /* Commit new block(s) */ - u64 blocks_needed = (new_pos - arena->committed + ArenaBlockSize - 1) / ArenaBlockSize; - u64 commit_bytes = blocks_needed * ArenaBlockSize; - u64 new_capacity = arena->committed + commit_bytes; - if (new_capacity > arena->reserved) - { - /* Hard fail if we overflow reserved memory for now */ - Panic(Lit("Failed to commit new memory block: Overflow of reserved memory")); - } - void *commit_address = base + arena->committed; - if (!CommitMemory(commit_address, commit_bytes)) - { - /* Hard fail on memory allocation failure for now */ - Panic(Lit("Failed to commit new memory block: System may be out of memory")); - } - arena->committed += commit_bytes; - __proffree(arena); - __profalloc(arena, arena->committed + ArenaHeaderSize); - AsanPoison(commit_address, commit_bytes); - } - - ptr = base + aligned_start_pos; - AsanUnpoison(ptr, new_pos - aligned_start_pos); - arena->pos = new_pos; - } - else - { - ptr = base + arena->pos; - } - - return ptr; -} - -/* Copies the memory from the source arena into the destination arena, - * replacing old contents. Destination arena will be expanded if necessary. */ -void CopyArena(Arena *dst, Arena *src) -{ - ResetArena(dst); - u64 data_size = src->pos; - u8 *data_src = ArenaBase(src); - u8 *data_dst = PushBytesNoZero(dst, data_size, 1); - CopyBytes(data_dst, data_src, data_size); -} - -void ShrinkArena(Arena *arena) -{ - /* Not implemented */ - Assert(0); - LAX arena; -} - -void SetArenaReadonly(Arena *arena) -{ -#if RtcIsEnabled - arena->readonly = 1; -#endif - SetMemoryReadonly(arena, arena->committed + ArenaHeaderSize); -} - -void SetArenaReadWrite(Arena *arena) -{ - SetMemoryReadWrite(arena, arena->committed + ArenaHeaderSize); -#if RtcIsEnabled - arena->readonly = 0; -#endif -} diff --git a/src/meta/meta_base/meta_base_arena.h b/src/meta/meta_base/meta_base_arena.h deleted file mode 100644 index 8671aeb2..00000000 --- a/src/meta/meta_base/meta_base_arena.h +++ /dev/null @@ -1,260 +0,0 @@ -//////////////////////////////// -//~ Arena types - -#define ArenaHeaderSize 64 -#define ArenaBlockSize 16384 - -Struct(Arena) -{ - u64 pos; - u64 committed; - u64 reserved; -#if RtcIsEnabled - b32 readonly; -#endif -}; - -Struct(TempArena) -{ - Arena *arena; - u64 start_pos; - -#if RtcIsEnabled - u64 scratch_id; -#endif -}; - -//////////////////////////////// -//~ Per-thread arena ctx types - -#define ScratchArenasPerCtx 2 - -Struct(ArenaCtx) -{ - Arena *scratch_arenas[ScratchArenasPerCtx]; - Arena *perm_arena; -}; - -//////////////////////////////// -//~ Shared state - -Struct(SharedArenaCtx) -{ - ArenaCtx arena_contexts[MaxThreads]; -}; - -extern SharedArenaCtx shared_arena_ctx; - -//////////////////////////////// -//~ Arena push/pop - -#define PushStruct(a, type) ((type *)PushBytes((a), sizeof(type), alignof(type))) -#define PushStructNoZero(a, type) ((type *)PushBytesNoZero((a), sizeof(type), alignof(type))) - -#define PushStructs(a, type, n) ((type *)PushBytes((a), (sizeof(type) * (n)), alignof(type))) -#define PushStructsNoZero(a, type, n) ((type *)PushBytesNoZero((a), (sizeof(type) * (n)), alignof(type))) - -#define PopStruct(a, type, dst) PopBytes((a), sizeof(type), dst) -#define PopStructs(a, type, n, dst) PopBytes((a), sizeof(type) * (n), dst) - -#define PopStructNoCopy(a, type) PopBytesNoCopy((a), sizeof(type)) -#define PopStructsNoCopy(a, type, n) PopBytesNoCopy((a), sizeof(type) * (n)) - -/* Returns a pointer to where the next push would be (at alignment of type). - * Equivalent to PushStruct but without actually allocating anything or modifying the arena. */ -#define PushDry(a, type) (type *)(_PushDry((a), alignof(type))) - -void *PushBytesNoZero(Arena *arena, u64 size, u64 align); - -Inline void *PushBytes(Arena *arena, u64 size, u64 align) -{ - void *p = PushBytesNoZero(arena, size, align); - ZeroBytes(p, size); - return p; -} - -Inline u8 *ArenaBase(Arena *arena) -{ - return (u8 *)arena + ArenaHeaderSize; -} - -Inline void PopTo(Arena *arena, u64 pos) -{ - Assert(arena->pos >= pos); - Assert(!arena->readonly); - - AsanPoison(ArenaBase(arena) + pos, arena->pos - pos); - arena->pos = pos; -} - -Inline void PopBytesNoCopy(Arena *arena, u64 size) -{ - Assert(arena->pos >= size); - Assert(!arena->readonly); - u64 new_pos = arena->pos - size; - AsanPoison(ArenaBase(arena) + new_pos, arena->pos - new_pos); - arena->pos = new_pos; -} - -Inline void PopBytes(Arena *arena, u64 size, void *copy_dst) -{ - Assert(arena->pos >= size); - Assert(!arena->readonly); - - u64 new_pos = arena->pos - size; - void *src = (void *)(ArenaBase(arena) + new_pos); - CopyBytes(copy_dst, src, size); - - AsanPoison(ArenaBase(arena) + new_pos, arena->pos - new_pos); - arena->pos = new_pos; -} - -Inline void *_PushDry(Arena *arena, u64 align) -{ - u64 aligned_start_pos = (arena->pos + (align - 1)); - aligned_start_pos -= aligned_start_pos % align; - void *ptr = ArenaBase(arena) + aligned_start_pos; - return ptr; -} - -//////////////////////////////// -//~ Arena management - -Arena *AcquireArena(u64 reserve); -void ReleaseArena(Arena *arena); - -void CopyArena(Arena *dst, Arena *src); -void ShrinkArena(Arena *arena); -void SetArenaReadonly(Arena *arena); -void SetArenaReadWrite(Arena *arena); - -Inline void *AlignArena(Arena *arena, u64 align) -{ - Assert(!arena->readonly); - if (align > 0) - { - u64 aligned_start_pos = (arena->pos + (align - 1)); - aligned_start_pos -= aligned_start_pos % align; - u64 align_bytes = aligned_start_pos - (u64)arena->pos; - if (align_bytes > 0) - { - return (void *)PushStructsNoZero(arena, u8, align_bytes); - } - else - { - return (void *)(ArenaBase(arena) + arena->pos); - } - } - else - { - /* 0 alignment */ - Assert(0); - return (void *)(ArenaBase(arena) + arena->pos); - } -} - -Inline void *ResetArena(Arena *arena) -{ - PopTo(arena, 0); - return (void *)ArenaBase(arena); -} - -//////////////////////////////// -//~ Temp arena operations - -Inline TempArena BeginTempArena(Arena *arena) -{ - TempArena t = ZI; - t.arena = arena; - t.start_pos = arena->pos; - return t; -} - -Inline void EndTempArena(TempArena temp) -{ - PopTo(temp.arena, temp.start_pos); -} - -//////////////////////////////// -//~ Arena ctx operations - -Inline ArenaCtx *ArenaCtxFromThreadId(i16 thread_id) -{ - SharedArenaCtx *shared = &shared_arena_ctx; - ArenaCtx *ctx = &shared->arena_contexts[thread_id]; - if (!ctx->scratch_arenas[0]) - { - __profn("Initialize thread arena ctx"); - for (i32 i = 0; i < (i32)countof(ctx->scratch_arenas); ++i) - { - ctx->scratch_arenas[i] = AcquireArena(Gibi(64)); - } - ctx->perm_arena = AcquireArena(Gibi(64)); - } - return ctx; -} - -//////////////////////////////// -//~ Scratch helpers - -/* Any parameterized arenas in the caller's scope should be passed into this - * function as a potential "conflict". This is to prevent friction in case the - * passed arena is itself a scratch arena from another scope (since - * parameterized arenas are often used to allocate persistent results for the - * caller). - * - * Use `BeginScratchNoConflict` instead if there is no arena in the current - * scope that could potentially be a scratch arena from another scope. */ -#define BeginScratch(potential_conflict) _BeginScratch(potential_conflict) - -Inline TempArena _BeginScratch(Arena *potential_conflict) -{ - /* This function is currently hard-coded to support 2 scratch arenas */ - StaticAssert(ScratchArenasPerCtx == 2); - - /* Use `BeginScratchNoConflict` if no conflicts are present */ - Assert(potential_conflict != 0); - - ArenaCtx *ctx = ArenaCtxFromThreadId(ThreadId()); - Arena *scratch_arena = ctx->scratch_arenas[0]; - if (potential_conflict && scratch_arena == potential_conflict) - { - scratch_arena = ctx->scratch_arenas[1]; - } - TempArena temp = BeginTempArena(scratch_arena); - return temp; -} - -/* This macro declares an unused "arena" variable that will error if an existing "arena" - * variable is present (due to shadowing). This is for catching obvious cases of - * `BeginScratchNoConflict` getting called when an `arena` variable already - * exists in the caller's scope (`BeginScratch(arena)` should be called - * instead). */ -#define BeginScratchNoConflict() \ - BeginScratchNoConflict_(); \ - do { \ - u8 arena = 0; \ - LAX arena; \ - } while (0) - -Inline TempArena BeginScratchNoConflict_(void) -{ - ArenaCtx *ctx = ArenaCtxFromThreadId(ThreadId()); - Arena *scratch_arena = ctx->scratch_arenas[0]; - TempArena temp = BeginTempArena(scratch_arena); - return temp; -} - -Inline void EndScratch(TempArena scratch_temp) -{ - EndTempArena(scratch_temp); -} - -//////////////////////////////// -//~ Perm arena helpers - -Inline Arena *GetPermArena(void) -{ - ArenaCtx *ctx = ArenaCtxFromThreadId(ThreadId()); - return ctx->perm_arena; -} diff --git a/src/meta/meta_base/meta_base_inc.h b/src/meta/meta_base/meta_base_inc.h deleted file mode 100644 index b075523d..00000000 --- a/src/meta/meta_base/meta_base_inc.h +++ /dev/null @@ -1,23 +0,0 @@ -//- Header files -#include "meta_base.h" -#include "meta_base_intrinsics.h" -#include "meta_base_memory.h" -#include "meta_base_arena.h" -#include "meta_base_math.h" -#include "meta_base_rand.h" -#include "meta_base_uni.h" -#include "meta_base_string.h" -#include "meta_base_util.h" - -//- Source files -#include "meta_base_arena.c" -#include "meta_base_math.c" -#include "meta_base_memory.c" -#include "meta_base_string.c" -#include "meta_base_uni.c" -#include "meta_base_rand.c" - -//- Win32 -#if PlatformIsWindows -# include "meta_base_win32/meta_base_win32_inc.h" -#endif diff --git a/src/meta/meta_base/meta_base_intrinsics.h b/src/meta/meta_base/meta_base_intrinsics.h deleted file mode 100644 index eb0f3213..00000000 --- a/src/meta/meta_base/meta_base_intrinsics.h +++ /dev/null @@ -1,105 +0,0 @@ -//////////////////////////////// -//~ Sqrt intrinsics - -Inline f32 IxSqrtF32(f32 f) -{ - __m128 n = _mm_set_ss(f); - n = _mm_sqrt_ss(n); - return _mm_cvtss_f32(n); -} - -Inline f64 IxSqrtF64(f64 f) -{ - __m128d n = _mm_set_sd(f); - n = _mm_sqrt_sd(_mm_setzero_pd(), n); - return _mm_cvtsd_f64(n); -} - -Inline f32 IxRsqrtF32(f32 f) -{ - __m128 n = _mm_set_ss(f); - n = _mm_rsqrt_ss(n); - return _mm_cvtss_f32(n); -} - -//////////////////////////////// -//~ Round intrinsics - -Inline i32 IxRoundF32ToI32(f32 f) -{ - return _mm_cvtss_si32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC)); -} - -Inline f32 IxRoundF32ToF32(f32 f) -{ - return _mm_cvtss_f32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC)); -} - -Inline i64 IxRoundF64ToI64(f64 f) -{ - return _mm_cvtsd_si64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC)); -} - -Inline f64 IxRoundF64ToF64(f64 f) -{ - return _mm_cvtsd_f64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC)); -} - -//////////////////////////////// -//~ Floor intrinsics - -Inline i32 IxFloorF32ToI32(f32 f) -{ - return _mm_cvtss_si32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f))); -} - -Inline f32 IxFloorF32ToF32(f32 f) -{ - return _mm_cvtss_f32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f))); -} - -Inline i64 IxFloorF64ToI64(f64 f) -{ - return _mm_cvtsd_si64(_mm_floor_sd(_mm_setzero_pd(), _mm_set_sd(f))); -} - -Inline f64 IxFloorF64ToF64(f64 f) -{ - return _mm_cvtsd_f64(_mm_floor_sd(_mm_setzero_pd(), _mm_set_sd(f))); -} - -//////////////////////////////// -//~ Ceil intrinsics - -Inline i32 IxCeilF32ToI32(f32 f) -{ - return _mm_cvtss_si32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f))); -} - -Inline f32 IxCeilF32ToF32(f32 f) -{ - return _mm_cvtss_f32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f))); -} - -Inline i64 IxCeilF64ToI64(f64 f) -{ - return _mm_cvtsd_si64(_mm_ceil_sd(_mm_setzero_pd(), _mm_set_sd(f))); -} - -Inline f64 IxCeilF64ToF64(f64 f) -{ - return _mm_cvtsd_f64(_mm_ceil_sd(_mm_setzero_pd(), _mm_set_sd(f))); -} - -//////////////////////////////// -//~ Truncate intrinsics - -Inline f32 IxTruncF32ToF32(f32 f) -{ - return _mm_cvtss_f32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC)); -} - -Inline f64 IxTruncF64ToF64(f64 f) -{ - return _mm_cvtsd_f64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC)); -} diff --git a/src/meta/meta_base/meta_base_math.c b/src/meta/meta_base/meta_base_math.c deleted file mode 100644 index edc74d78..00000000 --- a/src/meta/meta_base/meta_base_math.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* Math functions are default 32 bit (f32, i32, etc) unless specified */ - -//////////////////////////////// -//~ Min / max - -//- Min -u8 MinU8(u8 a, u8 b) { return a <= b ? a : b; } -i8 MinI8(i8 a, i8 b) { return a <= b ? a : b; } -u32 MinU32(u32 a, u32 b) { return a <= b ? a : b; } -i32 MinI32(i32 a, i32 b) { return a <= b ? a : b; } -f32 MinF32(f32 a, f32 b) { return a <= b ? a : b; } -u64 MinU64(u64 a, u64 b) { return a <= b ? a : b; } -i64 MinI64(i64 a, i64 b) { return a <= b ? a : b; } -f64 MinF64(f64 a, f64 b) { return a <= b ? a : b; } - -//- Max -u8 MaxU8(u8 a, u8 b) { return a >= b ? a : b; } -i8 MaxI8(i8 a, i8 b) { return a >= b ? a : b; } -u32 MaxU32(u32 a, u32 b) { return a >= b ? a : b; } -i32 MaxI32(i32 a, i32 b) { return a >= b ? a : b; } -f32 MaxF32(f32 a, f32 b) { return a >= b ? a : b; } -u64 MaxU64(u64 a, u64 b) { return a >= b ? a : b; } -i64 MaxI64(i64 a, i64 b) { return a >= b ? a : b; } -f64 MaxF64(f64 a, f64 b) { return a >= b ? a : b; } - -//- Clamp -u32 ClampU32(u32 v, u32 min, u32 max) { return v < min ? min : v > max ? max : v; } -i32 ClampI32(i32 v, i32 min, i32 max) { return v < min ? min : v > max ? max : v; } -f32 ClampF32(f32 v, f32 min, f32 max) { return v < min ? min : v > max ? max : v; } -u64 ClampU64(u64 v, u64 min, u64 max) { return v < min ? min : v > max ? max : v; } -i64 ClampI64(i64 v, i64 min, i64 max) { return v < min ? min : v > max ? max : v; } -f64 ClampF64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ? max : v; } - -//////////////////////////////// -//~ Rounding ops - -//- Round -f32 RoundF32(f32 f) -{ - return IxRoundF32ToF32(f); -} - -f64 RoundF64(f64 f) -{ - return IxRoundF64ToF64(f); -} - -i32 RoundF32ToI32(f32 f) -{ - return IxRoundF32ToI32(f); -} - -i64 RoundF64ToI64(f64 f) -{ - return IxRoundF64ToI64(f); -} - -//- Floor -f32 FloorF32(f32 f) -{ - return IxFloorF32ToF32(f); -} - -f64 FloorF64(f64 f) -{ - return IxFloorF64ToF64(f); -} - -i32 FloorF32ToI32(f32 f) -{ - return IxFloorF32ToI32(f); -} - -i64 FloorF64ToI64(f64 f) -{ - return IxFloorF64ToI64(f); -} - -//- Ceil -f32 CeilF32(f32 f) -{ - return IxCeilF32ToF32(f); -} - -f64 CeilF64(f64 f) -{ - return IxCeilF64ToF64(f); -} - -i32 CeilF32ToI32(f32 f) -{ - return IxCeilF32ToI32(f); -} - -i64 CeilF64ToI64(f64 f) -{ - return IxCeilF64ToI64(f); -} - -//- Trunc -f32 TruncF32(f32 f) -{ - return IxTruncF32ToF32(f); -} - -f64 TruncF64(f64 f) -{ - return IxTruncF64ToF64(f); -} - -//////////////////////////////// -//~ Fmod - -f32 ModF32(f32 x, f32 m) -{ - return x - m * TruncF32(x / m); -} - -f64 ModF64(f64 x, f64 m) -{ - return x - m * TruncF64(x / m); -} - -//////////////////////////////// -//~ Floating point sign - -f32 AbsF32(f32 f) -{ - u32 truncated = *(u32 *)&f & 0x7FFFFFFF; - return *(f32 *)&truncated; -} - -f64 AbsF64(f64 f) -{ - u64 truncated = *(u64 *)&f & 0x7FFFFFFFFFFFFFFFULL; - return *(f64 *)&truncated; -} - -u32 AbsI32(i32 v) -{ - return (u32)(v * ((v >= 0) - (v < 0))); -} - -u64 AbsI64(i64 v) -{ - return (u64)(v * ((v >= 0) - (v < 0))); -} - -i32 SignF32(f32 f) -{ - u32 sign_bit = (*(u32 *)&f >> 31) & 1; - return 1 + -((i32)(sign_bit << 1)); -} - -i64 SignF64(f64 f) -{ - u64 sign_bit = (*(u64 *)&f >> 63) & 1; - return 1 + -((i64)(sign_bit << 1)); -} - -//////////////////////////////// -//~ U64 pow - -/* Taken from https://gist.github.com/orlp/3551590 */ -u64 PowU64(u64 base, u8 exp) -{ - LocalPersist const u8 highest_bit_set[] = { - 0, 1, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 255, /* Anything past 63 is a guaranteed overflow with base > 1 */ - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - }; - - u64 result = 1; - - switch (highest_bit_set[exp]) - { - case 255: - { - /* 255 = overflow, return 0 */ - if (base == 1) - { - return 1; - } - // if (base == -1) - // { - // return 1 - 2 * (exp & 1); - // } - return 0; - } break; - case 6: - { - if (exp & 1) result *= base; - exp >>= 1; - base *= base; - } FALLTHROUGH; - case 5: - { - if (exp & 1) result *= base; - exp >>= 1; - base *= base; - } FALLTHROUGH; - case 4: - { - if (exp & 1) result *= base; - exp >>= 1; - base *= base; - } FALLTHROUGH; - case 3: - { - if (exp & 1) result *= base; - exp >>= 1; - base *= base; - } FALLTHROUGH; - case 2: - { - if (exp & 1) result *= base; - exp >>= 1; - base *= base; - } FALLTHROUGH; - case 1: - { - if (exp & 1) result *= base; - } FALLTHROUGH; - default: return result; - } -} - -//////////////////////////////// -//~ Align up - -u64 AlignU64Pow2(u64 x) -{ - u64 result = 0; - if (x > 0) - { - result = x - 1; - result |= result >> 1; - result |= result >> 2; - result |= result >> 4; - result |= result >> 8; - result |= result >> 16; - result |= result >> 32; - ++result; - } - return result; -} - -//////////////////////////////// -//~ Logn - -/* Based on FreeBSD's implementation - * https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_logf.c */ -f32 LnF32(f32 x) -{ - LocalPersist const f32 ln2_hi = 6.9313812256e-01f; - LocalPersist const f32 ln2_lo = 9.0580006145e-06f; - - i32 x_int = *(i32 *)&x; - - i32 k = 0; - if (x_int < 0x00800000) - { - f32 two_p25 = 3.3554432000e+07; - if ((x_int & 0x7fffffff) == 0) - { - /* Return -inf if x is 0 */ - return -F32Infinity; - } - else if (x_int < 0) - { - /* Return NaN if x is negative */ - return F32Nan; - } - k -= 25; - x *= two_p25; - x_int = *(i32 *)&x; - } - else if (x_int >= 0x7f800000) - { - return x + x; - } - - k += (x_int >> 23) - 127; - x_int &= 0x007fffff; - i32 i = (x_int + (0x95f64 << 3)) & 0x800000; - i32 x_int_normalized = x_int | (i ^ 0x3f800000); - x = *(f32 *)&x_int_normalized - 1.0f; - k += (i >> 23); - - if ((0x007fffff & (0x8000 + x_int)) < 0xc000) - { - if (x == 0) - { - if (k == 0) - { - return 0; - } - else - { - return (f32)k * ln2_hi + (f32)k * ln2_lo; - } - } - f32 r = x * x * (0.5f - 0.33333333333333333f * x); - if (k == 0) - { - return x - r; - } - else - { - return (f32)k * ln2_hi - ((r - (f32)k * ln2_lo) - x); - } - } - - f32 s = x / (2.0f + x); - f32 z = s * s; - f32 w = z * z; - f32 r = (z * (0.66666662693f + w * 0.28498786688f)) + (w * (0.40000972152f + w * 0.24279078841f)); - if (((x_int - (0x6147a << 3)) | ((0x6b851 << 3) - x_int)) > 0) - { - f32 hfsq = 0.5f * x * x; - if (k == 0) - { - return x - (hfsq - s * (hfsq + r)); - } - else - { - return (f32)k * ln2_hi - ((hfsq - (s * (hfsq + r) + (f32)k * ln2_lo)) - x); - } - } - else - { - if (k == 0) - { - return x - s * (x - r); - } - else - { - return (f32)k * ln2_hi - ((s * (x - r) - (f32)k * ln2_lo) - x); - } - } -} - -//////////////////////////////// -//~ Exp - -/* Based on FreeBSD's implementation - * https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_expf.c */ -f32 ExpF32(f32 x) -{ - LocalPersist const f32 half[2] = { 0.5, -0.5 }; - LocalPersist const f32 o_threshold = 8.8721679688e+01f; - LocalPersist const f32 u_threshold = -1.0397208405e+02f; - LocalPersist const f32 ln2_hi[2] = { 6.9314575195e-01f, -6.9314575195e-01f }; - LocalPersist const f32 ln2_lo[2] = { 1.4286067653e-06f, -1.4286067653e-06f }; - LocalPersist const f32 inv_ln2 = 1.4426950216e+00f; - LocalPersist const f32 huge = 1.0e+30f; - LocalPersist const f32 two_m100 = 7.8886090522e-31f; - - u32 x_uint = *(u32 *)&x; - i32 x_sign_bit = (i32)((x_uint >> 31) & 1); - x_uint &= 0x7fffffff; - - /* Filter out non-finite argument */ - if (x_uint >= 0x42b17218) - { /* if |x| >= 88.721... */ - if (x_uint > 0x7f800000) - { - return x + x; /* NaN */ - } - else if (x_uint == 0x7f800000) - { - return (x_sign_bit == 0) ? x : 0; - } - if (x > o_threshold) - { - /* Overflow */ - return F32Infinity; - } - else if (x < u_threshold) - { - /* Underflow */ - return two_m100 * two_m100; - } - } - - /* Argument reduction */ - i32 k = 0; - f32 hi = 0; - f32 lo = 0; - if (x_uint > 0x3eb17218) - { - if (x_uint < 0x3F851592) - { - hi = x - ln2_hi[x_sign_bit]; - lo = ln2_lo[x_sign_bit]; - k = 1 - x_sign_bit - x_sign_bit; - } - else - { - k = (i32)(inv_ln2 * x + half[x_sign_bit]); - hi = x - (f32)k * ln2_hi[0]; - lo = (f32)k * ln2_lo[0]; - } - x = hi - lo; - } - else if (x_uint < 0x39000000) - { - if (huge + x > 1.0f) - { - return 1.0f + x; - } - } - else - { - k = 0; - } - - f32 two_pk; - if (k >= -125) - { - u32 temp = ((u32)(0x7f + k)) << 23; - two_pk = *(f32 *)&temp; - } - else - { - u32 temp = ((u32)(0x7f + (k + 100))) << 23; - two_pk = *(f32 *)&temp; - } - - f32 t = x * x; - f32 c = x - t * (1.6666625440e-1f + t * -2.7667332906e-3f); - if (k == 0) - { - return 1.0f - ((x * c) / (c - 2.0f) - x); - } - else - { - f32 y = 1.0f - ((lo - (x * c) / (2.0f - c)) - hi); - if (k >= -125) - { - if (k == 128) - { - u32 temp = 0x7f800000; - return y * 2.0f * (*(f32 *)&temp); - } - return y * two_pk; - } - else - { - return y * two_pk * two_m100; - } - } -} - -//////////////////////////////// -//~ Pow - -f32 PowF32(f32 a, f32 b) -{ - if (a >= 0) - { - /* a is positive */ - return ExpF32(LnF32(a) * b); - } - else - { - /* a is negative */ - f32 res_sign = RoundF32ToI32(b) % 2 == 0 ? 1 : -1; - return ExpF32(LnF32(-a) * b) * res_sign; - } -} - -//////////////////////////////// -//~ Sqrt - -f32 SqrtF32(f32 x) -{ - return IxSqrtF32(x); -} - -f64 SqrtF64(f64 x) -{ - return IxSqrtF64(x); -} - -f32 RSqrtF32(f32 x) -{ - return IxRsqrtF32(x); -} - -//////////////////////////////// -//~ Trig - -/* Functions based on Cephes implementation (https://www.netlib.org/cephes/): - * - SinApproxF32 - * - CosApproxF32 - * - ReduceToPio4 - * - ArcTanF32 - */ - -//- Reduce -/* Reduce postive x to range [0, Pi/4] (Cody-Waite argument reduction). - * Returns 0 if x > (2^24 - 1); - * Sets octant_out=-1 on error. */ -f32 ReduceToPio4(f32 x, i32 *octant_out) -{ - i32 octant = -1; - - if (x <= ((1 << 24) - 1)) - { - octant = x * (4 / Pi); /* Integer part of x/(Pi/4) */ - f32 y = octant; - if (octant & 1) - { - octant += 1; - y += 1.0; - } - - /* Modulo 360 degrees */ - octant &= 7; - - if (x > 8192) - { - x = x - y * (Pi / 4); - } - else - { - /* Extended precision modular arithmetic */ - x = ((x - y * 0.78515625) - y * 2.4187564849853515625e-4) - y * 3.77489497744594108e-8; - } - } - - *octant_out = octant; - return x; -} - -//- Sin approximation -/* Approximate sin in range [0, Pi/4] */ -f32 SinApproxF32(f32 x) -{ - f32 x_sq = x * x; - return (((-1.9515295891E-4 * x_sq + 8.3321608736E-3) * x_sq - 1.6666654611E-1) * x_sq * x) + x; -} - -//- Cos approximation -f32 CosApproxF32(f32 x) -{ - f32 x_sq = x * x; - return (((2.443315711809948E-005 * x_sq - 1.388731625493765E-003) * x_sq + 4.166664568298827E-002) * x_sq * x_sq) - (x_sq * 0.5) + 1; -} - -//- Sin -f32 SinF32(f32 x) -{ - f32 sign = 1; - - if (IsF32Nan(x)) - { - return 0; - } - else if (x < 0) - { - sign = -1; - x = -x; - } - - i32 octant; - x = ReduceToPio4(x, &octant); - - /* Reflect in x axis */ - if (octant > 3) - { - sign = -sign; - octant -= 4; - } - - switch (octant) - { - case -1: return 0; - case 1: case 2: return CosApproxF32(x) * sign; - default: return SinApproxF32(x) * sign; - } -} - -//- Cos -f32 CosF32(f32 x) -{ - f32 sign = 1; - - if (IsF32Nan(x)) - { - return 0; - } - else if (x < 0) - { - x = -x; - } - - i32 octant; - x = ReduceToPio4(x, &octant); - - /* Reflect in x axis */ - if (octant > 3) - { - sign = -sign; - octant -= 4; - } - - if (octant > 1) - { - sign = -sign; - } - - switch (octant) - { - case -1: return 0; - case 1: case 2: return SinApproxF32(x) * sign; - default: return CosApproxF32(x) * sign; - } -} - -//- ArcTan -f32 ArcTanF32(f32 x) -{ - f32 sign = 1; - if (x < 0) - { - sign = -1; - x = -x; - } - - /* Reduce range */ - f32 y; - if (x > 2.414213562373095) - { /* tan((Pi / 8) * 3) */ - y = Pi / 2; - x = -(1.f / x); - } - else if (x > 0.4142135623730950) - { /* tan(Pi / 8) */ - y = Pi / 4; - x = (x - 1.f) / (x + 1.f); - } - else - { - y = 0; - } - - f32 x_sq = x * x; - y += ((((8.05374449538e-2 * x_sq - 1.38776856032E-1) * x_sq + 1.99777106478E-1) * x_sq - 3.33329491539E-1) * x_sq * x + x); - - return y * sign; -} - -//- ArcTan2 -f32 ArcTan2F32(f32 y, f32 x) -{ - f32 result; - if (x == 0) - { - if (y < 0) - { - result = 3 * Pi / 2; - } - else if (y == 0) - { - result = 0; - } - else - { - result = Pi / 2; - } - } - else if (y == 0) - { - if (x < 0) - { - result = Pi; - } - else - { - result = 0; - } - } - else - { - f32 offset; - if (x < 0) - { - offset = Pi; - } - else if (y < 0) - { - offset = Pi * 2; - } - else - { - offset = 0; - } - result = ArcTanF32(y / x) + offset; - } - return result; -} - -//- ArcSin -f32 ArcSinF32(f32 x) -{ - /* TODO: Dedicated arcsin approximation */ - return ArcTan2F32(x, SqrtF32(1.0f - (x * x))); -} - -//- ArcCos -f32 ArcCosF32(f32 x) -{ - /* TODO: Dedicated arccos approximation */ - return (Pi / 2.0f) - ArcTan2F32(x, SqrtF32(1.0f - (x * x))); -} - -//////////////////////////////// -//~ Angle unwind - -/* Returns angle in range [-Pi, Pi] */ -f32 UnwindAngleF32(f32 a) -{ - f32 d = ModF32(a, Tau); - return ModF32(2.0f * d, Tau) - d; -} - -//////////////////////////////// -//~ Float lerp - -f32 LerpF32(f32 val0, f32 val1, f32 t) -{ - return val0 + ((val1 - val0) * t); -} - -f64 LerpF64(f64 val0, f64 val1, f64 t) -{ - return val0 + ((val1 - val0) * t); -} - -f32 LerpAngleF32(f32 a, f32 b, f32 t) -{ - f32 diff = UnwindAngleF32(b - a); - return a + diff * t; -} - -//////////////////////////////// -//~ Int lerp - -i32 LerpI32(i32 val0, i32 val1, f32 t) -{ - return val0 + RoundF32ToI32(((f32)(val1 - val0) * t)); -} - - -//- Lerp i64 -i64 LerpI64(i64 val0, i64 val1, f64 t) -{ - return val0 + RoundF64ToI64(((f64)(val1 - val0) * t)); -} - -//////////////////////////////// -//~ Vec2 operations - -b32 IsVec2Zero(Vec2 a) -{ - return a.x == 0 && a.y == 0; -} - -b32 EqVec2(Vec2 a, Vec2 b) -{ - return a.x == b.x && a.y == b.y; -} - -//- Mul - -Vec2 MulVec2(Vec2 a, f32 s) -{ - return VEC2(a.x * s, a.y * s); -} - -Vec2 MulVec2Vec2(Vec2 a, Vec2 b) -{ - return VEC2(a.x * b.x, a.y * b.y); -} - -Vec2 NegVec2(Vec2 a) -{ - return VEC2(-a.x, -a.y); -} - -//- Div - -Vec2 DivVec2(Vec2 a, f32 s) -{ - f32 d = 1 / s; - return VEC2(a.x * d, a.y * d); -} - -Vec2 DivVec2Vec2(Vec2 a, Vec2 b) -{ - return VEC2(a.x * (1 / b.x), a.y * (1 / b.y)); -} - -//- Add - -Vec2 AddVec2(Vec2 a, Vec2 b) -{ - return VEC2(a.x + b.x, a.y + b.y); -} - -Vec2 SubVec2(Vec2 a, Vec2 b) -{ - return VEC2(a.x - b.x, a.y - b.y); -} - -//- Len - -f32 Vec2Len(Vec2 a) -{ - return SqrtF32(a.x * a.x + a.y * a.y); -} - -f32 Vec2LenSq(Vec2 a) -{ - return a.x * a.x + a.y * a.y; -} - -Vec2 Vec2WithLen(Vec2 a, f32 len) -{ - f32 l_sq = a.x * a.x + a.y * a.y; - if (l_sq != 0) - { - f32 denom = len / SqrtF32(l_sq); - a.x *= denom; - a.y *= denom; - } - return a; -} - -Vec2 ClampVec2Len(Vec2 a, f32 max) -{ - f32 l_sq = a.x * a.x + a.y * a.y; - if (l_sq > max * max) - { - f32 denom = max / SqrtF32(l_sq); - a.x *= denom; - a.y *= denom; - } - return a; -} - -f32 Vec2Distance(Vec2 a, Vec2 b) -{ - f32 dx = b.x - a.x; - f32 dy = b.y - a.y; - return SqrtF32(dx * dx + dy * dy); -} - -Vec2 NormVec2(Vec2 a) -{ - return Vec2WithLen(a, 1.f); -} - - -//- Dot - -f32 DotVec2(Vec2 a, Vec2 b) -{ - return a.x * b.x + a.y * b.y; -} - -/* Returns signed area between vectors (positive in clockwise direction) - * AKA perpendicular dot product - * AKA 2d cross-product */ -f32 WedgeVec2(Vec2 a, Vec2 b) -{ - return a.x * b.y - a.y * b.x; -} - -/* Clockwise (right) perpendicular vector */ -Vec2 PerpVec2(Vec2 a) -{ - return VEC2(-a.y, a.x); -} - -/* Clockwise (right) perpendicular vector scaled by s */ -Vec2 MulPerpVec2(Vec2 a, f32 s) -{ - return VEC2(s * -a.y, s * a.x); -} - -Vec2 PerpVec2TowardsDir(Vec2 v, Vec2 dir) -{ - f32 wedge = WedgeVec2(v, dir); - return MulPerpVec2(v, (wedge >= 0) - (wedge < 0)); -} - -//- Round / floor / ceil - -Vec2 RoundVec2(Vec2 a) -{ - return VEC2(RoundF32(a.x), RoundF32(a.y)); -} - -Vec2I32 RoundVec2ToVec2I32(Vec2 a) -{ - return VEC2I32(RoundF32ToI32(a.x), RoundF32ToI32(a.y)); -} - -Vec2 FloorVec2(Vec2 a) -{ - return VEC2(FloorF32(a.x), FloorF32(a.y)); -} - -Vec2 CeilVec2(Vec2 a) -{ - return VEC2(CeilF32(a.x), CeilF32(a.y)); -} - -//- Angle - -/* Returns 1 if winding between vectors a & b is clockwise or straight, -1 if counter-clockwise */ -i32 WindingFromVec2(Vec2 a, Vec2 b) -{ - f32 w = WedgeVec2(a, b); - return (w >= 0) - (w < 0); -} - -Vec2 RotateVec2(Vec2 v, f32 a) -{ - f32 c = CosF32(a); - f32 s = SinF32(a); - return VEC2(v.x * c - v.y * s, v.x * s + v.y * c); -} - -Vec2 Vec2FromAngle(f32 a) -{ - return VEC2(CosF32(a), SinF32(a)); -} - -f32 AngleFromVec2(Vec2 v) -{ - return ArcTan2F32(v.y, v.x); -} - -f32 AngleFromVec2Dirs(Vec2 dir1, Vec2 dir2) -{ - return ArcTan2F32(WedgeVec2(dir1, dir2), DotVec2(dir1, dir2)); -} - -f32 AngleFromVec2Points(Vec2 pt1, Vec2 pt2) -{ - return AngleFromVec2(SubVec2(pt2, pt1)); -} - -//- Closest point - -Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p) -{ - Vec2 ray_p_dir = SubVec2(p, ray_pos); - f32 dot = DotVec2(ray_dir_norm, ray_p_dir); - Vec2 ray_dir_closest = MulVec2(ray_dir_norm, dot); - return AddVec2(ray_pos, ray_dir_closest); -} - -//- Lerp - -/* Interpolate position vectors */ -Vec2 LerpVec2(Vec2 val0, Vec2 val1, f32 t) -{ - return VEC2(LerpF32(val0.x, val1.x, t), LerpF32(val0.y, val1.y, t)); -} - -/* Interpolate direction vectors (spherical lerp) */ -Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t) -{ - f32 rot = LerpAngleF32(AngleFromVec2(val0), AngleFromVec2(val1), t); - f32 len = LerpF32(Vec2Len(val0), Vec2Len(val1), t); - return MulVec2(Vec2FromAngle(rot), len); -} - -//////////////////////////////// -//~ Vec2I32 Operations - -b32 EqVec2I32(Vec2I32 a, Vec2I32 b) -{ - return a.x == b.x && a.y == b.y; -} - -Vec2I32 NegVec2I32(Vec2I32 a) -{ - return VEC2I32(-a.x, -a.y); -} - -Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b) -{ - return VEC2I32(a.x + b.x, a.y + b.y); -} - -Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b) -{ - return VEC2I32(a.x - b.x, a.y - b.y); -} - -//////////////////////////////// -//~ Xform operations - -b32 EqXform(Xform xf1, Xform xf2) -{ - return EqVec2(xf1.og, xf2.og) && EqVec2(xf1.bx, xf2.bx) && EqVec2(xf1.by, xf2.by); -} - -//- Initialization -Xform XformFromPos(Vec2 v) -{ - Xform xf; - xf.bx = VEC2(1, 0); - xf.by = VEC2(0, 1); - xf.og = v; - return xf; -} - -Xform XformFromRot(f32 r) -{ - Xform result; - f32 c = CosF32(r); - f32 s = SinF32(r); - result.bx = VEC2(c, s); - result.by = VEC2(-s, c); - result.og = VEC2(0, 0); - return result; -} - -Xform XformFromScale(Vec2 scale) -{ - Xform result; - result.bx = VEC2(scale.x, 0); - result.by = VEC2(0, scale.y); - result.og = VEC2(0, 0); - return result; -} - -Xform XformFromTrs(Trs trs) -{ - Xform xf = XformFromPos(trs.t); - xf = RotateXform(xf, trs.r); - xf = ScaleXform(xf, trs.s); - return xf; -} - -Xform XformFromRect(Rect rect) -{ - Vec2 half_size = MulVec2(rect.size, 0.5); - Xform xf = ZI; - xf.bx = VEC2(rect.size.x, 0); - xf.by = VEC2(0, rect.size.y); - xf.og = AddVec2(rect.pos, half_size); - return xf; -} - -//- Translation -Xform TranslateXform(Xform xf, Vec2 v) -{ - xf.og = VEC2(xf.bx.x * v.x + xf.by.x * v.y + xf.og.x, xf.bx.y * v.x + xf.by.y * v.y + xf.og.y); - return xf; -} - -Xform WorldTranslateXform(Xform xf, Vec2 v) -{ - xf.og = AddVec2(xf.og, v); - return xf; -} - -//- Rotation -Xform RotateXform(Xform xf, f32 r) -{ - return MulXform(xf, XformFromRot(r)); -} - -Xform WorldRotateXform(Xform xf, f32 r) -{ - return MulXform(XformFromRot(r), xf); -} - -Xform WorldRotateXformBasis(Xform xf, f32 r) -{ - f32 diff = r; - f32 c = CosF32(diff); - f32 s = SinF32(diff); - xf.bx = VEC2(xf.bx.x * c - xf.bx.y * s, xf.bx.x * s + xf.bx.y * c); - xf.by = VEC2(xf.by.x * c - xf.by.y * s, xf.by.x * s + xf.by.y * c); - return xf; -} - -Xform XformWIthWorldRotation(Xform xf, f32 r) -{ - return WorldRotateXformBasis(xf, r - RotationFromXform(xf)); -} - -//- Scale -Xform ScaleXform(Xform xf, Vec2 scale) -{ - xf.bx = MulVec2(xf.bx, scale.x); - xf.by = MulVec2(xf.by, scale.y); - return xf; -} - -Xform WorldScaleXform(Xform xf, Vec2 scale) -{ - Xform result; - result.bx = MulVec2Vec2(xf.bx, scale); - result.by = MulVec2Vec2(xf.by, scale); - result.og = MulVec2Vec2(xf.og, scale); - return result; -} - -//- Lerp -Xform LerpXform(Xform a, Xform b, f32 t) -{ - Xform result; - result.bx = SlerpVec2(a.bx, b.bx, t); - result.by = SlerpVec2(a.by, b.by, t); - result.og = LerpVec2(a.og, b.og, t); - return result; -} - -//- Invert -Xform InvertXform(Xform xf) -{ - f32 det = DeterminantFromXform(xf); - f32 inv_det = 1.0f / det; - - f32 old_bx_x = xf.bx.x; - xf.bx.x = xf.by.y; - xf.by.y = old_bx_x; - - xf.bx = MulVec2Vec2(xf.bx, VEC2(inv_det, -inv_det)); - xf.by = MulVec2Vec2(xf.by, VEC2(-inv_det, inv_det)); - - xf.og = MulXformBasisV2(xf, NegVec2(xf.og)); - - return xf; -} - -//- Mul -Xform MulXform(Xform a, Xform b) -{ - Xform result; - result.bx.x = a.bx.x * b.bx.x + a.by.x * b.bx.y; - result.bx.y = a.bx.y * b.bx.x + a.by.y * b.bx.y; - result.by.x = a.bx.x * b.by.x + a.by.x * b.by.y; - result.by.y = a.bx.y * b.by.x + a.by.y * b.by.y; - result.og = MulXformV2(a, b.og); - return result; -} - -Vec2 MulXformBasisV2(Xform xf, Vec2 v) -{ - return VEC2( - xf.bx.x * v.x + xf.by.x * v.y, - xf.bx.y * v.x + xf.by.y * v.y - ); -} - -Vec2 MulXformV2(Xform xf, Vec2 v) -{ - Vec2 result = MulXformBasisV2(xf, v); - result = AddVec2(result, xf.og); - return result; -} - - -Quad MulXformQuad(Xform xf, Quad quad) -{ - Quad result; - result.p0 = MulXformV2(xf, quad.p0); - result.p1 = MulXformV2(xf, quad.p1); - result.p2 = MulXformV2(xf, quad.p2); - result.p3 = MulXformV2(xf, quad.p3); - return result; -} - -Vec2 InvertXformBasisMulV2(Xform xf, Vec2 v) -{ - Xform inv = InvertXform(xf); - Vec2 result = MulXformBasisV2(inv, v); - return result; -} - -/* TODO: Get rid of this? Just force caller to use invert manually since it's expensive. */ -Vec2 InvertXformMulV2(Xform xf, Vec2 v) -{ - Xform inv = InvertXform(xf); - return MulXformV2(inv, v); -} - -//- Helpers -Xform BasisFromXform(Xform xf) -{ - Xform result = ZI; - result.bx = xf.bx; - result.by = xf.by; - return result; -} - -f32 DeterminantFromXform(Xform xf) -{ - return WedgeVec2(xf.bx, xf.by); -} - -Vec2 RightFromXform(Xform xf) -{ - return xf.bx; -} - -Vec2 LeftFromXform(Xform xf) -{ - return NegVec2(xf.bx); -} - -Vec2 UpFromXform(Xform xf) -{ - return NegVec2(xf.by); -} - -Vec2 DownFromXform(Xform xf) -{ - return xf.by; -} - -f32 RotationFromXform(Xform xf) -{ - return AngleFromVec2(xf.bx); -} - -Vec2 ScaleFromXform(Xform xf) -{ - f32 det_sign = SignF32(DeterminantFromXform(xf)); - return VEC2(Vec2Len(xf.bx), det_sign * Vec2Len(xf.by)); -} - -//////////////////////////////// -//~ Quad operations - -Quad QuadFromRect(Rect rect) -{ - Quad result; - result.p0 = VEC2(rect.x, rect.y); /* Top left */ - result.p1 = VEC2(rect.x + rect.width, rect.y); /* Top right */ - result.p2 = VEC2(rect.x + rect.width, rect.y + rect.height); /* Bottom right */ - result.p3 = VEC2(rect.x, rect.y + rect.height); /* Bottom left */ - return result; -} - -Quad QuadFromAabb(Aabb aabb) -{ - Quad result; - result.p0 = VEC2(aabb.p0.x, aabb.p0.y); /* Top left */ - result.p1 = VEC2(aabb.p1.x, aabb.p0.y); /* Top right */ - result.p2 = VEC2(aabb.p1.x, aabb.p1.y); /* Bottom right */ - result.p3 = VEC2(aabb.p0.x, aabb.p1.y); /* Bottom left */ - return result; -} - -Quad QuadFromLine(Vec2 start, Vec2 end, f32 thickness) -{ - f32 width = thickness / 2.f; - - Vec2 dir = NormVec2(SubVec2(end, start)); - Vec2 dir_perp = PerpVec2(dir); - - Vec2 left = MulVec2(dir_perp, -width); - Vec2 right = MulVec2(dir_perp, width); - - Quad result; - result.p0 = AddVec2(start, left); - result.p1 = AddVec2(start, right); - result.p2 = AddVec2(end, right); - result.p3 = AddVec2(end, left); - return result; -} - -Quad QuadFromRay(Vec2 pos, Vec2 rel, f32 thickness) -{ - Vec2 end = AddVec2(pos, rel); - return QuadFromLine(pos, end, thickness); -} - -Quad ScaleQuad(Quad q, f32 s) -{ - q.p0 = MulVec2(q.p0, s); - q.p1 = MulVec2(q.p1, s); - q.p2 = MulVec2(q.p2, s); - q.p3 = MulVec2(q.p3, s); - return q; -} - -Quad RoundQuad(Quad quad) -{ - Quad result; - result.p0 = RoundVec2(quad.p0); - result.p1 = RoundVec2(quad.p1); - result.p2 = RoundVec2(quad.p2); - result.p3 = RoundVec2(quad.p3); - return result; -} - -Quad FloorQuad(Quad quad) -{ - Quad result; - result.p0 = FloorVec2(quad.p0); - result.p1 = FloorVec2(quad.p1); - result.p2 = FloorVec2(quad.p2); - result.p3 = FloorVec2(quad.p3); - return result; -} - -//////////////////////////////// -//~ Spring operations - -/* https://box2d.org/files/ErinCatto_SoftConstraints_GDC2011.pdf */ -SoftSpring MakeSpring(f32 hertz, f32 damping_ratio, f32 dt) -{ - SoftSpring result; - if (hertz == 0.0f) - { - result.bias_rate = 0; - result.mass_scale = 1; - result.impulse_scale = 0; - } - else - { - f32 angular_frequency = Tau * hertz; - f32 a = 2 * damping_ratio + angular_frequency * dt; - f32 b = angular_frequency * a * dt; - f32 c = 1 / (b + 1); - result.bias_rate = angular_frequency / a; - result.mass_scale = b * c; - result.impulse_scale = c; - } - return result; -} - -//////////////////////////////// -//~ Mat4x4 operations - -Mat4x4 Mat4x4FromXform(Xform xf) -{ - return (Mat4x4) - { - .e = { - {xf.bx.x, xf.bx.y, 0, 0}, - {xf.by.x, xf.by.y, 0, 0}, - {0, 0, 1, 0}, - {xf.og.x, xf.og.y, 0, 1}, - } - }; -} - -Mat4x4 Mat4x4FromOrtho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z) -{ - Mat4x4 m = ZI; - - f32 rl = 1.0f / (right - left); - f32 tb = 1.0f / (top - bottom); - f32 fn = -1.0f / (far_z - near_z); - - m.e[0][0] = 2.0f * rl; - m.e[1][1] = 2.0f * tb; - m.e[2][2] = 2.0f * fn; - m.e[3][0] = -(right + left) * rl; - m.e[3][1] = -(top + bottom) * tb; - m.e[3][2] = (far_z + near_z) * fn; - m.e[3][3] = 1.0f; - - return m; -} - -Mat4x4 MulMat4x4(Mat4x4 m1, Mat4x4 m2) -{ - f32 a00 = m1.e[0][0], a01 = m1.e[0][1], a02 = m1.e[0][2], a03 = m1.e[0][3], - a10 = m1.e[1][0], a11 = m1.e[1][1], a12 = m1.e[1][2], a13 = m1.e[1][3], - a20 = m1.e[2][0], a21 = m1.e[2][1], a22 = m1.e[2][2], a23 = m1.e[2][3], - a30 = m1.e[3][0], a31 = m1.e[3][1], a32 = m1.e[3][2], a33 = m1.e[3][3], - - b00 = m2.e[0][0], b01 = m2.e[0][1], b02 = m2.e[0][2], b03 = m2.e[0][3], - b10 = m2.e[1][0], b11 = m2.e[1][1], b12 = m2.e[1][2], b13 = m2.e[1][3], - b20 = m2.e[2][0], b21 = m2.e[2][1], b22 = m2.e[2][2], b23 = m2.e[2][3], - b30 = m2.e[3][0], b31 = m2.e[3][1], b32 = m2.e[3][2], b33 = m2.e[3][3]; - - Mat4x4 result; - result.e[0][0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03; - result.e[0][1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03; - result.e[0][2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03; - result.e[0][3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03; - result.e[1][0] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13; - result.e[1][1] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13; - result.e[1][2] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13; - result.e[1][3] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13; - result.e[2][0] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23; - result.e[2][1] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23; - result.e[2][2] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23; - result.e[2][3] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23; - result.e[3][0] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33; - result.e[3][1] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33; - result.e[3][2] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33; - result.e[3][3] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33; - - return result; -} - -Mat4x4 ProjectMat4x4View(Xform view, f32 viewport_width, f32 viewport_height) -{ - Mat4x4 projection = Mat4x4FromOrtho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0); - Mat4x4 view4x4 = Mat4x4FromXform(view); - return MulMat4x4(projection, view4x4); -} diff --git a/src/meta/meta_base/meta_base_math.h b/src/meta/meta_base/meta_base_math.h deleted file mode 100644 index a8c65199..00000000 --- a/src/meta/meta_base/meta_base_math.h +++ /dev/null @@ -1,415 +0,0 @@ -/* Math functions are default 32 bit (f32, i32, etc) unless specified */ - -#define Pi ((f32)3.14159265358979323846) -#define Tau ((f32)6.28318530717958647693) -#define GoldenRatio ((f32)1.61803398874989484820) - -//////////////////////////////// -//~ Floating point vector2 types - -Struct(Vec2) { - f32 x, y; -}; -#define VEC2(x, y) (Vec2) { (x), (y) } - -Struct(Vec2Array) { - Vec2 *points; - u64 count; -}; - -//////////////////////////////// -//~ Floating point vector3 types - -Struct(Vec3) { - f32 x, y, z; -}; -#define VEC3(x, y, z) (Vec3) { (x), (y), (z) } - -Struct(Vec3Array) { - Vec3 *points; - u64 count; -}; - -//////////////////////////////// -//~ Floating point vector4 types - -Struct(Vec4) { - f32 x, y, z, w; -}; -#define VEC4(x, y, z, w) ((Vec4) { (x), (y), (z), (w) }) - -Struct(Vec4Array) { - Vec4 *points; - u64 count; -}; - -//////////////////////////////// -//~ Integer vec2 types - -Struct(Vec2I32) { - i32 x, y; -}; -#define VEC2I32(x, y) (Vec2I32) { (x), (y) } - -//////////////////////////////// -//~ Integer vector3 types - -Struct(Vec3I32) { - i32 x, y, z; -}; -#define VEC3I32(x, y, z) (Vec3I32) { (x), (y), (z) } - -//////////////////////////////// -//~ Integer vector4 types - -Struct(Vec4I32) -{ - i32 x, y, z, w; -}; -#define VEC4I32(x, y, z, w) (Vec4I32) { (x), (y), (z), (w) } - -//////////////////////////////// -//~ Xform types - -Struct(Xform) -{ - Vec2 bx; /* X basis vector (x axis) */ - Vec2 by; /* Y basis vector (y axis)*/ - Vec2 og; /* Translation vector (origin) */ -}; - -/* (T)ranslation, (R)otation, (S)cale */ -Struct(Trs) -{ - Vec2 t; - Vec2 s; - f32 r; -}; - -//////////////////////////////// -//~ Rect types - -Struct(Rect) { - union - { - struct { f32 x, y, width, height; }; - struct { Vec2 pos, size; }; - }; -}; - - -/* Values expected to be normalized 0.0 -> 1.0 */ -Struct(ClipRect) -{ - Vec2 p0, p1; -}; - -//////////////////////////////// -//~ Axis aligned bounding box types - -Struct(Aabb) { - Vec2 p0, p1; -}; - -//////////////////////////////// -//~ Quad types - -Struct(Quad) { - union - { - struct { Vec2 p0, p1, p2, p3; }; - struct { Vec2 e[4]; }; - }; -}; - -//////////////////////////////// -//~ Spring types - -Struct(SoftSpring) -{ - f32 bias_rate; - f32 mass_scale; - f32 impulse_scale; -}; - -//////////////////////////////// -//~ Mat4x4 types - -Struct(Mat4x4) -{ - union - { - struct { Vec4 bx, by, bz, bw; }; - f32 e[4][4]; - }; -}; - -//////////////////////////////// -//~ Min / max - -//- Min -u8 MinU8(u8 a, u8 b); -i8 MinI8(i8 a, i8 b); -u32 MinU32(u32 a, u32 b); -i32 MinI32(i32 a, i32 b); -f32 MinF32(f32 a, f32 b); -u64 MinU64(u64 a, u64 b); -i64 MinI64(i64 a, i64 b); -f64 MinF64(f64 a, f64 b); - -//- Max -u8 MaxU8(u8 a, u8 b); -i8 MaxI8(i8 a, i8 b); -u32 MaxU32(u32 a, u32 b); -i32 MaxI32(i32 a, i32 b); -f32 MaxF32(f32 a, f32 b); -u64 MaxU64(u64 a, u64 b); -i64 MaxI64(i64 a, i64 b); -f64 MaxF64(f64 a, f64 b); - -//- Clamp -u32 ClampU32(u32 v, u32 min, u32 max); -i32 ClampI32(i32 v, i32 min, i32 max); -f32 ClampF32(f32 v, f32 min, f32 max); -u64 ClampU64(u64 v, u64 min, u64 max); -i64 ClampI64(i64 v, i64 min, i64 max); -f64 ClampF64(f64 v, f64 min, f64 max); - -//////////////////////////////// -//~ Rounding ops - -//- Round -f32 RoundF32(f32 f); -f64 RoundF64(f64 f); -i32 RoundF32ToI32(f32 f); -i64 RoundF64ToI64(f64 f); - -//- Floor -f32 FloorF32(f32 f); -f64 FloorF64(f64 f); -i32 FloorF32ToI32(f32 f); -i64 FloorF64ToI64(f64 f); - -//- Ceil -f32 CeilF32(f32 f); -f64 CeilF64(f64 f); -i32 CeilF32ToI32(f32 f); -i64 CeilF64ToI64(f64 f); - -//- Trunc -f32 TruncF32(f32 f); -f64 TruncF64(f64 f); - -//////////////////////////////// -//~ Fmod - -f32 ModF32(f32 x, f32 m); -f64 ModF64(f64 x, f64 m); - -//////////////////////////////// -//~ Abs - -f32 AbsF32(f32 f); -f64 AbsF64(f64 f); -u32 AbsI32(i32 v); -u64 AbsI64(i64 v); -i32 SignF32(f32 f); -i64 SignF64(f64 f); - -//////////////////////////////// -//~ Exponential ops - -u64 PowU64(u64 base, u8 exp); -u64 AlignU64Pow2(u64 x); -f32 LnF32(f32 x); -f32 ExpF32(f32 x); -f32 PowF32(f32 a, f32 b); -f32 SqrtF32(f32 x); -f64 SqrtF64(f64 x); -f32 RSqrtF32(f32 x); - -//////////////////////////////// -//~ Trig - -f32 ReduceToPio4(f32 x, i32 *octant_out); -f32 SinApproxF32(f32 x); -f32 CosApproxF32(f32 x); -f32 SinF32(f32 x); -f32 CosF32(f32 x); -f32 ArcTanF32(f32 x); -f32 ArcTan2F32(f32 y, f32 x); -f32 ArcSinF32(f32 x); -f32 ArcCosF32(f32 x); - -//////////////////////////////// -//~ Angle unwind - -/* Returns angle in range [-Pi, Pi] */ -f32 UnwindAngleF32(f32 a); - -//////////////////////////////// -//~ Float lerp - -f32 LerpF32(f32 val0, f32 val1, f32 t); -f64 LerpF64(f64 val0, f64 val1, f64 t); -f32 LerpAngleF32(f32 a, f32 b, f32 t); - -//////////////////////////////// -//~ Int lerp - -i32 LerpI32(i32 val0, i32 val1, f32 t); -i64 LerpI64(i64 val0, i64 val1, f64 t); - -//////////////////////////////// -//~ Vec2 operations - -#define Vec2FromVec2I32(v) VEC2((v).x, (v).y) - -b32 IsVec2Zero(Vec2 a); -b32 EqVec2(Vec2 a, Vec2 b); - -//- Mul -Vec2 MulVec2(Vec2 a, f32 s); -Vec2 MulVec2Vec2(Vec2 a, Vec2 b); -Vec2 NegVec2(Vec2 a); - -//- Div -Vec2 DivVec2(Vec2 a, f32 s); -Vec2 DivVec2Vec2(Vec2 a, Vec2 b); - -//- Add -Vec2 AddVec2(Vec2 a, Vec2 b); -Vec2 SubVec2(Vec2 a, Vec2 b); - -//- Len -f32 Vec2Len(Vec2 a); -f32 Vec2LenSq(Vec2 a); -Vec2 Vec2WithLen(Vec2 a, f32 len); -Vec2 ClampVec2Len(Vec2 a, f32 max); -f32 Vec2Distance(Vec2 a, Vec2 b); -Vec2 NormVec2(Vec2 a); - -//- Dot -f32 DotVec2(Vec2 a, Vec2 b); -f32 WedgeVec2(Vec2 a, Vec2 b); -Vec2 PerpVec2(Vec2 a); -Vec2 MulPerpVec2(Vec2 a, f32 s); -Vec2 PerpVec2TowardsDir(Vec2 v, Vec2 dir); - -//- Round / floor / ceil -Vec2 RoundVec2(Vec2 a); -Vec2I32 RoundVec2ToVec2I32(Vec2 a); -Vec2 FloorVec2(Vec2 a); -Vec2 CeilVec2(Vec2 a); - -//- Angle -i32 WindingFromVec2(Vec2 a, Vec2 b); -Vec2 RotateVec2(Vec2 v, f32 a); -Vec2 Vec2FromAngle(f32 a); -f32 AngleFromVec2(Vec2 v); -f32 AngleFromVec2Dirs(Vec2 dir1, Vec2 dir2); -f32 AngleFromVec2Points(Vec2 pt1, Vec2 pt2); - -//- Closest point -Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p); - -//- Lerp -Vec2 LerpVec2(Vec2 val0, Vec2 val1, f32 t); -Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t); - -//////////////////////////////// -//~ Vec2I32 Operations - -b32 EqVec2I32(Vec2I32 a, Vec2I32 b); -Vec2I32 NegVec2I32(Vec2I32 a); -Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b); -Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b); - -//////////////////////////////// -//~ Xform operations - -b32 EqXform(Xform xf1, Xform xf2); - -//- Initialization -#define XformIdentity (Xform) { .bx = VEC2(1, 0), .by = VEC2(0, 1) } -#define XformIdentityNoCast { .bx = VEC2(1, 0), .by = VEC2(0, 1) } -Xform XformFromPos(Vec2 v); -Xform XformFromRot(f32 r); -Xform XformFromScale(Vec2 scale); -Xform XformFromTrs(Trs trs); -Xform XformFromRect(Rect rect); - -//- Translation -Xform TranslateXform(Xform xf, Vec2 v); -Xform WorldTranslateXform(Xform xf, Vec2 v); - -//- Rotation -Xform RotateXform(Xform xf, f32 r); -Xform WorldRotateXform(Xform xf, f32 r); -Xform WorldRotateXformBasis(Xform xf, f32 r); -Xform XformWIthWorldRotation(Xform xf, f32 r); - -//- Scale -Xform ScaleXform(Xform xf, Vec2 scale); -Xform WorldScaleXform(Xform xf, Vec2 scale); - -//- Lerp -Xform LerpXform(Xform a, Xform b, f32 t); - -//- Invert -Xform InvertXform(Xform xf); - -//- Mul -Vec2 MulXformV2(Xform xf, Vec2 v); -Xform MulXform(Xform a, Xform b); -Quad MulXformQuad(Xform xf, Quad quad); -Vec2 MulXformBasisV2(Xform xf, Vec2 v); -Vec2 InvertXformMulV2(Xform xf, Vec2 v); -Vec2 InvertXformBasisMulV2(Xform xf, Vec2 v); - -//- Helpers -Xform BasisFromXform(Xform xf); -f32 DeterminantFromXform(Xform xf); -Vec2 RightFromXform(Xform xf); -Vec2 LeftFromXform(Xform xf); -Vec2 UpFromXform(Xform xf); -Vec2 DownFromXform(Xform xf); -f32 RotationFromXform(Xform xf); -Vec2 ScaleFromXform(Xform xf); - -//- Trs -#define TRS(...) ((Trs) { .t = VEC2(0,0), .s = VEC2(1, 1), .r = 0, __VA_ARGS__ }) - -//////////////////////////////// -//~ Rect operations - -#define RectFromScalar(_x, _y, _width, _height) (Rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) } -#define RectFromVec2(_pos, _size) (Rect) { .pos = (_pos), .size = (_size) } -#define AllClipped ((ClipRect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } }) - -//////////////////////////////// -//~ Quad operations - -#define UnitSquareQuad (Quad) { .p0 = VEC2(0, 0), .p1 = VEC2(0, 1), .p2 = VEC2(1, 1), .p3 = VEC2(1, 0) } -#define CenteredUnitSquareQuad (Quad) { .p0 = VEC2(-0.5f, -0.5f), .p1 = VEC2(0.5f, -0.5f), .p2 = VEC2(0.5f, 0.5f), .p3 = VEC2(-0.5f, 0.5f) } - -Quad QuadFromRect(Rect rect); -Quad QuadFromAabb(Aabb aabb); -Quad QuadFromLine(Vec2 start, Vec2 end, f32 thickness); -Quad QuadFromRay(Vec2 pos, Vec2 rel, f32 thickness); -Quad ScaleQuad(Quad q, f32 s); -Quad RoundQuad(Quad quad); -Quad FloorQuad(Quad quad); - -//////////////////////////////// -//~ Spring operations - -SoftSpring MakeSpring(f32 hertz, f32 damping_ratio, f32 dt); - -//////////////////////////////// -//~ Mat4x4 operations - -Mat4x4 Mat4x4FromXform(Xform xf); -Mat4x4 Mat4x4FromOrtho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z); -Mat4x4 MulMat4x4(Mat4x4 m1, Mat4x4 m2); -Mat4x4 ProjectMat4x4View(Xform view, f32 viewport_width, f32 viewport_height); diff --git a/src/meta/meta_base/meta_base_memory.c b/src/meta/meta_base/meta_base_memory.c deleted file mode 100644 index fbb5eb3e..00000000 --- a/src/meta/meta_base/meta_base_memory.c +++ /dev/null @@ -1,85 +0,0 @@ -//////////////////////////////// -//~ Win32 memory allocation - -#if PlatformIsWindows - -//- Reserve -void *ReserveMemory(u64 size) -{ - void *ptr = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS); - return ptr; -} - -void ReleaseMemory(void *address) -{ - VirtualFree(address, 0, MEM_RELEASE); -} - -//- Commit -void *CommitMemory(void *address, u64 size) -{ - void *ptr = VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE); - return ptr; -} - -void DecommitMemory(void *address, u64 size) -{ - VirtualFree(address, size, MEM_DECOMMIT); -} - -//- Protect -void SetMemoryReadonly(void *address, u64 size) -{ - DWORD old; - VirtualProtect(address, size, PAGE_READONLY, &old); -} - -void SetMemoryReadWrite(void *address, u64 size) -{ - DWORD old; - VirtualProtect(address, size, PAGE_READWRITE, &old); -} - -#else -# error Memory allocation not implemented for this platform -#endif - -//////////////////////////////// -//~ Memory operations - -void *CopyBytes(void *dst, void *src, u64 count) -{ - char *dst_pchar = dst; - char *src_pchar = src; - for (u64 i = 0; i < count; ++i) - { - dst_pchar[i] = src_pchar[i]; - } - return dst; -} - -void *SetBytes(void *dst, u8 c, u64 count) -{ - char *dst_pchar = dst; - for (u64 i = 0; i < count; ++i) - { - dst_pchar[i] = (char)c; - } - return dst; -} - -i32 CmpBytes(void *p1, void *p2, u64 count) -{ - i32 result = 0; - char *p1_pchar = p1; - char *p2_pchar = p2; - for (u64 i = 0; i < count; ++i) - { - result = p1_pchar[i] - p2_pchar[i]; - if (result != 0) - { - break; - } - } - return result; -} diff --git a/src/meta/meta_base/meta_base_memory.h b/src/meta/meta_base/meta_base_memory.h deleted file mode 100644 index fcb2f726..00000000 --- a/src/meta/meta_base/meta_base_memory.h +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////// -//~ Memory allocation - -//- Reserve -void *ReserveMemory(u64 size); -void ReleaseMemory(void *address); - -//- Commit -void *CommitMemory(void *address, u64 size); -void DecommitMemory(void *address, u64 size); - -//- Protect -void SetMemoryReadonly(void *address, u64 size); -void SetMemoryReadWrite(void *address, u64 size); - -//////////////////////////////// -//~ Memory operations - -//- Wrappers -#define ZeroStruct(ptr) ZeroBytes((ptr), sizeof(*(ptr))) -#define ZeroArray(a) Assert(IsArray(a)); ZeroBytes((a), sizeof((a))) -#define CopyStruct(ptr_dst, ptr_src) CopyBytes((ptr_dst), (ptr_src), sizeof(*(ptr_dst))) -#define EqStruct(p1, p2) EqBytes((p1), (p2), sizeof(*p1)) -#define ZeroBytes(ptr, count) SetBytes((ptr), 0, (count)) -#define EqBytes(p1, p2, n) (CmpBytes((p1), (p2), (n)) == 0) - -void *CopyBytes(void *dst, void *src, u64 count); -void *SetBytes(void *dst, u8 c, u64 count); -i32 CmpBytes(void *p1, void *p2, u64 count); diff --git a/src/meta/meta_base/meta_base_rand.c b/src/meta/meta_base/meta_base_rand.c deleted file mode 100644 index 05c6fb13..00000000 --- a/src/meta/meta_base/meta_base_rand.c +++ /dev/null @@ -1,43 +0,0 @@ -//////////////////////////////// -//~ Stateful randomness - -u64 RandU64FromState(RandState *state) -{ - u64 seed = state->seed; - if (seed == 0) - { - TrueRand(StringFromStruct(&seed)); - state->seed = seed; - } - return seed ^ RandU64FromSeed(++state->counter); -} - -f64 RandF64FromState(RandState *state, f64 range_start, f64 range_end) -{ - return range_start + (range_end - range_start) * ((f64)(RandU64FromState(state) % RandMaxF64) / (f64)RandMaxF64); -} - -//////////////////////////////// -//~ Seeded randomness - -/* Based on Jon Maiga's "mx3" - * https://jonkagstrom.com/mx3/mx3_rev2.html - */ -u64 RandU64FromSeed(u64 seed) -{ - seed = (seed ^ (seed >> 32)) * 0xbea225f9eb34556d; - seed = (seed ^ (seed >> 29)) * 0xbea225f9eb34556d; - seed = (seed ^ (seed >> 32)) * 0xbea225f9eb34556d; - seed = (seed ^ (seed >> 29)); - return seed; -} - -u64 RandU64FromSeeds(u64 seed_a, u64 seed_b) -{ - return RandU64FromSeed((seed_a * 3) + seed_b); -} - -f64 RandF64FromSeed(u64 seed, f64 range_start, f64 range_end) -{ - return range_start + (range_end - range_start) * ((f64)(RandU64FromSeed(seed) % RandMaxF64) / (f64)RandMaxF64); -} diff --git a/src/meta/meta_base/meta_base_rand.h b/src/meta/meta_base/meta_base_rand.h deleted file mode 100644 index c2c79cb8..00000000 --- a/src/meta/meta_base/meta_base_rand.h +++ /dev/null @@ -1,23 +0,0 @@ -//////////////////////////////// -//~ Rand types - -Struct(RandState) -{ - u64 seed; /* If a state's seed == 0 upon a call to a related function, it will be initialized using platform's true rng source */ - u64 counter; -}; - -/* TODO: Use a value that gives good precision when dividing into range 0 -> 1 */ -#define RandMaxF64 U64Max - -//////////////////////////////// -//~ Rand operations - -//- Stateful randomness -u64 RandU64FromState(RandState *state); -f64 RandF64FromState(RandState *state, f64 range_start, f64 range_end); - -//- Seeded randomness -u64 RandU64FromSeed(u64 seed); -u64 RandU64FromSeeds(u64 seed_a, u64 seed_b); -f64 RandF64FromSeed(u64 seed, f64 range_start, f64 range_end); diff --git a/src/meta/meta_base/meta_base_string.c b/src/meta/meta_base/meta_base_string.c deleted file mode 100644 index 1a8df924..00000000 --- a/src/meta/meta_base/meta_base_string.c +++ /dev/null @@ -1,919 +0,0 @@ -//////////////////////////////// -//~ Conversion helpers - -//- Char conversion - -String StringFromChar(Arena *arena, char c) -{ - u8 *dst = PushStructNoZero(arena, u8); - *dst = c; - return (String) - { - .len = 1, - .text = dst - }; -} - -//- Unsigned int conversion - -String StringFromU64(Arena *arena, u64 n, u64 base, u64 zfill) -{ - /* Base too large */ - Assert(base <= (countof(IntChars) - 1)); - - TempArena scratch = BeginScratch(arena); - - /* Build backwards text starting from least significant digit */ - u64 len = 0; - u8 *backwards_text = PushDry(scratch.arena, u8); - do - { - StringFromChar(scratch.arena, IntChars[n % base]); - ++len; - n /= base; - } while (n > 0); - - while (len < zfill) - { - StringFromChar(scratch.arena, '0'); - ++len; - } - - /* Reverse text into final string */ - u8 *final_text = PushStructsNoZero(arena, u8, len); - for (u64 i = 0; i < len; ++i) - { - final_text[i] = backwards_text[len - i - 1]; - } - - EndScratch(scratch); - - return (String) - { - .len = len, - .text = final_text - }; -} - -//- Signed int conversion - -String StringFromI64(Arena *arena, i64 n, u64 base, u64 zfill) -{ - u8 *final_text = PushDry(arena, u8); - u8 len = 0; - if (n < 0) - { - /* Push sign */ - StringFromChar(arena, '-'); - len = 1; - n = -n; - } - /* Push unsigned number */ - String uint_str = StringFromU64(arena, n, base, zfill); - return (String) - { - .len = len + uint_str.len, - .text = final_text - }; -} - -//- Pointer conversion - -String StringFromPtr(Arena *arena, void *ptr) -{ - String prepend = PushString(arena, Lit("0x")); - String uint_str = StringFromU64(arena, (u64)ptr, 16, sizeof(ptr)); - return (String) - { - .len = prepend.len + uint_str.len, - .text = prepend.text - }; -} - -//- Floating point conversion - -String StringFromF64(Arena *arena, f64 f, u32 precision) -{ - TempArena scratch = BeginScratch(arena); - u8 *final_text = PushDry(arena, u8); - u64 final_len = 0; - - if (IsF32Nan(f)) - { - final_len += PushString(arena, Lit("NaN")).len; - } - else if (f == F64Infinity) - { - final_len += PushString(arena, Lit("inf")).len; - } - else if (f == -F64Infinity) - { - final_len += PushString(arena, Lit("-inf")).len; - } - else - { - if (f < 0) - { - StringFromChar(arena, '-'); - f = -f; - ++final_len; - } - - /* Add one half of next precision level to round up */ - f += 0.5 / (f64)PowU64(10, (u8)precision); - - f64 part_whole = TruncF64(f); - f64 part_decimal = f - part_whole; - - /* Print whole part */ - { - /* Build backwards text starting from least significant digit */ - u8 *backwards_text = PushDry(scratch.arena, u8); - u64 backwards_text_len = 0; - do - { - u64 digit = (u64)RoundF64ToI64(ModF64(part_whole, 10.0)); - StringFromChar(scratch.arena, IntChars[digit % 10]); - ++backwards_text_len; - part_whole = TruncF64(part_whole / 10.0); - } while (part_whole > 0); - - /* Reverse text into final string */ - PushStructsNoZero(arena, u8, backwards_text_len); - for (u64 i = backwards_text_len; i-- > 0;) - { - final_text[final_len++] = backwards_text[i]; - } - } - - /* Print decimal part */ - if (precision > 0) - { - StringFromChar(arena, '.'); - for (u64 i = 0; i < precision; ++i) - { - part_decimal *= 10.0; - u64 digit = (u64)part_decimal; - part_decimal -= digit; - StringFromChar(arena, IntChars[digit % 10]); - } - final_len += (u64)precision + 1; - } - } - - EndScratch(scratch); - - return (String) - { - .len = final_len, - .text = final_text - }; -} - -//////////////////////////////// -//~ String helpers - -//- Copy - -String PushString(Arena *arena, String src) -{ - String str = { - .len = src.len, - .text = PushStructsNoZero(arena, u8, src.len) - }; - CopyBytes(str.text, src.text, src.len); - return str; -} - -String PushStringToBuff(String dst, String src) -{ - String result = ZI; - result.len = MinU64(dst.len, src.len); - result.text = dst.text; - CopyBytes(result.text, src.text, result.len); - return result; -} - -//- Repeat - -String RepeatString(Arena *arena, String src, u64 count) -{ - u64 final_len = src.len * count; - u8 *final_text = PushStructsNoZero(arena, u8, final_len); - for (u64 i = 0; i < count; ++i) - { - CopyBytes(final_text + (src.len * i), src.text, src.len); - } - return (String) - { - .text = final_text, - .len = final_len - }; -} - -//- Concatenate - -String CatString(Arena *arena, String str1, String str2) -{ - String new_str = ZI; - new_str.len = str1.len + str2.len; - new_str.text = PushStructsNoZero(arena, u8, new_str.len); - CopyBytes(new_str.text, str1.text, str1.len); - CopyBytes(new_str.text + str1.len, str2.text, str2.len); - return new_str; -} - -//- Split - -/* `arena` is where pieces will be allocated. These strings point - * into the existing string and do not allocate any new text. */ -StringArray SplitString(Arena *arena, String str, String delim) -{ - StringArray pieces = ZI; - pieces.strings = PushDry(arena, String); - i64 piece_start = 0; - for (i64 i = 0; i < (i64)str.len - (i64)delim.len; ++i) - { - String cmp = ZI; - cmp.text = &str.text[i]; - cmp.len = MinI64(str.len - i, delim.len); - - b32 is_delimiter = EqString(cmp, delim); - if (is_delimiter) - { - String piece = ZI; - piece.text = &str.text[piece_start]; - piece.len = i - piece_start; - i += delim.len; - piece_start = i; - if (piece.len > 0) - { - *PushStructNoZero(arena, String) = piece; - ++pieces.count; - } - } - } - if (piece_start < (i64)str.len) - { - String piece = ZI; - piece.text = &str.text[piece_start]; - piece.len = str.len - piece_start; - *PushStructNoZero(arena, String) = piece; - ++pieces.count; - } - return pieces; -} - -//- Indent - -/* NOTE: Really slow */ -String IndentString(Arena *arena, String str, u32 indent) -{ - TempArena scratch = BeginScratch(arena); - - u64 final_len = 0; - u8 *final_text = PushDry(arena, u8); - - StringArray split = SplitString(scratch.arena, str, Lit("\n")); - for (u64 i = 0; i < split.count; ++i) - { - String piece = split.strings[i]; - for (u32 j = 0; j < indent; ++j) - { - StringFromChar(arena, ' '); - ++final_len; - } - PushString(arena, piece); - final_len += piece.len; - if (i < split.count - 1) - { - StringFromChar(arena, '\n'); - ++final_len; - } - } - - EndScratch(scratch); - - return (String) - { - .len = final_len, - .text = final_text - }; -} - -//- Lower - -String LowerString(Arena *arena, String str) -{ - String result = ZI; - result.text = PushStructsNoZero(arena, u8, str.len); - result.len = str.len; - - for (u64 i = 0; i < str.len; ++i) - { - u8 c = str.text[i]; - if (65 <= c && c <= 90) - { - c += 32; - } - result.text[i] = c; - } - - return result; -} - -//- Compare - -b32 EqString(String str1, String str2) -{ - b32 eq = 1; - if (str1.len == str2.len) - { - for (u64 i = 0; i < str1.len; ++i) - { - if (str1.text[i] != str2.text[i]) - { - eq = 0; - break; - } - } - } - else - { - eq = 0; - } - return eq; -} - -//- Match - -b32 StringContains(String str, String substring) -{ - if (substring.len > str.len) - { - return 0; - } - - for (u64 i = 0; i <= str.len - substring.len; ++i) - { - b32 match = 1; - for (u64 j = 0; j < substring.len; ++j) - { - if (str.text[i + j] != substring.text[j]) - { - match = 0; - break; - } - } - if (match) - { - return 1; - } - } - - return 0; -} - -b32 StringStartsWith(String str, String substring) -{ - if (str.len >= substring.len) - { - for (u64 i = 0; i < substring.len; ++i) - { - if (str.text[i] != substring.text[i]) - { - return 0; - } - } - return 1; - } - return 0; -} - -b32 StringEndsWith(String str, String substring) -{ - if (str.len >= substring.len) - { - u64 start = str.len - substring.len; - for (u64 i = 0; i < substring.len; ++i) - { - if (str.text[start + i] != substring.text[i]) - { - return 0; - } - } - return 1; - } - return 0; -} - -//////////////////////////////// -//~ String list helpers - -StringListNode *PushStringToList(Arena *arena, StringList *l, String s) -{ - StringListNode *n = PushStruct(arena, StringListNode); - n->s = s; - n->prev = l->last; - if (l->last) - { - l->last->next = n; - } - else - { - l->first = n; - } - l->last = n; - ++l->count; - return n; -} - -String StringFromList(Arena *arena, StringList l, String separator) -{ - String result = ZI; - result.text = PushDry(arena, u8); - for (StringListNode *n = l.first; n; n = n->next) - { - String s = n->s; - PushString(arena, s); - result.len += s.len; - if (n->next) - { - PushString(arena, separator); - result.len += separator.len; - } - } - return result; -} - -//////////////////////////////// -//~ Trimming helpers - -String TrimLeft(String s, String pattern) -{ - String result = s; - while (StringStartsWith(result, pattern)) - { - result.text += pattern.len; - } - return result; -} - -String TrimRight(String s, String pattern) -{ - String result = s; - while (StringEndsWith(result, pattern)) - { - result.len -= pattern.len; - } - return result; -} - -String Trim(String s, String pattern) -{ - return TrimLeft(TrimRight(s, pattern), pattern); -} - -//////////////////////////////// -//~ Formatting - -/* String formatting only has one format specifier: "%F". All specifier info is - * included in the arguments (instead of w/ the specifier like in printf). - * - * Example: - * StringFormat(arena, Lit("Hello there %F"), FmtString(Lit("George"))) - * - * NOTE: FmtEnd must be passed as the last arg in the va_list (This is - * done automatically by the `StringFormat` macro). - * - * Format arguments: - * FmtChar: Format a single u8 character - * FmtString: Format a `string` struct - * FmtUint: Format a u64 - * FmtSint: Format an i64 - * FmtFloat: Format an f64 with DefaultFmtPrecision - * FmtFloatP: Format an f64 with specified precision - * FmtHex: Format a u64 in hexadecimal notation - * FmtPtr: Format a pointer in hexadecimal notation prefixed by "0x" - * - * FmtEnd (internal): Denote the end of the va_list - * - * TODO: - * %n equivalent? (nothing) - * %e/%E equivalent? (scientific notation of floats) - * %o equivalent? (octal representation) - */ -String StringFormatV(Arena *arena, String fmt, va_list args) -{ - __prof; - - u64 final_len = 0; - u8 *final_text = PushDry(arena, u8); - - u8 *end = fmt.text + fmt.len; - b32 no_more_args = 0; - for (u8 *c = fmt.text; c < end; ++c) - { - u8 *next = ((c + 1) < end) ? (c + 1) : (u8 *)"\0"; - - /* Escape '%%' */ - b32 escape = !no_more_args && *c == '%' && *next == '%'; - if (escape) - { - /* Skip the escape '%' char from parsing */ - ++c; - } - - if (!no_more_args && !escape && *c == '%' && *next == 'F') - { - String parsed_str = ZI; - /* Detect arg type and parse to string */ - FmtArg arg = va_arg(args, FmtArg); - switch (arg.kind) - { - case FmtKind_Char: - { - parsed_str = StringFromChar(arena, arg.value.c); - } break; - - case FmtKind_String: - { - parsed_str = PushString(arena, arg.value.string); - } break; - - case FmtKind_Uint: - { - parsed_str = StringFromU64(arena, arg.value.uint, 10, arg.zfill); - } break; - - case FmtKind_Sint: - { - parsed_str = StringFromI64(arena, arg.value.sint, 10, arg.zfill); - } break; - - case FmtKind_Hex: - { - parsed_str = StringFromU64(arena, arg.value.sint, 16, arg.zfill); - } break; - - case FmtKind_Ptr: - { - parsed_str = StringFromPtr(arena, arg.value.ptr); - } break; - - case FmtKind_Float: - { - parsed_str = StringFromF64(arena, arg.value.f, arg.precision); - } break; - - case FmtKind_End: - { - /* Unexpected end. Not enough FMT args passed to function. */ - Assert(0); - parsed_str = PushString(arena, Lit("")); - no_more_args = 1; - } break; - - default: - { - /* Unknown format type */ - Assert(0); - parsed_str = PushString(arena, Lit("")); - no_more_args = 1; - } break; - } - /* Update final string len / start */ - final_len += parsed_str.len; - /* Skip 'F' from parsing */ - ++c; - } - else - { - /* Parse character normally */ - StringFromChar(arena, *c); - ++final_len; - } - } - -#if RtcIsEnabled - if (!no_more_args) - { - FmtArg last_arg = va_arg(args, FmtArg); - /* End arg not reached. Too many FMT values passed to function. */ - Assert(last_arg.kind == FmtKind_End); - } -#endif - - return (String) - { - .len = final_len, - .text = final_text - }; -} - -String StringFormat_(Arena *arena, String fmt, ...) -{ - va_list args; - va_start(args, fmt); - String new_str = StringFormatV(arena, fmt, args); - va_end(args); - return new_str; -} - -//////////////////////////////// -//~ Unicode - -//- Codepoint iteration - -CodepointIter BeginCodepointIter(String str) -{ - return (CodepointIter) - { - .src = str - }; -} - -/* Returns 0 if done iterating */ -b32 AdvanceCodepointIter(CodepointIter *iter) -{ - if (iter->pos < iter->src.len) - { - String str_remaining = { .len = (iter->src.len - iter->pos), .text = iter->src.text + iter->pos }; - Utf8DecodeResult decoded = DecodeUtf8(str_remaining); - iter->pos += decoded.advance8; - iter->codepoint = decoded.codepoint; - return 1; - } - else - { - return 0; - } -} - -void EndCodepointIter(CodepointIter *iter) -{ - /* Do nothing */ - LAX iter; -} - -//- String decode - -/* utf8 <- utf16 */ -String StringFromString16(Arena *arena, String16 str16) -{ - String result = { - .len = 0, - .text = PushDry(arena, u8) - }; - - u64 pos16 = 0; - while (pos16 < str16.len) - { - String16 str16_remaining = { .len = (str16.len - pos16), .text = str16.text + pos16 }; - Utf16DecodeResult decoded = DecodeUtf16(str16_remaining); - Utf8EncodeResult encoded = EncodeUtf8(decoded.codepoint); - - u8 *dst = PushStructsNoZero(arena, u8, encoded.count8); - CopyBytes(dst, encoded.chars8, encoded.count8); - - pos16 += decoded.advance16; - result.len += encoded.count8; - } - - return result; -} - -/* utf8 <- utf32 */ -String StringFromString32(Arena *arena, String32 str32) -{ - String result = { - .len = 0, - .text = PushDry(arena, u8) - }; - - u64 pos32 = 0; - while (pos32 < str32.len) - { - String32 str32_remaining = { .len = (str32.len - pos32), .text = str32.text + pos32 }; - Utf32DecodeResult decoded = DecodeUtf32(str32_remaining); - Utf8EncodeResult encoded = EncodeUtf8(decoded.codepoint); - - u8 *dst = PushStructsNoZero(arena, u8, encoded.count8); - CopyBytes(dst, &encoded.chars8, encoded.count8); - - pos32 += 1; - result.len += encoded.count8; - } - - return result; -} - -//- String encode - -/* utf16 <- utf8 */ -String16 String16FromString(Arena *arena, String str8) -{ - String16 result = { - .len = 0, - .text = PushDry(arena, u16) - }; - - u64 pos8 = 0; - while (pos8 < str8.len) - { - String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; - Utf8DecodeResult decoded = DecodeUtf8(str8_remaining); - Utf16EncodeResult encoded = EncodeUtf16(decoded.codepoint); - - u16 *dst = PushStructsNoZero(arena, u16, encoded.count16); - CopyBytes(dst, encoded.chars16, (encoded.count16 << 1)); - - pos8 += decoded.advance8; - result.len += encoded.count16; - } - - return result; -} - -/* utf32 <- utf8 */ -String32 String32FromString(Arena *arena, String str8) -{ - String32 result = { - .len = 0, - .text = PushDry(arena, u32) - }; - - u64 pos8 = 0; - while (pos8 < str8.len) - { - String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; - Utf8DecodeResult decoded = DecodeUtf8(str8_remaining); - Utf32EncodeResult encoded = EncodeUtf32(decoded.codepoint); - - u32 *dst = PushStructNoZero(arena, u32); - *dst = encoded.chars32; - - pos8 += decoded.advance8; - result.len += 1; - } - - return result; -} - -//////////////////////////////// -//~ Legacy null-terminated C string operations - -//- Narrow C strings - -u64 CstrLenNoLimit(char *cstr) -{ - char *end = cstr; - if (cstr) - { - while (*end) - { - ++end; - } - } - return end - cstr; -} - -u64 CstrLen(char *cstr, u64 limit) -{ - char *end = cstr; - if (cstr) - { - for (u64 i = 0; i < limit; ++i) - { - if (*end) - { - ++end; - } - else - { - break; - } - } - } - return end - cstr; -} - -char *CstrFromString(Arena *arena, String src) -{ - u8 *text = PushStructsNoZero(arena, u8, src.len + 1); - CopyBytes(text, src.text, src.len); - text[src.len] = 0; - return (char *)text; -} - -char *CstrFromStringToBuff(String dst_buff, String src) -{ - if (dst_buff.len > 0) - { - u64 len = MinU64(src.len, dst_buff.len - 1); - CopyBytes(dst_buff.text, src.text, len); - dst_buff.text[len] = 0; - } - return (char *)dst_buff.text; -} - -String StringFromCstrNoLimit(char *cstr) -{ - u64 len = CstrLenNoLimit(cstr); - return (String) - { - .len = len, - .text = (u8 *)cstr - }; -} - -String StringFromCstr(char *cstr, u64 limit) -{ - u64 len = CstrLen(cstr, limit); - return (String) - { - .text = (u8 *)cstr, - .len = len - }; -} - -//- Wide C strings - -u64 WstrLenNoLimit(wchar_t *wstr) -{ - wchar_t *end = wstr; - if (end) - { - while (*end) - { - ++end; - } - } - return end - wstr; -} - -u64 WstrLen(wchar_t *wstr, u64 limit) -{ - wchar_t *end = wstr; - if (wstr) - { - for (u64 i = 0; i < limit; ++i) - { - if (*end) - { - ++end; - } - else - { - break; - } - } - } - return end - wstr; -} - -wchar_t *WstrFromString(Arena *arena, String src) -{ - String16 str16 = String16FromString(arena, src); - *PushStructNoZero(arena, u16) = 0; - return (wchar_t *)str16.text; -} - -wchar_t *WstrFromString16(Arena *arena, String16 src) -{ - u16 *text = PushStructsNoZero(arena, u16, src.len + 1); - text[src.len] = 0; - return (wchar_t *)text; -} - -String StringFromWstrNoLimit(Arena *arena, wchar_t *wstr) -{ - String16 str16 = String16FromWstrNoLimit(wstr); - return StringFromString16(arena, str16); -} - -String StringFromWstr(Arena *arena, wchar_t *wstr, u64 limit) -{ - String16 str16 = String16FromWstr(wstr, limit); - return StringFromString16(arena, str16); -} - -String16 String16FromWstrNoLimit(wchar_t *wstr) -{ - u64 len = WstrLenNoLimit(wstr); - return (String16) - { - .len = len, - .text = (u16 *)wstr - }; -} - -String16 String16FromWstr(wchar_t *wstr, u64 limit) -{ - u64 len = WstrLen(wstr, limit); - return (String16) - { - .len = len, - .text = (u16 *)wstr - }; -} diff --git a/src/meta/meta_base/meta_base_string.h b/src/meta/meta_base/meta_base_string.h deleted file mode 100644 index feea4f8e..00000000 --- a/src/meta/meta_base/meta_base_string.h +++ /dev/null @@ -1,169 +0,0 @@ -//////////////////////////////// -//~ String types - -Struct(StringArray) -{ - u64 count; - String *strings; -}; - -Struct(StringListNode) -{ - String s; - StringListNode *next; - StringListNode *prev; -}; - -Struct(StringList) -{ - StringListNode *first; - StringListNode *last; - u64 count; -}; - -//////////////////////////////// -//~ Formatting types - -#define DefaultFmtPrecision 3 -#define IntChars ("0123456789abcdef") - -Enum(FmtKind) -{ - FmtKind_None, - - /* Arbitrary magic numbers for argument validation */ - FmtKind_Char = 0x0f5281df, - FmtKind_String = 0x0a5ffa9a, - FmtKind_Uint = 0x0746f19b, - FmtKind_Sint = 0x08603694, - FmtKind_Hex = 0x0a3d0792, - FmtKind_Ptr = 0x0c4519e4, - FmtKind_Float = 0x04814143, - - FmtKind_End = 0x0ecbc5ae -}; - -Struct(FmtArg) -{ - FmtKind kind; - u32 precision; - u32 zfill; - union - { - u8 c; - String string; - u64 uint; - i64 sint; - void *ptr; - f64 f; - } value; -}; - -//////////////////////////////// -//~ Unicode types - -Struct(CodepointIter) -{ - u32 codepoint; - - /* Internal */ - String src; - u64 pos; -}; - -//////////////////////////////// -//~ Conversion helpers - -String StringFromChar(Arena *arena, char c); -String StringFromU64(Arena *arena, u64 n, u64 base, u64 zfill); -String StringFromI64(Arena *arena, i64 n, u64 base, u64 zfill); -String StringFromPtr(Arena *arena, void *ptr); -String StringFromF64(Arena *arena, f64 f, u32 precision); - -//////////////////////////////// -//~ String helpers - -String PushString(Arena *arena, String src); -String PushStringToBuff(String dst, String src); -String RepeatString(Arena *arena, String src, u64 count); -String CatString(Arena *arena, String str1, String str2); -StringArray SplitString(Arena *arena, String str, String delim); -String IndentString(Arena *arena, String str, u32 indent); -String LowerString(Arena *arena, String str); -b32 EqString(String str1, String str2); -b32 StringContains(String str, String substring); -b32 StringStartsWith(String str, String substring); -b32 StringEndsWith(String str, String substring); - -//////////////////////////////// -//~ String list helpers - -StringListNode *PushStringToList(Arena *arena, StringList *l, String s); -String StringFromList(Arena *arena, StringList l, String separator); - -//////////////////////////////// -//~ Trimming helpers - -String TrimLeft(String s, String pattern); -String TrimRight(String s, String pattern); -String Trim(String s, String pattern); - -//////////////////////////////// -//~ Formatting - -//- Format arg helpers -#define FmtChar(v) (FmtArg) {.kind = FmtKind_Char, .value.c = (v)} -#define FmtString(v) (FmtArg) {.kind = FmtKind_String, .value.string = (v)} -#define FmtUint(v) (FmtArg) {.kind = FmtKind_Uint, .value.uint = (v)} -#define FmtUintZ(v, z) (FmtArg) {.kind = FmtKind_Uint, .value.uint = (v), .zfill = (z)} -#define FmtSint(v) (FmtArg) {.kind = FmtKind_Sint, .value.sint = (v)} -#define FmtHex(v) (FmtArg) {.kind = FmtKind_Hex, .value.uint = (v)} -#define FmtPtr(v) (FmtArg) {.kind = FmtKind_Ptr, .value.ptr = (v)} -#define FmtFloat(v) FmtFloatP(v, DefaultFmtPrecision) -#define FmtFloatP(v, p) (FmtArg) {.kind = FmtKind_Float, .value.f = (v), .precision = (p)} -#define FmtHandle(v) (FmtArg) {.kind = FmtKind_Handle, .value.handle.h64[0] = (v).idx, .value.handle.h64[1] = (v).gen} -#define FmtUid(v) (FmtArg) {.kind = FmtKind_Uid, .value.uid = (v) } -#define FmtEnd (FmtArg) {.kind = FmtKind_End} - -//- Format functions -#define StringF(arena, lit, ...) StringFormat_((arena), Lit(lit), __VA_ARGS__, FmtEnd) -#define StringFormat(arena, fmt, ...) StringFormat_((arena), (fmt), __VA_ARGS__, FmtEnd) -String StringFormat_(Arena *arena, String fmt, ...); -String StringFormatV(Arena *arena, String fmt, va_list args); - -//////////////////////////////// -//~ Unicode operations - -//- Iter -CodepointIter BeginCodepointIter(String str); -b32 AdvanceCodepointIter(CodepointIter *iter); -void EndCodepointIter(CodepointIter *iter); - -//- Decode string -String StringFromString16(Arena *arena, String16 str16); -String StringFromString32(Arena *arena, String32 str32); - -//- Encode string -String16 String16FromString(Arena *arena, String str8); -String32 String32FromString(Arena *arena, String str8); - -//////////////////////////////// -//~ Legacy null-terminated C string operations - -//- Narrow strings -u64 CstrLenNoLimit(char *cstr); -u64 CstrLen(char *cstr, u64 limit); -char *CstrFromString(Arena *arena, String src); -char *CstrFromStringToBuff(String dest_buff, String src); -String StringFromCstrNoLimit(char *cstr); -String StringFromCstr(char *cstr, u64 limit); - -//- Wide strings -u64 WstrLenNoLimit(wchar_t *wstr); -u64 WstrLen(wchar_t *wstr, u64 limit); -wchar_t *WstrFromString(Arena *arena, String src); -wchar_t *WstrFromString16(Arena *arena, String16 src); -String StringFromWstrNoLimit(Arena *arena, wchar_t *wstr); -String StringFromWstr(Arena *arena, wchar_t *wstr, u64 limit); -String16 String16FromWstrNoLimit(wchar_t *wstr); -String16 String16FromWstr(wchar_t *wstr, u64 limit); diff --git a/src/meta/meta_base/meta_base_uni.c b/src/meta/meta_base/meta_base_uni.c deleted file mode 100644 index f7a498bf..00000000 --- a/src/meta/meta_base/meta_base_uni.c +++ /dev/null @@ -1,245 +0,0 @@ -//////////////////////////////// -//~ Utf8 - -//- Decode - -Utf8DecodeResult DecodeUtf8(String str) -{ - LocalPersist const u8 lengths[32] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5 - }; - - Utf8DecodeResult result = ZI; - u32 codepoint = U32Max; - u32 advance = 0; - if (str.len > 0) - { - u8 c0 = str.text[0]; - u8 utf8_len = lengths[c0 >> 3]; - - advance = 1; - switch (utf8_len) - { - case 1: - { - codepoint = c0; - } break; - - case 2: - { - if (str.len >= 2) - { - u8 c1 = str.text[1]; - if (lengths[c1 >> 3] == 0) - { - codepoint = (c1 & 0x3F) << 0; - codepoint |= (c0 & 0x1F) << 6; - advance = 2; - } - } - } break; - - case 3: - { - if (str.len >= 3) - { - u8 c1 = str.text[1]; - u8 c2 = str.text[2]; - if (lengths[c1 >> 3] == 0 && - lengths[c2 >> 3] == 0) - { - codepoint = (c2 & 0x3F) << 0; - codepoint |= (c1 & 0x3F) << 6; - codepoint |= (c0 & 0x0F) << 12; - advance = 3; - } - } - } break; - - case 4: - { - if (str.len >= 4) - { - u8 c1 = str.text[1]; - u8 c2 = str.text[2]; - u8 c3 = str.text[3]; - if (lengths[c1 >> 3] == 0 && - lengths[c2 >> 3] == 0 && - lengths[c3 >> 3] == 0) - { - codepoint = (c3 & 0x3F) << 0; - codepoint |= (c2 & 0x3F) << 6; - codepoint |= (c1 & 0x3F) << 12; - codepoint |= (c0 & 0x07) << 16; - advance = 3; - } - } - } break; - - default: break; - } - } - - result.advance8 = advance; - result.codepoint = codepoint; - return result; -} - -//- Encode - -Utf8EncodeResult EncodeUtf8(u32 codepoint) -{ - Utf8EncodeResult result = ZI; - - if (codepoint <= 0x7F) - { - result.count8 = 1; - result.chars8[0] = codepoint; - } - else if (codepoint <= 0x7FF) - { - result.count8 = 2; - result.chars8[1] = 0x80 | ((codepoint >> 0) & 0x3F); - result.chars8[0] = 0xC0 | ((codepoint >> 6) & 0x1F); - } - else if (codepoint <= 0xFFFF) - { - result.count8 = 3; - result.chars8[2] = 0x80 | ((codepoint >> 0) & 0x3F); - result.chars8[1] = 0x80 | ((codepoint >> 6) & 0x3F); - result.chars8[0] = 0xE0 | ((codepoint >> 12) & 0x0F); - } - else if (codepoint <= 0x10FFFF) - { - result.count8 = 4; - result.chars8[3] = 0x80 | ((codepoint >> 0) & 0x3F); - result.chars8[2] = 0x80 | ((codepoint >> 6) & 0x3F); - result.chars8[1] = 0x80 | ((codepoint >> 12) & 0x3F); - result.chars8[0] = 0xF0 | ((codepoint >> 18) & 0x07); - } - else - { - /* Invalid codepoint */ - result.count8 = 1; - result.chars8[0] = '?'; - } - - return result; -} - -//////////////////////////////// -//~ Utf16 - -//- Decode - -Utf16DecodeResult DecodeUtf16(String16 str) -{ - Utf16DecodeResult result = ZI; - u32 codepoint = U32Max; - u32 advance = 0; - - if (str.len >= 1) - { - u16 c0 = str.text[0]; - codepoint = c0; - advance = 1; - if (str.len >= 2) - { - u16 c1 = str.text[1]; - if ((0xD800 <= c0 && c0 < 0xDC00) && (0xDC00 <= c1 && c1 < 0xE000)) - { - codepoint = (c1 & 0x3FF) << 0; - codepoint |= (c0 & 0x3FF) << 10; - advance = 2; - } - } - } - - result.advance16 = advance; - result.codepoint = codepoint; - return result; -} - -//- Encode - -Utf16EncodeResult EncodeUtf16(u32 codepoint) -{ - Utf16EncodeResult result = ZI; - - if (codepoint <= 0xFFFF) - { - result.count16 = 1; - result.chars16[0] = codepoint; - } - else if (codepoint <= 0x10FFFF) - { - result.count16 = 2; - result.chars16[1] = 0xDC00 | ((codepoint >> 0) & 0x3FF); - result.chars16[0] = 0xD800 | ((codepoint >> 10) & 0x3FF); - } - else - { - /* Invalid codepoint */ - result.count16 = 1; - result.chars16[0] = '?'; - } - - return result; -} - -//- Surrogate check - -b32 IsUtf16HighSurrogate(u16 c) -{ - return 0xD800 <= c && c < 0xDC00; -} - -b32 IsUtf16LowSurrogate(u16 c) -{ - return 0xDC00 <= c && c < 0xE000; -} - -//////////////////////////////// -//~ Utf32 - -//- Decode - -Utf32DecodeResult DecodeUtf32(String32 str) -{ - Utf32DecodeResult result = ZI; - u32 codepoint = U32Max; - u32 advance = 0; - - if (str.len >= 1) - { - u32 c = str.text[0]; - advance = 1; - if (c <= 0x10FFFF) - { - codepoint = c; - } - } - - result.advance32 = advance; - result.codepoint = codepoint; - return result; -} - -//- Encode - -Utf32EncodeResult EncodeUtf32(u32 codepoint) -{ - Utf32EncodeResult result = ZI; - - if (codepoint <= 0x10FFFF) - { - result.chars32 = codepoint; - } - else - { - /* Invalid codepoint */ - result.chars32 = '?'; - } - - return result; -} diff --git a/src/meta/meta_base/meta_base_uni.h b/src/meta/meta_base/meta_base_uni.h deleted file mode 100644 index f542a12e..00000000 --- a/src/meta/meta_base/meta_base_uni.h +++ /dev/null @@ -1,64 +0,0 @@ -//////////////////////////////// -//~ Utf8 types - -Struct(Utf8DecodeResult) -{ - u32 advance8; - u32 codepoint; -}; - -Struct(Utf8EncodeResult) -{ - u32 count8; - u8 chars8[4]; -}; - -//////////////////////////////// -//~ Utf16 types - -Struct(Utf16DecodeResult) -{ - u32 advance16; - u32 codepoint; -}; - -Struct(Utf16EncodeResult) -{ - u32 count16; - u16 chars16[2]; -}; - -//////////////////////////////// -//~ Utf32 types - -Struct(Utf32DecodeResult) -{ - u32 advance32; - u32 codepoint; -}; - -Struct(Utf32EncodeResult) -{ - u32 chars32; -}; - -//////////////////////////////// -//~ Utf8 operations - -Utf8DecodeResult DecodeUtf8(String str); -Utf8EncodeResult EncodeUtf8(u32 codepoint); - -//////////////////////////////// -//~ Utf16 operations - -Utf16DecodeResult DecodeUtf16(String16 str); -Utf16EncodeResult EncodeUtf16(u32 codepoint); - -b32 IsUtf16HighSurrogate(u16 c); -b32 IsUtf16LowSurrogate(u16 c); - -//////////////////////////////// -//~ Utf32 operations - -Utf32DecodeResult DecodeUtf32(String32 str); -Utf32EncodeResult EncodeUtf32(u32 codepoint); diff --git a/src/meta/meta_base/meta_base_util.h b/src/meta/meta_base/meta_base_util.h deleted file mode 100644 index ecd0a761..00000000 --- a/src/meta/meta_base/meta_base_util.h +++ /dev/null @@ -1,296 +0,0 @@ -//////////////////////////////// -//~ Hash types - -#define Fnv64Basis 0xCBF29CE484222325 - -//////////////////////////////// -//~ Mergesort types - -/* Compare functions should - * return a positive value if a should go before b - * return a negative value if a should go after b - * return 0 otherwise - */ -#define MergesortCompareFuncDef(name, arg_a, arg_b, arg_udata) i32 name(void *arg_a, void *arg_b, void *arg_udata) -typedef MergesortCompareFuncDef(MergesortCompareFunc, a, b, udata); - -//////////////////////////////// -//~ Dict types - -Struct(DictEntry) -{ - u64 hash; - u64 value; - DictEntry *prev_in_bin; - DictEntry *next_in_bin; - DictEntry *prev; - DictEntry *next; -}; - -Struct(DictBin) -{ - DictEntry *first; - DictEntry *last; -}; - -Struct(Dict) -{ - u64 bins_count; - DictBin *bins; - DictEntry *first_free; - DictEntry *first; - DictEntry *last; -}; - -//////////////////////////////// -//~ Hash utils - -/* FNV-1a parameters for different hash sizes: - * https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_hash_parameters - */ -Inline u64 HashFnv64(u64 seed, String s) -{ - u64 hash = seed; - for (u64 i = 0; i < s.len; ++i) - { - hash ^= (u8)s.text[i]; - hash *= 0x100000001B3; - } - return hash; -} - -//////////////////////////////// -//~ Mergesort utils - -Inline void MergesortInternal(u8 *left, u8 *right, u8 *items, u64 left_count, u64 right_count, u64 item_size, MergesortCompareFunc *callback, void *udata) -{ - /* Sort */ - u64 i = 0; - u64 l = 0; - u64 r = 0; - while (l < left_count && r < right_count) - { - u8 *dst = items + (i * item_size); - u8 *left_item = left + (l * item_size); - u8 *right_item = right + (r * item_size); - ++i; - if (callback(left_item, right_item, udata) > 0) - { - CopyBytes(dst, left_item, item_size); - ++l; - } - else - { - CopyBytes(dst, right_item, item_size); - ++r; - } - } - /* Copy remaining */ - if (l != left_count) - { - u64 remaining_count = left_count - l; - u64 remaining_bytes = remaining_count * item_size; - u8 *dst = items + (i * item_size); - u8 *src = left + (l * item_size); - CopyBytes(dst, src, remaining_bytes); - } - else if (r != right_count) - { - u64 remaining_count = right_count - r; - u64 remaining_bytes = remaining_count * item_size; - u8 *dst = items + (i * item_size); - u8 *src = right + (r * item_size); - CopyBytes(dst, src, remaining_bytes); - } -} - -Inline void Mergesort(void *items, u64 item_count, u64 item_size, MergesortCompareFunc *callback, void *udata) -{ - if (item_count > 1) - { - TempArena scratch = BeginScratchNoConflict(); - u64 left_count = item_count / 2; - u64 right_count = item_count - left_count; - - u64 left_size = left_count * item_size; - u64 right_size = right_count * item_size; - - u8 *left = PushStructsNoZero(scratch.arena, u8, left_size); - u8 *right = PushStructsNoZero(scratch.arena, u8, right_size); - CopyBytes(left, items, left_size); - CopyBytes(right, (u8 *)items + left_size, right_size); - - Mergesort(left, left_count, item_size, callback, udata); - Mergesort(right, right_count, item_size, callback, udata); - MergesortInternal(left, right, (u8 *)items, left_count, right_count, item_size, callback, udata); - EndScratch(scratch); - } -} - -//////////////////////////////// -//~ Dict utils - -//- Dict init - -Inline Dict *InitDict(Arena *arena, u64 bins_count) -{ - __prof; - Dict *dict = PushStruct(arena, Dict); - dict->bins_count = MaxU64(bins_count, 1); /* Ensure at least 1 bin */ - dict->bins = PushStructs(arena, DictBin, dict->bins_count); - return dict; -} - -Inline void ResetDict(Dict *dict) -{ - ZeroBytes(dict->bins, sizeof(*dict->bins) * dict->bins_count); - if (dict->first) - { - dict->last->next = dict->first_free; - dict->first_free = dict->first; - } -} - -//- Dict set - -Inline DictEntry *EnsureDictEntry(Arena *arena, Dict *dict, u64 hash) -{ - __prof; - DictBin *bin = &dict->bins[hash % dict->bins_count]; - - DictEntry *entry = bin->first; - while (entry) - { - if (hash == entry->hash) - { - /* Existing match found */ - break; - } - entry = entry->next_in_bin; - } - - /* No match found, create new entry */ - if (!entry) - { - if (dict->first_free) - { - entry = dict->first_free; - dict->first_free = entry->next; - } - else - { - entry = PushStructNoZero(arena, DictEntry); - } - ZeroStruct(entry); - entry->hash = hash; - if (bin->last) - { - bin->last->next_in_bin = entry; - entry->prev_in_bin = bin->last; - } - else - { - bin->first = entry; - } - bin->last = entry; - if (dict->last) - { - dict->last->next = entry; - entry->prev = dict->last; - } - else - { - dict->first = entry; - } - dict->last = entry; - } - - return entry; -} - -Inline void SetDictValue(Arena *arena, Dict *dict, u64 hash, u64 value) -{ - __prof; - DictEntry *entry = EnsureDictEntry(arena, dict, hash); - entry->value = value; -} - -//- Dict remove - -Inline void RemoveDictEntry(Dict *dict, DictEntry *entry) -{ - /* Remove from bin */ - { - DictBin *bin = &dict->bins[entry->hash % dict->bins_count]; - DictEntry *prev_in_bin = entry->prev_in_bin; - DictEntry *next_in_bin = entry->next_in_bin; - if (prev_in_bin) - { - prev_in_bin->next_in_bin = next_in_bin; - } - else - { - bin->first = next_in_bin; - } - if (next_in_bin) - { - next_in_bin->prev_in_bin = prev_in_bin; - } - else - { - bin->last = prev_in_bin; - } - } - /* Remove from list */ - { - DictEntry *prev = entry->prev; - DictEntry *next = entry->next; - if (prev) - { - prev->next = next; - } - else - { - dict->first = next; - } - if (next) - { - next->prev = prev; - } - else - { - dict->last = prev; - } - } - /* Insert into free list */ - { - entry->next = dict->first_free; - dict->first_free = entry; - } -} - -//- Dict index - -Inline DictEntry *DictEntryFromHash(Dict *dict, u64 hash) -{ - __prof; - DictEntry *result = 0; - DictBin *bin = &dict->bins[hash % dict->bins_count]; - for (DictEntry *entry = bin->first; entry; entry = entry->next_in_bin) - { - if (hash == entry->hash) - { - /* Match found */ - result = entry; - break; - } - } - return result; -} - -Inline u64 DictValueFromHash(Dict *dict, u64 hash) -{ - __prof; - DictEntry *entry = DictEntryFromHash(dict, hash); - return entry ? entry->value : 0; -} diff --git a/src/meta/meta_base/meta_base_win32/meta_base_win32.c b/src/meta/meta_base/meta_base_win32/meta_base_win32.c deleted file mode 100644 index e86273b6..00000000 --- a/src/meta/meta_base/meta_base_win32/meta_base_win32.c +++ /dev/null @@ -1,59 +0,0 @@ -W32_SharedState W32_shared_state = ZI; - -//////////////////////////////// -//~ @hookdef OS startup hook - -void StartupBase(void) -{ - W32_SharedState *g = &W32_shared_state; - g->tls_index = TlsAlloc(); - TlsSetValue(g->tls_index, 0); -} - -//////////////////////////////// -//~ @hookdef Core panic hooks - -/* TODO: Remove stdio & printf */ -#include - -b32 Panic(String msg) -{ - char msg_cstr[4096]; - CstrFromStringToBuff(StringFromArray(msg_cstr), msg); - { - u32 mb_flags = MB_SETFOREGROUND | MB_ICONERROR; - MessageBoxExA(0, msg_cstr, "Fatal error", mb_flags, 0); - } - printf(msg_cstr); - fflush(stdout); - if ((1)) /* Supress unreachable code warning */ - { - ExitProcess(1); - } - return 0; -} - -//////////////////////////////// -//~ @hookdef Debugger hooks - -b32 IsRunningInDebugger(void) -{ - return IsDebuggerPresent(); -} - -//////////////////////////////// -//~ @hookdef Thread hooks - -i16 ThreadId(void) -{ - W32_SharedState *g = &W32_shared_state; - return (i16)(i64)TlsGetValue(g->tls_index); -} - -//////////////////////////////// -//~ @hookdef Randomness hooks - -void TrueRand(String buffer) -{ - BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (u8 *)buffer.text, buffer.len, 0); -} diff --git a/src/meta/meta_base/meta_base_win32/meta_base_win32.h b/src/meta/meta_base/meta_base_win32/meta_base_win32.h deleted file mode 100644 index 5eb5cea8..00000000 --- a/src/meta/meta_base/meta_base_win32/meta_base_win32.h +++ /dev/null @@ -1,21 +0,0 @@ -//////////////////////////////// -//~ Win32 libs - -#ifndef BCRYPT_RNG_ALG_HANDLE -#define BCRYPT_RNG_ALG_HANDLE ((void *)0x00000081) -u32 BCryptGenRandom(void *algorithm, u8 *buffer, u32 buffer_size, u32 flags); -#endif - -#pragma comment(lib, "kernel32") -#pragma comment(lib, "user32") -#pragma comment(lib, "bcrypt") - -//////////////////////////////// -//~ Shared state - -Struct(W32_SharedState) -{ - DWORD tls_index; -}; - -extern W32_SharedState W32_shared_state; diff --git a/src/meta/meta_base/meta_base_win32/meta_base_win32_inc.h b/src/meta/meta_base/meta_base_win32/meta_base_win32_inc.h deleted file mode 100644 index c32f4de4..00000000 --- a/src/meta/meta_base/meta_base_win32/meta_base_win32_inc.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "meta_base_win32.h" -#include "meta_base_win32.c" diff --git a/src/meta/meta_os/meta_os_win32/meta_os_win32.c b/src/meta/meta_os/meta_os_win32/meta_os_win32.c index c61b3aa2..bb21efe6 100644 --- a/src/meta/meta_os/meta_os_win32/meta_os_win32.c +++ b/src/meta/meta_os/meta_os_win32/meta_os_win32.c @@ -195,7 +195,7 @@ OS_CommandResult OS_RunCommand(Arena *arena, String cmd) SECURITY_ATTRIBUTES sa = ZI; sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; + sa.bInheritHandle = 1; HANDLE pipe_read, pipe_write; if (!CreatePipe(&pipe_read, &pipe_write, &sa, 0)) @@ -215,7 +215,7 @@ OS_CommandResult OS_RunCommand(Arena *arena, String cmd) PROCESS_INFORMATION pi = ZI; result.output.text = PushDry(arena, u8); - if (!CreateProcessW(NULL, cmd_wstr, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) + if (!CreateProcessW(0, cmd_wstr, 0, 0, 1, 0, 0, 0, &si, &pi)) { /* TODO: error handling */ Assert(0); @@ -228,7 +228,7 @@ OS_CommandResult OS_RunCommand(Arena *arena, String cmd) { u8 buff[4096] = ZI; DWORD bytes_read = 0; - if (!ReadFile(pipe_read, buff, countof(buff), &bytes_read, NULL)) + if (!ReadFile(pipe_read, buff, countof(buff), &bytes_read, 0)) { if (GetLastError() == ERROR_BROKEN_PIPE) { diff --git a/src/mixer/mixer.lay b/src/mixer/mixer.lay index a0a65899..a399d811 100644 --- a/src/mixer/mixer.lay +++ b/src/mixer/mixer.lay @@ -1,7 +1,6 @@ @Layer mixer //- Dependencies -@Dep base @Dep platform @Dep sound diff --git a/src/mp3/mp3.lay b/src/mp3/mp3.lay index f99e45ad..0f803924 100644 --- a/src/mp3/mp3.lay +++ b/src/mp3/mp3.lay @@ -1,8 +1,5 @@ @Layer mp3 -//- Dependencies -@Dep base - //- Api @IncludeC mp3_core.h diff --git a/src/net/net.lay b/src/net/net.lay index c9201e7b..60afcd07 100644 --- a/src/net/net.lay +++ b/src/net/net.lay @@ -1,7 +1,6 @@ @Layer net //- Dependencies -@Dep base @Dep platform @Dep bitbuff diff --git a/src/platform/platform.lay b/src/platform/platform.lay index ec4550de..116db360 100644 --- a/src/platform/platform.lay +++ b/src/platform/platform.lay @@ -1,8 +1,5 @@ @Layer platform -//- Dependencies -@Dep base - //- Api @IncludeC platform_core.h @IncludeC platform_log.h diff --git a/src/playback/playback.lay b/src/playback/playback.lay index 0601c7b5..bfa0a79d 100644 --- a/src/playback/playback.lay +++ b/src/playback/playback.lay @@ -1,7 +1,6 @@ @Layer playback //- Dependencies -@Dep base @Dep platform @Dep mixer diff --git a/src/pp/pp.lay b/src/pp/pp.lay index 178cee1f..756768b6 100644 --- a/src/pp/pp.lay +++ b/src/pp/pp.lay @@ -1,7 +1,6 @@ @Layer pp //- Dependencies -@Dep base @Dep gpu @Dep sprite @Dep font diff --git a/src/pp/pp_core.c b/src/pp/pp_core.c index 45ae36c3..fc0ab703 100644 --- a/src/pp/pp_core.c +++ b/src/pp/pp_core.c @@ -631,7 +631,7 @@ void UpdateUser(P_Window *window) P_WindowEvent *event = &events.events[ent_index]; if (event->kind == P_WindowEventKind_Quit) { - Exit(); + SignalExit(0); } if (event->kind == P_WindowEventKind_ButtonUp) @@ -639,7 +639,7 @@ void UpdateUser(P_Window *window) /* Escape quit */ if (event->button == P_Btn_ESC) { - Exit(); + SignalExit(0); } } diff --git a/src/rendertest/rendertest.lay b/src/rendertest/rendertest.lay index ec01a912..eeebea25 100644 --- a/src/rendertest/rendertest.lay +++ b/src/rendertest/rendertest.lay @@ -1,7 +1,6 @@ @Layer rendertest //- Dependencies -@Dep base @Dep gpu @Dep sprite @Dep font diff --git a/src/resource/resource.lay b/src/resource/resource.lay index 07c87be6..da92bfad 100644 --- a/src/resource/resource.lay +++ b/src/resource/resource.lay @@ -1,7 +1,6 @@ @Layer resource //- Dependencies -@Dep base @Dep platform @Dep tar @Dep inc diff --git a/src/sound/sound.lay b/src/sound/sound.lay index e033b537..9c49552b 100644 --- a/src/sound/sound.lay +++ b/src/sound/sound.lay @@ -1,7 +1,6 @@ @Layer sound //- Dependencies -@Dep base @Dep platform @Dep mp3 @Dep resource diff --git a/src/sprite/sprite.lay b/src/sprite/sprite.lay index 517d4907..218c3060 100644 --- a/src/sprite/sprite.lay +++ b/src/sprite/sprite.lay @@ -1,7 +1,6 @@ @Layer sprite //- Dependencies -@Dep base @Dep platform @Dep gpu @Dep ase diff --git a/src/tar/tar.lay b/src/tar/tar.lay index 977832f3..c638f880 100644 --- a/src/tar/tar.lay +++ b/src/tar/tar.lay @@ -1,7 +1,6 @@ @Layer tar //- Dependencies -@Dep base @Dep platform @Dep bitbuff diff --git a/src/ttf/ttf.lay b/src/ttf/ttf.lay index a633e130..3ec3f9e3 100644 --- a/src/ttf/ttf.lay +++ b/src/ttf/ttf.lay @@ -1,8 +1,5 @@ @Layer ttf -//- Dependencies -@Dep base - //- Api @IncludeC ttf_core.h diff --git a/src/watch/watch.lay b/src/watch/watch.lay index bcad839a..b3cff368 100644 --- a/src/watch/watch.lay +++ b/src/watch/watch.lay @@ -1,7 +1,6 @@ @Layer watch //- Dependencies -@Dep base @Dep platform //- Api