diff --git a/README.md b/README.md index 46e3eee..35225ed 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,14 @@ Building Lumenarium requires having MSVC installed (sorry, Windows only for now! 2. Run the appropriate build batch file - for Windows: use `build\build_app_msvc_win32_debug.bat` - other platforms coming soon +3. Build scripts will output executables into the app_run_tree directory, by platform ## Run Lumenarium Windows - Debug -1. Just run `win32_msvc\debug\win32_foldhaus.exe` +1. Run `app_run_tree\win32_msvc\debug\win32_foldhaus.exe` + +If you want to run in headless mode: +1. Run `app_run_tree\win32_msvc\debug\win32_foldhaus.exe -headless` ## Debug Lumenarium ### Windows diff --git a/compile.bat b/bin/compile.bat similarity index 100% rename from compile.bat rename to bin/compile.bat diff --git a/debug.bat b/bin/debug.bat similarity index 100% rename from debug.bat rename to bin/debug.bat diff --git a/run.bat b/bin/run.bat similarity index 100% rename from run.bat rename to bin/run.bat diff --git a/build/build_app_msvc_win32_debug.bat b/build/build_app_msvc_win32_debug.bat index eec2df0..7e14230 100644 --- a/build/build_app_msvc_win32_debug.bat +++ b/build/build_app_msvc_win32_debug.bat @@ -6,7 +6,7 @@ SET MyPath=%MyPath:~0,-1% call %MyPath%\_prebuild_win32.bat app debug msvc call %MyPath%\setup_cl.bat -SET CommonCompilerFlags=-nologo -DDEBUG=1 -DPLATFORM_WINDOWS -FC -WX -W4 -Z7 -Oi -GR- -EHsc -EHa- -MTd -fp:fast -fp:except- -IC:\programs-dev\gs_libs\src +SET CommonCompilerFlags=-nologo -DDEBUG=0 -DPLATFORM_WINDOWS -FC -WX -W4 -Z7 -Oi -GR- -EHsc -EHa- -MTd -fp:fast -fp:except- -IC:\programs-dev\gs_libs\src SET CommonCompilerFlags=-wd4127 -wd4702 -wd4101 -wd4505 -wd4100 -wd4189 -wd4244 -wd4201 -wd4996 -I%CommonLibs% -O2 %CommonCompilerFlags% diff --git a/src/app/editor/foldhaus_editor_draw.h b/src/app/editor/foldhaus_editor_draw.h index f4a4edc..bad44a2 100644 --- a/src/app/editor/foldhaus_editor_draw.h +++ b/src/app/editor/foldhaus_editor_draw.h @@ -128,7 +128,6 @@ Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* Ren if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawString) && Widget.String.Length > 0) { - // TODO(pjs): add this color to the style v4 TextColor = BlackV4; Editor_DrawWidgetString(State, Context, RenderBuffer, Widget, ClippedFillBounds, TextColor, -1); } diff --git a/src/app/editor/foldhaus_operation_mode.h b/src/app/editor/foldhaus_operation_mode.h index 81e12fe..46d5830 100644 --- a/src/app/editor/foldhaus_operation_mode.h +++ b/src/app/editor/foldhaus_operation_mode.h @@ -40,11 +40,10 @@ OperationModeSystemInit(gs_memory_arena* Storage, gs_thread_context ThreadContex // TODO(Peter): Do we really need an arena? Can this just operate in constant memory footprint? Result.Arena.Allocator = ThreadContext.Allocator; - Result.ModeMemoryPagesFreeList.CountMax = 32; // TODO(Peter): Static number of modes that can be active simultaneously + Result.ModeMemoryPagesFreeList.CountMax = 8; Result.ModeMemoryPagesFreeList.Data = PushArray(Storage, gs_data, Result.ModeMemoryPagesFreeList.CountMax); for (u32 Page = 0; Page < Result.ModeMemoryPagesFreeList.CountMax; Page++) { - // TODO(Peter): 4k pages = page size on windows Result.ModeMemoryPagesFreeList.Data[Page] = PushSizeToData(Storage, KB(4)); } Result.ModeMemoryPagesFreeList.Count = Result.ModeMemoryPagesFreeList.CountMax; diff --git a/src/app/editor/panels/foldhaus_panel_profiler.h b/src/app/editor/panels/foldhaus_panel_profiler.h index 82e7d6f..b8684ee 100644 --- a/src/app/editor/panels/foldhaus_panel_profiler.h +++ b/src/app/editor/panels/foldhaus_panel_profiler.h @@ -163,15 +163,42 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, deb ui_EndList(Interface); } +struct mem_amt +{ + u64 OrigSize; + r64 Size; + char* Units; +}; + +internal mem_amt +GetMemAmt (u64 BytesCount) +{ + mem_amt Result = {}; + Result.OrigSize = BytesCount; + Result.Size = (r64)BytesCount; + Result.Units = "bytes"; + + u32 i = 0; + char* UnitList[] = { "kb", "mb", "gb", "tb" }; + while (Result.Size > 1024) { + Result.Size /= 1024.0; + Result.Units = UnitList[i++]; + } + + return Result; +} + 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; + mem_amt MemFootprint = GetMemAmt(Debug.TotalAllocSize); u64 AllocCount = Debug.AllocationsCount; - PrintF(&TempString, "Total Memory Size: %lld | Allocations: %lld", MemFootprint, AllocCount); + + + PrintF(&TempString, "Total Memory Size: %.2f %s | Allocations: %lld", MemFootprint.Size, MemFootprint.Units, AllocCount); ui_Label(Interface, TempString); ui_column_spec ColumnWidths[] = { @@ -194,7 +221,9 @@ RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state* PrintF(&TempString, "%S", A.Location); ui_Label(Interface, TempString); - PrintF(&TempString, "%lld bytes", A.Size); + mem_amt Amt = GetMemAmt(A.Size); + + PrintF(&TempString, "%.2f %s", Amt.Size, Amt.Units); ui_Label(Interface, TempString); } ui_EndRow(Interface); @@ -216,59 +245,65 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds); rect2 FrameListInner = RectInset(FrameListBounds, 4); - r32 SingleFrameStep = Rect2Width(FrameListInner) / DEBUG_FRAME_COUNT; - r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2); - - ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4); - if (MouseButtonHeldDown(Context.Mouse.LeftButtonState)) + s32 FramesToDisplay = DEBUG_FRAME_COUNT; + if (FramesToDisplay != 0) { - if (PointIsInRect(FrameListBounds, Context.Mouse.Pos)) + r32 SingleFrameStep = Rect2Width(FrameListInner) / FramesToDisplay; + r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2); + + ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4); + if (MouseButtonHeldDown(Context.Mouse.LeftButtonState)) { - v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos); - s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep); - if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT) + if (PointIsInRect(FrameListBounds, Context.Mouse.Pos)) { - GlobalDebugServices->RecordFrames = false; - GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex; + v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos); + s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep); + if (ClosestFrameIndex >= 0 && ClosestFrameIndex < FramesToDisplay) + { + GlobalDebugServices->RecordFrames = false; + GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex; + } } } + + rect2 FrameBounds = MakeRect2MinDim(FrameListInner.Min, v2{SingleFrameWidth, Rect2Height(FrameListInner)}); + for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++) + { + rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep); + s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F); + if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; } + v4 Color = FrameColors[Clamp(0, FramesAgo, 3)]; + ui_FillRect(&State->Interface, PositionedFrameBounds, Color); + } } - rect2 FrameBounds = MakeRect2MinDim(FrameListInner.Min, v2{SingleFrameWidth, Rect2Height(FrameListInner)}); - for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++) - { - rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep); - s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F); - if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; } - v4 Color = FrameColors[Clamp(0, FramesAgo, 3)]; - ui_FillRect(&State->Interface, PositionedFrameBounds, Color); - } - - debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices); - ui_widget* Layout = ui_PushLayout(&State->Interface, ProcListBounds, LayoutDirection_TopDown, MakeString("Profiler Layout")); - ui_BeginRow(&State->Interface, 4); + debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices); + if (VisibleFrame) { - s64 FrameStartCycles = VisibleFrame->FrameStartCycles; - s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles; - u32 CurrentDebugFrame = GlobalDebugServices->CurrentDebugFrame - 1; - PrintF(&String, "Frame %d", CurrentDebugFrame); - ui_Label(&State->Interface, String); - - PrintF(&String, "Total Cycles: %lld", FrameTotalCycles); - ui_Label(&State->Interface, String); - - // NOTE(NAME): Skipping a space for aesthetic reasons, not functional, and could - // be removed, or used for something else - ui_ReserveBounds(&State->Interface, Layout, true); - - if (ui_Button(&State->Interface, MakeString("Resume Recording"))) + ui_BeginRow(&State->Interface, 4); { - GlobalDebugServices->RecordFrames = true; + s64 FrameStartCycles = VisibleFrame->FrameStartCycles; + s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles; + u32 CurrentDebugFrame = GlobalDebugServices->CurrentDebugFrame - 1; + PrintF(&String, "Frame %d", CurrentDebugFrame); + ui_Label(&State->Interface, String); + + PrintF(&String, "Total Cycles: %lld", FrameTotalCycles); + ui_Label(&State->Interface, String); + + // NOTE(NAME): Skipping a space for aesthetic reasons, not functional, and could + // be removed, or used for something else + ui_ReserveBounds(&State->Interface, Layout, true); + + if (ui_Button(&State->Interface, MakeString("Resume Recording"))) + { + GlobalDebugServices->RecordFrames = true; + } } + ui_EndRow(&State->Interface); } - ui_EndRow(&State->Interface); ui_BeginRow(&State->Interface, 8); { @@ -291,12 +326,18 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend { case DebugUI_Profiler: { - RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory); + if (VisibleFrame) + { + RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory); + } }break; case DebugUI_ScopeList: { - RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory); + if (VisibleFrame) + { + RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory); + } }break; case DebugUI_MemoryView: diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h index 2385238..313ee68 100644 --- a/src/app/engine/animation/foldhaus_animation.h +++ b/src/app/engine/animation/foldhaus_animation.h @@ -74,8 +74,6 @@ struct animation gs_string Name; anim_layer_array Layers; - // TODO(pjs): Pretty sure Blocks_ should be obsolete and - // Layers should contain their own blocks animation_block_array Blocks_; frame_range PlayableRange; @@ -169,6 +167,7 @@ struct animation_system // panel animation_fade_group ActiveFadeGroup; + r32 SecondsOnCurrentFrame; s32 CurrentFrame; s32 LastUpdatedFrame; r32 SecondsPerFrame; @@ -762,13 +761,28 @@ AnimationSystem_Update(animation_system* System, r32 DeltaTime) animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System); if (ActiveAnim) { - // TODO(Peter): Revisit this. This implies that the framerate of the animation system - // is tied to the framerate of the simulation. That seems correct to me, but I'm not sure - System->CurrentFrame += 1; + System->SecondsOnCurrentFrame += DeltaTime; + while (System->SecondsOnCurrentFrame > System->SecondsPerFrame) + { + System->CurrentFrame += 1; + System->SecondsOnCurrentFrame -= System->SecondsPerFrame; + } // Loop back to the beginning if (System->CurrentFrame > ActiveAnim->PlayableRange.Max) { + // NOTE(PS): There's no long term reason why this needs to be true + // but I don't want to implement dealing with PlayableRanges that + // don't start at zero right now becuse there's literally no reason + // I can think of where that's useful. + Assert(ActiveAnim->PlayableRange.Min == 0); + + s32 FramesPastEnd = System->CurrentFrame; + while (FramesPastEnd > ActiveAnim->PlayableRange.Max) + { + FramesPastEnd -= ActiveAnim->PlayableRange.Max; + } + switch (System->RepeatMode) { case AnimationRepeat_Single: diff --git a/src/app/foldhaus_app.cpp b/src/app/foldhaus_app.cpp index 0712c40..e71f40b 100644 --- a/src/app/foldhaus_app.cpp +++ b/src/app/foldhaus_app.cpp @@ -81,8 +81,6 @@ INITIALIZE_APPLICATION(InitializeApplication) ReloadStaticData(*Context, GlobalDebugServices, true); US_CustomInit(&State->UserSpaceDesc, State, *Context); - GlobalDebugServices->Interface.RenderSculpture = true; - if (!Context->Headless) { // NOTE(pjs): This just sets up the default panel layout diff --git a/src/app/foldhaus_debug.h b/src/app/foldhaus_debug.h index c6b7133..8c99d6e 100644 --- a/src/app/foldhaus_debug.h +++ b/src/app/foldhaus_debug.h @@ -75,11 +75,6 @@ enum debug_ui_view struct debug_interface { - b32 ShowCameraMouse; - b32 ShowTrackedScopes; - b32 RenderSculpture; - b32 SendSACNData; - s32 FrameView; }; @@ -105,34 +100,39 @@ struct debug_histogram_entry u32 Total_CallCount; }; -#define DEBUG_FRAME_COUNT 128 +#if DEBUG +# define DEBUG_FRAME_COUNT 128 +#else +# define DEBUG_FRAME_COUNT 0 +#endif + struct debug_services { s64 PerformanceCountFrequency; b32 RecordFrames; s32 CurrentDebugFrame; - debug_frame Frames[DEBUG_FRAME_COUNT]; + debug_frame* Frames; debug_interface Interface; + gs_thread_context Ctx; + debug_get_thread_id* GetThreadId; debug_timing_proc* GetWallClock; - debug_alloc* Alloc; - debug_realloc* Realloc; }; internal void InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32 ScopeCallsMax, debug_services* Services) { Frame->ScopeNamesMax = NameHashMax; - Frame->ScopeNamesHash = (scope_name*)Services->Alloc(sizeof(scope_name), NameHashMax); + Frame->ScopeNamesHash = AllocatorAllocArray(Services->Ctx.Allocator, scope_name, NameHashMax); // NOTE(Peter): We use the same size as scope names because we're only storing a single instance // per scope. If ScopeNamesMax can't hold all the scopes, this will never get filled and // we should assert and recompile with a resized NameHashMax Frame->CollatedScopesMax = NameHashMax; - Frame->CollatedScopes = (collated_scope_record*)Services->Alloc(sizeof(collated_scope_record), NameHashMax); + Frame->CollatedScopes = AllocatorAllocArray(Services->Ctx.Allocator, collated_scope_record, NameHashMax); for (s32 i = 0; i < Frame->ScopeNamesMax; i++) { @@ -141,14 +141,13 @@ InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32 } Frame->ThreadCount = ThreadCount; - Frame->ThreadCalls = (debug_scope_record_list*)Services->Alloc(sizeof(debug_scope_record_list), - ThreadCount); + Frame->ThreadCalls = AllocatorAllocArray(Services->Ctx.Allocator, debug_scope_record_list, ThreadCount); for (s32 i = 0; i < ThreadCount; i++) { Frame->ThreadCalls[i].Max = ScopeCallsMax; Frame->ThreadCalls[i].Count = 0; - Frame->ThreadCalls[i].Calls = (scope_record*)Services->Alloc(sizeof(scope_record), ScopeCallsMax); + Frame->ThreadCalls[i].Calls = AllocatorAllocArray(Services->Ctx.Allocator, scope_record, ScopeCallsMax); Frame->ThreadCalls[i].CurrentScopeCallDepth = 0; Frame->ThreadCalls[i].ThreadId = 0; } @@ -178,16 +177,34 @@ StartDebugFrame(debug_frame* Frame, debug_services* Services) } internal void -InitDebugServices (debug_services* Services, - s64 PerformanceCountFrequency, - debug_alloc* Alloc, - debug_realloc* Realloc, - debug_timing_proc* GetWallClock, - debug_get_thread_id* GetThreadId, - s32 ThreadCount) +InitDebugServices_OffMode (debug_services* Services, + s64 PerformanceCountFrequency, + debug_timing_proc* GetWallClock, + debug_get_thread_id* GetThreadId, + gs_thread_context Ctx, + s32 ThreadCount) { - Services->Alloc = Alloc; - Services->Realloc = Realloc; + Services->Ctx = Ctx; + Services->GetWallClock = GetWallClock; + Services->GetThreadId = GetThreadId; + + Services->RecordFrames = false; + Services->Frames = 0; + + Services->CurrentDebugFrame = 0; + Services->PerformanceCountFrequency = PerformanceCountFrequency; +} + + +internal void +InitDebugServices_DebugMode (debug_services* Services, + s64 PerformanceCountFrequency, + debug_timing_proc* GetWallClock, + debug_get_thread_id* GetThreadId, + gs_thread_context Ctx, + s32 ThreadCount) +{ + Services->Ctx = Ctx; Services->GetWallClock = GetWallClock; Services->GetThreadId = GetThreadId; @@ -196,19 +213,13 @@ InitDebugServices (debug_services* Services, Services->CurrentDebugFrame = 0; s32 NameHashMax = 4096; s32 ScopeCallsMax = 4096; + Services->Frames = AllocatorAllocArray(Ctx.Allocator, debug_frame, DEBUG_FRAME_COUNT); for (s32 i = 0; i < DEBUG_FRAME_COUNT; i++) { InitializeDebugFrame(&Services->Frames[i], NameHashMax, ThreadCount, ScopeCallsMax, Services); } - Services->Interface.RenderSculpture = true; - Services->PerformanceCountFrequency = PerformanceCountFrequency; - - Services->Interface.ShowCameraMouse = false; - Services->Interface.ShowTrackedScopes = false; - Services->Interface.RenderSculpture = true; - Services->Interface.SendSACNData = false; } internal debug_frame* @@ -221,6 +232,8 @@ GetCurrentDebugFrame (debug_services* Services) internal debug_frame* GetLastDebugFrame(debug_services* Services) { + if (!Services->Frames) return 0; + s32 Index = (Services->CurrentDebugFrame - 1); if (Index < 0) { Index += DEBUG_FRAME_COUNT; } debug_frame* Result = Services->Frames + Index; @@ -323,7 +336,11 @@ EndDebugFrame (debug_services* Services) } ClosingFrame->ScopeNamesCount = ScopeNamesCount; - Services->CurrentDebugFrame = (Services->CurrentDebugFrame + 1) % DEBUG_FRAME_COUNT; + s32 FramesCount = DEBUG_FRAME_COUNT; + if (FramesCount > 0) + { + Services->CurrentDebugFrame = (Services->CurrentDebugFrame + 1) % FramesCount; + } StartDebugFrame(&Services->Frames[Services->CurrentDebugFrame], Services); } @@ -388,10 +405,9 @@ PushScopeTimeOnFrame (debug_services* Services, s32 NameHash, u64 StartCycles, u if (ThreadList->Count >= ThreadList->Max) { - s32 CurrentSize = ThreadList->Max * sizeof(scope_record); s32 NewMax = (ThreadList->Max + DEBUG_FRAME_GROW_SIZE); - s32 NewSize = NewMax * sizeof(scope_record); - ThreadList->Calls = (scope_record*)Services->Realloc((u8*)ThreadList->Calls, CurrentSize, NewSize); + AllocatorFreeArray(Services->Ctx.Allocator, ThreadList->Calls, scope_record, ThreadList->Max); + ThreadList->Calls = AllocatorAllocArray(Services->Ctx.Allocator, scope_record, NewMax); ThreadList->Max = NewMax; } @@ -411,7 +427,7 @@ internal r32 DEBUGGetSecondsElapsed (s64 Start, s64 End, r32 PerformanceCountFre return Result; } -#ifdef DEBUG +#if DEBUG #define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices) #define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices) #else diff --git a/src/app/foldhaus_platform.h b/src/app/foldhaus_platform.h index 76eb968..d2d190b 100644 --- a/src/app/foldhaus_platform.h +++ b/src/app/foldhaus_platform.h @@ -202,8 +202,6 @@ typedef struct system_time s32 Second; } system_time; -#define STATUS_PACKET_FREQ_SECONDS 2 - struct context { gs_thread_context ThreadContext; diff --git a/src/app/foldhaus_renderer.cpp b/src/app/foldhaus_renderer.cpp index bfd6522..548acda 100644 --- a/src/app/foldhaus_renderer.cpp +++ b/src/app/foldhaus_renderer.cpp @@ -6,22 +6,22 @@ #ifndef FOLDHAUS_RENDERER_CPP internal render_command_buffer -AllocateRenderCommandBuffer (u8* Memory, s32 Size, renderer_realloc* Realloc) +AllocateRenderCommandBuffer (u8* Memory, s32 Size, gs_thread_context Ctx) { render_command_buffer Result = {}; Result.CommandMemory = Memory; Result.CommandMemorySize = Size; Result.CommandMemoryUsed = 0; - Result.Realloc = Realloc; + Result.Ctx = Ctx; return Result; } internal render_command_buffer AllocateRenderCommandBuffer(u32 MemorySize, gs_memory_arena* Arena, - renderer_realloc* Realloc) + gs_thread_context Ctx) { u8* Memory = PushSize(Arena, MemorySize); - return AllocateRenderCommandBuffer(Memory, MemorySize, Realloc); + return AllocateRenderCommandBuffer(Memory, MemorySize, Ctx); } internal void diff --git a/src/app/foldhaus_renderer.h b/src/app/foldhaus_renderer.h index 7e25346..0a264de 100644 --- a/src/app/foldhaus_renderer.h +++ b/src/app/foldhaus_renderer.h @@ -124,7 +124,6 @@ struct render_quad_3d struct render_texture { - // TODO(Peter): Is all this necessary? u8* Memory; s32 Handle; s32 Width; @@ -214,7 +213,7 @@ struct render_command_buffer s32 CommandMemoryUsed; s32 CommandMemorySize; - renderer_realloc* Realloc; + gs_thread_context Ctx; s32 ViewWidth; s32 ViewHeight; @@ -265,9 +264,9 @@ ResizeBufferIfNecessary(render_command_buffer* Buffer, s32 DataSize) s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE); s32 NewSize = Buffer->CommandMemorySize + AdditionSize; - Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory, - Buffer->CommandMemorySize, - NewSize); + + AllocatorFree(Buffer->Ctx.Allocator, Buffer->CommandMemory, Buffer->CommandMemorySize); + Buffer->CommandMemory = AllocatorAlloc(Buffer->Ctx.Allocator, NewSize).Memory; Buffer->CommandMemorySize = NewSize; } } diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index f8bc0cd..d284503 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -356,22 +356,6 @@ SetApplicationLinks (context* Context, win32_dll_refresh DLL, gs_work_queue* Wor } } -// TODO(Peter): :Redundant remove -internal u8* -DEBUGAlloc(s32 ElementSize, s32 ElementCount) -{ - return (u8*)Win32Alloc(ElementSize * ElementCount, 0); -} - -// TODO(Peter): :Redundant remove -internal u8* -Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize) -{ - u8* NewMemory = (u8*)Win32Alloc(NewSize, 0); - CopyMemoryTo(Buf, NewMemory, OldSize); - return NewMemory; -} - internal void Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt) { @@ -604,7 +588,7 @@ WinMain ( gs_allocator_debug AllocDebug = {}; AllocDebug.AllocationsCountMax = 4096; - AllocDebug.Allocations = (gs_debug_allocation*)Win32Alloc(sizeof(gs_debug_allocation) * AllocDebug.AllocationsCountMax, 0); + AllocDebug.Allocations = AllocatorAllocArray(ThreadContext.Allocator, gs_debug_allocation, AllocDebug.AllocationsCountMax); ThreadContext.Allocator.Debug = &AllocDebug; @@ -636,17 +620,25 @@ WinMain ( s64 PerformanceCountFrequency = GetPerformanceFrequency(); s64 LastFrameEnd = GetWallClock(); - r32 TargetSecondsPerFrame = 1 / 60.0f; + r32 TargetSecondsPerFrame = 1 / 30.0f; r32 LastFrameSecondsElapsed = 0.0f; GlobalDebugServices = PushStruct(&PlatformPermanent, debug_services); - InitDebugServices(GlobalDebugServices, - PerformanceCountFrequency, - DEBUGAlloc, - Win32Realloc, - GetWallClock, - Win32GetThreadId, - PLATFORM_THREAD_COUNT + 1); +#if DEBUG + InitDebugServices_DebugMode(GlobalDebugServices, + PerformanceCountFrequency, + GetWallClock, + Win32GetThreadId, + Context.ThreadContext, + PLATFORM_THREAD_COUNT + 1); +#else + InitDebugServices_OffMode(GlobalDebugServices, + PerformanceCountFrequency, + GetWallClock, + Win32GetThreadId, + Context.ThreadContext, + PLATFORM_THREAD_COUNT + 1); +#endif input_queue InputQueue = InputQueue_Create(&PlatformPermanent, 32); @@ -674,7 +666,11 @@ WinMain ( Win32SerialArray_Create(ThreadContext); - render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(MB(12), &PlatformPermanent, Win32Realloc); + render_command_buffer RenderBuffer = {}; + if (!Context.Headless) + { + RenderBuffer = AllocateRenderCommandBuffer(MB(12), &PlatformPermanent, ThreadContext); + } addressed_data_buffer_list OutputData = AddressedDataBufferList_Create(ThreadContext); @@ -690,6 +686,7 @@ WinMain ( { EndDebugFrame(GlobalDebugServices); } + DEBUG_TRACK_SCOPE(MainLoop); { diff --git a/src/app/platform_win32/win32_foldhaus_socket.h b/src/app/platform_win32/win32_foldhaus_socket.h index 2cb326a..b67107f 100644 --- a/src/app/platform_win32/win32_foldhaus_socket.h +++ b/src/app/platform_win32/win32_foldhaus_socket.h @@ -251,7 +251,6 @@ Win32SocketPeek(platform_socket_manager* Manager, platform_socket* Socket) } else { - // TODO(pjs): Error handling s32 Error = WSAGetLastError(); switch (Error) { diff --git a/src/app/platform_win32/win32_foldhaus_work_queue.h b/src/app/platform_win32/win32_foldhaus_work_queue.h index 8d18986..5f9ce27 100644 --- a/src/app/platform_win32/win32_foldhaus_work_queue.h +++ b/src/app/platform_win32/win32_foldhaus_work_queue.h @@ -63,7 +63,7 @@ Win32CreateThreadContext(gs_memory_arena* Transient = 0) PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue) { -#ifdef DEBUG +#if DEBUG // NOTE(Peter): Just prints out the names of all the pending jobs if we end up // overflowing the buffer if (Queue->JobsCount >= Queue->JobsMax) @@ -82,7 +82,7 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue) gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount; Job->WorkProc = WorkProc; Job->Data = Data; -#ifdef DEBUG +#if DEBUG Job->JobName = JobName; #endif @@ -184,7 +184,7 @@ CREATE_THREAD(Win32CreateThread) Thread->UserData = UserData; // TODO(pjs): ugh, allocation out in the middle of nowhere - HANDLE* ThreadHandle = (HANDLE*)Win32Alloc(sizeof(HANDLE), 0); + HANDLE* ThreadHandle = AllocatorAllocStruct(Ctx.Allocator, HANDLE); *ThreadHandle = CreateThread(0, 0, Win32ThreadProcWrapper, (void*)Thread, 0, 0); // TODO(pjs): Error checking on the created thread diff --git a/src/app/ss_blumen_lumen/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp index ee55776..d287917 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.cpp +++ b/src/app/ss_blumen_lumen/blumen_lumen.cpp @@ -149,7 +149,6 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) { if (SocketPeek(Data->SocketManager, ListenSocket)) { - // TODO(pjs): Make this a peek operation Msg = SocketRecieve(Data->SocketManager, ListenSocket, Ctx->Transient); if (Msg.Size > 0) { @@ -233,7 +232,7 @@ BlumenLumen_CustomInit(app_state* State, context Context) BLState->PatternSpeed = GlobalAnimSpeed; #if 1 - BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData); + BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData, Context.ThreadContext); #endif assembly* Flower0 = LoadAssembly(Flower0AssemblyPath, State, Context); @@ -276,10 +275,54 @@ BlumenLumen_CustomInit(app_state* State, context Context) return Result; } +internal void +BlumenLumen_UpdateLog(app_state* State, blumen_lumen_state* BLState, context Context) +{ + if (!BLState->ShouldUpdateLog) return; + + gs_string FileStr = PushString(State->Transient, 1024); + AppendPrintF(&FileStr, "Lumenarium Status\n\n"); + + animation* CurrAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem); + AppendPrintF(&FileStr, "Curr Animation: %S\n", CurrAnim->Name); + + char* Connected = BLState->MicListenJobData.IsConnected ? "Connected" : "Disconnected"; + AppendPrintF(&FileStr, "Connected to Python: %s\n", Connected); + + u8 MP0 = BLState->LastKnownMotorState.FlowerPositions[0]; + u8 MP1 = BLState->LastKnownMotorState.FlowerPositions[1]; + u8 MP2 = BLState->LastKnownMotorState.FlowerPositions[2]; + AppendPrintF(&FileStr, "Last Known Motor State: %d %d %d\n", MP0, MP1, MP2); + + char* PatternMode = 0; + switch (BLState->PatternMode) + { + case BlumenPattern_Standard: { PatternMode = "Standard"; } break; + case BlumenPattern_VoiceCommand: { PatternMode = "Voice Command"; } break; + } + AppendPrintF(&FileStr, "Pattern Mode: %s\n", PatternMode); + + phrase_hue LastHuePhrase = BLState->LastHuePhrase; + AppendPrintF(&FileStr, "Last Mic Phrase: %S\n", LastHuePhrase.Phrase); + + AppendPrintF(&FileStr, "Pattern Speed: %f\n", BLState->PatternSpeed); + + AppendPrintF(&FileStr, "Pattern Brightness: %f\n", BLState->BrightnessPercent); + + AppendPrintF(&FileStr, "Last Temp Received: %d\n", BLState->LastTemperatureReceived); + + gs_data LogMem = StringToData(FileStr); + if (!WriteEntireFile(Context.ThreadContext.FileHandler, ConstString("lumenarium_status.log"), LogMem)) + { + InvalidCodePath; + } +} + internal void BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) { blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; + BLState->ShouldUpdateLog = false; bool SendMotorCommand = false; blumen_packet MotorCommand = {}; @@ -314,7 +357,9 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState); BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current; + BLState->LastHuePhrase = NewHue; } + BLState->ShouldUpdateLog = true; }break; case PacketType_MotorState: @@ -340,14 +385,14 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) } BLState->LastKnownMotorState = Motor.Pos; - + BLState->ShouldUpdateLog = true; }break; case PacketType_Temperature: { temp_packet Temp = Packet.TempPacket; - if (Temp.Temperature > 0) + if (Temp.Temperature > MinHighTemperature) { BLState->BrightnessPercent = HighTemperatureBrightnessPercent; } @@ -355,8 +400,10 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) { BLState->BrightnessPercent = FullBrightnessPercent; } + BLState->LastTemperatureReceived = Temp.Temperature; DEBUG_ReceivedTemperature(Temp, Context->ThreadContext); + BLState->ShouldUpdateLog = true; }break; InvalidDefaultCase; @@ -392,6 +439,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup, NewAnim, VoiceCommandFadeDuration); + BLState->ShouldUpdateLog = true; } } @@ -517,7 +565,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) { system_time LastSendTime = BLState->LastStatusUpdateTime; r64 NanosSinceLastSend = ((r64)Context->SystemTime_Current.NanosSinceEpoch - (r64)LastSendTime.NanosSinceEpoch); - r64 SecondsSinceLastSend = NanosSinceLastSend / PowR32(10, 8); + r64 SecondsSinceLastSend = NanosSinceLastSend * NanosToSeconds; if (SecondsSinceLastSend >= STATUS_PACKET_FREQ_SECONDS) { BLState->LastStatusUpdateTime = Context->SystemTime_Current; @@ -538,8 +586,15 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) gs_data Msg = StructToData(&Packet, blumen_packet); MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); + + // there's no new information here, but by updating the log here, + // we're updating it at some infrequent but regular period that isnt + // every single frame + BLState->ShouldUpdateLog = true; } } + + BlumenLumen_UpdateLog(State, BLState, *Context); } US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI) diff --git a/src/app/ss_blumen_lumen/blumen_lumen.h b/src/app/ss_blumen_lumen/blumen_lumen.h index 6dd55ac..cc271d7 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.h +++ b/src/app/ss_blumen_lumen/blumen_lumen.h @@ -109,6 +109,9 @@ struct mic_listen_job_data blumen_network_msg_queue* IncomingMsgQueue; blumen_network_msg_queue* OutgoingMsgQueue; + + // Status + bool IsConnected; }; typedef struct time_range @@ -151,6 +154,7 @@ struct blumen_lumen_state // NOTE(pjs): Based on temperature data from weatherman // dim the leds. r32 BrightnessPercent; + s8 LastTemperatureReceived; system_time LastStatusUpdateTime; system_time LastSendTime; @@ -172,11 +176,15 @@ struct blumen_lumen_state phrase_hue_map PhraseHueMap; system_time TimeLastSetToVoiceMode; + phrase_hue LastHuePhrase; r32 PatternSpeed; + // Debug motor_packet DEBUG_PendingMotorPacket; bool DEBUG_IgnoreWeatherDimmingLeds; + + bool ShouldUpdateLog; }; #include "message_queue.cpp" diff --git a/src/app/ss_blumen_lumen/blumen_lumen_settings.h b/src/app/ss_blumen_lumen/blumen_lumen_settings.h index 97b6686..809106e 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen_settings.h +++ b/src/app/ss_blumen_lumen/blumen_lumen_settings.h @@ -111,8 +111,17 @@ r64 VoiceCommandSustainDuration = 30.0; // in seconds // to have been on the whole time. r64 TurnUpperLedsOffAfterMotorCloseCommandDelay = 5.0; // in seconds + // NOTE: Temperature & Time of Day Based Led Brightness Settings +// The temperature above which we dim the leds to +// HighTemperatureBrightnessPercent (below) +// +// NOTE: this is an 8bit signed integer so its range is +// -128 to 127, not that we should need either of those extremes for +// this, but just a note that you can't just put anything in here. +s8 MinHighTemperature = 0; + // The percent brightness we set leds to during high temperatures. // A value in the range 0:1 inclusive // This is multiplied by each pixels R, G, & B channels before being @@ -128,6 +137,12 @@ r32 FullBrightnessPercent = 1.0f; // A global modifier so Joerg can just slow all the patterns right down // XD +// This is a percent - so 1 is full speed, 0.1f is 1/10 full speed and +// 2 is 2x as fast. r32 GlobalAnimSpeed = 1.0f; +// How often should Lumenarium send its status to the python server? +// +#define STATUS_PACKET_FREQ_SECONDS 2 // in seconds + #endif //BLUMEN_LUMEN_SETTINGS_H diff --git a/src/gs_libs/gs_language.h b/src/gs_libs/gs_language.h index b95b246..3e31391 100644 --- a/src/gs_libs/gs_language.h +++ b/src/gs_libs/gs_language.h @@ -85,7 +85,7 @@ typedef double r64; #endif -#ifdef DEBUG +#if DEBUG static void DebugPrint(char* Format, ...); @@ -95,8 +95,8 @@ static void DebugPrint(char* Format, ...); if((expression)) \ { \ }else{ \ - volatile int* p = 0; \ - *p = 5; \ +volatile int* p = 0; \ +*p = 5; \ } #endif @@ -319,9 +319,9 @@ GSIntDivideRoundUpDef(s64); #define GSRemapDef(type) \ static type GSRemap(type Value, type OldMin, type OldMax, type NewMin, type NewMax) { \ - type Result = (Value - OldMin) / (OldMax - OldMin); \ - Result = (Result * (NewMax - NewMin)) + NewMin; \ - return Result; \ +type Result = (Value - OldMin) / (OldMax - OldMin); \ +Result = (Result * (NewMax - NewMin)) + NewMin; \ +return Result; \ } GSRemapDef(u8); GSRemapDef(u16); diff --git a/src/gs_libs/gs_memory_arena.h b/src/gs_libs/gs_memory_arena.h index 4fbeb3b..e4bad68 100644 --- a/src/gs_libs/gs_memory_arena.h +++ b/src/gs_libs/gs_memory_arena.h @@ -153,13 +153,13 @@ typedef unsigned int gs_mem_u32; typedef unsigned long long int gs_mem_u64; -#ifdef DEBUG +#if DEBUG #if !defined(GSMem_Assert) #define GSMem_Assert(expression) \ if((expression)) { \ }else{ \ - volatile int* p = 0; \ - *p = 5; \ +volatile int* p = 0; \ +*p = 5; \ } #endif diff --git a/src/gs_libs/gs_radix_sort.h b/src/gs_libs/gs_radix_sort.h index 8e62a27..cf4464d 100644 --- a/src/gs_libs/gs_radix_sort.h +++ b/src/gs_libs/gs_radix_sort.h @@ -1,12 +1,11 @@ /* gs_radix_sort.h - An implementation of radix sort for fixed size unsigned 32bit integer buffers -TODO */ #ifndef GS_RADIX_SORT_H -#ifdef DEBUG +#if DEBUG #if !defined(GSRad_Assert) #define GSRad_Assert(expression) \ if(!(expression)) { \ diff --git a/src/gs_libs/gs_types.cpp b/src/gs_libs/gs_types.cpp index 1098c92..28238c4 100644 --- a/src/gs_libs/gs_types.cpp +++ b/src/gs_libs/gs_types.cpp @@ -2474,7 +2474,6 @@ AllocatorDebug_PushAlloc(gs_allocator_debug* Debug, u64 Size, char* Location) 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) @@ -2486,7 +2485,6 @@ AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location) internal void AllocatorFree_(gs_allocator Allocator, void* Base, u64 Size, char* Location) { - // TODO(Peter): Memory Profiling with Location if (Base != 0 && Size != 0) { Allocator.Free(Base, Size); @@ -3498,7 +3496,7 @@ CreatePlatformThreadManager(platform_create_thread* CreateThreadProc, } internal platform_thread_handle -CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg) +CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg, gs_thread_context Ctx) { platform_thread_handle Result = {}; @@ -3513,7 +3511,7 @@ CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg) Assert(Result.Index != 0); Manager->ThreadsUsed[Result.Index] = true; - Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg); + Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg, Ctx); return Result; } @@ -3719,7 +3717,6 @@ CloseSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) } // NOTE(pjs): returns true if the socket is connected -// TODO(pjs): make this more descriptive? internal bool SocketQueryStatus(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle) { diff --git a/src/gs_libs/gs_types.h b/src/gs_libs/gs_types.h index 49513f0..7356fbb 100644 --- a/src/gs_libs/gs_types.h +++ b/src/gs_libs/gs_types.h @@ -140,8 +140,6 @@ global_const r64 EpsilonR64 = 1.11022302462515650e-16; global_const r64 NanosToSeconds = 1 / 10000000.0; global_const r64 SecondsToNanos = 10000000.0; -// TODO: va_start and va_arg replacements - internal r32 DegToRadR32(r32 Degrees) { @@ -1090,10 +1088,9 @@ typedef struct platform_thread u8* PlatformHandle; thread_proc_* Proc; u8* UserData; - // TODO(pjs): Some kind of platform thread handle } platform_thread; -#define CREATE_THREAD(name) bool name(platform_thread* Thread, thread_proc_* Proc, u8* UserData) +#define CREATE_THREAD(name) bool name(platform_thread* Thread, thread_proc_* Proc, u8* UserData, gs_thread_context Ctx) typedef CREATE_THREAD(platform_create_thread); #define KILL_THREAD(name) bool name(platform_thread* Thread) diff --git a/src/gs_libs/gs_win32.cpp b/src/gs_libs/gs_win32.cpp index b96ae2e..120bbd1 100644 --- a/src/gs_libs/gs_win32.cpp +++ b/src/gs_libs/gs_win32.cpp @@ -40,7 +40,7 @@ struct window struct handle_window_msg_result { b32 NeedsUpdate; -#ifdef DEBUG +#if DEBUG char MessageType[128]; #endif }; diff --git a/test_motor_header.h b/test_motor_header.h deleted file mode 100644 index 3a443b3..0000000 --- a/test_motor_header.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// File: test_motor_header.h -// Author: Peter Slattery -// Creation Date: 2021-01-14 -// -#ifndef TEST_MOTOR_HEADER_H - -struct -{ - u8 MotorOnePos; - u8 MotorTwoPos; - u8 MotorThreePos; -} typedef packet; - -static packet -UnpackPacket - -#define TEST_MOTOR_HEADER_H -#endif // TEST_MOTOR_HEADER_H \ No newline at end of file diff --git a/test_sound_interface_packet.h b/test_sound_interface_packet.h deleted file mode 100644 index a046c21..0000000 --- a/test_sound_interface_packet.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// File: test_sound_interface_packet.h -// Author: Peter Slattery -// Creation Date: 2021-01-14 -// -#ifndef TEST_SOUND_INTERFACE_PACKET_H - -enum selectable_patterns -{ -}; - -typedef struct -{ - u8 PrimaryColor[3]; - u8 SecondaryColor[3]; - u32 PatternIndex; // Set via selectable_patterns - u8 Speed; // -} sound_interface_packet; - -// expects V to be in the range -1:1 -u8 FloatToSpeed (float V) -{ - u8 Result = (u8)(((V + 1) / 2) * 255); - return Result; -} - - -#define TEST_SOUND_INTERFACE_PACKET_H -#endif // TEST_SOUND_INTERFACE_PACKET_H \ No newline at end of file