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};
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, v2 FooterMin,
|
|||
}
|
||||
|
||||
|
||||
for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
||||
for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
||||
{
|
||||
panel_definition Def = GlobalPanelDefs[i];
|
||||
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,
|
||||
PanelSelectButtonMax,
|
||||
PanelSelectButtonMax,
|
||||
MakeStringLiteral("Select"), Interface, Mouse);
|
||||
if (ButtonResult.Pressed)
|
||||
{
|
||||
|
@ -68,26 +68,26 @@ RenderPanel(panel* Panel, v2 PanelMin, v2 PanelMax, v2 WindowMin, v2 WindowMax,
|
|||
{
|
||||
Assert(Panel->PanelDefinitionIndex >= 0);
|
||||
|
||||
v2 FooterMin = PanelMin;
|
||||
v2 FooterMin = PanelMin;
|
||||
v2 FooterMax = v2{PanelMax.x, PanelMin.y + 25};
|
||||
v2 PanelViewMin = v2{PanelMin.x, FooterMax.y};
|
||||
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);
|
||||
DrawPanelFooter(Panel, RenderBuffer, FooterMin, FooterMax, State->Interface, Mouse);
|
||||
PushRenderOrthographic(RenderBuffer, WindowMin.x, WindowMin.y, WindowMax.x, WindowMax.y);
|
||||
DrawPanelFooter(Panel, RenderBuffer, FooterMin, FooterMax, State->Interface, Mouse);
|
||||
}
|
||||
|
||||
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);
|
||||
r32 X = ((2.0f * MouseX) / WindowWidth) - 1;
|
||||
r32 Y = ((2.0f * MouseY) / WindowHeight) - 1;
|
||||
r32 X = ((2.0f * MouseX) / Width(WindowBounds)) - 1;
|
||||
r32 Y = ((2.0f * MouseY) / Height(WindowBounds)) - 1;
|
||||
|
||||
v4 ScreenPos = v4{X, Y, -1, 1};
|
||||
|
||||
|
@ -147,12 +147,6 @@ RELOAD_STATIC_DATA(ReloadStaticData)
|
|||
GlobalDebugServices = DebugServices;
|
||||
GSAlloc = Alloc;
|
||||
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)
|
||||
|
@ -165,8 +159,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
State->Transient.Alloc = (gs_memory_alloc*)Context.PlatformAlloc;
|
||||
State->Transient.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
||||
|
||||
InitializeInputCommandRegistry(&State->DefaultInputCommandRegistry, 32, &State->Permanent);
|
||||
|
||||
s32 CommandQueueSize = 32;
|
||||
command_queue_entry* CommandQueueMemory = PushArray(&State->Permanent,
|
||||
command_queue_entry,
|
||||
|
@ -223,7 +215,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
}
|
||||
|
||||
State->Interface.Font = Font;
|
||||
State->Font = Font;
|
||||
|
||||
Font->BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Font->BitmapMemory,
|
||||
Font->BitmapWidth, Font->BitmapHeight);
|
||||
|
@ -246,7 +237,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
||||
|
||||
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.Far = 100.0f;
|
||||
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.FindAddressRule = FindAddress_InLastBufferOnly;
|
||||
|
||||
{ // MODES PLAYGROUND
|
||||
{ // Animation PLAYGROUND
|
||||
InitializeAnimationSystem(&State->AnimationSystem);
|
||||
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||
|
||||
animation_block BlockOne = {0};
|
||||
BlockOne.StartTime = 0;
|
||||
|
@ -294,23 +285,33 @@ State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
|||
} // End Animation Playground
|
||||
|
||||
|
||||
{ // Panels Playground
|
||||
InitializePanelLayout(&State->PanelLayout);
|
||||
panel* Panel = TakeNewPanel(&State->PanelLayout);
|
||||
panel* Panel = TakeNewPanel(&State->PanelLayout);
|
||||
SetPanelDefinition(Panel, 0);
|
||||
} // End Panels Playground
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
input_command_registry ActiveCommands = State->DefaultInputCommandRegistry;
|
||||
input_command_registry ActiveCommands = {};
|
||||
if (State->Modes.ActiveModesCount > 0)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
|
@ -358,7 +359,7 @@ CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena)
|
|||
leds_in_universe_range LEDUniverseRange = Assembly.LEDUniverseMap[Range];
|
||||
|
||||
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.TotalSize = BufferSize;
|
||||
NewBuffer->Buffer.HeaderSize = BufferHeaderSize;
|
||||
|
@ -395,6 +396,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
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,
|
||||
// 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.
|
||||
ClearArena(&State->Transient);
|
||||
|
||||
HandleInput(State, InputQueue, Mouse);
|
||||
HandleInput(State, State->WindowBounds, InputQueue, Mouse);
|
||||
|
||||
if (State->AnimationSystem.TimelineShouldAdvance) {
|
||||
State->AnimationSystem.Time += Context.DeltaTime;
|
||||
|
@ -412,7 +414,7 @@ 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)
|
||||
{
|
||||
State->AnimationSystem.LastUpdatedFrame = CurrentFrame;
|
||||
|
@ -484,77 +486,11 @@ 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);
|
||||
v2 WindowMin = v2{0, 0};
|
||||
v2 WindowMax = v2{Context.WindowWidth, Context.WindowHeight};
|
||||
HandleMousePanelInteraction(&State->PanelLayout, WindowMin, WindowMax, Mouse);
|
||||
DrawAllPanels(State->PanelLayout, WindowMin, WindowMax, RenderBuffer, State->Interface, Mouse, State, Context);
|
||||
|
||||
////////////////////////////////
|
||||
// Render Assembly
|
||||
///////////////////////////////
|
||||
if (Context.WindowIsVisible)
|
||||
{
|
||||
#if 0
|
||||
///////////////////////////////////////
|
||||
// Interface
|
||||
//////////////////////////////////////
|
||||
|
||||
DEBUG_TRACK_SCOPE(DrawInterface);
|
||||
|
||||
PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Menu Bar
|
||||
//////////////////////////////////////
|
||||
r32 TopBarHeight = 40;
|
||||
{
|
||||
panel_result TopBarPanel = EvaluatePanel(RenderBuffer,
|
||||
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
|
||||
}
|
||||
HandleMousePanelInteraction(&State->PanelLayout, State->WindowBounds, Mouse);
|
||||
|
||||
DrawAllPanels(&State->PanelLayout, State->WindowBounds, RenderBuffer, State->Interface, Mouse, State, Context);
|
||||
|
||||
for (s32 m = 0; m < State->Modes.ActiveModesCount; m++)
|
||||
{
|
||||
|
@ -565,7 +501,6 @@ PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHe
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Checking for overflows
|
||||
{
|
||||
DEBUG_TRACK_SCOPE(OverflowChecks);
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
#include "foldhaus_node.h"
|
||||
#include "assembly_parser.cpp"
|
||||
#include "test_patterns.h"
|
||||
#include "foldhaus_interface.h"
|
||||
|
||||
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_command_dispatch.h"
|
||||
#include "foldhaus_command_dispatch.cpp"
|
||||
#include "foldhaus_operation_mode.h"
|
||||
|
||||
#include "animation/foldhaus_animation.h"
|
||||
|
@ -40,16 +40,17 @@ enum network_protocol
|
|||
|
||||
struct app_state
|
||||
{
|
||||
rect WindowBounds;
|
||||
|
||||
memory_arena Permanent;
|
||||
memory_arena Transient;
|
||||
|
||||
s32 NetworkProtocolHeaderSize;
|
||||
s32 NetworkProtocolHeaderSize;
|
||||
network_protocol NetworkProtocol;
|
||||
|
||||
streaming_acn SACN;
|
||||
|
||||
s32 TotalLEDsCount;
|
||||
|
||||
assembly_array AssemblyList;
|
||||
array_entry_handle_contiguous_array ActiveAssemblyIndecies;
|
||||
|
||||
|
@ -57,11 +58,9 @@ s32 NetworkProtocolHeaderSize;
|
|||
r32 PixelsToWorldScale;
|
||||
|
||||
operation_mode_system Modes;
|
||||
input_command_registry DefaultInputCommandRegistry;
|
||||
input_command_queue CommandQueue;
|
||||
text_entry ActiveTextEntry;
|
||||
|
||||
bitmap_font* Font;
|
||||
interface_config Interface;
|
||||
|
||||
animation_system AnimationSystem;
|
||||
|
@ -97,7 +96,7 @@ TestPatternTwo(assembly* Assembly, r32 Time)
|
|||
r32 PeriodicTime = (Time / PI) * 2;
|
||||
|
||||
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) };
|
||||
|
||||
v4 Center = v4{0, 0, 0, 1};
|
||||
|
@ -111,10 +110,10 @@ r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
|
|||
r32 OuterRadiusSquared = 1000000;
|
||||
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];
|
||||
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
||||
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
||||
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
||||
LEDIdx++)
|
||||
{
|
||||
|
@ -143,7 +142,7 @@ for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
|||
Assembly->Colors[LED.Index] = {};
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
Assembly->Colors[LED.Index] = {};
|
||||
}
|
||||
|
@ -154,7 +153,7 @@ else
|
|||
internal void
|
||||
TestPatternThree(assembly* Assembly, r32 Time)
|
||||
{
|
||||
r32 GreenSize = 20.0f;
|
||||
r32 GreenSize = 20.0f;
|
||||
r32 BlueSize = 25.0f;
|
||||
r32 RedSize = 25.0f;
|
||||
|
||||
|
@ -196,13 +195,10 @@ r32 GreenSize = 20.0f;
|
|||
|
||||
#include "foldhaus_assembly.cpp"
|
||||
|
||||
#include "foldhaus_debug_visuals.h"
|
||||
//#include "foldhaus_sacn_view.cpp"
|
||||
#include "foldhaus_text_entry.cpp"
|
||||
#include "foldhaus_search_lister.cpp"
|
||||
|
||||
#include "foldhaus_interface.cpp"
|
||||
#include "animation/foldhaus_animation_interface.h"
|
||||
|
||||
#define PANEL_INIT_PROC(name) void name(panel* Panel)
|
||||
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;
|
||||
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
|
||||
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 TopOfScreenLinePos = TopOfDebugView;
|
||||
|
||||
//arena_snapshot StartTempMemory = TakeSnapshotOfArena(*Transient);
|
||||
|
||||
string DebugString = InitializeEmptyString(PushArray(Transient, char, 256), 256);
|
||||
|
||||
if (GlobalDebugServices->Interface.ShowCameraMouse)
|
||||
|
@ -306,55 +112,4 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
|||
TopOfScreenLinePos, WhiteV4);
|
||||
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->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
|
||||
{
|
||||
PanelSplit_NoSplit,
|
||||
PanelSplit_Horizontal,
|
||||
PanelSplit_Horizontal,
|
||||
PanelSplit_Vertical,
|
||||
|
||||
PanelSplit_Count,
|
||||
|
@ -58,7 +58,7 @@ struct panel_entry
|
|||
#define PANELS_MAX 16
|
||||
struct panel_layout
|
||||
{
|
||||
panel_entry Panels[PANELS_MAX];
|
||||
panel_entry Panels[PANELS_MAX];
|
||||
u32 PanelsUsed;
|
||||
|
||||
panel_entry FreeList;
|
||||
|
@ -102,9 +102,9 @@ TakeNewPanel(panel_layout* Layout)
|
|||
{
|
||||
panel* Result = 0;
|
||||
panel_entry* FreeEntry = TakeNewPanelEntry(Layout);
|
||||
Result = &FreeEntry->Panel;
|
||||
Result = &FreeEntry->Panel;
|
||||
|
||||
*Result = {0};
|
||||
*Result = {0};
|
||||
Result->PanelDefinitionIndex = -1;
|
||||
|
||||
return Result;
|
||||
|
@ -129,35 +129,35 @@ FreePanelAtIndex(s32 Index, panel_layout* Layout)
|
|||
}
|
||||
|
||||
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);
|
||||
if (SplitX > ParentMin.x && SplitX < ParentMax.x)
|
||||
r32 SplitX = GSLerp(ParentBounds.Min.x, ParentBounds.Max.x, Percent);
|
||||
if (SplitX > ParentBounds.Min.x && SplitX < ParentBounds.Max.x)
|
||||
{
|
||||
Parent->SplitDirection = PanelSplit_Vertical;
|
||||
Parent->SplitDirection = PanelSplit_Vertical;
|
||||
Parent->SplitPercent = Percent;
|
||||
|
||||
Parent->Left = TakeNewPanelEntry(Layout);
|
||||
Parent->Left->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||
|
||||
Parent->Right = TakeNewPanelEntry(Layout);
|
||||
Parent->Right = TakeNewPanelEntry(Layout);
|
||||
Parent->Right->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (SplitY > ParentMin.y && SplitY < ParentMax.y)
|
||||
r32 SplitY = GSLerp(ParentBounds.Min.y, ParentBounds.Max.y, Percent);
|
||||
if (SplitY > ParentBounds.Min.y && SplitY < ParentBounds.Max.y)
|
||||
{
|
||||
Parent->SplitDirection = PanelSplit_Horizontal;
|
||||
Parent->SplitDirection = PanelSplit_Horizontal;
|
||||
Parent->SplitPercent = Percent;
|
||||
|
||||
Parent->Bottom = TakeNewPanelEntry(Layout);
|
||||
Parent->Bottom->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||
|
||||
Parent->Top = TakeNewPanelEntry(Layout);
|
||||
Parent->Top = TakeNewPanelEntry(Layout);
|
||||
Parent->Top->Panel.PanelDefinitionIndex = Parent->PanelDefinitionIndex;
|
||||
}
|
||||
}
|
||||
|
@ -182,91 +182,203 @@ SetPanelDefinition(panel* Panel, s32 NewDefinitionIndex)
|
|||
Panel->PanelDefinitionIndex = NewDefinitionIndex;
|
||||
SetPanelDefinitionExternal(Panel, OldDefinitionIndex, NewDefinitionIndex);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
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;
|
||||
|
||||
// TODO(Peter): Need a way to calculate this button's position more systemically
|
||||
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 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
|
||||
|
||||
if (XDistance > YDistance)
|
||||
{
|
||||
r32 XPercent = (Mouse.Pos.x - PanelMin.x) / (PanelMax.x - PanelMin.x);
|
||||
SplitPanelVertically(Panel, XPercent, PanelMin, PanelMax, PanelLayout);
|
||||
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Width(PanelBounds);
|
||||
SplitPanelVertically(Panel, XPercent, PanelBounds, PanelLayout);
|
||||
}
|
||||
else
|
||||
{
|
||||
r32 YPercent = (Mouse.Pos.y - PanelMin.y) / (PanelMax.y - PanelMin.y);
|
||||
SplitPanelHorizontally(Panel, YPercent, PanelMin, PanelMax, PanelLayout);
|
||||
r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Height(PanelBounds);
|
||||
SplitPanelHorizontally(Panel, YPercent, PanelBounds, PanelLayout);
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
|
||||
{
|
||||
r32 NewSplitY = Mouse.Pos.y;
|
||||
if (NewSplitY <= PanelMin.y)
|
||||
if (NewSplitY <= PanelBounds.Min.y)
|
||||
{
|
||||
ConsolidatePanelsKeepOne(Panel, Panel->Top, PanelLayout);
|
||||
}
|
||||
else if (NewSplitY >= PanelMax.y)
|
||||
else if (NewSplitY >= PanelBounds.Max.y)
|
||||
{
|
||||
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, PanelLayout);
|
||||
}
|
||||
else
|
||||
{
|
||||
Panel->SplitPercent = (NewSplitY - PanelMin.y) / (PanelMax.y - PanelMin.y);
|
||||
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Height(PanelBounds);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleMousePanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelMin, v2{PanelMax.x, SplitY}, PanelLayout, Mouse);
|
||||
HandleMousePanelInteractionOrRecurse(&Panel->Top->Panel, v2{PanelMin.x, SplitY}, PanelMax, PanelLayout, Mouse);
|
||||
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
|
||||
{
|
||||
r32 NewSplitX = Mouse.Pos.x;
|
||||
if (NewSplitX <= PanelMin.x)
|
||||
if (NewSplitX <= PanelBounds.Min.x)
|
||||
{
|
||||
ConsolidatePanelsKeepOne(Panel, Panel->Right, PanelLayout);
|
||||
}
|
||||
else if (NewSplitX >= PanelMax.x)
|
||||
else if (NewSplitX >= PanelBounds.Max.x)
|
||||
{
|
||||
ConsolidatePanelsKeepOne(Panel, Panel->Left, PanelLayout);
|
||||
}
|
||||
else
|
||||
{
|
||||
Panel->SplitPercent = (NewSplitX - PanelMin.x) / (PanelMax.x - PanelMin.x);
|
||||
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Width(PanelBounds);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleMousePanelInteractionOrRecurse(&Panel->Left->Panel, PanelMin, v2{SplitX, PanelMax.y}, PanelLayout, Mouse);
|
||||
HandleMousePanelInteractionOrRecurse(&Panel->Right->Panel, v2{SplitX, PanelMin.y}, PanelMax, PanelLayout, Mouse);
|
||||
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||
HandleMousePanelInteractionOrRecurse(&Panel->Left->Panel, LeftPanelBounds, PanelLayout, Mouse);
|
||||
HandleMousePanelInteractionOrRecurse(&Panel->Right->Panel, RightPanelBounds, PanelLayout, Mouse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -274,7 +386,7 @@ HandleMousePanelInteraction(panel_layout* PanelLayout, v2 WindowMin, v2 WindowMa
|
|||
{
|
||||
Assert(PanelLayout->PanelsUsed > 0);
|
||||
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
|
||||
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)
|
||||
{
|
||||
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};
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
if (PointIsInRange(Mouse.Pos, PanelMin, PanelMax))
|
||||
{
|
||||
BorderColor = v4{1, 0, 1, 1};
|
||||
}
|
||||
#endif
|
||||
|
||||
PushRenderOrthographic(RenderBuffer, WindowMin.x, WindowMin.y, WindowMax.x, WindowMax.y);
|
||||
DrawPanelBorder(*Panel, PanelMin, PanelMax, BorderColor, RenderBuffer);
|
||||
PushRenderOrthographic(RenderBuffer, WindowRect.Min.x, WindowRect.Min.y, WindowRect.Max.x, WindowRect.Max.y);
|
||||
DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, RenderBuffer);
|
||||
}
|
||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||
{
|
||||
r32 SplitY = GSLerp(PanelMin.y, PanelMax.y, Panel->SplitPercent);
|
||||
DrawPanelOrRecurse(&Panel->Bottom->Panel, PanelMin, v2{PanelMax.x, SplitY}, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
||||
DrawPanelOrRecurse(&Panel->Top->Panel, v2{PanelMin.x, SplitY}, PanelMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
||||
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||
|
||||
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)
|
||||
{
|
||||
r32 SplitX = GSLerp(PanelMin.x, PanelMax.x, Panel->SplitPercent);
|
||||
DrawPanelOrRecurse(&Panel->Left->Panel, PanelMin, v2{SplitX, PanelMax.y}, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
||||
DrawPanelOrRecurse(&Panel->Right->Panel, v2{SplitX, PanelMin.y}, PanelMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
||||
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||
|
||||
DrawPanelOrRecurse(&Panel->Left->Panel, LeftPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
|
||||
DrawPanelOrRecurse(&Panel->Right->Panel, RightPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
panel* FirstPanel = &PanelLayout.Panels[0].Panel;
|
||||
DrawPanelOrRecurse(FirstPanel, WindowMin, WindowMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
|
||||
Assert(PanelLayout->PanelsUsed > 0);
|
||||
panel* FirstPanel = &PanelLayout->Panels[0].Panel;
|
||||
DrawPanelOrRecurse(FirstPanel, WindowBounds, WindowBounds, RenderBuffer, Interface, Mouse, State, Context);
|
||||
}
|
||||
|
|
|
@ -122,8 +122,7 @@ struct context
|
|||
u32 MemorySize;
|
||||
|
||||
b32 WindowIsVisible;
|
||||
r32 WindowWidth;
|
||||
r32 WindowHeight;
|
||||
rect WindowBounds;
|
||||
r32 DeltaTime;
|
||||
|
||||
// Application Services
|
||||
|
|
|
@ -11,7 +11,7 @@ struct panel_definition
|
|||
global_variable s32 GlobalPanelDefsCount = 5;
|
||||
global_variable panel_definition GlobalPanelDefs[] = {
|
||||
{ "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 },
|
||||
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, 0 },
|
||||
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, 0 },
|
||||
|
|
|
@ -7,6 +7,62 @@
|
|||
// [] - 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)
|
||||
{
|
||||
|
||||
|
@ -139,15 +195,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
|
|||
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||
{
|
||||
MouseDownAndNotHandled = false;
|
||||
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
||||
{
|
||||
// If the block is already selected, deselect it.
|
||||
Result = {0};
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = CurrentBlockHandle;
|
||||
}
|
||||
SelectAndBeginDragAnimationBlock(CurrentBlockHandle, State);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,18 +219,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
|
|||
|
||||
if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, TimelineMin, TimelineMax))
|
||||
{
|
||||
r32 MouseDownPositionPercent = (Mouse.Pos.x - PanelMin.x) / AnimationPanelWidth;
|
||||
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;
|
||||
DeselectCurrentAnimationBlock(State);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
@ -245,6 +282,4 @@ PANEL_RENDER_PROC(AnimationTimeline_Render)
|
|||
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||
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[] = {
|
||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
|
||||
};
|
||||
|
@ -79,7 +122,7 @@ PANEL_RENDER_PROC(SculptureView_Render)
|
|||
{
|
||||
DEBUG_TRACK_SCOPE(RenderSculpture);
|
||||
|
||||
r32 PanelWidth = PanelMax.x - PanelMin.x;
|
||||
r32 PanelWidth = PanelMax.x - PanelMin.x;
|
||||
r32 PanelHeight = PanelMax.y - PanelMin.y;
|
||||
State->Camera.AspectRatio = PanelWidth / PanelHeight;
|
||||
|
||||
|
|
|
@ -488,11 +488,11 @@ Win32GetThreadId()
|
|||
|
||||
int WINAPI
|
||||
WinMain (
|
||||
HINSTANCE HInstance,
|
||||
HINSTANCE HPrevInstance,
|
||||
PSTR CmdLineArgs,
|
||||
INT NCmdShow
|
||||
)
|
||||
HINSTANCE HInstance,
|
||||
HINSTANCE HPrevInstance,
|
||||
PSTR CmdLineArgs,
|
||||
INT NCmdShow
|
||||
)
|
||||
{
|
||||
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
||||
Win32UpdateWindowDimension(&MainWindow);
|
||||
|
@ -560,15 +560,14 @@ INT NCmdShow
|
|||
context Context = {};
|
||||
Context.MemorySize = InitialMemorySize;
|
||||
Context.MemoryBase = InitialMemory;
|
||||
Context.WindowWidth = MainWindow.Width;
|
||||
Context.WindowHeight = MainWindow.Height;
|
||||
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||
|
||||
// Platform functions
|
||||
Context.GeneralWorkQueue = &WorkQueue;
|
||||
Context.PlatformAlloc = Win32Alloc;
|
||||
Context.PlatformFree = Win32Free;
|
||||
Context.PlatformRealloc = Win32Realloc;
|
||||
Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
||||
Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
||||
Context.PlatformWriteEntireFile = Win32WriteEntireFile;
|
||||
Context.PlatformGetFilePath = Win32SystemDialogueOpenFile;
|
||||
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
||||
|
@ -634,11 +633,7 @@ Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
|||
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
|
||||
// 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;
|
||||
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||
RenderBuffer.ViewWidth = MainWindow.Width;
|
||||
RenderBuffer.ViewHeight = MainWindow.Height;
|
||||
Context.DeltaTime = LastFrameSecondsElapsed;
|
||||
|
|
14
todo.txt
14
todo.txt
|
@ -1,7 +1,12 @@
|
|||
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
|
||||
x you need to rebuild the map from leds -> universes
|
||||
|
@ -89,17 +94,14 @@ Resource Management
|
|||
- Icons
|
||||
|
||||
Animation
|
||||
- timeline
|
||||
- create clips that play
|
||||
x timeline
|
||||
x create clips that play
|
||||
- clips can have parameters that drive them?
|
||||
- clips should have prerequesites
|
||||
- - channels active
|
||||
- - patterns active in the channel
|
||||
- - when a clip is playing, it should just take over the whole structure
|
||||
|
||||
Command Line
|
||||
- select a channel/pattern
|
||||
|
||||
Optimization
|
||||
- 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
|
||||
|
|
Loading…
Reference in New Issue