Lotta work on panels geting animation and sculpture view more up to scratch. Deleted a bunch of now obsolete files.
This commit is contained in:
parent
76d27e3b57
commit
d112b01e79
BIN
data/splash.png
BIN
data/splash.png
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlock)
|
|
||||||
{
|
|
||||||
if (AnimationBlockHandleIsValid(State->SelectedAnimationBlockHandle))
|
|
||||||
{
|
|
||||||
RemoveAnimationBlock(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
|
|
||||||
State->SelectedAnimationBlockHandle = {0};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,12 +30,12 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, v2 FooterMin,
|
||||||
v2 MenuMax = v2{ButtonMin.x + ButtonDimension.x, ButtonMin.y + (ButtonDimension.y * GlobalPanelDefsCount)};
|
v2 MenuMax = v2{ButtonMin.x + ButtonDimension.x, ButtonMin.y + (ButtonDimension.y * GlobalPanelDefsCount)};
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||||
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
|
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
|
||||||
{
|
{
|
||||||
Panel->PanelSelectionMenuOpen = false;
|
Panel->PanelSelectionMenuOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
||||||
{
|
{
|
||||||
panel_definition Def = GlobalPanelDefs[i];
|
panel_definition Def = GlobalPanelDefs[i];
|
||||||
string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
||||||
|
@ -52,9 +52,9 @@ for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button_result ButtonResult = EvaluateButton(RenderBuffer,
|
button_result ButtonResult = EvaluateButton(RenderBuffer,
|
||||||
PanelSelectButtonMin,
|
PanelSelectButtonMin,
|
||||||
PanelSelectButtonMax,
|
PanelSelectButtonMax,
|
||||||
MakeStringLiteral("Select"), Interface, Mouse);
|
MakeStringLiteral("Select"), Interface, Mouse);
|
||||||
if (ButtonResult.Pressed)
|
if (ButtonResult.Pressed)
|
||||||
{
|
{
|
||||||
|
@ -68,26 +68,26 @@ RenderPanel(panel* Panel, v2 PanelMin, v2 PanelMax, v2 WindowMin, v2 WindowMax,
|
||||||
{
|
{
|
||||||
Assert(Panel->PanelDefinitionIndex >= 0);
|
Assert(Panel->PanelDefinitionIndex >= 0);
|
||||||
|
|
||||||
v2 FooterMin = PanelMin;
|
v2 FooterMin = PanelMin;
|
||||||
v2 FooterMax = v2{PanelMax.x, PanelMin.y + 25};
|
v2 FooterMax = v2{PanelMax.x, PanelMin.y + 25};
|
||||||
v2 PanelViewMin = v2{PanelMin.x, FooterMax.y};
|
v2 PanelViewMin = v2{PanelMin.x, FooterMax.y};
|
||||||
v2 PanelViewMax = PanelMax;
|
v2 PanelViewMax = PanelMax;
|
||||||
|
|
||||||
panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex];
|
panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex];
|
||||||
|
|
||||||
|
|
||||||
Definition.Render(*Panel, PanelMin, PanelMax, RenderBuffer, State, Context, Mouse);
|
Definition.Render(*Panel, PanelMin, PanelMax, RenderBuffer, State, Context, Mouse);
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, WindowMin.x, WindowMin.y, WindowMax.x, WindowMax.y);
|
PushRenderOrthographic(RenderBuffer, WindowMin.x, WindowMin.y, WindowMax.x, WindowMax.y);
|
||||||
DrawPanelFooter(Panel, RenderBuffer, FooterMin, FooterMax, State->Interface, Mouse);
|
DrawPanelFooter(Panel, RenderBuffer, FooterMin, FooterMax, State->Interface, Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v4
|
internal v4
|
||||||
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, r32 WindowWidth, r32 WindowHeight)
|
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(MouseToWorldRay);
|
DEBUG_TRACK_SCOPE(MouseToWorldRay);
|
||||||
r32 X = ((2.0f * MouseX) / WindowWidth) - 1;
|
r32 X = ((2.0f * MouseX) / Width(WindowBounds)) - 1;
|
||||||
r32 Y = ((2.0f * MouseY) / WindowHeight) - 1;
|
r32 Y = ((2.0f * MouseY) / Height(WindowBounds)) - 1;
|
||||||
|
|
||||||
v4 ScreenPos = v4{X, Y, -1, 1};
|
v4 ScreenPos = v4{X, Y, -1, 1};
|
||||||
|
|
||||||
|
@ -147,12 +147,6 @@ RELOAD_STATIC_DATA(ReloadStaticData)
|
||||||
GlobalDebugServices = DebugServices;
|
GlobalDebugServices = DebugServices;
|
||||||
GSAlloc = Alloc;
|
GSAlloc = Alloc;
|
||||||
GSFree = Free;
|
GSFree = Free;
|
||||||
|
|
||||||
if (State->DefaultInputCommandRegistry.Size > 0)
|
|
||||||
{
|
|
||||||
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_U, Command_Began, KeyCode_Invalid, OpenUniverseView);
|
|
||||||
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_X, Command_Ended, KeyCode_Invalid, DeleteAnimationBlock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INITIALIZE_APPLICATION(InitializeApplication)
|
INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
|
@ -165,8 +159,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->Transient.Alloc = (gs_memory_alloc*)Context.PlatformAlloc;
|
State->Transient.Alloc = (gs_memory_alloc*)Context.PlatformAlloc;
|
||||||
State->Transient.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
State->Transient.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
||||||
|
|
||||||
InitializeInputCommandRegistry(&State->DefaultInputCommandRegistry, 32, &State->Permanent);
|
|
||||||
|
|
||||||
s32 CommandQueueSize = 32;
|
s32 CommandQueueSize = 32;
|
||||||
command_queue_entry* CommandQueueMemory = PushArray(&State->Permanent,
|
command_queue_entry* CommandQueueMemory = PushArray(&State->Permanent,
|
||||||
command_queue_entry,
|
command_queue_entry,
|
||||||
|
@ -223,7 +215,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
}
|
}
|
||||||
|
|
||||||
State->Interface.Font = Font;
|
State->Interface.Font = Font;
|
||||||
State->Font = Font;
|
|
||||||
|
|
||||||
Font->BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Font->BitmapMemory,
|
Font->BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Font->BitmapMemory,
|
||||||
Font->BitmapWidth, Font->BitmapHeight);
|
Font->BitmapWidth, Font->BitmapHeight);
|
||||||
|
@ -246,7 +237,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
||||||
|
|
||||||
State->Camera.FieldOfView = DegreesToRadians(45.0f);
|
State->Camera.FieldOfView = DegreesToRadians(45.0f);
|
||||||
State->Camera.AspectRatio = (r32)Context.WindowWidth / (r32)Context.WindowHeight;
|
State->Camera.AspectRatio = AspectRatio(State->WindowBounds);
|
||||||
State->Camera.Near = 1.0f;
|
State->Camera.Near = 1.0f;
|
||||||
State->Camera.Far = 100.0f;
|
State->Camera.Far = 100.0f;
|
||||||
State->Camera.Position = v3{0, 0, -250};
|
State->Camera.Position = v3{0, 0, -250};
|
||||||
|
@ -273,9 +264,9 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->Modes.Arena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
State->Modes.Arena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
||||||
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
|
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
|
||||||
|
|
||||||
{ // MODES PLAYGROUND
|
{ // Animation PLAYGROUND
|
||||||
InitializeAnimationSystem(&State->AnimationSystem);
|
InitializeAnimationSystem(&State->AnimationSystem);
|
||||||
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||||
|
|
||||||
animation_block BlockOne = {0};
|
animation_block BlockOne = {0};
|
||||||
BlockOne.StartTime = 0;
|
BlockOne.StartTime = 0;
|
||||||
|
@ -294,23 +285,33 @@ State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||||
} // End Animation Playground
|
} // End Animation Playground
|
||||||
|
|
||||||
|
|
||||||
{ // Panels Playground
|
InitializePanelLayout(&State->PanelLayout);
|
||||||
InitializePanelLayout(&State->PanelLayout);
|
panel* Panel = TakeNewPanel(&State->PanelLayout);
|
||||||
panel* Panel = TakeNewPanel(&State->PanelLayout);
|
SetPanelDefinition(Panel, 0);
|
||||||
SetPanelDefinition(Panel, 0);
|
|
||||||
} // End Panels Playground
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
HandleInput (app_state* State, input_queue InputQueue, mouse_state Mouse)
|
HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
input_command_registry ActiveCommands = State->DefaultInputCommandRegistry;
|
input_command_registry ActiveCommands = {};
|
||||||
if (State->Modes.ActiveModesCount > 0)
|
if (State->Modes.ActiveModesCount > 0)
|
||||||
{
|
{
|
||||||
ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands;
|
ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panel_and_bounds PanelWithMouseOverIt = GetPanelContainingPoint(Mouse.Pos, &State->PanelLayout, WindowBounds);
|
||||||
|
if (!PanelWithMouseOverIt.Panel) { return; }
|
||||||
|
|
||||||
|
panel_definition PanelDefinition = GlobalPanelDefs[PanelWithMouseOverIt.Panel->PanelDefinitionIndex];
|
||||||
|
if (!PanelDefinition.InputCommands) { return; }
|
||||||
|
|
||||||
|
ActiveCommands.Commands = PanelDefinition.InputCommands;
|
||||||
|
ActiveCommands.Size = sizeof(*PanelDefinition.InputCommands) / sizeof(PanelDefinition.InputCommands[0]);
|
||||||
|
ActiveCommands.Used = ActiveCommands.Size;
|
||||||
|
}
|
||||||
|
|
||||||
for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++)
|
for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++)
|
||||||
{
|
{
|
||||||
|
@ -358,7 +359,7 @@ CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena)
|
||||||
leds_in_universe_range LEDUniverseRange = Assembly.LEDUniverseMap[Range];
|
leds_in_universe_range LEDUniverseRange = Assembly.LEDUniverseMap[Range];
|
||||||
|
|
||||||
dmx_buffer_list* NewBuffer = PushStruct(Arena, dmx_buffer_list);
|
dmx_buffer_list* NewBuffer = PushStruct(Arena, dmx_buffer_list);
|
||||||
NewBuffer->Buffer.Universe = LEDUniverseRange.Universe;
|
NewBuffer->Buffer.Universe = LEDUniverseRange.Universe;
|
||||||
NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize);
|
NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize);
|
||||||
NewBuffer->Buffer.TotalSize = BufferSize;
|
NewBuffer->Buffer.TotalSize = BufferSize;
|
||||||
NewBuffer->Buffer.HeaderSize = BufferHeaderSize;
|
NewBuffer->Buffer.HeaderSize = BufferHeaderSize;
|
||||||
|
@ -395,6 +396,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
app_state* State = (app_state*)Context.MemoryBase;
|
app_state* State = (app_state*)Context.MemoryBase;
|
||||||
|
State->WindowBounds = Context.WindowBounds;
|
||||||
|
|
||||||
// NOTE(Peter): We do this at the beginning because all the render commands are stored in Transient,
|
// NOTE(Peter): We do this at the beginning because all the render commands are stored in Transient,
|
||||||
// and need to persist beyond the end of the UpdateAndRender call. In the release version, we won't
|
// and need to persist beyond the end of the UpdateAndRender call. In the release version, we won't
|
||||||
|
@ -402,7 +404,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
// incorrect to clear the arena, and then access the memory later.
|
// incorrect to clear the arena, and then access the memory later.
|
||||||
ClearArena(&State->Transient);
|
ClearArena(&State->Transient);
|
||||||
|
|
||||||
HandleInput(State, InputQueue, Mouse);
|
HandleInput(State, State->WindowBounds, InputQueue, Mouse);
|
||||||
|
|
||||||
if (State->AnimationSystem.TimelineShouldAdvance) {
|
if (State->AnimationSystem.TimelineShouldAdvance) {
|
||||||
State->AnimationSystem.Time += Context.DeltaTime;
|
State->AnimationSystem.Time += Context.DeltaTime;
|
||||||
|
@ -412,11 +414,11 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.SecondsPerFrame);
|
s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.SecondsPerFrame);
|
||||||
if (CurrentFrame != State->AnimationSystem.LastUpdatedFrame)
|
if (CurrentFrame != State->AnimationSystem.LastUpdatedFrame)
|
||||||
{
|
{
|
||||||
State->AnimationSystem.LastUpdatedFrame = CurrentFrame;
|
State->AnimationSystem.LastUpdatedFrame = CurrentFrame;
|
||||||
r32 FrameTime = CurrentFrame * State->AnimationSystem.SecondsPerFrame;
|
r32 FrameTime = CurrentFrame * State->AnimationSystem.SecondsPerFrame;
|
||||||
|
|
||||||
for (u32 i = 0; i < State->AnimationSystem.BlocksCount; i++)
|
for (u32 i = 0; i < State->AnimationSystem.BlocksCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -435,8 +437,8 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
||||||
dmx_buffer_list* DMXBuffers = 0;
|
dmx_buffer_list* DMXBuffers = 0;
|
||||||
|
@ -450,7 +452,7 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se
|
||||||
array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||||
assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList);
|
assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList);
|
||||||
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, HeaderSize, &State->Transient);
|
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, HeaderSize, &State->Transient);
|
||||||
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_IF(GlobalDebugServices->Interface.SendSACNData)
|
DEBUG_IF(GlobalDebugServices->Interface.SendSACNData)
|
||||||
|
@ -484,88 +486,21 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight);
|
PushRenderOrthographic(RenderBuffer, 0, 0, Width(State->WindowBounds), Height(State->WindowBounds));
|
||||||
PushRenderClearScreen(RenderBuffer);
|
PushRenderClearScreen(RenderBuffer);
|
||||||
v2 WindowMin = v2{0, 0};
|
HandleMousePanelInteraction(&State->PanelLayout, State->WindowBounds, Mouse);
|
||||||
v2 WindowMax = v2{Context.WindowWidth, Context.WindowHeight};
|
|
||||||
HandleMousePanelInteraction(&State->PanelLayout, WindowMin, WindowMax, Mouse);
|
|
||||||
DrawAllPanels(State->PanelLayout, WindowMin, WindowMax, RenderBuffer, State->Interface, Mouse, State, Context);
|
|
||||||
|
|
||||||
////////////////////////////////
|
DrawAllPanels(&State->PanelLayout, State->WindowBounds, RenderBuffer, State->Interface, Mouse, State, Context);
|
||||||
// Render Assembly
|
|
||||||
///////////////////////////////
|
for (s32 m = 0; m < State->Modes.ActiveModesCount; m++)
|
||||||
if (Context.WindowIsVisible)
|
|
||||||
{
|
{
|
||||||
#if 0
|
operation_mode OperationMode = State->Modes.ActiveModes[m];
|
||||||
///////////////////////////////////////
|
if (OperationMode.Render != 0)
|
||||||
// Interface
|
|
||||||
//////////////////////////////////////
|
|
||||||
|
|
||||||
DEBUG_TRACK_SCOPE(DrawInterface);
|
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight);
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
// Menu Bar
|
|
||||||
//////////////////////////////////////
|
|
||||||
r32 TopBarHeight = 40;
|
|
||||||
{
|
{
|
||||||
panel_result TopBarPanel = EvaluatePanel(RenderBuffer,
|
OperationMode.Render(State, RenderBuffer, OperationMode, Mouse);
|
||||||
v2{0, Context.WindowHeight - TopBarHeight},
|
|
||||||
v2{Context.WindowWidth, Context.WindowHeight},
|
|
||||||
0, State->Interface);
|
|
||||||
|
|
||||||
v2 ButtonDim = v2{200, (r32)NewLineYOffset(*State->Interface.Font) + 10};
|
|
||||||
v2 ButtonPos = v2{State->Interface.Margin.x, Context.WindowHeight - (ButtonDim.y + 10)};
|
|
||||||
button_result LoadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
|
||||||
MakeStringLiteral("Load Assembly"),
|
|
||||||
State->Interface, Mouse);
|
|
||||||
|
|
||||||
string InterfaceString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
|
||||||
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
|
||||||
{
|
|
||||||
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
|
||||||
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
|
||||||
PrintF(&InterfaceString, "Unload %.*s", Assembly.Name.Length, Assembly.Name.Memory);
|
|
||||||
|
|
||||||
ButtonPos.x += ButtonDim.x + 10;
|
|
||||||
button_result UnloadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
|
||||||
InterfaceString, State->Interface, Mouse);
|
|
||||||
|
|
||||||
if (UnloadAssemblyBtn.Pressed)
|
|
||||||
{
|
|
||||||
UnloadAssembly(i, State, Context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LoadAssemblyBtn.Pressed)
|
|
||||||
{
|
|
||||||
char FilePath[256];
|
|
||||||
b32 Success = Context.PlatformGetFilePath(FilePath, 256, "Foldhaus Files\0*.fold\0\0");
|
|
||||||
if (Success)
|
|
||||||
{
|
|
||||||
LoadAssembly(State, Context, FilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawDebugInterface(RenderBuffer, 25,
|
|
||||||
State->Interface, Context.WindowWidth, Context.WindowHeight - TopBarHeight,
|
|
||||||
Context.DeltaTime, State, State->Camera, Mouse, &State->Transient);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (s32 m = 0; m < State->Modes.ActiveModesCount; m++)
|
|
||||||
{
|
|
||||||
operation_mode OperationMode = State->Modes.ActiveModes[m];
|
|
||||||
if (OperationMode.Render != 0)
|
|
||||||
{
|
|
||||||
OperationMode.Render(State, RenderBuffer, OperationMode, Mouse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checking for overflows
|
// Checking for overflows
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(OverflowChecks);
|
DEBUG_TRACK_SCOPE(OverflowChecks);
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
#include "foldhaus_node.h"
|
#include "foldhaus_node.h"
|
||||||
#include "assembly_parser.cpp"
|
#include "assembly_parser.cpp"
|
||||||
#include "test_patterns.h"
|
#include "test_patterns.h"
|
||||||
#include "foldhaus_interface.h"
|
|
||||||
|
|
||||||
typedef struct app_state app_state;
|
typedef struct app_state app_state;
|
||||||
|
|
||||||
|
// TODO(Peter): something we can do later is to remove all reliance on app_state and context
|
||||||
|
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
|
||||||
|
// perform operations on, like panel_draw_requests = { bounds, panel* } etc.
|
||||||
#include "foldhaus_panel.h"
|
#include "foldhaus_panel.h"
|
||||||
|
|
||||||
#include "foldhaus_command_dispatch.h"
|
#include "foldhaus_command_dispatch.h"
|
||||||
#include "foldhaus_command_dispatch.cpp"
|
|
||||||
#include "foldhaus_operation_mode.h"
|
#include "foldhaus_operation_mode.h"
|
||||||
|
|
||||||
#include "animation/foldhaus_animation.h"
|
#include "animation/foldhaus_animation.h"
|
||||||
|
@ -40,16 +40,17 @@ enum network_protocol
|
||||||
|
|
||||||
struct app_state
|
struct app_state
|
||||||
{
|
{
|
||||||
|
rect WindowBounds;
|
||||||
|
|
||||||
memory_arena Permanent;
|
memory_arena Permanent;
|
||||||
memory_arena Transient;
|
memory_arena Transient;
|
||||||
|
|
||||||
s32 NetworkProtocolHeaderSize;
|
s32 NetworkProtocolHeaderSize;
|
||||||
network_protocol NetworkProtocol;
|
network_protocol NetworkProtocol;
|
||||||
|
|
||||||
streaming_acn SACN;
|
streaming_acn SACN;
|
||||||
|
|
||||||
s32 TotalLEDsCount;
|
s32 TotalLEDsCount;
|
||||||
|
|
||||||
assembly_array AssemblyList;
|
assembly_array AssemblyList;
|
||||||
array_entry_handle_contiguous_array ActiveAssemblyIndecies;
|
array_entry_handle_contiguous_array ActiveAssemblyIndecies;
|
||||||
|
|
||||||
|
@ -57,11 +58,9 @@ s32 NetworkProtocolHeaderSize;
|
||||||
r32 PixelsToWorldScale;
|
r32 PixelsToWorldScale;
|
||||||
|
|
||||||
operation_mode_system Modes;
|
operation_mode_system Modes;
|
||||||
input_command_registry DefaultInputCommandRegistry;
|
|
||||||
input_command_queue CommandQueue;
|
input_command_queue CommandQueue;
|
||||||
text_entry ActiveTextEntry;
|
text_entry ActiveTextEntry;
|
||||||
|
|
||||||
bitmap_font* Font;
|
|
||||||
interface_config Interface;
|
interface_config Interface;
|
||||||
|
|
||||||
animation_system AnimationSystem;
|
animation_system AnimationSystem;
|
||||||
|
@ -88,7 +87,7 @@ TestPatternOne(assembly* Assembly, r32 Time)
|
||||||
Assembly->Colors[LED.Index].B = 255;
|
Assembly->Colors[LED.Index].B = 255;
|
||||||
Assembly->Colors[LED.Index].G = 255;
|
Assembly->Colors[LED.Index].G = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -97,7 +96,7 @@ TestPatternTwo(assembly* Assembly, r32 Time)
|
||||||
r32 PeriodicTime = (Time / PI) * 2;
|
r32 PeriodicTime = (Time / PI) * 2;
|
||||||
|
|
||||||
r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f;
|
r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f;
|
||||||
r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
|
r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
|
||||||
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
||||||
|
|
||||||
v4 Center = v4{0, 0, 0, 1};
|
v4 Center = v4{0, 0, 0, 1};
|
||||||
|
@ -111,42 +110,42 @@ r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
|
||||||
r32 OuterRadiusSquared = 1000000;
|
r32 OuterRadiusSquared = 1000000;
|
||||||
r32 InnerRadiusSquared = 0;
|
r32 InnerRadiusSquared = 0;
|
||||||
|
|
||||||
for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++)
|
for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++)
|
||||||
{
|
{
|
||||||
leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range];
|
leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range];
|
||||||
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
||||||
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
||||||
LEDIdx++)
|
LEDIdx++)
|
||||||
{
|
{
|
||||||
led LED = Assembly->LEDs[LEDIdx];
|
led LED = Assembly->LEDs[LEDIdx];
|
||||||
|
|
||||||
v4 Position = LED.Position;
|
v4 Position = LED.Position;
|
||||||
|
|
||||||
v4 ToFront = Position + FrontCenter;
|
v4 ToFront = Position + FrontCenter;
|
||||||
v4 ToBack = Position + BackCenter;
|
v4 ToBack = Position + BackCenter;
|
||||||
|
|
||||||
r32 ToFrontDotNormal = Dot(ToFront, Normal);
|
r32 ToFrontDotNormal = Dot(ToFront, Normal);
|
||||||
r32 ToBackDotNormal = Dot(ToBack, Normal);
|
r32 ToBackDotNormal = Dot(ToBack, Normal);
|
||||||
|
|
||||||
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000);
|
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000);
|
||||||
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000);
|
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000);
|
||||||
|
|
||||||
r32 SqDistToCenter = MagSqr(Position);
|
r32 SqDistToCenter = MagSqr(Position);
|
||||||
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
||||||
{
|
|
||||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
|
||||||
{
|
{
|
||||||
|
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
||||||
|
{
|
||||||
Assembly->Colors[LED.Index] = Color;
|
Assembly->Colors[LED.Index] = Color;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assembly->Colors[LED.Index] = {};
|
Assembly->Colors[LED.Index] = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assembly->Colors[LED.Index] = {};
|
Assembly->Colors[LED.Index] = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +153,7 @@ else
|
||||||
internal void
|
internal void
|
||||||
TestPatternThree(assembly* Assembly, r32 Time)
|
TestPatternThree(assembly* Assembly, r32 Time)
|
||||||
{
|
{
|
||||||
r32 GreenSize = 20.0f;
|
r32 GreenSize = 20.0f;
|
||||||
r32 BlueSize = 25.0f;
|
r32 BlueSize = 25.0f;
|
||||||
r32 RedSize = 25.0f;
|
r32 RedSize = 25.0f;
|
||||||
|
|
||||||
|
@ -196,13 +195,10 @@ r32 GreenSize = 20.0f;
|
||||||
|
|
||||||
#include "foldhaus_assembly.cpp"
|
#include "foldhaus_assembly.cpp"
|
||||||
|
|
||||||
#include "foldhaus_debug_visuals.h"
|
|
||||||
//#include "foldhaus_sacn_view.cpp"
|
|
||||||
#include "foldhaus_text_entry.cpp"
|
#include "foldhaus_text_entry.cpp"
|
||||||
#include "foldhaus_search_lister.cpp"
|
#include "foldhaus_search_lister.cpp"
|
||||||
|
|
||||||
#include "foldhaus_interface.cpp"
|
#include "foldhaus_interface.cpp"
|
||||||
#include "animation/foldhaus_animation_interface.h"
|
|
||||||
|
|
||||||
#define PANEL_INIT_PROC(name) void name(panel* Panel)
|
#define PANEL_INIT_PROC(name) void name(panel* Panel)
|
||||||
typedef PANEL_INIT_PROC(panel_init_proc);
|
typedef PANEL_INIT_PROC(panel_init_proc);
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
internal void
|
|
||||||
InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
|
|
||||||
s32 Size,
|
|
||||||
memory_arena* Storage)
|
|
||||||
{
|
|
||||||
CommandRegistry->Commands = PushArray(Storage, input_command, Size);
|
|
||||||
CommandRegistry->Size = Size;
|
|
||||||
CommandRegistry->Used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
RegisterMouseWheelCommand (input_command_registry* CommandRegistry,
|
|
||||||
input_command_proc* Proc)
|
|
||||||
{
|
|
||||||
CommandRegistry->MouseWheelCommand = Proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal s32
|
|
||||||
GetCommandIndexInQueue(input_command_queue* Queue, input_command Command, input_entry Event)
|
|
||||||
{
|
|
||||||
s32 Result = -1;
|
|
||||||
for (s32 CommandIndex = 0; CommandIndex < Queue->Used; CommandIndex++)
|
|
||||||
{
|
|
||||||
command_queue_entry* Entry = Queue->Commands + CommandIndex;
|
|
||||||
if(Entry->Event.Key == Event.Key)
|
|
||||||
{
|
|
||||||
Result = CommandIndex;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal input_command_queue
|
|
||||||
InitializeCommandQueue(command_queue_entry* Memory, s32 MemorySize)
|
|
||||||
{
|
|
||||||
input_command_queue Result = {};
|
|
||||||
Result.Size = MemorySize;
|
|
||||||
Result.Used = 0;
|
|
||||||
Result.Commands = Memory;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
ClearCommandQueue(input_command_queue* Queue)
|
|
||||||
{
|
|
||||||
Queue->Used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
PushCommandOnQueue(input_command_queue* Queue, input_command Command, input_entry Event)
|
|
||||||
{
|
|
||||||
Assert(Queue->Used < Queue->Size);
|
|
||||||
command_queue_entry Entry = {};
|
|
||||||
Entry.Command = Command;
|
|
||||||
Entry.Event = Event;
|
|
||||||
Queue->Commands[Queue->Used++] = Entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
RemoveCommandFromQueue(input_command_queue* Queue, s32 Index)
|
|
||||||
{
|
|
||||||
s32 CommandIndex = Index;
|
|
||||||
if (CommandIndex < Queue->Used)
|
|
||||||
{
|
|
||||||
Queue->Used -= 1;
|
|
||||||
|
|
||||||
for (; CommandIndex < Queue->Used; CommandIndex++)
|
|
||||||
{
|
|
||||||
Queue->Commands[CommandIndex] = Queue->Commands[CommandIndex + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_entry Event)
|
|
||||||
{
|
|
||||||
s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event);
|
|
||||||
|
|
||||||
// NOTE(Peter): If we made it through the queue without finding an event, there wasn't one
|
|
||||||
// to remove. This happens when we've changed command registries as a result of an input command,
|
|
||||||
// and the command exists in the new registry.
|
|
||||||
// For example:
|
|
||||||
// clicking a mouse button triggers a command to switch registries
|
|
||||||
// the new registry tracks mouse drag (persist until release)
|
|
||||||
// when the mouse is released, the event fires, but there is no mouse down event to remove
|
|
||||||
// For this reason, I'm allowing the case where we try and remove a command where non exists
|
|
||||||
// I don't think this is a great solution but Im not super familiar with the codebase right now
|
|
||||||
// so leaving it as is. revisit if it becomes a problem.
|
|
||||||
RemoveCommandFromQueue(Queue, CommandIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal input_command*
|
|
||||||
FindExistingCommand (input_command_registry CommandRegistry, key_code Key, key_code Mdfr, b32 Flags)
|
|
||||||
{
|
|
||||||
input_command* Result = 0;
|
|
||||||
|
|
||||||
for (s32 Cmd = 0; Cmd < CommandRegistry.Used; Cmd++)
|
|
||||||
{
|
|
||||||
input_command* Command = CommandRegistry.Commands + Cmd;
|
|
||||||
if (Command->Key == Key && Command->Mdfr == Mdfr)
|
|
||||||
{
|
|
||||||
b32 FlagsOverlap = Flags & Command->Flags;
|
|
||||||
if (FlagsOverlap)
|
|
||||||
{
|
|
||||||
Result = Command;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
FindAndPushExistingCommand(input_command_registry CommandRegistry, input_entry Event, b32 Flags, input_command_queue* CommandQueue)
|
|
||||||
{
|
|
||||||
b32 CommandFound = false;
|
|
||||||
input_command* Command = FindExistingCommand(CommandRegistry, Event.Key, (key_code)0, Flags);
|
|
||||||
if (Command)
|
|
||||||
{
|
|
||||||
PushCommandOnQueue(CommandQueue, *Command, Event);
|
|
||||||
CommandFound = true;
|
|
||||||
}
|
|
||||||
return CommandFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
RegisterKeyPressCommand (input_command_registry* CommandRegistry,
|
|
||||||
key_code Key,
|
|
||||||
b32 Flags,
|
|
||||||
key_code Mdfr,
|
|
||||||
input_command_proc* Proc)
|
|
||||||
{
|
|
||||||
input_command* Command = FindExistingCommand(*CommandRegistry, Key, Mdfr, Flags);
|
|
||||||
|
|
||||||
if (!Command)
|
|
||||||
{
|
|
||||||
Assert(CommandRegistry->Size > CommandRegistry->Used);
|
|
||||||
Assert(Mdfr == KeyCode_Invalid || Mdfr == KeyCode_LeftShift || Mdfr == KeyCode_RightShift ||
|
|
||||||
Mdfr == KeyCode_LeftCtrl || Mdfr == KeyCode_RightCtrl || Mdfr == KeyCode_Alt);
|
|
||||||
Command = CommandRegistry->Commands + CommandRegistry->Used++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command->Key = Key;
|
|
||||||
Command->Flags = Flags;
|
|
||||||
Command->Mdfr = Mdfr;
|
|
||||||
Command->Proc = Proc;
|
|
||||||
}
|
|
|
@ -44,3 +44,153 @@ struct input_command_queue
|
||||||
s32 Used;
|
s32 Used;
|
||||||
command_queue_entry* Commands;
|
command_queue_entry* Commands;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
|
||||||
|
s32 Size,
|
||||||
|
memory_arena* Storage)
|
||||||
|
{
|
||||||
|
CommandRegistry->Commands = PushArray(Storage, input_command, Size);
|
||||||
|
CommandRegistry->Size = Size;
|
||||||
|
CommandRegistry->Used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
RegisterMouseWheelCommand (input_command_registry* CommandRegistry,
|
||||||
|
input_command_proc* Proc)
|
||||||
|
{
|
||||||
|
CommandRegistry->MouseWheelCommand = Proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal s32
|
||||||
|
GetCommandIndexInQueue(input_command_queue* Queue, input_command Command, input_entry Event)
|
||||||
|
{
|
||||||
|
s32 Result = -1;
|
||||||
|
for (s32 CommandIndex = 0; CommandIndex < Queue->Used; CommandIndex++)
|
||||||
|
{
|
||||||
|
command_queue_entry* Entry = Queue->Commands + CommandIndex;
|
||||||
|
if(Entry->Event.Key == Event.Key)
|
||||||
|
{
|
||||||
|
Result = CommandIndex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal input_command_queue
|
||||||
|
InitializeCommandQueue(command_queue_entry* Memory, s32 MemorySize)
|
||||||
|
{
|
||||||
|
input_command_queue Result = {};
|
||||||
|
Result.Size = MemorySize;
|
||||||
|
Result.Used = 0;
|
||||||
|
Result.Commands = Memory;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
ClearCommandQueue(input_command_queue* Queue)
|
||||||
|
{
|
||||||
|
Queue->Used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
PushCommandOnQueue(input_command_queue* Queue, input_command Command, input_entry Event)
|
||||||
|
{
|
||||||
|
Assert(Queue->Used < Queue->Size);
|
||||||
|
command_queue_entry Entry = {};
|
||||||
|
Entry.Command = Command;
|
||||||
|
Entry.Event = Event;
|
||||||
|
Queue->Commands[Queue->Used++] = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
RemoveCommandFromQueue(input_command_queue* Queue, s32 Index)
|
||||||
|
{
|
||||||
|
s32 CommandIndex = Index;
|
||||||
|
if (CommandIndex < Queue->Used)
|
||||||
|
{
|
||||||
|
Queue->Used -= 1;
|
||||||
|
|
||||||
|
for (; CommandIndex < Queue->Used; CommandIndex++)
|
||||||
|
{
|
||||||
|
Queue->Commands[CommandIndex] = Queue->Commands[CommandIndex + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_entry Event)
|
||||||
|
{
|
||||||
|
s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event);
|
||||||
|
|
||||||
|
// NOTE(Peter): If we made it through the queue without finding an event, there wasn't one
|
||||||
|
// to remove. This happens when we've changed command registries as a result of an input command,
|
||||||
|
// and the command exists in the new registry.
|
||||||
|
// For example:
|
||||||
|
// clicking a mouse button triggers a command to switch registries
|
||||||
|
// the new registry tracks mouse drag (persist until release)
|
||||||
|
// when the mouse is released, the event fires, but there is no mouse down event to remove
|
||||||
|
// For this reason, I'm allowing the case where we try and remove a command where non exists
|
||||||
|
// I don't think this is a great solution but Im not super familiar with the codebase right now
|
||||||
|
// so leaving it as is. revisit if it becomes a problem.
|
||||||
|
RemoveCommandFromQueue(Queue, CommandIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal input_command*
|
||||||
|
FindExistingCommand (input_command_registry CommandRegistry, key_code Key, key_code Mdfr, b32 Flags)
|
||||||
|
{
|
||||||
|
input_command* Result = 0;
|
||||||
|
|
||||||
|
for (s32 Cmd = 0; Cmd < CommandRegistry.Used; Cmd++)
|
||||||
|
{
|
||||||
|
input_command* Command = CommandRegistry.Commands + Cmd;
|
||||||
|
if (Command->Key == Key && Command->Mdfr == Mdfr)
|
||||||
|
{
|
||||||
|
b32 FlagsOverlap = Flags & Command->Flags;
|
||||||
|
if (FlagsOverlap)
|
||||||
|
{
|
||||||
|
Result = Command;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
FindAndPushExistingCommand(input_command_registry CommandRegistry, input_entry Event, b32 Flags, input_command_queue* CommandQueue)
|
||||||
|
{
|
||||||
|
b32 CommandFound = false;
|
||||||
|
input_command* Command = FindExistingCommand(CommandRegistry, Event.Key, (key_code)0, Flags);
|
||||||
|
if (Command)
|
||||||
|
{
|
||||||
|
PushCommandOnQueue(CommandQueue, *Command, Event);
|
||||||
|
CommandFound = true;
|
||||||
|
}
|
||||||
|
return CommandFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
RegisterKeyPressCommand (input_command_registry* CommandRegistry,
|
||||||
|
key_code Key,
|
||||||
|
b32 Flags,
|
||||||
|
key_code Mdfr,
|
||||||
|
input_command_proc* Proc)
|
||||||
|
{
|
||||||
|
input_command* Command = FindExistingCommand(*CommandRegistry, Key, Mdfr, Flags);
|
||||||
|
|
||||||
|
if (!Command)
|
||||||
|
{
|
||||||
|
Assert(CommandRegistry->Size > CommandRegistry->Used);
|
||||||
|
Assert(Mdfr == KeyCode_Invalid || Mdfr == KeyCode_LeftShift || Mdfr == KeyCode_RightShift ||
|
||||||
|
Mdfr == KeyCode_LeftCtrl || Mdfr == KeyCode_RightCtrl || Mdfr == KeyCode_Alt);
|
||||||
|
Command = CommandRegistry->Commands + CommandRegistry->Used++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command->Key = Key;
|
||||||
|
Command->Flags = Flags;
|
||||||
|
Command->Mdfr = Mdfr;
|
||||||
|
Command->Proc = Proc;
|
||||||
|
}
|
|
@ -1,195 +1,3 @@
|
||||||
#if 0
|
|
||||||
internal void
|
|
||||||
RenderProfiler_ScopeVisualization(render_command_buffer* RenderBuffer,
|
|
||||||
interface_config Interface, mouse_state Mouse,
|
|
||||||
v2 Min, v2 Max,
|
|
||||||
debug_frame* VisibleFrame, memory_arena* Memory)
|
|
||||||
{
|
|
||||||
v4 ThreadColors[] = {
|
|
||||||
v4{.73f, .33f, .83f, 1},
|
|
||||||
v4{0, .50f, .50f, 1},
|
|
||||||
v4{.83f, 0, 0, 1},
|
|
||||||
v4{.33f, .49f, .83f, 1},
|
|
||||||
v4{.74f, .40f, .25f, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
r32 Width = Max.x - Min.x;
|
|
||||||
r32 DepthHeight = 64;
|
|
||||||
|
|
||||||
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
|
||||||
s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles;
|
|
||||||
|
|
||||||
debug_scope_record_list* ThreadScopeCalls = GetScopeListForThreadInFrame(GlobalDebugServices,
|
|
||||||
VisibleFrame);
|
|
||||||
|
|
||||||
MakeStringBuffer(String, 256);
|
|
||||||
for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
|
|
||||||
{
|
|
||||||
scope_record* Record = ThreadScopeCalls->Calls + i;
|
|
||||||
scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash);
|
|
||||||
r32 PercentStart = (r32)(Record->StartCycles - FrameStartCycles) / (r32)FrameTotalCycles;
|
|
||||||
r32 PercentEnd = (r32)(Record->EndCycles - FrameStartCycles) / (r32)FrameTotalCycles;
|
|
||||||
|
|
||||||
v2 ScopeMin = v2{Min.x + (Width * PercentStart), Max.y - ((Record->CallDepth + 1) * DepthHeight)};
|
|
||||||
v2 ScopeMax = v2{Min.x + (Width * PercentEnd), ScopeMin.y + (DepthHeight - 4)};
|
|
||||||
|
|
||||||
if ((ScopeMax.x - ScopeMin.x) >= 1)
|
|
||||||
{
|
|
||||||
v4 Color = ThreadColors[0];
|
|
||||||
if (PointIsInRange(Mouse.Pos, ScopeMin, ScopeMax))
|
|
||||||
{
|
|
||||||
Color = GreenV4;
|
|
||||||
}
|
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, ScopeMin, ScopeMax, Color);
|
|
||||||
PushRenderBoundingBox2D(RenderBuffer, ScopeMin, ScopeMax, 1, BlackV4);
|
|
||||||
|
|
||||||
if (PointIsInRange(Mouse.Pos, ScopeMin, ScopeMax))
|
|
||||||
{
|
|
||||||
PushRenderQuad2D(RenderBuffer, Mouse.Pos, Mouse.Pos + v2{256, 32}, BlackV4);
|
|
||||||
PrintF(&String, "%.*s : %d - %d", Name->Name.Length, Name->Name.Memory, Record->StartCycles, Record->EndCycles);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, Mouse.Pos, WhiteV4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
RenderProfiler_ListVisualization(render_command_buffer* RenderBuffer,
|
|
||||||
interface_config Interface, mouse_state Mouse,
|
|
||||||
v2 Min, v2 Max,
|
|
||||||
debug_frame* VisibleFrame, memory_arena* Memory)
|
|
||||||
{
|
|
||||||
MakeStringBuffer(String, 256);
|
|
||||||
|
|
||||||
r32 YAt = Max.y - Interface.Font->PixelHeight;
|
|
||||||
r32 Column0X = Min.x;
|
|
||||||
r32 Column1X = Column0X + 256;
|
|
||||||
r32 Column2X = Column1X + 128;
|
|
||||||
r32 Column3X = Column2X + 128;
|
|
||||||
r32 Column4X = Column3X + 100;
|
|
||||||
|
|
||||||
for (s32 n = 0; n < VisibleFrame->ScopeNamesMax; n++)
|
|
||||||
{
|
|
||||||
scope_name NameEntry = VisibleFrame->ScopeNamesHash[n];
|
|
||||||
if (NameEntry.Hash != 0)
|
|
||||||
{
|
|
||||||
collated_scope_record* CollatedRecord = VisibleFrame->CollatedScopes + n;
|
|
||||||
|
|
||||||
PrintF(&String, "%.*s", NameEntry.Name.Length, NameEntry.Name.Memory);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, v2{Column0X, YAt}, WhiteV4);
|
|
||||||
|
|
||||||
PrintF(&String, "%f", CollatedRecord->PercentFrameTime);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, v2{Column1X, YAt}, WhiteV4);
|
|
||||||
|
|
||||||
PrintF(&String, "%fs", CollatedRecord->TotalSeconds);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, v2{Column2X, YAt}, WhiteV4);
|
|
||||||
|
|
||||||
PrintF(&String, "%dcy", CollatedRecord->TotalCycles);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, v2{Column3X, YAt}, WhiteV4);
|
|
||||||
|
|
||||||
PrintF(&String, "%d calls", CollatedRecord->CallCount);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, v2{Column4X, YAt}, WhiteV4);
|
|
||||||
|
|
||||||
YAt -= Interface.Font->PixelHeight + 4;
|
|
||||||
|
|
||||||
if (YAt < Min.y) { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
DrawDebugFrameList (render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, v2 BoundsMin, v2 BoundsMax, memory_arena* Memory)
|
|
||||||
{
|
|
||||||
string String = InitializeEmptyString(PushArray(Memory, char, 256), 256);
|
|
||||||
|
|
||||||
v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 };
|
|
||||||
|
|
||||||
r32 FrameListHeight = 64;
|
|
||||||
v2 FrameListMin = v2{BoundsMin.x + 16, BoundsMax.y - (16 + FrameListHeight)};
|
|
||||||
v2 FrameListMax = v2{BoundsMax.x - 16, BoundsMax.y - 16};
|
|
||||||
|
|
||||||
r32 FrameListPadding = 4;
|
|
||||||
r32 FrameListInnerWidth = (FrameListMax.x - FrameListMin.x) - (FrameListPadding * 2);
|
|
||||||
|
|
||||||
r32 SingleFrameStep = FrameListInnerWidth / DEBUG_FRAME_COUNT;
|
|
||||||
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
|
|
||||||
|
|
||||||
PushRenderBoundingBox2D(RenderBuffer, FrameListMin, FrameListMax, 2, WhiteV4);
|
|
||||||
|
|
||||||
if (PointIsInRange(Mouse.Pos, FrameListMin, FrameListMax) &&
|
|
||||||
MouseButtonHeldDown(Mouse.LeftButtonState))
|
|
||||||
{
|
|
||||||
r32 LocalMouseX = (Mouse.Pos.x - FrameListMin.x) + FrameListPadding;
|
|
||||||
s32 ClosestFrameIndex = (LocalMouseX / SingleFrameStep);
|
|
||||||
|
|
||||||
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
|
|
||||||
{
|
|
||||||
GlobalDebugServices->RecordFrames = false;
|
|
||||||
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
|
|
||||||
{
|
|
||||||
v2 Min = v2{FrameListMin.x + FrameListPadding + (F * SingleFrameStep), FrameListMin.y + 4};
|
|
||||||
v2 Max = v2{Min.x + SingleFrameWidth, FrameListMax.y - 4};
|
|
||||||
|
|
||||||
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
|
|
||||||
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
|
|
||||||
v4 Color = FrameColors[GSClamp(0, FramesAgo, 3)];
|
|
||||||
PushRenderQuad2D(RenderBuffer, Min, Max, Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices);
|
|
||||||
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
|
||||||
s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles;
|
|
||||||
|
|
||||||
PrintF(&String, "Frame %d - Total Cycles: %lld",
|
|
||||||
GlobalDebugServices->CurrentDebugFrame - 1,
|
|
||||||
FrameTotalCycles);
|
|
||||||
DrawString(RenderBuffer, String, Interface.Font, FrameListMin - v2{0, 32}, WhiteV4);
|
|
||||||
|
|
||||||
v2 ButtonMin = v2{FrameListMax.x - 128, FrameListMin.y - 32};
|
|
||||||
v2 ButtonMax = ButtonMin + v2{128, 28};
|
|
||||||
button_result ShouldResumeRecording = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
|
||||||
MakeString("Resume Recording"), Interface, Mouse);
|
|
||||||
if (ShouldResumeRecording.Pressed)
|
|
||||||
{
|
|
||||||
GlobalDebugServices->RecordFrames = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ButtonMin = v2{FrameListMin.x, FrameListMin.y - 60};
|
|
||||||
ButtonMax = v2{FrameListMin.x + 128, FrameListMin.y - 42};
|
|
||||||
button_result ActivateScopeView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
|
||||||
MakeString("Scope View"), Interface, Mouse);
|
|
||||||
|
|
||||||
ButtonMin.x += 152;
|
|
||||||
ButtonMax.x += 152;
|
|
||||||
button_result ActivateListView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
|
||||||
MakeString("List View"), Interface, Mouse);
|
|
||||||
|
|
||||||
if (ActivateScopeView.Pressed) { GlobalDebugServices->Interface.FrameView = FRAME_VIEW_PROFILER; }
|
|
||||||
if (ActivateListView.Pressed) { GlobalDebugServices->Interface.FrameView = FRAME_VIEW_SCOPE_LIST; }
|
|
||||||
|
|
||||||
v2 ViewModeMin = v2{FrameListMin.x, BoundsMin.y};
|
|
||||||
v2 ViewModeMax = v2{FrameListMax.x, FrameListMin.y - 96};
|
|
||||||
|
|
||||||
if (GlobalDebugServices->Interface.FrameView == FRAME_VIEW_PROFILER)
|
|
||||||
{
|
|
||||||
RenderProfiler_ScopeVisualization(RenderBuffer, Interface, Mouse,
|
|
||||||
ViewModeMin, ViewModeMax,
|
|
||||||
VisibleFrame, Memory);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RenderProfiler_ListVisualization(RenderBuffer, Interface, Mouse,
|
|
||||||
ViewModeMin, ViewModeMax,
|
|
||||||
VisibleFrame, Memory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_config Interface, r32 WindowWidth, r32 WindowHeight, r32 DeltaTime, app_state* State, camera Camera, mouse_state Mouse, memory_arena* Transient)
|
DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_config Interface, r32 WindowWidth, r32 WindowHeight, r32 DeltaTime, app_state* State, camera Camera, mouse_state Mouse, memory_arena* Transient)
|
||||||
{
|
{
|
||||||
|
@ -198,8 +6,6 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
v2 TopOfDebugView = v2{StartX, WindowHeight - (NewLineYOffset(*Interface.Font) + 5)};
|
v2 TopOfDebugView = v2{StartX, WindowHeight - (NewLineYOffset(*Interface.Font) + 5)};
|
||||||
v2 TopOfScreenLinePos = TopOfDebugView;
|
v2 TopOfScreenLinePos = TopOfDebugView;
|
||||||
|
|
||||||
//arena_snapshot StartTempMemory = TakeSnapshotOfArena(*Transient);
|
|
||||||
|
|
||||||
string DebugString = InitializeEmptyString(PushArray(Transient, char, 256), 256);
|
string DebugString = InitializeEmptyString(PushArray(Transient, char, 256), 256);
|
||||||
|
|
||||||
if (GlobalDebugServices->Interface.ShowCameraMouse)
|
if (GlobalDebugServices->Interface.ShowCameraMouse)
|
||||||
|
@ -306,55 +112,4 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
TopOfScreenLinePos, WhiteV4);
|
TopOfScreenLinePos, WhiteV4);
|
||||||
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GlobalDebugServices->Interface.ShowTrackedScopes)
|
|
||||||
{
|
|
||||||
v2 ProfilerMin = v2{TopOfDebugView.x, TopOfDebugView.y - 500};
|
|
||||||
v2 ProfilerMax = v2{TopOfDebugView.x + 700, TopOfDebugView.y - 64};
|
|
||||||
PushRenderQuad2D(RenderBuffer, ProfilerMin, ProfilerMax, v4{0, 0, 0, .8f});
|
|
||||||
//DrawDebugFrameList(RenderBuffer, Interface, Mouse, ProfilerMin, ProfilerMax, Transient);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
r32 ColumnsStartX = TopOfScreenLinePos.x;
|
|
||||||
for (s32 i = 0; i < GlobalDebugServices->ScopeHistogramUsed; i++)
|
|
||||||
{
|
|
||||||
v2 Register = v2{ColumnsStartX, TopOfScreenLinePos.y};
|
|
||||||
|
|
||||||
s32 CurrentFrame = GlobalDebugServices->ScopeHistogramSorted[i].CurrentFrame - 1;
|
|
||||||
if (CurrentFrame < 0) { CurrentFrame = HISTOGRAM_DEPTH - 1; }
|
|
||||||
|
|
||||||
u64 CyclesPerHit = GlobalDebugServices->ScopeHistogramSorted[i].PerFrame_Cycles[CurrentFrame];
|
|
||||||
r32 SecondsPerHit = (r32)CyclesPerHit / (r32)GlobalDebugServices->PerformanceCountFrequency;
|
|
||||||
|
|
||||||
// Column 1
|
|
||||||
PrintF(&DebugString, "%.*s",
|
|
||||||
GlobalDebugServices->ScopeHistogramSorted[i].ScopeName.Length,
|
|
||||||
GlobalDebugServices->ScopeHistogramSorted[i].ScopeName.Memory);
|
|
||||||
r32 ColumnOneX = DrawString(RenderBuffer, DebugString, Interface.Font,
|
|
||||||
Register, WhiteV4).x;
|
|
||||||
Register.x += GSMax(ColumnOneX - Register.x, 250.f);
|
|
||||||
|
|
||||||
// Column 2
|
|
||||||
PrintF(&DebugString, "%d hits", GlobalDebugServices->ScopeHistogramSorted[i].PerFrame_CallCount[CurrentFrame]);
|
|
||||||
r32 ColumnTwoX = DrawString(RenderBuffer, DebugString, Interface.Font,
|
|
||||||
Register, WhiteV4).x;
|
|
||||||
Register.x += GSMax(ColumnTwoX - Register.x, 150.f);
|
|
||||||
|
|
||||||
// Column 3
|
|
||||||
PrintF(&DebugString, "%lld cycles", CyclesPerHit);
|
|
||||||
r32 ColumnThreeX = DrawString(RenderBuffer, DebugString, Interface.Font,
|
|
||||||
Register, WhiteV4).x;
|
|
||||||
Register.x += GSMax(ColumnThreeX - Register.x, 200.f);
|
|
||||||
|
|
||||||
PrintF(&DebugString, "%f sec", SecondsPerHit);
|
|
||||||
r32 ColumnFourX = DrawString(RenderBuffer, DebugString, Interface.Font,
|
|
||||||
Register, WhiteV4).x;
|
|
||||||
Register.x += GSMax(ColumnFourX - Register.x, 200.f);
|
|
||||||
|
|
||||||
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,47 +127,3 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenUniverseView)
|
||||||
OpState->DisplayOffset = v2{0, 0};
|
OpState->DisplayOffset = v2{0, 0};
|
||||||
OpState->Zoom = 1.0f;
|
OpState->Zoom = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// 3D View Mouse Rotate
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
struct mouse_rotate_view_operation_state
|
|
||||||
{
|
|
||||||
v4 CameraStartPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(Update3DViewMouseRotate)
|
|
||||||
{
|
|
||||||
mouse_rotate_view_operation_state* OpState = (mouse_rotate_view_operation_state*)Operation.OpStateMemory;
|
|
||||||
|
|
||||||
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
|
|
||||||
|
|
||||||
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale);
|
|
||||||
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale);
|
|
||||||
m44 Combined = XRotation * YRotation;
|
|
||||||
|
|
||||||
State->Camera.Position = V3(Combined * OpState->CameraStartPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
|
|
||||||
{
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command MouseRotateViewCommands [] = {
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, End3DViewMouseRotate},
|
|
||||||
};
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
|
|
||||||
{
|
|
||||||
operation_mode* RotateViewMode = ActivateOperationModeWithCommands(&State->Modes, MouseRotateViewCommands);
|
|
||||||
RotateViewMode->Render = Update3DViewMouseRotate;
|
|
||||||
|
|
||||||
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
|
|
||||||
&State->Modes,
|
|
||||||
mouse_rotate_view_operation_state);
|
|
||||||
OpState->CameraStartPos = V4(State->Camera.Position, 1);
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ typedef struct panel panel;
|
||||||
enum panel_split_direction
|
enum panel_split_direction
|
||||||
{
|
{
|
||||||
PanelSplit_NoSplit,
|
PanelSplit_NoSplit,
|
||||||
PanelSplit_Horizontal,
|
PanelSplit_Horizontal,
|
||||||
PanelSplit_Vertical,
|
PanelSplit_Vertical,
|
||||||
|
|
||||||
PanelSplit_Count,
|
PanelSplit_Count,
|
||||||
|
@ -35,13 +35,13 @@ struct panel
|
||||||
b32 PanelSelectionMenuOpen;
|
b32 PanelSelectionMenuOpen;
|
||||||
|
|
||||||
union{
|
union{
|
||||||
panel_entry* Left;
|
panel_entry* Left;
|
||||||
panel_entry* Top;
|
panel_entry* Top;
|
||||||
};
|
};
|
||||||
union{
|
union{
|
||||||
panel_entry* Right;
|
panel_entry* Right;
|
||||||
panel_entry* Bottom;
|
panel_entry* Bottom;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct free_panel
|
struct free_panel
|
||||||
|
@ -52,16 +52,16 @@ struct free_panel
|
||||||
struct panel_entry
|
struct panel_entry
|
||||||
{
|
{
|
||||||
panel Panel;
|
panel Panel;
|
||||||
free_panel Free;
|
free_panel Free;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PANELS_MAX 16
|
#define PANELS_MAX 16
|
||||||
struct panel_layout
|
struct panel_layout
|
||||||
{
|
{
|
||||||
panel_entry Panels[PANELS_MAX];
|
panel_entry Panels[PANELS_MAX];
|
||||||
u32 PanelsUsed;
|
u32 PanelsUsed;
|
||||||
|
|
||||||
panel_entry FreeList;
|
panel_entry FreeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void SetPanelDefinitionExternal(panel* Panel, s32 OldPanelDefinitionIndex, s32 NewPanelDefinitionIndex);
|
internal void SetPanelDefinitionExternal(panel* Panel, s32 OldPanelDefinitionIndex, s32 NewPanelDefinitionIndex);
|
||||||
|
@ -102,9 +102,9 @@ TakeNewPanel(panel_layout* Layout)
|
||||||
{
|
{
|
||||||
panel* Result = 0;
|
panel* Result = 0;
|
||||||
panel_entry* FreeEntry = TakeNewPanelEntry(Layout);
|
panel_entry* FreeEntry = TakeNewPanelEntry(Layout);
|
||||||
Result = &FreeEntry->Panel;
|
Result = &FreeEntry->Panel;
|
||||||
|
|
||||||
*Result = {0};
|
*Result = {0};
|
||||||
Result->PanelDefinitionIndex = -1;
|
Result->PanelDefinitionIndex = -1;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -129,35 +129,35 @@ FreePanelAtIndex(s32 Index, panel_layout* Layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
SplitPanelVertically(panel* Parent, r32 Percent, v2 ParentMin, v2 ParentMax, panel_layout* Layout)
|
SplitPanelVertically(panel* Parent, r32 Percent, rect ParentBounds, panel_layout* Layout)
|
||||||
{
|
{
|
||||||
r32 SplitX = GSLerp(ParentMin.x, ParentMax.x, Percent);
|
r32 SplitX = GSLerp(ParentBounds.Min.x, ParentBounds.Max.x, Percent);
|
||||||
if (SplitX > ParentMin.x && SplitX < ParentMax.x)
|
if (SplitX > ParentBounds.Min.x && SplitX < ParentBounds.Max.x)
|
||||||
{
|
{
|
||||||
Parent->SplitDirection = PanelSplit_Vertical;
|
Parent->SplitDirection = PanelSplit_Vertical;
|
||||||
Parent->SplitPercent = Percent;
|
Parent->SplitPercent = Percent;
|
||||||
|
|
||||||
Parent->Left = TakeNewPanelEntry(Layout);
|
Parent->Left = TakeNewPanelEntry(Layout);
|
||||||
Parent->Left->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
Parent->Left->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||||
|
|
||||||
Parent->Right = TakeNewPanelEntry(Layout);
|
Parent->Right = TakeNewPanelEntry(Layout);
|
||||||
Parent->Right->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
Parent->Right->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
SplitPanelHorizontally(panel* Parent, r32 Percent, v2 ParentMin, v2 ParentMax, panel_layout* Layout)
|
SplitPanelHorizontally(panel* Parent, r32 Percent, rect ParentBounds, panel_layout* Layout)
|
||||||
{
|
{
|
||||||
r32 SplitY = GSLerp(ParentMin.y, ParentMax.y, Percent);
|
r32 SplitY = GSLerp(ParentBounds.Min.y, ParentBounds.Max.y, Percent);
|
||||||
if (SplitY > ParentMin.y && SplitY < ParentMax.y)
|
if (SplitY > ParentBounds.Min.y && SplitY < ParentBounds.Max.y)
|
||||||
{
|
{
|
||||||
Parent->SplitDirection = PanelSplit_Horizontal;
|
Parent->SplitDirection = PanelSplit_Horizontal;
|
||||||
Parent->SplitPercent = Percent;
|
Parent->SplitPercent = Percent;
|
||||||
|
|
||||||
Parent->Bottom = TakeNewPanelEntry(Layout);
|
Parent->Bottom = TakeNewPanelEntry(Layout);
|
||||||
Parent->Bottom->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
Parent->Bottom->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||||
|
|
||||||
Parent->Top = TakeNewPanelEntry(Layout);
|
Parent->Top = TakeNewPanelEntry(Layout);
|
||||||
Parent->Top->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
Parent->Top->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,91 +182,203 @@ SetPanelDefinition(panel* Panel, s32 NewDefinitionIndex)
|
||||||
Panel->PanelDefinitionIndex = NewDefinitionIndex;
|
Panel->PanelDefinitionIndex = NewDefinitionIndex;
|
||||||
SetPanelDefinitionExternal(Panel, OldDefinitionIndex, NewDefinitionIndex);
|
SetPanelDefinitionExternal(Panel, OldDefinitionIndex, NewDefinitionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
//
|
//
|
||||||
// Rendering And Interaction
|
// Rendering And Interaction
|
||||||
//
|
//
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
internal rect
|
||||||
|
GetTopPanelBounds(panel* Panel, rect PanelBounds)
|
||||||
|
{
|
||||||
|
rect Result = {};
|
||||||
|
Result.Min = v2{
|
||||||
|
PanelBounds.Min.x,
|
||||||
|
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent)
|
||||||
|
};
|
||||||
|
Result.Max = PanelBounds.Max;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal rect
|
||||||
|
GetBottomPanelBounds(panel* Panel, rect PanelBounds)
|
||||||
|
{
|
||||||
|
rect Result = {};
|
||||||
|
Result.Min = PanelBounds.Min;
|
||||||
|
Result.Max = v2{
|
||||||
|
PanelBounds.Max.x,
|
||||||
|
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent)
|
||||||
|
};
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal rect
|
||||||
|
GetRightPanelBounds(panel* Panel, rect PanelBounds)
|
||||||
|
{
|
||||||
|
rect Result = {};
|
||||||
|
Result.Min = v2{
|
||||||
|
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent),
|
||||||
|
PanelBounds.Min.y
|
||||||
|
};
|
||||||
|
Result.Max = PanelBounds.Max;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal rect
|
||||||
|
GetLeftPanelBounds(panel* Panel, rect PanelBounds)
|
||||||
|
{
|
||||||
|
rect Result = {};
|
||||||
|
Result.Min = PanelBounds.Min;
|
||||||
|
Result.Max = v2{
|
||||||
|
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent),
|
||||||
|
PanelBounds.Max.y
|
||||||
|
};
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct panel_and_bounds
|
||||||
|
{
|
||||||
|
panel* Panel;
|
||||||
|
rect Bounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal panel_and_bounds
|
||||||
|
GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
|
||||||
|
{
|
||||||
|
panel_and_bounds Result = {0};
|
||||||
|
|
||||||
|
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
||||||
|
{
|
||||||
|
Result.Panel = Panel;
|
||||||
|
Result.Bounds = PanelBounds;
|
||||||
|
}
|
||||||
|
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||||
|
{
|
||||||
|
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||||
|
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||||
|
|
||||||
|
if (PointIsInRange(Point, TopPanelBounds.Min, TopPanelBounds.Max))
|
||||||
|
{
|
||||||
|
Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds);
|
||||||
|
}
|
||||||
|
else if (PointIsInRange(Point, BottomPanelBounds.Min, BottomPanelBounds.Max))
|
||||||
|
{
|
||||||
|
Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
|
{
|
||||||
|
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||||
|
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||||
|
|
||||||
|
if (PointIsInRange(Point, LeftPanelBounds.Min, LeftPanelBounds.Max))
|
||||||
|
{
|
||||||
|
Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds);
|
||||||
|
}
|
||||||
|
else if (PointIsInRange(Point, RightPanelBounds.Min, RightPanelBounds.Max))
|
||||||
|
{
|
||||||
|
Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal panel_and_bounds
|
||||||
|
GetPanelContainingPoint(v2 Point, panel_layout* Layout, rect WindowBounds)
|
||||||
|
{
|
||||||
|
panel_and_bounds Result = {0};
|
||||||
|
if (Layout->PanelsUsed > 0)
|
||||||
|
{
|
||||||
|
Result = GetPanelContainingPoint(Point, &Layout->Panels[0].Panel, WindowBounds);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
HandleMousePanelInteractionOrRecurse(panel* Panel, v2 PanelMin, v2 PanelMax, panel_layout* PanelLayout, mouse_state Mouse)
|
HandleMousePanelInteractionOrRecurse(panel* Panel, rect PanelBounds, panel_layout* PanelLayout, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
r32 PanelEdgeClickMaxDistance = 4;
|
r32 PanelEdgeClickMaxDistance = 4;
|
||||||
|
|
||||||
// TODO(Peter): Need a way to calculate this button's position more systemically
|
// TODO(Peter): Need a way to calculate this button's position more systemically
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit
|
if (Panel->SplitDirection == PanelSplit_NoSplit
|
||||||
&& PointIsInRange(Mouse.DownPos, PanelMin, PanelMin + v2{25, 25}))
|
&& PointIsInRange(Mouse.DownPos, PanelBounds.Min, PanelBounds.Min + v2{25, 25}))
|
||||||
{
|
{
|
||||||
r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
|
r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
|
||||||
r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
|
r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
|
||||||
|
|
||||||
if (XDistance > YDistance)
|
if (XDistance > YDistance)
|
||||||
{
|
{
|
||||||
r32 XPercent = (Mouse.Pos.x - PanelMin.x) / (PanelMax.x - PanelMin.x);
|
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Width(PanelBounds);
|
||||||
SplitPanelVertically(Panel, XPercent, PanelMin, PanelMax, PanelLayout);
|
SplitPanelVertically(Panel, XPercent, PanelBounds, PanelLayout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r32 YPercent = (Mouse.Pos.y - PanelMin.y) / (PanelMax.y - PanelMin.y);
|
r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Height(PanelBounds);
|
||||||
SplitPanelHorizontally(Panel, YPercent, PanelMin, PanelMax, PanelLayout);
|
SplitPanelHorizontally(Panel, YPercent, PanelBounds, PanelLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
r32 SplitY = GSLerp(PanelMin.y, PanelMax.y, Panel->SplitPercent);
|
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent);
|
||||||
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY);
|
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY);
|
||||||
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
|
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
|
||||||
{
|
{
|
||||||
r32 NewSplitY = Mouse.Pos.y;
|
r32 NewSplitY = Mouse.Pos.y;
|
||||||
if (NewSplitY <= PanelMin.y)
|
if (NewSplitY <= PanelBounds.Min.y)
|
||||||
{
|
{
|
||||||
ConsolidatePanelsKeepOne(Panel, Panel->Top, PanelLayout);
|
ConsolidatePanelsKeepOne(Panel, Panel->Top, PanelLayout);
|
||||||
}
|
}
|
||||||
else if (NewSplitY >= PanelMax.y)
|
else if (NewSplitY >= PanelBounds.Max.y)
|
||||||
{
|
{
|
||||||
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, PanelLayout);
|
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, PanelLayout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Panel->SplitPercent = (NewSplitY - PanelMin.y) / (PanelMax.y - PanelMin.y);
|
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Height(PanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandleMousePanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelMin, v2{PanelMax.x, SplitY}, PanelLayout, Mouse);
|
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||||
HandleMousePanelInteractionOrRecurse(&Panel->Top->Panel, v2{PanelMin.x, SplitY}, PanelMax, PanelLayout, Mouse);
|
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||||
|
HandleMousePanelInteractionOrRecurse(&Panel->Bottom->Panel, BottomPanelBounds, PanelLayout, Mouse);
|
||||||
|
HandleMousePanelInteractionOrRecurse(&Panel->Top->Panel, TopPanelBounds, PanelLayout, Mouse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
r32 SplitX = GSLerp(PanelMin.x, PanelMax.x, Panel->SplitPercent);
|
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent);
|
||||||
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX);
|
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX);
|
||||||
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
|
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
|
||||||
{
|
{
|
||||||
r32 NewSplitX = Mouse.Pos.x;
|
r32 NewSplitX = Mouse.Pos.x;
|
||||||
if (NewSplitX <= PanelMin.x)
|
if (NewSplitX <= PanelBounds.Min.x)
|
||||||
{
|
{
|
||||||
ConsolidatePanelsKeepOne(Panel, Panel->Right, PanelLayout);
|
ConsolidatePanelsKeepOne(Panel, Panel->Right, PanelLayout);
|
||||||
}
|
}
|
||||||
else if (NewSplitX >= PanelMax.x)
|
else if (NewSplitX >= PanelBounds.Max.x)
|
||||||
{
|
{
|
||||||
ConsolidatePanelsKeepOne(Panel, Panel->Left, PanelLayout);
|
ConsolidatePanelsKeepOne(Panel, Panel->Left, PanelLayout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Panel->SplitPercent = (NewSplitX - PanelMin.x) / (PanelMax.x - PanelMin.x);
|
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Width(PanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandleMousePanelInteractionOrRecurse(&Panel->Left->Panel, PanelMin, v2{SplitX, PanelMax.y}, PanelLayout, Mouse);
|
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||||
HandleMousePanelInteractionOrRecurse(&Panel->Right->Panel, v2{SplitX, PanelMin.y}, PanelMax, PanelLayout, Mouse);
|
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||||
|
HandleMousePanelInteractionOrRecurse(&Panel->Left->Panel, LeftPanelBounds, PanelLayout, Mouse);
|
||||||
|
HandleMousePanelInteractionOrRecurse(&Panel->Right->Panel, RightPanelBounds, PanelLayout, Mouse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
HandleMousePanelInteraction(panel_layout* PanelLayout, v2 WindowMin, v2 WindowMax, mouse_state Mouse)
|
HandleMousePanelInteraction(panel_layout* PanelLayout, rect WindowBounds, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
r32 PanelEdgeClickMaxDistance = 4;
|
r32 PanelEdgeClickMaxDistance = 4;
|
||||||
|
|
||||||
|
@ -274,7 +386,7 @@ HandleMousePanelInteraction(panel_layout* PanelLayout, v2 WindowMin, v2 WindowMa
|
||||||
{
|
{
|
||||||
Assert(PanelLayout->PanelsUsed > 0);
|
Assert(PanelLayout->PanelsUsed > 0);
|
||||||
panel* FirstPanel = &PanelLayout->Panels[0].Panel;
|
panel* FirstPanel = &PanelLayout->Panels[0].Panel;
|
||||||
HandleMousePanelInteractionOrRecurse(FirstPanel, WindowMin, WindowMax, PanelLayout, Mouse);
|
HandleMousePanelInteractionOrRecurse(FirstPanel, WindowBounds, PanelLayout, Mouse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,41 +397,45 @@ DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, render_command_
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawPanelOrRecurse(panel* Panel, v2 PanelMin, v2 PanelMax, v2 WindowMin, v2 WindowMax, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context)
|
DrawPanelOrRecurse(panel* Panel, rect PanelBounds, rect WindowRect, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
||||||
{
|
{
|
||||||
RenderPanel(Panel, PanelMin, PanelMax, WindowMin, WindowMax, RenderBuffer, State, Context, Mouse);
|
RenderPanel(Panel, PanelBounds.Min, PanelBounds.Max, WindowRect.Min, WindowRect.Max, RenderBuffer, State, Context, Mouse);
|
||||||
v4 BorderColor = v4{0, 0, 0, 1};
|
v4 BorderColor = v4{0, 0, 0, 1};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (PointIsInRange(Mouse.Pos, PanelMin, PanelMax))
|
if (PointIsInRange(Mouse.Pos, PanelMin, PanelMax))
|
||||||
{
|
{
|
||||||
BorderColor = v4{1, 0, 1, 1};
|
BorderColor = v4{1, 0, 1, 1};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, WindowMin.x, WindowMin.y, WindowMax.x, WindowMax.y);
|
PushRenderOrthographic(RenderBuffer, WindowRect.Min.x, WindowRect.Min.y, WindowRect.Max.x, WindowRect.Max.y);
|
||||||
DrawPanelBorder(*Panel, PanelMin, PanelMax, BorderColor, RenderBuffer);
|
DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, RenderBuffer);
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
r32 SplitY = GSLerp(PanelMin.y, PanelMax.y, Panel->SplitPercent);
|
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||||
DrawPanelOrRecurse(&Panel->Bottom->Panel, PanelMin, v2{PanelMax.x, SplitY}, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||||
DrawPanelOrRecurse(&Panel->Top->Panel, v2{PanelMin.x, SplitY}, PanelMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
|
||||||
|
DrawPanelOrRecurse(&Panel->Bottom->Panel, BottomPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
|
||||||
|
DrawPanelOrRecurse(&Panel->Top->Panel, TopPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
r32 SplitX = GSLerp(PanelMin.x, PanelMax.x, Panel->SplitPercent);
|
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||||
DrawPanelOrRecurse(&Panel->Left->Panel, PanelMin, v2{SplitX, PanelMax.y}, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||||
DrawPanelOrRecurse(&Panel->Right->Panel, v2{SplitX, PanelMin.y}, PanelMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
|
||||||
|
DrawPanelOrRecurse(&Panel->Left->Panel, LeftPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
|
||||||
|
DrawPanelOrRecurse(&Panel->Right->Panel, RightPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawAllPanels(panel_layout PanelLayout, v2 WindowMin, v2 WindowMax, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context)
|
DrawAllPanels(panel_layout* PanelLayout, rect WindowBounds, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
Assert(PanelLayout.PanelsUsed > 0);
|
Assert(PanelLayout->PanelsUsed > 0);
|
||||||
panel* FirstPanel = &PanelLayout.Panels[0].Panel;
|
panel* FirstPanel = &PanelLayout->Panels[0].Panel;
|
||||||
DrawPanelOrRecurse(FirstPanel, WindowMin, WindowMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
DrawPanelOrRecurse(FirstPanel, WindowBounds, WindowBounds, RenderBuffer, Interface, Mouse, State, Context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,8 +122,7 @@ struct context
|
||||||
u32 MemorySize;
|
u32 MemorySize;
|
||||||
|
|
||||||
b32 WindowIsVisible;
|
b32 WindowIsVisible;
|
||||||
r32 WindowWidth;
|
rect WindowBounds;
|
||||||
r32 WindowHeight;
|
|
||||||
r32 DeltaTime;
|
r32 DeltaTime;
|
||||||
|
|
||||||
// Application Services
|
// Application Services
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct panel_definition
|
||||||
global_variable s32 GlobalPanelDefsCount = 5;
|
global_variable s32 GlobalPanelDefsCount = 5;
|
||||||
global_variable panel_definition GlobalPanelDefs[] = {
|
global_variable panel_definition GlobalPanelDefs[] = {
|
||||||
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands},
|
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands},
|
||||||
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, 0 },
|
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands },
|
||||||
{ "DMX View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, 0 },
|
{ "DMX View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, 0 },
|
||||||
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, 0 },
|
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, 0 },
|
||||||
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, 0 },
|
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, 0 },
|
||||||
|
|
|
@ -7,6 +7,62 @@
|
||||||
// [] - displaying multiple layers
|
// [] - displaying multiple layers
|
||||||
// [] -
|
// [] -
|
||||||
|
|
||||||
|
internal void
|
||||||
|
DeleteAnimationBlock(animation_block_handle AnimationBlockHandle, app_state* State)
|
||||||
|
{
|
||||||
|
RemoveAnimationBlock(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
|
||||||
|
State->SelectedAnimationBlockHandle = {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
SelectAnimationBlock(animation_block_handle BlockHandle, app_state* State)
|
||||||
|
{
|
||||||
|
State->SelectedAnimationBlockHandle = BlockHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
SelectAndBeginDragAnimationBlock(animation_block_handle BlockHandle, app_state* State)
|
||||||
|
{
|
||||||
|
SelectAnimationBlock(BlockHandle, State);
|
||||||
|
// TODO(Peter): Begin Dragging Mode
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
DeselectCurrentAnimationBlock(app_state* State)
|
||||||
|
{
|
||||||
|
State->SelectedAnimationBlockHandle = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
|
||||||
|
{
|
||||||
|
if (AnimationBlockHandleIsValid(State->SelectedAnimationBlockHandle))
|
||||||
|
{
|
||||||
|
DeleteAnimationBlock(State->SelectedAnimationBlockHandle, State);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(AddAnimationBlockCommand)
|
||||||
|
{
|
||||||
|
panel_and_bounds ActivePanel = GetPanelContainingPoint(Mouse.Pos, &State->PanelLayout, State->WindowBounds);
|
||||||
|
r32 MouseDownPositionPercent = (Mouse.Pos.x - ActivePanel.Bounds.Min.x) / Width(ActivePanel.Bounds);
|
||||||
|
r32 NewBlockTimeStart = MouseDownPositionPercent * State->AnimationSystem.AnimationEnd;
|
||||||
|
#define NEW_BLOCK_DURATION 1
|
||||||
|
r32 NewBlockTimeEnd = NewBlockTimeStart + NEW_BLOCK_DURATION;
|
||||||
|
|
||||||
|
animation_block Block = {0};
|
||||||
|
Block.StartTime = NewBlockTimeStart;
|
||||||
|
Block.EndTime = NewBlockTimeEnd;
|
||||||
|
Block.Proc = TestPatternThree;
|
||||||
|
|
||||||
|
animation_block_handle NewBlockHandle = AddAnimationBlock(Block, &State->AnimationSystem);
|
||||||
|
SelectAnimationBlock(NewBlockHandle, State);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command AnimationTimeline_Commands[] = {
|
||||||
|
{ KeyCode_X, KeyCode_Invalid, Command_Began, DeleteAnimationBlockCommand },
|
||||||
|
{ KeyCode_A, KeyCode_Invalid, Command_Began, AddAnimationBlockCommand },
|
||||||
|
};
|
||||||
|
|
||||||
PANEL_INIT_PROC(AnimationTimeline_Init)
|
PANEL_INIT_PROC(AnimationTimeline_Init)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -139,15 +195,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
|
||||||
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
MouseDownAndNotHandled = false;
|
MouseDownAndNotHandled = false;
|
||||||
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
SelectAndBeginDragAnimationBlock(CurrentBlockHandle, State);
|
||||||
{
|
|
||||||
// If the block is already selected, deselect it.
|
|
||||||
Result = {0};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = CurrentBlockHandle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,18 +219,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
|
||||||
|
|
||||||
if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, TimelineMin, TimelineMax))
|
if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, TimelineMin, TimelineMax))
|
||||||
{
|
{
|
||||||
r32 MouseDownPositionPercent = (Mouse.Pos.x - PanelMin.x) / AnimationPanelWidth;
|
DeselectCurrentAnimationBlock(State);
|
||||||
r32 NewBlockTimeStart = MouseDownPositionPercent * AnimationSystem->AnimationEnd;
|
|
||||||
#define NEW_BLOCK_DURATION 1
|
|
||||||
r32 NewBlockTimeEnd = NewBlockTimeStart + NEW_BLOCK_DURATION;
|
|
||||||
|
|
||||||
animation_block Block = {0};
|
|
||||||
Block.StartTime = NewBlockTimeStart;
|
|
||||||
Block.EndTime = NewBlockTimeEnd;
|
|
||||||
Block.Proc = TestPatternThree;
|
|
||||||
|
|
||||||
animation_block_handle NewBlockHandle = AddAnimationBlock(Block, AnimationSystem);
|
|
||||||
Result = NewBlockHandle;
|
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -245,6 +282,4 @@ PANEL_RENDER_PROC(AnimationTimeline_Render)
|
||||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||||
State->AnimationSystem.Time = 0;
|
State->AnimationSystem.Time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
State->SelectedAnimationBlockHandle = SelectedBlockHandle;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,46 @@
|
||||||
|
|
||||||
|
// 3D Mouse View
|
||||||
|
|
||||||
|
struct mouse_rotate_view_operation_state
|
||||||
|
{
|
||||||
|
v4 CameraStartPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(Update3DViewMouseRotate)
|
||||||
|
{
|
||||||
|
mouse_rotate_view_operation_state* OpState = (mouse_rotate_view_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
|
||||||
|
|
||||||
|
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale);
|
||||||
|
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale);
|
||||||
|
m44 Combined = XRotation * YRotation;
|
||||||
|
|
||||||
|
State->Camera.Position = V3(Combined * OpState->CameraStartPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
|
||||||
|
{
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command MouseRotateViewCommands [] = {
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, End3DViewMouseRotate},
|
||||||
|
};
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
|
||||||
|
{
|
||||||
|
operation_mode* RotateViewMode = ActivateOperationModeWithCommands(&State->Modes, MouseRotateViewCommands);
|
||||||
|
RotateViewMode->Render = Update3DViewMouseRotate;
|
||||||
|
|
||||||
|
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
|
||||||
|
&State->Modes,
|
||||||
|
mouse_rotate_view_operation_state);
|
||||||
|
OpState->CameraStartPos = V4(State->Camera.Position, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
|
||||||
input_command SculptureView_Commands[] = {
|
input_command SculptureView_Commands[] = {
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
|
||||||
};
|
};
|
||||||
|
@ -79,7 +122,7 @@ PANEL_RENDER_PROC(SculptureView_Render)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(RenderSculpture);
|
DEBUG_TRACK_SCOPE(RenderSculpture);
|
||||||
|
|
||||||
r32 PanelWidth = PanelMax.x - PanelMin.x;
|
r32 PanelWidth = PanelMax.x - PanelMin.x;
|
||||||
r32 PanelHeight = PanelMax.y - PanelMin.y;
|
r32 PanelHeight = PanelMax.y - PanelMin.y;
|
||||||
State->Camera.AspectRatio = PanelWidth / PanelHeight;
|
State->Camera.AspectRatio = PanelWidth / PanelHeight;
|
||||||
|
|
||||||
|
|
|
@ -488,11 +488,11 @@ Win32GetThreadId()
|
||||||
|
|
||||||
int WINAPI
|
int WINAPI
|
||||||
WinMain (
|
WinMain (
|
||||||
HINSTANCE HInstance,
|
HINSTANCE HInstance,
|
||||||
HINSTANCE HPrevInstance,
|
HINSTANCE HPrevInstance,
|
||||||
PSTR CmdLineArgs,
|
PSTR CmdLineArgs,
|
||||||
INT NCmdShow
|
INT NCmdShow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
||||||
Win32UpdateWindowDimension(&MainWindow);
|
Win32UpdateWindowDimension(&MainWindow);
|
||||||
|
@ -560,15 +560,14 @@ INT NCmdShow
|
||||||
context Context = {};
|
context Context = {};
|
||||||
Context.MemorySize = InitialMemorySize;
|
Context.MemorySize = InitialMemorySize;
|
||||||
Context.MemoryBase = InitialMemory;
|
Context.MemoryBase = InitialMemory;
|
||||||
Context.WindowWidth = MainWindow.Width;
|
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||||
Context.WindowHeight = MainWindow.Height;
|
|
||||||
|
|
||||||
// Platform functions
|
// Platform functions
|
||||||
Context.GeneralWorkQueue = &WorkQueue;
|
Context.GeneralWorkQueue = &WorkQueue;
|
||||||
Context.PlatformAlloc = Win32Alloc;
|
Context.PlatformAlloc = Win32Alloc;
|
||||||
Context.PlatformFree = Win32Free;
|
Context.PlatformFree = Win32Free;
|
||||||
Context.PlatformRealloc = Win32Realloc;
|
Context.PlatformRealloc = Win32Realloc;
|
||||||
Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
||||||
Context.PlatformWriteEntireFile = Win32WriteEntireFile;
|
Context.PlatformWriteEntireFile = Win32WriteEntireFile;
|
||||||
Context.PlatformGetFilePath = Win32SystemDialogueOpenFile;
|
Context.PlatformGetFilePath = Win32SystemDialogueOpenFile;
|
||||||
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
||||||
|
@ -634,11 +633,7 @@ Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
||||||
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Mouse);
|
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Peter): We shouldn't need to do this translation. the platform layer knows about win32_windows. We should just make that the interface
|
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||||
// to all windows.
|
|
||||||
// TODO(Peter): Decide which we want to use, context or renderbuffer. Should only be one
|
|
||||||
Context.WindowWidth = MainWindow.Width;
|
|
||||||
Context.WindowHeight = MainWindow.Height;
|
|
||||||
RenderBuffer.ViewWidth = MainWindow.Width;
|
RenderBuffer.ViewWidth = MainWindow.Width;
|
||||||
RenderBuffer.ViewHeight = MainWindow.Height;
|
RenderBuffer.ViewHeight = MainWindow.Height;
|
||||||
Context.DeltaTime = LastFrameSecondsElapsed;
|
Context.DeltaTime = LastFrameSecondsElapsed;
|
||||||
|
|
14
todo.txt
14
todo.txt
|
@ -1,7 +1,12 @@
|
||||||
TODO FOLDHAUS
|
TODO FOLDHAUS
|
||||||
|
|
||||||
YOU WERE IN THE MIDDLE OF
|
Animation Timeline
|
||||||
|
- click to drag time marker
|
||||||
|
- drag ends of animation clips to change start and end times
|
||||||
|
-
|
||||||
|
|
||||||
|
Reimplement Node View
|
||||||
|
- probably want to take a fresh pass at nodes all together
|
||||||
|
|
||||||
Assembly -> SACN interface
|
Assembly -> SACN interface
|
||||||
x you need to rebuild the map from leds -> universes
|
x you need to rebuild the map from leds -> universes
|
||||||
|
@ -89,17 +94,14 @@ Resource Management
|
||||||
- Icons
|
- Icons
|
||||||
|
|
||||||
Animation
|
Animation
|
||||||
- timeline
|
x timeline
|
||||||
- create clips that play
|
x create clips that play
|
||||||
- clips can have parameters that drive them?
|
- clips can have parameters that drive them?
|
||||||
- clips should have prerequesites
|
- clips should have prerequesites
|
||||||
- - channels active
|
- - channels active
|
||||||
- - patterns active in the channel
|
- - patterns active in the channel
|
||||||
- - when a clip is playing, it should just take over the whole structure
|
- - when a clip is playing, it should just take over the whole structure
|
||||||
|
|
||||||
Command Line
|
|
||||||
- select a channel/pattern
|
|
||||||
|
|
||||||
Optimization
|
Optimization
|
||||||
- investigate the memory access pattern of the SACN / LED systems. Guessing they are very slow
|
- investigate the memory access pattern of the SACN / LED systems. Guessing they are very slow
|
||||||
- look into why debug logging functions seems to incur a large hit on framrate
|
- look into why debug logging functions seems to incur a large hit on framrate
|
||||||
|
|
Loading…
Reference in New Issue