diff --git a/compile.bat b/compile.bat new file mode 100644 index 0000000..b623ea0 --- /dev/null +++ b/compile.bat @@ -0,0 +1,2 @@ +@echo off +build\build_app_msvc_win32_debug.bat \ No newline at end of file diff --git a/msdev.bat b/msdev.bat deleted file mode 100644 index 31ca5aa..0000000 --- a/msdev.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off - -remedybg build\win32_foldhaus.rdbg \ No newline at end of file diff --git a/src/app/editor/foldhaus_editor.cpp b/src/app/editor/foldhaus_editor.cpp index 6d71ca3..d6abf2e 100644 --- a/src/app/editor/foldhaus_editor.cpp +++ b/src/app/editor/foldhaus_editor.cpp @@ -144,8 +144,8 @@ Editor_Render(app_state* State, context* Context, render_command_buffer* RenderB // Draw the Interface if (State->Interface.DrawOrderRoot != 0) { - ui_widget Widget = *State->Interface.DrawOrderRoot; - Editor_DrawWidget(State, Context, RenderBuffer, Widget, Context->WindowBounds); + ui_widget* Widget = State->Interface.DrawOrderRoot; + Editor_DrawWidgetList(State, Context, RenderBuffer, Widget, Context->WindowBounds); } Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext); diff --git a/src/app/editor/foldhaus_editor_draw.h b/src/app/editor/foldhaus_editor_draw.h index 065bc21..f4a4edc 100644 --- a/src/app/editor/foldhaus_editor_draw.h +++ b/src/app/editor/foldhaus_editor_draw.h @@ -77,12 +77,11 @@ Editor_GetWidgetFillBounds(ui_widget Widget) return Result; } +internal void Editor_DrawWidgetList(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget Widget, rect2 ParentClipBounds); + internal void -Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget Widget, rect2 ParentClipBounds) +Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget Widget, rect2 WidgetParentUnion) { - rect2 WidgetParentUnion = Widget.Bounds; - WidgetParentUnion = Rect2Union(Widget.Bounds, ParentClipBounds); - bool IsActiveWidget = ui_WidgetIdsEqual(Widget.Id, State->Interface.ActiveWidget); ; if (!Widget.Parent || (Rect2Area(WidgetParentUnion) > 0)) @@ -146,18 +145,27 @@ Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* Ren PushRenderBoundingBox2D(RenderBuffer, WidgetParentUnion.Min, WidgetParentUnion.Max, Thickness, Color); } } - - if (Widget.ChildrenRoot) - { - Editor_DrawWidget(State, Context, RenderBuffer, *Widget.ChildrenRoot, WidgetParentUnion); - } - - if (Widget.Next) - { - Editor_DrawWidget(State, Context, RenderBuffer, *Widget.Next, ParentClipBounds); - } } +internal void Editor_DrawWidgetList(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget* Widget, rect2 ParentClipBounds) +{ + ui_widget* WidgetAt = Widget; + while (WidgetAt) + { + rect2 WidgetParentUnion = WidgetAt->Bounds; + WidgetParentUnion = Rect2Union(WidgetAt->Bounds, ParentClipBounds); + + Editor_DrawWidget(State, Context, RenderBuffer, *WidgetAt, WidgetParentUnion); + + if (WidgetAt->ChildrenRoot) + { + Editor_DrawWidgetList(State, Context, RenderBuffer, WidgetAt->ChildrenRoot, WidgetParentUnion); + } + + WidgetAt = WidgetAt->Next; + } +} + #define FOLDHAUS_EDITOR_DRAW_H #endif // FOLDHAUS_EDITOR_DRAW_H \ No newline at end of file diff --git a/src/app/interface.h b/src/app/editor/interface.h similarity index 99% rename from src/app/interface.h rename to src/app/editor/interface.h index 566b1ad..6b91bef 100644 --- a/src/app/interface.h +++ b/src/app/editor/interface.h @@ -1582,7 +1582,7 @@ ui_InterfaceCreate(context Context, interface_config Style, gs_memory_arena* Per Result.WidgetsCountMax = 4096; Result.Widgets = PushArray(Permanent, ui_widget, Result.WidgetsCountMax); Result.PerFrameMemory = PushStruct(Permanent, gs_memory_arena); - *Result.PerFrameMemory = CreateMemoryArena(Context.ThreadContext.Allocator); + *Result.PerFrameMemory = CreateMemoryArena(Context.ThreadContext.Allocator, "Interface Per Frame Memory Arena", KB(32)); InterfaceAssert(Result.PerFrameMemory); Result.Permanent = Permanent; diff --git a/src/app/editor/panels/foldhaus_panel_file_view.h b/src/app/editor/panels/foldhaus_panel_file_view.h index 0910e66..050bd0a 100644 --- a/src/app/editor/panels/foldhaus_panel_file_view.h +++ b/src/app/editor/panels/foldhaus_panel_file_view.h @@ -90,7 +90,7 @@ FileView_Init(panel* Panel, app_state* State, context Context) // TODO: :FreePanelMemory file_view_state* FileViewState = PushStruct(&State->Permanent, file_view_state); Panel->StateMemory = StructToData(FileViewState, file_view_state); - FileViewState->FileNamesArena = CreateMemoryArena(Context.ThreadContext.Allocator); + FileViewState->FileNamesArena = CreateMemoryArena(Context.ThreadContext.Allocator, "File View - File Names Arena"); // TODO(pjs): this shouldn't be stored in permanent FileViewState->DisplayDirectory = PushString(&State->Permanent, 1024); diff --git a/src/app/editor/panels/foldhaus_panel_profiler.h b/src/app/editor/panels/foldhaus_panel_profiler.h index 405b50f..82e7d6f 100644 --- a/src/app/editor/panels/foldhaus_panel_profiler.h +++ b/src/app/editor/panels/foldhaus_panel_profiler.h @@ -163,6 +163,44 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, deb ui_EndList(Interface); } +internal void +RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state* State, context Context, gs_memory_arena* Memory) +{ + gs_allocator_debug Debug = *Context.ThreadContext.Allocator.Debug; + gs_string TempString = PushString(State->Transient, 256); + + u64 MemFootprint = Debug.TotalAllocSize; + u64 AllocCount = Debug.AllocationsCount; + PrintF(&TempString, "Total Memory Size: %lld | Allocations: %lld", MemFootprint, AllocCount); + ui_Label(Interface, TempString); + + ui_column_spec ColumnWidths[] = { + { UIColumnSize_Fill, 0 }, + { UIColumnSize_Fixed,256 }, + }; + ui_BeginRow(Interface, 2, &ColumnWidths[0]); + { + ui_Label(Interface, MakeString("Location")); + ui_Label(Interface, MakeString("Alloc Size")); + } + ui_EndRow(Interface); + + ui_BeginList(Interface, MakeString("Alloc List"), 10, Debug.AllocationsCount); + ui_BeginRow(Interface, 2, &ColumnWidths[0]); + for (s32 n = 0; n < Debug.AllocationsCount; n++) + { + gs_debug_allocation A = Debug.Allocations[n]; + + PrintF(&TempString, "%S", A.Location); + ui_Label(Interface, TempString); + + PrintF(&TempString, "%lld bytes", A.Size); + ui_Label(Interface, TempString); + } + ui_EndRow(Interface); + ui_EndList(Interface); +} + GSMetaTag(panel_render); GSMetaTag(panel_type_profiler); internal void @@ -234,24 +272,39 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend ui_BeginRow(&State->Interface, 8); { - if (ui_Button(&State->Interface, MakeString("Scope View"))) + if (ui_Button(&State->Interface, MakeString("Profiler"))) { - GlobalDebugServices->Interface.FrameView = FRAME_VIEW_PROFILER; + GlobalDebugServices->Interface.FrameView = DebugUI_Profiler; } if (ui_Button(&State->Interface, MakeString("List View"))) { - GlobalDebugServices->Interface.FrameView = FRAME_VIEW_SCOPE_LIST; + GlobalDebugServices->Interface.FrameView = DebugUI_ScopeList; + } + if (ui_Button(&State->Interface, MakeString("Memory"))) + { + GlobalDebugServices->Interface.FrameView = DebugUI_MemoryView; } } ui_EndRow(&State->Interface); - if (GlobalDebugServices->Interface.FrameView == FRAME_VIEW_PROFILER) + switch (GlobalDebugServices->Interface.FrameView) { - RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory); - } - else - { - RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory); + case DebugUI_Profiler: + { + RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory); + }break; + + case DebugUI_ScopeList: + { + RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory); + }break; + + case DebugUI_MemoryView: + { + RenderProfiler_MemoryView(&State->Interface, Layout, State, Context, Memory); + }break; + + InvalidDefaultCase; } ui_PopLayout(&State->Interface, MakeString("Profiler Layout")); diff --git a/src/app/engine/assembly/foldhaus_assembly.cpp b/src/app/engine/assembly/foldhaus_assembly.cpp index 4ae1a6c..1a8cb6f 100644 --- a/src/app/engine/assembly/foldhaus_assembly.cpp +++ b/src/app/engine/assembly/foldhaus_assembly.cpp @@ -206,7 +206,7 @@ LoadAssembly (assembly_array* Assemblies, led_system* LedSystem, gs_memory_arena gs_const_string FileName = Substring(Path, IndexOfLastSlash + 1, Path.Length); assembly* NewAssembly = AssemblyArray_Take(Assemblies); - NewAssembly->Arena = CreateMemoryArena(Context.ThreadContext.Allocator); + NewAssembly->Arena = CreateMemoryArena(Context.ThreadContext.Allocator, "Assembly Arena"); parser AssemblyParser = ParseAssemblyFile(NewAssembly, FileName, AssemblyFileText, Scratch); if (AssemblyParser.Success) diff --git a/src/app/engine/foldhaus_addressed_data.h b/src/app/engine/foldhaus_addressed_data.h index c27bd59..8339b6e 100644 --- a/src/app/engine/foldhaus_addressed_data.h +++ b/src/app/engine/foldhaus_addressed_data.h @@ -100,7 +100,7 @@ AddressedDataBufferList_Create(gs_thread_context TC) { addressed_data_buffer_list Result = {}; Result.Arena = AllocatorAllocStruct(TC.Allocator, gs_memory_arena); - *Result.Arena = CreateMemoryArena(TC.Allocator); + *Result.Arena = CreateMemoryArena(TC.Allocator, "Addressed Data Buffer List Arena"); return Result; } diff --git a/src/app/foldhaus_app.cpp b/src/app/foldhaus_app.cpp index df1df6a..e91070d 100644 --- a/src/app/foldhaus_app.cpp +++ b/src/app/foldhaus_app.cpp @@ -24,7 +24,7 @@ INITIALIZE_APPLICATION(InitializeApplication) app_state* State = (app_state*)Context.MemoryBase; *State = {}; - State->Permanent = CreateMemoryArena(Context.ThreadContext.Allocator); + State->Permanent = CreateMemoryArena(Context.ThreadContext.Allocator, "Permanent"); State->Transient = Context.ThreadContext.Transient; State->Assemblies = AssemblyArray_Create(8, &State->Permanent); @@ -91,6 +91,8 @@ INITIALIZE_APPLICATION(InitializeApplication) Panel_SetType(Hierarchy, &State->PanelSystem, PanelType_AssemblyDebug, State, Context); } + + State->RunEditor = true; } UPDATE_AND_RENDER(UpdateAndRender) @@ -104,7 +106,10 @@ UPDATE_AND_RENDER(UpdateAndRender) // incorrect to clear the arena, and then access the memory later. ClearArena(State->Transient); - Editor_Update(State, Context, InputQueue); + if (State->RunEditor) + { + Editor_Update(State, Context, InputQueue); + } AnimationSystem_Update(&State->AnimationSystem, Context->DeltaTime); if (AnimationSystem_NeedsRender(State->AnimationSystem)) @@ -123,7 +128,10 @@ UPDATE_AND_RENDER(UpdateAndRender) State->Assemblies, State->LedSystem); - Editor_Render(State, Context, RenderBuffer); + if (State->RunEditor) + { + Editor_Render(State, Context, RenderBuffer); + } // NOTE(pjs): Building data buffers to be sent out to the sculpture // This array is used on the platform side to actually send the information diff --git a/src/app/foldhaus_app.h b/src/app/foldhaus_app.h index 43ded68..f18ea3f 100644 --- a/src/app/foldhaus_app.h +++ b/src/app/foldhaus_app.h @@ -13,7 +13,7 @@ #include "../gs_libs/gs_font.h" #include "foldhaus_log.h" -#include "interface.h" +#include "editor/interface.h" #include "engine/foldhaus_network_ordering.h" @@ -42,7 +42,7 @@ typedef struct panel panel; #include "engine/animation/foldhaus_animation_renderer.cpp" #include "engine/user_space.h" -#include "blumen_lumen.h" +#include "ss_blumen_lumen/blumen_lumen.h" struct app_state { @@ -72,6 +72,8 @@ struct app_state panel* HotPanel; user_space_desc UserSpaceDesc; + + bool RunEditor; }; internal void OpenColorPicker(app_state* State, v4* Address); @@ -81,7 +83,7 @@ internal void OpenColorPicker(app_state* State, v4* Address); #include "engine/user_space.cpp" #include "patterns/blumen_patterns.h" -#include "blumen_lumen.cpp" +#include "ss_blumen_lumen/blumen_lumen.cpp" internal void EndCurrentOperationMode(app_state* State) diff --git a/src/app/foldhaus_debug.h b/src/app/foldhaus_debug.h index 7acdfcc..c6b7133 100644 --- a/src/app/foldhaus_debug.h +++ b/src/app/foldhaus_debug.h @@ -64,8 +64,14 @@ struct debug_frame collated_scope_record* CollatedScopes; }; -#define FRAME_VIEW_PROFILER 0 -#define FRAME_VIEW_SCOPE_LIST 1 +enum debug_ui_view +{ + DebugUI_Profiler, + DebugUI_ScopeList, + DebugUI_MemoryView, + + DebugUI_Count, +}; struct debug_interface { diff --git a/src/app/handmade_math.h b/src/app/handmade_math.h deleted file mode 100644 index 049dfdb..0000000 --- a/src/app/handmade_math.h +++ /dev/null @@ -1,3239 +0,0 @@ -/* - HandmadeMath.h v1.11.0 - - This is a single header file with a bunch of useful functions for game and - graphics math operations. - - ============================================================================= - - You MUST - - #define HANDMADE_MATH_IMPLEMENTATION - - in EXACTLY one C or C++ file that includes this header, BEFORE the - include, like this: - - #define HANDMADE_MATH_IMPLEMENTATION - #include "HandmadeMath.h" - - All other files should just #include "HandmadeMath.h" without the #define. - - ============================================================================= - - To disable SSE intrinsics, you MUST - - #define HANDMADE_MATH_NO_SSE - - in EXACTLY one C or C++ file that includes this header, BEFORE the - include, like this: - - #define HANDMADE_MATH_IMPLEMENTATION - #define HANDMADE_MATH_NO_SSE - #include "HandmadeMath.h" - - ============================================================================= - - If you would prefer not to use the HMM_ prefix on function names, you can - - #define HMM_PREFIX - - To use a custom prefix instead, you can - - #define HMM_PREFIX(name) YOUR_PREFIX_##name - - ============================================================================= - - To use HandmadeMath without the CRT, you MUST - - #define HMM_SINF MySinF - #define HMM_COSF MyCosF - #define HMM_TANF MyTanF - #define HMM_SQRTF MySqrtF - #define HMM_EXPF MyExpF - #define HMM_LOGF MyLogF - #define HMM_ACOSF MyACosF - #define HMM_ATANF MyATanF - #define HMM_ATAN2F MYATan2F - - Provide your own implementations of SinF, CosF, TanF, ACosF, ATanF, ATan2F, - ExpF, and LogF in EXACTLY one C or C++ file that includes this header, - BEFORE the include, like this: - - #define HMM_SINF MySinF - #define HMM_COSF MyCosF - #define HMM_TANF MyTanF - #define HMM_SQRTF MySqrtF - #define HMM_EXPF MyExpF - #define HMM_LOGF MyLogF - #define HMM_ACOSF MyACosF - #define HMM_ATANF MyATanF - #define HMM_ATAN2F MyATan2F - #define HANDMADE_MATH_IMPLEMENTATION - #include "HandmadeMath.h" - - If you do not define all of these, HandmadeMath.h will use the - versions of these functions that are provided by the CRT. - - ============================================================================= - - LICENSE - - This software is in the public domain. Where that dedication is not - recognized, you are granted a perpetual, irrevocable license to copy, - distribute, and modify this file as you see fit. - - CREDITS - - Written by Zakary Strange (strangezak@gmail.com && @strangezak) - - Functionality: - Matt Mascarenhas (@miblo_) - Aleph - FieryDrake (@fierydrake) - Gingerbill (@TheGingerBill) - Ben Visness (@bvisness) - Trinton Bullard (@Peliex_Dev) - @AntonDan - - Fixes: - Jeroen van Rijn (@J_vanRijn) - Kiljacken (@Kiljacken) - Insofaras (@insofaras) - Daniel Gibson (@DanielGibson) -*/ - -// Dummy macros for when test framework is not present. -#ifndef COVERAGE -#define COVERAGE(a, b) -#endif - -#ifndef ASSERT_COVERED -#define ASSERT_COVERED(a) -#endif - -/* let's figure out if SSE is really available (unless disabled anyway) - (it isn't on non-x86/x86_64 platforms or even x86 without explicit SSE support) - => only use "#ifdef HANDMADE_MATH__USE_SSE" to check for SSE support below this block! */ -#ifndef HANDMADE_MATH_NO_SSE - -# ifdef _MSC_VER -/* MSVC supports SSE in amd64 mode or _M_IX86_FP >= 1 (2 means SSE2) */ -# if defined(_M_AMD64) || ( defined(_M_IX86_FP) && _M_IX86_FP >= 1 ) -# define HANDMADE_MATH__USE_SSE 1 -# endif -# else /* not MSVC, probably GCC, clang, icc or something that doesn't support SSE anyway */ -# ifdef __SSE__ /* they #define __SSE__ if it's supported */ -# define HANDMADE_MATH__USE_SSE 1 -# endif /* __SSE__ */ -# endif /* not _MSC_VER */ - -#endif /* #ifndef HANDMADE_MATH_NO_SSE */ - -#ifdef HANDMADE_MATH__USE_SSE -#include -#endif - -#ifndef HANDMADE_MATH_H -#define HANDMADE_MATH_H - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 8) -#pragma GCC diagnostic ignored "-Wmissing-braces" -#endif -#ifdef __clang__ -#pragma GCC diagnostic ignored "-Wgnu-anonymous-struct" -#endif -#endif - -#if defined(__GNUC__) || defined(__clang__) -#define HMM_DEPRECATED(msg) __attribute__((deprecated(msg))) -#elif defined(_MSC_VER) -#define HMM_DEPRECATED(msg) __declspec(deprecated(msg)) -#else -#define HMM_DEPRECATED(msg) -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define HMM_INLINE static inline -#define HMM_EXTERN extern - -#if !defined(HMM_SINF) || !defined(HMM_COSF) || !defined(HMM_TANF) || \ - !defined(HMM_SQRTF) || !defined(HMM_EXPF) || !defined(HMM_LOGF) || \ - !defined(HMM_ACOSF) || !defined(HMM_ATANF)|| !defined(HMM_ATAN2F) -#include -#endif - -#ifndef HMM_SINF -#define HMM_SINF sinf -#endif - -#ifndef HMM_COSF -#define HMM_COSF cosf -#endif - -#ifndef HMM_TANF -#define HMM_TANF tanf -#endif - -#ifndef HMM_SQRTF -#define HMM_SQRTF sqrtf -#endif - -#ifndef HMM_EXPF -#define HMM_EXPF expf -#endif - -#ifndef HMM_LOGF -#define HMM_LOGF logf -#endif - -#ifndef HMM_ACOSF -#define HMM_ACOSF acosf -#endif - -#ifndef HMM_ATANF -#define HMM_ATANF atanf -#endif - -#ifndef HMM_ATAN2F -#define HMM_ATAN2F atan2f -#endif - -#define HMM_PI32 3.14159265359f -#define HMM_PI 3.14159265358979323846 - -#define HMM_MIN(a, b) (a) > (b) ? (b) : (a) -#define HMM_MAX(a, b) (a) < (b) ? (b) : (a) -#define HMM_ABS(a) ((a) > 0 ? (a) : -(a)) -#define HMM_MOD(a, m) ((a) % (m)) >= 0 ? ((a) % (m)) : (((a) % (m)) + (m)) -#define HMM_SQUARE(x) ((x) * (x)) - -#ifndef HMM_PREFIX -#define HMM_PREFIX(name) HMM_##name -#endif - - typedef union hmm_vec2 - { - struct - { - float X, Y; - }; - - struct - { - float U, V; - }; - - struct - { - float Left, Right; - }; - - struct - { - float Width, Height; - }; - - float Elements[2]; - -#ifdef __cplusplus - inline float &operator[](const int &Index) - { - return Elements[Index]; - } -#endif - } hmm_vec2; - - typedef union hmm_vec3 - { - struct - { - float X, Y, Z; - }; - - struct - { - float U, V, W; - }; - - struct - { - float R, G, B; - }; - - struct - { - hmm_vec2 XY; - float Ignored0_; - }; - - struct - { - float Ignored1_; - hmm_vec2 YZ; - }; - - struct - { - hmm_vec2 UV; - float Ignored2_; - }; - - struct - { - float Ignored3_; - hmm_vec2 VW; - }; - - float Elements[3]; - -#ifdef __cplusplus - inline float &operator[](const int &Index) - { - return Elements[Index]; - } -#endif - } hmm_vec3; - - typedef union hmm_vec4 - { - struct - { - union - { - hmm_vec3 XYZ; - struct - { - float X, Y, Z; - }; - }; - - float W; - }; - struct - { - union - { - hmm_vec3 RGB; - struct - { - float R, G, B; - }; - }; - - float A; - }; - - struct - { - hmm_vec2 XY; - float Ignored0_; - float Ignored1_; - }; - - struct - { - float Ignored2_; - hmm_vec2 YZ; - float Ignored3_; - }; - - struct - { - float Ignored4_; - float Ignored5_; - hmm_vec2 ZW; - }; - - float Elements[4]; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 InternalElementsSSE; -#endif - -#ifdef __cplusplus - inline float &operator[](const int &Index) - { - return Elements[Index]; - } -#endif - } hmm_vec4; - - typedef union hmm_mat4 - { - float Elements[4][4]; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Columns[4]; - - HMM_DEPRECATED("Our matrices are column-major, so this was named incorrectly. Use Columns instead.") - __m128 Rows[4]; -#endif - -#ifdef __cplusplus - inline hmm_vec4 operator[](const int &Index) - { - float* col = Elements[Index]; - - hmm_vec4 result; - result.Elements[0] = col[0]; - result.Elements[1] = col[1]; - result.Elements[2] = col[2]; - result.Elements[3] = col[3]; - - return result; - } -#endif - } hmm_mat4; - - typedef union hmm_quaternion - { - struct - { - union - { - hmm_vec3 XYZ; - struct - { - float X, Y, Z; - }; - }; - - float W; - }; - - float Elements[4]; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 InternalElementsSSE; -#endif - } hmm_quaternion; - - typedef signed int hmm_bool; - - typedef hmm_vec2 hmm_v2; - typedef hmm_vec3 hmm_v3; - typedef hmm_vec4 hmm_v4; - typedef hmm_mat4 hmm_m4; - - - /* - * Floating-point math functions - */ - - COVERAGE(HMM_SinF, 1) - HMM_INLINE float HMM_PREFIX(SinF)(float Radians) - { - ASSERT_COVERED(HMM_SinF); - - float Result = HMM_SINF(Radians); - - return (Result); - } - - COVERAGE(HMM_CosF, 1) - HMM_INLINE float HMM_PREFIX(CosF)(float Radians) - { - ASSERT_COVERED(HMM_CosF); - - float Result = HMM_COSF(Radians); - - return (Result); - } - - COVERAGE(HMM_TanF, 1) - HMM_INLINE float HMM_PREFIX(TanF)(float Radians) - { - ASSERT_COVERED(HMM_TanF); - - float Result = HMM_TANF(Radians); - - return (Result); - } - - COVERAGE(HMM_ACosF, 1) - HMM_INLINE float HMM_PREFIX(ACosF)(float Radians) - { - ASSERT_COVERED(HMM_ACosF); - - float Result = HMM_ACOSF(Radians); - - return (Result); - } - - COVERAGE(HMM_ATanF, 1) - HMM_INLINE float HMM_PREFIX(ATanF)(float Radians) - { - ASSERT_COVERED(HMM_ATanF); - - float Result = HMM_ATANF(Radians); - - return (Result); - } - - COVERAGE(HMM_ATan2F, 1) - HMM_INLINE float HMM_PREFIX(ATan2F)(float Left, float Right) - { - ASSERT_COVERED(HMM_ATan2F); - - float Result = HMM_ATAN2F(Left, Right); - - return (Result); - } - - COVERAGE(HMM_ExpF, 1) - HMM_INLINE float HMM_PREFIX(ExpF)(float Float) - { - ASSERT_COVERED(HMM_ExpF); - - float Result = HMM_EXPF(Float); - - return (Result); - } - - COVERAGE(HMM_LogF, 1) - HMM_INLINE float HMM_PREFIX(LogF)(float Float) - { - ASSERT_COVERED(HMM_LogF); - - float Result = HMM_LOGF(Float); - - return (Result); - } - - COVERAGE(HMM_SquareRootF, 1) - HMM_INLINE float HMM_PREFIX(SquareRootF)(float Float) - { - ASSERT_COVERED(HMM_SquareRootF); - - float Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 In = _mm_set_ss(Float); - __m128 Out = _mm_sqrt_ss(In); - Result = _mm_cvtss_f32(Out); -#else - Result = HMM_SQRTF(Float); -#endif - - return(Result); - } - - COVERAGE(HMM_RSquareRootF, 1) - HMM_INLINE float HMM_PREFIX(RSquareRootF)(float Float) - { - ASSERT_COVERED(HMM_RSquareRootF); - - float Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 In = _mm_set_ss(Float); - __m128 Out = _mm_rsqrt_ss(In); - Result = _mm_cvtss_f32(Out); -#else - Result = 1.0f/HMM_PREFIX(SquareRootF)(Float); -#endif - - return(Result); - } - - HMM_EXTERN float HMM_PREFIX(Power)(float Base, int Exponent); - - COVERAGE(HMM_PowerF, 1) - HMM_INLINE float HMM_PREFIX(PowerF)(float Base, float Exponent) - { - ASSERT_COVERED(HMM_PowerF); - - float Result = HMM_EXPF(Exponent * HMM_LOGF(Base)); - - return (Result); - } - - - /* - * Utility functions - */ - - COVERAGE(HMM_ToRadians, 1) - HMM_INLINE float HMM_PREFIX(ToRadians)(float Degrees) - { - ASSERT_COVERED(HMM_ToRadians); - - float Result = Degrees * (HMM_PI32 / 180.0f); - - return (Result); - } - - COVERAGE(HMM_Lerp, 1) - HMM_INLINE float HMM_PREFIX(Lerp)(float A, float Time, float B) - { - ASSERT_COVERED(HMM_Lerp); - - float Result = (1.0f - Time) * A + Time * B; - - return (Result); - } - - COVERAGE(HMM_Clamp, 1) - HMM_INLINE float HMM_PREFIX(Clamp)(float Min, float Value, float Max) - { - ASSERT_COVERED(HMM_Clamp); - - float Result = Value; - - if(Result < Min) - { - Result = Min; - } - else if(Result > Max) - { - Result = Max; - } - - return (Result); - } - - - /* - * Vector initialization - */ - - COVERAGE(HMM_Vec2, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(Vec2)(float X, float Y) - { - ASSERT_COVERED(HMM_Vec2); - - hmm_vec2 Result; - - Result.X = X; - Result.Y = Y; - - return (Result); - } - - COVERAGE(HMM_Vec2i, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(Vec2i)(int X, int Y) - { - ASSERT_COVERED(HMM_Vec2i); - - hmm_vec2 Result; - - Result.X = (float)X; - Result.Y = (float)Y; - - return (Result); - } - - COVERAGE(HMM_Vec3, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(Vec3)(float X, float Y, float Z) - { - ASSERT_COVERED(HMM_Vec3); - - hmm_vec3 Result; - - Result.X = X; - Result.Y = Y; - Result.Z = Z; - - return (Result); - } - - COVERAGE(HMM_Vec3i, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(Vec3i)(int X, int Y, int Z) - { - ASSERT_COVERED(HMM_Vec3i); - - hmm_vec3 Result; - - Result.X = (float)X; - Result.Y = (float)Y; - Result.Z = (float)Z; - - return (Result); - } - - COVERAGE(HMM_Vec4, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(Vec4)(float X, float Y, float Z, float W) - { - ASSERT_COVERED(HMM_Vec4); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_setr_ps(X, Y, Z, W); -#else - Result.X = X; - Result.Y = Y; - Result.Z = Z; - Result.W = W; -#endif - - return (Result); - } - - COVERAGE(HMM_Vec4i, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(Vec4i)(int X, int Y, int Z, int W) - { - ASSERT_COVERED(HMM_Vec4i); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_setr_ps((float)X, (float)Y, (float)Z, (float)W); -#else - Result.X = (float)X; - Result.Y = (float)Y; - Result.Z = (float)Z; - Result.W = (float)W; -#endif - - return (Result); - } - - COVERAGE(HMM_Vec4v, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(Vec4v)(hmm_vec3 Vector, float W) - { - ASSERT_COVERED(HMM_Vec4v); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_setr_ps(Vector.X, Vector.Y, Vector.Z, W); -#else - Result.XYZ = Vector; - Result.W = W; -#endif - - return (Result); - } - - - /* - * Binary vector operations - */ - - COVERAGE(HMM_AddVec2, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(AddVec2)(hmm_vec2 Left, hmm_vec2 Right) - { - ASSERT_COVERED(HMM_AddVec2); - - hmm_vec2 Result; - - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - - return (Result); - } - - COVERAGE(HMM_AddVec3, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(AddVec3)(hmm_vec3 Left, hmm_vec3 Right) - { - ASSERT_COVERED(HMM_AddVec3); - - hmm_vec3 Result; - - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - Result.Z = Left.Z + Right.Z; - - return (Result); - } - - COVERAGE(HMM_AddVec4, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(AddVec4)(hmm_vec4 Left, hmm_vec4 Right) - { - ASSERT_COVERED(HMM_AddVec4); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_add_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); -#else - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - Result.Z = Left.Z + Right.Z; - Result.W = Left.W + Right.W; -#endif - - return (Result); - } - - COVERAGE(HMM_SubtractVec2, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(SubtractVec2)(hmm_vec2 Left, hmm_vec2 Right) - { - ASSERT_COVERED(HMM_SubtractVec2); - - hmm_vec2 Result; - - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - - return (Result); - } - - COVERAGE(HMM_SubtractVec3, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(SubtractVec3)(hmm_vec3 Left, hmm_vec3 Right) - { - ASSERT_COVERED(HMM_SubtractVec3); - - hmm_vec3 Result; - - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - Result.Z = Left.Z - Right.Z; - - return (Result); - } - - COVERAGE(HMM_SubtractVec4, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(SubtractVec4)(hmm_vec4 Left, hmm_vec4 Right) - { - ASSERT_COVERED(HMM_SubtractVec4); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_sub_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); -#else - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - Result.Z = Left.Z - Right.Z; - Result.W = Left.W - Right.W; -#endif - - return (Result); - } - - COVERAGE(HMM_MultiplyVec2, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(MultiplyVec2)(hmm_vec2 Left, hmm_vec2 Right) - { - ASSERT_COVERED(HMM_MultiplyVec2); - - hmm_vec2 Result; - - Result.X = Left.X * Right.X; - Result.Y = Left.Y * Right.Y; - - return (Result); - } - - COVERAGE(HMM_MultiplyVec2f, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(MultiplyVec2f)(hmm_vec2 Left, float Right) - { - ASSERT_COVERED(HMM_MultiplyVec2f); - - hmm_vec2 Result; - - Result.X = Left.X * Right; - Result.Y = Left.Y * Right; - - return (Result); - } - - COVERAGE(HMM_MultiplyVec3, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(MultiplyVec3)(hmm_vec3 Left, hmm_vec3 Right) - { - ASSERT_COVERED(HMM_MultiplyVec3); - - hmm_vec3 Result; - - Result.X = Left.X * Right.X; - Result.Y = Left.Y * Right.Y; - Result.Z = Left.Z * Right.Z; - - return (Result); - } - - COVERAGE(HMM_MultiplyVec3f, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(MultiplyVec3f)(hmm_vec3 Left, float Right) - { - ASSERT_COVERED(HMM_MultiplyVec3f); - - hmm_vec3 Result; - - Result.X = Left.X * Right; - Result.Y = Left.Y * Right; - Result.Z = Left.Z * Right; - - return (Result); - } - - COVERAGE(HMM_MultiplyVec4, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(MultiplyVec4)(hmm_vec4 Left, hmm_vec4 Right) - { - ASSERT_COVERED(HMM_MultiplyVec4); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_mul_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); -#else - Result.X = Left.X * Right.X; - Result.Y = Left.Y * Right.Y; - Result.Z = Left.Z * Right.Z; - Result.W = Left.W * Right.W; -#endif - - return (Result); - } - - COVERAGE(HMM_MultiplyVec4f, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(MultiplyVec4f)(hmm_vec4 Left, float Right) - { - ASSERT_COVERED(HMM_MultiplyVec4f); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Right); - Result.InternalElementsSSE = _mm_mul_ps(Left.InternalElementsSSE, Scalar); -#else - Result.X = Left.X * Right; - Result.Y = Left.Y * Right; - Result.Z = Left.Z * Right; - Result.W = Left.W * Right; -#endif - - return (Result); - } - - COVERAGE(HMM_DivideVec2, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(DivideVec2)(hmm_vec2 Left, hmm_vec2 Right) - { - ASSERT_COVERED(HMM_DivideVec2); - - hmm_vec2 Result; - - Result.X = Left.X / Right.X; - Result.Y = Left.Y / Right.Y; - - return (Result); - } - - COVERAGE(HMM_DivideVec2f, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(DivideVec2f)(hmm_vec2 Left, float Right) - { - ASSERT_COVERED(HMM_DivideVec2f); - - hmm_vec2 Result; - - Result.X = Left.X / Right; - Result.Y = Left.Y / Right; - - return (Result); - } - - COVERAGE(HMM_DivideVec3, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(DivideVec3)(hmm_vec3 Left, hmm_vec3 Right) - { - ASSERT_COVERED(HMM_DivideVec3); - - hmm_vec3 Result; - - Result.X = Left.X / Right.X; - Result.Y = Left.Y / Right.Y; - Result.Z = Left.Z / Right.Z; - - return (Result); - } - - COVERAGE(HMM_DivideVec3f, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(DivideVec3f)(hmm_vec3 Left, float Right) - { - ASSERT_COVERED(HMM_DivideVec3f); - - hmm_vec3 Result; - - Result.X = Left.X / Right; - Result.Y = Left.Y / Right; - Result.Z = Left.Z / Right; - - return (Result); - } - - COVERAGE(HMM_DivideVec4, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(DivideVec4)(hmm_vec4 Left, hmm_vec4 Right) - { - ASSERT_COVERED(HMM_DivideVec4); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_div_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); -#else - Result.X = Left.X / Right.X; - Result.Y = Left.Y / Right.Y; - Result.Z = Left.Z / Right.Z; - Result.W = Left.W / Right.W; -#endif - - return (Result); - } - - COVERAGE(HMM_DivideVec4f, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(DivideVec4f)(hmm_vec4 Left, float Right) - { - ASSERT_COVERED(HMM_DivideVec4f); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Right); - Result.InternalElementsSSE = _mm_div_ps(Left.InternalElementsSSE, Scalar); -#else - Result.X = Left.X / Right; - Result.Y = Left.Y / Right; - Result.Z = Left.Z / Right; - Result.W = Left.W / Right; -#endif - - return (Result); - } - - COVERAGE(HMM_EqualsVec2, 1) - HMM_INLINE hmm_bool HMM_PREFIX(EqualsVec2)(hmm_vec2 Left, hmm_vec2 Right) - { - ASSERT_COVERED(HMM_EqualsVec2); - - hmm_bool Result = (Left.X == Right.X && Left.Y == Right.Y); - - return (Result); - } - - COVERAGE(HMM_EqualsVec3, 1) - HMM_INLINE hmm_bool HMM_PREFIX(EqualsVec3)(hmm_vec3 Left, hmm_vec3 Right) - { - ASSERT_COVERED(HMM_EqualsVec3); - - hmm_bool Result = (Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z); - - return (Result); - } - - COVERAGE(HMM_EqualsVec4, 1) - HMM_INLINE hmm_bool HMM_PREFIX(EqualsVec4)(hmm_vec4 Left, hmm_vec4 Right) - { - ASSERT_COVERED(HMM_EqualsVec4); - - hmm_bool Result = (Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z && Left.W == Right.W); - - return (Result); - } - - COVERAGE(HMM_DotVec2, 1) - HMM_INLINE float HMM_PREFIX(DotVec2)(hmm_vec2 VecOne, hmm_vec2 VecTwo) - { - ASSERT_COVERED(HMM_DotVec2); - - float Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y); - - return (Result); - } - - COVERAGE(HMM_DotVec3, 1) - HMM_INLINE float HMM_PREFIX(DotVec3)(hmm_vec3 VecOne, hmm_vec3 VecTwo) - { - ASSERT_COVERED(HMM_DotVec3); - - float Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); - - return (Result); - } - - COVERAGE(HMM_DotVec4, 1) - HMM_INLINE float HMM_PREFIX(DotVec4)(hmm_vec4 VecOne, hmm_vec4 VecTwo) - { - ASSERT_COVERED(HMM_DotVec4); - - float Result; - - // NOTE(zak): IN the future if we wanna check what version SSE is support - // we can use _mm_dp_ps (4.3) but for now we will use the old way. - // Or a r = _mm_mul_ps(v1, v2), r = _mm_hadd_ps(r, r), r = _mm_hadd_ps(r, r) for SSE3 -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEResultOne = _mm_mul_ps(VecOne.InternalElementsSSE, VecTwo.InternalElementsSSE); - __m128 SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(2, 3, 0, 1)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(0, 1, 2, 3)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - _mm_store_ss(&Result, SSEResultOne); -#else - Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z) + (VecOne.W * VecTwo.W); -#endif - - return (Result); - } - - COVERAGE(HMM_Cross, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(Cross)(hmm_vec3 VecOne, hmm_vec3 VecTwo) - { - ASSERT_COVERED(HMM_Cross); - - hmm_vec3 Result; - - Result.X = (VecOne.Y * VecTwo.Z) - (VecOne.Z * VecTwo.Y); - Result.Y = (VecOne.Z * VecTwo.X) - (VecOne.X * VecTwo.Z); - Result.Z = (VecOne.X * VecTwo.Y) - (VecOne.Y * VecTwo.X); - - return (Result); - } - - - /* - * Unary vector operations - */ - - COVERAGE(HMM_LengthSquaredVec2, 1) - HMM_INLINE float HMM_PREFIX(LengthSquaredVec2)(hmm_vec2 A) - { - ASSERT_COVERED(HMM_LengthSquaredVec2); - - float Result = HMM_PREFIX(DotVec2)(A, A); - - return (Result); - } - - COVERAGE(HMM_LengthSquaredVec3, 1) - HMM_INLINE float HMM_PREFIX(LengthSquaredVec3)(hmm_vec3 A) - { - ASSERT_COVERED(HMM_LengthSquaredVec3); - - float Result = HMM_PREFIX(DotVec3)(A, A); - - return (Result); - } - - COVERAGE(HMM_LengthSquaredVec4, 1) - HMM_INLINE float HMM_PREFIX(LengthSquaredVec4)(hmm_vec4 A) - { - ASSERT_COVERED(HMM_LengthSquaredVec4); - - float Result = HMM_PREFIX(DotVec4)(A, A); - - return (Result); - } - - COVERAGE(HMM_LengthVec2, 1) - HMM_INLINE float HMM_PREFIX(LengthVec2)(hmm_vec2 A) - { - ASSERT_COVERED(HMM_LengthVec2); - - float Result = HMM_PREFIX(SquareRootF)(HMM_PREFIX(LengthSquaredVec2)(A)); - - return (Result); - } - - COVERAGE(HMM_LengthVec3, 1) - HMM_INLINE float HMM_PREFIX(LengthVec3)(hmm_vec3 A) - { - ASSERT_COVERED(HMM_LengthVec3); - - float Result = HMM_PREFIX(SquareRootF)(HMM_PREFIX(LengthSquaredVec3)(A)); - - return (Result); - } - - COVERAGE(HMM_LengthVec4, 1) - HMM_INLINE float HMM_PREFIX(LengthVec4)(hmm_vec4 A) - { - ASSERT_COVERED(HMM_LengthVec4); - - float Result = HMM_PREFIX(SquareRootF)(HMM_PREFIX(LengthSquaredVec4)(A)); - - return(Result); - } - - COVERAGE(HMM_NormalizeVec2, 2) - HMM_INLINE hmm_vec2 HMM_PREFIX(NormalizeVec2)(hmm_vec2 A) - { - ASSERT_COVERED(HMM_NormalizeVec2); - - hmm_vec2 Result = {0}; - - float VectorLength = HMM_PREFIX(LengthVec2)(A); - - /* NOTE(kiljacken): We need a zero check to not divide-by-zero */ - if (VectorLength != 0.0f) - { - ASSERT_COVERED(HMM_NormalizeVec2); - - Result.X = A.X * (1.0f / VectorLength); - Result.Y = A.Y * (1.0f / VectorLength); - } - - return (Result); - } - - COVERAGE(HMM_NormalizeVec3, 2) - HMM_INLINE hmm_vec3 HMM_PREFIX(NormalizeVec3)(hmm_vec3 A) - { - ASSERT_COVERED(HMM_NormalizeVec3); - - hmm_vec3 Result = {0}; - - float VectorLength = HMM_PREFIX(LengthVec3)(A); - - /* NOTE(kiljacken): We need a zero check to not divide-by-zero */ - if (VectorLength != 0.0f) - { - ASSERT_COVERED(HMM_NormalizeVec3); - - Result.X = A.X * (1.0f / VectorLength); - Result.Y = A.Y * (1.0f / VectorLength); - Result.Z = A.Z * (1.0f / VectorLength); - } - - return (Result); - } - - COVERAGE(HMM_NormalizeVec4, 2) - HMM_INLINE hmm_vec4 HMM_PREFIX(NormalizeVec4)(hmm_vec4 A) - { - ASSERT_COVERED(HMM_NormalizeVec4); - - hmm_vec4 Result = {0}; - - float VectorLength = HMM_PREFIX(LengthVec4)(A); - - /* NOTE(kiljacken): We need a zero check to not divide-by-zero */ - if (VectorLength != 0.0f) - { - ASSERT_COVERED(HMM_NormalizeVec4); - - float Multiplier = 1.0f / VectorLength; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEMultiplier = _mm_set1_ps(Multiplier); - Result.InternalElementsSSE = _mm_mul_ps(A.InternalElementsSSE, SSEMultiplier); -#else - Result.X = A.X * Multiplier; - Result.Y = A.Y * Multiplier; - Result.Z = A.Z * Multiplier; - Result.W = A.W * Multiplier; -#endif - } - - return (Result); - } - - COVERAGE(HMM_FastNormalizeVec2, 1) - HMM_INLINE hmm_vec2 HMM_PREFIX(FastNormalizeVec2)(hmm_vec2 A) - { - ASSERT_COVERED(HMM_FastNormalizeVec2); - - return HMM_PREFIX(MultiplyVec2f)(A, HMM_PREFIX(RSquareRootF)(HMM_PREFIX(DotVec2)(A, A))); - } - - COVERAGE(HMM_FastNormalizeVec3, 1) - HMM_INLINE hmm_vec3 HMM_PREFIX(FastNormalizeVec3)(hmm_vec3 A) - { - ASSERT_COVERED(HMM_FastNormalizeVec3); - - return HMM_PREFIX(MultiplyVec3f)(A, HMM_PREFIX(RSquareRootF)(HMM_PREFIX(DotVec3)(A, A))); - } - - COVERAGE(HMM_FastNormalizeVec4, 1) - HMM_INLINE hmm_vec4 HMM_PREFIX(FastNormalizeVec4)(hmm_vec4 A) - { - ASSERT_COVERED(HMM_FastNormalizeVec4); - - return HMM_PREFIX(MultiplyVec4f)(A, HMM_PREFIX(RSquareRootF)(HMM_PREFIX(DotVec4)(A, A))); - } - - - /* - * SSE stuff - */ - -#ifdef HANDMADE_MATH__USE_SSE - COVERAGE(HMM_LinearCombineSSE, 1) - HMM_INLINE __m128 HMM_PREFIX(LinearCombineSSE)(__m128 Left, hmm_mat4 Right) - { - ASSERT_COVERED(HMM_LinearCombineSSE); - - __m128 Result; - Result = _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0x00), Right.Columns[0]); - Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0x55), Right.Columns[1])); - Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0xaa), Right.Columns[2])); - Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0xff), Right.Columns[3])); - - return (Result); - } -#endif - - - /* - * Matrix functions - */ - - COVERAGE(HMM_Mat4, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Mat4)(void) - { - ASSERT_COVERED(HMM_Mat4); - - hmm_mat4 Result = {0}; - - return (Result); - } - - COVERAGE(HMM_Mat4d, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Mat4d)(float Diagonal) - { - ASSERT_COVERED(HMM_Mat4d); - - hmm_mat4 Result = HMM_PREFIX(Mat4)(); - - Result.Elements[0][0] = Diagonal; - Result.Elements[1][1] = Diagonal; - Result.Elements[2][2] = Diagonal; - Result.Elements[3][3] = Diagonal; - - return (Result); - } - -#ifdef HANDMADE_MATH__USE_SSE - COVERAGE(HMM_Transpose, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Transpose)(hmm_mat4 Matrix) - { - ASSERT_COVERED(HMM_Transpose); - - hmm_mat4 Result = Matrix; - - _MM_TRANSPOSE4_PS(Result.Columns[0], Result.Columns[1], Result.Columns[2], Result.Columns[3]); - - return (Result); - } -#else - HMM_EXTERN hmm_mat4 HMM_PREFIX(Transpose)(hmm_mat4 Matrix); -#endif - -#ifdef HANDMADE_MATH__USE_SSE - COVERAGE(HMM_AddMat4, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(AddMat4)(hmm_mat4 Left, hmm_mat4 Right) - { - ASSERT_COVERED(HMM_AddMat4); - - hmm_mat4 Result; - - Result.Columns[0] = _mm_add_ps(Left.Columns[0], Right.Columns[0]); - Result.Columns[1] = _mm_add_ps(Left.Columns[1], Right.Columns[1]); - Result.Columns[2] = _mm_add_ps(Left.Columns[2], Right.Columns[2]); - Result.Columns[3] = _mm_add_ps(Left.Columns[3], Right.Columns[3]); - - return (Result); - } -#else - HMM_EXTERN hmm_mat4 HMM_PREFIX(AddMat4)(hmm_mat4 Left, hmm_mat4 Right); -#endif - -#ifdef HANDMADE_MATH__USE_SSE - COVERAGE(HMM_SubtractMat4, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(SubtractMat4)(hmm_mat4 Left, hmm_mat4 Right) - { - ASSERT_COVERED(HMM_SubtractMat4); - - hmm_mat4 Result; - - Result.Columns[0] = _mm_sub_ps(Left.Columns[0], Right.Columns[0]); - Result.Columns[1] = _mm_sub_ps(Left.Columns[1], Right.Columns[1]); - Result.Columns[2] = _mm_sub_ps(Left.Columns[2], Right.Columns[2]); - Result.Columns[3] = _mm_sub_ps(Left.Columns[3], Right.Columns[3]); - - return (Result); - } -#else - HMM_EXTERN hmm_mat4 HMM_PREFIX(SubtractMat4)(hmm_mat4 Left, hmm_mat4 Right); -#endif - - HMM_EXTERN hmm_mat4 HMM_PREFIX(MultiplyMat4)(hmm_mat4 Left, hmm_mat4 Right); - -#ifdef HANDMADE_MATH__USE_SSE - COVERAGE(HMM_MultiplyMat4f, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(MultiplyMat4f)(hmm_mat4 Matrix, float Scalar) - { - ASSERT_COVERED(HMM_MultiplyMat4f); - - hmm_mat4 Result; - - __m128 SSEScalar = _mm_set1_ps(Scalar); - Result.Columns[0] = _mm_mul_ps(Matrix.Columns[0], SSEScalar); - Result.Columns[1] = _mm_mul_ps(Matrix.Columns[1], SSEScalar); - Result.Columns[2] = _mm_mul_ps(Matrix.Columns[2], SSEScalar); - Result.Columns[3] = _mm_mul_ps(Matrix.Columns[3], SSEScalar); - - return (Result); - } -#else - HMM_EXTERN hmm_mat4 HMM_PREFIX(MultiplyMat4f)(hmm_mat4 Matrix, float Scalar); -#endif - - HMM_EXTERN hmm_vec4 HMM_PREFIX(MultiplyMat4ByVec4)(hmm_mat4 Matrix, hmm_vec4 Vector); - -#ifdef HANDMADE_MATH__USE_SSE - COVERAGE(HMM_DivideMat4f, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(DivideMat4f)(hmm_mat4 Matrix, float Scalar) - { - ASSERT_COVERED(HMM_DivideMat4f); - - hmm_mat4 Result; - - __m128 SSEScalar = _mm_set1_ps(Scalar); - Result.Columns[0] = _mm_div_ps(Matrix.Columns[0], SSEScalar); - Result.Columns[1] = _mm_div_ps(Matrix.Columns[1], SSEScalar); - Result.Columns[2] = _mm_div_ps(Matrix.Columns[2], SSEScalar); - Result.Columns[3] = _mm_div_ps(Matrix.Columns[3], SSEScalar); - - return (Result); - } -#else - HMM_EXTERN hmm_mat4 HMM_PREFIX(DivideMat4f)(hmm_mat4 Matrix, float Scalar); -#endif - - - /* - * Common graphics transformations - */ - - COVERAGE(HMM_Orthographic, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Orthographic)(float Left, float Right, float Bottom, float Top, float Near, float Far) - { - ASSERT_COVERED(HMM_Orthographic); - - hmm_mat4 Result = HMM_PREFIX(Mat4)(); - - Result.Elements[0][0] = 2.0f / (Right - Left); - Result.Elements[1][1] = 2.0f / (Top - Bottom); - Result.Elements[2][2] = 2.0f / (Near - Far); - Result.Elements[3][3] = 1.0f; - - Result.Elements[3][0] = (Left + Right) / (Left - Right); - Result.Elements[3][1] = (Bottom + Top) / (Bottom - Top); - Result.Elements[3][2] = (Far + Near) / (Near - Far); - - return (Result); - } - - COVERAGE(HMM_Perspective, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Perspective)(float FOV, float AspectRatio, float Near, float Far) - { - ASSERT_COVERED(HMM_Perspective); - - hmm_mat4 Result = HMM_PREFIX(Mat4)(); - - // See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml - - float Cotangent = 1.0f / HMM_PREFIX(TanF)(FOV * (HMM_PI32 / 360.0f)); - - Result.Elements[0][0] = Cotangent / AspectRatio; - Result.Elements[1][1] = Cotangent; - Result.Elements[2][3] = -1.0f; - Result.Elements[2][2] = (Near + Far) / (Near - Far); - Result.Elements[3][2] = (2.0f * Near * Far) / (Near - Far); - Result.Elements[3][3] = 0.0f; - - return (Result); - } - - COVERAGE(HMM_Translate, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Translate)(hmm_vec3 Translation) - { - ASSERT_COVERED(HMM_Translate); - - hmm_mat4 Result = HMM_PREFIX(Mat4d)(1.0f); - - Result.Elements[3][0] = Translation.X; - Result.Elements[3][1] = Translation.Y; - Result.Elements[3][2] = Translation.Z; - - return (Result); - } - - HMM_EXTERN hmm_mat4 HMM_PREFIX(Rotate)(float Angle, hmm_vec3 Axis); - - COVERAGE(HMM_Scale, 1) - HMM_INLINE hmm_mat4 HMM_PREFIX(Scale)(hmm_vec3 Scale) - { - ASSERT_COVERED(HMM_Scale); - - hmm_mat4 Result = HMM_PREFIX(Mat4d)(1.0f); - - Result.Elements[0][0] = Scale.X; - Result.Elements[1][1] = Scale.Y; - Result.Elements[2][2] = Scale.Z; - - return (Result); - } - - HMM_EXTERN hmm_mat4 HMM_PREFIX(LookAt)(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up); - - - /* - * Quaternion operations - */ - - COVERAGE(HMM_Quaternion, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(Quaternion)(float X, float Y, float Z, float W) - { - ASSERT_COVERED(HMM_Quaternion); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_setr_ps(X, Y, Z, W); -#else - Result.X = X; - Result.Y = Y; - Result.Z = Z; - Result.W = W; -#endif - - return (Result); - } - - COVERAGE(HMM_QuaternionV4, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(QuaternionV4)(hmm_vec4 Vector) - { - ASSERT_COVERED(HMM_QuaternionV4); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = Vector.InternalElementsSSE; -#else - Result.X = Vector.X; - Result.Y = Vector.Y; - Result.Z = Vector.Z; - Result.W = Vector.W; -#endif - - return (Result); - } - - COVERAGE(HMM_AddQuaternion, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(AddQuaternion)(hmm_quaternion Left, hmm_quaternion Right) - { - ASSERT_COVERED(HMM_AddQuaternion); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_add_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); -#else - - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - Result.Z = Left.Z + Right.Z; - Result.W = Left.W + Right.W; -#endif - - return (Result); - } - - COVERAGE(HMM_SubtractQuaternion, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(SubtractQuaternion)(hmm_quaternion Left, hmm_quaternion Right) - { - ASSERT_COVERED(HMM_SubtractQuaternion); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = _mm_sub_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); -#else - - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - Result.Z = Left.Z - Right.Z; - Result.W = Left.W - Right.W; -#endif - - return (Result); - } - - COVERAGE(HMM_MultiplyQuaternion, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(MultiplyQuaternion)(hmm_quaternion Left, hmm_quaternion Right) - { - ASSERT_COVERED(HMM_MultiplyQuaternion); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(0, 0, 0, 0)), _mm_setr_ps(0.f, -0.f, 0.f, -0.f)); - __m128 SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(0, 1, 2, 3)); - __m128 SSEResultThree = _mm_mul_ps(SSEResultTwo, SSEResultOne); - - SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(1, 1, 1, 1)) , _mm_setr_ps(0.f, 0.f, -0.f, -0.f)); - SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(1, 0, 3, 2)); - SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); - - SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(2, 2, 2, 2)), _mm_setr_ps(-0.f, 0.f, 0.f, -0.f)); - SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(2, 3, 0, 1)); - SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); - - SSEResultOne = _mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(3, 3, 3, 3)); - SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(3, 2, 1, 0)); - Result.InternalElementsSSE = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); -#else - Result.X = (Left.X * Right.W) + (Left.Y * Right.Z) - (Left.Z * Right.Y) + (Left.W * Right.X); - Result.Y = (-Left.X * Right.Z) + (Left.Y * Right.W) + (Left.Z * Right.X) + (Left.W * Right.Y); - Result.Z = (Left.X * Right.Y) - (Left.Y * Right.X) + (Left.Z * Right.W) + (Left.W * Right.Z); - Result.W = (-Left.X * Right.X) - (Left.Y * Right.Y) - (Left.Z * Right.Z) + (Left.W * Right.W); -#endif - - return (Result); - } - - COVERAGE(HMM_MultiplyQuaternionF, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(MultiplyQuaternionF)(hmm_quaternion Left, float Multiplicative) - { - ASSERT_COVERED(HMM_MultiplyQuaternionF); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Multiplicative); - Result.InternalElementsSSE = _mm_mul_ps(Left.InternalElementsSSE, Scalar); -#else - Result.X = Left.X * Multiplicative; - Result.Y = Left.Y * Multiplicative; - Result.Z = Left.Z * Multiplicative; - Result.W = Left.W * Multiplicative; -#endif - - return (Result); - } - - COVERAGE(HMM_DivideQuaternionF, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(DivideQuaternionF)(hmm_quaternion Left, float Dividend) - { - ASSERT_COVERED(HMM_DivideQuaternionF); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Dividend); - Result.InternalElementsSSE = _mm_div_ps(Left.InternalElementsSSE, Scalar); -#else - Result.X = Left.X / Dividend; - Result.Y = Left.Y / Dividend; - Result.Z = Left.Z / Dividend; - Result.W = Left.W / Dividend; -#endif - - return (Result); - } - - HMM_EXTERN hmm_quaternion HMM_PREFIX(InverseQuaternion)(hmm_quaternion Left); - - COVERAGE(HMM_DotQuaternion, 1) - HMM_INLINE float HMM_PREFIX(DotQuaternion)(hmm_quaternion Left, hmm_quaternion Right) - { - ASSERT_COVERED(HMM_DotQuaternion); - - float Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEResultOne = _mm_mul_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); - __m128 SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(2, 3, 0, 1)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(0, 1, 2, 3)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - _mm_store_ss(&Result, SSEResultOne); -#else - Result = (Left.X * Right.X) + (Left.Y * Right.Y) + (Left.Z * Right.Z) + (Left.W * Right.W); -#endif - - return (Result); - } - - COVERAGE(HMM_NormalizeQuaternion, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(NormalizeQuaternion)(hmm_quaternion Left) - { - ASSERT_COVERED(HMM_NormalizeQuaternion); - - hmm_quaternion Result; - - float Length = HMM_PREFIX(SquareRootF)(HMM_PREFIX(DotQuaternion)(Left, Left)); - Result = HMM_PREFIX(DivideQuaternionF)(Left, Length); - - return (Result); - } - - COVERAGE(HMM_NLerp, 1) - HMM_INLINE hmm_quaternion HMM_PREFIX(NLerp)(hmm_quaternion Left, float Time, hmm_quaternion Right) - { - ASSERT_COVERED(HMM_NLerp); - - hmm_quaternion Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 ScalarLeft = _mm_set1_ps(1.0f - Time); - __m128 ScalarRight = _mm_set1_ps(Time); - __m128 SSEResultOne = _mm_mul_ps(Left.InternalElementsSSE, ScalarLeft); - __m128 SSEResultTwo = _mm_mul_ps(Right.InternalElementsSSE, ScalarRight); - Result.InternalElementsSSE = _mm_add_ps(SSEResultOne, SSEResultTwo); -#else - Result.X = HMM_PREFIX(Lerp)(Left.X, Time, Right.X); - Result.Y = HMM_PREFIX(Lerp)(Left.Y, Time, Right.Y); - Result.Z = HMM_PREFIX(Lerp)(Left.Z, Time, Right.Z); - Result.W = HMM_PREFIX(Lerp)(Left.W, Time, Right.W); -#endif - Result = HMM_PREFIX(NormalizeQuaternion)(Result); - - return (Result); - } - - HMM_EXTERN hmm_quaternion HMM_PREFIX(Slerp)(hmm_quaternion Left, float Time, hmm_quaternion Right); - HMM_EXTERN hmm_mat4 HMM_PREFIX(QuaternionToMat4)(hmm_quaternion Left); - HMM_EXTERN hmm_quaternion HMM_PREFIX(Mat4ToQuaternion)(hmm_mat4 Left); - HMM_EXTERN hmm_quaternion HMM_PREFIX(QuaternionFromAxisAngle)(hmm_vec3 Axis, float AngleOfRotation); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus - -COVERAGE(HMM_LengthVec2CPP, 1) -HMM_INLINE float HMM_PREFIX(Length)(hmm_vec2 A) -{ - ASSERT_COVERED(HMM_LengthVec2CPP); - - float Result = HMM_PREFIX(LengthVec2)(A); - - return (Result); -} - -COVERAGE(HMM_LengthVec3CPP, 1) -HMM_INLINE float HMM_PREFIX(Length)(hmm_vec3 A) -{ - ASSERT_COVERED(HMM_LengthVec3CPP); - - float Result = HMM_PREFIX(LengthVec3)(A); - - return (Result); -} - -COVERAGE(HMM_LengthVec4CPP, 1) -HMM_INLINE float HMM_PREFIX(Length)(hmm_vec4 A) -{ - ASSERT_COVERED(HMM_LengthVec4CPP); - - float Result = HMM_PREFIX(LengthVec4)(A); - - return (Result); -} - -COVERAGE(HMM_LengthSquaredVec2CPP, 1) -HMM_INLINE float HMM_PREFIX(LengthSquared)(hmm_vec2 A) -{ - ASSERT_COVERED(HMM_LengthSquaredVec2CPP); - - float Result = HMM_PREFIX(LengthSquaredVec2)(A); - - return (Result); -} - -COVERAGE(HMM_LengthSquaredVec3CPP, 1) -HMM_INLINE float HMM_PREFIX(LengthSquared)(hmm_vec3 A) -{ - ASSERT_COVERED(HMM_LengthSquaredVec3CPP); - - float Result = HMM_PREFIX(LengthSquaredVec3)(A); - - return (Result); -} - -COVERAGE(HMM_LengthSquaredVec4CPP, 1) -HMM_INLINE float HMM_PREFIX(LengthSquared)(hmm_vec4 A) -{ - ASSERT_COVERED(HMM_LengthSquaredVec4CPP); - - float Result = HMM_PREFIX(LengthSquaredVec4)(A); - - return (Result); -} - -COVERAGE(HMM_NormalizeVec2CPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Normalize)(hmm_vec2 A) -{ - ASSERT_COVERED(HMM_NormalizeVec2CPP); - - hmm_vec2 Result = HMM_PREFIX(NormalizeVec2)(A); - - return (Result); -} - -COVERAGE(HMM_NormalizeVec3CPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Normalize)(hmm_vec3 A) -{ - ASSERT_COVERED(HMM_NormalizeVec3CPP); - - hmm_vec3 Result = HMM_PREFIX(NormalizeVec3)(A); - - return (Result); -} - -COVERAGE(HMM_NormalizeVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Normalize)(hmm_vec4 A) -{ - ASSERT_COVERED(HMM_NormalizeVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(NormalizeVec4)(A); - - return (Result); -} - -COVERAGE(HMM_FastNormalizeVec2CPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(FastNormalize)(hmm_vec2 A) -{ - ASSERT_COVERED(HMM_FastNormalizeVec2CPP); - - hmm_vec2 Result = HMM_PREFIX(FastNormalizeVec2)(A); - - return (Result); -} - -COVERAGE(HMM_FastNormalizeVec3CPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(FastNormalize)(hmm_vec3 A) -{ - ASSERT_COVERED(HMM_FastNormalizeVec3CPP); - - hmm_vec3 Result = HMM_PREFIX(FastNormalizeVec3)(A); - - return (Result); -} - -COVERAGE(HMM_FastNormalizeVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(FastNormalize)(hmm_vec4 A) -{ - ASSERT_COVERED(HMM_FastNormalizeVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(FastNormalizeVec4)(A); - - return (Result); -} - -COVERAGE(HMM_NormalizeQuaternionCPP, 1) -HMM_INLINE hmm_quaternion HMM_PREFIX(Normalize)(hmm_quaternion A) -{ - ASSERT_COVERED(HMM_NormalizeQuaternionCPP); - - hmm_quaternion Result = HMM_PREFIX(NormalizeQuaternion)(A); - - return (Result); -} - -COVERAGE(HMM_DotVec2CPP, 1) -HMM_INLINE float HMM_PREFIX(Dot)(hmm_vec2 VecOne, hmm_vec2 VecTwo) -{ - ASSERT_COVERED(HMM_DotVec2CPP); - - float Result = HMM_PREFIX(DotVec2)(VecOne, VecTwo); - - return (Result); -} - -COVERAGE(HMM_DotVec3CPP, 1) -HMM_INLINE float HMM_PREFIX(Dot)(hmm_vec3 VecOne, hmm_vec3 VecTwo) -{ - ASSERT_COVERED(HMM_DotVec3CPP); - - float Result = HMM_PREFIX(DotVec3)(VecOne, VecTwo); - - return (Result); -} - -COVERAGE(HMM_DotVec4CPP, 1) -HMM_INLINE float HMM_PREFIX(Dot)(hmm_vec4 VecOne, hmm_vec4 VecTwo) -{ - ASSERT_COVERED(HMM_DotVec4CPP); - - float Result = HMM_PREFIX(DotVec4)(VecOne, VecTwo); - - return (Result); -} - -COVERAGE(HMM_DotQuaternionCPP, 1) -HMM_INLINE float HMM_PREFIX(Dot)(hmm_quaternion QuatOne, hmm_quaternion QuatTwo) -{ - ASSERT_COVERED(HMM_DotQuaternionCPP); - - float Result = HMM_PREFIX(DotQuaternion)(QuatOne, QuatTwo); - - return (Result); -} - -COVERAGE(HMM_AddVec2CPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Add)(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_AddVec2CPP); - - hmm_vec2 Result = HMM_PREFIX(AddVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddVec3CPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Add)(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_AddVec3CPP); - - hmm_vec3 Result = HMM_PREFIX(AddVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Add)(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_AddVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(AddVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddMat4CPP, 1) -HMM_INLINE hmm_mat4 HMM_PREFIX(Add)(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_AddMat4CPP); - - hmm_mat4 Result = HMM_PREFIX(AddMat4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddQuaternionCPP, 1) -HMM_INLINE hmm_quaternion HMM_PREFIX(Add)(hmm_quaternion Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_AddQuaternionCPP); - - hmm_quaternion Result = HMM_PREFIX(AddQuaternion)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractVec2CPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Subtract)(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_SubtractVec2CPP); - - hmm_vec2 Result = HMM_PREFIX(SubtractVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractVec3CPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Subtract)(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_SubtractVec3CPP); - - hmm_vec3 Result = HMM_PREFIX(SubtractVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Subtract)(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_SubtractVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(SubtractVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractMat4CPP, 1) -HMM_INLINE hmm_mat4 HMM_PREFIX(Subtract)(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_SubtractMat4CPP); - - hmm_mat4 Result = HMM_PREFIX(SubtractMat4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractQuaternionCPP, 1) -HMM_INLINE hmm_quaternion HMM_PREFIX(Subtract)(hmm_quaternion Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_SubtractQuaternionCPP); - - hmm_quaternion Result = HMM_PREFIX(SubtractQuaternion)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec2CPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Multiply)(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2CPP); - - hmm_vec2 Result = HMM_PREFIX(MultiplyVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec2fCPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Multiply)(hmm_vec2 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2fCPP); - - hmm_vec2 Result = HMM_PREFIX(MultiplyVec2f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec3CPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Multiply)(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3CPP); - - hmm_vec3 Result = HMM_PREFIX(MultiplyVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec3fCPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Multiply)(hmm_vec3 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3fCPP); - - hmm_vec3 Result = HMM_PREFIX(MultiplyVec3f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Multiply)(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(MultiplyVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec4fCPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Multiply)(hmm_vec4 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4fCPP); - - hmm_vec4 Result = HMM_PREFIX(MultiplyVec4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4CPP, 1) -HMM_INLINE hmm_mat4 HMM_PREFIX(Multiply)(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4CPP); - - hmm_mat4 Result = HMM_PREFIX(MultiplyMat4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4fCPP, 1) -HMM_INLINE hmm_mat4 HMM_PREFIX(Multiply)(hmm_mat4 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4fCPP); - - hmm_mat4 Result = HMM_PREFIX(MultiplyMat4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4ByVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Multiply)(hmm_mat4 Matrix, hmm_vec4 Vector) -{ - ASSERT_COVERED(HMM_MultiplyMat4ByVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(MultiplyMat4ByVec4)(Matrix, Vector); - - return (Result); -} - -COVERAGE(HMM_MultiplyQuaternionCPP, 1) -HMM_INLINE hmm_quaternion HMM_PREFIX(Multiply)(hmm_quaternion Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_MultiplyQuaternionCPP); - - hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternion)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyQuaternionFCPP, 1) -HMM_INLINE hmm_quaternion HMM_PREFIX(Multiply)(hmm_quaternion Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyQuaternionFCPP); - - hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternionF)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec2CPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Divide)(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_DivideVec2CPP); - - hmm_vec2 Result = HMM_PREFIX(DivideVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec2fCPP, 1) -HMM_INLINE hmm_vec2 HMM_PREFIX(Divide)(hmm_vec2 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec2fCPP); - - hmm_vec2 Result = HMM_PREFIX(DivideVec2f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec3CPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Divide)(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_DivideVec3CPP); - - hmm_vec3 Result = HMM_PREFIX(DivideVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec3fCPP, 1) -HMM_INLINE hmm_vec3 HMM_PREFIX(Divide)(hmm_vec3 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec3fCPP); - - hmm_vec3 Result = HMM_PREFIX(DivideVec3f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec4CPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Divide)(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_DivideVec4CPP); - - hmm_vec4 Result = HMM_PREFIX(DivideVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec4fCPP, 1) -HMM_INLINE hmm_vec4 HMM_PREFIX(Divide)(hmm_vec4 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec4fCPP); - - hmm_vec4 Result = HMM_PREFIX(DivideVec4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideMat4fCPP, 1) -HMM_INLINE hmm_mat4 HMM_PREFIX(Divide)(hmm_mat4 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideMat4fCPP); - - hmm_mat4 Result = HMM_PREFIX(DivideMat4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideQuaternionFCPP, 1) -HMM_INLINE hmm_quaternion HMM_PREFIX(Divide)(hmm_quaternion Left, float Right) -{ - ASSERT_COVERED(HMM_DivideQuaternionFCPP); - - hmm_quaternion Result = HMM_PREFIX(DivideQuaternionF)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_EqualsVec2CPP, 1) -HMM_INLINE hmm_bool HMM_PREFIX(Equals)(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_EqualsVec2CPP); - - hmm_bool Result = HMM_PREFIX(EqualsVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_EqualsVec3CPP, 1) -HMM_INLINE hmm_bool HMM_PREFIX(Equals)(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_EqualsVec3CPP); - - hmm_bool Result = HMM_PREFIX(EqualsVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_EqualsVec4CPP, 1) -HMM_INLINE hmm_bool HMM_PREFIX(Equals)(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_EqualsVec4CPP); - - hmm_bool Result = HMM_PREFIX(EqualsVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddVec2Op, 1) -HMM_INLINE hmm_vec2 operator+(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_AddVec2Op); - - hmm_vec2 Result = HMM_PREFIX(AddVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddVec3Op, 1) -HMM_INLINE hmm_vec3 operator+(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_AddVec3Op); - - hmm_vec3 Result = HMM_PREFIX(AddVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddVec4Op, 1) -HMM_INLINE hmm_vec4 operator+(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_AddVec4Op); - - hmm_vec4 Result = HMM_PREFIX(AddVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddMat4Op, 1) -HMM_INLINE hmm_mat4 operator+(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_AddMat4Op); - - hmm_mat4 Result = HMM_PREFIX(AddMat4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddQuaternionOp, 1) -HMM_INLINE hmm_quaternion operator+(hmm_quaternion Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_AddQuaternionOp); - - hmm_quaternion Result = HMM_PREFIX(AddQuaternion)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractVec2Op, 1) -HMM_INLINE hmm_vec2 operator-(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_SubtractVec2Op); - - hmm_vec2 Result = HMM_PREFIX(SubtractVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractVec3Op, 1) -HMM_INLINE hmm_vec3 operator-(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_SubtractVec3Op); - - hmm_vec3 Result = HMM_PREFIX(SubtractVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractVec4Op, 1) -HMM_INLINE hmm_vec4 operator-(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_SubtractVec4Op); - - hmm_vec4 Result = HMM_PREFIX(SubtractVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractMat4Op, 1) -HMM_INLINE hmm_mat4 operator-(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_SubtractMat4Op); - - hmm_mat4 Result = HMM_PREFIX(SubtractMat4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_SubtractQuaternionOp, 1) -HMM_INLINE hmm_quaternion operator-(hmm_quaternion Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_SubtractQuaternionOp); - - hmm_quaternion Result = HMM_PREFIX(SubtractQuaternion)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec2Op, 1) -HMM_INLINE hmm_vec2 operator*(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2Op); - - hmm_vec2 Result = HMM_PREFIX(MultiplyVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec3Op, 1) -HMM_INLINE hmm_vec3 operator*(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3Op); - - hmm_vec3 Result = HMM_PREFIX(MultiplyVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec4Op, 1) -HMM_INLINE hmm_vec4 operator*(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4Op); - - hmm_vec4 Result = HMM_PREFIX(MultiplyVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4Op, 1) -HMM_INLINE hmm_mat4 operator*(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4Op); - - hmm_mat4 Result = HMM_PREFIX(MultiplyMat4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyQuaternionOp, 1) -HMM_INLINE hmm_quaternion operator*(hmm_quaternion Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_MultiplyQuaternionOp); - - hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternion)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec2fOp, 1) -HMM_INLINE hmm_vec2 operator*(hmm_vec2 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2fOp); - - hmm_vec2 Result = HMM_PREFIX(MultiplyVec2f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec3fOp, 1) -HMM_INLINE hmm_vec3 operator*(hmm_vec3 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3fOp); - - hmm_vec3 Result = HMM_PREFIX(MultiplyVec3f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec4fOp, 1) -HMM_INLINE hmm_vec4 operator*(hmm_vec4 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4fOp); - - hmm_vec4 Result = HMM_PREFIX(MultiplyVec4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4fOp, 1) -HMM_INLINE hmm_mat4 operator*(hmm_mat4 Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4fOp); - - hmm_mat4 Result = HMM_PREFIX(MultiplyMat4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyQuaternionFOp, 1) -HMM_INLINE hmm_quaternion operator*(hmm_quaternion Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyQuaternionFOp); - - hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternionF)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec2fOpLeft, 1) -HMM_INLINE hmm_vec2 operator*(float Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2fOpLeft); - - hmm_vec2 Result = HMM_PREFIX(MultiplyVec2f)(Right, Left); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec3fOpLeft, 1) -HMM_INLINE hmm_vec3 operator*(float Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3fOpLeft); - - hmm_vec3 Result = HMM_PREFIX(MultiplyVec3f)(Right, Left); - - return (Result); -} - -COVERAGE(HMM_MultiplyVec4fOpLeft, 1) -HMM_INLINE hmm_vec4 operator*(float Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4fOpLeft); - - hmm_vec4 Result = HMM_PREFIX(MultiplyVec4f)(Right, Left); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4fOpLeft, 1) -HMM_INLINE hmm_mat4 operator*(float Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4fOpLeft); - - hmm_mat4 Result = HMM_PREFIX(MultiplyMat4f)(Right, Left); - - return (Result); -} - -COVERAGE(HMM_MultiplyQuaternionFOpLeft, 1) -HMM_INLINE hmm_quaternion operator*(float Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_MultiplyQuaternionFOpLeft); - - hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternionF)(Right, Left); - - return (Result); -} - -COVERAGE(HMM_MultiplyMat4ByVec4Op, 1) -HMM_INLINE hmm_vec4 operator*(hmm_mat4 Matrix, hmm_vec4 Vector) -{ - ASSERT_COVERED(HMM_MultiplyMat4ByVec4Op); - - hmm_vec4 Result = HMM_PREFIX(MultiplyMat4ByVec4)(Matrix, Vector); - - return (Result); -} - -COVERAGE(HMM_DivideVec2Op, 1) -HMM_INLINE hmm_vec2 operator/(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_DivideVec2Op); - - hmm_vec2 Result = HMM_PREFIX(DivideVec2)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec3Op, 1) -HMM_INLINE hmm_vec3 operator/(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_DivideVec3Op); - - hmm_vec3 Result = HMM_PREFIX(DivideVec3)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec4Op, 1) -HMM_INLINE hmm_vec4 operator/(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_DivideVec4Op); - - hmm_vec4 Result = HMM_PREFIX(DivideVec4)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec2fOp, 1) -HMM_INLINE hmm_vec2 operator/(hmm_vec2 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec2fOp); - - hmm_vec2 Result = HMM_PREFIX(DivideVec2f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec3fOp, 1) -HMM_INLINE hmm_vec3 operator/(hmm_vec3 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec3fOp); - - hmm_vec3 Result = HMM_PREFIX(DivideVec3f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideVec4fOp, 1) -HMM_INLINE hmm_vec4 operator/(hmm_vec4 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec4fOp); - - hmm_vec4 Result = HMM_PREFIX(DivideVec4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideMat4fOp, 1) -HMM_INLINE hmm_mat4 operator/(hmm_mat4 Left, float Right) -{ - ASSERT_COVERED(HMM_DivideMat4fOp); - - hmm_mat4 Result = HMM_PREFIX(DivideMat4f)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_DivideQuaternionFOp, 1) -HMM_INLINE hmm_quaternion operator/(hmm_quaternion Left, float Right) -{ - ASSERT_COVERED(HMM_DivideQuaternionFOp); - - hmm_quaternion Result = HMM_PREFIX(DivideQuaternionF)(Left, Right); - - return (Result); -} - -COVERAGE(HMM_AddVec2Assign, 1) -HMM_INLINE hmm_vec2 &operator+=(hmm_vec2 &Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_AddVec2Assign); - - return (Left = Left + Right); -} - -COVERAGE(HMM_AddVec3Assign, 1) -HMM_INLINE hmm_vec3 &operator+=(hmm_vec3 &Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_AddVec3Assign); - - return (Left = Left + Right); -} - -COVERAGE(HMM_AddVec4Assign, 1) -HMM_INLINE hmm_vec4 &operator+=(hmm_vec4 &Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_AddVec4Assign); - - return (Left = Left + Right); -} - -COVERAGE(HMM_AddMat4Assign, 1) -HMM_INLINE hmm_mat4 &operator+=(hmm_mat4 &Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_AddMat4Assign); - - return (Left = Left + Right); -} - -COVERAGE(HMM_AddQuaternionAssign, 1) -HMM_INLINE hmm_quaternion &operator+=(hmm_quaternion &Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_AddQuaternionAssign); - - return (Left = Left + Right); -} - -COVERAGE(HMM_SubtractVec2Assign, 1) -HMM_INLINE hmm_vec2 &operator-=(hmm_vec2 &Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_SubtractVec2Assign); - - return (Left = Left - Right); -} - -COVERAGE(HMM_SubtractVec3Assign, 1) -HMM_INLINE hmm_vec3 &operator-=(hmm_vec3 &Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_SubtractVec3Assign); - - return (Left = Left - Right); -} - -COVERAGE(HMM_SubtractVec4Assign, 1) -HMM_INLINE hmm_vec4 &operator-=(hmm_vec4 &Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_SubtractVec4Assign); - - return (Left = Left - Right); -} - -COVERAGE(HMM_SubtractMat4Assign, 1) -HMM_INLINE hmm_mat4 &operator-=(hmm_mat4 &Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_SubtractMat4Assign); - - return (Left = Left - Right); -} - -COVERAGE(HMM_SubtractQuaternionAssign, 1) -HMM_INLINE hmm_quaternion &operator-=(hmm_quaternion &Left, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_SubtractQuaternionAssign); - - return (Left = Left - Right); -} - -COVERAGE(HMM_MultiplyVec2Assign, 1) -HMM_INLINE hmm_vec2 &operator*=(hmm_vec2 &Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2Assign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyVec3Assign, 1) -HMM_INLINE hmm_vec3 &operator*=(hmm_vec3 &Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3Assign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyVec4Assign, 1) -HMM_INLINE hmm_vec4 &operator*=(hmm_vec4 &Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4Assign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyVec2fAssign, 1) -HMM_INLINE hmm_vec2 &operator*=(hmm_vec2 &Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec2fAssign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyVec3fAssign, 1) -HMM_INLINE hmm_vec3 &operator*=(hmm_vec3 &Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec3fAssign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyVec4fAssign, 1) -HMM_INLINE hmm_vec4 &operator*=(hmm_vec4 &Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyVec4fAssign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyMat4fAssign, 1) -HMM_INLINE hmm_mat4 &operator*=(hmm_mat4 &Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4fAssign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_MultiplyQuaternionFAssign, 1) -HMM_INLINE hmm_quaternion &operator*=(hmm_quaternion &Left, float Right) -{ - ASSERT_COVERED(HMM_MultiplyQuaternionFAssign); - - return (Left = Left * Right); -} - -COVERAGE(HMM_DivideVec2Assign, 1) -HMM_INLINE hmm_vec2 &operator/=(hmm_vec2 &Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_DivideVec2Assign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideVec3Assign, 1) -HMM_INLINE hmm_vec3 &operator/=(hmm_vec3 &Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_DivideVec3Assign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideVec4Assign, 1) -HMM_INLINE hmm_vec4 &operator/=(hmm_vec4 &Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_DivideVec4Assign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideVec2fAssign, 1) -HMM_INLINE hmm_vec2 &operator/=(hmm_vec2 &Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec2fAssign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideVec3fAssign, 1) -HMM_INLINE hmm_vec3 &operator/=(hmm_vec3 &Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec3fAssign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideVec4fAssign, 1) -HMM_INLINE hmm_vec4 &operator/=(hmm_vec4 &Left, float Right) -{ - ASSERT_COVERED(HMM_DivideVec4fAssign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideMat4fAssign, 1) -HMM_INLINE hmm_mat4 &operator/=(hmm_mat4 &Left, float Right) -{ - ASSERT_COVERED(HMM_DivideMat4fAssign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_DivideQuaternionFAssign, 1) -HMM_INLINE hmm_quaternion &operator/=(hmm_quaternion &Left, float Right) -{ - ASSERT_COVERED(HMM_DivideQuaternionFAssign); - - return (Left = Left / Right); -} - -COVERAGE(HMM_EqualsVec2Op, 1) -HMM_INLINE hmm_bool operator==(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_EqualsVec2Op); - - return HMM_PREFIX(EqualsVec2)(Left, Right); -} - -COVERAGE(HMM_EqualsVec3Op, 1) -HMM_INLINE hmm_bool operator==(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_EqualsVec3Op); - - return HMM_PREFIX(EqualsVec3)(Left, Right); -} - -COVERAGE(HMM_EqualsVec4Op, 1) -HMM_INLINE hmm_bool operator==(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_EqualsVec4Op); - - return HMM_PREFIX(EqualsVec4)(Left, Right); -} - -COVERAGE(HMM_EqualsVec2OpNot, 1) -HMM_INLINE hmm_bool operator!=(hmm_vec2 Left, hmm_vec2 Right) -{ - ASSERT_COVERED(HMM_EqualsVec2OpNot); - - return !HMM_PREFIX(EqualsVec2)(Left, Right); -} - -COVERAGE(HMM_EqualsVec3OpNot, 1) -HMM_INLINE hmm_bool operator!=(hmm_vec3 Left, hmm_vec3 Right) -{ - ASSERT_COVERED(HMM_EqualsVec3OpNot); - - return !HMM_PREFIX(EqualsVec3)(Left, Right); -} - -COVERAGE(HMM_EqualsVec4OpNot, 1) -HMM_INLINE hmm_bool operator!=(hmm_vec4 Left, hmm_vec4 Right) -{ - ASSERT_COVERED(HMM_EqualsVec4OpNot); - - return !HMM_PREFIX(EqualsVec4)(Left, Right); -} - -#endif /* __cplusplus */ - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif - -#endif /* HANDMADE_MATH_H */ - -#ifdef HANDMADE_MATH_IMPLEMENTATION - -COVERAGE(HMM_Power, 2) -float HMM_PREFIX(Power)(float Base, int Exponent) -{ - ASSERT_COVERED(HMM_Power); - - float Result = 1.0f; - float Mul = Exponent < 0 ? 1.f / Base : Base; - int X = Exponent < 0 ? -Exponent : Exponent; - while (X) - { - if (X & 1) - { - ASSERT_COVERED(HMM_Power); - - Result *= Mul; - } - - Mul *= Mul; - X >>= 1; - } - - return (Result); -} - -#ifndef HANDMADE_MATH__USE_SSE -COVERAGE(HMM_Transpose, 1) -hmm_mat4 HMM_PREFIX(Transpose)(hmm_mat4 Matrix) -{ - ASSERT_COVERED(HMM_Transpose); - - hmm_mat4 Result; - - int Columns; - for(Columns = 0; Columns < 4; ++Columns) - { - int Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - Result.Elements[Rows][Columns] = Matrix.Elements[Columns][Rows]; - } - } - - return (Result); -} -#endif - -#ifndef HANDMADE_MATH__USE_SSE -COVERAGE(HMM_AddMat4, 1) -hmm_mat4 HMM_PREFIX(AddMat4)(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_AddMat4); - - hmm_mat4 Result; - - int Columns; - for(Columns = 0; Columns < 4; ++Columns) - { - int Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - Result.Elements[Columns][Rows] = Left.Elements[Columns][Rows] + Right.Elements[Columns][Rows]; - } - } - - return (Result); -} -#endif - -#ifndef HANDMADE_MATH__USE_SSE -COVERAGE(HMM_SubtractMat4, 1) -hmm_mat4 HMM_PREFIX(SubtractMat4)(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_SubtractMat4); - - hmm_mat4 Result; - - int Columns; - for(Columns = 0; Columns < 4; ++Columns) - { - int Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - Result.Elements[Columns][Rows] = Left.Elements[Columns][Rows] - Right.Elements[Columns][Rows]; - } - } - - return (Result); -} -#endif - -COVERAGE(HMM_MultiplyMat4, 1) -hmm_mat4 HMM_PREFIX(MultiplyMat4)(hmm_mat4 Left, hmm_mat4 Right) -{ - ASSERT_COVERED(HMM_MultiplyMat4); - - hmm_mat4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.Columns[0] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[0], Left); - Result.Columns[1] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[1], Left); - Result.Columns[2] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[2], Left); - Result.Columns[3] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[3], Left); -#else - int Columns; - for(Columns = 0; Columns < 4; ++Columns) - { - int Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - float Sum = 0; - int CurrentMatrice; - for(CurrentMatrice = 0; CurrentMatrice < 4; ++CurrentMatrice) - { - Sum += Left.Elements[CurrentMatrice][Rows] * Right.Elements[Columns][CurrentMatrice]; - } - - Result.Elements[Columns][Rows] = Sum; - } - } -#endif - - return (Result); -} - -#ifndef HANDMADE_MATH__USE_SSE -COVERAGE(HMM_MultiplyMat4f, 1) -hmm_mat4 HMM_PREFIX(MultiplyMat4f)(hmm_mat4 Matrix, float Scalar) -{ - ASSERT_COVERED(HMM_MultiplyMat4f); - - hmm_mat4 Result; - - int Columns; - for(Columns = 0; Columns < 4; ++Columns) - { - int Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - Result.Elements[Columns][Rows] = Matrix.Elements[Columns][Rows] * Scalar; - } - } - - return (Result); -} -#endif - -COVERAGE(HMM_MultiplyMat4ByVec4, 1) -hmm_vec4 HMM_PREFIX(MultiplyMat4ByVec4)(hmm_mat4 Matrix, hmm_vec4 Vector) -{ - ASSERT_COVERED(HMM_MultiplyMat4ByVec4); - - hmm_vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.InternalElementsSSE = HMM_PREFIX(LinearCombineSSE)(Vector.InternalElementsSSE, Matrix); -#else - int Columns, Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - float Sum = 0; - for(Columns = 0; Columns < 4; ++Columns) - { - Sum += Matrix.Elements[Columns][Rows] * Vector.Elements[Columns]; - } - - Result.Elements[Rows] = Sum; - } -#endif - - return (Result); -} - -#ifndef HANDMADE_MATH__USE_SSE -COVERAGE(HMM_DivideMat4f, 1); -hmm_mat4 HMM_PREFIX(DivideMat4f)(hmm_mat4 Matrix, float Scalar) -{ - ASSERT_COVERED(HMM_DivideMat4f); - - hmm_mat4 Result; - - int Columns; - for(Columns = 0; Columns < 4; ++Columns) - { - int Rows; - for(Rows = 0; Rows < 4; ++Rows) - { - Result.Elements[Columns][Rows] = Matrix.Elements[Columns][Rows] / Scalar; - } - } - - return (Result); -} -#endif - -COVERAGE(HMM_Rotate, 1) -hmm_mat4 HMM_PREFIX(Rotate)(float Angle, hmm_vec3 Axis) -{ - ASSERT_COVERED(HMM_Rotate); - - hmm_mat4 Result = HMM_PREFIX(Mat4d)(1.0f); - - Axis = HMM_PREFIX(NormalizeVec3)(Axis); - - float SinTheta = HMM_PREFIX(SinF)(HMM_PREFIX(ToRadians)(Angle)); - float CosTheta = HMM_PREFIX(CosF)(HMM_PREFIX(ToRadians)(Angle)); - float CosValue = 1.0f - CosTheta; - - Result.Elements[0][0] = (Axis.X * Axis.X * CosValue) + CosTheta; - Result.Elements[0][1] = (Axis.X * Axis.Y * CosValue) + (Axis.Z * SinTheta); - Result.Elements[0][2] = (Axis.X * Axis.Z * CosValue) - (Axis.Y * SinTheta); - - Result.Elements[1][0] = (Axis.Y * Axis.X * CosValue) - (Axis.Z * SinTheta); - Result.Elements[1][1] = (Axis.Y * Axis.Y * CosValue) + CosTheta; - Result.Elements[1][2] = (Axis.Y * Axis.Z * CosValue) + (Axis.X * SinTheta); - - Result.Elements[2][0] = (Axis.Z * Axis.X * CosValue) + (Axis.Y * SinTheta); - Result.Elements[2][1] = (Axis.Z * Axis.Y * CosValue) - (Axis.X * SinTheta); - Result.Elements[2][2] = (Axis.Z * Axis.Z * CosValue) + CosTheta; - - return (Result); -} - -COVERAGE(HMM_LookAt, 1) -hmm_mat4 HMM_PREFIX(LookAt)(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up) -{ - ASSERT_COVERED(HMM_LookAt); - - hmm_mat4 Result; - - hmm_vec3 F = HMM_PREFIX(NormalizeVec3)(HMM_PREFIX(SubtractVec3)(Center, Eye)); - hmm_vec3 S = HMM_PREFIX(NormalizeVec3)(HMM_PREFIX(Cross)(F, Up)); - hmm_vec3 U = HMM_PREFIX(Cross)(S, F); - - Result.Elements[0][0] = S.X; - Result.Elements[0][1] = U.X; - Result.Elements[0][2] = -F.X; - Result.Elements[0][3] = 0.0f; - - Result.Elements[1][0] = S.Y; - Result.Elements[1][1] = U.Y; - Result.Elements[1][2] = -F.Y; - Result.Elements[1][3] = 0.0f; - - Result.Elements[2][0] = S.Z; - Result.Elements[2][1] = U.Z; - Result.Elements[2][2] = -F.Z; - Result.Elements[2][3] = 0.0f; - - Result.Elements[3][0] = -HMM_PREFIX(DotVec3)(S, Eye); - Result.Elements[3][1] = -HMM_PREFIX(DotVec3)(U, Eye); - Result.Elements[3][2] = HMM_PREFIX(DotVec3)(F, Eye); - Result.Elements[3][3] = 1.0f; - - return (Result); -} - -COVERAGE(HMM_InverseQuaternion, 1) -hmm_quaternion HMM_PREFIX(InverseQuaternion)(hmm_quaternion Left) -{ - ASSERT_COVERED(HMM_InverseQuaternion); - - hmm_quaternion Conjugate; - hmm_quaternion Result; - float Norm = 0; - float NormSquared = 0; - - Conjugate.X = -Left.X; - Conjugate.Y = -Left.Y; - Conjugate.Z = -Left.Z; - Conjugate.W = Left.W; - - Norm = HMM_PREFIX(SquareRootF)(HMM_PREFIX(DotQuaternion)(Left, Left)); - NormSquared = Norm * Norm; - - Result = HMM_PREFIX(DivideQuaternionF)(Conjugate, NormSquared); - - return (Result); -} - -COVERAGE(HMM_Slerp, 1) -hmm_quaternion HMM_PREFIX(Slerp)(hmm_quaternion Left, float Time, hmm_quaternion Right) -{ - ASSERT_COVERED(HMM_Slerp); - - hmm_quaternion Result; - hmm_quaternion QuaternionLeft; - hmm_quaternion QuaternionRight; - - float Cos_Theta = HMM_PREFIX(DotQuaternion)(Left, Right); - float Angle = HMM_PREFIX(ACosF)(Cos_Theta); - - float S1 = HMM_PREFIX(SinF)((1.0f - Time) * Angle); - float S2 = HMM_PREFIX(SinF)(Time * Angle); - float Is = 1.0f / HMM_PREFIX(SinF)(Angle); - - QuaternionLeft = HMM_PREFIX(MultiplyQuaternionF)(Left, S1); - QuaternionRight = HMM_PREFIX(MultiplyQuaternionF)(Right, S2); - - Result = HMM_PREFIX(AddQuaternion)(QuaternionLeft, QuaternionRight); - Result = HMM_PREFIX(MultiplyQuaternionF)(Result, Is); - - return (Result); -} - -COVERAGE(HMM_QuaternionToMat4, 1) -hmm_mat4 HMM_PREFIX(QuaternionToMat4)(hmm_quaternion Left) -{ - ASSERT_COVERED(HMM_QuaternionToMat4); - - hmm_mat4 Result; - - hmm_quaternion NormalizedQuaternion = HMM_PREFIX(NormalizeQuaternion)(Left); - - float XX, YY, ZZ, - XY, XZ, YZ, - WX, WY, WZ; - - XX = NormalizedQuaternion.X * NormalizedQuaternion.X; - YY = NormalizedQuaternion.Y * NormalizedQuaternion.Y; - ZZ = NormalizedQuaternion.Z * NormalizedQuaternion.Z; - XY = NormalizedQuaternion.X * NormalizedQuaternion.Y; - XZ = NormalizedQuaternion.X * NormalizedQuaternion.Z; - YZ = NormalizedQuaternion.Y * NormalizedQuaternion.Z; - WX = NormalizedQuaternion.W * NormalizedQuaternion.X; - WY = NormalizedQuaternion.W * NormalizedQuaternion.Y; - WZ = NormalizedQuaternion.W * NormalizedQuaternion.Z; - - Result.Elements[0][0] = 1.0f - 2.0f * (YY + ZZ); - Result.Elements[0][1] = 2.0f * (XY + WZ); - Result.Elements[0][2] = 2.0f * (XZ - WY); - Result.Elements[0][3] = 0.0f; - - Result.Elements[1][0] = 2.0f * (XY - WZ); - Result.Elements[1][1] = 1.0f - 2.0f * (XX + ZZ); - Result.Elements[1][2] = 2.0f * (YZ + WX); - Result.Elements[1][3] = 0.0f; - - Result.Elements[2][0] = 2.0f * (XZ + WY); - Result.Elements[2][1] = 2.0f * (YZ - WX); - Result.Elements[2][2] = 1.0f - 2.0f * (XX + YY); - Result.Elements[2][3] = 0.0f; - - Result.Elements[3][0] = 0.0f; - Result.Elements[3][1] = 0.0f; - Result.Elements[3][2] = 0.0f; - Result.Elements[3][3] = 1.0f; - - return (Result); -} - -// This method taken from Mike Day at Insomniac Games. -// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf -// -// Note that as mentioned at the top of the paper, the paper assumes the matrix -// would be *post*-multiplied to a vector to rotate it, meaning the matrix is -// the transpose of what we're dealing with. But, because our matrices are -// stored in column-major order, the indices *appear* to match the paper. -// -// For example, m12 in the paper is row 1, column 2. We need to transpose it to -// row 2, column 1. But, because the column comes first when referencing -// elements, it looks like M.Elements[1][2]. -// -// Don't be confused! Or if you must be confused, at least trust this -// comment. :) -COVERAGE(HMM_Mat4ToQuaternion, 4) -hmm_quaternion HMM_PREFIX(Mat4ToQuaternion)(hmm_mat4 M) -{ - float T; - hmm_quaternion Q; - - if (M.Elements[2][2] < 0.0f) { - if (M.Elements[0][0] > M.Elements[1][1]) { - ASSERT_COVERED(HMM_Mat4ToQuaternion); - - T = 1 + M.Elements[0][0] - M.Elements[1][1] - M.Elements[2][2]; - Q = HMM_PREFIX(Quaternion)( - T, - M.Elements[0][1] + M.Elements[1][0], - M.Elements[2][0] + M.Elements[0][2], - M.Elements[1][2] - M.Elements[2][1] - ); - } else { - ASSERT_COVERED(HMM_Mat4ToQuaternion); - - T = 1 - M.Elements[0][0] + M.Elements[1][1] - M.Elements[2][2]; - Q = HMM_PREFIX(Quaternion)( - M.Elements[0][1] + M.Elements[1][0], - T, - M.Elements[1][2] + M.Elements[2][1], - M.Elements[2][0] - M.Elements[0][2] - ); - } - } else { - if (M.Elements[0][0] < -M.Elements[1][1]) { - ASSERT_COVERED(HMM_Mat4ToQuaternion); - - T = 1 - M.Elements[0][0] - M.Elements[1][1] + M.Elements[2][2]; - Q = HMM_PREFIX(Quaternion)( - M.Elements[2][0] + M.Elements[0][2], - M.Elements[1][2] + M.Elements[2][1], - T, - M.Elements[0][1] - M.Elements[1][0] - ); - } else { - ASSERT_COVERED(HMM_Mat4ToQuaternion); - - T = 1 + M.Elements[0][0] + M.Elements[1][1] + M.Elements[2][2]; - Q = HMM_PREFIX(Quaternion)( - M.Elements[1][2] - M.Elements[2][1], - M.Elements[2][0] - M.Elements[0][2], - M.Elements[0][1] - M.Elements[1][0], - T - ); - } - } - - Q = HMM_PREFIX(MultiplyQuaternionF)(Q, 0.5f / HMM_PREFIX(SquareRootF)(T)); - - return Q; -} - -COVERAGE(HMM_QuaternionFromAxisAngle, 1) -hmm_quaternion HMM_PREFIX(QuaternionFromAxisAngle)(hmm_vec3 Axis, float AngleOfRotation) -{ - ASSERT_COVERED(HMM_QuaternionFromAxisAngle); - - hmm_quaternion Result; - - hmm_vec3 AxisNormalized = HMM_PREFIX(NormalizeVec3)(Axis); - float SineOfRotation = HMM_PREFIX(SinF)(AngleOfRotation / 2.0f); - - Result.XYZ = HMM_PREFIX(MultiplyVec3f)(AxisNormalized, SineOfRotation); - Result.W = HMM_PREFIX(CosF)(AngleOfRotation / 2.0f); - - return (Result); -} - -#endif /* HANDMADE_MATH_IMPLEMENTATION */ \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index e959107..765af09 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -535,6 +535,12 @@ WinMain ( { gs_thread_context ThreadContext = Win32CreateThreadContext(); + gs_allocator_debug AllocDebug = {}; + AllocDebug.AllocationsCountMax = 4096; + AllocDebug.Allocations = (gs_debug_allocation*)Win32Alloc(sizeof(gs_debug_allocation) * AllocDebug.AllocationsCountMax, 0); + + ThreadContext.Allocator.Debug = &AllocDebug; + gs_file_info A = GetFileInfo(ThreadContext.FileHandler, ConstString("C:\\projects\\Lumenarium")); gs_file_info B = GetFileInfo(ThreadContext.FileHandler, ConstString("C:\\projects\\Lumenarium\\")); @@ -556,7 +562,7 @@ WinMain ( Context.MemorySize = MB(64); Context.MemoryBase = (u8*)Win32Alloc(Context.MemorySize, 0); - gs_memory_arena PlatformPermanent = CreateMemoryArena(Context.ThreadContext.Allocator); + gs_memory_arena PlatformPermanent = CreateMemoryArena(Context.ThreadContext.Allocator, "Platform Memory"); s64 PerformanceCountFrequency = GetPerformanceFrequency(); s64 LastFrameEnd = GetWallClock(); diff --git a/src/app/platform_win32/win32_foldhaus_serial.h b/src/app/platform_win32/win32_foldhaus_serial.h index 7f21539..c3dcfb1 100644 --- a/src/app/platform_win32/win32_foldhaus_serial.h +++ b/src/app/platform_win32/win32_foldhaus_serial.h @@ -204,9 +204,13 @@ Win32SerialArray_Create(gs_thread_context Context) Win32SerialPortNames = AllocatorAllocArray(Context.Allocator, gs_string, Win32SerialHandlesCountMax); Win32SerialPortFilled = AllocatorAllocArray(Context.Allocator, s32, Win32SerialHandlesCountMax); + u64 PortNameSize = 256; + u64 PortNameBufferSize = PortNameSize * Win32SerialHandlesCountMax; + char* PortNameBuffer = AllocatorAllocArray(Context.Allocator, char, PortNameBufferSize); for (u32 i = 0; i < Win32SerialHandlesCountMax; i++) { - Win32SerialPortNames[i] = AllocatorAllocString(Context.Allocator, 256); + char* NameBase = PortNameBuffer + (PortNameSize * i); + Win32SerialPortNames[i] = MakeString(NameBase, 0, PortNameSize); Win32SerialPortFilled[i] = 0; } } diff --git a/src/app/platform_win32/win32_foldhaus_work_queue.h b/src/app/platform_win32/win32_foldhaus_work_queue.h index b3a2a36..8d18986 100644 --- a/src/app/platform_win32/win32_foldhaus_work_queue.h +++ b/src/app/platform_win32/win32_foldhaus_work_queue.h @@ -48,7 +48,7 @@ Win32CreateThreadContext(gs_memory_arena* Transient = 0) else { Result.Transient = (gs_memory_arena*)AllocatorAlloc(Result.Allocator, sizeof(gs_memory_arena)).Memory; - *Result.Transient = CreateMemoryArena(Result.Allocator); + *Result.Transient = CreateMemoryArena(Result.Allocator, "Tctx Transient"); } Result.FileHandler = CreateFileHandler(Win32GetFileInfo, Win32ReadEntireFile, diff --git a/src/app/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp similarity index 98% rename from src/app/blumen_lumen.cpp rename to src/app/ss_blumen_lumen/blumen_lumen.cpp index 09cf12d..698451f 100644 --- a/src/app/blumen_lumen.cpp +++ b/src/app/ss_blumen_lumen/blumen_lumen.cpp @@ -24,10 +24,8 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) while (*Data->Running) { -#if 1 if (SocketQueryStatus(Data->SocketManager, Data->ListenSocket)) { - // TODO(pjs): Removing this block for now - nothing is wrong with it except that SocketPeek is still blocking for some reason if (SocketPeek(Data->SocketManager, Data->ListenSocket)) { // TODO(pjs): Make this a peek operation @@ -41,7 +39,6 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) } } } -#endif while (Data->OutgoingMsgQueue->ReadHead != Data->OutgoingMsgQueue->WriteHead) { diff --git a/src/app/blumen_lumen.h b/src/app/ss_blumen_lumen/blumen_lumen.h similarity index 100% rename from src/app/blumen_lumen.h rename to src/app/ss_blumen_lumen/blumen_lumen.h diff --git a/src/app/sse_mathfun.h b/src/app/sse_mathfun.h deleted file mode 100644 index 16b22e9..0000000 --- a/src/app/sse_mathfun.h +++ /dev/null @@ -1,711 +0,0 @@ -/* SIMD (SSE1+MMX or SSE2) implementation of sin, cos, exp and log - - Inspired by Intel Approximate Math library, and based on the - corresponding algorithms of the cephes math library - - The default is to use the SSE1 version. If you define USE_SSE2 the - the SSE2 intrinsics will be used in place of the MMX intrinsics. Do - not expect any significant performance improvement with SSE2. -*/ - -/* Copyright (C) 2007 Julien Pommier - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - (this is the zlib license) -*/ - -#include - -/* yes I know, the top of this file is quite ugly */ - -#ifdef _MSC_VER /* visual c++ */ -# define ALIGN16_BEG __declspec(align(16)) -# define ALIGN16_END -#else /* gcc or icc */ -# define ALIGN16_BEG -# define ALIGN16_END __attribute__((aligned(16))) -#endif - -/* __m128 is ugly to write */ -typedef __m128 v4sf; // vector of 4 float (sse1) - -#ifdef USE_SSE2 -# include -typedef __m128i v4si; // vector of 4 int (sse2) -#else -typedef __m64 v2si; // vector of 2 int (mmx) -#endif - -/* declare some SSE constants -- why can't I figure a better way to do that? */ -#define _PS_CONST(Name, Val) \ -static const ALIGN16_BEG float _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val } -#define _PI32_CONST(Name, Val) \ -static const ALIGN16_BEG int _pi32_##Name[4] ALIGN16_END = { Val, Val, Val, Val } -#define _PS_CONST_TYPE(Name, Type, Val) \ -static const ALIGN16_BEG Type _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val } - -_PS_CONST(1 , 1.0f); -_PS_CONST(0p5, 0.5f); -/* the smallest non denormalized float number */ -_PS_CONST_TYPE(min_norm_pos, int, 0x00800000); -_PS_CONST_TYPE(mant_mask, int, 0x7f800000); -_PS_CONST_TYPE(inv_mant_mask, int, ~0x7f800000); - -_PS_CONST_TYPE(sign_mask, int, (int)0x80000000); -_PS_CONST_TYPE(inv_sign_mask, int, ~0x80000000); - -_PI32_CONST(1, 1); -_PI32_CONST(inv1, ~1); -_PI32_CONST(2, 2); -_PI32_CONST(4, 4); -_PI32_CONST(0x7f, 0x7f); - -_PS_CONST(cephes_SQRTHF, 0.707106781186547524); -_PS_CONST(cephes_log_p0, 7.0376836292E-2); -_PS_CONST(cephes_log_p1, - 1.1514610310E-1); -_PS_CONST(cephes_log_p2, 1.1676998740E-1); -_PS_CONST(cephes_log_p3, - 1.2420140846E-1); -_PS_CONST(cephes_log_p4, + 1.4249322787E-1); -_PS_CONST(cephes_log_p5, - 1.6668057665E-1); -_PS_CONST(cephes_log_p6, + 2.0000714765E-1); -_PS_CONST(cephes_log_p7, - 2.4999993993E-1); -_PS_CONST(cephes_log_p8, + 3.3333331174E-1); -_PS_CONST(cephes_log_q1, -2.12194440e-4); -_PS_CONST(cephes_log_q2, 0.693359375); - -#ifndef USE_SSE2 -typedef union xmm_mm_union { - __m128 xmm; - __m64 mm[2]; -} xmm_mm_union; - -#define COPY_XMM_TO_MM(xmm_, mm0_, mm1_) { \ - xmm_mm_union u; u.xmm = xmm_; \ - mm0_ = u.mm[0]; \ - mm1_ = u.mm[1]; \ -} - -#define COPY_MM_TO_XMM(mm0_, mm1_, xmm_) { \ - xmm_mm_union u; u.mm[0]=mm0_; u.mm[1]=mm1_; xmm_ = u.xmm; \ -} - -#endif // USE_SSE2 - -/* natural logarithm computed for 4 simultaneous float - return NaN for x <= 0 -*/ -v4sf log_ps(v4sf x) { -#ifdef USE_SSE2 - v4si emm0; -#else - v2si mm0, mm1; -#endif - v4sf one = *(v4sf*)_ps_1; - - v4sf invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps()); - - x = _mm_max_ps(x, *(v4sf*)_ps_min_norm_pos); /* cut off denormalized stuff */ - -#ifndef USE_SSE2 - /* part 1: x = frexpf(x, &e); */ - COPY_XMM_TO_MM(x, mm0, mm1); - mm0 = _mm_srli_pi32(mm0, 23); - mm1 = _mm_srli_pi32(mm1, 23); -#else - emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23); -#endif - /* keep only the fractional part */ - x = _mm_and_ps(x, *(v4sf*)_ps_inv_mant_mask); - x = _mm_or_ps(x, *(v4sf*)_ps_0p5); - -#ifndef USE_SSE2 - /* now e=mm0:mm1 contain the really base-2 exponent */ - mm0 = _mm_sub_pi32(mm0, *(v2si*)_pi32_0x7f); - mm1 = _mm_sub_pi32(mm1, *(v2si*)_pi32_0x7f); - v4sf e = _mm_cvtpi32x2_ps(mm0, mm1); - _mm_empty(); /* bye bye mmx */ -#else - emm0 = _mm_sub_epi32(emm0, *(v4si*)_pi32_0x7f); - v4sf e = _mm_cvtepi32_ps(emm0); -#endif - - e = _mm_add_ps(e, one); - - /* part2: - if( x < SQRTHF ) { - e -= 1; - x = x + x - 1.0; - } else { x = x - 1.0; } - */ - v4sf mask = _mm_cmplt_ps(x, *(v4sf*)_ps_cephes_SQRTHF); - v4sf tmp = _mm_and_ps(x, mask); - x = _mm_sub_ps(x, one); - e = _mm_sub_ps(e, _mm_and_ps(one, mask)); - x = _mm_add_ps(x, tmp); - - - v4sf z = _mm_mul_ps(x,x); - - v4sf y = *(v4sf*)_ps_cephes_log_p0; - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p1); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p2); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p3); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p4); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p5); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p6); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p7); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p8); - y = _mm_mul_ps(y, x); - - y = _mm_mul_ps(y, z); - - - tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q1); - y = _mm_add_ps(y, tmp); - - - tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5); - y = _mm_sub_ps(y, tmp); - - tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q2); - x = _mm_add_ps(x, y); - x = _mm_add_ps(x, tmp); - x = _mm_or_ps(x, invalid_mask); // negative arg will be NAN - return x; -} - -_PS_CONST(exp_hi, 88.3762626647949f); -_PS_CONST(exp_lo, -88.3762626647949f); - -_PS_CONST(cephes_LOG2EF, 1.44269504088896341); -_PS_CONST(cephes_exp_C1, 0.693359375); -_PS_CONST(cephes_exp_C2, -2.12194440e-4); - -_PS_CONST(cephes_exp_p0, 1.9875691500E-4); -_PS_CONST(cephes_exp_p1, 1.3981999507E-3); -_PS_CONST(cephes_exp_p2, 8.3334519073E-3); -_PS_CONST(cephes_exp_p3, 4.1665795894E-2); -_PS_CONST(cephes_exp_p4, 1.6666665459E-1); -_PS_CONST(cephes_exp_p5, 5.0000001201E-1); - -v4sf exp_ps(v4sf x) { - v4sf tmp = _mm_setzero_ps(), fx; -#ifdef USE_SSE2 - v4si emm0; -#else - v2si mm0, mm1; -#endif - v4sf one = *(v4sf*)_ps_1; - - x = _mm_min_ps(x, *(v4sf*)_ps_exp_hi); - x = _mm_max_ps(x, *(v4sf*)_ps_exp_lo); - - /* express exp(x) as exp(g + n*log(2)) */ - fx = _mm_mul_ps(x, *(v4sf*)_ps_cephes_LOG2EF); - fx = _mm_add_ps(fx, *(v4sf*)_ps_0p5); - - /* how to perform a floorf with SSE: just below */ -#ifndef USE_SSE2 - /* step 1 : cast to int */ - tmp = _mm_movehl_ps(tmp, fx); - mm0 = _mm_cvttps_pi32(fx); - mm1 = _mm_cvttps_pi32(tmp); - /* step 2 : cast back to float */ - tmp = _mm_cvtpi32x2_ps(mm0, mm1); -#else - emm0 = _mm_cvttps_epi32(fx); - tmp = _mm_cvtepi32_ps(emm0); -#endif - /* if greater, substract 1 */ - v4sf mask = _mm_cmpgt_ps(tmp, fx); - mask = _mm_and_ps(mask, one); - fx = _mm_sub_ps(tmp, mask); - - tmp = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C1); - v4sf z = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C2); - x = _mm_sub_ps(x, tmp); - x = _mm_sub_ps(x, z); - - z = _mm_mul_ps(x,x); - - v4sf y = *(v4sf*)_ps_cephes_exp_p0; - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p1); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p2); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p3); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p4); - y = _mm_mul_ps(y, x); - y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p5); - y = _mm_mul_ps(y, z); - y = _mm_add_ps(y, x); - y = _mm_add_ps(y, one); - - /* build 2^n */ -#ifndef USE_SSE2 - z = _mm_movehl_ps(z, fx); - mm0 = _mm_cvttps_pi32(fx); - mm1 = _mm_cvttps_pi32(z); - mm0 = _mm_add_pi32(mm0, *(v2si*)_pi32_0x7f); - mm1 = _mm_add_pi32(mm1, *(v2si*)_pi32_0x7f); - mm0 = _mm_slli_pi32(mm0, 23); - mm1 = _mm_slli_pi32(mm1, 23); - - v4sf pow2n; - COPY_MM_TO_XMM(mm0, mm1, pow2n); - _mm_empty(); -#else - emm0 = _mm_cvttps_epi32(fx); - emm0 = _mm_add_epi32(emm0, *(v4si*)_pi32_0x7f); - emm0 = _mm_slli_epi32(emm0, 23); - v4sf pow2n = _mm_castsi128_ps(emm0); -#endif - y = _mm_mul_ps(y, pow2n); - return y; -} - -_PS_CONST(minus_cephes_DP1, -0.78515625); -_PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4); -_PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8); -_PS_CONST(sincof_p0, -1.9515295891E-4); -_PS_CONST(sincof_p1, 8.3321608736E-3); -_PS_CONST(sincof_p2, -1.6666654611E-1); -_PS_CONST(coscof_p0, 2.443315711809948E-005); -_PS_CONST(coscof_p1, -1.388731625493765E-003); -_PS_CONST(coscof_p2, 4.166664568298827E-002); -_PS_CONST(cephes_FOPI, 1.27323954473516); // 4 / M_PI - - -/* evaluation of 4 sines at onces, using only SSE1+MMX intrinsics so - it runs also on old athlons XPs and the pentium III of your grand - mother. - - The code is the exact rewriting of the cephes sinf function. - Precision is excellent as long as x < 8192 (I did not bother to - take into account the special handling they have for greater values - -- it does not return garbage for arguments over 8192, though, but - the extra precision is missing). - - Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the - surprising but correct result. - - Performance is also surprisingly good, 1.33 times faster than the - macos vsinf SSE2 function, and 1.5 times faster than the - __vrs4_sinf of amd's ACML (which is only available in 64 bits). Not - too bad for an SSE1 function (with no special tuning) ! - However the latter libraries probably have a much better handling of NaN, - Inf, denormalized and other special arguments.. - - On my core 1 duo, the execution of this function takes approximately 95 cycles. - - From what I have observed on the experiments with Intel AMath lib, switching to an - SSE2 version would improve the perf by only 10%. - - Since it is based on SSE intrinsics, it has to be compiled at -O2 to - deliver full speed. -*/ -v4sf sin_ps(v4sf x) { // any x - v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; - -#ifdef USE_SSE2 - v4si emm0, emm2; -#else - v2si mm0, mm1, mm2, mm3; -#endif - sign_bit = x; - /* take the absolute value */ - x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask); - /* extract the sign bit (upper one) */ - sign_bit = _mm_and_ps(sign_bit, *(v4sf*)_ps_sign_mask); - - /* scale by 4/Pi */ - y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI); - -#ifdef USE_SSE2 - /* store the integer part of y in mm0 */ - emm2 = _mm_cvttps_epi32(y); - /* j=(j+1) & (~1) (see the cephes sources) */ - emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1); - emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1); - y = _mm_cvtepi32_ps(emm2); - - /* get the swap sign flag */ - emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4); - emm0 = _mm_slli_epi32(emm0, 29); - /* get the polynom selection mask - there is one polynom for 0 <= x <= Pi/4 - and another one for Pi/4> precision OK for the tan_ps <<- - -checking tan on [-0.49*Pi, 0.49*Pi] -max deviation from tanf(x): 3.8147e-06 at -0.490000009841*Pi, max deviation from cephes_tan(x): -9.53674e-07 - ->> precision OK for the tan_ps <<- - -checking cot on [0.2*Pi, 0.7*Pi] -max deviation from cotf(x): 1.19209e-07 at 0.204303119606*Pi, max deviation from cephes_cot(x): -1.19209e-07 - ->> precision OK for the cot_ps <<- - -checking cot on [0.01*Pi, 0.99*Pi] -max deviation from cotf(x): 3.8147e-06 at 0.987876517942*Pi, max deviation from cephes_cot(x): -9.53674e-07 - ->> precision OK for the cot_ps <<- - -With atan_ps and atan2_ps you get pretty good precision, atan_ps max deviation is < 2e-7 and -atan2_ps max deviation is < 2.5e-7 -*/ - -/* Copyright (C) 2016 Tolga Mizrak - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - (this is the zlib license) -*/ - -#pragma once - -#ifndef _SSE_MATHFUN_EXTENSION_H_INCLUDED_ -#define _SSE_MATHFUN_EXTENSION_H_INCLUDED_ - -#ifndef USE_SSE2 -#error sse1 & mmx version not implemented -#endif - -#ifdef _MSC_VER -#pragma warning( push ) -/* warning C4838: conversion from 'double' to 'const float' requires a narrowing conversion */ -#pragma warning( disable : 4838 ) -/* warning C4305: 'initializing': truncation from 'double' to 'const float' */ -#pragma warning( disable : 4305 ) -#endif - -#include "sse_mathfun.h" - -_PS_CONST( 0, 0 ); -_PS_CONST( 2, 2 ); -_PI32_CONST( neg1, 1 ); - -_PS_CONST( tancof_p0, 9.38540185543E-3 ); -_PS_CONST( tancof_p1, 3.11992232697E-3 ); -_PS_CONST( tancof_p2, 2.44301354525E-2 ); -_PS_CONST( tancof_p3, 5.34112807005E-2 ); -_PS_CONST( tancof_p4, 1.33387994085E-1 ); -_PS_CONST( tancof_p5, 3.33331568548E-1 ); - -_PS_CONST( tancot_eps, 1.0e-4 ); - -v4sf tancot_ps( v4sf x, int cotFlag ) -{ - v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; - -#ifdef USE_SSE2 - v4si emm2; -#else -#endif - sign_bit = x; - /* take the absolute value */ - x = _mm_and_ps( x, *(v4sf*)_ps_inv_sign_mask ); - /* extract the sign bit (upper one) */ - sign_bit = _mm_and_ps( sign_bit, *(v4sf*)_ps_sign_mask ); - - /* scale by 4/Pi */ - y = _mm_mul_ps( x, *(v4sf*)_ps_cephes_FOPI ); - -#ifdef USE_SSE2 - /* store the integer part of y in mm0 */ - emm2 = _mm_cvttps_epi32( y ); - /* j=(j+1) & (~1) (see the cephes sources) */ - emm2 = _mm_add_epi32( emm2, *(v4si*)_pi32_1 ); - emm2 = _mm_and_si128( emm2, *(v4si*)_pi32_inv1 ); - y = _mm_cvtepi32_ps( emm2 ); - - emm2 = _mm_and_si128( emm2, *(v4si*)_pi32_2 ); - emm2 = _mm_cmpeq_epi32( emm2, _mm_setzero_si128() ); - - v4sf poly_mask = _mm_castsi128_ps( emm2 ); -#else -#endif - /* The magic pass: "Extended precision modular arithmetic" - x = ((x - y * DP1) - y * DP2) - y * DP3; */ - xmm1 = *(v4sf*)_ps_minus_cephes_DP1; - xmm2 = *(v4sf*)_ps_minus_cephes_DP2; - xmm3 = *(v4sf*)_ps_minus_cephes_DP3; - xmm1 = _mm_mul_ps( y, xmm1 ); - xmm2 = _mm_mul_ps( y, xmm2 ); - xmm3 = _mm_mul_ps( y, xmm3 ); - v4sf z = _mm_add_ps( x, xmm1 ); - z = _mm_add_ps( z, xmm2 ); - z = _mm_add_ps( z, xmm3 ); - - v4sf zz = _mm_mul_ps( z, z ); - - y = *(v4sf*)_ps_tancof_p0; - y = _mm_mul_ps( y, zz ); - y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p1 ); - y = _mm_mul_ps( y, zz ); - y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p2 ); - y = _mm_mul_ps( y, zz ); - y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p3 ); - y = _mm_mul_ps( y, zz ); - y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p4 ); - y = _mm_mul_ps( y, zz ); - y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p5 ); - y = _mm_mul_ps( y, zz ); - y = _mm_mul_ps( y, z ); - y = _mm_add_ps( y, z ); - - v4sf y2; - if( cotFlag ) { - y2 = _mm_xor_ps( y, *(v4sf*)_ps_sign_mask ); - /* y = _mm_rcp_ps( y ); */ - /* using _mm_rcp_ps here loses on way too much precision, better to do a div */ - y = _mm_div_ps( *(v4sf*)_ps_1, y ); - } else { - /* y2 = _mm_rcp_ps( y ); */ - /* using _mm_rcp_ps here loses on way too much precision, better to do a div */ - y2 = _mm_div_ps( *(v4sf*)_ps_1, y ); - y2 = _mm_xor_ps( y2, *(v4sf*)_ps_sign_mask ); - } - - /* select the correct result from the two polynoms */ - xmm3 = poly_mask; - y = _mm_and_ps( xmm3, y ); - y2 = _mm_andnot_ps( xmm3, y2 ); - y = _mm_or_ps( y, y2 ); - - /* update the sign */ - y = _mm_xor_ps( y, sign_bit ); - - return y; -} - -v4sf tan_ps( v4sf x ) { return tancot_ps( x, 0 ); } - -v4sf cot_ps( v4sf x ) { return tancot_ps( x, 1 ); } - -_PS_CONST( atanrange_hi, 2.414213562373095 ); -_PS_CONST( atanrange_lo, 0.4142135623730950 ); -const float PIF = 3.141592653589793238; -const float PIO2F = 1.5707963267948966192; -_PS_CONST( cephes_PIF, 3.141592653589793238 ); -_PS_CONST( cephes_PIO2F, 1.5707963267948966192 ); -_PS_CONST( cephes_PIO4F, 0.7853981633974483096 ); - -_PS_CONST( atancof_p0, 8.05374449538e-2 ); -_PS_CONST( atancof_p1, 1.38776856032E-1 ); -_PS_CONST( atancof_p2, 1.99777106478E-1 ); -_PS_CONST( atancof_p3, 3.33329491539E-1 ); - -v4sf atan_ps( v4sf x ) -{ - v4sf sign_bit, y; - - sign_bit = x; - /* take the absolute value */ - x = _mm_and_ps( x, *(v4sf*)_ps_inv_sign_mask ); - /* extract the sign bit (upper one) */ - sign_bit = _mm_and_ps( sign_bit, *(v4sf*)_ps_sign_mask ); - - /* range reduction, init x and y depending on range */ -#ifdef USE_SSE2 - /* x > 2.414213562373095 */ - v4sf cmp0 = _mm_cmpgt_ps( x, *(v4sf*)_ps_atanrange_hi ); - /* x > 0.4142135623730950 */ - v4sf cmp1 = _mm_cmpgt_ps( x, *(v4sf*)_ps_atanrange_lo ); - - /* x > 0.4142135623730950 && !( x > 2.414213562373095 ) */ - v4sf cmp2 = _mm_andnot_ps( cmp0, cmp1 ); - - /* -( 1.0/x ) */ - v4sf y0 = _mm_and_ps( cmp0, *(v4sf*)_ps_cephes_PIO2F ); - v4sf x0 = _mm_div_ps( *(v4sf*)_ps_1, x ); - x0 = _mm_xor_ps( x0, *(v4sf*)_ps_sign_mask ); - - v4sf y1 = _mm_and_ps( cmp2, *(v4sf*)_ps_cephes_PIO4F ); - /* (x-1.0)/(x+1.0) */ - v4sf x1_o = _mm_sub_ps( x, *(v4sf*)_ps_1 ); - v4sf x1_u = _mm_add_ps( x, *(v4sf*)_ps_1 ); - v4sf x1 = _mm_div_ps( x1_o, x1_u ); - - v4sf x2 = _mm_and_ps( cmp2, x1 ); - x0 = _mm_and_ps( cmp0, x0 ); - x2 = _mm_or_ps( x2, x0 ); - cmp1 = _mm_or_ps( cmp0, cmp2 ); - x2 = _mm_and_ps( cmp1, x2 ); - x = _mm_andnot_ps( cmp1, x ); - x = _mm_or_ps( x2, x ); - - y = _mm_or_ps( y0, y1 ); -#else -#error sse1 & mmx version not implemented -#endif - - v4sf zz = _mm_mul_ps( x, x ); - v4sf acc = *(v4sf*)_ps_atancof_p0; - acc = _mm_mul_ps( acc, zz ); - acc = _mm_sub_ps( acc, *(v4sf*)_ps_atancof_p1 ); - acc = _mm_mul_ps( acc, zz ); - acc = _mm_add_ps( acc, *(v4sf*)_ps_atancof_p2 ); - acc = _mm_mul_ps( acc, zz ); - acc = _mm_sub_ps( acc, *(v4sf*)_ps_atancof_p3 ); - acc = _mm_mul_ps( acc, zz ); - acc = _mm_mul_ps( acc, x ); - acc = _mm_add_ps( acc, x ); - y = _mm_add_ps( y, acc ); - - /* update the sign */ - y = _mm_xor_ps( y, sign_bit ); - - return y; -} - -v4sf atan2_ps( v4sf y, v4sf x ) -{ - v4sf x_eq_0 = _mm_cmpeq_ps( x, *(v4sf*)_ps_0 ); - v4sf x_gt_0 = _mm_cmpgt_ps( x, *(v4sf*)_ps_0 ); - v4sf x_le_0 = _mm_cmple_ps( x, *(v4sf*)_ps_0 ); - v4sf y_eq_0 = _mm_cmpeq_ps( y, *(v4sf*)_ps_0 ); - v4sf x_lt_0 = _mm_cmplt_ps( x, *(v4sf*)_ps_0 ); - v4sf y_lt_0 = _mm_cmplt_ps( y, *(v4sf*)_ps_0 ); - - v4sf zero_mask = _mm_and_ps( x_eq_0, y_eq_0 ); - v4sf zero_mask_other_case = _mm_and_ps( y_eq_0, x_gt_0 ); - zero_mask = _mm_or_ps( zero_mask, zero_mask_other_case ); - - v4sf pio2_mask = _mm_andnot_ps( y_eq_0, x_eq_0 ); - v4sf pio2_mask_sign = _mm_and_ps( y_lt_0, *(v4sf*)_ps_sign_mask ); - v4sf pio2_result = *(v4sf*)_ps_cephes_PIO2F; - pio2_result = _mm_xor_ps( pio2_result, pio2_mask_sign ); - pio2_result = _mm_and_ps( pio2_mask, pio2_result ); - - v4sf pi_mask = _mm_and_ps( y_eq_0, x_le_0 ); - v4sf pi = *(v4sf*)_ps_cephes_PIF; - v4sf pi_result = _mm_and_ps( pi_mask, pi ); - - v4sf swap_sign_mask_offset = _mm_and_ps( x_lt_0, y_lt_0 ); - swap_sign_mask_offset = _mm_and_ps( swap_sign_mask_offset, *(v4sf*)_ps_sign_mask ); - - v4sf offset0 = _mm_setzero_ps(); - v4sf offset1 = *(v4sf*)_ps_cephes_PIF; - offset1 = _mm_xor_ps( offset1, swap_sign_mask_offset ); - - v4sf offset = _mm_andnot_ps( x_lt_0, offset0 ); - offset = _mm_and_ps( x_lt_0, offset1 ); - - v4sf arg = _mm_div_ps( y, x ); - v4sf atan_result = atan_ps( arg ); - atan_result = _mm_add_ps( atan_result, offset ); - - /* select between zero_result, pio2_result and atan_result */ - - v4sf result = _mm_andnot_ps( zero_mask, pio2_result ); - atan_result = _mm_andnot_ps( pio2_mask, atan_result ); - atan_result = _mm_andnot_ps( pio2_mask, atan_result); - result = _mm_or_ps( result, atan_result ); - result = _mm_or_ps( result, pi_result ); - - return result; -} - -/* for convenience of calling simd sqrt */ -float sqrt_ps( float x ) -{ - v4sf sse_value = _mm_set_ps1( x ); - sse_value = _mm_sqrt_ps( sse_value ); - return _mm_cvtss_f32( sse_value ); -} -float rsqrt_ps( float x ) -{ - v4sf sse_value = _mm_set_ps1( x ); - sse_value = _mm_rsqrt_ps( sse_value ); - return _mm_cvtss_f32( sse_value ); -} - -/* atan2 implementation using atan, used as a reference to implement atan2_ps */ -float atan2_ref( float y, float x ) -{ - if( x == 0.0f ) { - if( y == 0.0f ) { - return 0.0f; - } - float result = _ps_cephes_PIO2F[0]; - if( y < 0.0f ) { - result = -result; - } - return result; - } - - if( y == 0.0f ) { - if( x > 0.0f ) { - return 0.0f; - } - return PIF; - } - - float offset = 0; - if( x < 0.0f ) { - offset = PIF; - if( y < 0.0f ) { - offset = -offset; - } - } - - v4sf val = _mm_set_ps1( y / x ); - val = atan_ps( val ); - return offset + _mm_cvtss_f32( val ); -} - -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - -#endif diff --git a/src/gs_libs/gs_types.cpp b/src/gs_libs/gs_types.cpp index 3f444fa..1b59488 100644 --- a/src/gs_libs/gs_types.cpp +++ b/src/gs_libs/gs_types.cpp @@ -2424,12 +2424,37 @@ CreateAllocator_(allocator_allocate* Alloc, allocator_free* Free) } #define CreateAllocator(a, f) CreateAllocator_((allocator_allocate*)(a), (allocator_free*)(f)) +internal void +AllocatorDebug_PushAlloc(gs_allocator_debug* Debug, u64 Size, char* Location) +{ + // NOTE(pjs): I don't want this debug procedure to be the reason the + // application crashes. + if (Debug->AllocationsCount < Debug->AllocationsCountMax) + { + gs_debug_allocation Allocation = {}; + + gs_const_string L = ConstString(Location); + + s64 LastSlash = FindLastFromSet(L, "\\/"); + if (LastSlash < 0) LastSlash = 0; + Allocation.Location = GetStringAfter(L, LastSlash); + Allocation.Size = Size; + + Debug->Allocations[Debug->AllocationsCount++] = Allocation; + } + Debug->TotalAllocSize += Size; +} + internal gs_data AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location) { // TODO(Peter): Memory Profiling with Location u64 SizeResult = 0; void* Memory = Allocator.Alloc(Size, &SizeResult); + if (Allocator.Debug) + { + AllocatorDebug_PushAlloc(Allocator.Debug, Size, Location); + } return CreateData((u8*)Memory, SizeResult); } internal void @@ -2439,6 +2464,13 @@ AllocatorFree_(gs_allocator Allocator, void* Base, u64 Size, char* Location) if (Base != 0 && Size != 0) { Allocator.Free(Base, Size); + if (Allocator.Debug) + { + // NOTE(pjs): There's no reason we should be going negative + // ie. Freeing more memory than we allocated + Assert(Allocator.Debug->TotalAllocSize >= Size); + Allocator.Debug->TotalAllocSize -= Size; + } } } @@ -2526,30 +2558,37 @@ FreeCursorListEntry(gs_allocator Allocator, gs_memory_cursor_list* CursorEntry) } internal gs_memory_arena -CreateMemoryArena_(arena_type ArenaType, gs_allocator Allocator, u64 ChunkSize, u64 Alignment, gs_memory_arena* ParentArena) +CreateMemoryArena_(arena_type ArenaType, gs_allocator Allocator, u64 ChunkSize, u64 Alignment, gs_memory_arena* ParentArena, char* Name) { // we only want a parent arena if the type is Arena_SubArena Assert(((ArenaType == Arena_BaseArena) && (ParentArena == 0)) || ((ArenaType == Arena_SubArena) && (ParentArena != 0))); gs_memory_arena Arena = {}; + Arena.ArenaName = Name; Arena.Type = ArenaType; Arena.Allocator = Allocator; Arena.Parent = ParentArena; + +#if MEMORY_CURSOR_STATIC_ARRAY + Arena.CursorsCountMax = 4096; + Arena.Cursors = AllocatorAllocArray(Allocator, gs_memory_cursor_list, Arena.CursorsCountMax); +#endif + Arena.MemoryChunkSize = ChunkSize; Arena.MemoryAlignment = Alignment; return Arena; } internal gs_memory_arena -CreateMemoryArena(gs_allocator Allocator, u64 ChunkSize = KB(32), u64 Alignment = Bytes(8)) +CreateMemoryArena(gs_allocator Allocator, char* Name, u64 ChunkSize = KB(32), u64 Alignment = Bytes(8)) { - return CreateMemoryArena_(Arena_BaseArena, Allocator, ChunkSize, Alignment, 0); + return CreateMemoryArena_(Arena_BaseArena, Allocator, ChunkSize, Alignment, 0, Name); } internal gs_memory_arena -CreateMemorySubArena(gs_memory_arena* Parent, u64 ChunkSize = KB(32), u64 Alignment = Bytes(8)) +CreateMemorySubArena(gs_memory_arena* Parent, char* Name, u64 ChunkSize = KB(32), u64 Alignment = Bytes(8)) { - return CreateMemoryArena_(Arena_SubArena, Parent->Allocator, ChunkSize, Alignment, Parent); + return CreateMemoryArena_(Arena_SubArena, Parent->Allocator, ChunkSize, Alignment, Parent, Name); } internal gs_data PushSize_(gs_memory_arena* Arena, u64 Size, char* Location); @@ -2557,6 +2596,7 @@ internal gs_data PushSize_(gs_memory_arena* Arena, u64 Size, char* Location); internal void FreeCursorList(gs_memory_cursor_list* List, gs_allocator Allocator) { +#if !MEMORY_CURSOR_STATIC_ARRAY gs_memory_cursor_list* CursorAt = List; while (CursorAt != 0) { @@ -2564,13 +2604,18 @@ FreeCursorList(gs_memory_cursor_list* List, gs_allocator Allocator) FreeCursorListEntry(Allocator, CursorAt); CursorAt = Prev; } +#endif } internal gs_memory_cursor_list* MemoryArenaNewCursor(gs_memory_arena* Arena, u64 MinSize, char* Location) { +#if MEMORY_CURSOR_STATIC_ARRAY + u64 AllocSize = Max(MinSize, Arena->MemoryChunkSize); +#else // Allocate enough spcae for the minimum size needed + sizeo for the cursor list u64 AllocSize = Max(MinSize, Arena->MemoryChunkSize) + sizeof(gs_memory_cursor_list); +#endif gs_data Data = {0}; switch (Arena->Type) @@ -2588,6 +2633,11 @@ MemoryArenaNewCursor(gs_memory_arena* Arena, u64 MinSize, char* Location) InvalidDefaultCase; } +#if MEMORY_CURSOR_STATIC_ARRAY + Assert(Arena->CursorsCount < Arena->CursorsCountMax); + gs_memory_cursor_list* Result = Arena->Cursors + Arena->CursorsCount++; + Result->Cursor = CreateMemoryCursor(Data.Memory, Data.Size); +#else // Fit the memory cursor into the region allocated Assert(MinSize + sizeof(gs_memory_cursor_list) <= Data.Size); gs_memory_cursor_list* Result = (gs_memory_cursor_list*)Data.Memory; @@ -2599,9 +2649,14 @@ MemoryArenaNewCursor(gs_memory_arena* Arena, u64 MinSize, char* Location) Result->Next = 0; if (Arena->CursorList != 0) { + if (Arena->CursorList->Next != 0) + { + Result->Next = Arena->CursorList->Next; + } Arena->CursorList->Next = Result; } Arena->CursorList = Result; +#endif return Result; } @@ -2611,6 +2666,27 @@ PushSize_(gs_memory_arena* Arena, u64 Size, char* Location) gs_data Result = {0}; if (Size > 0) { +#if MEMORY_CURSOR_STATIC_ARRAY + gs_memory_cursor_list* CursorEntry = 0; + for (u64 i = 0; + i < Arena->CursorsCount; + i++) + { + gs_memory_cursor_list* At = Arena->Cursors + i; + if (CursorHasRoom(At->Cursor, Size)) + { + CursorEntry = At; + break; + } + } + if (!CursorEntry) + { + CursorEntry = MemoryArenaNewCursor(Arena, Size, Location); + } + Assert(CursorEntry); + Assert(CursorHasRoom(CursorEntry->Cursor, Size)); +#else + gs_memory_cursor_list* CursorEntry = Arena->CursorList; if (CursorEntry == 0) { @@ -2627,6 +2703,7 @@ PushSize_(gs_memory_arena* Arena, u64 Size, char* Location) CursorEntry = MemoryArenaNewCursor(Arena, Size, Location); } } +#endif Assert(CursorEntry != 0); Result = PushSizeOnCursor_(&CursorEntry->Cursor, Size, Location); Assert(Result.Memory != 0); @@ -2651,44 +2728,19 @@ PushSize_(gs_memory_arena* Arena, u64 Size, char* Location) return Result; } -internal void -PopSize(gs_memory_arena* Arena, u64 Size) -{ - gs_allocator Allocator = Arena->Allocator; - gs_memory_cursor_list* CursorEntry = Arena->CursorList; - for (gs_memory_cursor_list* Prev = 0; - CursorEntry != 0 && Size != 0; - CursorEntry = Prev) - { - Prev = CursorEntry->Prev; - if (Size >= CursorEntry->Cursor.Position) - { - Size -= CursorEntry->Cursor.Position; - FreeCursorListEntry(Allocator, CursorEntry); - } - else - { - PopSizeOnCursor(&CursorEntry->Cursor, Size); - break; - } - } - Arena->CursorList = CursorEntry; -} internal void FreeMemoryArena(gs_memory_arena* Arena) { - gs_allocator Allocator = Arena->Allocator; - gs_memory_cursor_list* CursorEntry = Arena->CursorList; - for (gs_memory_cursor_list* Prev = 0; - CursorEntry != 0; - CursorEntry = Prev) +#if MEMORY_CURSOR_STATIC_ARRAY + for (u32 i = 0; i < Arena->CursorsCount; i++) { - Prev = CursorEntry->Prev; - if (CursorEntry != 0) - { - FreeCursorListEntry(Allocator, CursorEntry); - } + gs_memory_cursor_list E = Arena->Cursors[i]; + AllocatorFree(Arena->Allocator, E.Cursor.Data.Memory, E.Cursor.Data.Size); } + AllocatorFreeArray(Arena->Allocator, Arena->Cursors, gs_memory_cursor_list, Arena->CursorsCountMax); +#else + FreeCursorList(Arena->CursorList, Arena->Allocator); +#endif } #define PushSizeToData(arena, size) PushSize_((arena), (size), FileNameAndLineNumberString) @@ -2726,6 +2778,12 @@ PushStringCopy(gs_memory_arena* Arena, gs_const_string String) internal void ClearArena(gs_memory_arena* Arena) { +#if MEMORY_CURSOR_STATIC_ARRAY + for (u32 i = 0; i < Arena->CursorsCount; i++) + { + Arena->Cursors[i].Cursor.Position = 0; + } +#else gs_memory_cursor_list* First = 0; for (gs_memory_cursor_list* CursorEntry = Arena->CursorList; CursorEntry != 0; @@ -2735,12 +2793,13 @@ ClearArena(gs_memory_arena* Arena) CursorEntry->Cursor.Position = 0; } Arena->CursorList = First; +#endif } internal void FreeArena(gs_memory_arena* Arena) { - FreeCursorList(Arena->CursorList, Arena->Allocator); + FreeMemoryArena(Arena); } /////////////////////////// @@ -2789,14 +2848,14 @@ CreateDynarrayWithStorage(gs_memory_arena Storage, u32 ElementSize, u32 Elements internal gs_dynarray CreateDynarray_(gs_allocator Allocator, u32 ElementSize, u32 ElementsPerBuffer) { - gs_memory_arena Storage = CreateMemoryArena(Allocator, ElementSize * ElementsPerBuffer); + gs_memory_arena Storage = CreateMemoryArena(Allocator, "Dynarray Arena", ElementSize * ElementsPerBuffer); return CreateDynarrayWithStorage(Storage, ElementSize, ElementsPerBuffer); }; internal gs_dynarray CreateDynarray_(gs_memory_arena* Arena, u32 ElementSize, u32 ElementsPerBuffer) { - gs_memory_arena Storage = CreateMemorySubArena(Arena, ElementSize * ElementsPerBuffer); + gs_memory_arena Storage = CreateMemorySubArena(Arena, "Dynarray Sub Arena", ElementSize * ElementsPerBuffer); return CreateDynarrayWithStorage(Storage, ElementSize, ElementsPerBuffer); }; diff --git a/src/gs_libs/gs_types.h b/src/gs_libs/gs_types.h index e6ab857..792f2de 100644 --- a/src/gs_libs/gs_types.h +++ b/src/gs_libs/gs_types.h @@ -247,7 +247,7 @@ enum { \ #define DontCompile ImAfraidICantDoThat #define LineNumberString Stringify(__LINE__) -#define FileNameAndLineNumberString_ __FILE__ ":" LineNumberString ":" +#define FileNameAndLineNumberString_ __FILE__ ":" LineNumberString ":" __FUNCTION__ #define FileNameAndLineNumberString (char*)FileNameAndLineNumberString_ // @@ -633,10 +633,27 @@ typedef ALLOCATOR_ALLOC(allocator_allocate); #define ALLOCATOR_FREE(name) void name(void* Ptr, u64 Size) typedef ALLOCATOR_FREE(allocator_free); +struct gs_debug_allocation +{ + gs_const_string Location; + u64 Size; +}; + +struct gs_allocator_debug +{ + u64 TotalAllocSize; + + u64 AllocationsCount; + u64 AllocationsCountMax; + gs_debug_allocation* Allocations; +}; + struct gs_allocator { allocator_allocate* Alloc; allocator_free* Free; + + gs_allocator_debug* Debug; }; struct gs_memory_cursor @@ -645,11 +662,26 @@ struct gs_memory_cursor u64 Position; }; +/* TODO(pjs): Setting MEMORY_CURSOR_STATIC_ARRAY will still compile, + However, it introduces a bug that I haven't fully diagnosed. +The problem seems to occur when trying to push to a cleared memory arena +Where the FirstCursor doesn't have enough room for the allocation, but +also FirstCursor->Next points to a valid cursor. The new cursor is put +in the middle however we seem to continually keep allocating new +cursors forever and losing old ones. +The problem in Lumenarium is found in the OutputData structure + +Leaving this in a simplified state for now +*/ +#define MEMORY_CURSOR_STATIC_ARRAY 1 + struct gs_memory_cursor_list { gs_memory_cursor Cursor; +#if !MEMORY_CURSOR_STATIC_ARRAY gs_memory_cursor_list* Next; gs_memory_cursor_list* Prev; +#endif }; enum arena_type @@ -664,9 +696,18 @@ struct gs_memory_arena gs_allocator Allocator; gs_memory_arena* Parent; +#if MEMORY_CURSOR_STATIC_ARRAY + gs_memory_cursor_list* Cursors; + u64 CursorsCount; + u64 CursorsCountMax; +#else gs_memory_cursor_list* CursorList; +#endif + u64 MemoryChunkSize; u64 MemoryAlignment; + + char* ArenaName; }; struct gs_memory_arena_array diff --git a/src/app/interface_test.cpp b/src/tests/interface_test.cpp similarity index 100% rename from src/app/interface_test.cpp rename to src/tests/interface_test.cpp diff --git a/src/tests/sanity_tests.cpp b/src/tests/sanity_tests.cpp index 3d37c1a..437fc4d 100644 --- a/src/tests/sanity_tests.cpp +++ b/src/tests/sanity_tests.cpp @@ -31,7 +31,7 @@ bool PathTest (char* In, char* Out) { int main (int ArgCount, char** Args) { - Scratch = CreateMemoryArena(CreateAllocator(Alloc, Free)); + Scratch = CreateMemoryArena(CreateAllocator(Alloc, Free), "Scratch"); Test("gs_string") { diff --git a/src/app/test_patterns.h b/src/tests/test_patterns.h similarity index 100% rename from src/app/test_patterns.h rename to src/tests/test_patterns.h