diff --git a/build.bat b/build.bat index 9ab6dff..514d5e8 100644 --- a/build.bat +++ b/build.bat @@ -18,8 +18,7 @@ pushd build del *.pdb > NUL 2> NUL -REM Compile and Run the Preprocessor -REM cl %CommonCompilerFlags% ..\meta\foldhaus_meta.cpp /link %CommonLinkerFlags% +REM Run the Preprocessor pushd ..\src\ ..\build\foldhaus_meta.exe C:\projects\foldhaus\src\ popd @@ -35,5 +34,5 @@ del lock.tmp cl %CommonCompilerFlags% ..\src\win32_foldhaus.cpp /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib opengl32.lib dsound.lib Ws2_32.lib Comdlg32.lib -incremental:no C:\programs\ctime\ctime.exe -end C:\projects\foldhaus\build\win32_foldhaus_build_time.ctm %LastError% -C:\programs\ctime\ctime.exe -stats C:\projects\foldhaus\build\win32_foldhaus_build_time.ctm +REM C:\programs\ctime\ctime.exe -stats C:\projects\foldhaus\build\win32_foldhaus_build_time.ctm popd \ No newline at end of file diff --git a/foldhaus_app.cpp b/foldhaus_app.cpp index 255fd31..a5084f3 100644 --- a/foldhaus_app.cpp +++ b/foldhaus_app.cpp @@ -336,57 +336,6 @@ UnloadAssembly (s32 AssemblyIndex, app_state* State, context Context) //////////////////////////////////////////////////////////////////////// -internal render_texture* -PushTexture (app_state* State) -{ - render_texture* Result = 0; - - if (State->LoadedTexturesUsed < State->LoadedTexturesSize) - { - Result = State->LoadedTextures + State->LoadedTexturesUsed++; - } - else - { - // TODO(Peter): Be able to grow this array - for (s32 i = 0; i < State->LoadedTexturesUsed; i++) - { - if (State->LoadedTextures[i].Handle == 0) - { - Result = State->LoadedTextures + i; - } - } - } - - Assert(Result); - return Result; -} - -internal render_texture* -StoreTexture (app_state* State, u8* Memory, s32 Width, s32 Height, s32 BytesPerPixel, s32 Stride) -{ - render_texture* Result = PushTexture(State); - Result->Memory = Memory; - Result->Handle = 0; - Result->Width = Width; - Result->Height = Height; - Result->BytesPerPixel = BytesPerPixel; - Result->Stride = Stride; -} - -internal void -RemoveTexture (app_state* State, s32 Index) -{ - State->LoadedTextures[Index].Handle = 0; - // TODO(Peter): Free the memory it was using -} - -internal void -RemoveTexture (app_state* State, render_texture* Texture) -{ - Texture->Handle = 0; - // TODO(Peter): Free the memory it was using -} - RELOAD_STATIC_DATA(ReloadStaticData) { app_state* State = (app_state*)Context.MemoryBase; @@ -395,13 +344,14 @@ RELOAD_STATIC_DATA(ReloadStaticData) if (State->InputCommandRegistry.Size > 0) { - RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_Delete, false, KeyCode_Invalid, - DeleteSelectedChannelOrPattern); RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_MouseLeftButton, true, KeyCode_Invalid, CameraMouseControl); RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_U, false, KeyCode_Invalid, ToggleUniverseDebugView); RegisterMouseWheelCommand(&State->InputCommandRegistry, CameraMouseZoom); RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_A, false, KeyCode_Invalid, AddNode); + RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_Tab, false, KeyCode_Invalid, ToggleNodeDisplay); + + InitializeTextInputCommands(&State->TextEntryCommandRegistry, State->Permanent); } } @@ -416,11 +366,9 @@ INITIALIZE_APPLICATION(InitializeApplication) InitMemoryArena(&State->SACNMemory, 0, 0, Context.PlatformAlloc); - State->LoadedTexturesSize = 8; - State->LoadedTextures = PushArray(State->Permanent, render_texture, State->LoadedTexturesSize); - State->LoadedTexturesUsed = 0; - InitializeInputCommandRegistry(&State->InputCommandRegistry, 32, State->Permanent); + InitializeInputCommandRegistry(&State->TextEntryCommandRegistry, 32, State->Permanent); + State->ActiveCommands = &State->InputCommandRegistry; // TODO(Peter): put in InitializeInterface? r32 FontSize = 14; @@ -498,11 +446,6 @@ INITIALIZE_APPLICATION(InitializeApplication) State->Camera.Position = v3{0, 0, -250}; State->Camera.LookAt = v3{0, 0, 0}; - InitLEDPatternSystem(&State->PatternSystem, State->Permanent, - 32, Megabytes(4)); - InitLEDChannelSystem(&State->ChannelSystem, State->Permanent, - sizeof(led_channel) * 32); - #if 1 char Path[] = "radialumia.fold"; LoadAssembly(State, Context, Path); @@ -533,6 +476,9 @@ INITIALIZE_APPLICATION(InitializeApplication) State->OutputNode = PushOutputNodeOnList(State->NodeList, v2{500, 250}, State->Permanent); + State->GeneralPurposeSearch.Backbuffer = PushArray(State->Permanent, char, 256); + InitializeEmptyString(&State->GeneralPurposeSearch.Buffer, State->GeneralPurposeSearch.Backbuffer, 256); + ReloadStaticData(Context, GlobalDebugServices); } @@ -546,14 +492,21 @@ UPDATE_AND_RENDER(UpdateAndRender) // incorrect to clear the arena, and then access the memory later. ClearArena(State->Transient); - ExecuteAllRegisteredCommands(&State->InputCommandRegistry, Input, State); + if (State->ActiveCommands == &State->TextEntryCommandRegistry) + { + AppendInputToEntryString(State->ActiveTextEntry, Input.New->StringInput, Input.New->StringInputUsed); + } + ExecuteAllRegisteredCommands(State->ActiveCommands, Input, State); - UpdateOutputNodeCalculations(State->OutputNode, State->NodeList, - State->Permanent, State->Transient, - State->LEDBufferList->LEDs, - State->LEDBufferList->Colors, - State->LEDBufferList->Count, - Context.DeltaTime); + if (State->LEDBufferList) + { + UpdateOutputNodeCalculations(State->OutputNode, State->NodeList, + State->Permanent, State->Transient, + State->LEDBufferList->LEDs, + State->LEDBufferList->Colors, + State->LEDBufferList->Count, + Context.DeltaTime); + } ClearTransientNodeColorBuffers(State->NodeList); @@ -691,7 +644,7 @@ UPDATE_AND_RENDER(UpdateAndRender) { DEBUG_TRACK_SCOPE(DrawUniverseOutputDisplay); - string TitleBarString = InitializeString(PushArray(State->Transient, char, 64), 64); + string TitleBarString = InitializeEmptyString(PushArray(State->Transient, char, 64), 64); v2 DisplayArea_Dimension = v2{600, 600}; v2 DisplayContents_Offset = State->UniverseOutputDisplayOffset; @@ -772,7 +725,7 @@ UPDATE_AND_RENDER(UpdateAndRender) if (LoadAssemblyBtn.Pressed) { char FilePath[256]; - b32 Success = Context.PlatformGetFilePath(FilePath, 256); + b32 Success = Context.PlatformGetFilePath(FilePath, 256, "Foldhaus Files\0*.fold\0\0"); if (Success) { LoadAssembly(State, Context, FilePath); @@ -783,6 +736,7 @@ UPDATE_AND_RENDER(UpdateAndRender) /////////////////////////////////////// // Figuring Out Nodes ////////////////////////////////////// + if (State->NodeRenderSettings.Display) { v2 MousePos = v2{(r32)Input.New->MouseX, (r32)Input.New->MouseY}; v2 LastFrameMousePos = v2{(r32)Input.Old->MouseX, (r32)Input.Old->MouseY}; @@ -817,33 +771,35 @@ UPDATE_AND_RENDER(UpdateAndRender) if (State->InterfaceShowNodeList) { v2 TopLeft = State->NodeListMenuPosition; + v2 Dimension = v2{300, 30}; - // Title Bar - PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, - v4{.3f, .3f, .3f, 1.f}); - DrawString(RenderBuffer, MakeStringLiteral("Nodes List"), State->Font, 14, - v2{TopLeft.x, TopLeft.y - 25}, WhiteV4); - TopLeft.y -= 30; - - for (s32 i = 0; i < NodeSpecificationsCount; i++) - { - node_specification Spec = NodeSpecifications[i]; - - button_result Button = EvaluateButton(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, - MakeStringLiteral(Spec.Name), State->Interface, Input); - if (Button.Pressed) - { - PushNodeOnListFromSpecification(State->NodeList, Spec, MousePos, State->Permanent); - } - - TopLeft.y -= 30; - } + search_lister_result NodeListResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension, + MakeStringLiteral("Nodes List"), + NodeSpecificationsCount, (u8*)NodeSpecifications, + State->GeneralPurposeSearchHotItem, + NodeListerGetNodeName, + &State->GeneralPurposeSearch.Buffer, + State->GeneralPurposeSearch.CursorPosition, + State->Font, State->Interface, Input); + State->GeneralPurposeSearchHotItem = NodeListResult.HotItem; if (KeyTransitionedDown(Input, KeyCode_MouseLeftButton) || KeyTransitionedDown(Input, KeyCode_Esc)) { State->InterfaceShowNodeList = false; + DeactivateTextEntry(State); } + + if (KeyTransitionedDown(Input, KeyCode_Enter)) + { + State->InterfaceShowNodeList = false; + if (NodeListResult.HotItem > 0) + { + PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[NodeListResult.HotItem], + MousePos, State->NodeRenderSettings, State->Permanent); + } + } + } } @@ -859,65 +815,6 @@ UPDATE_AND_RENDER(UpdateAndRender) } } -#if 0 - /////////////////////////////////////// - // Current Patterns Panel - ////////////////////////////////////// - - r32 LeftPanelRightEdge = DrawLeftHandInterface(State, Input, Context.WindowHeight - TopBarHeight, RenderBuffer); - - if (State->InterfaceState.ChannelSelected >= 0) - { - led_channel* ActiveChannel = GetChannelByIndex(State->InterfaceState.ChannelSelected, - State->ChannelSystem); - - button_result OperationButtonState = EvaluateButton( - RenderBuffer, - v2{Context.WindowWidth - 150, 500}, - v2{Context.WindowWidth - 50, 550}, - MakeStringLiteral(PatternSelectorOperationsText[ActiveChannel->BlendMode]), - State->Interface, - Input); - - if (OperationButtonState.Pressed) - { - State->InterfaceState.ChooseOperationPanelOpen = !State->InterfaceState.ChooseOperationPanelOpen; - } - - if (State->InterfaceState.ChooseOperationPanelOpen) - { - s32 StringLength = 128; - s32 OperationsStart = PatternSelectorCombine_Invalid + 1; - s32 OperationsOnePastLast = PatternSelectorCombine_Count; - s32 OperationsCount = (OperationsOnePastLast - OperationsStart); - string* OperationChoices = PushArray(State->Transient, string, OperationsCount); - - for (s32 Choice = OperationsStart; - Choice < OperationsOnePastLast; - Choice++) - { - s32 Index = Choice - OperationsStart; - PushString(&OperationChoices[Index], State->Transient, StringLength); - CopyCharArrayToString(PatternSelectorOperationsText[Choice], - &OperationChoices[Index]); - } - - v2 Min = v2{Context.WindowWidth - 250, 250}; - v2 Max = v2{Context.WindowWidth - 50, 500}; - - scroll_list_result OperationChoice = DrawSelectableOptionsList(RenderBuffer, Min, Max, OperationChoices, OperationsCount, - 0, ActiveChannel->BlendMode - 1, - State->Interface, Input); - if (OperationChoice.IndexSelected + 1 > (int)ChannelBlend_Invalid && - OperationChoice.IndexSelected + 1 < (int)ChannelBlend_Count) - { - ActiveChannel->BlendMode = (channel_blend_mode)(OperationChoice.IndexSelected + 1); - } - } - } - -#endif - DrawDebugInterface(RenderBuffer, 25, State->Interface, Context.WindowWidth, Context.WindowHeight - TopBarHeight, Context.DeltaTime, State->Camera, Input, State->Transient); diff --git a/foldhaus_app.h b/foldhaus_app.h index 4fcb82f..1c9e992 100644 --- a/foldhaus_app.h +++ b/foldhaus_app.h @@ -40,21 +40,10 @@ struct assembly }; #include "assembly_parser.h" - -// TODO(Peter): remove this, and get pattern_system.h outta here!! -typedef struct led_pattern led_pattern; - #include "foldhaus_node.h" - -#include "foldhaus_patterns.h" -#include "foldhaus_channel.h" -#include "foldhaus_patterns.cpp" -#include "foldhaus_channel.cpp" - #include "assembly_parser.cpp" - #include "test_patterns.h" -#include "patterns_registry.h" +#include "kraftwerks_patterns.h" #include "foldhaus_interface.h" typedef struct app_state app_state; @@ -62,6 +51,9 @@ typedef struct app_state app_state; #include "foldhaus_debug_visuals.h" #include "foldhaus_command_dispatch.h" +#include "foldhaus_text_entry.h" + +#include "foldhaus_default_nodes.h" #include "generated/foldhaus_nodes_generated.cpp" struct app_state @@ -70,13 +62,18 @@ struct app_state memory_arena* Transient; memory_arena SACNMemory; + /* render_texture* LoadedTextures; s32 LoadedTexturesSize; s32 LoadedTexturesUsed; + */ camera Camera; input_command_registry InputCommandRegistry; + input_command_registry TextEntryCommandRegistry; + input_command_registry* ActiveCommands; + text_input* ActiveTextEntry; streaming_acn SACN; s32 TotalLEDsCount; @@ -89,10 +86,6 @@ struct app_state assembly AssemblyList[ASSEMBLY_LIST_LENGTH]; s32 AssembliesUsed; - //environment Environment; - led_channel_system ChannelSystem; - led_pattern_system PatternSystem; - bitmap_font* Font; interface_state InterfaceState; interface_config Interface; @@ -114,9 +107,14 @@ struct app_state interface_node* OutputNode; v4* ColorPickerEditValue; + + text_input GeneralPurposeSearch; + s32 GeneralPurposeSearchHotItem; + }; #include "foldhaus_sacn_view.cpp" #include "foldhaus_command_dispatch.cpp" #include "foldhaus_node.cpp" +#include "foldhaus_text_entry.cpp" #include "foldhaus_interface.cpp" diff --git a/foldhaus_channel.cpp b/foldhaus_channel.cpp deleted file mode 100644 index 9b1dd8e..0000000 --- a/foldhaus_channel.cpp +++ /dev/null @@ -1,261 +0,0 @@ -inline void -SetTransition(pattern_transition* Transition, r32 Duration, r32 Elapsed) -{ - Transition->Duration = Duration; - Transition->TimeElapsed = Elapsed; -} - -internal void -InitLEDChannelSystem (led_channel_system* System, memory_arena* ParentStorage, s32 StorageSize) -{ - System->Channels = 0; - System->ChannelCount = 0; - InitMemoryArena(&System->Storage, PushSize(ParentStorage, StorageSize), StorageSize, 0); - System->FreeList = 0; -} - -inline void -ResetChannel (led_channel* Channel, led_channel_system* ChannelSystem) -{ - if (Channel->Patterns == 0) - { - Channel->Patterns = PushArray(&ChannelSystem->Storage, - pattern_index_id_key, - CHANNEL_MAX_PATTERNS); - } - Channel->ActivePatterns = 0; - Channel->ActivePatternIndex = -1; - - SetTransition(&Channel->Transition, 3, 0); - - Channel->BlendMode = ChannelBlend_Override; - Channel->ChannelID = ChannelIDAccumulator++; - - Channel->Next = 0; -} - -internal led_channel* -AddLEDChannel (led_channel_system* ChannelSystem) -{ - led_channel* Channel = 0; - - if (ChannelSystem->FreeList) - { - Channel = ChannelSystem->FreeList; - ChannelSystem->FreeList = ChannelSystem->FreeList->Next; - } - else - { - Channel = PushStruct(&ChannelSystem->Storage, led_channel); - } - ResetChannel(Channel, ChannelSystem); - - Channel->Next = ChannelSystem->Channels; - ChannelSystem->Channels = Channel; - ChannelSystem->ChannelCount++; - - return Channel; -} - -internal b32 -RemoveLEDChannel_ (led_channel* PrevChannel, led_channel* ToRemove, led_channel_system* ChannelSystem) -{ - b32 Result = true; - - if (PrevChannel->Next == ToRemove) - { - PrevChannel->Next = ToRemove->Next; - ToRemove->Next = ChannelSystem->FreeList; - ChannelSystem->FreeList = ToRemove; - ChannelSystem->ChannelCount--; - Result = true; - } - else - { - Result = false; - } - - return Result; -} - -internal b32 -RemoveLEDChannel (led_channel* Channel, led_channel_system* ChannelSystem) -{ - b32 Result = true; - - led_channel* Cursor = ChannelSystem->Channels; - for (s32 i = 0; - (Cursor->Next != Channel && i < ChannelSystem->ChannelCount); - Cursor = Cursor->Next, i++){} - - Result = RemoveLEDChannel_(Cursor, Channel, ChannelSystem); - - return Result; -} - -internal b32 -RemoveLEDChannel (s32 Index, led_channel_system* ChannelSystem) -{ - Assert(Index < ChannelSystem->ChannelCount); - b32 Result = true; - - if (Index == 0) - { - led_channel* FirstChannel = ChannelSystem->Channels; - ChannelSystem->Channels = FirstChannel->Next; - FirstChannel->Next = ChannelSystem->FreeList; - ChannelSystem->FreeList = FirstChannel; - ChannelSystem->ChannelCount--; - Result = true; - } - else - { - led_channel* PrevChannel = ChannelSystem->Channels; - for (s32 i = 0; i < Index - 1; i++) - { - PrevChannel = PrevChannel->Next; - } - - Result = RemoveLEDChannel_(PrevChannel, PrevChannel->Next, ChannelSystem); - } - - return Result; -} - -internal led_channel* -GetChannelByIndex (s32 Index, led_channel_system ChannelSystem) -{ - Assert(Index < ChannelSystem.ChannelCount); - led_channel* Result = ChannelSystem.Channels; - - for (s32 i = 0; i < Index; i++) - { - Result = Result->Next; - } - - return Result; -} - -internal void -AddPatternKeyToChannel (pattern_index_id_key Key, led_channel* Channel) -{ - Assert(Channel->ActivePatterns < CHANNEL_MAX_PATTERNS); - Channel->Patterns[Channel->ActivePatterns++] = Key; -} - -internal b32 -RemovePatternKeyFromChannel (pattern_index_id_key Key, led_channel* Channel) -{ - b32 Result = false; - - s32 RemoveFrom = -1; - for (s32 i = 0; i < Channel->ActivePatterns; i++) - { - if (Channel->Patterns[i].ID == Key.ID) - { - RemoveFrom = i; - } - } - - if (RemoveFrom >= 0) - { - for (s32 j = 0; j < Channel->ActivePatterns; j++) - { - Channel->Patterns[j] = Channel->Patterns[j + 1]; - } - Channel->ActivePatterns--; - Result = true; - } - - return Result; -} - -internal void -PushPatternKeyOnUpdateList (pattern_index_id_key Key, - pattern_push_color_proc* PushColorProc, - patterns_update_list* UpdateList, - memory_arena* Storage) -{ - if (UpdateList->Used >= UpdateList->Size) - { - if (!UpdateList->Next) - { - UpdateList->Next = PushStruct(Storage, patterns_update_list); - UpdateList->Next->Size = UpdateList->Size; - UpdateList->Next->Used = 0; - UpdateList->Next->Patterns = PushArray(Storage, pattern_update_list_entry, UpdateList->Next->Size); - } - PushPatternKeyOnUpdateList(Key, PushColorProc, UpdateList->Next, Storage); - } - else - { - pattern_update_list_entry Entry = {}; - Entry.Key = Key; - Entry.PushColorProc = PushColorProc; - UpdateList->Patterns[UpdateList->Used++] = Entry; - } -} - -internal void -UpdateChannel (led_channel* Channel, - patterns_update_list* PatternsNeedUpdateList, - r32 DeltaTime, - memory_arena* Storage) -{ - // Update Transition - Channel->Transition.TimeElapsed += DeltaTime; - if (Channel->Transition.TimeElapsed >= Channel->Transition.Duration || - (Channel->ActivePatternIndex < 0 && Channel->ActivePatterns > 0)) - { - Channel->Transition.TimeElapsed -= Channel->Transition.Duration; - Channel->ActivePatternIndex++; - if (Channel->ActivePatternIndex >= Channel->ActivePatterns) - { - Channel->ActivePatternIndex = 0; - } - } - - // Create Active Pattern List - if (Channel->ActivePatterns > 0) - { - Assert(Channel->ActivePatternIndex >= 0 && Channel->ActivePatternIndex < Channel->ActivePatterns); - - pattern_push_color_proc* PushColorProc = 0; - switch (Channel->BlendMode) - { - case ChannelBlend_Override: { PushColorProc = PushColor_Override; } break; - case ChannelBlend_Add: { PushColorProc = PushColor_Add; } break; - case ChannelBlend_Multiply: { PushColorProc = PushColor_Multiply; } break; - default: - { - InvalidCodePath; - }break; - } - - PushPatternKeyOnUpdateList(Channel->Patterns[Channel->ActivePatternIndex], - PushColorProc, - PatternsNeedUpdateList, Storage); - } -} - -internal patterns_update_list -UpdateAllChannels (led_channel_system* ChannelSystem, r32 DeltaTime, memory_arena* Transient) -{ - patterns_update_list Result = {}; - // NOTE(Peter): The initial size of this array is ChannelCount * 2 b/c at the moment, in the worst case, - // we need to update the two patterns a channel is blending between, and there isn't a case where we'd - // update 3 per channel - Result.Size = ChannelSystem->ChannelCount * 2; - Result.Used = 0; - Result.Patterns = PushArray(Transient, pattern_update_list_entry, Result.Size); - Result.Next = 0; - - for (led_channel* Channel = ChannelSystem->Channels; - Channel; - Channel = Channel->Next) - { - UpdateChannel(Channel, &Result, DeltaTime, Transient); - } - - return Result; -} diff --git a/foldhaus_channel.h b/foldhaus_channel.h deleted file mode 100644 index 0a2c722..0000000 --- a/foldhaus_channel.h +++ /dev/null @@ -1,98 +0,0 @@ -#if 0 // USAGE CODE - -{ - channel* FirstChannel = AddChannel(State, State->Channels); - - channel* ActiveChannel = GetChannelAtIndex(State->Channels, ActiveIndex); - AddPattern(State, ActiveChannel, PatternSpec); - - patterns_need_update UpdatePatternsList = UdpateAllChannels(ChannelSystem, State->Transient); - - for (s32 i = 0; i < UpdatePatternsList.Count; i++) - { - UpdateActivePatterns(State, Patterns, UpdatePatternsList.PatternIDs[i]); - } - - pattern* Pattern = ...; - DeletePattern(State, Pattern); - - RemoveChannel(FirstChannel, State->Channels); - RemoveChannel(2, State->Channels); -} -#endif - -struct pattern_transition -{ - r32 Duration; - r32 TimeElapsed; -}; - -enum channel_blend_mode -{ - ChannelBlend_Invalid, - - ChannelBlend_Override, - ChannelBlend_Add, - ChannelBlend_Multiply, - - ChannelBlend_Count, -}; - -char* METAChannelBlendModeNames[] = { - "Invalid", //ChannelBlend_Invalid - "Override", //ChannelBlend_Override - "Add", // ChannelBlend_Add - "Multiply", //ChannelBlend_Multiply - "Count", //ChannelBlend_Count -}; - -global_variable s32 ChannelIDAccumulator; - -// TODO(Peter): This number is gonna have to get bigger -#define CHANNEL_MAX_PATTERNS 8 -struct led_channel -{ - s32 ChannelID; - - pattern_index_id_key* Patterns; - // TODO(Peter): Rename this once we get patterns in their own system. All patterns in this - // list are active. ATM this is just here for legacy reasons. - s32 ActivePatterns; - // TODO(Peter): and this should probably be CurrentPatternIndex, or HotPatternIndex - s32 ActivePatternIndex; - - // TODO(Peter): extend this to be able to have different kinds of transitions - // including, most importantly, being able to fade between patterns - pattern_transition Transition; - channel_blend_mode BlendMode; - - led_channel* Next; -}; - -struct led_channel_system -{ - led_channel* Channels; - s32 ChannelCount; - - // TODO(Peter): think about ways this can give back to the main pool - // Like, if we just stay within initial storage, no problem. But if we grow really big, - // then shrink really small, we should probably give some of it back to the main app. - // maybe by keeping track of FreeList size... - // TODO(Peter): Also need to think about how memory_arenas get bigger... - memory_arena Storage; - led_channel* FreeList; -}; - -struct pattern_update_list_entry -{ - pattern_index_id_key Key; - pattern_push_color_proc* PushColorProc; -}; - -struct patterns_update_list -{ - pattern_update_list_entry* Patterns; - s32 Size; - s32 Used; - patterns_update_list* Next; -}; diff --git a/foldhaus_debug_visuals.h b/foldhaus_debug_visuals.h index 07179f1..8a1a490 100644 --- a/foldhaus_debug_visuals.h +++ b/foldhaus_debug_visuals.h @@ -8,7 +8,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c arena_snapshot StartTempMemory = TakeSnapshotOfArena(*Transient); - string DebugString = InitializeString(PushArray(Transient, char, 256), 256); + string DebugString = InitializeEmptyString(PushArray(Transient, char, 256), 256); if (GlobalDebugServices->Interface.ShowCameraMouse || GlobalDebugServices->Interface.ShowTrackedScopes) { diff --git a/foldhaus_default_nodes.h b/foldhaus_default_nodes.h new file mode 100644 index 0000000..bacafe1 --- /dev/null +++ b/foldhaus_default_nodes.h @@ -0,0 +1,137 @@ +////////////////////////////////// +// +// Values +// +///////////////////////////////// + +NODE_STRUCT(float_value_data) +{ + NODE_IN(r32, Value); + NODE_OUT(r32, Result); +}; + +NODE_PROC(FloatValue, float_value_data) +{ + Data->Result = Data->Value; +} + +NODE_STRUCT(vector_data) +{ + NODE_IN(r32, X); + NODE_IN(r32, Y); + NODE_IN(r32, Z); + NODE_IN(r32, W); + NODE_OUT(v4, Result); +}; + +NODE_PROC(VectorValue, vector_data) +{ + Data->Result = v4{Data->X, Data->Y, Data->Z, Data->W}; +} + +////////////////////////////////// +// +// Arithmetic +// +///////////////////////////////// + +NODE_STRUCT(multiply_data) +{ + NODE_IN(r32, A); + NODE_IN(r32, B); + NODE_OUT(r32, Result); +}; + +NODE_PROC(MultiplyNodeProc, multiply_data) +{ + Data->Result = Data->A * Data->B; +} + +NODE_STRUCT(add_data) +{ + NODE_IN(v4, A); + NODE_IN(v4, B); + NODE_OUT(v4, Result); +}; + +NODE_PROC(AddNodeProc, add_data) +{ + Data->Result = Data->A + Data->B; +} + +////////////////////////////////// +// +// Animators +// +///////////////////////////////// + +NODE_STRUCT(sin_wave_data) +{ + NODE_IN(r32, Period); + NODE_IN(r32, Min); + NODE_IN(r32, Max); + NODE_OUT(r32, Result); + + r32 Accumulator; +}; + +NODE_PROC(SinWave, sin_wave_data) +{ + Data->Accumulator += DeltaTime; + if (Data->Period > 0) + { + while (Data->Accumulator > Data->Period) + { + Data->Accumulator -= Data->Period; + } + + r32 ActualMin = GSMin(Data->Min, Data->Max); + r32 ActualMax = GSMax(Data->Min, Data->Max); + r32 SinResult = GSSin((Data->Accumulator / Data->Period) * PI * 2); + Data->Result = GSRemap(SinResult, -1.f, 1.f, ActualMin, ActualMax); + } + else + { + Data->Result = 0; + } +} + +////////////////////////////////// +// +// Pattern Mixing +// +///////////////////////////////// + +NODE_STRUCT(multiply_patterns_data) +{ + NODE_COLOR_BUFFER_IN(A); + NODE_COLOR_BUFFER_IN(B); + NODE_COLOR_BUFFER_OUT(Result); +}; + +NODE_PROC(MultiplyPatterns, multiply_patterns_data) +{ + led* LED = Data->ResultLEDs; + for (s32 l = 0; l < Data->ResultLEDCount; l++) + { + Assert(LED->Index >= 0 && LED->Index < Data->ResultLEDCount); + + s32 AR = Data->AColors[LED->Index].R; + s32 AG = Data->AColors[LED->Index].G; + s32 AB = Data->AColors[LED->Index].B; + + s32 BR = Data->BColors[LED->Index].R; + s32 BG = Data->BColors[LED->Index].G; + s32 BB = Data->BColors[LED->Index].B; + + s32 RCombined = (AR * BR) / 255; + s32 GCombined = (AG * BG) / 255; + s32 BCombined = (AB * BB) / 255; + + Data->ResultColors[LED->Index].R = (u8)RCombined; + Data->ResultColors[LED->Index].G = (u8)GCombined; + Data->ResultColors[LED->Index].B = (u8)BCombined; + + LED++; + } +} diff --git a/foldhaus_interface.cpp b/foldhaus_interface.cpp index 251241f..0fac442 100644 --- a/foldhaus_interface.cpp +++ b/foldhaus_interface.cpp @@ -1,224 +1,3 @@ - - -// NOTE(Peter): returns the rightmost bound of the panel -internal r32 -DrawLeftHandInterface (app_state* State, input Input, r32 WindowHeight, render_command_buffer* RenderBuffer) -{ - DEBUG_TRACK_FUNCTION; - - s32 StringLength = 128; - - panel_result LeftHandPanel = EvaluatePanel(RenderBuffer, v2{0, 0}, v2{250, WindowHeight}, - MakeStringLiteral("Channel Ops"), 0, State->Interface, Input); - - r32 ListHeight = (LeftHandPanel.ChildMax.y - LeftHandPanel.ChildMin.y) / 2; - panel_result ChannelListPanel = EvaluatePanel(RenderBuffer, &LeftHandPanel, - ListHeight, MakeStringLiteral("Channels"), - State->Interface, Input); - panel_result PatternsListPanel = EvaluatePanel(RenderBuffer, &LeftHandPanel, ListHeight, MakeStringLiteral("Patterns"), - State->Interface, Input); - - // NOTE(Peter): have to do this before we open it otherwise, it'll just close again immediately - // due to the mouse being pressed, outside the box, on the frame it is opened; - if (State->InterfaceState.AddingPattern && - State->InterfaceState.ChannelSelected >= 0) - { - v2 PatternSelectorDim = v2{300, 200}; - v2 PatternSelectorPosition = PatternsListPanel.NextPanelMin; - PatternSelectorPosition.y = PatternsListPanel.ChildMax.y - PatternSelectorDim.y; - - panel_result AddPatternPanel = EvaluatePanel( - RenderBuffer, - PatternSelectorPosition, PatternSelectorPosition + PatternSelectorDim, - MakeStringLiteral("Add Pattern"), 0, State->Interface, Input); - - if (KeyTransitionedDown(Input, KeyCode_MouseLeftButton) && - !PointIsInRange(v2{(r32)Input.New->MouseX, (r32)Input.New->MouseY}, - AddPatternPanel.ChildMin, AddPatternPanel.ChildMax)) - { - State->InterfaceState.AddingPattern = false; - } - - s32 PatternsCount = sizeof(PatternRegistry)/sizeof(PatternRegistry[0]); - string* PatternNames = PushArray(State->Transient, string, PatternsCount); - - for (s32 i = 0; i < PatternsCount; i++) - { - PushString(&PatternNames[i], State->Transient, StringLength); - CopyCharArrayToString(PatternRegistry[i].Name, &PatternNames[i]); - } - - scroll_list_result PatternsResult = DrawOptionsList(RenderBuffer, AddPatternPanel.ChildMin, - AddPatternPanel.ChildMax, - PatternNames, - PatternsCount, - State->InterfaceState.PatternSelectorStart, - State->Interface, - Input); - if (PatternsResult.IndexSelected >= 0) - { - led_channel* ActiveChannel = GetChannelByIndex(State->InterfaceState.ChannelSelected, - State->ChannelSystem); - pattern_index_id_key PatternKey = AddPattern( - &State->PatternSystem, - &PatternRegistry[PatternsResult.IndexSelected]); - AddPatternKeyToChannel(PatternKey, ActiveChannel); - } - - State->InterfaceState.PatternSelectorStart = PatternsResult.StartIndex; - } - - s32 ChannelCount = State->ChannelSystem.ChannelCount; - // NOTE(Peter): adding one to the channel count here so that we can tack on the '+ Add Channel' lable at the end. - // NOTE(Peter): I think I've spelled lable as label all throughout here now... oops. - s32 ChannelLabelsCount = ChannelCount + 1; - string* ChannelTitles = PushArray(State->Transient, string, ChannelLabelsCount); - - led_channel* Channel = State->ChannelSystem.Channels; - for (s32 ChannelIdx = 0; ChannelIdx < ChannelCount; ChannelIdx++) - { - PushString(&ChannelTitles[ChannelIdx], State->Transient, StringLength); - PrintF(&ChannelTitles[ChannelIdx], "Channel %d", Channel->ChannelID); - Channel = Channel->Next; - } - - ChannelTitles[ChannelCount] = MakeStringLiteral("+ Add Channel"); - - scroll_list_result ChannelList = DrawSelectableOptionsList( - RenderBuffer, - ChannelListPanel.ChildMin, - ChannelListPanel.ChildMax, - ChannelTitles, - ChannelLabelsCount, - State->InterfaceState.ChannelSelectorStart, - State->InterfaceState.ChannelSelected, - State->Interface, Input); - - State->InterfaceState.ChannelSelectorStart = ChannelList.StartIndex; - if (ChannelList.Selection == Selection_Selected) - { - if (ChannelList.IndexSelected >= ChannelCount) - { - led_channel* NewChannel = AddLEDChannel(&State->ChannelSystem); - } - else - { - State->InterfaceState.SelectionType = InterfaceSelection_Channel; - State->InterfaceState.ChannelSelected = ChannelList.IndexSelected; - State->InterfaceState.ActiveChannelPatternSelected = -1; - } - } - else if (ChannelList.Selection == Selection_Deselected) - { - State->InterfaceState.ChannelSelected = -1; - State->InterfaceState.ActiveChannelPatternSelected = -1; - } - - s32 ActiveChannelPatternCount = 0; - s32 PatternLabelsCount = 1; - string* PatternTitles = PushArray(State->Transient, string, 1);; - - if (State->InterfaceState.ChannelSelected >= 0) - { - led_channel* ActiveChannel = GetChannelByIndex(State->InterfaceState.ChannelSelected, - State->ChannelSystem); - ActiveChannelPatternCount = ActiveChannel->ActivePatterns; - - // NOTE(Peter): We're just growing the PatternTitles array allocated above. - // IMPORTANT(Peter): make sure no allocations happen between the PushArray to PatternTitles and this one vvv - PushArray(State->Transient, string, ActiveChannelPatternCount); - PatternLabelsCount += ActiveChannelPatternCount; - - for (s32 P = 0; P < ActiveChannelPatternCount; P++) - { - led_pattern* Pattern = FindPatternAndUpdateIDKey(&ActiveChannel->Patterns[P], - &State->PatternSystem); - - PushString(&PatternTitles[P], State->Transient, StringLength); - PrintF(&PatternTitles[P], "%s %d", Pattern->Name, ActiveChannel->Patterns[P].ID); - - Pattern++; - } - } - - PatternTitles[ActiveChannelPatternCount]= MakeStringLiteral("+ Add Pattern"); - - scroll_list_result PatternsList = DrawSelectableOptionsList( - RenderBuffer, - PatternsListPanel.ChildMin, - PatternsListPanel.ChildMax, - PatternTitles, - PatternLabelsCount, - State->InterfaceState.ActiveChannelPatternSelectorStart, - State->InterfaceState.ActiveChannelPatternSelected, - State->Interface, Input - ); - - State->InterfaceState.ActiveChannelPatternSelectorStart = PatternsList.StartIndex; - if (PatternsList.Selection == Selection_Selected) - { - if (PatternsList.IndexSelected >= ActiveChannelPatternCount) - { - State->InterfaceState.AddingPattern = true; - } - else if (PatternsList.IndexSelected >= 0) - { - State->InterfaceState.SelectionType = InterfaceSelection_Pattern; - OutputDebugStringA("Pattern\n"); - State->InterfaceState.ActiveChannelPatternSelected = PatternsList.IndexSelected; - } - } - else if (PatternsList.Selection == Selection_Deselected) - { - State->InterfaceState.SelectionType = InterfaceSelection_None; - OutputDebugStringA("None\n"); - State->InterfaceState.ActiveChannelPatternSelected = -1; - } - - return LeftHandPanel.NextPanelMin.x; -} - -FOLDHAUS_INPUT_COMMAND_PROC(DeleteSelectedChannelOrPattern) -{ - if (State->InterfaceState.ChannelSelected >= 0) - { - switch (State->InterfaceState.SelectionType) - { - case InterfaceSelection_Channel: - { - led_channel* DeleteCandidate = GetChannelByIndex( - State->InterfaceState.ChannelSelected, - State->ChannelSystem); - - for (s32 i = 0; i < DeleteCandidate->ActivePatterns; i++) - { - RemovePattern(DeleteCandidate->Patterns[i], - &State->PatternSystem); - } - - RemoveLEDChannel(State->InterfaceState.ChannelSelected, &State->ChannelSystem); - State->InterfaceState.ChannelSelected--; - - }break; - - case InterfaceSelection_Pattern: - { - if (State->InterfaceState.ActiveChannelPatternSelected >= 0) - { - led_channel* ActiveChannel = GetChannelByIndex(State->InterfaceState.ChannelSelected, - State->ChannelSystem); - s32 KeyIndex = State->InterfaceState.ActiveChannelPatternSelected; - pattern_index_id_key Key = ActiveChannel->Patterns[KeyIndex]; - if (RemovePattern(Key, &State->PatternSystem)) - { - RemovePatternKeyFromChannel(Key, ActiveChannel); - } - } - }break; - } - } -} - FOLDHAUS_INPUT_COMMAND_PROC(CameraMouseControl) { if (State->NodeInteraction.NodeOffset >= 0) { return; } @@ -275,4 +54,10 @@ FOLDHAUS_INPUT_COMMAND_PROC(AddNode) { State->InterfaceShowNodeList = true; State->NodeListMenuPosition = v2{(r32)Input.New->MouseX, (r32)Input.New->MouseY}; + ActivateTextEntry(&State->GeneralPurposeSearch, State); +} + +FOLDHAUS_INPUT_COMMAND_PROC(ToggleNodeDisplay) +{ + State->NodeRenderSettings.Display = !State->NodeRenderSettings.Display; } \ No newline at end of file diff --git a/foldhaus_memory.h b/foldhaus_memory.h index 225aed8..7dec4fb 100644 --- a/foldhaus_memory.h +++ b/foldhaus_memory.h @@ -79,6 +79,7 @@ BootstrapRegionOntoMemory (u8* Memory, s32 Size) Result->Base = Memory + sizeof(memory_region); Result->Size = Size - sizeof(memory_region); Result->Used = 0; + Result->PreviousRegion = 0; return Result; } @@ -161,6 +162,7 @@ BootstrapArenaIntoMemory (u8* Memory, u32 Size) // NOTE(Peter): takes in a block of memory, places a memory arena at the head, and gives // the arena access to the rest of the block to use. memory_arena* Result = (memory_arena*)Memory; + *Result = {}; InitMemoryArena(Result, Memory + sizeof(memory_arena), Size - sizeof(memory_arena), 0); return Result; } @@ -251,6 +253,37 @@ ClearArenaToSnapshot (memory_arena* Arena, arena_snapshot Snapshot) RegionCursor->Used = Snapshot.UsedAtSnapshot; } +// +// Basic Memory Arena +// A no-bookkeeping overhead version of the memory_arena above. +// + +struct static_memory_arena +{ + u8* Base; + u32 Size; + u32 Used; +}; + +static static_memory_arena +CreateMemoryArena (u8* Base, u32 Size) +{ + static_memory_arena Result = {}; + Result.Base = Base; + Result.Size = Size; + Result.Used = 0; + return Result; +} + +static u8* +PushSize_ (static_memory_arena* Arena, u32 Size) +{ + Assert(Arena->Used + Size <= Arena->Size); + u8* Result = Arena->Base + Arena->Used; + Arena->Used += Size; + return Result; +} + // // Tracked Array Implementation // diff --git a/foldhaus_node.cpp b/foldhaus_node.cpp index 6bf07b8..ba0ffa9 100644 --- a/foldhaus_node.cpp +++ b/foldhaus_node.cpp @@ -1,3 +1,4 @@ + inline s32 GetNodeMemorySize (interface_node Node) { @@ -125,15 +126,22 @@ InitializeNodeConnection (node_connection* Connection, struct_member_type Type, } } -internal void -PushNodeOnListFromSpecification (node_list* List, node_specification Spec, v2 Min, memory_arena* Storage) +internal r32 +CalculateNodeHeight (s32 Members, node_render_settings RenderSettings) { - // TODO(Peter): Calculate the size of a node; + r32 Result = (RenderSettings.PortStep * Members) + NODE_HEADER_HEIGHT; + return Result; +} + +internal void +PushNodeOnListFromSpecification (node_list* List, node_specification Spec, v2 Min, node_render_settings RenderSettings, memory_arena* Storage) +{ + r32 NodeHeight = CalculateNodeHeight (Spec.MemberListLength, RenderSettings); interface_node* Node = PushNodeOnList(List, Spec.NameLength, Spec.MemberListLength, Min, - v2{150, 150}, + v2{150, NodeHeight}, Storage); Node->Type = Spec.Type; @@ -146,6 +154,7 @@ PushNodeOnListFromSpecification (node_list* List, node_specification Spec, v2 Mi InitializeNodeConnection(Node->Connections + MemberIdx, Member.Type, Member.IsInput); } + Node->PersistentData = PushArray(Storage, u8, Spec.DataStructSize); } internal interface_node* @@ -182,18 +191,6 @@ GetNodeAtOffset (node_list* List, s32 Offset) return Node; } -internal node_interaction -NewNodeInteraction () -{ - node_interaction Result = {}; - Result.NodeOffset = -1; - Result.InputPort = -1; - Result.InputValue = -1; - Result.OutputPort = -1; - Result.OutputValue = -1; - return Result; -} - internal rect CalculateNodeBounds (interface_node* Node, node_render_settings Settings) { @@ -273,6 +270,18 @@ CalculateNodeDragHandleBounds (rect NodeBounds, s32 Index, node_render_settings return Result; } +internal node_interaction +NewNodeInteraction () +{ + node_interaction Result = {}; + Result.NodeOffset = -1; + Result.InputPort = -1; + Result.InputValue = -1; + Result.OutputPort = -1; + Result.OutputValue = -1; + return Result; +} + internal b32 IsDraggingNode (node_interaction Interaction) { @@ -658,7 +667,7 @@ PlaceNode (node_list* NodeList, interface_node* Node, v2 Position, b32 Flags) v2 NewPos = CurrPos + Offset; // NOTE(Peter): Have to negate the all downstream component so it doesn't turn around and try // to move this node again. - PlaceNode(NodeList, ConnectedNode, NewPos, Flags & ~NodeInteraction_AllDownstream); + PlaceNode(NodeList, ConnectedNode, NewPos, Flags & ~NodeInteraction_AllUpstream); } } } @@ -677,7 +686,7 @@ PlaceNode (node_list* NodeList, interface_node* Node, v2 Position, b32 Flags) v2 NewPos = CurrPos + Offset; // NOTE(Peter): Have to negate the all upstream component so it doesn't turn around and try // to move this node again. - PlaceNode(NodeList, ConnectedNode, NewPos, Flags & ~NodeInteraction_AllUpstream); + PlaceNode(NodeList, ConnectedNode, NewPos, Flags & ~NodeInteraction_AllDownstream); } } } @@ -825,6 +834,7 @@ UpdateNodeCalculation (interface_node* Node, node_list* NodeList, led* LEDs, sacn_pixel* ColorsInit, s32 LEDCount, r32 DeltaTime) { DEBUG_TRACK_FUNCTION; + Assert(Node->PersistentData != 0); // NOTE(Peter): Have to subtract one here so that we account for the // NodeType_OutputNode entry in the enum @@ -839,12 +849,6 @@ UpdateNodeCalculation (interface_node* Node, node_list* NodeList, sacn_pixel* Colors = ColorsInit; - // TODO(Peter): Should do this at node creation time - if (Node->PersistentData == 0) - { - Node->PersistentData = PushArray(Permanent, u8, Spec.DataStructSize); - } - UpdateNodesConnectedUpstream(Node, NodeList, Permanent, Transient, LEDs, Colors, LEDCount, DeltaTime); for (s32 ConnectionIdx = 0; ConnectionIdx < Node->ConnectionsCount; ConnectionIdx++) @@ -1111,3 +1115,11 @@ ResetNodesUpdateState (node_list* NodeList) } } + +internal char* +NodeListerGetNodeName (u8* NodeSpecificationsList, s32 NodeSpecificationsListCount, s32 Offset) +{ + node_specification* Specifications = (node_specification*)NodeSpecificationsList + Offset; + char* Result = Specifications->Name; + return Result; +} \ No newline at end of file diff --git a/foldhaus_node.h b/foldhaus_node.h index 1426df7..1341370 100644 --- a/foldhaus_node.h +++ b/foldhaus_node.h @@ -155,6 +155,7 @@ struct node_render_settings r32 PortStep; v4 PortColors[MemberTypeCount]; bitmap_font* Font; + b32 Display; }; v4 DragButtonColors[] = { diff --git a/foldhaus_patterns.cpp b/foldhaus_patterns.cpp deleted file mode 100644 index 69945dd..0000000 --- a/foldhaus_patterns.cpp +++ /dev/null @@ -1,247 +0,0 @@ -NODE_STRUCT(multiply_data) -{ - NODE_IN(r32, A); - NODE_IN(r32, B); - NODE_OUT(r32, Result); -}; - -NODE_PROC(MultiplyNodeProc, multiply_data) -{ - Data->Result = Data->A * Data->B; -} - -NODE_STRUCT(add_data) -{ - NODE_IN(v4, A); - NODE_IN(v4, B); - NODE_OUT(v4, Result); -}; - -NODE_PROC(AddNodeProc, add_data) -{ - Data->Result = Data->A + Data->B; -} - -////////////////////////////////////// -// -// OLD - Pre Node System -// -/////////////////////////////////////// - -PATTERN_PUSH_COLOR_PROC(PushColor_Override) -{ - Colors[LED->Index].R = R; - Colors[LED->Index].G = G; - Colors[LED->Index].B = B; -} - -PATTERN_PUSH_COLOR_PROC(PushColor_Add) -{ - Colors[LED->Index].R += R; - Colors[LED->Index].G += G; - Colors[LED->Index].B += B; -} - -PATTERN_PUSH_COLOR_PROC(PushColor_Multiply) -{ - Colors[LED->Index].R *= R; - Colors[LED->Index].G *= G; - Colors[LED->Index].B *= B; -} - -inline u32 -PackColorStruct (u8* Channels) -{ - u32 Result = 0; - Result |= (*Channels++ << 24); - Result |= (*Channels++ << 16); - Result |= (*Channels++ << 8); - Result |= (255 << 0); // Alpha - return Result; -}; - -inline u8 -ToColorU8 (r32 V) -{ - return (u8)(V * 255.f); -} - -inline u32 -PackColorStructFromVector (v4 Color) -{ - u32 Result = ((ToColorU8(Color.r) << 24) | - (ToColorU8(Color.g) << 16) | - (ToColorU8(Color.b) << 8) | - (ToColorU8(Color.a) << 0)); - return Result; -} - -internal void -InitLEDPatternSystem (led_pattern_system* PatternSystem, memory_arena* ParentStorage, - s32 MaxPatternsCount, s32 PatternWorkingMemoryStorageSize) -{ - PatternSystem->Patterns = PushArray(ParentStorage, led_pattern, MaxPatternsCount); - PatternSystem->PatternsUsed = 0; - PatternSystem->PatternsMax = MaxPatternsCount; - - InitMemoryArena(&PatternSystem->PatternWorkingMemoryStorage, PushSize(ParentStorage, PatternWorkingMemoryStorageSize), PatternWorkingMemoryStorageSize, 0); -} - -internal pattern_index_id_key -AddPattern (led_pattern_system* PatternSystem, - pattern_registry_entry* PatternSpec) -{ - Assert(PatternSystem->PatternsUsed < PatternSystem->PatternsMax); - - pattern_index_id_key Result = {}; - - led_pattern* NewPattern = &PatternSystem->Patterns[PatternSystem->PatternsUsed]; - NewPattern->ID = PatternSystem->IDAccumulator++; - NewPattern->Name = PatternSpec->Name; - NewPattern->UpdateProc = PatternSpec->Update; - PatternSpec->Init(NewPattern, &PatternSystem->PatternWorkingMemoryStorage); - - Result.Index = PatternSystem->PatternsUsed++; - Result.ID = NewPattern->ID; - - return Result; -} - -internal b32 -RemovePattern (pattern_index_id_key Key, led_pattern_system* PatternSystem) -{ - b32 Result = false; - s32 ActualIndex = -1; - - if (PatternSystem->Patterns[Key.Index].ID == Key.ID) - { - ActualIndex = Key.Index; - } - else - { - for (s32 i = 0; i < PatternSystem->PatternsUsed; i++) - { - if (PatternSystem->Patterns[i].ID == Key.ID) - { - ActualIndex = i; - break; - } - } - } - - if (ActualIndex >= 0) - { - for (s32 j = ActualIndex; j < PatternSystem->PatternsUsed - 1; j++) - { - PatternSystem->Patterns[j] = PatternSystem->Patterns[j + 1]; - } - - PatternSystem->PatternsUsed--; - - Result = true; - } - else - { - Result = false; - } - - return Result; -} - -internal led_pattern* -FindPatternAndUpdateIDKey (pattern_index_id_key* Key, led_pattern_system* PatternSystem) -{ - led_pattern* Result = 0; - - if (Key->Index < PatternSystem->PatternsUsed && - PatternSystem->Patterns[Key->Index].ID == Key->ID) - { - Result = &PatternSystem->Patterns[Key->Index]; - } - else - { - for (s32 i = 0; i < PatternSystem->PatternsUsed; i++) - { - if (PatternSystem->Patterns[i].ID == Key->ID) - { - Result = &PatternSystem->Patterns[i]; - Key->Index = i; - break; - } - } - } - - return Result; -} - -#if 0 -internal void -UpdateAllPatterns_ (patterns_update_list* UpdateList, - led_pattern_system* PatternSystem, - pattern_led* LEDs, - s32 LEDsCount, - r32 DeltaTime, - memory_arena* Transient) -{ - pattern_push_color_proc* PushColorProc = 0; - - for (s32 PatternKeyIdx = 0; PatternKeyIdx < UpdateList->Used; PatternKeyIdx++) - { - pattern_update_list_entry ListEntry = UpdateList->Patterns[PatternKeyIdx]; - pattern_index_id_key Key = ListEntry.Key; - led_pattern* Pattern = FindPatternAndUpdateIDKey(&Key, PatternSystem); - - if (!Pattern) - { - Pattern = FindPatternAndUpdateIDKey(&Key, PatternSystem); - } - - Pattern->UpdateProc(LEDs, LEDsCount, - Pattern->Memory, - DeltaTime, ListEntry.PushColorProc); - } - - if (UpdateList->Next) - { - UpdateAllPatterns(UpdateList->Next, PatternSystem, LEDs, LEDsCount, DeltaTime, Transient); - } -} -#endif - -internal void -UpdateAllPatterns (patterns_update_list* UpdateList, - led_pattern_system* PatternSystem, - led_buffer* LEDBuffer, - r32 DeltaTime, - memory_arena* Transient) -{ - pattern_push_color_proc* PushColorProc = 0; - - for (s32 PatternKeyIdx = 0; PatternKeyIdx < UpdateList->Used; PatternKeyIdx++) - { - pattern_update_list_entry ListEntry = UpdateList->Patterns[PatternKeyIdx]; - pattern_index_id_key Key = ListEntry.Key; - led_pattern* Pattern = FindPatternAndUpdateIDKey(&Key, PatternSystem); - - if (!Pattern) - { - Pattern = FindPatternAndUpdateIDKey(&Key, PatternSystem); - } - - led_buffer* LEDBufferIter = LEDBuffer; - while(LEDBufferIter) - { - Pattern->UpdateProc(LEDBufferIter->LEDs, LEDBufferIter->Colors, LEDBufferIter->Count, - Pattern->Memory, - DeltaTime, ListEntry.PushColorProc); - LEDBufferIter = LEDBufferIter->Next; - } - } - - if (UpdateList->Next) - { - UpdateAllPatterns(UpdateList->Next, PatternSystem, LEDBuffer, DeltaTime, Transient); - } -} - - diff --git a/foldhaus_patterns.h b/foldhaus_patterns.h deleted file mode 100644 index 0026d50..0000000 --- a/foldhaus_patterns.h +++ /dev/null @@ -1,78 +0,0 @@ -typedef s32 pattern_id; - -typedef struct pattern_led pattern_led; - -#define PATTERN_INIT_PROC(name) void name(led_pattern* Pattern, memory_arena* Storage) -typedef PATTERN_INIT_PROC(pattern_init_proc); - -#define PATTERN_PUSH_COLOR_PROC(name) void name(led* LED, sacn_pixel* Colors, u8 R, u8 G, u8 B) -typedef PATTERN_PUSH_COLOR_PROC(pattern_push_color_proc); - -#define PATTERN_UPDATE_PROC(name) void name(led* LEDs, sacn_pixel* Colors, s32 LEDCount, void* Memory, r32 DeltaTime, pattern_push_color_proc PushColor) -typedef PATTERN_UPDATE_PROC(pattern_update_proc); - -struct pattern_registry_entry -{ - char* Name; - pattern_init_proc* Init; - pattern_update_proc* Update; -}; - -struct pattern_led -{ - s32 LocationInSendBuffer; - u32 Color; - v3 Position; -}; - -enum pattern_selector_combine_operation -{ - PatternSelectorCombine_Invalid, - - PatternSelectorCombine_Override, - PatternSelectorCombine_Add, - PatternSelectorCombine_Multiply, - - PatternSelectorCombine_Count, -}; - -char* PatternSelectorOperationsText[] = { - "Invalid", - - "Override", - "Add", - "Multiply", - - "Count", -}; - -struct pattern_index_id_key -{ - s32 Index; - pattern_id ID; -}; - -struct led_pattern -{ - pattern_id ID; - - void* Memory; - - pattern_update_proc* UpdateProc; - char* Name; -}; - -struct led_pattern_system -{ - // TODO(Peter): Need to think about how this grows - led_pattern* Patterns; - s32 PatternsUsed; - s32 PatternsMax; - - // TODO(Peter): Need to think about how this can have a free list as well of some sort. - // It might be inexpensive enough to just compress this memory whenever we remove a pattern - memory_arena PatternWorkingMemoryStorage; - - - pattern_id IDAccumulator; -}; diff --git a/foldhaus_sacn.h b/foldhaus_sacn.h index c0bb2d8..689ccb3 100644 --- a/foldhaus_sacn.h +++ b/foldhaus_sacn.h @@ -139,6 +139,16 @@ struct sacn_pixel u8 B; }; +internal sacn_pixel +PackFloatsToSACNPixel (r32 R, r32 G, r32 B) +{ + sacn_pixel Result = {}; + Result.R = (u8)(GSClamp01(R) * 255); + Result.G = (u8)(GSClamp01(G) * 255); + Result.B = (u8)(GSClamp01(B) * 255); + return Result; +} + // internal sacn_universe* diff --git a/foldhaus_text_entry.cpp b/foldhaus_text_entry.cpp new file mode 100644 index 0000000..c89d8d4 --- /dev/null +++ b/foldhaus_text_entry.cpp @@ -0,0 +1,63 @@ +FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntryString) +{ + if (State->GeneralPurposeSearch.CursorPosition > 0) + { + RemoveCharAt(&State->GeneralPurposeSearch.Buffer, + State->GeneralPurposeSearch.CursorPosition - 1); + State->GeneralPurposeSearch.CursorPosition--; + } +} + +internal void +ActivateTextEntry(text_input* ActiveEntryString, app_state* State) +{ + State->ActiveTextEntry = ActiveEntryString; + State->ActiveTextEntry->PreviousCommandRegistry = State->ActiveCommands; + State->ActiveCommands = &State->TextEntryCommandRegistry; +} + +internal void +DeactivateTextEntry(app_state* State) +{ + if (State->ActiveTextEntry->PreviousCommandRegistry != 0) + { + State->ActiveCommands = State->ActiveTextEntry->PreviousCommandRegistry; + State->ActiveTextEntry = 0; + } +} + +internal void +AppendInputToEntryString (text_input* EntryString, char* InputString, s32 InputStringLength) +{ + if (InputStringLength > 0) + { + for (s32 i = 0; i < InputStringLength; i++) + { + InsertChar(&EntryString->Buffer, InputString[i], EntryString->CursorPosition); + EntryString->CursorPosition++; + } + } +} + +FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorRight) +{ + State->ActiveTextEntry->CursorPosition = GSMin(State->ActiveTextEntry->Buffer.Length, + State->ActiveTextEntry->CursorPosition + 1); +} + +FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorLeft) +{ + State->ActiveTextEntry->CursorPosition = GSMax(0, + State->ActiveTextEntry->CursorPosition - 1); +} + +internal void +InitializeTextInputCommands (input_command_registry* SearchCommands, memory_arena* PermanentStorage) +{ + if (SearchCommands->Size > 0) + { + RegisterKeyPressCommand(SearchCommands, KeyCode_Backspace, false, KeyCode_Invalid, RemoveCharacterFromEntryString); + RegisterKeyPressCommand(SearchCommands, KeyCode_LeftArrow, false, KeyCode_Invalid, TextEntryMoveCursorLeft); + RegisterKeyPressCommand(SearchCommands, KeyCode_RightArrow, false, KeyCode_Invalid, TextEntryMoveCursorRight); + } +} diff --git a/foldhaus_text_entry.h b/foldhaus_text_entry.h new file mode 100644 index 0000000..eba56ff --- /dev/null +++ b/foldhaus_text_entry.h @@ -0,0 +1,7 @@ +struct text_input +{ + char* Backbuffer; + string Buffer; + s32 CursorPosition; + input_command_registry* PreviousCommandRegistry; +}; \ No newline at end of file diff --git a/generated/foldhaus_nodes_generated.cpp b/generated/foldhaus_nodes_generated.cpp index 931d751..5e9c930 100644 --- a/generated/foldhaus_nodes_generated.cpp +++ b/generated/foldhaus_nodes_generated.cpp @@ -1,17 +1,33 @@ enum node_type { NodeType_OutputNode, +NodeType_FloatValue, +NodeType_VectorValue, NodeType_MultiplyNodeProc, NodeType_AddNodeProc, -NodeType_FloatValueProc, -NodeType_SolidColorProc, -NodeType_SinWaveProc, -NodeType_VectorProc, +NodeType_SinWave, NodeType_MultiplyPatterns, +NodeType_SwdColorProc, +NodeType_SolidColorProc, NodeType_VerticalColorFadeProc, +NodeType_RevolvingDiscs, +NodeType_MichelleColorProc, NodeType_Count, }; +node_struct_member MemberList_float_value_data[] = { +{ MemberType_r32, "Value", (u64)&((float_value_data*)0)->Value, IsInputMember }, +{ MemberType_r32, "Result", (u64)&((float_value_data*)0)->Result, IsOutputMember}, +}; + +node_struct_member MemberList_vector_data[] = { +{ MemberType_r32, "X", (u64)&((vector_data*)0)->X, IsInputMember }, +{ MemberType_r32, "Y", (u64)&((vector_data*)0)->Y, IsInputMember }, +{ MemberType_r32, "Z", (u64)&((vector_data*)0)->Z, IsInputMember }, +{ MemberType_r32, "W", (u64)&((vector_data*)0)->W, IsInputMember }, +{ MemberType_v4, "Result", (u64)&((vector_data*)0)->Result, IsOutputMember}, +}; + node_struct_member MemberList_multiply_data[] = { { MemberType_r32, "A", (u64)&((multiply_data*)0)->A, IsInputMember }, { MemberType_r32, "B", (u64)&((multiply_data*)0)->B, IsInputMember }, @@ -24,16 +40,6 @@ node_struct_member MemberList_add_data[] = { { MemberType_v4, "Result", (u64)&((add_data*)0)->Result, IsOutputMember}, }; -node_struct_member MemberList_float_value_data[] = { -{ MemberType_r32, "Value", (u64)&((float_value_data*)0)->Value, IsInputMember }, -{ MemberType_r32, "Result", (u64)&((float_value_data*)0)->Result, IsOutputMember}, -}; - -node_struct_member MemberList_solid_color_data[] = { -{ MemberType_v4, "Color", (u64)&((solid_color_data*)0)->Color, IsInputMember }, -{ MemberType_NODE_COLOR_BUFFER, "LEDs", (u64)&((solid_color_data*)0)->LEDs, IsInputMember | IsOutputMember}, -}; - node_struct_member MemberList_sin_wave_data[] = { { MemberType_r32, "Period", (u64)&((sin_wave_data*)0)->Period, IsInputMember }, { MemberType_r32, "Min", (u64)&((sin_wave_data*)0)->Min, IsInputMember }, @@ -41,20 +47,23 @@ node_struct_member MemberList_sin_wave_data[] = { { MemberType_r32, "Result", (u64)&((sin_wave_data*)0)->Result, IsOutputMember}, }; -node_struct_member MemberList_vector_data[] = { -{ MemberType_r32, "X", (u64)&((vector_data*)0)->X, IsInputMember }, -{ MemberType_r32, "Y", (u64)&((vector_data*)0)->Y, IsInputMember }, -{ MemberType_r32, "Z", (u64)&((vector_data*)0)->Z, IsInputMember }, -{ MemberType_r32, "W", (u64)&((vector_data*)0)->W, IsInputMember }, -{ MemberType_v4, "Result", (u64)&((vector_data*)0)->Result, IsOutputMember}, -}; - node_struct_member MemberList_multiply_patterns_data[] = { { MemberType_NODE_COLOR_BUFFER, "ALEDs", (u64)&((multiply_patterns_data*)0)->ALEDs, IsInputMember }, { MemberType_NODE_COLOR_BUFFER, "BLEDs", (u64)&((multiply_patterns_data*)0)->BLEDs, IsInputMember }, { MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((multiply_patterns_data*)0)->ResultLEDs, IsOutputMember}, }; +node_struct_member MemberList_swd_color_data[] = { +{ MemberType_v4, "Color", (u64)&((swd_color_data*)0)->Color, IsInputMember }, +{ MemberType_v4, "ColorB", (u64)&((swd_color_data*)0)->ColorB, IsInputMember }, +{ MemberType_NODE_COLOR_BUFFER, "LEDs", (u64)&((swd_color_data*)0)->LEDs, IsInputMember | IsOutputMember}, +}; + +node_struct_member MemberList_solid_color_data[] = { +{ MemberType_v4, "Color", (u64)&((solid_color_data*)0)->Color, IsInputMember }, +{ MemberType_NODE_COLOR_BUFFER, "LEDs", (u64)&((solid_color_data*)0)->LEDs, IsInputMember | IsOutputMember}, +}; + node_struct_member MemberList_vertical_color_fade_data[] = { { MemberType_v4, "Color", (u64)&((vertical_color_fade_data*)0)->Color, IsInputMember }, { MemberType_r32, "Min", (u64)&((vertical_color_fade_data*)0)->Min, IsInputMember }, @@ -62,29 +71,51 @@ node_struct_member MemberList_vertical_color_fade_data[] = { { MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((vertical_color_fade_data*)0)->ResultLEDs, IsOutputMember}, }; +node_struct_member MemberList_revolving_discs_data[] = { +{ MemberType_r32, "Rotation", (u64)&((revolving_discs_data*)0)->Rotation, IsInputMember }, +{ MemberType_r32, "ThetaZ", (u64)&((revolving_discs_data*)0)->ThetaZ, IsInputMember }, +{ MemberType_r32, "ThetaY", (u64)&((revolving_discs_data*)0)->ThetaY, IsInputMember }, +{ MemberType_r32, "DiscWidth", (u64)&((revolving_discs_data*)0)->DiscWidth, IsInputMember }, +{ MemberType_r32, "InnerRadius", (u64)&((revolving_discs_data*)0)->InnerRadius, IsInputMember }, +{ MemberType_r32, "OuterRadius", (u64)&((revolving_discs_data*)0)->OuterRadius, IsInputMember }, +{ MemberType_v4, "Color", (u64)&((revolving_discs_data*)0)->Color, IsInputMember }, +{ MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((revolving_discs_data*)0)->ResultLEDs, IsOutputMember}, +}; + +node_struct_member MemberList_michelle_data[] = { +{ MemberType_v4, "Color", (u64)&((michelle_data*)0)->Color, IsInputMember }, +{ MemberType_NODE_COLOR_BUFFER, "LEDs", (u64)&((michelle_data*)0)->LEDs, IsInputMember | IsOutputMember}, +}; + node_specification NodeSpecifications[] = { +{ NodeType_FloatValue, "FloatValue", 10, MemberList_float_value_data, 8, 2, false}, +{ NodeType_VectorValue, "VectorValue", 11, MemberList_vector_data, 32, 5, false}, { NodeType_MultiplyNodeProc, "MultiplyNodeProc", 16, MemberList_multiply_data, 12, 3, false}, { NodeType_AddNodeProc, "AddNodeProc", 11, MemberList_add_data, 48, 3, false}, -{ NodeType_FloatValueProc, "FloatValueProc", 14, MemberList_float_value_data, 8, 2, false}, -{ NodeType_SolidColorProc, "SolidColorProc", 14, MemberList_solid_color_data, 36, 2, false}, -{ NodeType_SinWaveProc, "SinWaveProc", 11, MemberList_sin_wave_data, 16, 4, false}, -{ NodeType_VectorProc, "VectorProc", 10, MemberList_vector_data, 32, 5, false}, +{ NodeType_SinWave, "SinWave", 7, MemberList_sin_wave_data, 20, 4, false}, { NodeType_MultiplyPatterns, "MultiplyPatterns", 16, MemberList_multiply_patterns_data, 60, 3, false}, +{ NodeType_SwdColorProc, "SwdColorProc", 12, MemberList_swd_color_data, 52, 3, false}, +{ NodeType_SolidColorProc, "SolidColorProc", 14, MemberList_solid_color_data, 36, 2, false}, { NodeType_VerticalColorFadeProc, "VerticalColorFadeProc", 21, MemberList_vertical_color_fade_data, 44, 4, false}, +{ NodeType_RevolvingDiscs, "RevolvingDiscs", 14, MemberList_revolving_discs_data, 60, 8, false}, +{ NodeType_MichelleColorProc, "MichelleColorProc", 17, MemberList_michelle_data, 36, 2, false}, }; -s32 NodeSpecificationsCount = 8; +s32 NodeSpecificationsCount = 11; internal void CallNodeProc(interface_node* Node, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime) { switch (Node->Type) { +case NodeType_FloatValue: { FloatValue((float_value_data*)Data, DeltaTime); } break; +case NodeType_VectorValue: { VectorValue((vector_data*)Data, DeltaTime); } break; case NodeType_MultiplyNodeProc: { MultiplyNodeProc((multiply_data*)Data, DeltaTime); } break; case NodeType_AddNodeProc: { AddNodeProc((add_data*)Data, DeltaTime); } break; -case NodeType_FloatValueProc: { FloatValueProc((float_value_data*)Data, DeltaTime); } break; -case NodeType_SolidColorProc: { SolidColorProc((solid_color_data*)Data, DeltaTime); } break; -case NodeType_SinWaveProc: { SinWaveProc((sin_wave_data*)Data, DeltaTime); } break; -case NodeType_VectorProc: { VectorProc((vector_data*)Data, DeltaTime); } break; +case NodeType_SinWave: { SinWave((sin_wave_data*)Data, DeltaTime); } break; case NodeType_MultiplyPatterns: { MultiplyPatterns((multiply_patterns_data*)Data, DeltaTime); } break; +case NodeType_SwdColorProc: { SwdColorProc((swd_color_data*)Data, DeltaTime); } break; +case NodeType_SolidColorProc: { SolidColorProc((solid_color_data*)Data, DeltaTime); } break; case NodeType_VerticalColorFadeProc: { VerticalColorFadeProc((vertical_color_fade_data*)Data, DeltaTime); } break; +case NodeType_RevolvingDiscs: { RevolvingDiscs((revolving_discs_data*)Data, DeltaTime); } break; +case NodeType_MichelleColorProc: { MichelleColorProc((michelle_data*)Data, DeltaTime); } break; } } diff --git a/gs_language.h b/gs_language.h index 051c6ff..d1b233a 100644 --- a/gs_language.h +++ b/gs_language.h @@ -171,11 +171,16 @@ GSMaxDef(r32) GSMaxDef(r64) #undef GSMaxDef +inline b32 XOR(b32 A, b32 B) +{ + b32 Result = (A == !B); + return Result; +} #define GSClampDef(type) static type GSClamp(type Min, type V, type Max) { \ - type Result = V; \ - if (V < Min) { Result = Min; } \ - if (V > Max) { Result = Max; } \ - return Result; \ + type Result = V; \ + if (V < Min) { Result = Min; } \ + if (V > Max) { Result = Max; } \ + return Result; \ } GSClampDef(s8) GSClampDef(s16) diff --git a/gs_platform.h b/gs_platform.h index 97295db..266e3b9 100644 --- a/gs_platform.h +++ b/gs_platform.h @@ -81,7 +81,7 @@ typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file); #define PLATFORM_WRITE_ENTIRE_FILE(name) b32 name(char* Path, u8* Contents, s32 Size) typedef PLATFORM_WRITE_ENTIRE_FILE(platform_write_entire_file); -#define PLATFORM_GET_FILE_PATH(name) b32 name(char* PathBuffer, s32 BufferLength) +#define PLATFORM_GET_FILE_PATH(name) b32 name(char* PathBuffer, s32 BufferLength, const char* FilterStrings) typedef PLATFORM_GET_FILE_PATH(platform_get_file_path); #define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height) @@ -233,6 +233,7 @@ KeyTransitionedUp (input Input, key_code Key) { return !Input.New->KeysDown[Key] && Input.Old->KeysDown[Key]; } + #endif // GS_INPUT internal window PlatformCreateWindow (char* Name, s32 Width, s32 Height); diff --git a/gs_string.h b/gs_string.h index 76d5a98..9548c29 100644 --- a/gs_string.h +++ b/gs_string.h @@ -1,3 +1,4 @@ +#ifndef GS_STRING_H //////////////////////////////////////////////////////////////// // String //////////////////////////////////////////////////////////////// @@ -98,9 +99,7 @@ char* TokenNames[] = { struct token { token_type Type; - char* Text; - s32 TextLength; - + string Text; token* Next; }; @@ -150,8 +149,10 @@ static float GSPowF (float N, s32 Power); #define PushString(str, arena, size) (str)->Memory = PushArray(arena, char, size); (str)->Length = 0; (str)->Max = size; #endif -static void InitializeString (string* String, char* Data, s32 DataSize); -static string InitializeString (char* Data, s32 DataSize); +static void InitializeEmptyString (string* String, char* Data, s32 DataSize); +static void InitializeString(string* String, char* Data, s32 Used, s32 Max); +static string InitializeEmptyString (char* Data, s32 DataSize); +static string InitializeString (char* Data, s32 Used, s32 Max); static void ClearString (string* String); // Character Values @@ -161,12 +162,13 @@ static bool IsWhitespace (char C); static bool IsAlpha (char C); static bool IsUpper (char C); static bool IsLower (char C); +static char ToUpper (char C); +static char ToLower (char C); static bool IsNumeric (char C); static bool IsNumericExtended (char C); -static bool ToUpper (char C); -static bool ToLower (char C); static bool IsAlphaNumeric (char C); static bool IsOperator (char C); +static bool CharsEqualCaseInsensitive(char A, char B); // Tokenizing static b32 AtValidPosition(tokenizer Tokenizer); @@ -240,6 +242,11 @@ static s32 LastIndexOfChar(string String, char C); static string Substring (string* String, s32 Start, s32 End); static string Substring (string* String, s32 Start); +static b32 StringContainsCharArray(string SearchIn, char* SearchFor, s32 SearchForLength); +static b32 StringContainsString(string SearchIn, string SearchFor); +static b32 StringContainsCharArrayCaseInsensitive(string SearchIn, char* SearchFor, s32 SearchForLength); +static b32 StringContainsStringCaseInsensitive(string SearchIn, string SearchFor); + static void NullTerminate (string* String); @@ -339,15 +346,23 @@ GSPow (float N, s32 Power) //////////////////////////////////////////////////////////////// static void -InitializeString (string* String, char* Data, s32 DataSize) +InitializeEmptyString (string* String, char* Data, s32 DataSize) { String->Memory = Data; String->Max = DataSize; String->Length = 0; } +static void +InitializeString(string* String, char* Data, s32 Used, s32 Max) +{ + String->Memory = Data; + String->Max = Max; + String->Length = Used; +} + static string -InitializeString (char* Data, s32 DataSize) +InitializeEmptyString (char* Data, s32 DataSize) { string Result = {}; Result.Memory = Data; @@ -356,6 +371,16 @@ InitializeString (char* Data, s32 DataSize) return Result; } +static string +InitializeString (char* Data, s32 Used, s32 Max) +{ + string Result = {}; + Result.Memory = Data; + Result.Max = Max; + Result.Length = Used; + return Result; +} + static void ClearString (string* String) { @@ -407,6 +432,30 @@ static bool IsOperator (char C) (C == '<') || (C == '>')); } +static char ToUpper (char A) +{ + char Result = A; + if (IsLower(A)) + { + Result += 'A' - 'a'; + } + return Result; +} +static char ToLower (char A) +{ + char Result = A; + if (IsUpper(A)) + { + Result -= 'A' - 'a'; + } + return Result; +} +static bool CharsEqualCaseInsensitive (char A, char B) +{ + b32 Result = (ToLower(A) == ToLower(B)); + return Result; +} + //////////////////////////////////////////////////////////////// // Tokenizing //////////////////////////////////////////////////////////////// @@ -1050,7 +1099,7 @@ InsertChar (string* String, char Char, s32 Index) Assert(Index >= 0 && Index < String->Max); Assert(String->Length < String->Max); - char* Src = String->Memory + String->Length; + char* Src = String->Memory + String->Length - 1; char* Dst = Src + 1; for (int i = String->Length - 1; i >= Index; i--) { @@ -1132,6 +1181,74 @@ Substring (string String, s32 Start) return Result; } +static b32 +StringContainsCharArray(string SearchIn, char* SearchFor, s32 SearchForLength) +{ + b32 Result = false; + + char* SearchInAt = SearchIn.Memory; + for (s32 i = 0; i < (SearchIn.Length - SearchForLength) + 1; i++) + { + char* InAt = SearchInAt; + char* ForAt = SearchFor; + s32 LengthMatch = 0; + while (*InAt == *ForAt) + { + InAt++; + ForAt++; + LengthMatch++; + } + if (LengthMatch == SearchForLength) + { + Result = true; + break; + } + SearchInAt++; + } + + return Result; +} + +static b32 +StringContainsString(string SearchIn, string SearchFor) +{ + return StringContainsCharArray(SearchIn, SearchFor.Memory, SearchFor.Length); +} + +static b32 +StringContainsCharArrayCaseInsensitive(string SearchIn, char* SearchFor, s32 SearchForLength) +{ + b32 Result = false; + + char* SearchInAt = SearchIn.Memory; + for (s32 i = 0; i < (SearchIn.Length - SearchForLength) + 1; i++) + { + char* InAt = SearchInAt; + char* ForAt = SearchFor; + s32 LengthMatch = 0; + while (CharsEqualCaseInsensitive(*InAt, *ForAt)) + { + InAt++; + ForAt++; + LengthMatch++; + } + if (LengthMatch == SearchForLength) + { + Result = true; + break; + } + SearchInAt++; + } + + return Result; +} + +static b32 +StringContainsStringCaseInsensitive(string SearchIn, string SearchFor) +{ + return StringContainsCharArrayCaseInsensitive(SearchIn, SearchFor.Memory, SearchFor.Length); +} + static void NullTerminate (string* String) { @@ -2081,3 +2198,6 @@ TestStrings() #endif // DEBUG_GS_STRING #endif // DEBUG + +#define GS_STRING_H +#endif // GS_STRING_H \ No newline at end of file diff --git a/gs_win32.cpp b/gs_win32.cpp index ae29243..03c3217 100644 --- a/gs_win32.cpp +++ b/gs_win32.cpp @@ -727,6 +727,27 @@ GetFileLastWriteTime(char* Path) PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile) { b32 Result = false; + + PathBuffer[0] = 0; + + OPENFILENAMEA OpenFileName = {}; + OpenFileName.lStructSize = sizeof(OpenFileName); + OpenFileName.hwndOwner = NULL; + OpenFileName.lpstrFilter = FilterStrings; + OpenFileName.lpstrCustomFilter = NULL; // NOTE(Peter): for preserving last filter string chosen + OpenFileName.nMaxCustFilter = 0; // NOTE(Peter): ignored since we left CustomFilter null + OpenFileName.nFilterIndex = 1; + OpenFileName.lpstrFile = PathBuffer; + OpenFileName.nMaxFile = BufferLength; + OpenFileName.lpstrFileTitle = NULL; + OpenFileName.nMaxFileTitle = 0; // NOTE(Peter): Ignored since fileTitle is null + OpenFileName.lpstrInitialDir = NULL; + OpenFileName.lpstrTitle = NULL; + OpenFileName.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST; + OpenFileName.lpstrDefExt = NULL; + + Result = GetOpenFileNameA (&OpenFileName); + return Result; } diff --git a/interface.h b/interface.h index 3d52358..d146dd2 100644 --- a/interface.h +++ b/interface.h @@ -1,112 +1,27 @@ -// NOTE(Peter): This stuff was all a test to see how I could do panel splitting. Thinking about moving away -// from that for now. Might return later if necessary -// TODO(Peter): Finish this if necessary - -struct interface_region -{ - v2 Min, Max; - union - { - struct - { - interface_region* A; - interface_region* B; - }; - struct - { - interface_region* Left; - interface_region* Right; - }; - struct - { - interface_region* Top; - interface_region* Bottom; - }; - }; -}; - -struct interface_tracker +internal v2 +DrawCharacter (render_quad_batch_constructor* BatchConstructor, char C, bitmap_font Font, v2 Position, v4 Color, r32 FontScale) { - memory_arena* Storage; - interface_region RootRegion; -}; - -enum interface_region_split -{ - InterfaceRegionSplit_Vertical, - InterfaceRegionSplit_Horizontal, -}; - -inline s32 -RegionWidth (interface_region Region) -{ - s32 Result = Region.Max.x - Region.Min.x; - return Result; -} - -inline s32 -RegionHeight (interface_region Region) -{ - s32 Result = Region.Max.y - Region.Min.y; - return Result; -} - -internal void -SplitRegion (interface_tracker* Tracker, interface_region* Parent, s32 SplitPosition, interface_region_split SplitDirection) -{ - if (!Parent->A) - { - interface_region* A = PushStruct(Tracker->Storage, interface_region); - A->A = 0; - A->B = 0; - Parent->A = A; - } - Parent->A->Min = Parent->Min; - Parent->A->Max = Parent->Max; + s32 GlyphDataIndex = GetIndexForCodepoint(Font, C); + codepoint_bitmap CodepointInfo = Font.CodepointValues[GlyphDataIndex]; - if (!Parent->B) - { - interface_region* B = PushStruct(Tracker->Storage, interface_region); - B->A = 0; - B->B = 0; - Parent->B = B; - } - Parent->B->Min = Parent->Min; - Parent->B->Max = Parent->Max; + r32 MinX = Position.x + CodepointInfo.XOffset * FontScale; + r32 MinY = Position.y + CodepointInfo.YOffset * FontScale; + r32 MaxX = MinX + (CodepointInfo.Width) * FontScale; + r32 MaxY = MinY + (CodepointInfo.Height) * FontScale; - switch (SplitDirection) - { - case InterfaceRegionSplit_Vertical: - { - Parent->Left->Max.x = Parent->Min.x + SplitPosition; - Parent->Right->Min.x = Parent->Min.x + SplitPosition; - }break; - - case InterfaceRegionSplit_Horizontal: - { - Parent->Bottom->Max.y = Parent->Min.y + SplitPosition; - Parent->Top->Min.y = Parent->Min.y + SplitPosition; - }break; - } -} - -internal interface_tracker -CreateInterfaceTracker (memory_arena* Storage, s32 ScreenWidth, s32 ScreenHeight) -{ - interface_tracker Result = {}; - Result.Storage = Storage; - Result.RootRegion.A = 0; - Result.RootRegion.B = 0; - Result.RootRegion.Min = v2{0, 0}; - Result.RootRegion.Max = v2{(r32)ScreenWidth, (r32)ScreenHeight}; - return Result; + PushQuad2DOnBatch(BatchConstructor, + v2{MinX, MinY}, v2{MaxX, MinY}, + v2{MaxX, MaxY}, v2{MinX, MaxY}, + CodepointInfo.UVMin, CodepointInfo.UVMax, + Color); + + return v2{Position.x + CodepointInfo.Width * FontScale, Position.y}; } internal v2 DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Font, s32 PointSize, v2 Position, v4 Color) { DEBUG_TRACK_FUNCTION; - v2 LowerRight = Position; render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, String.Length, @@ -122,21 +37,8 @@ DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Fon char* C = String.Memory; for (s32 i = 0; i < String.Length; i++) { - s32 GlyphDataIndex = GetIndexForCodepoint(*Font, *C); - codepoint_bitmap CodepointInfo = Font->CodepointValues[GlyphDataIndex]; - - r32 MinX = RegisterPosition.x + CodepointInfo.XOffset * FontScale; - r32 MinY = RegisterPosition.y + CodepointInfo.YOffset * FontScale; - r32 MaxX = MinX + (CodepointInfo.Width) * FontScale; - r32 MaxY = MinY + (CodepointInfo.Height) * FontScale; - - PushQuad2DOnBatch(&BatchConstructor, - v2{MinX, MinY}, v2{MaxX, MinY}, - v2{MaxX, MaxY}, v2{MinX, MaxY}, - CodepointInfo.UVMin, CodepointInfo.UVMax, - Color); - - RegisterPosition.x += CodepointInfo.Width * FontScale; + v2 PositionAfterCharacter = DrawCharacter(&BatchConstructor, *C, *Font, RegisterPosition, Color, FontScale); + RegisterPosition.x = PositionAfterCharacter.x; C++; } @@ -145,6 +47,54 @@ DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Fon return LowerRight; } +internal void +DrawCursor (render_quad_batch_constructor* BatchConstructor, v2 Position, v4 Color, bitmap_font Font, r32 FontScale) +{ + v2 Min = Position; + v2 Max = Position + v2{(r32)Font.MaxCharWidth * FontScale, Font.Ascent + Font.Descent * FontScale}; + PushQuad2DOnBatch(BatchConstructor, Min, Max, Color); +} + +internal v2 +DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 CursorPosition, bitmap_font* Font, s32 PointSize, v2 Position, v4 Color, v4 CursorColor) +{ + DEBUG_TRACK_FUNCTION; + v2 LowerRight = Position; + + // NOTE(Peter): We push this on first so that the cursor will be drawn underneath any character it may overlap with + render_quad_batch_constructor CursorBatch = PushRenderQuad2DBatch(RenderBuffer, 1); + render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, String.Length, + Font->BitmapMemory, + Font->BitmapTextureHandle, + Font->BitmapWidth, + Font->BitmapHeight, + Font->BitmapBytesPerPixel, + Font->BitmapStride); + + r32 FontScale = (r32)PointSize / Font->PixelHeight; + v2 RegisterPosition = Position; + char* C = String.Memory; + for (s32 i = 0; i < String.Length; i++) + { + if (i == CursorPosition) + { + DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font, FontScale); + } + + v2 PositionAfterCharacter = DrawCharacter(&BatchConstructor, *C, *Font, RegisterPosition, Color, FontScale); + RegisterPosition.x = PositionAfterCharacter.x; + C++; + } + + if (CursorPosition == String.Length) + { + DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font, FontScale); + } + + LowerRight.x = RegisterPosition.x; + return LowerRight; +} + struct interface_config { v4 PanelBGColors[4]; @@ -162,11 +112,17 @@ struct button_result }; internal button_result -EvaluateButton_ (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label, interface_config Config, input Input, v4 BGColor) +EvaluateButton (render_command_buffer* RenderBuffer, + v2 Min, v2 Max, v2 Margin, string Label, + v4 IdleBGColor, v4 HotBGColor, v4 IdleTextColor, v4 HotTextColor, + bitmap_font* Font, input Input) { button_result Result = {}; Result.Pressed = false; + v4 BGColor = IdleBGColor; + v4 TextColor = IdleTextColor; + v2 MousePos = v2{(r32)Input.New->MouseX, (r32)Input.New->MouseY}; if (PointIsInRange(MousePos, Min, Max)) { @@ -176,21 +132,26 @@ EvaluateButton_ (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Lab } else { - BGColor = Config.ButtonColor_Active; + BGColor = HotBGColor; + TextColor = HotTextColor; } } PushRenderQuad2D(RenderBuffer, Min, Max, BGColor); - DrawString(RenderBuffer, Label, Config.Font, Config.Font->PixelHeight, Min + Config.Margin, Config.TextColor); + DrawString(RenderBuffer, Label, Font, Font->PixelHeight, Min + Margin, TextColor); - Result.Advance = (Max.y - Min.y) + Config.Margin.y; + Result.Advance = (Max.y - Min.y) + Margin.y; return Result; } internal button_result EvaluateButton (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label, interface_config Config, input Input) { - button_result Result = EvaluateButton_(RenderBuffer, Min, Max, Label, Config, Input, Config.ButtonColor_Inactive); + button_result Result = EvaluateButton(RenderBuffer, + Min, Max, Config.Margin, Label, + Config.ButtonColor_Inactive, Config.ButtonColor_Active, + Config.TextColor, Config.TextColor, + Config.Font, Input); return Result; } @@ -203,7 +164,11 @@ EvaluateSelectableButton (render_command_buffer* RenderBuffer, v2 Min, v2 Max, s BGColor = Config.ButtonColor_Selected; } - button_result Result = EvaluateButton_(RenderBuffer, Min, Max, Label, Config, Input, BGColor); + button_result Result = EvaluateButton(RenderBuffer, + Min, Max, Config.Margin, Label, + Config.ButtonColor_Inactive, Config.ButtonColor_Active, + Config.TextColor, Config.TextColor, + Config.Font, Input); return Result; } @@ -592,4 +557,80 @@ EvaluateColorPicker (render_command_buffer* RenderBuffer, v4* Value, v2 PanelMin } return ShouldClose; +} + +struct search_lister_result +{ + s32 HotItem; + b32 ShouldRemainOpen; +}; + +typedef char* search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, s32 Offset); + +internal search_lister_result +EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimension, string Title, + s32 ListLength, u8* ListMemory, s32 HotItem, search_lister_get_list_item_at_offset* GetListItem, + string* SearchString, s32 SearchStringCursorPosition, + bitmap_font* Font, interface_config Config, input Input) +{ + Assert(GetListItem != 0); + + search_lister_result Result = {}; + Result.ShouldRemainOpen = true; + Result.HotItem = HotItem; + + // NOTE(Peter): These are direction reversed because going up the list in terms of indicies is + // visually displayed as going down. + if (KeyTransitionedDown(Input, KeyCode_DownArrow)) + { + Result.HotItem = GSMin(Result.HotItem + 1, ListLength - 1); + } + if (KeyTransitionedDown(Input, KeyCode_UpArrow)) + { + Result.HotItem = GSMax(0, Result.HotItem - 1); + } + + // Title Bar + PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f}); + DrawString(RenderBuffer, Title, Font, 14, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4); + TopLeft.y -= 30; + + // Search Bar + PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f}); + DrawStringWithCursor(RenderBuffer, *SearchString, SearchStringCursorPosition, Font, 14, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4); + TopLeft.y -= 30; + + s32 VisibleItemIndex = 0; + for (s32 i = 0; i < ListLength; i++) + { + char* ListItemText = GetListItem(ListMemory, ListLength, i); + Assert(ListItemText); + string ListItemString = MakeStringLiteral(ListItemText); + + if (SearchString->Length == 0 || + StringContainsStringCaseInsensitive(ListItemString, *SearchString)) + { + v2 Min = v2{TopLeft.x, TopLeft.y - 30}; + v2 Max = Min + Dimension - v2{0, Config.Margin.y}; + + v4 ButtonColor = Config.ButtonColor_Inactive; + if (VisibleItemIndex == HotItem) + { + ButtonColor = Config.ButtonColor_Active; + } + + button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemString, + ButtonColor, ButtonColor, Config.TextColor, Config.TextColor, + Config.Font, Input); + if (Button.Pressed) + { + Result.HotItem = i; + } + + TopLeft.y -= 30; + VisibleItemIndex++; + } + } + + return Result; } \ No newline at end of file diff --git a/kraftwerks_patterns.h b/kraftwerks_patterns.h new file mode 100644 index 0000000..2435d7e --- /dev/null +++ b/kraftwerks_patterns.h @@ -0,0 +1,27 @@ +// This file left empty for SwD Kraftwerks + + +NODE_STRUCT(swd_color_data) +{ + NODE_IN(v4, Color); + NODE_IN(v4, ColorB); + NODE_COLOR_BUFFER_INOUT; +}; + +NODE_PROC(SwdColorProc, swd_color_data) +{ + u8 R = (u8)GSClamp(0.f, (Data->Color.r * 255), 255.f); + u8 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f); + u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f); + + led* LED = Data->LEDs; + for (s32 l = 0; l < Data->LEDCount; l++) + { + Assert(LED->Index >= 0 && LED->Index < Data->LEDCount); + + Data->Colors[LED->Index].R = R; + Data->Colors[LED->Index].G = R; + Data->Colors[LED->Index].B = R; + LED++; + } +} diff --git a/patterns_registry.h b/patterns_registry.h deleted file mode 100644 index bef0080..0000000 --- a/patterns_registry.h +++ /dev/null @@ -1,6 +0,0 @@ -pattern_registry_entry PatternRegistry[] = -{ - {"Solid", SolidPatternInitProc, SolidPatternUpdateProc}, - {"Rainbow", InitRainbowPatternProc, RainbowPatternProc}, - {"Radial", InitRadialProc, UpdateRadialProc}, -}; \ No newline at end of file diff --git a/test_patterns.h b/test_patterns.h index 061ce29..15234e3 100644 --- a/test_patterns.h +++ b/test_patterns.h @@ -1,13 +1,3 @@ -NODE_STRUCT(float_value_data) -{ - NODE_IN(r32, Value); - NODE_OUT(r32, Result); -}; - -NODE_PROC(FloatValueProc, float_value_data) -{ - Data->Result = Data->Value; -} NODE_STRUCT(solid_color_data) { @@ -33,85 +23,6 @@ NODE_PROC(SolidColorProc, solid_color_data) } } -NODE_STRUCT(sin_wave_data) -{ - NODE_IN(r32, Period); - NODE_IN(r32, Min); - NODE_IN(r32, Max); - NODE_OUT(r32, Result); - - r32 Accumulator; -}; - -NODE_PROC(SinWaveProc, sin_wave_data) -{ - Data->Accumulator += DeltaTime; - if (Data->Period > 0) - { - while (Data->Accumulator > Data->Period) - { - Data->Accumulator -= Data->Period; - } - - r32 ActualMin = GSMin(Data->Min, Data->Max); - r32 ActualMax = GSMax(Data->Min, Data->Max); - r32 SinResult = GSSin((Data->Accumulator / Data->Period) * PI * 2); - Data->Result = GSRemap(SinResult, -1.f, 1.f, ActualMin, ActualMax); - } - else - { - Data->Result = 0; - } -} - -NODE_STRUCT(vector_data) -{ - NODE_IN(r32, X); - NODE_IN(r32, Y); - NODE_IN(r32, Z); - NODE_IN(r32, W); - NODE_OUT(v4, Result); -}; - -NODE_PROC(VectorProc, vector_data) -{ - Data->Result = v4{Data->X, Data->Y, Data->Z, Data->W}; -} - -NODE_STRUCT(multiply_patterns_data) -{ - NODE_COLOR_BUFFER_IN(A); - NODE_COLOR_BUFFER_IN(B); - NODE_COLOR_BUFFER_OUT(Result); -}; - -NODE_PROC(MultiplyPatterns, multiply_patterns_data) -{ - led* LED = Data->ResultLEDs; - for (s32 l = 0; l < Data->ResultLEDCount; l++) - { - Assert(LED->Index >= 0 && LED->Index < Data->ResultLEDCount); - - s32 AR = Data->AColors[LED->Index].R; - s32 AG = Data->AColors[LED->Index].G; - s32 AB = Data->AColors[LED->Index].B; - - s32 BR = Data->BColors[LED->Index].R; - s32 BG = Data->BColors[LED->Index].G; - s32 BB = Data->BColors[LED->Index].B; - - s32 RCombined = (AR * BR) / 255; - s32 GCombined = (AG * BG) / 255; - s32 BCombined = (AB * BB) / 255; - - Data->ResultColors[LED->Index].R = (u8)RCombined; - Data->ResultColors[LED->Index].G = (u8)GCombined; - Data->ResultColors[LED->Index].B = (u8)BCombined; - - LED++; - } -} - NODE_STRUCT(vertical_color_fade_data) { NODE_IN(v4, Color); @@ -143,114 +54,77 @@ NODE_PROC(VerticalColorFadeProc, vertical_color_fade_data) } } -// ^^^ New ^^^ -// vvv Old vvv - -PATTERN_INIT_PROC(SolidPatternInitProc) +// Original -> DiscPatterns.pde : Revolving Discs +NODE_STRUCT(revolving_discs_data) { - Pattern->Memory = (void*)PushArray(Storage, u8, 3); - - u8* Color = (u8*)Pattern->Memory; - Color[0] = 0; - Color[1] = 0; - Color[2] = 128; -} - -PATTERN_UPDATE_PROC(SolidPatternUpdateProc) -{ - u8* Color = (u8*)Memory; - u8 R = Color[0]; - u8 G = Color[1]; - u8 B = Color[2]; - - led* LED = LEDs; - for (s32 l = 0; l < LEDCount; l++) - { - PushColor(LED++, Colors, R, G, B); - } -} - -struct rainbow_pattern_memory -{ - r32 TimeAccumulator; - r32 Period; + NODE_IN(r32, Rotation); + NODE_IN(r32, ThetaZ); + NODE_IN(r32, ThetaY); + NODE_IN(r32, DiscWidth); + NODE_IN(r32, InnerRadius); + NODE_IN(r32, OuterRadius); + NODE_IN(v4, Color); + NODE_COLOR_BUFFER_OUT(Result); }; -PATTERN_INIT_PROC(InitRainbowPatternProc) +NODE_PROC(RevolvingDiscs, revolving_discs_data) { - Pattern->Memory = (void*)PushStruct(Storage, rainbow_pattern_memory); - rainbow_pattern_memory* Mem = (rainbow_pattern_memory*)Pattern->Memory; - Mem->TimeAccumulator = 0; - Mem->Period = 6.0f; -} - -PATTERN_UPDATE_PROC(RainbowPatternProc) -{ - DEBUG_TRACK_SCOPE(RainbowPatternProc); + sacn_pixel Color = PackFloatsToSACNPixel(Data->Color.r, Data->Color.g, Data->Color.b); - rainbow_pattern_memory* Mem = (rainbow_pattern_memory*)Memory; - Mem->TimeAccumulator += DeltaTime; - if (Mem->TimeAccumulator >= Mem->Period) + v3 Center = v3{0, 0, 0}; + v3 Normal = v3{GSCos(Data->ThetaZ), 0, GSSin(Data->ThetaZ)}; // NOTE(Peter): dont' need to normalize. Should always be 1 + v3 Right = Cross(Normal, v3{0, 1, 0}); + //Normal = RotateAround(Data->ThetaY, Right); + + v3 FrontCenter = Center + (Normal * Data->DiscWidth); + v3 BackCenter = Center - (Normal * Data->DiscWidth); + + led* LED = Data->ResultLEDs; + for (s32 l = 0; l < Data->ResultLEDCount; l++) { - Mem->TimeAccumulator -= Mem->Period; - } - - r32 Percent = Mem->TimeAccumulator / Mem->Period; - r32 HueAdd = Percent * 360.0f; - - r32 HueScale = 360.0f / 100; - - led* LED = LEDs; - for (s32 l = 0; l < LEDCount; l++) - { - r32 Hue = (LED->Position.y * HueScale) + HueAdd; - v4 Color = HSVToRGB(v4{Hue, 1, 1, 1}) * .75f; + v3 Position = LED->Position; - PushColor(LED++, Colors, (u8)(Color.r * 255), (u8)(Color.g * 255), (u8)(Color.b * 255)); - } -} - -PATTERN_INIT_PROC(InitRadialProc) -{ - Pattern->Memory = (void*)PushStruct(Storage, rainbow_pattern_memory); - rainbow_pattern_memory* Mem = (rainbow_pattern_memory*)Pattern->Memory; - Mem->TimeAccumulator = 0; - Mem->Period = 10.0; -} - -PATTERN_UPDATE_PROC(UpdateRadialProc) -{ - - rainbow_pattern_memory* Mem = (rainbow_pattern_memory*)Memory; - Mem->TimeAccumulator += DeltaTime; - if (Mem->TimeAccumulator >= Mem->Period) - { - Mem->TimeAccumulator -= Mem->Period; - } - - r32 Percent = Mem->TimeAccumulator / Mem->Period; - r32 AngleAdd = Percent * PI * 2; - r32 HueAdd = Percent * 360; - - v2 DirectionVector = v2{GSSin(AngleAdd), GSCos(AngleAdd)}; - - led* LED = LEDs; - for (s32 l = 0; l < LEDCount; l++) - { - v4 Color = {0, 0, 0, 1}; + v3 ToFront = Normalize(Position + FrontCenter); + v3 ToBack = Normalize(Position + BackCenter); - if (LED->Position.y >= 70) + r32 ToFrontDotNormal = Dot(ToFront, Normal); + r32 ToBackDotNormal = Dot(ToBack, Normal); + + ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000); + ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000); + + r32 DistToCenter = Mag(Position); + if (DistToCenter < Data->OuterRadius && DistToCenter > Data->InnerRadius) { - v2 TwoDPos = v2{LED->Position.x, LED->Position.z}; - r32 Angle = Dot(Normalize(TwoDPos), DirectionVector) * .25f; - r32 Hue = Angle * 360 + HueAdd; - Color = HSVToRGB(v4{Hue, 1, 1, 1}) * .9f; + if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0)) + { + Data->ResultColors[LED->Index] = Color; + } } - else - { - Color = HSVToRGB(v4{HueAdd, 1, 1, 1}) * .9f; - } - - PushColor(LED++, Colors, (u8)(Color.r * 255), (u8)(Color.g * 255), (u8)(Color.b * 255)); + LED++; } -} \ No newline at end of file +} + +NODE_STRUCT(michelle_data) +{ + NODE_IN(v4, Color); + NODE_COLOR_BUFFER_INOUT; +}; + +NODE_PROC(MichelleColorProc, michelle_data) +{ + u8 R = (u8)GSClamp(0.f, (Data->Color.r * 255), 255.f); + u8 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f); + u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f); + + led* LED = Data->LEDs; + for (s32 l = 0; l < Data->LEDCount; l++) + { + Assert(LED->Index >= 0 && LED->Index < Data->LEDCount); + + Data->Colors[LED->Index].R = R; + Data->Colors[LED->Index].G = G; + Data->Colors[LED->Index].B = B; + LED++; + } +} diff --git a/todo.txt b/todo.txt index cf5c90b..105d8c0 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,15 @@ TODO FOLDHAUS +Hardening +- input context changes +- x don't type into the search bar when its not open +- x don't type into the search bar when you press a to open it +- - type into text boxes +- - shift drag to 10x drag speed +- select nodes -> delete nodes + Name -x lumen lab - Splash screen (like blender) (thisll be fun) -- x Create Image - - Image importer (stb image? or find a png > bmp converter for the image you have) - - Display on startup @@ -14,12 +20,8 @@ x Keep an eye out. Application - More efficient HSV <-> RGB -x Load/Unload sculptures -- - Make sure that we offload unloading until after all jobs are completed. Otherwise they'll try and write -- to data that doesn't exist - Save and load a session -- - Serialize Channels -- - Serialize Patterns +- - Serialize Nodes - Don't render if the window isn't visible Development @@ -39,7 +41,6 @@ Interface Switch To Nodes x basic node elements - - evaluation step (one node at a time) -- - search nodes by name - - selector node (has a list of connections that it can switch between) - serialize - delete nodes @@ -68,10 +69,6 @@ Animation Command Line - select a channel/pattern -- Channel: Add/remove pattern by name -- Channel: Set Blend Mode -- Channel: Set Current Pattern -- Pattern: Edit parameter values Optimization - patterns are asking to be multithreaded diff --git a/win32_foldhaus.cpp b/win32_foldhaus.cpp index 5c04e2b..0b66267 100644 --- a/win32_foldhaus.cpp +++ b/win32_foldhaus.cpp @@ -394,9 +394,12 @@ HandleWindowMessage (MSG Message, window* Window, input_frame* InputFrame) { int VirtualKey = (int)Message.wParam; bool KeyDown = (Message.lParam & (1 << 31)) == 0; - int KeyIndex = Win32GetKeyIndex(VirtualKey, true, false); + int KeyIndex = Win32GetKeyIndex(VirtualKey, true, true); if (KeyIndex == WIN32_SHOULD_TRANSLATE_TO_CHAR) { + KeyIndex = Win32GetKeyIndex(VirtualKey, true, false); + InputFrame->KeysDown[KeyIndex] = KeyDown; + TranslateMessage(&Message); DispatchMessage(&Message); }