Cleaning up todos, documentation, blumen lumen status, etc.
This commit is contained in:
parent
18bef60ba1
commit
bafbcd966a
|
@ -7,10 +7,14 @@ Building Lumenarium requires having MSVC installed (sorry, Windows only for now!
|
||||||
2. Run the appropriate build batch file
|
2. Run the appropriate build batch file
|
||||||
- for Windows: use `build\build_app_msvc_win32_debug.bat`
|
- for Windows: use `build\build_app_msvc_win32_debug.bat`
|
||||||
- other platforms coming soon
|
- other platforms coming soon
|
||||||
|
3. Build scripts will output executables into the app_run_tree directory, by platform
|
||||||
|
|
||||||
## Run Lumenarium
|
## Run Lumenarium
|
||||||
Windows - Debug
|
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
|
## Debug Lumenarium
|
||||||
### Windows
|
### Windows
|
||||||
|
|
|
@ -6,7 +6,7 @@ SET MyPath=%MyPath:~0,-1%
|
||||||
call %MyPath%\_prebuild_win32.bat app debug msvc
|
call %MyPath%\_prebuild_win32.bat app debug msvc
|
||||||
call %MyPath%\setup_cl.bat
|
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%
|
SET CommonCompilerFlags=-wd4127 -wd4702 -wd4101 -wd4505 -wd4100 -wd4189 -wd4244 -wd4201 -wd4996 -I%CommonLibs% -O2 %CommonCompilerFlags%
|
||||||
|
|
||||||
|
|
|
@ -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)
|
if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawString) && Widget.String.Length > 0)
|
||||||
{
|
{
|
||||||
// TODO(pjs): add this color to the style
|
|
||||||
v4 TextColor = BlackV4;
|
v4 TextColor = BlackV4;
|
||||||
Editor_DrawWidgetString(State, Context, RenderBuffer, Widget, ClippedFillBounds, TextColor, -1);
|
Editor_DrawWidgetString(State, Context, RenderBuffer, Widget, ClippedFillBounds, TextColor, -1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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?
|
// TODO(Peter): Do we really need an arena? Can this just operate in constant memory footprint?
|
||||||
Result.Arena.Allocator = ThreadContext.Allocator;
|
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);
|
Result.ModeMemoryPagesFreeList.Data = PushArray(Storage, gs_data, Result.ModeMemoryPagesFreeList.CountMax);
|
||||||
for (u32 Page = 0; Page < Result.ModeMemoryPagesFreeList.CountMax; Page++)
|
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.Data[Page] = PushSizeToData(Storage, KB(4));
|
||||||
}
|
}
|
||||||
Result.ModeMemoryPagesFreeList.Count = Result.ModeMemoryPagesFreeList.CountMax;
|
Result.ModeMemoryPagesFreeList.Count = Result.ModeMemoryPagesFreeList.CountMax;
|
||||||
|
|
|
@ -163,15 +163,42 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, deb
|
||||||
ui_EndList(Interface);
|
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
|
internal void
|
||||||
RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state* State, context Context, gs_memory_arena* Memory)
|
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_allocator_debug Debug = *Context.ThreadContext.Allocator.Debug;
|
||||||
gs_string TempString = PushString(State->Transient, 256);
|
gs_string TempString = PushString(State->Transient, 256);
|
||||||
|
|
||||||
u64 MemFootprint = Debug.TotalAllocSize;
|
mem_amt MemFootprint = GetMemAmt(Debug.TotalAllocSize);
|
||||||
u64 AllocCount = Debug.AllocationsCount;
|
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_Label(Interface, TempString);
|
||||||
|
|
||||||
ui_column_spec ColumnWidths[] = {
|
ui_column_spec ColumnWidths[] = {
|
||||||
|
@ -194,7 +221,9 @@ RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state*
|
||||||
PrintF(&TempString, "%S", A.Location);
|
PrintF(&TempString, "%S", A.Location);
|
||||||
ui_Label(Interface, TempString);
|
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_Label(Interface, TempString);
|
||||||
}
|
}
|
||||||
ui_EndRow(Interface);
|
ui_EndRow(Interface);
|
||||||
|
@ -216,59 +245,65 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
|
||||||
RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
|
RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
|
||||||
rect2 FrameListInner = RectInset(FrameListBounds, 4);
|
rect2 FrameListInner = RectInset(FrameListBounds, 4);
|
||||||
|
|
||||||
r32 SingleFrameStep = Rect2Width(FrameListInner) / DEBUG_FRAME_COUNT;
|
s32 FramesToDisplay = DEBUG_FRAME_COUNT;
|
||||||
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
|
if (FramesToDisplay != 0)
|
||||||
|
|
||||||
ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4);
|
|
||||||
if (MouseButtonHeldDown(Context.Mouse.LeftButtonState))
|
|
||||||
{
|
{
|
||||||
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);
|
if (PointIsInRect(FrameListBounds, Context.Mouse.Pos))
|
||||||
s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
|
|
||||||
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
|
|
||||||
{
|
{
|
||||||
GlobalDebugServices->RecordFrames = false;
|
v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos);
|
||||||
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
|
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)});
|
rect2 FrameBounds = MakeRect2MinDim(FrameListInner.Min, v2{SingleFrameWidth, Rect2Height(FrameListInner)});
|
||||||
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
|
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
|
||||||
{
|
{
|
||||||
rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep);
|
rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep);
|
||||||
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
|
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
|
||||||
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
|
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
|
||||||
v4 Color = FrameColors[Clamp(0, FramesAgo, 3)];
|
v4 Color = FrameColors[Clamp(0, FramesAgo, 3)];
|
||||||
ui_FillRect(&State->Interface, PositionedFrameBounds, Color);
|
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_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;
|
ui_BeginRow(&State->Interface, 4);
|
||||||
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;
|
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);
|
ui_BeginRow(&State->Interface, 8);
|
||||||
{
|
{
|
||||||
|
@ -291,12 +326,18 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
|
||||||
{
|
{
|
||||||
case DebugUI_Profiler:
|
case DebugUI_Profiler:
|
||||||
{
|
{
|
||||||
RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory);
|
if (VisibleFrame)
|
||||||
|
{
|
||||||
|
RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory);
|
||||||
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case DebugUI_ScopeList:
|
case DebugUI_ScopeList:
|
||||||
{
|
{
|
||||||
RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory);
|
if (VisibleFrame)
|
||||||
|
{
|
||||||
|
RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory);
|
||||||
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case DebugUI_MemoryView:
|
case DebugUI_MemoryView:
|
||||||
|
|
|
@ -74,8 +74,6 @@ struct animation
|
||||||
gs_string Name;
|
gs_string Name;
|
||||||
|
|
||||||
anim_layer_array Layers;
|
anim_layer_array Layers;
|
||||||
// TODO(pjs): Pretty sure Blocks_ should be obsolete and
|
|
||||||
// Layers should contain their own blocks
|
|
||||||
animation_block_array Blocks_;
|
animation_block_array Blocks_;
|
||||||
|
|
||||||
frame_range PlayableRange;
|
frame_range PlayableRange;
|
||||||
|
@ -169,6 +167,7 @@ struct animation_system
|
||||||
// panel
|
// panel
|
||||||
animation_fade_group ActiveFadeGroup;
|
animation_fade_group ActiveFadeGroup;
|
||||||
|
|
||||||
|
r32 SecondsOnCurrentFrame;
|
||||||
s32 CurrentFrame;
|
s32 CurrentFrame;
|
||||||
s32 LastUpdatedFrame;
|
s32 LastUpdatedFrame;
|
||||||
r32 SecondsPerFrame;
|
r32 SecondsPerFrame;
|
||||||
|
@ -762,13 +761,28 @@ AnimationSystem_Update(animation_system* System, r32 DeltaTime)
|
||||||
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System);
|
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System);
|
||||||
if (ActiveAnim)
|
if (ActiveAnim)
|
||||||
{
|
{
|
||||||
// TODO(Peter): Revisit this. This implies that the framerate of the animation system
|
System->SecondsOnCurrentFrame += DeltaTime;
|
||||||
// is tied to the framerate of the simulation. That seems correct to me, but I'm not sure
|
while (System->SecondsOnCurrentFrame > System->SecondsPerFrame)
|
||||||
System->CurrentFrame += 1;
|
{
|
||||||
|
System->CurrentFrame += 1;
|
||||||
|
System->SecondsOnCurrentFrame -= System->SecondsPerFrame;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop back to the beginning
|
// Loop back to the beginning
|
||||||
if (System->CurrentFrame > ActiveAnim->PlayableRange.Max)
|
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)
|
switch (System->RepeatMode)
|
||||||
{
|
{
|
||||||
case AnimationRepeat_Single:
|
case AnimationRepeat_Single:
|
||||||
|
|
|
@ -81,8 +81,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
ReloadStaticData(*Context, GlobalDebugServices, true);
|
ReloadStaticData(*Context, GlobalDebugServices, true);
|
||||||
US_CustomInit(&State->UserSpaceDesc, State, *Context);
|
US_CustomInit(&State->UserSpaceDesc, State, *Context);
|
||||||
|
|
||||||
GlobalDebugServices->Interface.RenderSculpture = true;
|
|
||||||
|
|
||||||
if (!Context->Headless)
|
if (!Context->Headless)
|
||||||
{
|
{
|
||||||
// NOTE(pjs): This just sets up the default panel layout
|
// NOTE(pjs): This just sets up the default panel layout
|
||||||
|
|
|
@ -75,11 +75,6 @@ enum debug_ui_view
|
||||||
|
|
||||||
struct debug_interface
|
struct debug_interface
|
||||||
{
|
{
|
||||||
b32 ShowCameraMouse;
|
|
||||||
b32 ShowTrackedScopes;
|
|
||||||
b32 RenderSculpture;
|
|
||||||
b32 SendSACNData;
|
|
||||||
|
|
||||||
s32 FrameView;
|
s32 FrameView;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,34 +100,39 @@ struct debug_histogram_entry
|
||||||
u32 Total_CallCount;
|
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
|
struct debug_services
|
||||||
{
|
{
|
||||||
s64 PerformanceCountFrequency;
|
s64 PerformanceCountFrequency;
|
||||||
|
|
||||||
b32 RecordFrames;
|
b32 RecordFrames;
|
||||||
s32 CurrentDebugFrame;
|
s32 CurrentDebugFrame;
|
||||||
debug_frame Frames[DEBUG_FRAME_COUNT];
|
debug_frame* Frames;
|
||||||
|
|
||||||
debug_interface Interface;
|
debug_interface Interface;
|
||||||
|
|
||||||
|
gs_thread_context Ctx;
|
||||||
|
|
||||||
debug_get_thread_id* GetThreadId;
|
debug_get_thread_id* GetThreadId;
|
||||||
debug_timing_proc* GetWallClock;
|
debug_timing_proc* GetWallClock;
|
||||||
debug_alloc* Alloc;
|
|
||||||
debug_realloc* Realloc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32 ScopeCallsMax, debug_services* Services)
|
InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32 ScopeCallsMax, debug_services* Services)
|
||||||
{
|
{
|
||||||
Frame->ScopeNamesMax = NameHashMax;
|
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
|
// 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
|
// 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
|
// we should assert and recompile with a resized NameHashMax
|
||||||
Frame->CollatedScopesMax = 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++)
|
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->ThreadCount = ThreadCount;
|
||||||
Frame->ThreadCalls = (debug_scope_record_list*)Services->Alloc(sizeof(debug_scope_record_list),
|
Frame->ThreadCalls = AllocatorAllocArray(Services->Ctx.Allocator, debug_scope_record_list, ThreadCount);
|
||||||
ThreadCount);
|
|
||||||
|
|
||||||
for (s32 i = 0; i < ThreadCount; i++)
|
for (s32 i = 0; i < ThreadCount; i++)
|
||||||
{
|
{
|
||||||
Frame->ThreadCalls[i].Max = ScopeCallsMax;
|
Frame->ThreadCalls[i].Max = ScopeCallsMax;
|
||||||
Frame->ThreadCalls[i].Count = 0;
|
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].CurrentScopeCallDepth = 0;
|
||||||
Frame->ThreadCalls[i].ThreadId = 0;
|
Frame->ThreadCalls[i].ThreadId = 0;
|
||||||
}
|
}
|
||||||
|
@ -178,16 +177,34 @@ StartDebugFrame(debug_frame* Frame, debug_services* Services)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
InitDebugServices (debug_services* Services,
|
InitDebugServices_OffMode (debug_services* Services,
|
||||||
s64 PerformanceCountFrequency,
|
s64 PerformanceCountFrequency,
|
||||||
debug_alloc* Alloc,
|
debug_timing_proc* GetWallClock,
|
||||||
debug_realloc* Realloc,
|
debug_get_thread_id* GetThreadId,
|
||||||
debug_timing_proc* GetWallClock,
|
gs_thread_context Ctx,
|
||||||
debug_get_thread_id* GetThreadId,
|
s32 ThreadCount)
|
||||||
s32 ThreadCount)
|
|
||||||
{
|
{
|
||||||
Services->Alloc = Alloc;
|
Services->Ctx = Ctx;
|
||||||
Services->Realloc = Realloc;
|
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->GetWallClock = GetWallClock;
|
||||||
Services->GetThreadId = GetThreadId;
|
Services->GetThreadId = GetThreadId;
|
||||||
|
|
||||||
|
@ -196,19 +213,13 @@ InitDebugServices (debug_services* Services,
|
||||||
Services->CurrentDebugFrame = 0;
|
Services->CurrentDebugFrame = 0;
|
||||||
s32 NameHashMax = 4096;
|
s32 NameHashMax = 4096;
|
||||||
s32 ScopeCallsMax = 4096;
|
s32 ScopeCallsMax = 4096;
|
||||||
|
Services->Frames = AllocatorAllocArray(Ctx.Allocator, debug_frame, DEBUG_FRAME_COUNT);
|
||||||
for (s32 i = 0; i < DEBUG_FRAME_COUNT; i++)
|
for (s32 i = 0; i < DEBUG_FRAME_COUNT; i++)
|
||||||
{
|
{
|
||||||
InitializeDebugFrame(&Services->Frames[i], NameHashMax, ThreadCount, ScopeCallsMax, Services);
|
InitializeDebugFrame(&Services->Frames[i], NameHashMax, ThreadCount, ScopeCallsMax, Services);
|
||||||
}
|
}
|
||||||
|
|
||||||
Services->Interface.RenderSculpture = true;
|
|
||||||
|
|
||||||
Services->PerformanceCountFrequency = PerformanceCountFrequency;
|
Services->PerformanceCountFrequency = PerformanceCountFrequency;
|
||||||
|
|
||||||
Services->Interface.ShowCameraMouse = false;
|
|
||||||
Services->Interface.ShowTrackedScopes = false;
|
|
||||||
Services->Interface.RenderSculpture = true;
|
|
||||||
Services->Interface.SendSACNData = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal debug_frame*
|
internal debug_frame*
|
||||||
|
@ -221,6 +232,8 @@ GetCurrentDebugFrame (debug_services* Services)
|
||||||
internal debug_frame*
|
internal debug_frame*
|
||||||
GetLastDebugFrame(debug_services* Services)
|
GetLastDebugFrame(debug_services* Services)
|
||||||
{
|
{
|
||||||
|
if (!Services->Frames) return 0;
|
||||||
|
|
||||||
s32 Index = (Services->CurrentDebugFrame - 1);
|
s32 Index = (Services->CurrentDebugFrame - 1);
|
||||||
if (Index < 0) { Index += DEBUG_FRAME_COUNT; }
|
if (Index < 0) { Index += DEBUG_FRAME_COUNT; }
|
||||||
debug_frame* Result = Services->Frames + Index;
|
debug_frame* Result = Services->Frames + Index;
|
||||||
|
@ -323,7 +336,11 @@ EndDebugFrame (debug_services* Services)
|
||||||
}
|
}
|
||||||
ClosingFrame->ScopeNamesCount = ScopeNamesCount;
|
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);
|
StartDebugFrame(&Services->Frames[Services->CurrentDebugFrame], Services);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,10 +405,9 @@ PushScopeTimeOnFrame (debug_services* Services, s32 NameHash, u64 StartCycles, u
|
||||||
|
|
||||||
if (ThreadList->Count >= ThreadList->Max)
|
if (ThreadList->Count >= ThreadList->Max)
|
||||||
{
|
{
|
||||||
s32 CurrentSize = ThreadList->Max * sizeof(scope_record);
|
|
||||||
s32 NewMax = (ThreadList->Max + DEBUG_FRAME_GROW_SIZE);
|
s32 NewMax = (ThreadList->Max + DEBUG_FRAME_GROW_SIZE);
|
||||||
s32 NewSize = NewMax * sizeof(scope_record);
|
AllocatorFreeArray(Services->Ctx.Allocator, ThreadList->Calls, scope_record, ThreadList->Max);
|
||||||
ThreadList->Calls = (scope_record*)Services->Realloc((u8*)ThreadList->Calls, CurrentSize, NewSize);
|
ThreadList->Calls = AllocatorAllocArray(Services->Ctx.Allocator, scope_record, NewMax);
|
||||||
ThreadList->Max = NewMax;
|
ThreadList->Max = NewMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +427,7 @@ internal r32 DEBUGGetSecondsElapsed (s64 Start, s64 End, r32 PerformanceCountFre
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if DEBUG
|
||||||
#define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices)
|
#define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices)
|
||||||
#define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices)
|
#define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -202,8 +202,6 @@ typedef struct system_time
|
||||||
s32 Second;
|
s32 Second;
|
||||||
} system_time;
|
} system_time;
|
||||||
|
|
||||||
#define STATUS_PACKET_FREQ_SECONDS 2
|
|
||||||
|
|
||||||
struct context
|
struct context
|
||||||
{
|
{
|
||||||
gs_thread_context ThreadContext;
|
gs_thread_context ThreadContext;
|
||||||
|
|
|
@ -6,22 +6,22 @@
|
||||||
#ifndef FOLDHAUS_RENDERER_CPP
|
#ifndef FOLDHAUS_RENDERER_CPP
|
||||||
|
|
||||||
internal render_command_buffer
|
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 = {};
|
render_command_buffer Result = {};
|
||||||
Result.CommandMemory = Memory;
|
Result.CommandMemory = Memory;
|
||||||
Result.CommandMemorySize = Size;
|
Result.CommandMemorySize = Size;
|
||||||
Result.CommandMemoryUsed = 0;
|
Result.CommandMemoryUsed = 0;
|
||||||
Result.Realloc = Realloc;
|
Result.Ctx = Ctx;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
internal render_command_buffer
|
internal render_command_buffer
|
||||||
AllocateRenderCommandBuffer(u32 MemorySize,
|
AllocateRenderCommandBuffer(u32 MemorySize,
|
||||||
gs_memory_arena* Arena,
|
gs_memory_arena* Arena,
|
||||||
renderer_realloc* Realloc)
|
gs_thread_context Ctx)
|
||||||
{
|
{
|
||||||
u8* Memory = PushSize(Arena, MemorySize);
|
u8* Memory = PushSize(Arena, MemorySize);
|
||||||
return AllocateRenderCommandBuffer(Memory, MemorySize, Realloc);
|
return AllocateRenderCommandBuffer(Memory, MemorySize, Ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
|
@ -124,7 +124,6 @@ struct render_quad_3d
|
||||||
|
|
||||||
struct render_texture
|
struct render_texture
|
||||||
{
|
{
|
||||||
// TODO(Peter): Is all this necessary?
|
|
||||||
u8* Memory;
|
u8* Memory;
|
||||||
s32 Handle;
|
s32 Handle;
|
||||||
s32 Width;
|
s32 Width;
|
||||||
|
@ -214,7 +213,7 @@ struct render_command_buffer
|
||||||
s32 CommandMemoryUsed;
|
s32 CommandMemoryUsed;
|
||||||
s32 CommandMemorySize;
|
s32 CommandMemorySize;
|
||||||
|
|
||||||
renderer_realloc* Realloc;
|
gs_thread_context Ctx;
|
||||||
|
|
||||||
s32 ViewWidth;
|
s32 ViewWidth;
|
||||||
s32 ViewHeight;
|
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 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point
|
||||||
s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
|
s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
|
||||||
s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
|
s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
|
||||||
Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory,
|
|
||||||
Buffer->CommandMemorySize,
|
AllocatorFree(Buffer->Ctx.Allocator, Buffer->CommandMemory, Buffer->CommandMemorySize);
|
||||||
NewSize);
|
Buffer->CommandMemory = AllocatorAlloc(Buffer->Ctx.Allocator, NewSize).Memory;
|
||||||
Buffer->CommandMemorySize = NewSize;
|
Buffer->CommandMemorySize = NewSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
internal void
|
||||||
Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt)
|
Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt)
|
||||||
{
|
{
|
||||||
|
@ -604,7 +588,7 @@ WinMain (
|
||||||
|
|
||||||
gs_allocator_debug AllocDebug = {};
|
gs_allocator_debug AllocDebug = {};
|
||||||
AllocDebug.AllocationsCountMax = 4096;
|
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;
|
ThreadContext.Allocator.Debug = &AllocDebug;
|
||||||
|
|
||||||
|
@ -636,17 +620,25 @@ WinMain (
|
||||||
|
|
||||||
s64 PerformanceCountFrequency = GetPerformanceFrequency();
|
s64 PerformanceCountFrequency = GetPerformanceFrequency();
|
||||||
s64 LastFrameEnd = GetWallClock();
|
s64 LastFrameEnd = GetWallClock();
|
||||||
r32 TargetSecondsPerFrame = 1 / 60.0f;
|
r32 TargetSecondsPerFrame = 1 / 30.0f;
|
||||||
r32 LastFrameSecondsElapsed = 0.0f;
|
r32 LastFrameSecondsElapsed = 0.0f;
|
||||||
|
|
||||||
GlobalDebugServices = PushStruct(&PlatformPermanent, debug_services);
|
GlobalDebugServices = PushStruct(&PlatformPermanent, debug_services);
|
||||||
InitDebugServices(GlobalDebugServices,
|
#if DEBUG
|
||||||
PerformanceCountFrequency,
|
InitDebugServices_DebugMode(GlobalDebugServices,
|
||||||
DEBUGAlloc,
|
PerformanceCountFrequency,
|
||||||
Win32Realloc,
|
GetWallClock,
|
||||||
GetWallClock,
|
Win32GetThreadId,
|
||||||
Win32GetThreadId,
|
Context.ThreadContext,
|
||||||
PLATFORM_THREAD_COUNT + 1);
|
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);
|
input_queue InputQueue = InputQueue_Create(&PlatformPermanent, 32);
|
||||||
|
|
||||||
|
@ -674,7 +666,11 @@ WinMain (
|
||||||
|
|
||||||
Win32SerialArray_Create(ThreadContext);
|
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);
|
addressed_data_buffer_list OutputData = AddressedDataBufferList_Create(ThreadContext);
|
||||||
|
|
||||||
|
@ -690,6 +686,7 @@ WinMain (
|
||||||
{
|
{
|
||||||
EndDebugFrame(GlobalDebugServices);
|
EndDebugFrame(GlobalDebugServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_TRACK_SCOPE(MainLoop);
|
DEBUG_TRACK_SCOPE(MainLoop);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -251,7 +251,6 @@ Win32SocketPeek(platform_socket_manager* Manager, platform_socket* Socket)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO(pjs): Error handling
|
|
||||||
s32 Error = WSAGetLastError();
|
s32 Error = WSAGetLastError();
|
||||||
switch (Error)
|
switch (Error)
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,7 @@ Win32CreateThreadContext(gs_memory_arena* Transient = 0)
|
||||||
|
|
||||||
PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
|
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
|
// NOTE(Peter): Just prints out the names of all the pending jobs if we end up
|
||||||
// overflowing the buffer
|
// overflowing the buffer
|
||||||
if (Queue->JobsCount >= Queue->JobsMax)
|
if (Queue->JobsCount >= Queue->JobsMax)
|
||||||
|
@ -82,7 +82,7 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
|
||||||
gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount;
|
gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount;
|
||||||
Job->WorkProc = WorkProc;
|
Job->WorkProc = WorkProc;
|
||||||
Job->Data = Data;
|
Job->Data = Data;
|
||||||
#ifdef DEBUG
|
#if DEBUG
|
||||||
Job->JobName = JobName;
|
Job->JobName = JobName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ CREATE_THREAD(Win32CreateThread)
|
||||||
Thread->UserData = UserData;
|
Thread->UserData = UserData;
|
||||||
|
|
||||||
// TODO(pjs): ugh, allocation out in the middle of nowhere
|
// 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);
|
*ThreadHandle = CreateThread(0, 0, Win32ThreadProcWrapper, (void*)Thread, 0, 0);
|
||||||
// TODO(pjs): Error checking on the created thread
|
// TODO(pjs): Error checking on the created thread
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,6 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
|
||||||
{
|
{
|
||||||
if (SocketPeek(Data->SocketManager, ListenSocket))
|
if (SocketPeek(Data->SocketManager, ListenSocket))
|
||||||
{
|
{
|
||||||
// TODO(pjs): Make this a peek operation
|
|
||||||
Msg = SocketRecieve(Data->SocketManager, ListenSocket, Ctx->Transient);
|
Msg = SocketRecieve(Data->SocketManager, ListenSocket, Ctx->Transient);
|
||||||
if (Msg.Size > 0)
|
if (Msg.Size > 0)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +232,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
BLState->PatternSpeed = GlobalAnimSpeed;
|
BLState->PatternSpeed = GlobalAnimSpeed;
|
||||||
|
|
||||||
#if 1
|
#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
|
#endif
|
||||||
|
|
||||||
assembly* Flower0 = LoadAssembly(Flower0AssemblyPath, State, Context);
|
assembly* Flower0 = LoadAssembly(Flower0AssemblyPath, State, Context);
|
||||||
|
@ -276,10 +275,54 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
return Result;
|
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
|
internal void
|
||||||
BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
{
|
{
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory;
|
||||||
|
BLState->ShouldUpdateLog = false;
|
||||||
|
|
||||||
bool SendMotorCommand = false;
|
bool SendMotorCommand = false;
|
||||||
blumen_packet MotorCommand = {};
|
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);
|
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState);
|
||||||
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
|
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
|
||||||
|
BLState->LastHuePhrase = NewHue;
|
||||||
}
|
}
|
||||||
|
BLState->ShouldUpdateLog = true;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PacketType_MotorState:
|
case PacketType_MotorState:
|
||||||
|
@ -340,14 +385,14 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
BLState->LastKnownMotorState = Motor.Pos;
|
BLState->LastKnownMotorState = Motor.Pos;
|
||||||
|
BLState->ShouldUpdateLog = true;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PacketType_Temperature:
|
case PacketType_Temperature:
|
||||||
{
|
{
|
||||||
temp_packet Temp = Packet.TempPacket;
|
temp_packet Temp = Packet.TempPacket;
|
||||||
|
|
||||||
if (Temp.Temperature > 0)
|
if (Temp.Temperature > MinHighTemperature)
|
||||||
{
|
{
|
||||||
BLState->BrightnessPercent = HighTemperatureBrightnessPercent;
|
BLState->BrightnessPercent = HighTemperatureBrightnessPercent;
|
||||||
}
|
}
|
||||||
|
@ -355,8 +400,10 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
{
|
{
|
||||||
BLState->BrightnessPercent = FullBrightnessPercent;
|
BLState->BrightnessPercent = FullBrightnessPercent;
|
||||||
}
|
}
|
||||||
|
BLState->LastTemperatureReceived = Temp.Temperature;
|
||||||
|
|
||||||
DEBUG_ReceivedTemperature(Temp, Context->ThreadContext);
|
DEBUG_ReceivedTemperature(Temp, Context->ThreadContext);
|
||||||
|
BLState->ShouldUpdateLog = true;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
InvalidDefaultCase;
|
InvalidDefaultCase;
|
||||||
|
@ -392,6 +439,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
|
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
|
||||||
NewAnim,
|
NewAnim,
|
||||||
VoiceCommandFadeDuration);
|
VoiceCommandFadeDuration);
|
||||||
|
BLState->ShouldUpdateLog = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +565,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
{
|
{
|
||||||
system_time LastSendTime = BLState->LastStatusUpdateTime;
|
system_time LastSendTime = BLState->LastStatusUpdateTime;
|
||||||
r64 NanosSinceLastSend = ((r64)Context->SystemTime_Current.NanosSinceEpoch - (r64)LastSendTime.NanosSinceEpoch);
|
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)
|
if (SecondsSinceLastSend >= STATUS_PACKET_FREQ_SECONDS)
|
||||||
{
|
{
|
||||||
BLState->LastStatusUpdateTime = Context->SystemTime_Current;
|
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);
|
gs_data Msg = StructToData(&Packet, blumen_packet);
|
||||||
MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg);
|
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)
|
US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI)
|
||||||
|
|
|
@ -109,6 +109,9 @@ struct mic_listen_job_data
|
||||||
blumen_network_msg_queue* IncomingMsgQueue;
|
blumen_network_msg_queue* IncomingMsgQueue;
|
||||||
|
|
||||||
blumen_network_msg_queue* OutgoingMsgQueue;
|
blumen_network_msg_queue* OutgoingMsgQueue;
|
||||||
|
|
||||||
|
// Status
|
||||||
|
bool IsConnected;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct time_range
|
typedef struct time_range
|
||||||
|
@ -151,6 +154,7 @@ struct blumen_lumen_state
|
||||||
// NOTE(pjs): Based on temperature data from weatherman
|
// NOTE(pjs): Based on temperature data from weatherman
|
||||||
// dim the leds.
|
// dim the leds.
|
||||||
r32 BrightnessPercent;
|
r32 BrightnessPercent;
|
||||||
|
s8 LastTemperatureReceived;
|
||||||
system_time LastStatusUpdateTime;
|
system_time LastStatusUpdateTime;
|
||||||
|
|
||||||
system_time LastSendTime;
|
system_time LastSendTime;
|
||||||
|
@ -172,11 +176,15 @@ struct blumen_lumen_state
|
||||||
|
|
||||||
phrase_hue_map PhraseHueMap;
|
phrase_hue_map PhraseHueMap;
|
||||||
system_time TimeLastSetToVoiceMode;
|
system_time TimeLastSetToVoiceMode;
|
||||||
|
phrase_hue LastHuePhrase;
|
||||||
|
|
||||||
r32 PatternSpeed;
|
r32 PatternSpeed;
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
motor_packet DEBUG_PendingMotorPacket;
|
motor_packet DEBUG_PendingMotorPacket;
|
||||||
bool DEBUG_IgnoreWeatherDimmingLeds;
|
bool DEBUG_IgnoreWeatherDimmingLeds;
|
||||||
|
|
||||||
|
bool ShouldUpdateLog;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "message_queue.cpp"
|
#include "message_queue.cpp"
|
||||||
|
|
|
@ -111,8 +111,17 @@ r64 VoiceCommandSustainDuration = 30.0; // in seconds
|
||||||
// to have been on the whole time.
|
// to have been on the whole time.
|
||||||
r64 TurnUpperLedsOffAfterMotorCloseCommandDelay = 5.0; // in seconds
|
r64 TurnUpperLedsOffAfterMotorCloseCommandDelay = 5.0; // in seconds
|
||||||
|
|
||||||
|
|
||||||
// NOTE: Temperature & Time of Day Based Led Brightness Settings
|
// 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.
|
// The percent brightness we set leds to during high temperatures.
|
||||||
// A value in the range 0:1 inclusive
|
// A value in the range 0:1 inclusive
|
||||||
// This is multiplied by each pixels R, G, & B channels before being
|
// 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
|
// A global modifier so Joerg can just slow all the patterns right down
|
||||||
// XD
|
// 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;
|
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
|
#endif //BLUMEN_LUMEN_SETTINGS_H
|
||||||
|
|
|
@ -85,7 +85,7 @@ typedef double r64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
static void DebugPrint(char* Format, ...);
|
static void DebugPrint(char* Format, ...);
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ static void DebugPrint(char* Format, ...);
|
||||||
if((expression)) \
|
if((expression)) \
|
||||||
{ \
|
{ \
|
||||||
}else{ \
|
}else{ \
|
||||||
volatile int* p = 0; \
|
volatile int* p = 0; \
|
||||||
*p = 5; \
|
*p = 5; \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -319,9 +319,9 @@ GSIntDivideRoundUpDef(s64);
|
||||||
|
|
||||||
#define GSRemapDef(type) \
|
#define GSRemapDef(type) \
|
||||||
static type GSRemap(type Value, type OldMin, type OldMax, type NewMin, type NewMax) { \
|
static type GSRemap(type Value, type OldMin, type OldMax, type NewMin, type NewMax) { \
|
||||||
type Result = (Value - OldMin) / (OldMax - OldMin); \
|
type Result = (Value - OldMin) / (OldMax - OldMin); \
|
||||||
Result = (Result * (NewMax - NewMin)) + NewMin; \
|
Result = (Result * (NewMax - NewMin)) + NewMin; \
|
||||||
return Result; \
|
return Result; \
|
||||||
}
|
}
|
||||||
GSRemapDef(u8);
|
GSRemapDef(u8);
|
||||||
GSRemapDef(u16);
|
GSRemapDef(u16);
|
||||||
|
|
|
@ -153,13 +153,13 @@ typedef unsigned int gs_mem_u32;
|
||||||
|
|
||||||
typedef unsigned long long int gs_mem_u64;
|
typedef unsigned long long int gs_mem_u64;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if DEBUG
|
||||||
#if !defined(GSMem_Assert)
|
#if !defined(GSMem_Assert)
|
||||||
#define GSMem_Assert(expression) \
|
#define GSMem_Assert(expression) \
|
||||||
if((expression)) { \
|
if((expression)) { \
|
||||||
}else{ \
|
}else{ \
|
||||||
volatile int* p = 0; \
|
volatile int* p = 0; \
|
||||||
*p = 5; \
|
*p = 5; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
/*
|
/*
|
||||||
gs_radix_sort.h - An implementation of radix sort for fixed size unsigned 32bit integer buffers
|
gs_radix_sort.h - An implementation of radix sort for fixed size unsigned 32bit integer buffers
|
||||||
|
|
||||||
TODO
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GS_RADIX_SORT_H
|
#ifndef GS_RADIX_SORT_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if DEBUG
|
||||||
#if !defined(GSRad_Assert)
|
#if !defined(GSRad_Assert)
|
||||||
#define GSRad_Assert(expression) \
|
#define GSRad_Assert(expression) \
|
||||||
if(!(expression)) { \
|
if(!(expression)) { \
|
||||||
|
|
|
@ -2474,7 +2474,6 @@ AllocatorDebug_PushAlloc(gs_allocator_debug* Debug, u64 Size, char* Location)
|
||||||
internal gs_data
|
internal gs_data
|
||||||
AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location)
|
AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location)
|
||||||
{
|
{
|
||||||
// TODO(Peter): Memory Profiling with Location
|
|
||||||
u64 SizeResult = 0;
|
u64 SizeResult = 0;
|
||||||
void* Memory = Allocator.Alloc(Size, &SizeResult);
|
void* Memory = Allocator.Alloc(Size, &SizeResult);
|
||||||
if (Allocator.Debug)
|
if (Allocator.Debug)
|
||||||
|
@ -2486,7 +2485,6 @@ AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location)
|
||||||
internal void
|
internal void
|
||||||
AllocatorFree_(gs_allocator Allocator, void* Base, u64 Size, char* Location)
|
AllocatorFree_(gs_allocator Allocator, void* Base, u64 Size, char* Location)
|
||||||
{
|
{
|
||||||
// TODO(Peter): Memory Profiling with Location
|
|
||||||
if (Base != 0 && Size != 0)
|
if (Base != 0 && Size != 0)
|
||||||
{
|
{
|
||||||
Allocator.Free(Base, Size);
|
Allocator.Free(Base, Size);
|
||||||
|
@ -3498,7 +3496,7 @@ CreatePlatformThreadManager(platform_create_thread* CreateThreadProc,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal platform_thread_handle
|
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 = {};
|
platform_thread_handle Result = {};
|
||||||
|
|
||||||
|
@ -3513,7 +3511,7 @@ CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg)
|
||||||
Assert(Result.Index != 0);
|
Assert(Result.Index != 0);
|
||||||
|
|
||||||
Manager->ThreadsUsed[Result.Index] = true;
|
Manager->ThreadsUsed[Result.Index] = true;
|
||||||
Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg);
|
Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg, Ctx);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -3719,7 +3717,6 @@ CloseSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(pjs): returns true if the socket is connected
|
// NOTE(pjs): returns true if the socket is connected
|
||||||
// TODO(pjs): make this more descriptive?
|
|
||||||
internal bool
|
internal bool
|
||||||
SocketQueryStatus(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle)
|
SocketQueryStatus(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,8 +140,6 @@ global_const r64 EpsilonR64 = 1.11022302462515650e-16;
|
||||||
global_const r64 NanosToSeconds = 1 / 10000000.0;
|
global_const r64 NanosToSeconds = 1 / 10000000.0;
|
||||||
global_const r64 SecondsToNanos = 10000000.0;
|
global_const r64 SecondsToNanos = 10000000.0;
|
||||||
|
|
||||||
// TODO: va_start and va_arg replacements
|
|
||||||
|
|
||||||
internal r32
|
internal r32
|
||||||
DegToRadR32(r32 Degrees)
|
DegToRadR32(r32 Degrees)
|
||||||
{
|
{
|
||||||
|
@ -1090,10 +1088,9 @@ typedef struct platform_thread
|
||||||
u8* PlatformHandle;
|
u8* PlatformHandle;
|
||||||
thread_proc_* Proc;
|
thread_proc_* Proc;
|
||||||
u8* UserData;
|
u8* UserData;
|
||||||
// TODO(pjs): Some kind of platform thread handle
|
|
||||||
} platform_thread;
|
} 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);
|
typedef CREATE_THREAD(platform_create_thread);
|
||||||
|
|
||||||
#define KILL_THREAD(name) bool name(platform_thread* Thread)
|
#define KILL_THREAD(name) bool name(platform_thread* Thread)
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct window
|
||||||
struct handle_window_msg_result
|
struct handle_window_msg_result
|
||||||
{
|
{
|
||||||
b32 NeedsUpdate;
|
b32 NeedsUpdate;
|
||||||
#ifdef DEBUG
|
#if DEBUG
|
||||||
char MessageType[128];
|
char MessageType[128];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
Loading…
Reference in New Issue