diff --git a/bin/gen_incenter_cities.js b/bin/gen_incenter_cities.js index bf78e0c..f620272 100644 --- a/bin/gen_incenter_cities.js +++ b/bin/gen_incenter_cities.js @@ -2,7 +2,7 @@ const fs = require("fs"); const IN_FILE_PATH_PRIMARY = "../run_tree/data/cities_final.json"; const IN_FILE_PATH_SECONDARY = "../run_tree/data/cities_secondary_final.json"; -const OUT_FILE_PATH = "../src_v2/user_space/incenter_gen_cities.h" +const OUT_FILE_PATH = "../src/user_space/incenter_gen_cities.h" function print_city_desc (city, prefix, dest, gets_own_universe) { diff --git a/build/build.sh b/build/build.sh index 832c948..85c426f 100755 --- a/build/build.sh +++ b/build/build.sh @@ -3,7 +3,3 @@ set -e SCRIPT_REL_DIR=$(dirname "${BASH_SOURCE[0]}") $SCRIPT_REL_DIR/build_.sh debug osx arm64 # $SCRIPT_REL_DIR/build_.sh debug wasm intel - -# pushd "run_tree/raspi/arm64/debug" -# clang -o lumenarium /home/pi/dev/Lumenarium/src_v2/platform/raspi/lumenarium_first_raspi.c -lm -# popd diff --git a/build/build_.sh b/build/build_.sh index 68daf04..babe282 100755 --- a/build/build_.sh +++ b/build/build_.sh @@ -95,11 +95,11 @@ Compiler_linux="clang++" # Platform Entry Points -PlatformEntry_win32="src_v2/platform/win32/lumenarium_first_win32.cpp" -PlatformEntry_osx="src_v2/platform/osx/lumenarium_first_osx.c" -PlatformEntry_wasm="src_v2/platform/wasm/lumenarium_first_wasm.cpp" -PlatformEntry_linux="src_v2/platform/linux/lumenarium_first_linux.cpp" -PlatformEntry_raspi="src_v2/platform/raspi/lumenarium_first_raspi.c" +PlatformEntry_win32="src/platform/win32/lumenarium_first_win32.cpp" +PlatformEntry_osx="src/platform/osx/lumenarium_first_osx.c" +PlatformEntry_wasm="src/platform/wasm/lumenarium_first_wasm.cpp" +PlatformEntry_linux="src/platform/linux/lumenarium_first_linux.cpp" +PlatformEntry_raspi="src/platform/raspi/lumenarium_first_raspi.c" # Intermediate Outputs @@ -118,7 +118,7 @@ LinkerOutput_linux="" LinkerOutput_raspi="lumenarium" # Wasm Sys Root -WasmSysRoot="${PROJECT_PATH}/src_v2/platform/wasm/sysroot/" +WasmSysRoot="${PROJECT_PATH}/src/platform/wasm/sysroot/" # Compiler Flags @@ -197,7 +197,7 @@ LinkerFlags_PROD="" LinkerLibs_win32="user32.lib kernel32.lib gdi32.lib opengl32.lib" # winmm.lib gdi32.lib dsound.lib Ws2_32.lib Comdlg32.lib Winspool.lib" -LinkerLibs_osx="-framework OpenGL -framework Cocoa -framework IOKit ${PROJECT_PATH}/src_v2/libs/glfw_osx/lib-universal/libglfw3.a" +LinkerLibs_osx="-framework OpenGL -framework Cocoa -framework IOKit ${PROJECT_PATH}/src/libs/glfw_osx/lib-universal/libglfw3.a" LinkerLibs_wasm="" LinkerLibs_linux="" LinkerLibs_raspi="" @@ -354,13 +354,13 @@ then -o $LinkerOutput \ $EntryPath cp \ - "${PROJECT_PATH}/src_v2/platform/wasm/lumenarium_wasm_imports.js" \ + "${PROJECT_PATH}/src/platform/wasm/lumenarium_wasm_imports.js" \ ./lumenarium_wasm_imports.js else # Preprocessing Steps - ConvertCsvEntry="${PROJECT_PATH}/src_v2/tools/convert_csv.c" + ConvertCsvEntry="${PROJECT_PATH}/src/tools/convert_csv.c" $Compiler \ -o convert_csv \ $CompilerFlags \ diff --git a/project.4coder b/project.4coder index c48210c..70aba3c 100644 --- a/project.4coder +++ b/project.4coder @@ -16,8 +16,7 @@ blacklist_patterns = { load_paths_base = { { ".", .relative = true, .recursive = false, }, { "build", .relative = true, .recursive = false, }, -// { "src", .relative = true, .recursive = true, }, - { "src_v2", .relative = true, .recursive = true, }, + { "src", .relative = true, .recursive = true, }, { "meta", .relative = true, .recursive = true, }, { "gs_libs", .relative = true, .recursive = true, }, }; diff --git a/run_tree/osx/arm64/debug/convert_csv b/run_tree/osx/arm64/debug/convert_csv index e1790c9..c8c1f0b 100755 Binary files a/run_tree/osx/arm64/debug/convert_csv and b/run_tree/osx/arm64/debug/convert_csv differ diff --git a/run_tree/osx/arm64/debug/lumenarium b/run_tree/osx/arm64/debug/lumenarium index 2d5ff7e..989b47b 100755 Binary files a/run_tree/osx/arm64/debug/lumenarium and b/run_tree/osx/arm64/debug/lumenarium differ diff --git a/src/app/deprecated/foldhaus_default_nodes.h b/src/app/deprecated/foldhaus_default_nodes.h deleted file mode 100644 index 3fddaa0..0000000 --- a/src/app/deprecated/foldhaus_default_nodes.h +++ /dev/null @@ -1,159 +0,0 @@ -// -// File: foldhaus_default_nodes.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_DEFAULT_NODES_H - -////////////////////////////////// -// -// 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 -// -///////////////////////////////// - -GSMetaTag(node_struct); -struct sin_wave_data -{ - GSMetaTag(node_input); - r32 Period; - - GSMetaTag(node_input); - r32 Min; - - GSMetaTag(node_input); - r32 Max; - - GSMetaTag(node_input); - 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 = Min(Data->Min, Data->Max); - r32 ActualMax = Max(Data->Min, Data->Max); - r32 SinResult = SinR32((Data->Accumulator / Data->Period) * PiR32 * 2); - Data->Result = RemapR32(SinResult, -1.f, 1.f, ActualMin, ActualMax); - } - else - { - Data->Result = 0; - } -} - -////////////////////////////////// -// -// Pattern Mixing -// -///////////////////////////////// - -GSMetaTag(node_struct); -struct multiply_patterns_data -{ - GSMetaTag(node_input); - color_buffer A; - - GSMetaTag(node_input); - color_buffer B; - - GSMetaTag(node_output); - color_buffer Result; -}; - -NODE_PROC(MultiplyPatterns, multiply_patterns_data) -{ - for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++) - { - Assert(LedIndex >= 0 && LedIndex < Data->Result.LEDCount); - - s32 AR = Data->A.Colors[LedIndex].R; - s32 AG = Data->A.Colors[LedIndex].G; - s32 AB = Data->A.Colors[LedIndex].B; - - s32 BR = Data->B.Colors[LedIndex].R; - s32 BG = Data->B.Colors[LedIndex].G; - s32 BB = Data->B.Colors[LedIndex].B; - - s32 RCombined = (AR * BR) / 255; - s32 GCombined = (AG * BG) / 255; - s32 BCombined = (AB * BB) / 255; - - Data->Result.Colors[LedIndex].R = (u8)RCombined; - Data->Result.Colors[LedIndex].G = (u8)GCombined; - Data->Result.Colors[LedIndex].B = (u8)BCombined; - } -} - - -#define FOLDHAUS_DEFAULT_NODES_H -#endif // FOLDHAUS_DEFAULT_NODES_H \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_node.cpp b/src/app/deprecated/foldhaus_node.cpp deleted file mode 100644 index 092d55f..0000000 --- a/src/app/deprecated/foldhaus_node.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// -// File: foldhaus_node.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_NODE_CPP - -internal b32 -MemberIsInput(gsm_struct_member_type_info Member) -{ - b32 Result = (0 <= gsm_GetMetaTagIndex(MetaTag_node_input, Member.Tags, Member.TagsCount)); - return Result; -} - -internal b32 -MemberIsOutput(gsm_struct_member_type_info Member) -{ - b32 Result = (0 <= gsm_GetMetaTagIndex(MetaTag_node_output, Member.Tags, Member.TagsCount)); - return Result; -} - -internal void -ClearNodeWorkspaceStorage(pattern_node_workspace* Workspace) -{ - ClearArena(&Workspace->Storage); - Workspace->SparseToSortedNodeMap = 0; - Workspace->SortedNodeHandles = 0; -} - -struct adjacency_list -{ - // TODO(Peter): Can make these as buffers, not single digits later - gs_list_handle NodeHandle; - adjacency_list* Next; -}; - -internal u32 -SortNodeNeighbors(u32 ContiguousNodeIndex, gs_list_handle NodeHandle, adjacency_list** NeighborsLists, b8* NodesVisited, gs_list_handle* SortedNodeHandles, u32 SortedNodesCount, s32* SparseToContiguousNodeMap) -{ - NodesVisited[ContiguousNodeIndex] = true; - - adjacency_list* Neighbor = NeighborsLists[ContiguousNodeIndex]; - while (Neighbor) - { - u32 ContiguousNeighborNodeIndex = SparseToContiguousNodeMap[Neighbor->NodeHandle.Index]; - if (!NodesVisited[ContiguousNeighborNodeIndex]) - { - SortedNodesCount = SortNodeNeighbors(ContiguousNeighborNodeIndex, Neighbor->NodeHandle, NeighborsLists, NodesVisited, SortedNodeHandles, SortedNodesCount, SparseToContiguousNodeMap); - } - Neighbor = Neighbor->Next; - } - - SortedNodeHandles[SortedNodesCount++] = NodeHandle; - return SortedNodesCount; -} - -internal s32* -CreateSparseToContiguousMap (pattern_node_workspace Workspace, gs_memory_arena* Scratch) -{ - s32* Result = PushArray(Scratch, s32, Workspace.Nodes.OnePastLastUsed); - s32 ContiguousIndex = 0; - for (u32 SparseNodeIndex = 0; SparseNodeIndex < Workspace.Nodes.OnePastLastUsed; SparseNodeIndex++) - { - gs_list_entry* Entry = Workspace.Nodes.GetEntryAtIndex(SparseNodeIndex); - if (!EntryIsFree(Entry)) - { - Result[SparseNodeIndex] = ContiguousIndex++; - } - } - return Result; -} - -internal void -UpdateSortedNodes(pattern_node_workspace* Workspace, gs_memory_arena* Scratch) -{ - ClearNodeWorkspaceStorage(Workspace); - - u32 NodeCount = Workspace->Nodes.Used; - u32 SparseNodeCount = Workspace->Nodes.OnePastLastUsed; - - s32* SparseToContiguousNodeMap = CreateSparseToContiguousMap(*Workspace, &Workspace->Storage); - - // NOTE(Peter): We need to sort this later on so I'm just storing list lengths in this format - // to begin with. - // NeighborsListLengths[n].Radix = the number of neighbors for the node - // NeighborsListLengths[n].ID = the sparse array index of the node - gs_radix_entry* NeighborsListLengths = PushArray(Scratch, gs_radix_entry, NodeCount); - adjacency_list** NeighborsLists = PushArray(Scratch, adjacency_list*, NodeCount); - GSZeroArray(NeighborsLists, adjacency_list*, SparseNodeCount); - - // Fill Radix - for (u32 n = 0; n < SparseNodeCount; n++) - { - s32 ContiguousIndex = SparseToContiguousNodeMap[n]; - if (ContiguousIndex >= 0) - { - NeighborsListLengths[ContiguousIndex].Radix = 0; - NeighborsListLengths[ContiguousIndex].ID = n; - } - } - - // Construct Adjaceny List - for (u32 c = 0; c < Workspace->Connections.Used; c++) - { - pattern_node_connection Connection = *Workspace->Connections.GetElementAtIndex(c); - - adjacency_list* ListAddition = PushStruct(Scratch, adjacency_list); - ListAddition->NodeHandle = Connection.DownstreamNodeHandle; - - s32 ContiguousNodeIndex = SparseToContiguousNodeMap[Connection.UpstreamNodeHandle.Index]; - ListAddition->Next = NeighborsLists[ContiguousNodeIndex]; - NeighborsLists[ContiguousNodeIndex] = ListAddition; - - // Increment the number of neighbors - stored in Radix - NeighborsListLengths[ContiguousNodeIndex].Radix++; - } - - // Sort by number of neighbors - RadixSortInPlace(NeighborsListLengths, Workspace->Nodes.Used); - - char* OutputCharArray = PushArray(Scratch, char, 1024); - gs_string Outputgs_string = MakeString(OutputCharArray, 0, 1024); - - PrintF(&Outputgs_string, "Neighbors Lists: \n"); - for (u32 d = 0; d < Workspace->Nodes.Used; d++) - { - PrintF(&Outputgs_string, " %d: Node [ %d ] : neighbors { ", d, NeighborsListLengths[d].ID); - - adjacency_list* Neighbors = NeighborsLists[d]; - while (Neighbors) - { - PrintF(&Outputgs_string, "%d, ", Neighbors->NodeHandle.Index); - Neighbors = Neighbors->Next; - } - PrintF(&Outputgs_string, " }\n"); - } - NullTerminate(&Outputgs_string); - - // This is a contiguous array. - b8* NodesVisited = PushArray(Scratch, b8, NodeCount); - GSZeroArray(NodesVisited, b8, NodeCount); - - Workspace->SortedNodeHandles = PushArray(&Workspace->Storage, gs_list_handle, NodeCount); - u32 SortedSparseNodeIndeciesUsed = 0; - - for (u32 n = 0; n < Workspace->Nodes.Used; n++) - { - gs_radix_entry SortedNeighborsCount = NeighborsListLengths[n]; - u32 NeighborCount = SortedNeighborsCount.Radix; - u32 NodeIndex = SortedNeighborsCount.ID; - gs_list_handle NodeHandle = Workspace->Nodes.GetEntryAtIndex(NodeIndex)->Handle; - u32 ContiguousNodeIndex = SparseToContiguousNodeMap[NodeIndex]; - - SortedSparseNodeIndeciesUsed = SortNodeNeighbors(ContiguousNodeIndex, NodeHandle, NeighborsLists, NodesVisited, Workspace->SortedNodeHandles, SortedSparseNodeIndeciesUsed, SparseToContiguousNodeMap); - } - - Workspace->SparseToSortedNodeMap = SparseToContiguousNodeMap; - for (u32 SortedIndex = 0; SortedIndex < NodeCount; SortedIndex++) - { - gs_list_handle SortedHandle = Workspace->SortedNodeHandles[SortedIndex]; - Workspace->SparseToSortedNodeMap[SortedHandle.Index] = SortedIndex; - } -} - -internal void -PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspace, gs_memory_arena* Scratch) -{ - pattern_node* NewNode = Workspace->Nodes.TakeElement(); - NewNode->SpecificationIndex = NodeSpecificationIndex; - - UpdateSortedNodes(Workspace, Scratch); -} - -internal void -PushNodeConnectionOnWorkspace(gs_list_handle UpstreamNodeHandle, u32 UpstreamPortIndex, gs_list_handle DownstreamNodeHandle, u32 DownstreamPortIndex, pattern_node_workspace* Workspace, gs_memory_arena* Scratch) -{ - pattern_node_connection Connection = {}; - Connection.UpstreamNodeHandle = UpstreamNodeHandle; - Connection.DownstreamNodeHandle = DownstreamNodeHandle; - Connection.UpstreamPortIndex = UpstreamPortIndex; - Connection.DownstreamPortIndex = DownstreamPortIndex; - - Workspace->Connections.PushElementOnBucket(Connection); - UpdateSortedNodes(Workspace, Scratch); -} - -#define FOLDHAUS_NODE_CPP -#endif // FOLDHAUS_NODE_CPP \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_node.h b/src/app/deprecated/foldhaus_node.h deleted file mode 100644 index b286b28..0000000 --- a/src/app/deprecated/foldhaus_node.h +++ /dev/null @@ -1,134 +0,0 @@ -// -// File: foldhaus_node.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_NODE_H - -typedef enum node_type node_type; - -#define IsInputMember 1 << 0 -#define IsOutputMember 1 << 1 - -#define DEFAULT_NODE_DIMENSION v2{125, 150} - -struct color_buffer -{ - v4* LedPositions; - pixel* Colors; - s32 LEDCount; -}; - -// TODO(Peter): Use the Meta RTTI -// :UseMetaInfo -enum struct_member_type -{ - MemberType_Invalid, - MemberType_s32, - MemberType_r32, - MemberType_v4, - MemberType_NODE_COLOR_BUFFER, - MemberTypeCount, -}; - -// TODO(Peter): Use the Meta RTTI -// :UseMetaInfo -struct node_struct_member -{ - struct_member_type Type; - char* Name; - u64 Offset; - b32 IsInput; -}; - -// :UseMetaInfo -struct node_specification -{ - node_type Type; - - char* Name; - s32 NameLength; - - node_struct_member* MemberList; - u32 DataStructSize; - u32 MemberListLength; - - b32 IsPattern; -}; - -struct node_specification_ -{ - node_type Type; - gs_string Identifier; - gsm_struct_type DataType; -}; - -struct pattern_node -{ - // TODO(Peter): Something to think about further down the line is the fact that - // SpecificationIndex doesn't have to stay static throughout a single instance of - // an application, let alone across separate runs. If you recompile (hot load or not) - // with a new specification, the indecies all get thrown off. Should we hash the spec - // names or something? - - // TODO(Peter): A more immediate thing to handle is that u32 should really be node_type - u32 SpecificationIndex; -}; - -struct pattern_node_connection -{ - gs_list_handle UpstreamNodeHandle; - gs_list_handle DownstreamNodeHandle; - - u32 UpstreamPortIndex; - u32 DownstreamPortIndex; -}; - -struct pattern_node_workspace -{ - gs_list Nodes; - gs_bucket Connections; - - // This is storage for all the structures which follow. - // It is cleared when new nodes are added so that the - // acceleration structures can be recalculated - gs_memory_arena Storage; - s32* SparseToSortedNodeMap; - gs_list_handle* SortedNodeHandles; -}; - - -/////////////////////////////////////////////// -// Pre Processor Macros -/////////////////////////////////////////////// - -#define NODE_STRUCT(data_name) \ -struct data_name - -#define NODE_PATTERN_STRUCT(data_name) \ -struct data_name - -#define NODE_PROC(proc_name, input_type) \ -void proc_name(input_type* Data, r32 DeltaTime) - -#define NODE_IN(type, name) type name -#define NODE_OUT(type, name) type name - - -/////////////////////////////////////////////// -// OUTPUT NODE -/////////////////////////////////////////////// - -struct output_node_data -{ - GSMetaTag(node_input); - color_buffer Result; -}; - -void OutputNode(output_node_data* Data, r32 DeltaTime) -{ - -} - -#define FOLDHAUS_NODE_H -#endif // FOLDHAUS_NODE_H \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_node_gui.h b/src/app/deprecated/foldhaus_node_gui.h deleted file mode 100644 index 14d7a71..0000000 --- a/src/app/deprecated/foldhaus_node_gui.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// File: foldhaus_node_gui.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_NODE_GUI_H - -struct gui_node -{ - s32 Handle; - node_type Type; - v2 Min, Dim; -}; - -#define GUI_NODES_MAX 256 -struct gui_node_list -{ - s32 NodesUsed; - gui_node Nodes[GUI_NODES_MAX]; -}; - - -#define FOLDHAUS_NODE_GUI_H -#endif // FOLDHAUS_NODE_GUI_H \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_panel_node_graph.h b/src/app/deprecated/foldhaus_panel_node_graph.h deleted file mode 100644 index fceb052..0000000 --- a/src/app/deprecated/foldhaus_panel_node_graph.h +++ /dev/null @@ -1,546 +0,0 @@ -// -// File: foldhaus_panel_node_graph.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PANEL_NODE_GRAPH_H - -struct visual_node -{ - node_specification_ Spec; - v2 Position; -}; - -struct visual_port -{ - gs_list_handle SparseNodeHandle; - u32 PortIndex; - rect2 PortBounds; -}; - -struct visual_connection -{ - u32 UpstreamVisualPortIndex; - u32 DownstreamVisualPortIndex; - v2 UpstreamPosition; - v2 DownstreamPosition; -}; - -struct node_layout -{ - // NOTE(Peter): This Map is a sparse array. - // index i corresponds to index i in some list of nodes - // the value at index i is the index of that node in a compressed list - // if the value at i is -1, that means the entry is free - s32* SparseToContiguousNodeMap; - u32 SparseToContiguousNodeMapCount; - - visual_node* VisualNodes; - u32* VisualNodeLayers; - u32 VisualNodesCount; - - visual_port* VisualPorts; - u32 VisualPortsCount; - - visual_connection* VisualConnections; - u32 VisualConnectionsCount; - - u32 LayerCount; - v2* LayerPositions; - - b32 ConnectionIsInProgress; - v2 InProgressConnectionStart; - v2 InProgressConnectionEnd; -}; - -struct node_graph_state -{ - v2 ViewOffset; - - gs_memory_arena LayoutMemory; - node_layout Layout; - - b32 LayoutIsDirty; -}; - -// -// Pan Node Graph -// - -OPERATION_STATE_DEF(pan_node_graph_operation_state) -{ - v2 InitialViewOffset; - - // TODO(Peter): I DON"T LIKE THIS!!!! - // We should have a way to access the panel that created an operation mode or something - v2* ViewOffset; -}; - -OPERATION_RENDER_PROC(UpdatePanNodeGraph) -{ - pan_node_graph_operation_state* OpState = (pan_node_graph_operation_state*)Operation.OpStateMemory; - v2 MouseDelta = Mouse.Pos - Mouse.DownPos; - *OpState->ViewOffset = MouseDelta + OpState->InitialViewOffset; -} - -input_command PanNodeGraphCommands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndCurrentOperationMode }, -}; - -FOLDHAUS_INPUT_COMMAND_PROC(BeginPanNodeGraph) -{ - operation_mode* PanNodeGraph = ActivateOperationModeWithCommands(&State->Modes, PanNodeGraphCommands, UpdatePanNodeGraph); - pan_node_graph_operation_state* OpState = CreateOperationState(PanNodeGraph, &State->Modes, pan_node_graph_operation_state); - - panel* NodeGraphPanel = State->HotPanel; - node_graph_state* NodeGraphState = (node_graph_state*)NodeGraphPanel->PanelStateMemory; - OpState->InitialViewOffset = NodeGraphState->ViewOffset; - OpState->ViewOffset = &NodeGraphState->ViewOffset; -} - -// -// Connect Nodes -// - -OPERATION_STATE_DEF(connect_nodes_operation_state) -{ - visual_port VisualPort; - u32 VisualPortIndex; - b32 IsInput; -}; - -OPERATION_RENDER_PROC(UpdateConnectNodeOperation) -{ - panel_with_layout NodeGraphPanel = GetPanelContainingPoint(Mouse.DownPos, &State->PanelSystem, State->WindowBounds); - node_graph_state* GraphState = (node_graph_state*)NodeGraphPanel.Panel->PanelStateMemory; - - GraphState->Layout.InProgressConnectionEnd = Mouse.Pos; -} - -FOLDHAUS_INPUT_COMMAND_PROC(EndConnectNodesOperation) -{ - connect_nodes_operation_state* OpState = GetCurrentOperationState(State->Modes, connect_nodes_operation_state); - - panel_with_layout NodeGraphPanel = GetPanelContainingPoint(Mouse.DownPos, &State->PanelSystem, State->WindowBounds); - node_graph_state* GraphState = (node_graph_state*)NodeGraphPanel.Panel->PanelStateMemory; - GraphState->Layout.ConnectionIsInProgress = false; - - for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; p++) - { - visual_port VisualPort = GraphState->Layout.VisualPorts[p]; - rect2 ViewAdjustedBounds = gs_RectOffsetByVector(VisualPort.PortBounds, GraphState->ViewOffset); - if (gs_PointIsInRect(Mouse.Pos, ViewAdjustedBounds)) - { - visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort; - visual_port DownstreamPort = (OpState->IsInput & IsInputMember) ? OpState->VisualPort : VisualPort; - - PushNodeConnectionOnWorkspace(UpstreamPort.SparseNodeHandle, UpstreamPort.PortIndex, - DownstreamPort.SparseNodeHandle, DownstreamPort.PortIndex, - &State->NodeWorkspace, &State->Transient); - - GraphState->LayoutIsDirty = true; - } - } - - EndCurrentOperationMode(State, Event, Mouse); -} - -input_command ConnectNodesOperationCommands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndConnectNodesOperation }, -}; - -internal void -BeginConnectNodesOperation(visual_port VisualPort, u32 VisualPortIndex, mouse_state Mouse, app_state* State) -{ - operation_mode* ConnectNodesOperation = ActivateOperationModeWithCommands(&State->Modes, ConnectNodesOperationCommands, UpdateConnectNodeOperation); - connect_nodes_operation_state* OpState = CreateOperationState(ConnectNodesOperation, &State->Modes, connect_nodes_operation_state); - OpState->VisualPort = VisualPort; - OpState->VisualPortIndex = VisualPortIndex; - - panel_with_layout NodeGraphPanel = GetPanelContainingPoint(Mouse.DownPos, &State->PanelSystem, State->WindowBounds); - node_graph_state* GraphState = (node_graph_state*)NodeGraphPanel.Panel->PanelStateMemory; - - GraphState->Layout.ConnectionIsInProgress = true; - GraphState->Layout.InProgressConnectionStart = gs_CalculateRectCenter(VisualPort.PortBounds); -} - -// -// Node Graph Panel -// - -GSMetaTag(panel_commands); -input_command NodeGraph_Commands[] = {{}}; -s32 NodeGraph_CommandsCount = 0; - -GSMetaTag(panel_init); -GSMetaTag(panel_type_node_graph); -internal void -NodeGraph_Init(panel* Panel, app_state* State) -{ - // TODO(Peter): We aren't able to free this memory. We need a system for - // taking fixed size chunks off the Memory stack and then reusing them. THis - // should probably live outside the paneling system. - // TODO: :FreePanelMemory - Panel->PanelStateMemory = (u8*)PushStruct(&State->Permanent, node_graph_state); - node_graph_state* GraphState = (node_graph_state*)Panel->PanelStateMemory; - GraphState->LayoutIsDirty = true; -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_node_graph); -internal void -NodeGraph_Cleanup(panel* Panel, app_state* State) -{ - node_graph_state* GraphState = (node_graph_state*)Panel->PanelStateMemory; - FreeMemoryArena(&GraphState->LayoutMemory); -} - -internal void -DrawGrid (v2 Offset, v2 GridSquareDim, rect2 PanelBounds, render_command_buffer* RenderBuffer) -{ - r32 LineValue = .16f; - v4 LineColor = v4{LineValue, LineValue, LineValue, 1.f}; - - v2 GridSquareOffset = v2{ - GSModF(Offset.x, GridSquareDim.x), - GSModF(Offset.y, GridSquareDim.y), - }; - v2 GridOrigin = PanelBounds.Min + GridSquareOffset; - - // Draw Vertical Lines - r32 XOffset = 0; - while (GridOrigin.x + XOffset < PanelBounds.Max.x) - { - v2 LineMin = v2{ GridOrigin.x + XOffset, PanelBounds.Min.y }; - v2 LineMax = v2{ LineMin.x + 1, PanelBounds.Max.y }; - PushRenderQuad2D(RenderBuffer, LineMin, LineMax, LineColor); - - XOffset += GridSquareDim.x; - } - - // Draw Horizontal Lines - r32 YOffset = 0; - while (GridOrigin.y + YOffset < PanelBounds.Max.y) - { - v2 LineMin = v2{ PanelBounds.Min.x, GridOrigin.y + YOffset }; - v2 LineMax = v2{ PanelBounds.Max.x, LineMin.y + 1, }; - PushRenderQuad2D(RenderBuffer, LineMin, LineMax, LineColor); - - YOffset += GridSquareDim.y; - } - -} - -internal void -DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position, r32 LineHeight, gs_string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse) -{ - rect2 PortBounds = rect2{v2{0, 0}, v2{6, 6}}; - - v2 LinePosition = Position; - for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++) - { - gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i]; - if (MemberIsInput(Member)) - { - // TODO(Peter): Can we make this rely on the same data that we use to - // render the actual connection points? - gs_string MemberName = MakeString(Member.Identifier, Member.IdentifierLength); - DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign); - LinePosition.y -= LineHeight; - } - } -} - -internal void -DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle NodeHandle, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse, gs_memory_arena* Scratch) -{ - gsm_struct_type_info NodeDataTypeInfo = StructTypes[NodeSpecification.DataType]; - - u32 InputMembers = 0; - u32 OutputMembers = 0; - for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++) - { - gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i]; - if (MemberIsInput(Member)) { InputMembers++; } - if (MemberIsOutput(Member)) { OutputMembers++; } - } - u32 LineCount = 1 + Max(InputMembers, OutputMembers); - - v2 NodeDim = v2{ - NodeWidth, - (LineHeight * LineCount) + Interface.Margin.y, - }; - rect2 NodeBounds = rect2{ - v2{ Position.x, Position.y - NodeDim.y }, - v2{ Position.x + NodeDim.x, Position.y }, - }; - - PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.16f, .16f, .16f, 1.f}); - - v2 LinePosition = v2{ NodeBounds.Min.x, NodeBounds.Max.y - LineHeight }; - v2 TextOffset = v2{Interface.Margin.x, 0}; - - PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f}); - - gs_string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256); - PrintF(&NodePrintName, "%S [%d]", NodeSpecification.Identifier, NodeHandle.Index); - DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4); - LinePosition.y -= LineHeight; - - v2 InputLinePosition = LinePosition; - v2 OutputLinePosition = v2{LinePosition.x + NodeDim.x, LinePosition.y }; - v2 OutputTextOffset = v2{-TextOffset.x, TextOffset.y}; - for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++) - { - gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i]; - gs_string MemberName = MakeString(Member.Identifier, Member.IdentifierLength); - - // TODO(Peter): Can we make this rely on the same data that we use to - // render the actual connection points? - if (MemberIsInput(Member)) - { - DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, Align_Left); - InputLinePosition.y -= LineHeight; - } - else if (MemberIsOutput(Member)) - { - DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, Align_Right); - OutputLinePosition.y -= LineHeight; - } - } -} - -internal s32 -GetVisualPortIndexForNode(gs_list_handle SparseNodeHandle, u32 PortIndex, node_layout Layout) -{ - s32 Result = -1; - - for (u32 i = 0; i < Layout.VisualPortsCount; i++) - { - visual_port Port = Layout.VisualPorts[i]; - if (GSListHandlesAreEqual(Port.SparseNodeHandle, SparseNodeHandle) && Port.PortIndex == PortIndex) - { - Result = i; - break; - } - } - - return Result; -} - -internal node_layout -ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, r32 LineHeight, gs_memory_arena* Storage, app_state* State) -{ - node_layout Result = {}; - - for (u32 n = 0; n < Workspace.Nodes.Used; n++) - { - gs_list_handle NodeHandle = Workspace.SortedNodeHandles[n]; - pattern_node Node = *Workspace.Nodes.GetElementWithHandle(NodeHandle); - - u32 SpecIndex = Node.SpecificationIndex; - - node_specification_ Spec = NodeSpecifications[SpecIndex]; - gsm_struct_type_info NodeDataTypeInfo = StructTypes[Spec.DataType]; - Result.VisualPortsCount += NodeDataTypeInfo.MembersCount;; - } - - // Place nodes and connections - Result.VisualNodesCount = Workspace.Nodes.Used; - Result.VisualNodes = PushArray(Storage, visual_node, Result.VisualNodesCount); - - u32 VisualPortsUsed = 0; - Result.VisualPorts = PushArray(Storage, visual_port, Result.VisualPortsCount); - - for (u32 n = 0; n < Workspace.Nodes.Used; n++) - { - gs_list_handle NodeHandle = Workspace.SortedNodeHandles[n]; - pattern_node Node = *Workspace.Nodes.GetElementWithHandle(NodeHandle); - - u32 SpecIndex = Node.SpecificationIndex; - - node_specification_ Spec = NodeSpecifications[SpecIndex]; - gsm_struct_type_info NodeDataTypeInfo = StructTypes[Spec.DataType]; - - visual_node* VisualNode = Result.VisualNodes + n; - VisualNode->Spec = Spec; - VisualNode->Position = v2{(1.5f * NodeWidth) * n, 0}; - - // NOTE(Peter): These start at 2 to account for the offset past the node title - s32 InputsCount = 2; - s32 OutputsCount = 2; - for (u32 p = 0; p < NodeDataTypeInfo.MembersCount; p++) - { - gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p]; - - rect2 PortBounds = {0}; - v2 PortDim = v2{8, 8}; - PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2}; - if (MemberIsInput(Member)) - { - PortBounds.Min.y -= LineHeight * InputsCount++; - PortBounds.Min.x -= PortDim.x; - } - else if (MemberIsOutput(Member)) - { - PortBounds.Min.y -= LineHeight * OutputsCount++; - PortBounds.Min.x += NodeWidth; - } - PortBounds.Max = PortBounds.Min + v2{8, 8}; - - visual_port* VisualPort = Result.VisualPorts + VisualPortsUsed++; - VisualPort->SparseNodeHandle = NodeHandle; - VisualPort->PortIndex = p; - VisualPort->PortBounds = PortBounds; - } - } - - Result.VisualConnectionsCount = 0; - - Result.VisualConnectionsCount = Workspace.Connections.Used; - Result.VisualConnections = PushArray(Storage, visual_connection, Result.VisualConnectionsCount); - for (u32 c = 0; c < Workspace.Connections.Used; c++) - { - pattern_node_connection* Connection = Workspace.Connections.GetElementAtIndex(c); - - visual_connection* VisualConnection = Result.VisualConnections + c; - VisualConnection->UpstreamVisualPortIndex = GetVisualPortIndexForNode(Connection->UpstreamNodeHandle, Connection->UpstreamPortIndex, Result); - VisualConnection->DownstreamVisualPortIndex = GetVisualPortIndexForNode(Connection->DownstreamNodeHandle, Connection->DownstreamPortIndex, Result); - - visual_port UpstreamPort = Result.VisualPorts[VisualConnection->UpstreamVisualPortIndex]; - visual_port DownstreamPort = Result.VisualPorts[VisualConnection->DownstreamVisualPortIndex]; - - VisualConnection->UpstreamPosition = gs_CalculateRectCenter(UpstreamPort.PortBounds); - VisualConnection->DownstreamPosition = gs_CalculateRectCenter(DownstreamPort.PortBounds); - } - - return Result; -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_node_graph); -internal void -NodeGraph_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - node_graph_state* GraphState = (node_graph_state*)Panel.PanelStateMemory; - b32 MouseHandled = false; - - rect2 NodeSelectionWindowBounds = rect2{ - PanelBounds.Min, - v2{PanelBounds.Min.x + 300, PanelBounds.Max.y}, - }; - rect2 GraphBounds = rect2{ - v2{NodeSelectionWindowBounds.Max.x, PanelBounds.Min.y}, - PanelBounds.Max, - }; - - r32 NodeWidth = 150; - r32 LayerDistance = 100; - r32 LineHeight = ui_GetTextLineHeight(State->Interface); - - if (GraphState->LayoutIsDirty) - { - // NOTE(Peter): Resset the LayoutMemory arena so we can use it again. - // If LayoutIsDirty, then we need to recalculate all the members of GraphState->Layout - // so we might as well just clear the whole thing (we aren't freeing, just reusing) - ClearArena(&GraphState->LayoutMemory); - GraphState->Layout = {}; - - GraphState->Layout = ArrangeNodes(State->NodeWorkspace, NodeWidth, LayerDistance, LineHeight, &GraphState->LayoutMemory, State); - GraphState->LayoutIsDirty = false; - } - - DrawGrid(GraphState->ViewOffset, v2{100, 100}, GraphBounds, RenderBuffer); - - for (u32 i = 0; i < GraphState->Layout.VisualConnectionsCount; i++) - { - visual_connection Connection = GraphState->Layout.VisualConnections[i]; - - v2 Start = GraphState->ViewOffset + Connection.UpstreamPosition; - v2 End = GraphState->ViewOffset + Connection.DownstreamPosition; - PushRenderLine2D(RenderBuffer, Start, End, 1.5f, WhiteV4); - - v2 TempDim = v2{6, 6}; - PushRenderQuad2D(RenderBuffer, Start - TempDim, Start + TempDim, PinkV4); - PushRenderQuad2D(RenderBuffer, End - TempDim, End + TempDim, YellowV4); - } - - if (GraphState->Layout.ConnectionIsInProgress) - { - PushRenderLine2D(RenderBuffer, - GraphState->Layout.InProgressConnectionStart, - GraphState->Layout.InProgressConnectionEnd, - 1.5f, WhiteV4); - } - - for (u32 i = 0; i < GraphState->Layout.VisualNodesCount; i++) - { - visual_node VisualNode = GraphState->Layout.VisualNodes[i]; - gs_list_handle NodeHandle = State->NodeWorkspace.SortedNodeHandles[i]; - DrawNode(VisualNode.Position + GraphState->ViewOffset, VisualNode.Spec, NodeHandle, NodeWidth, LineHeight, State->Interface.Style, RenderBuffer, Context.Mouse, &State->Transient); - } - - for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; p++) - { - visual_port VisualPort = GraphState->Layout.VisualPorts[p]; - VisualPort.PortBounds.Min += GraphState->ViewOffset; - VisualPort.PortBounds.Max += GraphState->ViewOffset; - - v4 PortColor = WhiteV4; - if (PointIsInRange(Context.Mouse.Pos, VisualPort.PortBounds.Min, VisualPort.PortBounds.Max)) - { - PortColor = PinkV4; - if (MouseButtonTransitionedDown(Context.Mouse.LeftButtonState)) - { - BeginConnectNodesOperation(VisualPort, p, Context.Mouse, State); - MouseHandled = true; - } - } - - PushRenderQuad2D(RenderBuffer, VisualPort.PortBounds.Min, VisualPort.PortBounds.Max, PortColor); - } - - // Node Selection Panel - v4 LineBGColors[] = { - { .16f, .16f, .16f, 1.f }, - { .18f, .18f, .18f, 1.f }, - }; - - interface_list List = {}; - List.LineBGColors = LineBGColors; - List.LineBGColorsCount = sizeof(LineBGColors) / sizeof(LineBGColors[0]); - List.LineBGHoverColor = v4{ .22f, .22f, .22f, 1.f }; - List.TextColor = WhiteV4; - List.ListBounds = NodeSelectionWindowBounds; - List.ListElementDimensions = v2{ - Rect2Width(NodeSelectionWindowBounds), - ui_GetTextLineHeight(State->Interface) - }; - List.ElementLabelIndent = v2{10, 4}; - - gs_string Titlegs_string = MakeStringLiteral("Available Nodes"); - DrawListElement(Titlegs_string, &List, Context.Mouse, RenderBuffer, State->Interface.Style); - - for (u32 i = 0; i < NodeType_Count; i++) - { - node_specification_ Spec = NodeSpecifications[i]; - rect2 ElementBounds = DrawListElement(Spec.Identifier, &List, Context.Mouse, RenderBuffer, State->Interface.Style); - - if (MouseButtonTransitionedDown(Context.Mouse.LeftButtonState) - && gs_PointIsInRect(Context.Mouse.DownPos, ElementBounds)) - { - PushNodeOnWorkspace(i, &State->NodeWorkspace, &State->Transient); - GraphState->LayoutIsDirty = true; - MouseHandled = true; - } - } - - if (!MouseHandled && MouseButtonTransitionedDown(Context.Mouse.LeftButtonState)) - { - BeginPanNodeGraph(State, {}, Context.Mouse); - } -} - - -#define FOLDHAUS_PANEL_NODE_GRAPH_H -#endif // FOLDHAUS_PANEL_NODE_GRAPH_H diff --git a/src/app/deprecated/foldhaus_search_lister.cpp b/src/app/deprecated/foldhaus_search_lister.cpp deleted file mode 100644 index cb0725b..0000000 --- a/src/app/deprecated/foldhaus_search_lister.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// File: foldhaus_search_lister.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_SEARCH_LISTER_CPP - -internal b32 -NamePassesFilter (gs_string Target, gs_string Filter) -{ - return (Filter.Length == 0 || StringContainsStringCaseInsensitive(Target, Filter)); -} - -internal void -FilterSearchLister (search_lister* SearchLister) -{ - Assert(SearchLister->FilteredIndexLUT != 0); - Assert(SearchLister->FilteredListMax == SearchLister->SourceListCount); - - SearchLister->FilteredListCount = 0; - - for (s32 i = 0; i < SearchLister->SourceListCount; i++) - { - gs_string* Namegs_string = SearchLister->SourceList + i; - if (NamePassesFilter(*Namegs_string, SearchLister->Filter)) - { - SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i; - } - } - - SearchLister->HotItem = Clamp(0, SearchLister->HotItem, SearchLister->FilteredListCount - 1); - - if (SearchLister->FilteredListCount == 0) - { - SearchLister->HotItem = -1; - } -} - -internal s32 -GetNextFilteredItem (search_lister SearchLister) -{ - s32 Result = Min(SearchLister.HotItem + 1, SearchLister.FilteredListCount - 1); - return Result; -} - -internal s32 -GetPrevFilteredItem (search_lister SearchLister) -{ - s32 Result = Max(SearchLister.HotItem - 1, 0); - return Result; -} - - -#define FOLDHAUS_SEARCH_LISTER_CPP -#endif // FOLDHAUS_SEARCH_LISTER_CPP \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_search_lister.h b/src/app/deprecated/foldhaus_search_lister.h deleted file mode 100644 index e2d502e..0000000 --- a/src/app/deprecated/foldhaus_search_lister.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// File: foldhaus_search_lister.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_SEARCH_LISTER_H - -struct search_lister -{ - // TODO(Peter): Giving up trying to just use the source list for now. At the moment - // we are copying the gs_strings you want to filter from and storing them here. Come back - // once its working and make the memory efficient version (ie store the existing memory - // location, the element stride and the offset to the char*) - s32 SourceListCount; - gs_string* SourceList; - - // NOTE(Peter): stores the source indecies of each filtered item - // For example: - // Index 0 in this array contains 3. This means the first item that passes the filter - // is index 3 in ListMemory - s32 FilteredListMax; - s32 FilteredListCount; - s32* FilteredIndexLUT; - s32 HotItem; - - gs_string Filter; -}; - - -#define FOLDHAUS_SEARCH_LISTER_H -#endif // FOLDHAUS_SEARCH_LISTER_H \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_text_entry.cpp b/src/app/deprecated/foldhaus_text_entry.cpp deleted file mode 100644 index 7deb830..0000000 --- a/src/app/deprecated/foldhaus_text_entry.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// -// File: foldhaus_text_entry.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_TEXT_ENTRY_CPP - -internal void -ResetTextInput (text_entry* Input) -{ - Input->CursorPosition = 0; - Input->Buffer.Length = 0; -} - -internal void -PipeSearchStringToDestination (text_entry* Input) -{ - switch (Input->Destination.Type) - { - case TextTranslateTo_gs_string: - { - PrintF(Input->Destination.StringDest, "%S", Input->Buffer); - }break; - - case TextTranslateTo_R32: - { - *Input->Destination.FloatDest = (r32)ParseFloat(Input->Buffer.ConstString); - }break; - - InvalidDefaultCase; - } -} - -internal void -RemoveCharacterAtCursor (text_entry* TextEntry) -{ - if (TextEntry->CursorPosition > 0) - { - for (u32 i = TextEntry->CursorPosition - 1; i < TextEntry->Buffer.Length; i++) - { - Assert(i + 1 < TextEntry->Buffer.Size); - TextEntry->Buffer.Str[i] = TextEntry->Buffer.Str[i + 1]; - } - TextEntry->CursorPosition--; - } -} - -internal void -SetTextInputDestinationToString (text_entry* TextInput, gs_string* DestinationString) -{ - ResetTextInput(TextInput); - TextInput->Destination.Type = TextTranslateTo_gs_string; - TextInput->Destination.StringDest = DestinationString; - PrintF(&TextInput->Buffer, "%S", *DestinationString); -} - -internal void -SetTextInputDestinationToFloat (text_entry* TextInput, r32* DestinationFloat) -{ - ResetTextInput(TextInput); - TextInput->Destination.Type = TextTranslateTo_R32; - TextInput->Destination.FloatDest = DestinationFloat; - PrintF(&TextInput->Buffer, "%f", *DestinationFloat); - - if (*DestinationFloat == 0.0f) - { - TextInput->CursorPosition = 1; - } -} - -internal void -MoveCursorRight (text_entry* TextEntry) -{ - TextEntry->CursorPosition = Min(TextEntry->Buffer.Length, TextEntry->CursorPosition + 1); -} - -internal void -MoveCursorLeft (text_entry* TextEntry) -{ - TextEntry->CursorPosition = Max(0, TextEntry->CursorPosition - 1); -} - -FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar) -{ - - char Char = CharacterFromKeyCode(Event.Key); - if (Event.Key >= KeyCode_A && Event.Key <= KeyCode_Z && (Event.Modifiers & Modifier_Shift) == 0) - { - Char += ('a' - 'A'); - } - - // Shift string forward - Assert(State->ActiveTextEntry.Buffer.Length < State->ActiveTextEntry.Buffer.Size); - for (u32 i = State->ActiveTextEntry.Buffer.Length; - i > (u32)State->ActiveTextEntry.CursorPosition; - i--) - { - State->ActiveTextEntry.Buffer.Str[i] = State->ActiveTextEntry.Buffer.Str[i - 1]; - } - // Insert new Character - State->ActiveTextEntry.Buffer.Str[State->ActiveTextEntry.CursorPosition] = Char; - State->ActiveTextEntry.CursorPosition++; - PipeSearchStringToDestination(&State->ActiveTextEntry); -} - -FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntrygs_string) -{ - RemoveCharacterAtCursor(&State->ActiveTextEntry); -} - -FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorRight) -{ - MoveCursorRight(&State->ActiveTextEntry); -} - -FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorLeft) -{ - MoveCursorLeft(&State->ActiveTextEntry); -} - -internal void -InitializeTextInputCommands (input_command_registry* Commands, gs_memory_arena* PermanentStorage) -{ - if (Commands->Size > 0) - { - RegisterKeyPressCommand(Commands, KeyCode_Backspace, Command_Began | Command_Held, KeyCode_Invalid, RemoveCharacterFromEntrygs_string); - RegisterKeyPressCommand(Commands, KeyCode_LeftArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorLeft); - RegisterKeyPressCommand(Commands, KeyCode_RightArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorRight); - - for (s32 i = KeyCode_a; i < KeyCode_UpArrow; i++) - { - RegisterKeyPressCommand(Commands, (key_code)i, Command_Began | Command_Held, KeyCode_Invalid, TextEntryInsertChar); - } - - } -} - -#define DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY \ -{ KeyCode_Backspace, KeyCode_Invalid, Command_Began | Command_Held, RemoveCharacterFromEntrygs_string }, \ -{ KeyCode_LeftArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorLeft }, \ -{ KeyCode_RightArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorRight }, \ -{ KeyCode_a, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_b, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_c, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_d, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_e, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_f, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_g, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_h, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_i, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_j, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_k, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_l, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_m, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_n, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_o, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_p, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_q, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_r, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_s, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_t, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_u, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_v, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_w, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_x, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_y, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_z, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_A, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_B, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_C, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_D, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_E, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_F, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_G, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_H, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_I, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_J, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_K, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_L, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_M, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_N, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_O, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_P, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Q, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_R, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_S, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_T, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_U, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_V, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_W, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_X, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Y, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Z, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_0, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_1, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_2, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_3, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_4, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_5, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_6, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_7, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_8, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_9, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num0, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num1, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num2, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num3, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num4, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num5, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num6, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num7, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num8, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Num9, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Bang, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_At, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Pound, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Dollar, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Percent, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Carrot, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Ampersand, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Star, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_LeftParen, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_RightParen, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Minus, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Plus, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Equals, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Underscore, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_LeftBrace, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_RightBrace, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_LeftBracket, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_RightBracket, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Colon, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_SemiColon, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_SingleQuote, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_DoubleQuote, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_ForwardSlash, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Backslash, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Pipe, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Comma, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Period, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_QuestionMark, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_LessThan, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_GreaterThan, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_Tilde, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ -{ KeyCode_BackQuote, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar } - - -#define FOLDHAUS_TEXT_ENTRY_CPP -#endif // FOLDHAUS_TEXT_ENTRY_CPP \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_text_entry.h b/src/app/deprecated/foldhaus_text_entry.h deleted file mode 100644 index e25608f..0000000 --- a/src/app/deprecated/foldhaus_text_entry.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// File: foldhaus_text_entry.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_TEXT_ENTRY_H - -enum text_translation_type -{ - TextTranslateTo_gs_string, - TextTranslateTo_R32, - TextTranslateTo_S32, - TextTranslateTo_U32, -}; - -struct text_entry_destination -{ - text_translation_type Type; - union { - gs_string* StringDest; - r32* FloatDest; - s32* SignedIntDest; - u32* UnsignedIntDest; - }; -}; - -struct text_entry -{ - gs_string Buffer; - s32 CursorPosition; - - text_entry_destination Destination; -}; - -#define FOLDHAUS_TEXT_ENTRY_H -#endif // FOLDHAUS_TEXT_ENTRY_H \ No newline at end of file diff --git a/src/app/deprecated/foldhaus_util_radialumia_file_converter.cpp b/src/app/deprecated/foldhaus_util_radialumia_file_converter.cpp deleted file mode 100644 index d03074f..0000000 --- a/src/app/deprecated/foldhaus_util_radialumia_file_converter.cpp +++ /dev/null @@ -1,377 +0,0 @@ -// -// File: foldhaus_util_radialumia_file_converter.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_UTIL_RADIALUMIA_FILE_CONVERTER_CPP - -#define DEBUG -#define DEBUG_TRACK_SCOPE(name) - -#include -#include -#include - -#include "gs/gs_language.h" -#include "gs/gs_string.h" -#include "../meta/gs_meta_lexer.h" -#include "gs/gs_vector.h" - -#define gs_string_BUFFER_SIZE 512 -struct gs_string_buffer -{ - char* Memory; - s32 Size; - gs_string_buffer* Next; -}; - -struct gs_string_writer -{ - char* Cursor; - s32 UsedIngs_string; - gs_string_buffer* Buffer; -}; - -internal gs_string_buffer* -Growgs_stringBuffer (gs_string_buffer* Buffer) -{ - gs_string_buffer* Result; - if (Buffer->Next) - { - Result = Growgs_stringBuffer(Buffer->Next); - } - else - { - Result = (gs_string_buffer*)malloc(sizeof(gs_string_buffer)); - Result->Memory = (char*)malloc(sizeof(char) * gs_string_BUFFER_SIZE); - memset(Result->Memory, 0, gs_string_BUFFER_SIZE); - Result->Size = gs_string_BUFFER_SIZE; - Result->Next = 0; - - Buffer->Next = Result; - } - return Result; -} - -internal void -Writegs_string(gs_string_writer* Writer, char* gs_string, s32 Length) -{ - char* Src = gs_string; - char* Dst = Writer->Cursor; - s32 LengthWritten = 0; - - while (*Src && Writer->UsedIngs_string < Writer->Buffer->Size &&LengthWritten < Length) - { - LengthWritten++; - *Dst++ = *Src++; - Writer->UsedIngs_string++; - } - - Writer->Cursor = Dst; - - if (*Src && Writer->UsedIngs_string == Writer->Buffer->Size) - { - *(Dst - 1) = 0; // Null terminate the buffer - Writer->Buffer = Growgs_stringBuffer(Writer->Buffer); - Writer->Cursor = Writer->Buffer->Memory; - Writer->UsedIngs_string = 0; - Writegs_string(Writer, (Src - 1), (Length - LengthWritten) + 1); - } -} - -struct control_box_pairs -{ - s32 Start; - s32 End; -}; - -struct extra_strips -{ - s32 BoxID; - v3 Start; - v3 End; -}; - -struct control_box -{ - s32 ID; - s32 Neighbors[6]; - r32 X; - r32 Y; - r32 Z; - char* Address; -}; - -int main(int ArgCount, char* Args[]) -{ - FILE* OldFilePtr = fopen("F:/data/radia_old.fold", "r"); - if (!OldFilePtr) - { - InvalidCodePath; - } - - fseek(OldFilePtr, 0, SEEK_END); - s32 OldFileSize = ftell(OldFilePtr); - fseek(OldFilePtr, 0, SEEK_SET); - - char* OldFile = (char*)malloc(sizeof(char) * OldFileSize); - fread(OldFile, 1, OldFileSize, OldFilePtr); - - fclose(OldFilePtr); - - s32 ControlBoxPairsUsed = 0; - control_box_pairs* ControlBoxPairs = (control_box_pairs*)malloc(sizeof(control_box_pairs) * 512); - s32 ControlBoxesUsed = 0; - control_box* ControlBoxes = (control_box*)malloc(sizeof(control_box) * 64); - s32 ExtraStripsUsed = 0; - extra_strips* ExtraStrips = (extra_strips*)malloc(sizeof(extra_strips) * (42 * 4)); - - control_box_pairs* NextControlBoxPair = &ControlBoxPairs[0]; - control_box* NextControlBox = &ControlBoxes[0]; - extra_strips* NextStrip = &ExtraStrips[0]; - - tokenizer Tokenizer = {}; - Tokenizer.At = OldFile; - while(*Tokenizer.At) - { - // Parse a Control Box - memset(NextControlBox->Neighbors, -1, 6); - s32 NeighborsAdded = 0; - - control_box_pairs* StartPair = NextControlBoxPair; - s32 PairsCount = 0; - - if (gs_stringsEqual(Tokenizer.At, "EOF")) - { - break; - } - - EatToCharacterInclusive(&Tokenizer, '{'); - EatWhitespace(&Tokenizer); - Assert(gs_stringsEqual(Tokenizer.At, "neighbors: [")); - Tokenizer.At += gs_stringLength("neighbors: ["); - - // Parse Neighbors - while(*Tokenizer.At && *Tokenizer.At != ']') - { - s32 NeighborIndex = ParseSignedInt(Tokenizer.At); - NextControlBox->Neighbors[NeighborsAdded++] = NeighborIndex; - NextControlBoxPair->End = NeighborIndex; - NextControlBoxPair++; - PairsCount++; - ControlBoxPairsUsed++; - - EatNumber(&Tokenizer); - if (*Tokenizer.At == ']') - { - Tokenizer.At += 2; // Eat past "];" - break; - } - else - { - EatToCharacterInclusive(&Tokenizer, ','); - EatWhitespace(&Tokenizer); - } - } - - EatWhitespace(&Tokenizer); - - //Parse IP - Assert(gs_stringsEqual(Tokenizer.At, "ip: ")); - Tokenizer.At += gs_stringLength("ip: "); - NextControlBox->Address = (char*)malloc(sizeof(char) * 13); - memcpy(NextControlBox->Address, Tokenizer.At, 13); - Tokenizer.At += 13; - Tokenizer.At++; // Eat past ";" - - // Parse X - EatWhitespace(&Tokenizer); - Assert(gs_stringsEqual(Tokenizer.At, "x: ")); - Tokenizer.At += gs_stringLength("x: "); - NextControlBox->X = ParseFloat(Tokenizer.At); - EatToCharacterInclusive(&Tokenizer, ';'); - // Parse Y - EatWhitespace(&Tokenizer); - Assert(gs_stringsEqual(Tokenizer.At, "y: ")); - Tokenizer.At += gs_stringLength("y: "); - NextControlBox->Y = ParseFloat(Tokenizer.At); - EatToCharacterInclusive(&Tokenizer, ';'); - // Parse Z - EatWhitespace(&Tokenizer); - Assert(gs_stringsEqual(Tokenizer.At, "z: ")); - Tokenizer.At += gs_stringLength("z: "); - NextControlBox->Z = ParseFloat(Tokenizer.At); - EatToCharacterInclusive(&Tokenizer, ';'); - - // Parse ID - EatWhitespace(&Tokenizer); - Assert(gs_stringsEqual(Tokenizer.At, "id: ")); - Tokenizer.At += gs_stringLength("id: "); - NextControlBox->ID = ParseSignedInt(Tokenizer.At); - EatToCharacterInclusive(&Tokenizer, ';'); - - control_box_pairs* PairCursor = StartPair; - for(s32 i = 0; i < PairsCount; i++) - { - PairCursor->Start = NextControlBox->ID; - PairCursor++; - } - - NextControlBox++; - ControlBoxesUsed++; - - EatToCharacterInclusive(&Tokenizer, ';'); - EatWhitespace(&Tokenizer); - } - - // Add Spikes - - -#define SPIKE_LEDS 346 - for (s32 sp = 0; sp < ControlBoxesUsed; sp++) - { - control_box* Box = &ControlBoxes[sp]; - - control_box* NeighborA = &ControlBoxes[Box->Neighbors[0]]; - control_box* NeighborB = &ControlBoxes[Box->Neighbors[1]]; - - v3 SpikeCenter = v3{Box->X, Box->Y, Box->Z}; - v3 StripPitch = Normalize(SpikeCenter) * ((2.f/8.f) / SPIKE_LEDS); - v3 ToNA = Normalize(v3{NeighborA->X, NeighborA->Y, NeighborA->Z} - SpikeCenter); - v3 ToNB = Normalize(v3{NeighborB->X, NeighborB->Y, NeighborB->Z} - SpikeCenter); - - v3 StripAOutStart = SpikeCenter + (ToNA * .01f); - v3 StripAOutEnd = StripAOutStart + (StripPitch * SPIKE_LEDS); - - v3 StripBOutStart = SpikeCenter + (ToNB * .01f); - v3 StripBOutEnd = StripBOutStart + (StripPitch * SPIKE_LEDS); - - v3 StripAInStart = StripAOutEnd - (ToNA * .02f); - v3 StripAInEnd = StripAOutStart - (ToNA * .02f); - - v3 StripBInStart = StripBOutEnd - (ToNA * .02f); - v3 StripBInEnd = StripBOutStart - (ToNA * .02f); - - NextStrip->BoxID = Box->ID; - NextStrip->Start = StripAOutStart; - NextStrip->End = StripAOutEnd; - NextStrip++; - ExtraStripsUsed++; - - NextStrip->BoxID = Box->ID; - NextStrip->Start = StripAInStart; - NextStrip->End = StripAInEnd; - NextStrip++; - ExtraStripsUsed++; - - NextStrip->BoxID = Box->ID; - NextStrip->Start = StripBOutStart; - NextStrip->End = StripBOutEnd; - NextStrip++; - ExtraStripsUsed++; - - NextStrip->BoxID = Box->ID; - NextStrip->Start = StripBInStart; - NextStrip->End = StripBInEnd; - NextStrip++; - ExtraStripsUsed++; - } - - - gs_string_buffer OutputFileBuffer = {}; - OutputFileBuffer.Memory = (char*)malloc(sizeof(char) * gs_string_BUFFER_SIZE); - OutputFileBuffer.Size = gs_string_BUFFER_SIZE; - OutputFileBuffer.Next = 0; - - gs_string_writer RefWriter = {}; - RefWriter.Cursor = OutputFileBuffer.Memory; - RefWriter.UsedIngs_string = 0; - RefWriter.Buffer = &OutputFileBuffer; - gs_string_writer* Writer = &RefWriter; - - char gs_stringBuffer[512]; - s32 Len = 0; - - Len = sprintf_s(gs_stringBuffer, 512, "control_box_count %d\n", ControlBoxesUsed); - Writegs_string(Writer, gs_stringBuffer, Len); - Len = sprintf_s(gs_stringBuffer, 512, "led_strip_count %d\n\n", ControlBoxPairsUsed); - Writegs_string(Writer, gs_stringBuffer, Len); - - for (s32 c = 0; c < ControlBoxesUsed; c++) - { - control_box* Box = ControlBoxes + c; - Len = sprintf_s(gs_stringBuffer, 512, - "control_box { %d, \"%s\", (%f, %f, %f) }\n", - Box->ID, Box->Address, - Box->X, Box->Y, Box->Z); - Writegs_string(Writer, gs_stringBuffer, Len); - } - - Writegs_string(Writer, "\n", 1); - -#define UNIVERSES_PER_BOX 25 - s32 UniversesPerBox[64]; - for (s32 u = 0; u < 64; u++) - { - UniversesPerBox[u] = UNIVERSES_PER_BOX * u; - } - - char LEDStripFormatgs_string[] = "led_strip { %d, %d, %d, INTERPOLATE_POINTS, (%f, %f, %f), (%f, %f, %f), 144 } \n"; - for (s32 s = 0; s < ControlBoxPairsUsed; s++) - { - control_box_pairs* Pair = ControlBoxPairs + s; - - s32 Universe = UniversesPerBox[Pair->Start]; - UniversesPerBox[Pair->Start]++; - - r32 StartX = ControlBoxes[Pair->Start].X; - r32 StartY = ControlBoxes[Pair->Start].Y; - r32 StartZ = ControlBoxes[Pair->Start].Z; - - r32 EndX = ControlBoxes[Pair->End].X; - r32 EndY = ControlBoxes[Pair->End].Y; - r32 EndZ = ControlBoxes[Pair->End].Z; - - Len = sprintf_s(gs_stringBuffer, 512, - LEDStripFormatgs_string, - Pair->Start, Universe, 0, - StartX, StartY, StartZ, - EndX, EndY, EndZ); - Writegs_string(Writer, gs_stringBuffer, Len); - } - - Writegs_string(Writer, "\n", 1); - - for (s32 sp = 0; sp < ExtraStripsUsed; sp++) - { - extra_strips* Strip = ExtraStrips + sp; - - s32 Universe = UniversesPerBox[Strip->BoxID]; - UniversesPerBox[Strip->BoxID]++; - - Len = sprintf_s(gs_stringBuffer, 512, - LEDStripFormatgs_string, - Strip->BoxID, Universe, 0, - Strip->Start.x, Strip->Start.y, Strip->Start.z, - Strip->End.x, Strip->End.y, Strip->End.z); - Writegs_string(Writer, gs_stringBuffer, Len); - } - - Writegs_string(Writer, "END_OF_ASSEMBLY_FILE", gs_stringLength("END_OF_ASSEMBLY_FILE")); - - *Writer->Cursor = 0; - - FILE* OutputFile = fopen("F:/data/radialumia.fold", "w"); - gs_string_buffer* BufferCursor = &OutputFileBuffer; - while(BufferCursor) - { - fprintf(OutputFile, BufferCursor->Memory); - BufferCursor = BufferCursor->Next; - } - fclose(OutputFile); - - return 0; -} - -#define FOLDHAUS_UTIL_RADIALUMIA_FILE_CONVERTER_CPP -#endif // FOLDHAUS_UTIL_RADIALUMIA_FILE_CONVERTER_CPP \ No newline at end of file diff --git a/src/app/deprecated/node/foldhaus_node_interface.cpp b/src/app/deprecated/node/foldhaus_node_interface.cpp deleted file mode 100644 index f4e3b39..0000000 --- a/src/app/deprecated/node/foldhaus_node_interface.cpp +++ /dev/null @@ -1,513 +0,0 @@ -// -// File: foldhaus_node_interface.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLHAUS_NODE_INTERFACE_CPP - -//////////////////////////////////////// -// -// Node Lister -// -/////////////////////////////////////// - -struct node_lister_operation_state -{ - search_lister SearchLister; - v2 ListPosition; -}; - -internal void -RenderNodeLister(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) -{ - node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory; - - v2 TopLeft = OpState->ListPosition; - v2 Dimension = v2{300, 30}; - - // Filter the lister - OpState->SearchLister.Filter = State->ActiveTextEntry.Buffer; - FilterSearchLister(&OpState->SearchLister); - - // Display Search Lister - search_lister_result NodeListerResult = EvaluateSearchLister (&State->Interface_, TopLeft, Dimension, - MakeStringLiteral("Nodes List"), - OpState->SearchLister.SourceList, - OpState->SearchLister.FilteredIndexLUT, - OpState->SearchLister.FilteredListCount, - OpState->SearchLister.HotItem, - &State->ActiveTextEntry.Buffer, - State->ActiveTextEntry.CursorPosition); -} - -FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem) -{ - node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state); - OpState->SearchLister.HotItem = GetNextFilteredItem(OpState->SearchLister); -} - -FOLDHAUS_INPUT_COMMAND_PROC(NodeListerPrevItem) -{ - node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state); - OpState->SearchLister.HotItem = GetPrevFilteredItem(OpState->SearchLister); -} - -FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeLister) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseNodeLister) -{ - node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state); - s32 FilteredNodeIndex = OpState->SearchLister.HotItem; - if (FilteredNodeIndex >= 0) - { - s32 NodeIndex = OpState->SearchLister.FilteredIndexLUT[FilteredNodeIndex]; - PushNodeOnListFromSpecification(State->NodeList, (node_type)NodeIndex, - Mouse.Pos, State->Permanent); - } - CloseNodeLister(State, Event, Mouse); -} - -input_command UniverseViewCommads [] = { - { KeyCode_DownArrow, KeyCode_Invalid, Command_Began, NodeListerNextItem }, - { KeyCode_UpArrow, KeyCode_Invalid, Command_Began, NodeListerPrevItem }, - { KeyCode_Enter, KeyCode_Invalid, Command_Began, SelectAndCloseNodeLister }, - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, CloseNodeLister }, - { KeyCode_Esc, KeyCode_Invalid, Command_Began, CloseNodeLister }, - DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY, -}; - -FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister) -{ - operation_mode* AddNodeOperation = ActivateOperationModeWithCommands(&State->Modes, UniverseViewCommads); - - AddNodeOperation->Render = RenderNodeLister; - - node_lister_operation_state* OpState = CreateOperationState(AddNodeOperation, - &State->Modes, - node_lister_operation_state); - { - OpState->SearchLister.SourceListCount = NodeSpecificationsCount; - OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, gs_string, OpState->SearchLister.SourceListCount); - { - for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++) - { - OpState->SearchLister.SourceList[i] = MakeString( - NodeSpecifications[i].Name, - NodeSpecifications[i].NameLength); - } - } - OpState->SearchLister.Filter = MakeString(PushArray(&State->Modes.Arena, char, 64), 0, 64); - - OpState->SearchLister.FilteredListMax = OpState->SearchLister.SourceListCount; - OpState->SearchLister.FilteredListCount = 0; - OpState->SearchLister.FilteredIndexLUT = PushArray(&State->Modes.Arena, s32, OpState->SearchLister.SourceListCount); - } - - OpState->ListPosition = Mouse.Pos; - SetTextInputDestinationTogs_string(&State->ActiveTextEntry, &OpState->SearchLister.Filter); -} - -//////////////////////////////////////// -// -// Node Color Picker -// -/////////////////////////////////////// - -struct color_picker_operation_state -{ - v4* ValueAddr; -}; - -internal void -CloseColorPicker(app_state* State) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -FOLDHAUS_INPUT_COMMAND_PROC(CloseColorPickerCommand) -{ - CloseColorPicker(State); -} - -internal void -RenderColorPicker(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) -{ - color_picker_operation_state* OpState = (color_picker_operation_state*)Operation.OpStateMemory; - - - b32 ShouldClose = EvaluateColorPicker(RenderBuffer, OpState->ValueAddr, - v2{200, 200}, State->Interface, Mouse); - - if (ShouldClose) - { - CloseColorPicker(State); - } -} - -input_command ColorPickerCommands [] = { - { KeyCode_Esc, KeyCode_Invalid, Command_Began, CloseColorPickerCommand }, -}; - -internal void -OpenColorPicker(app_state* State, node_connection* Connection) -{ - operation_mode* ColorPickerMode = ActivateOperationModeWithCommands(&State->Modes, ColorPickerCommands); - ColorPickerMode->Render = RenderColorPicker; - - color_picker_operation_state* OpState = CreateOperationState(ColorPickerMode, - &State->Modes, - color_picker_operation_state); - OpState->ValueAddr = Connection->V4ValuePtr; -} - - -//////////////////////////////////////// -// -// Node Field Text Edit -// -/////////////////////////////////////// - -FOLDHAUS_INPUT_COMMAND_PROC(EndNodeFieldTextEdit) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command NodeFieldTextEditCommands [] = { - { KeyCode_Enter, KeyCode_Invalid, Command_Began, EndNodeFieldTextEdit }, - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, EndNodeFieldTextEdit }, - DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY, -}; - -internal void -BeginNodeFieldTextEdit(app_state* State, node_connection* Connection) -{ - operation_mode* NodeFieldTextEditMode = ActivateOperationModeWithCommands(&State->Modes, - NodeFieldTextEditCommands); - - SetTextInputDestinationToFloat(&State->ActiveTextEntry, Connection->R32ValuePtr); -} - -//////////////////////////////////////// -// -// Node Port Mouse Drag -// -/////////////////////////////////////// - -struct drag_node_port_operation_state -{ - node_interaction Interaction; -}; - -internal void -RenderDraggingNodePort(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) -{ - drag_node_port_operation_state* OpState = (drag_node_port_operation_state*)Operation.OpStateMemory; - UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList, - State->NodeRenderSettings, RenderBuffer); -} - -FOLDHAUS_INPUT_COMMAND_PROC(EndDraggingNodePort) -{ - drag_node_port_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_port_operation_state); - - TryConnectNodes(OpState->Interaction, Mouse.Pos, State->NodeList, State->NodeRenderSettings); - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command DragNodePortInputCommands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDraggingNodePort }, -}; - -internal void -BeginDraggingNodePort(app_state* State, node_interaction Interaction) -{ - operation_mode* DragNodePortMode = ActivateOperationModeWithCommands( - &State->Modes, - DragNodePortInputCommands); - DragNodePortMode->Render = RenderDraggingNodePort; - - drag_node_port_operation_state* OpState = CreateOperationState(DragNodePortMode, - &State->Modes, - drag_node_port_operation_state); - OpState->Interaction = Interaction; -} - -//////////////////////////////////////// -// -// Node Field Mouse Drag -// -/////////////////////////////////////// - -internal void -RenderDragNodeField(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) -{ - // TODO(Peter): - //UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State); -} - -internal void -BeginInteractWithNodeField(app_state* State, node_interaction Interaction) -{ - // TODO(Peter): -} - -//////////////////////////////////////// -// -// Node Mouse Drag -// -/////////////////////////////////////// - -struct drag_node_operation_state -{ - node_interaction Interaction; -}; - -internal void -RenderDraggingNode(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) -{ - drag_node_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_operation_state); - UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList, - State->NodeRenderSettings); -} - -FOLDHAUS_INPUT_COMMAND_PROC(EndDraggingNode) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command DragNodeInputCommands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDraggingNode }, -}; - -internal void -BeginDraggingNode(app_state* State, node_interaction Interaction) -{ - operation_mode* DragNodeMode = ActivateOperationModeWithCommands( - &State->Modes, - DragNodeInputCommands); - DragNodeMode->Render = RenderDraggingNode; - - drag_node_operation_state* OpState = CreateOperationState(DragNodeMode, - &State->Modes, - drag_node_operation_state); - OpState->Interaction = Interaction; -} - -//////////////////////////////////////// -// -// Node View -// -/////////////////////////////////////// - -struct node_view_operation_state -{ - s32 SelectedNodeHandle; -}; - -FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction) -{ - node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state); - - node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings); - if (Node) - { - node_interaction NewInteraction = GetNodeInteractionType(Node, - Mouse.Pos, - State->NodeRenderSettings); - if (IsDraggingNodePort(NewInteraction)) - { - BeginDraggingNodePort(State, NewInteraction); - } - else if(IsDraggingNodeValue(NewInteraction)) - { - // TODO(Peter): This probably wants to live in a mouse held action - // the first frame we realize we're held over a field, just transition to - // drag node field - //BeginInteractWithNodeField(State, NewInteraction, State->NodeRenderSettings); - } - else // IsDraggingNode - { - OpState->SelectedNodeHandle = Node->Handle; - BeginDraggingNode(State, NewInteraction); - } - } - else - { - OpState->SelectedNodeHandle = 0; - } -} - -FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction) -{ - node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state); - - node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.Pos, State->NodeRenderSettings); - if (Node) - { - node_interaction NewInteraction = GetNodeInteractionType(Node, - Mouse.Pos, - State->NodeRenderSettings); - if(IsDraggingNodeValue(NewInteraction)) - { - node_connection* Connection = Node->Connections + NewInteraction.InputValue; - struct_member_type InputType = Connection->Type; - - if (InputType == MemberType_r32) - { - BeginNodeFieldTextEdit(State, Connection); - } - else if (InputType == MemberType_v4) - { - OpenColorPicker(State, Connection); - } - } - } -} - -internal void -RenderNodeView(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) -{ - node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory; - - DEBUG_TRACK_FUNCTION; - - MakeStringBuffer(NodeHeaderBuffer, 128); - - node_header* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle); - - node_list_iterator NodeIter = GetNodeListIterator(*State->NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - node_header* Node = NodeIter.At; - - rect2 NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings); - b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds); - - if (Node == SelectedNode) - { - PushRenderQuad2D(RenderBuffer, NodeBounds.Min - v2{2, 2}, NodeBounds.Max + v2{2, 2}, WhiteV4); - } - - PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f}); - - // TODO(Peter): This is just for debug purposes. We can remove and go back to just having - // Node->Name in Drawgs_string - gs_string NodeName = GetNodeName(*Node); - PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle); - DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font, - v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)}, - WhiteV4); - - for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++) - { - v4 PortColor = State->NodeRenderSettings.PortColors[Node->Connections[Connection].Type]; - - // Inputs - if (ConnectionIsInput(Node, Connection)) - { - rect2 PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings); - DrawPort(RenderBuffer, PortBounds, PortColor); - - // - // TODO(Peter): I don't like excluding OutputNode, feels too much like a special case - // but I don't want to get in to the meta programming right now. - // We should just generate a spec and struct member types for NodeType_OutputNode - // - // :ExcludingOutputNodeSpecialCase - // - if (Node->Type != NodeType_OutputNode && DrawFields) - { - node_specification Spec = NodeSpecifications[Node->Type]; - node_struct_member Member = Spec.MemberList[Connection]; - DrawString(RenderBuffer, MakeString(Member.Name), - State->NodeRenderSettings.Font, - v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right); - } - - rect2 ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings); - DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font); - - // NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship, - // whereas output ports might have many connections, they really only know about the most recent one - // Not sure if this is a problem. We mostly do everything backwards here, starting at the - // most downstream node and working back up to find dependencies. - if (ConnectionHasUpstreamConnection(Node, Connection)) - { - rect2 ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings); - v2 InputCenter = CalculateRectCenter(PortBounds); - v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds); - PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4); - } - } - - // Outputs - if (ConnectionIsOutput(Node, Connection)) - { - rect2 PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings); - DrawPort(RenderBuffer, PortBounds, PortColor); - - if (DrawFields) - { - node_specification Spec = NodeSpecifications[Node->Type]; - node_struct_member Member = Spec.MemberList[Connection]; - DrawString(RenderBuffer, MakeString(Member.Name), - State->NodeRenderSettings.Font, - v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4); - } - - rect2 ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings); - DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font); - } - - for (s32 Button = 0; Button < 3; Button++) - { - rect2 ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings); - PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]); - } - } - - Next(&NodeIter); - } -} - -FOLDHAUS_INPUT_COMMAND_PROC(NodeViewDeleteNode) -{ - node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state); - if (OpState->SelectedNodeHandle > 0) - { - node_header* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle); - FreeNodeOnList(State->NodeList, SelectedNode); - } -} - -FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeView) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command NodeViewCommands [] = { - { KeyCode_Tab, KeyCode_Invalid, Command_Began, CloseNodeView}, - { KeyCode_A, KeyCode_Invalid, Command_Began, OpenNodeLister}, - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, NodeViewBeginMouseDragInteraction}, - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, NodeViewBeginMouseSelectInteraction}, - { KeyCode_X, KeyCode_Invalid, Command_Began, NodeViewDeleteNode}, -}; - -FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView) -{ - operation_mode* NodeViewMode = ActivateOperationModeWithCommands(&State->Modes, NodeViewCommands); - NodeViewMode->Render = RenderNodeView; - - node_view_operation_state* OpState = CreateOperationState(NodeViewMode, - &State->Modes, - node_view_operation_state); - - OpState->SelectedNodeHandle = 0; -} - - -#define FOLHAUS_NODE_INTERFACE_CPP -#endif // FOLHAUS_NODE_INTERFACE_CPP diff --git a/src/app/editor/foldhaus_command_dispatch.h b/src/app/editor/foldhaus_command_dispatch.h deleted file mode 100644 index 6c6cf1c..0000000 --- a/src/app/editor/foldhaus_command_dispatch.h +++ /dev/null @@ -1,206 +0,0 @@ -// -// File: foldhaus_command_dispatch.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_COMMAND_DISPATCH_H - -#define FOLDHAUS_INPUT_COMMAND_PROC(name) void name(app_state* State, input_entry Event, mouse_state Mouse, context Context, panel* Panel) -typedef FOLDHAUS_INPUT_COMMAND_PROC(input_command_proc); - -// NOTE(Peter): Helper function so I don't have to remember the parameters to this define -#define ExecFoldhausCommand(cmd) cmd(State, Event, Mouse) - -enum input_command_flags -{ - Command_Began = 1 << 0, - Command_Held = 1 << 1, - Command_Ended = 1 << 2, -}; - -#define Command_Any Command_Began | Command_Held | Command_Ended - -// TODO(Peter): At the moment these are all key press commands. Need a way to differentiate between -// press and hold. Probably add a second array to input_command_Registry -struct input_command -{ - key_code Key; - key_code Mdfr; - b32 Flags; - input_command_proc* Proc; -}; - -struct input_command_registry -{ - input_command* Commands; - s32 Size; - s32 Used; - - input_command_proc* MouseWheelCommand; -}; - -struct command_queue_entry -{ - input_command Command; - input_entry Event; -}; - -struct input_command_queue -{ - s32 Size; - s32 Used; - command_queue_entry* Commands; -}; - -internal void -InitializeInputCommandRegistry (input_command_registry* CommandRegistry, - s32 Size, - gs_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 -CommandQueue_Create(gs_memory_arena* Storage, u64 CommandMaxCount) -{ - input_command_queue Result = {}; - Result.Size = CommandMaxCount; - Result.Used = 0; - Result.Commands = PushArray(Storage, command_queue_entry, CommandMaxCount); - 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; -} - -#define FOLDHAUS_COMMAND_DISPATCH_H -#endif // FOLDHAUS_COMMAND_DISPATCH_H \ No newline at end of file diff --git a/src/app/editor/foldhaus_editor.cpp b/src/app/editor/foldhaus_editor.cpp deleted file mode 100644 index 8db76a9..0000000 --- a/src/app/editor/foldhaus_editor.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// -// File: foldhaus_editor.cpp -// Author: Peter Slattery -// Creation Date: 2020-10-24 -// -#ifndef FOLDHAUS_EDITOR_CPP - -internal void -Editor_HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse_state Mouse, context Context) -{ - DEBUG_TRACK_FUNCTION; - - b32 MouseInputHandled = HandleMousePanelInteraction(&State->PanelSystem, State->WindowBounds, Mouse, State); - - gs_string TextInputString = PushString(State->Transient, 32); - - panel* ActivePanel = PanelSystem_GetPanelContainingPoint(&State->PanelSystem, Mouse.Pos); - if (ActivePanel) - { - panel_definition ActiveDef = State->PanelSystem.PanelDefs[ActivePanel->TypeIndex]; - - input_command_registry ActiveCommands = {}; - if (State->Modes.ActiveModesCount > 0) - { - ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands; - } - else if (ActiveDef.InputCommands) - { - ActiveCommands.Commands = ActiveDef.InputCommands; - ActiveCommands.Size = sizeof(*ActiveDef.InputCommands) / sizeof(ActiveDef.InputCommands[0]); - ActiveCommands.Used = ActiveCommands.Size; - } - - // Fill up the command queue - for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++) - { - input_entry Event = InputQueue.Entries[EventIdx]; - - bool IsMouseEvent = (Event.Key == KeyCode_MouseLeftButton || - Event.Key == KeyCode_MouseMiddleButton || - Event.Key == KeyCode_MouseRightButton); - if (IsMouseEvent && MouseInputHandled) - { - continue; - } - - // NOTE(Peter): These are in the order Down, Up, Held because we want to privalege - // Down and Up over Held. In other words, we don't want to call a Held command on the - // frame when the button was released, even if the command is registered to both events - if (KeyTransitionedDown(Event)) - { - if (!FindAndPushExistingCommand(ActiveCommands, Event, Command_Began, &State->CommandQueue)) - { - char KeyASCII = KeyCodeToChar(Event.Key); - if (KeyASCII) - { - OutChar(&TextInputString, KeyASCII); - } - } - } - else if (KeyTransitionedUp(Event)) - { - FindAndPushExistingCommand(ActiveCommands, Event, Command_Ended, &State->CommandQueue); - } - else if (KeyHeldDown(Event)) - { - if (!FindAndPushExistingCommand(ActiveCommands, Event, Command_Held, &State->CommandQueue)) - { - char KeyASCII = KeyCodeToChar(Event.Key); - if (KeyASCII) - { - OutChar(&TextInputString, KeyASCII); - } - } - } - } - } - - // Execute all commands in CommandQueue - for (s32 CommandIdx = State->CommandQueue.Used - 1; CommandIdx >= 0; CommandIdx--) - { - command_queue_entry* Entry = &State->CommandQueue.Commands[CommandIdx]; - if (Entry->Command.Proc) - { - Entry->Command.Proc(State, Entry->Event, Mouse, Context, ActivePanel); - } - else - { - EndCurrentOperationMode(State); - } - } - - State->Interface.TempInputString = TextInputString.ConstString; - - ClearCommandQueue(&State->CommandQueue); -} - -internal void -Editor_Update(app_state* State, context* Context, input_queue InputQueue) -{ - Context->Mouse.CursorType = CursorType_Arrow; - State->WindowBounds = Context->WindowBounds; - State->Interface.Mouse = Context->Mouse; - - State->Interface.HotWidgetFramesSinceUpdate += 1; - if (State->Interface.HotWidgetFramesSinceUpdate > 1) - { - State->Interface.HotWidget = {}; - } - - Assert(State->Interface.PerFrameMemory && - (u64)State->Interface.PerFrameMemory != 0x5); - - PanelSystem_UpdateLayout(&State->PanelSystem, State->WindowBounds); - Editor_HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse, *Context); -} - -internal void -Editor_Render(app_state* State, context* Context, render_command_buffer* RenderBuffer) -{ - State->Interface.WindowBounds = Context->WindowBounds; - PushRenderOrthographic(RenderBuffer, State->WindowBounds); - PushRenderClearScreen(RenderBuffer); - - - ui_InterfaceReset(&State->Interface); - State->Interface.RenderBuffer = RenderBuffer; - ui_PushLayout(&State->Interface, Context->WindowBounds, LayoutDirection_TopDown, MakeString("Editor Layout")); - { - DrawAllPanels(State->PanelSystem, RenderBuffer, &Context->Mouse, State, *Context); - - for (s32 m = 0; m < State->Modes.ActiveModesCount; m++) - { - operation_mode OperationMode = State->Modes.ActiveModes[m]; - if (OperationMode.Render != 0) - { - OperationMode.Render(State, RenderBuffer, OperationMode, Context->Mouse, *Context); - } - } - } - ui_PopLayout(&State->Interface, MakeString("Editor Layout")); - - - // Draw the Interface - if (State->Interface.DrawOrderRoot != 0) - { - ui_widget* Widget = State->Interface.DrawOrderRoot; - Editor_DrawWidgetList(State, Context, RenderBuffer, Widget, Context->WindowBounds); - } - - Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext); -} - - -#define FOLDHAUS_EDITOR_CPP -#endif // FOLDHAUS_EDITOR_CPP \ No newline at end of file diff --git a/src/app/editor/foldhaus_editor_draw.h b/src/app/editor/foldhaus_editor_draw.h deleted file mode 100644 index bad44a2..0000000 --- a/src/app/editor/foldhaus_editor_draw.h +++ /dev/null @@ -1,170 +0,0 @@ -// -// File: foldhaus_editor_draw.h -// Author: Peter Slattery -// Creation Date: 2021-01-16 -// -#ifndef FOLDHAUS_EDITOR_DRAW_H - -internal void -Editor_DrawWidgetString(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget Widget, rect2 ClippingBox, v4 Color, s32 CursorPosition) -{ - gs_string Temp = PushString(State->Transient, 256); - PrintF(&Temp, "%d", Widget.Id.Id); - render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, - Widget.String.Length + 1, - State->Interface.Style.Font->BitmapMemory, - State->Interface.Style.Font->BitmapTextureHandle, - State->Interface.Style.Font->BitmapWidth, - State->Interface.Style.Font->BitmapHeight, - State->Interface.Style.Font->BitmapBytesPerPixel, - State->Interface.Style.Font->BitmapStride); - - v2 RegisterPosition = Widget.Bounds.Min + State->Interface.Style.Margin; - - switch (Widget.Alignment) - { - case Align_Left: - { - RegisterPosition = DrawStringLeftAligned(RenderBuffer, - &BatchConstructor, StringExpand(Widget.String), RegisterPosition, State->Interface.Style.Font, ClippingBox, Color, CursorPosition, GreenV4); - }break; - - case Align_Right: - { - RegisterPosition = DrawStringRightAligned(&BatchConstructor, StringExpand(Widget.String), RegisterPosition, State->Interface.Style.Font, ClippingBox, Color); - }break; - - InvalidDefaultCase; - } -} - -enum widget_fill_dir -{ - WidgetFill_Horizontal = 0, - WidgetFill_Vertical = 1, -}; - -internal rect2 -Editor_GetWidgetFillBounds(ui_widget Widget) -{ - Assert(ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawHorizontalFill) || ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawVerticalFill)); - - rect2 Result = {}; - - widget_fill_dir Dir = WidgetFill_Horizontal; - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawHorizontalFill)) { Dir = WidgetFill_Vertical; } - widget_fill_dir OtherDir = (widget_fill_dir)(WidgetFill_Vertical - Dir); - - Result.Min.E[Dir] = Widget.Bounds.Min.E[Dir]; - Result.Max.E[Dir] = Widget.Bounds.Max.E[Dir]; - r32 FillToPoint = LerpR32(Widget.FillPercent, Widget.Bounds.Min.E[OtherDir], Widget.Bounds.Max.E[OtherDir]); - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawFillReversed)) - { - Result.Min.E[OtherDir] = FillToPoint; - Result.Max.E[OtherDir] = Widget.Bounds.Max.E[OtherDir]; - } - else if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawFillAsHandle)) - { - Result.Min.E[OtherDir] = FillToPoint - 5; - Result.Max.E[OtherDir] = FillToPoint + 5; - } - else - { - Result.Min.E[OtherDir] = Widget.Bounds.Min.E[OtherDir]; - Result.Max.E[OtherDir] = FillToPoint; - } - - return Result; -} - -internal void Editor_DrawWidgetList(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget Widget, rect2 ParentClipBounds); - -internal void -Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget Widget, rect2 WidgetParentUnion) -{ - bool IsActiveWidget = ui_WidgetIdsEqual(Widget.Id, State->Interface.ActiveWidget); - ; - if (!Widget.Parent || (Rect2Area(WidgetParentUnion) > 0)) - { - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawBackground)) - { - v4 Color = State->Interface.Style.ButtonColor_Inactive; - if (ui_WidgetIdsEqual(Widget.Id, State->Interface.HotWidget)) - { - Color = State->Interface.Style.ButtonColor_Active; - } - if (ui_WidgetIdsEqual(Widget.Id, State->Interface.ActiveWidget)) - { - Color = State->Interface.Style.ButtonColor_Selected; - } - PushRenderQuad2DClipped(RenderBuffer, Widget.Bounds, WidgetParentUnion, Color); - } - - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawString) && Widget.String.Length > 0) - { - v4 Color = State->Interface.Style.TextColor; - s32 CursorPosition = -1; - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_Typable) && IsActiveWidget) - { - CursorPosition = State->Interface.CursorPosition; - } - - Editor_DrawWidgetString(State, Context, RenderBuffer, Widget, WidgetParentUnion, Color, CursorPosition); - } - - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawHorizontalFill) || - ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawVerticalFill)) - { - v4 Color = State->Interface.Style.ButtonColor_Selected; - if (ui_WidgetIdsEqual(Widget.Id, State->Interface.HotWidget) || - ui_WidgetIdsEqual(Widget.Id, State->Interface.ActiveWidget)) - { - Color = WhiteV4; - } - - rect2 FillBounds = Editor_GetWidgetFillBounds(Widget); - rect2 ClippedFillBounds = Rect2Union(FillBounds, WidgetParentUnion); - PushRenderQuad2D(RenderBuffer, ClippedFillBounds, Color); - - if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawString) && Widget.String.Length > 0) - { - v4 TextColor = BlackV4; - Editor_DrawWidgetString(State, Context, RenderBuffer, Widget, ClippedFillBounds, TextColor, -1); - } - } - - bool DrawOutline = ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawOutline); - DrawOutline |= ui_WidgetIsFlagSet(Widget, UIWidgetFlag_Typable) && IsActiveWidget; - - if (DrawOutline) - { - // TODO(pjs): replace these with values from the style - r32 Thickness = 1.0f; - v4 Color = WhiteV4; - PushRenderBoundingBox2D(RenderBuffer, WidgetParentUnion.Min, WidgetParentUnion.Max, Thickness, Color); - } - } -} - - -internal void Editor_DrawWidgetList(app_state* State, context* Context, render_command_buffer* RenderBuffer, ui_widget* Widget, rect2 ParentClipBounds) -{ - ui_widget* WidgetAt = Widget; - while (WidgetAt) - { - rect2 WidgetParentUnion = WidgetAt->Bounds; - WidgetParentUnion = Rect2Union(WidgetAt->Bounds, ParentClipBounds); - - Editor_DrawWidget(State, Context, RenderBuffer, *WidgetAt, WidgetParentUnion); - - if (WidgetAt->ChildrenRoot) - { - Editor_DrawWidgetList(State, Context, RenderBuffer, WidgetAt->ChildrenRoot, WidgetParentUnion); - } - - WidgetAt = WidgetAt->Next; - } -} - -#define FOLDHAUS_EDITOR_DRAW_H -#endif // FOLDHAUS_EDITOR_DRAW_H \ No newline at end of file diff --git a/src/app/editor/foldhaus_interface.cpp b/src/app/editor/foldhaus_interface.cpp deleted file mode 100644 index d194260..0000000 --- a/src/app/editor/foldhaus_interface.cpp +++ /dev/null @@ -1,463 +0,0 @@ -// -// File: foldhaus_interface.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_INTERFACE_CPP - -//////////////////////////////////////// -// -// Panels -// -/////////////////////////////////////// - -enum panel_edit_mode -{ - PanelEdit_Invalid, - - PanelEdit_Modify, - PanelEdit_Destroy, - - PanelEdit_Count, -}; - -// -// Drag Panel Border Operation Mode - -OPERATION_STATE_DEF(drag_panel_border_operation_state) -{ - panel* Panel; - - // NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying, - // it stores the value calculated when the operation mode is kicked off. - rect2 InitialPanelBounds; - panel_split_direction PanelEdgeDirection; - panel_edit_mode PanelEditMode; -}; - -OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder) -{ - drag_panel_border_operation_state* OpState = (drag_panel_border_operation_state*)Operation.OpStateMemory; - rect2 PanelBounds = OpState->InitialPanelBounds; - - if (OpState->PanelEditMode == PanelEdit_Modify) - { - v4 EdgePreviewColor = v4{.3f, .3f, .3f, 1.f}; - - v2 EdgePreviewMin = {}; - v2 EdgePreviewMax = {}; - if (OpState->PanelEdgeDirection == PanelSplit_Horizontal) - { - EdgePreviewMin = v2{PanelBounds.Min.x, Mouse.Pos.y}; - EdgePreviewMax = v2{PanelBounds.Max.x, Mouse.Pos.y + 1}; - } - else if (OpState->PanelEdgeDirection == PanelSplit_Vertical) - { - EdgePreviewMin = v2{Mouse.Pos.x, PanelBounds.Min.y}; - EdgePreviewMax = v2{Mouse.Pos.x + 1, PanelBounds.Max.y}; - } - - PushRenderQuad2D(RenderBuffer, EdgePreviewMin, EdgePreviewMax, EdgePreviewColor); - } - else if (OpState->PanelEditMode == PanelEdit_Destroy) - { - rect2 PanelToDeleteBounds = {}; - if (OpState->PanelEdgeDirection == PanelSplit_Horizontal) - { - r32 SplitY = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y); - if (Mouse.Pos.y > SplitY) - { - PanelToDeleteBounds = GetTopPanelBounds(OpState->Panel, PanelBounds); - } - else - { - PanelToDeleteBounds = GetBottomPanelBounds(OpState->Panel, PanelBounds); - } - } - else if (OpState->PanelEdgeDirection == PanelSplit_Vertical) - { - r32 SplitX = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x); - if (Mouse.Pos.x > SplitX) - { - PanelToDeleteBounds = GetRightPanelBounds(OpState->Panel, PanelBounds); - } - else - { - PanelToDeleteBounds = GetLeftPanelBounds(OpState->Panel, PanelBounds); - } - } - v4 OverlayColor = v4{0, 0, 0, .3f}; - PushRenderQuad2D(RenderBuffer, PanelToDeleteBounds.Min, PanelToDeleteBounds.Max, OverlayColor); - } -} - -FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation) -{ - drag_panel_border_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_panel_border_operation_state); - rect2 PanelBounds = OpState->InitialPanelBounds; - - if (OpState->PanelEditMode == PanelEdit_Modify) - { - if (OpState->Panel->SplitDirection == PanelSplit_Horizontal) - { - r32 NewSplitY = Mouse.Pos.y; - if (NewSplitY <= PanelBounds.Min.y) - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Top, &State->PanelSystem); - } - else if (NewSplitY >= PanelBounds.Max.y) - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Bottom, &State->PanelSystem); - } - else - { - OpState->Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Rect2Height(PanelBounds); - Panel_UpdateLayout(OpState->Panel, PanelBounds); - } - } - else if (OpState->Panel->SplitDirection == PanelSplit_Vertical) - { - r32 NewSplitX = Mouse.Pos.x; - if (NewSplitX <= PanelBounds.Min.x) - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Right, &State->PanelSystem); - } - else if (NewSplitX >= PanelBounds.Max.x) - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Left, &State->PanelSystem); - } - else - { - OpState->Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Rect2Width(PanelBounds); - Panel_UpdateLayout(OpState->Panel, PanelBounds); - } - } - } - else // PanelEdit_Destroy - { - if (OpState->PanelEdgeDirection == PanelSplit_Horizontal) - { - r32 SplitY = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y); - if (Mouse.Pos.y > SplitY) - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Bottom, &State->PanelSystem); - } - else - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Top, &State->PanelSystem); - } - } - else if (OpState->PanelEdgeDirection == PanelSplit_Vertical) - { - r32 SplitX = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x); - if (Mouse.Pos.x > SplitX) - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Left, &State->PanelSystem); - } - else - { - ConsolidatePanelsKeepOne(OpState->Panel, OpState->Panel->Right, &State->PanelSystem); - } - } - } - - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command DragPanelBorderCommands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDragPanelBorderOperation }, - { KeyCode_MouseRightButton, KeyCode_Invalid, Command_Ended, EndDragPanelBorderOperation }, -}; - -internal void -BeginDragPanelBorder(panel* Panel, panel_edit_mode PanelEditMode, rect2 PanelBounds, panel_split_direction PanelEdgeDirection, mouse_state Mouse, app_state* State) -{ - operation_mode* DragPanelBorder = ActivateOperationModeWithCommands(&State->Modes, DragPanelBorderCommands, UpdateAndRenderDragPanelBorder); - drag_panel_border_operation_state* OpState = CreateOperationState(DragPanelBorder, &State->Modes, drag_panel_border_operation_state); - OpState->Panel = Panel; - OpState->InitialPanelBounds = PanelBounds; - OpState->PanelEdgeDirection = PanelEdgeDirection; - OpState->PanelEditMode = PanelEditMode; -} - -// ---------------- - -// -// Drag To Split Panel Operation - - -OPERATION_STATE_DEF(split_panel_operation_state) -{ - panel* Panel; - - // NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying, - // it stores the value calculated when the operation mode is kicked off. - rect2 InitialPanelBounds; -}; - -OPERATION_RENDER_PROC(UpdateAndRenderSplitPanel) -{ - split_panel_operation_state* OpState = (split_panel_operation_state*)Operation.OpStateMemory; - rect2 PanelBounds = OpState->InitialPanelBounds; - v4 EdgePreviewColor = v4{.3f, .3f, .3f, 1.f}; - - r32 MouseDeltaX = Abs(Mouse.Pos.x - Mouse.DownPos.x); - r32 MouseDeltaY = Abs(Mouse.Pos.y - Mouse.DownPos.y); - - v2 EdgePreviewMin = {}; - v2 EdgePreviewMax = {}; - if (MouseDeltaY > MouseDeltaX) // Horizontal Split - { - EdgePreviewMin = v2{PanelBounds.Min.x, Mouse.Pos.y}; - EdgePreviewMax = v2{PanelBounds.Max.x, Mouse.Pos.y + 1}; - } - else // Vertical Split - { - EdgePreviewMin = v2{Mouse.Pos.x, PanelBounds.Min.y}; - EdgePreviewMax = v2{Mouse.Pos.x + 1, PanelBounds.Max.y}; - } - - PushRenderQuad2D(RenderBuffer, EdgePreviewMin, EdgePreviewMax, EdgePreviewColor); -} - -FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation) -{ - split_panel_operation_state* OpState = GetCurrentOperationState(State->Modes, split_panel_operation_state); - rect2 PanelBounds = OpState->InitialPanelBounds; - - r32 XDistance = Abs(Mouse.Pos.x - Mouse.DownPos.x); - r32 YDistance = Abs(Mouse.Pos.y - Mouse.DownPos.y); - - if (XDistance > YDistance) - { - r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds); - SplitPanelVertically(Panel, XPercent, &State->PanelSystem, State, Context); - } - else - { - r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Rect2Height(PanelBounds); - SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem, State, Context); - } - - s32 PanelTypeIndex = Panel->TypeIndex; - gs_data PanelStateMemory = Panel->StateMemory; - Panel_SetCurrentType(Panel->Left, &State->PanelSystem, PanelTypeIndex, PanelStateMemory, State, Context); - - Panel_SetType(Panel->Right, &State->PanelSystem, PanelTypeIndex, State, Context); - - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command SplitPanelCommands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndSplitPanelOperation }, -}; - -internal void -BeginSplitPanelOperation(panel* Panel, mouse_state Mouse, app_state* State) -{ - operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel); - split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state); - OpState->Panel = Panel; - OpState->InitialPanelBounds = Panel->Bounds; -} - - -// ---------------- - -#define PANEL_EDGE_CLICK_MAX_DISTANCE 6 - -internal b32 -HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, mouse_state Mouse, app_state* State) -{ - b32 HandledMouseInput = false; - - // TODO(pjs): this can probably live in panel_with_layout - rect2 PanelSplitButtonBounds = rect2{ Panel->Bounds.Min, Panel->Bounds.Min + v2{25, 25} }; - - if (Panel->SplitDirection == PanelSplit_NoSplit - && PointIsInRect(PanelSplitButtonBounds, Mouse.DownPos)) - { - BeginSplitPanelOperation(Panel, Mouse, State); - HandledMouseInput = true; - } - else if (Panel->SplitDirection != PanelSplit_NoSplit) - { - u32 ElementIndex = 0; - switch(Panel->SplitDirection) - { - case PanelSplit_Vertical: { ElementIndex = 0; } break; - case PanelSplit_Horizontal: { ElementIndex = 1; } break; - InvalidDefaultCase; - } - - r32 SplitPosition = LerpR32(Panel->SplitPercent, Panel->Bounds.Min.E[ElementIndex], Panel->Bounds.Max.E[ElementIndex]); - r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.E[ElementIndex] - SplitPosition); - if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE) - { - BeginDragPanelBorder(Panel, PanelEditMode, Panel->Bounds, Panel->SplitDirection, Mouse, State); - } - else - { - if (PointIsInRect(Panel->Bottom->Bounds, Mouse.DownPos)) - { - HandleMouseDownPanelInteractionOrRecurse(Panel->Bottom, PanelEditMode, Mouse, State); - } - else if (PointIsInRect(Panel->Top->Bounds, Mouse.DownPos)) - { - HandleMouseDownPanelInteractionOrRecurse(Panel->Top, PanelEditMode, Mouse, State); - } - } - } - - return HandledMouseInput; -} - -internal b32 -HandleMousePanelInteraction(panel_system* PanelSystem, rect2 WindowBounds, mouse_state Mouse, app_state* State) -{ - b32 HandledMouseInput = false; - - panel* FirstPanel = PanelSystem->Panels + 0; - panel_edit_mode EditMode = PanelEdit_Invalid; - - if (MouseButtonTransitionedDown(Mouse.LeftButtonState)) - { - EditMode = PanelEdit_Modify; - } - else if (MouseButtonTransitionedDown(Mouse.RightButtonState)) - { - EditMode = PanelEdit_Destroy; - } - - if (EditMode != PanelEdit_Invalid) - { - HandledMouseInput = HandleMouseDownPanelInteractionOrRecurse(FirstPanel, EditMode, Mouse, State); - } - - return HandledMouseInput; -} - -internal void -DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, mouse_state* Mouse, render_command_buffer* RenderBuffer) -{ - r32 MouseLeftEdgeDistance = Abs(Mouse->Pos.x - PanelMin.x); - r32 MouseRightEdgeDistance = Abs(Mouse->Pos.x - PanelMax.x); - r32 MouseTopEdgeDistance = Abs(Mouse->Pos.y - PanelMax.y); - r32 MouseBottomEdgeDistance = Abs(Mouse->Pos.y - PanelMin.y); - - v4 Color = BlackV4; - PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color); - - v4 HighlightColor = v4{.3f, .3f, .3f, 1.f}; - r32 HighlightThickness = 1; - if (MouseLeftEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) - { - v2 LeftEdgeMin = PanelMin; - v2 LeftEdgeMax = v2{PanelMin.x + HighlightThickness, PanelMax.y}; - PushRenderQuad2D(RenderBuffer, LeftEdgeMin, LeftEdgeMax, HighlightColor); - Mouse->CursorType = CursorType_HArrows; - } - else if (MouseRightEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) - { - v2 RightEdgeMin = v2{PanelMax.x - HighlightThickness, PanelMin.y}; - v2 RightEdgeMax = PanelMax; - PushRenderQuad2D(RenderBuffer, RightEdgeMin, RightEdgeMax, HighlightColor); - Mouse->CursorType = CursorType_HArrows; - } - else if (MouseTopEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) - { - v2 TopEdgeMin = v2{PanelMin.x, PanelMax.y - HighlightThickness}; - v2 TopEdgeMax = PanelMax; - PushRenderQuad2D(RenderBuffer, TopEdgeMin, TopEdgeMax, HighlightColor); - Mouse->CursorType = CursorType_VArrows; - } - else if (MouseBottomEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) - { - v2 BottomEdgeMin = PanelMin; - v2 BottomEdgeMax = v2{PanelMax.x, PanelMin.y + HighlightThickness}; - PushRenderQuad2D(RenderBuffer, BottomEdgeMin, BottomEdgeMax, HighlightColor); - Mouse->CursorType = CursorType_VArrows; - } -} - -internal void -DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterBounds, mouse_state Mouse, app_state* State, context Context) -{ - PushRenderQuad2D(RenderBuffer, FooterBounds.Min, v2{FooterBounds.Max.x, FooterBounds.Min.y + 25}, v4{.5f, .5f, .5f, 1.f}); - PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4); - - rect2 PanelSelectBtnBounds = MakeRect2MinDim(FooterBounds.Min + v2{30, 1}, v2{100, 23}); - - panel_definition CurrentDef = State->PanelSystem.PanelDefs[Panel->TypeIndex]; - if (ui_BeginDropdown(&State->Interface, MakeString(CurrentDef.PanelName, CurrentDef.PanelNameLength), PanelSelectBtnBounds)) - { - for (s32 i = 0; i < GlobalPanelDefsCount; i++) - { - panel_definition Def = State->PanelSystem.PanelDefs[i]; - gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength); - if (ui_Button(&State->Interface, DefName)) - { - Panel_SetType(Panel, &State->PanelSystem, i, State, Context); - } - } - } - ui_EndDropdown(&State->Interface); -} - -internal void -RenderPanel(panel* Panel, rect2 PanelBounds, rect2 WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse) -{ - u32 PanelType = Panel->TypeIndex; - Assert(PanelType >= 0); - Assert(PanelType < State->PanelSystem.PanelDefsCount); - - rect2 FooterBounds = rect2{ - PanelBounds.Min, - v2{PanelBounds.Max.x, PanelBounds.Min.y + 25}, - }; - rect2 PanelViewBounds = rect2{ - v2{PanelBounds.Min.x, FooterBounds.Max.y}, - PanelBounds.Max, - }; - - panel_definition Definition = State->PanelSystem.PanelDefs[PanelType]; - Definition.Render(Panel, PanelViewBounds, RenderBuffer, State, Context); - - PushRenderOrthographic(RenderBuffer, WindowBounds); - DrawPanelFooter(Panel, RenderBuffer, FooterBounds, Mouse, State, Context); -} - -internal void -DrawPanelRecursive(panel* Panel, render_command_buffer* RenderBuffer, mouse_state* Mouse, app_state* State, context Context) -{ - rect2 Bounds = Panel->Bounds; - switch (Panel->SplitDirection) - { - case PanelSplit_Horizontal: - case PanelSplit_Vertical: - { - DrawPanelRecursive(Panel->Left, RenderBuffer, Mouse, State, Context); - DrawPanelRecursive(Panel->Right, RenderBuffer, Mouse, State, Context); - }break; - - case PanelSplit_NoSplit: - { - panel* OverridePanel = Panel_GetModalOverride(Panel); - RenderPanel(OverridePanel, Bounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse); - PushRenderOrthographic(RenderBuffer, State->WindowBounds); - DrawPanelBorder(*OverridePanel, Bounds.Min, Bounds.Max, Mouse, RenderBuffer); - }break; - - InvalidDefaultCase; - } -} - -internal void -DrawAllPanels(panel_system System, render_command_buffer* RenderBuffer, mouse_state* Mouse, app_state* State, context Context) -{ - panel* PanelAt = System.Panels + 0; - DrawPanelRecursive(PanelAt, RenderBuffer, Mouse, State, Context); -} - -#define FOLDHAUS_INTERFACE_CPP -#endif // FOLDHAUS_INTERFACE_CPP \ No newline at end of file diff --git a/src/app/editor/foldhaus_operation_mode.h b/src/app/editor/foldhaus_operation_mode.h deleted file mode 100644 index 375d342..0000000 --- a/src/app/editor/foldhaus_operation_mode.h +++ /dev/null @@ -1,142 +0,0 @@ -// -// File: foldhaus_operation_mode.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_OPERATION_MODE_H - -typedef struct operation_mode operation_mode; - -#define OPERATION_STATE_DEF(name) struct name - -#define OPERATION_RENDER_PROC(name) void name(app_state* State, render_command_buffer* RenderBuffer, operation_mode Operation, mouse_state Mouse, context Context) -typedef OPERATION_RENDER_PROC(operation_render_proc); - -struct operation_mode -{ - input_command_registry Commands; - operation_render_proc* Render; - gs_memory_cursor Memory; - u8* OpStateMemory; -}; - -#define OPERATION_MODES_MAX 32 -struct operation_mode_system -{ - s32 ActiveModesCount; - operation_mode ActiveModes[OPERATION_MODES_MAX]; - //arena_snapshot ModeMemorySnapshots[OPERATION_MODES_MAX]; - gs_data_array ModeMemoryPagesFreeList; - - // NOTE(Peter): This acts as mode scoped memory. When a mode gets activated, it can allocate - // temporary memory which then gets freed when the mode is deactivated - gs_memory_arena Arena; -}; - -internal operation_mode_system -OperationModeSystemInit(gs_memory_arena* Storage, gs_thread_context ThreadContext) -{ - operation_mode_system Result = {0}; - // TODO(Peter): Do we really need an arena? Can this just operate in constant memory footprint? - Result.Arena.Allocator = ThreadContext.Allocator; - - Result.ModeMemoryPagesFreeList.CountMax = 8; - Result.ModeMemoryPagesFreeList.Data = PushArray(Storage, gs_data, Result.ModeMemoryPagesFreeList.CountMax); - for (u32 Page = 0; Page < Result.ModeMemoryPagesFreeList.CountMax; Page++) - { - Result.ModeMemoryPagesFreeList.Data[Page] = PushSize(Storage, KB(4)); - } - Result.ModeMemoryPagesFreeList.Count = Result.ModeMemoryPagesFreeList.CountMax; - - return Result; -} - -internal gs_data -OperationModeTakeMemoryPage(operation_mode_system* System) -{ - Assert(System->ModeMemoryPagesFreeList.Count > 0); - gs_data Result = {0}; - System->ModeMemoryPagesFreeList.Count -= 1; - u64 LastIndex = System->ModeMemoryPagesFreeList.Count; - Result = System->ModeMemoryPagesFreeList.Data[LastIndex]; - return Result; -} - -internal void -OperationModeFreeMemoryPage(operation_mode_system* System, gs_data Data) -{ - Assert(System->ModeMemoryPagesFreeList.Count < System->ModeMemoryPagesFreeList.CountMax); - u64 LastIndex = System->ModeMemoryPagesFreeList.Count; - System->ModeMemoryPagesFreeList.Count += 1; - System->ModeMemoryPagesFreeList.Data[LastIndex] = Data; -} - -internal operation_mode* -ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc) -{ - Assert(System->ActiveModesCount < OPERATION_MODES_MAX); - operation_mode* Result = 0; - s32 ModeIndex = System->ActiveModesCount++; - - //System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena); - - Result = &System->ActiveModes[ModeIndex]; - Result->Memory = MemoryCursorCreateFromData(OperationModeTakeMemoryPage(System)); - Result->Render = RenderProc; - - return Result; -} - -#define ActivateOperationModeWithCommands(sys, cmds, render) \ -ActivateOperationModeWithCommands_(sys, cmds, (s32)(sizeof(cmds) / sizeof(cmds[0])), render); - -internal operation_mode* -ActivateOperationModeWithCommands_(operation_mode_system* System, input_command* Commands, s32 CommandsCount, operation_render_proc* RenderProc) -{ - operation_mode* NewMode = ActivateOperationMode(System, RenderProc); - -#if 0 - InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena); - for (s32 i = 0; i < CommandsCount; i++) - { - input_command Command = Commands[i]; - RegisterKeyPressCommand(&NewMode->Commands, Command.Key, Command.Flags, Command.Mdfr, Command.Proc); - } -#else - NewMode->Commands.Commands = Commands; - NewMode->Commands.Size = CommandsCount; - NewMode->Commands.Used = CommandsCount; -#endif - return NewMode; -} - -internal void -DeactivateCurrentOperationMode (operation_mode_system* System) -{ - Assert(System->ActiveModesCount > 0); - s32 ModeIndex = --System->ActiveModesCount; - OperationModeFreeMemoryPage(System, System->ActiveModes[ModeIndex].Memory.Data); - //ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]); -} - -#define CreateOperationState(mode, modeSystem, stateType) \ -(stateType*)CreateOperationState_(mode, modeSystem, sizeof(stateType)) - -#define GetCurrentOperationState(modeSystem, stateType) \ -(stateType*)(modeSystem).ActiveModes[(modeSystem).ActiveModesCount - 1].OpStateMemory; - - -internal u8* -CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize) -{ - // NOTE(Peter): This isn't a problem if this fires, it just means our page size is too small, - // and its time to make the pages dynamically sized - Assert(Mode->Memory.Data.Size >= StateSize); - u8* Result = MemoryCursorPushSize(&Mode->Memory, StateSize).Memory; - Mode->OpStateMemory = Result; - return Result; -} - - -#define FOLDHAUS_OPERATION_MODE_H -#endif // FOLDHAUS_OPERATION_MODE_H \ No newline at end of file diff --git a/src/app/editor/foldhaus_panel.h b/src/app/editor/foldhaus_panel.h deleted file mode 100644 index b8a59a8..0000000 --- a/src/app/editor/foldhaus_panel.h +++ /dev/null @@ -1,442 +0,0 @@ -// -// File: foldhaus_panel.h -// Author: Peter Slattery -// Creation Date: 2019-12-26 -// -// Usage: -// Include this file in ONE file in your project. -// Define SetPanelDefinitionExternal -// -#ifndef FOLDHAUS_PANEL_H - -enum panel_split_direction -{ - PanelSplit_NoSplit, - PanelSplit_Horizontal, - PanelSplit_Vertical, - - PanelSplit_Count, -}; - -typedef struct panel panel; - -#define PANEL_MODAL_OVERRIDE_CALLBACK(name) void name(panel* ReturningFrom, app_state* State, context Context) -typedef PANEL_MODAL_OVERRIDE_CALLBACK(panel_modal_override_callback); - -struct panel -{ - s32 TypeIndex; - gs_data StateMemory; - - panel* ModalOverride; - panel* IsModalOverrideFor; - panel_modal_override_callback* ModalOverrideCB; - - rect2 Bounds; - panel_split_direction SplitDirection; - r32 SplitPercent; - - panel* Parent; - - union{ - panel* Left; - panel* Top; - }; - union{ - panel* Right; - panel* Bottom; - }; -}; - -struct free_panel -{ - free_panel* Next; -}; - -#define PANEL_INIT_PROC(name) void name(panel* Panel, app_state* State, context Context) -typedef PANEL_INIT_PROC(panel_init_proc); - -#define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State) -typedef PANEL_CLEANUP_PROC(panel_cleanup_proc); - -#define PANEL_RENDER_PROC(name) void name(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -typedef PANEL_RENDER_PROC(panel_render_proc); - -// NOTE(Peter): This is used by the meta system to generate panel type info -struct panel_definition -{ - char* PanelName; - s32 PanelNameLength; - panel_init_proc* Init; - panel_cleanup_proc* Cleanup; - panel_render_proc* Render; - input_command* InputCommands; - s32 InputCommandsCount; -}; - -#define PANELS_MAX 16 -struct panel_system -{ - panel_definition* PanelDefs; - u32 PanelDefsCount; - - panel* Panels; - u32 PanelsUsed; - - free_panel* FreeList; -}; - -///////////////////////////////// -// -// Book-Keeping -// -///////////////////////////////// - -internal void -PanelSystem_Init(panel_system* PanelSystem, panel_definition* PanelDefs, u32 PanelDefsCount, gs_memory_arena* Storage) -{ - PanelSystem->FreeList = 0; - PanelSystem->PanelDefs = PanelDefs; - PanelSystem->PanelDefsCount = PanelDefsCount; - - PanelSystem->Panels = PushArray(Storage, panel, PANELS_MAX); -} - -internal panel* -PanelSystem_TakePanel(panel_system* PanelSystem) -{ - panel* FreeEntry = 0; - if (PanelSystem->FreeList != 0) - { - free_panel* FreePanel = PanelSystem->FreeList; - PanelSystem->FreeList = FreePanel->Next; - FreeEntry = (panel*)FreePanel; - } - else - { - Assert(PanelSystem->PanelsUsed < PANELS_MAX); - FreeEntry = PanelSystem->Panels + PanelSystem->PanelsUsed++; - } - return FreeEntry; -} - -internal void -PanelSystem_FreePanel(panel* Panel, panel_system* PanelSystem) -{ - Assert(Panel >= PanelSystem->Panels && Panel <= PanelSystem->Panels + PANELS_MAX); - - free_panel* FreeEntry = (free_panel*)Panel; - FreeEntry->Next = PanelSystem->FreeList; - PanelSystem->FreeList = FreeEntry; -} - -internal void -PanelSystem_FreePanelRecursive(panel* Panel, panel_system* PanelSystem) -{ - if (Panel->SplitDirection != PanelSplit_NoSplit) - { - PanelSystem_FreePanelRecursive(Panel->Left, PanelSystem); - PanelSystem_FreePanelRecursive(Panel->Right, PanelSystem); - } - PanelSystem_FreePanel(Panel, PanelSystem); -} - -internal panel* -Panel_GetModalOverride(panel* Panel) -{ - panel* Result = Panel; - if (Panel->ModalOverride != 0) - { - Result = Panel_GetModalOverride(Panel->ModalOverride); - } - return Result; -} - -internal void -Panel_PushModalOverride(panel* Root, panel* Override, panel_modal_override_callback* Callback) -{ - Root->ModalOverride = Override; - Root->ModalOverrideCB = Callback; - Override->IsModalOverrideFor = Root; - Override->Bounds = Root->Bounds; -} - -internal void -Panel_PopModalOverride(panel* Parent, panel_system* System) -{ - // TODO(pjs): Free the overrided panel - PanelSystem_FreePanel(Parent->ModalOverride, System); - Parent->ModalOverride = 0; -} - -internal void -Panel_SetCurrentType(panel* Panel, panel_system* System, s32 NewPanelType, gs_data TypeStateMemory, app_state* State, context Context) -{ - s32 OldTypeIndex = Panel->TypeIndex; - - Panel->TypeIndex = NewPanelType; - Panel->StateMemory = TypeStateMemory; - - if(OldTypeIndex >= 0) - { - System->PanelDefs[OldTypeIndex].Cleanup(Panel, State); - } -} - -internal void -Panel_SetType(panel* Panel, panel_system* System, s32 NewPanelTypeIndex, app_state* State, context Context) -{ - gs_data EmptyStateData = {0}; - Panel_SetCurrentType(Panel, System, NewPanelTypeIndex, EmptyStateData, State, Context); - System->PanelDefs[NewPanelTypeIndex].Init(Panel, State, Context); -} - -#define Panel_GetStateStruct(p, type) (type*)Panel_GetStateMemory((p), sizeof(type)).Memory -internal gs_data -Panel_GetStateMemory(panel* Panel, u64 Size) -{ - Assert(Panel->StateMemory.Size == Size); - gs_data Result = Panel->StateMemory; - return Result; -} - -internal panel* -PanelSystem_PushPanel(panel_system* PanelSystem, s32 PanelTypeIndex, app_state* State, context Context) -{ - panel* Panel = PanelSystem_TakePanel(PanelSystem); - Panel_SetType(Panel, PanelSystem, PanelTypeIndex, State, Context); - return Panel; -} - -internal void -SplitPanel(panel* Parent, r32 Percent, panel_split_direction SplitDirection, panel_system* PanelSystem, app_state* State, context Context) -{ - if (Percent >= 0.0f && Percent <= 1.0f) - { - Parent->SplitDirection = SplitDirection; - Parent->SplitPercent = Percent; - - s32 ParentTypeIndex = Parent->TypeIndex; - gs_data ParentStateMemory = Parent->StateMemory; - - Parent->Left = PanelSystem_TakePanel(PanelSystem); - Panel_SetCurrentType(Parent->Left, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context); - Parent->Left->Parent = Parent; - - Parent->Right = PanelSystem_TakePanel(PanelSystem); - Panel_SetCurrentType(Parent->Right, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context); - Parent->Right->Parent = Parent; - } -} - -internal void -SplitPanelVertically(panel* Parent, r32 Percent, panel_system* PanelSystem, app_state* State, context Context) -{ - SplitPanel(Parent, Percent, PanelSplit_Vertical, PanelSystem, State, Context); -} - -internal void -SplitPanelHorizontally(panel* Parent, r32 Percent, panel_system* PanelSystem, app_state* State, context Context) -{ - SplitPanel(Parent, Percent, PanelSplit_Horizontal, PanelSystem, State, Context); -} - -internal void -ConsolidatePanelsKeepOne(panel* Parent, panel* PanelToKeep, panel_system* PanelSystem) -{ - panel* LeftChild = Parent->Left; - panel* RightChild = Parent->Right; - - panel* PanelToDestroy = PanelToKeep == LeftChild ? RightChild : LeftChild; - - *Parent = *PanelToKeep; - - PanelSystem_FreePanel(PanelToKeep, PanelSystem); - PanelSystem_FreePanelRecursive(PanelToDestroy, PanelSystem); -} - -///////////////////////////////// -// -// Rendering And Interaction -// -///////////////////////////////// - -internal rect2 -GetTopPanelBounds(panel* Panel) -{ - rect2 Result = {}; - Result.Min = v2{ - Panel->Bounds.Min.x, - LerpR32(Panel->SplitPercent, Panel->Bounds.Min.y, Panel->Bounds.Max.y) - }; - Result.Max = Panel->Bounds.Max; - return Result; -} - -internal rect2 -GetBottomPanelBounds(panel* Panel) -{ - rect2 Result = {}; - Result.Min = Panel->Bounds.Min; - Result.Max = v2{ - Panel->Bounds.Max.x, - LerpR32(Panel->SplitPercent, Panel->Bounds.Min.y, Panel->Bounds.Max.y) - }; - return Result; -} - -internal rect2 -GetRightPanelBounds(panel* Panel) -{ - rect2 Result = {}; - Result.Min = v2{ - LerpR32(Panel->SplitPercent, Panel->Bounds.Min.x, Panel->Bounds.Max.x), - Panel->Bounds.Min.y - }; - Result.Max = Panel->Bounds.Max; - return Result; -} - -internal rect2 -GetLeftPanelBounds(panel* Panel) -{ - rect2 Result = {}; - Result.Min = Panel->Bounds.Min; - Result.Max = v2{ - LerpR32(Panel->SplitPercent, Panel->Bounds.Min.x, Panel->Bounds.Max.x), - Panel->Bounds.Max.y - }; - return Result; -} - -internal rect2 -GetTopPanelBounds(panel* Panel, rect2 PanelBounds) -{ - rect2 Result = {}; - Result.Min = v2{ - PanelBounds.Min.x, - LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y) - }; - Result.Max = PanelBounds.Max; - return Result; -} - -internal rect2 -GetBottomPanelBounds(panel* Panel, rect2 PanelBounds) -{ - rect2 Result = {}; - Result.Min = PanelBounds.Min; - Result.Max = v2{ - PanelBounds.Max.x, - LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y) - }; - return Result; -} - -internal rect2 -GetRightPanelBounds(panel* Panel, rect2 PanelBounds) -{ - rect2 Result = {}; - Result.Min = v2{ - LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x), - PanelBounds.Min.y - }; - Result.Max = PanelBounds.Max; - return Result; -} - -internal rect2 -GetLeftPanelBounds(panel* Panel, rect2 PanelBounds) -{ - rect2 Result = {}; - Result.Min = PanelBounds.Min; - Result.Max = v2{ - LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x), - PanelBounds.Max.y - }; - return Result; -} - -internal void -Panel_UpdateLayout(panel* Panel, rect2 Bounds) -{ - Panel->Bounds = Bounds; - - if (Panel->SplitDirection != PanelSplit_NoSplit) - { - rect2 LeftOrTopBounds = {}; - rect2 RightOrBottomBounds = {}; - switch (Panel->SplitDirection) - { - case PanelSplit_Horizontal: - { - LeftOrTopBounds = GetTopPanelBounds(Panel); - RightOrBottomBounds = GetBottomPanelBounds(Panel); - } break; - - case PanelSplit_Vertical: - { - LeftOrTopBounds = GetLeftPanelBounds(Panel); - RightOrBottomBounds = GetRightPanelBounds(Panel); - } break; - - InvalidDefaultCase; - } - - Panel_UpdateLayout(Panel->Left, LeftOrTopBounds); - Panel_UpdateLayout(Panel->Right, RightOrBottomBounds); - } -} - -internal void -PanelSystem_UpdateLayout(panel_system* System, rect2 WindowBounds) -{ - panel* Root = System->Panels; - Panel_UpdateLayout(Root, WindowBounds); -} - -internal panel* -GetPanelContainingPoint(panel* Panel, v2 Point) -{ - panel* Result = 0; - - if (PointIsInRect(Panel->Bounds, Point)) - { - switch (Panel->SplitDirection) - { - case PanelSplit_NoSplit: - { - Result = Panel; - }break; - - case PanelSplit_Vertical: - case PanelSplit_Horizontal: - {asdfasdfasdfasdfasdf - if (PointIsInRect(Panel->Left->Bounds, Point)) - { - Result = GetPanelContainingPoint(Panel->Left, Point); - } - else if (PointIsInRect(Panel->Right->Bounds, Point)) - { - Result = GetPanelContainingPoint(Panel->Right, Point); - } - }break; - - InvalidDefaultCase; - } - } - - return Result; -} - -internal panel* -PanelSystem_GetPanelContainingPoint(panel_system* System, v2 Point) -{ - panel* Result = 0; - panel* Root = System->Panels; - Result = GetPanelContainingPoint(Root, Point); - return Result; -} - -#define FOLDHAUS_PANEL_H -#endif // FOLDHAUS_PANEL_H \ No newline at end of file diff --git a/src/app/editor/interface.h b/src/app/editor/interface.h deleted file mode 100644 index d618089..0000000 --- a/src/app/editor/interface.h +++ /dev/null @@ -1,1677 +0,0 @@ -// -// File: interface.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef INTERFACE_H - -#define InterfaceAssert(IMemPtr) Assert(IMemPtr && (u64)IMemPtr != 0x5 && (u64)IMemPtr != 0xC) - -enum gs_string_alignment -{ - Align_Left, - Align_Center, - Align_Right, -}; - -internal void -ClipUVRect(rect2* Bounds, rect2* UVs, rect2 ClippingBox) -{ - rect2 NewBounds = Rect2Union(*Bounds, ClippingBox); - - r32 OldWidth = Rect2Width(*Bounds); - r32 OldHeight = Rect2Height(*Bounds); - - v2 MinInsetPercent = v2{ - (NewBounds.Min.x - Bounds->Min.x) / OldWidth, - (NewBounds.Min.y - Bounds->Min.y) / OldHeight, - }; - - v2 MaxInsetPercent = v2{ - (NewBounds.Max.x - Bounds->Min.x) / OldWidth, - (NewBounds.Max.y - Bounds->Min.y) / OldHeight, - }; - - UVs->Min.x = LerpR32(MinInsetPercent.x, UVs->Min.x, UVs->Max.x); - UVs->Min.y = LerpR32(MinInsetPercent.y, UVs->Min.y, UVs->Max.y); - UVs->Max.x = LerpR32(MaxInsetPercent.x, UVs->Min.x, UVs->Max.x); - UVs->Max.y = LerpR32(MaxInsetPercent.y, UVs->Min.y, UVs->Max.y); - - *Bounds = NewBounds; -} - -internal void -DrawCharacter_ (render_quad_batch_constructor* BatchConstructor, r32 MinX, r32 MinY, codepoint_bitmap CodepointInfo, rect2 ClippingBox, v4 Color) -{ - rect2 Bounds = {}; - Bounds.Min.x = FloorR32(MinX); - Bounds.Min.y = FloorR32(MinY); - Bounds.Max.x = Bounds.Min.x + (CodepointInfo.Width); - Bounds.Max.y = Bounds.Min.y + (CodepointInfo.Height); - - rect2 UVBounds = {}; - UVBounds.Min = CodepointInfo.UVMin; - UVBounds.Max = CodepointInfo.UVMax; - - ClipUVRect(&Bounds, &UVBounds, ClippingBox); - - s32 AlignedMinX = (s32)(MinX); - s32 AlignedMinY = (s32)(MinY); - s32 AlignedMaxX = AlignedMinX + (CodepointInfo.Width); - s32 AlignedMaxY = AlignedMinY + (CodepointInfo.Height); - - PushQuad2DOnBatch(BatchConstructor, - Rect2BottomLeft(Bounds), Rect2BottomRight(Bounds), - Rect2TopRight(Bounds), Rect2TopLeft(Bounds), - UVBounds.Min, UVBounds.Max, - Color); -} - -internal v2 -DrawCharacterLeftAligned (render_quad_batch_constructor* BatchConstructor, char C, bitmap_font Font, v2 Position, rect2 ClippingBox, v4 Color) -{ - s32 GlyphDataIndex = GetIndexForCodepoint(Font, C); - codepoint_bitmap CodepointInfo = Font.CodepointValues[GlyphDataIndex]; - - // NOTE(Peter): - r32 MinX = Position.x + CodepointInfo.XOffset; - r32 MinY = Position.y + CodepointInfo.YOffset; - DrawCharacter_(BatchConstructor, MinX, MinY, CodepointInfo, ClippingBox, Color); - - // NOTE(Peter): - v2 PointAfterCharacter = v2{Position.x + CodepointInfo.Width, Position.y}; - return PointAfterCharacter; -} - -internal v2 -DrawCharacterRightAligned (render_quad_batch_constructor* BatchConstructor, char C, bitmap_font Font, v2 Position, rect2 ClippingBox, v4 Color) -{ - s32 GlyphDataIndex = GetIndexForCodepoint(Font, C); - codepoint_bitmap CodepointInfo = Font.CodepointValues[GlyphDataIndex]; - - // NOTE(Peter): - r32 MinX = Position.x - (CodepointInfo.XOffset + CodepointInfo.Width); - r32 MinY = Position.y + CodepointInfo.YOffset + CodepointInfo.YOffset; - DrawCharacter_(BatchConstructor, MinX, MinY, CodepointInfo, ClippingBox, Color); - - // NOTE(Peter): - v2 PointAfterCharacter = v2{Position.x-(CodepointInfo.Width + CodepointInfo.XOffset), Position.y}; - return PointAfterCharacter; -} - -internal void -DrawCursor (render_command_buffer* RenderBuffer, v2 RegisterPosition, bitmap_font* Font, v4 Color) -{ - rect2 CursorRect = {}; - CursorRect.Min = RegisterPosition; - CursorRect.Max = CursorRect.Min + v2{5, (r32)Font->Ascent}; - PushRenderQuad2D(RenderBuffer, CursorRect, Color); -} - -internal v2 -DrawStringLeftAligned (render_command_buffer* RenderBuffer, render_quad_batch_constructor* BatchConstructor, s32 Length, char* gs_string, v2 InitialRegisterPosition, bitmap_font* Font, rect2 ClippingBox, v4 Color, s32 CursorBeforeIndex, v4 CursorColor) -{ - v2 RegisterPosition = InitialRegisterPosition; - char* C = gs_string; - for (s32 i = 0; i < Length; i++) - { - if (i == CursorBeforeIndex) - { - DrawCursor(RenderBuffer, RegisterPosition, Font, CursorColor); - } - - v2 PositionAfterCharacter = DrawCharacterLeftAligned(BatchConstructor, *C, *Font, RegisterPosition, ClippingBox, Color); - RegisterPosition.x = PositionAfterCharacter.x; - C++; - } - if (CursorBeforeIndex == Length) - { - DrawCursor(RenderBuffer, RegisterPosition, Font, CursorColor); - } - return RegisterPosition; -} - -internal v2 -DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* gs_string, v2 InitialRegisterPosition, bitmap_font* Font, rect2 ClippingBox, v4 Color) -{ - v2 RegisterPosition = InitialRegisterPosition; - char* C = gs_string + Length - 1; - for (s32 i = Length - 1; i >= 0; i--) - { - v2 PositionAfterCharacter = DrawCharacterRightAligned(BatchConstructor, *C, *Font, RegisterPosition, ClippingBox, Color); - RegisterPosition.x = PositionAfterCharacter.x; - C--; - } - return RegisterPosition; -} - -internal v2 -DrawString(render_command_buffer* RenderBuffer, gs_string String, bitmap_font* Font, v2 Position, v4 Color, s32 CursorPosition, v4 CursorColor, gs_string_alignment Alignment = Align_Left) -{ - DEBUG_TRACK_FUNCTION; - v2 LowerRight = Position; - - render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, String.Length + 1, - Font->BitmapMemory, - Font->BitmapTextureHandle, - Font->BitmapWidth, - Font->BitmapHeight, - Font->BitmapBytesPerPixel, - Font->BitmapStride); - - // TODO(pjs): I don't like this solution but it'll do for now and I want to focus on other problems - // especially since I think this one will go away once I finish the ui overhaul - rect2 InfiniteClipBox = {}; - InfiniteClipBox.Min.x = -100000; - InfiniteClipBox.Min.y = -100000; - InfiniteClipBox.Max.x = 100000; - InfiniteClipBox.Max.y = 100000; - - v2 RegisterPosition = Position; - if (Alignment == Align_Left) - { - RegisterPosition = DrawStringLeftAligned(RenderBuffer, &BatchConstructor, StringExpand(String), RegisterPosition, Font, InfiniteClipBox, Color, CursorPosition, CursorColor); - } - else if (Alignment == Align_Right) - { - RegisterPosition = DrawStringRightAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, InfiniteClipBox, Color); - } - else - { - InvalidCodePath; - } - - LowerRight.x = RegisterPosition.x; - - return LowerRight; -} - -internal void -DrawCursor (render_quad_batch_constructor* BatchConstructor, v2 Position, v4 Color, bitmap_font Font) -{ - v2 Min = Position; - v2 Max = Position + v2{(r32)Font.MaxCharWidth, (r32)(Font.Ascent + Font.Descent)}; - PushQuad2DOnBatch(BatchConstructor, Min, Max, Color); -} - -#if 0 -internal v2 -DrawStringWithCursor (render_command_buffer* RenderBuffer, gs_string String, s32 CursorPosition, bitmap_font* Font, v2 Position, v4 Color, v4 CursorColor, gs_string_alignment Alignment = Align_Left) -{ - 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); - - v2 RegisterPosition = Position; - if (Alignment == Align_Left) - { - RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color); - DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font); - if (String.Length - CursorPosition > 0) - { - RegisterPosition = DrawStringLeftAligned(&BatchConstructor, - String.Length - CursorPosition, - String.Str + CursorPosition, - RegisterPosition, Font, Color); - } - } - else if (Alignment == Align_Right) - { - RegisterPosition = DrawStringRightAligned(&BatchConstructor, - CursorPosition, String.Str, - RegisterPosition, Font, Color); - DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font); - if (String.Length - CursorPosition > 0) - { - RegisterPosition = DrawStringRightAligned(&BatchConstructor, - String.Length - CursorPosition, - String.Str + CursorPosition, - RegisterPosition, Font, Color); - } - } - else - { - InvalidCodePath; - } - - LowerRight.x = RegisterPosition.x; - return LowerRight; -} -#endif - -enum ui_widget_flag -{ - UIWidgetFlag_ExpandsToFitChildren, - - UIWidgetFlag_DrawBackground, - UIWidgetFlag_DrawString, - UIWidgetFlag_DrawOutline, - UIWidgetFlag_DrawHorizontalFill, - UIWidgetFlag_DrawVerticalFill, - UIWidgetFlag_DrawFillReversed, - UIWidgetFlag_DrawFillAsHandle, - - UIWidgetFlag_Clickable, - UIWidgetFlag_Selectable, - UIWidgetFlag_Typable, -}; - -struct ui_widget_id -{ - u64 Id; - u64 ZIndex; -}; - -enum ui_layout_direction -{ - LayoutDirection_TopDown, - LayoutDirection_BottomUp, - LayoutDirection_Inherit, -}; - -struct ui_column -{ - r32 XMin; - r32 XMax; -}; - -struct ui_widget -{ - ui_widget_id Id; - - gs_string String; - gs_string_alignment Alignment; - - rect2 Bounds; - u64 Flags; - - ui_widget* Next; - - // Slider - r32 FillPercent; - - // Layout - ui_widget* Parent; - - v2 Margin; - r32 RowHeight; - r32 RowYAt; - - ui_layout_direction FillDirection; - - ui_column* Columns; - u32 ColumnsCount; - u32 ColumnsFilled; - - // NOTE(pjs): I'm not sure this will stay but - // its here so that when we end things like a dropdown, - // we can check the retained state of that dropdown - ui_widget_id WidgetReference; - - u64 ChildZIndexOffset; - - ui_widget* ChildrenRoot; - ui_widget* ChildrenHead; - u32 ChildCount; -}; - -struct ui_eval_result -{ - bool Clicked; - bool Held; - v2 DragDelta; -}; - -struct interface_config -{ - v4 PanelBG; - - // TODO(pjs): Turn these into _Default, _Hot, _Active - v4 ButtonColor_Inactive, ButtonColor_Active, ButtonColor_Selected; - - v4 TextColor; - -#define LIST_BG_COLORS_COUNT 2 - v4 ListBGColors[LIST_BG_COLORS_COUNT]; - v4 ListBGHover; - v4 ListBGSelected; - - bitmap_font* Font; - r32 FontSize; - v2 Margin; - r32 RowHeight; -}; - -struct ui_widget_retained_state -{ - ui_widget_id Id; - bool Value; - r32 InitialValueR32; - u32 FramesSinceAccess; - - // For use in layouts that allow you to scroll / pan - v2 ChildrenDrawOffset; - - gs_string EditString; - - // For dropdowns and rows to be able to error check not closing - // a layout you open - u32 MaxChildren; -}; - -struct ui_interface -{ - interface_config Style; - - mouse_state Mouse; - rect2 WindowBounds; - - // A per-frame string of the characters which have been typed - gs_const_string TempInputString; - u64 CursorPosition; - - render_command_buffer* RenderBuffer; - - ui_widget* Widgets; - u64 WidgetsCount; - u64 WidgetsCountMax; - - ui_widget* DrawOrderHead; - ui_widget* DrawOrderRoot; - - ui_widget_id HotWidget; - // This should really never get higher than 1 or 2 - u8 HotWidgetFramesSinceUpdate; - - ui_widget_id ActiveWidget; - ui_widget_id LastActiveWidget; - - ui_widget* ActiveLayout; - -#define RETAINED_STATE_MAX 128 - ui_widget_retained_state RetainedState[RETAINED_STATE_MAX]; - u64 RetainedStateCount; - - gs_memory_arena* PerFrameMemory; - - // TODO(pjs): DONT USE THIS - // Right now you only need this to create EditStrings for ui_widget_retained_state's - // and even for those, you eventually want a better solution than "create a string and it lives forever" - // TODO(pjs): Get rid of the need for this vvv - gs_memory_arena* Permanent; -}; - -internal void -ui_InterfaceReset(ui_interface* Interface) -{ - Interface->WidgetsCount = 0; - Interface->DrawOrderHead = 0; - Interface->DrawOrderRoot = 0; - MemoryArenaClear(Interface->PerFrameMemory); - InterfaceAssert(Interface->PerFrameMemory); - - for (u32 i = 0; i < Interface->RetainedStateCount; i++) - { - Interface->RetainedState[i].FramesSinceAccess += 1; - if (Interface->RetainedState[i].FramesSinceAccess > 1) - { - Interface->RetainedState[i].Id = {0}; - } - } - - Interface->LastActiveWidget = Interface->ActiveWidget; -} - -internal bool -ui_WidgetIdsEqual(ui_widget_id A, ui_widget_id B) -{ - bool Result = (A.Id == B.Id);// && (A.ParentId == B.ParentId); - return Result; -} - -internal void -ui_WidgetSetFlag(ui_widget* Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - Widget->Flags = Widget->Flags | Value; -} - -internal void -ui_WidgetClearFlag(ui_widget* Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - Widget->Flags = Widget->Flags & ~Value; -} - -internal bool -ui_WidgetIsFlagSet(ui_widget Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - bool Result = (Widget.Flags & Value); - return Result; -} - -internal void -ui_WidgetSetChildrenPopover(ui_widget* Widget) -{ - Widget->ChildZIndexOffset = 1000; -} - -internal ui_widget* -ui_WidgetGetWidgetWithId(ui_widget* Parent, ui_widget_id Id) -{ - ui_widget* Result = 0; - - if (ui_WidgetIdsEqual(Parent->Id, Id)) - { - Result = Parent; - } - else if (Parent->ChildrenRoot != 0) - { - for (ui_widget* At = Parent->ChildrenRoot; At != 0; At = At->Next) - { - Result = ui_WidgetGetWidgetWithId(At, Id); - if (Result != 0) - { - break; - } - } - } - - return Result; -} - -internal ui_widget* -ui_InterfaceGetWidgetWithId(ui_interface* Interface, ui_widget_id Id) -{ - ui_widget* Result = 0; - - for (ui_widget* At = Interface->DrawOrderRoot; At != 0; At = At->Next) - { - Result = ui_WidgetGetWidgetWithId(At, Id); - if (Result != 0) - { - break; - } - } - - return Result; -} - -internal ui_widget_retained_state* -ui_GetRetainedState(ui_interface* Interface, ui_widget_id Id) -{ - ui_widget_retained_state* Result = 0; - for (u64 i = 0; i < Interface->RetainedStateCount; i++) - { - if (ui_WidgetIdsEqual(Interface->RetainedState[i].Id, Id)) - { - // NOTE(PS): If we are accessing a retained state, it shouldn't - // have been accessed longer ago than the last frame - //Assert(Interface->RetainedState[i].FramesSinceAccess <= 2); - Interface->RetainedState[i].FramesSinceAccess = 0; - Result = Interface->RetainedState + i; - break; - } - } - return Result; -} - -internal ui_widget_retained_state* -ui_CreateRetainedState(ui_interface* Interface, ui_widget* Widget) -{ - u64 Index = RETAINED_STATE_MAX; - if (Interface->RetainedStateCount >= RETAINED_STATE_MAX) - { - for (u32 i = 0; i < Interface->RetainedStateCount; i++) - { - if (Interface->RetainedState[i].FramesSinceAccess > 0) - { - Index = i; - break; - } - } - } else { - Index = Interface->RetainedStateCount++; - } - - Assert(Index < RETAINED_STATE_MAX); - ui_widget_retained_state* Result = Interface->RetainedState + Index; - Result->Id = Widget->Id; - if (Result->EditString.Size != 256) - { - Result->EditString = PushString(Interface->Permanent, 256); - } - return Result; -} - -internal ui_widget_retained_state* -ui_GetOrCreateRetainedState(ui_interface* Interface, ui_widget* Widget) -{ - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - if (!State) - { - State = ui_CreateRetainedState(Interface, Widget); - } - return State; -} - -internal ui_widget* -ui_CreateWidget(ui_interface* Interface, gs_string String) -{ - InterfaceAssert(Interface->PerFrameMemory); - Assert(Interface->WidgetsCount < Interface->WidgetsCountMax); - u64 Index = Interface->WidgetsCount++; - ui_widget* Result = Interface->Widgets + Index; - ZeroStruct(Result); - - Result->Parent = Interface->ActiveLayout; - - u64 Id = HashDJB2ToU64(StringExpand(String)); - if (Result->Parent) - { - Id = HashAppendDJB2ToU32(Id, Result->Parent->Id.Id); - Id = HashAppendDJB2ToU32(Id, Result->Parent->ChildCount); - //Result->Id.ParentId = Result->Parent->Id.Id; - } - Result->Id.Id = Id; - - u64 ZIndex = Index + 1; - if (Result->Parent) - { - Result->ChildZIndexOffset += Result->Parent->ChildZIndexOffset; - ZIndex += Result->Parent->ChildZIndexOffset; - } - Result->Id.ZIndex = ZIndex; - - Result->String = PushStringCopy(Interface->PerFrameMemory, String.ConstString); - InterfaceAssert(Interface->PerFrameMemory); - Result->Alignment = Align_Left; - Result->Next = 0; - Result->ChildrenRoot = 0; - Result->ChildrenHead = 0; - Result->Flags = 0; - ui_WidgetSetFlag(Result, UIWidgetFlag_ExpandsToFitChildren); - - return Result; -} - -// -// Interaction -// - -internal b32 -ui_MouseClickedRect(ui_interface Interface, rect2 Rect) -{ - b32 Result = MouseButtonTransitionedDown(Interface.Mouse.LeftButtonState); - Result &= PointIsInRect(Rect, Interface.Mouse.Pos); - return Result; -} - -// Layout - -static rect2 -ui_ReserveBounds(ui_interface* Interface, ui_widget* Widget, bool Inset) -{ - Assert(Widget->ColumnsCount > 0); - rect2 Bounds = {0}; - u32 ColumnIndex = Widget->ChildCount % Widget->ColumnsCount; - - ui_column Column = Widget->Columns[ColumnIndex]; - Bounds.Min.x = Column.XMin; - Bounds.Min.y = Widget->RowYAt; - Bounds.Max.x = Column.XMax; - Bounds.Max.y = Bounds.Min.y + Widget->RowHeight; - - if (Inset) - { - Bounds.Min.x += Widget->Margin.x; - Bounds.Min.y += Widget->Margin.y; - Bounds.Max.x -= Widget->Margin.x; - Bounds.Max.y -= Widget->Margin.y; - } - - if (Widget->ChildCount == 0) - { - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - if (State) - { - Bounds = Rect2Translate(Bounds, State->ChildrenDrawOffset); - } - } - - return Bounds; -} - -internal void -ui_CommitBounds(ui_widget* Parent, rect2 Bounds) -{ - u32 ColumnIndex = Parent->ChildCount % Parent->ColumnsCount; - if (ColumnIndex == 0) - { - switch (Parent->FillDirection) - { - case LayoutDirection_BottomUp: - { - Parent->RowYAt = Bounds.Max.y; - if (ui_WidgetIsFlagSet(*Parent, UIWidgetFlag_ExpandsToFitChildren)) - { - Parent->Bounds.Max.y = Parent->RowYAt; - } - }break; - - case LayoutDirection_TopDown: - { - Parent->RowYAt = Bounds.Min.y - Parent->RowHeight; - if (ui_WidgetIsFlagSet(*Parent, UIWidgetFlag_ExpandsToFitChildren)) - { - Parent->Bounds.Min.y = Bounds.Min.y; - } - }break; - } - } -} - -internal void -ui_ExpandParentToFit(ui_widget* Widget) -{ - ui_widget* Parent = Widget->Parent; - switch (Widget->FillDirection) - { - case LayoutDirection_TopDown: - { - Parent->Bounds.Min.y = Min(Parent->Bounds.Min.y, Widget->Bounds.Min.y - Parent->Margin.y); - }break; - - case LayoutDirection_BottomUp: - { - Parent->Bounds.Max.y = Max(Parent->Bounds.Max.y, Widget->Bounds.Max.y + Parent->Margin.y); - }break; - - InvalidDefaultCase; - } -} - -internal void -ui_WidgetCreateColumns(ui_widget* Widget, u32 ColumnsCount, ui_interface* Interface) -{ - Widget->Columns = PushArray(Interface->PerFrameMemory, ui_column, ColumnsCount); - InterfaceAssert(Interface->PerFrameMemory); - Widget->ColumnsCount = ColumnsCount; - Widget->ColumnsFilled = 0; -} - -internal void -ui_WidgetInitUniformColumns(ui_widget* Widget) -{ - r32 CurrentRowWidth = Rect2Width(Widget->Bounds); - r32 ColumnWidth = CurrentRowWidth / Widget->ColumnsCount; - for (u32 i = 0; i < Widget->ColumnsCount; i++) - { - ui_column* Column = Widget->Columns + i; - Column->XMin = Widget->Bounds.Min.x + (ColumnWidth * i); - Column->XMax = Column->XMin + ColumnWidth; - } -} - -internal ui_widget* -ui_CreateLayoutWidget(ui_interface* Interface, rect2 Bounds, gs_string Name, ui_layout_direction FillDir = LayoutDirection_Inherit) -{ - ui_widget* Result = ui_CreateWidget(Interface, Name); - //ui_WidgetSetFlag(Result, UIWidgetFlag_DrawOutline); - - Result->Bounds = Bounds; - Result->Margin = Interface->Style.Margin; - Result->RowHeight = Interface->Style.RowHeight; - - // Single Column Layout - ui_WidgetCreateColumns(Result, 1, Interface); - ui_WidgetInitUniformColumns(Result); - - if (FillDir == LayoutDirection_Inherit && Result->Parent != 0) - { - Result->FillDirection = Result->Parent->FillDirection; - } - else - { - Result->FillDirection = FillDir; - } - - switch(Result->FillDirection) - { - case LayoutDirection_BottomUp: - { - Result->RowYAt = Bounds.Min.y; - }break; - - case LayoutDirection_TopDown: - { - Result->RowYAt = Bounds.Max.y - Result->RowHeight; - }break; - - InvalidDefaultCase; - } - - return Result; -} - -static ui_widget* -ui_PushOverlayLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) -{ - ui_widget* Result = ui_CreateLayoutWidget(Interface, Bounds, Name, FillDir); - SLLPushOrInit(Interface->DrawOrderRoot, Interface->DrawOrderHead, Result); - Interface->ActiveLayout = Result; - return Result; -} - -static gs_string -ui_PushLayoutCategoryName(ui_interface* Interface, gs_string Category, u32 Value) -{ - gs_string Result = PushStringF(Interface->PerFrameMemory, - Category.Length + 25, - "%S%d", - Category.ConstString, - Value); - return Result; -} - -static ui_widget* -ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) -{ - ui_widget* Result = ui_CreateLayoutWidget(Interface, Bounds, Name, FillDir); - - if (Interface->DrawOrderRoot) - { - SLLPushOrInit(Interface->ActiveLayout->ChildrenRoot, Interface->ActiveLayout->ChildrenHead, Result); - Interface->ActiveLayout->ChildCount++; - } - else - { - SLLPushOrInit(Interface->DrawOrderRoot, Interface->DrawOrderHead, Result); - } - - Interface->ActiveLayout = Result; - return Result; -} -static ui_widget* -ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Category, u32 Value) -{ - gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Value); - return ui_PushLayout(Interface, Bounds, FillDir, Name); -} - -static ui_widget* -ui_PushLayout(ui_interface* Interface, gs_string Name, bool Inset = true) -{ - rect2 Bounds = {}; - ui_layout_direction Direction = LayoutDirection_TopDown; - if (Interface->ActiveLayout) - { - Bounds = ui_ReserveBounds(Interface, Interface->ActiveLayout, Inset); - Direction = Interface->ActiveLayout->FillDirection; - } - else - { - Bounds.Min.x = Interface->WindowBounds.Min.x; - Bounds.Min.y = Interface->WindowBounds.Max.y; - Bounds.Max.x = Interface->WindowBounds.Max.x; - Bounds.Max.y = Interface->WindowBounds.Max.y; - - if (Inset) - { - Bounds.Min.x += Interface->Style.Margin.x; - Bounds.Max.x -= Interface->Style.Margin.x; - } - - Direction = LayoutDirection_TopDown; - } - return ui_PushLayout(Interface, Bounds, Direction, Name); -} - -internal void -ui_ExpandToFitChildren(ui_widget* Parent) -{ - if (!ui_WidgetIsFlagSet(*Parent, UIWidgetFlag_ExpandsToFitChildren)) { return; } - - v2 Extents = { Parent->Bounds.Max.y, Parent->Bounds.Min.y }; - for (ui_widget* Child = Parent->ChildrenRoot; Child != 0; Child = Child->Next) - { - Extents.x = Min(Extents.x, Child->Bounds.Min.y); - Extents.y = Max(Extents.y, Child->Bounds.Max.y); - } - - switch(Parent->FillDirection) - { - case LayoutDirection_BottomUp: - { - Parent->Bounds.Max.y = Max(Extents.y + Parent->Margin.y, Parent->Bounds.Max.y); - }break; - - case LayoutDirection_TopDown: - { - Parent->Bounds.Min.y = Min(Extents.x - Parent->Margin.y, Parent->Bounds.Min.y); - }break; - - InvalidDefaultCase; - } -} - -static void -ui_PopLayout(ui_interface* Interface, gs_string LayoutName) -{ - Assert(Interface->ActiveLayout != 0); - - ui_widget* Layout = Interface->ActiveLayout; - - // NOTE(pjs): If this isn't true then a layout was opened without being closed - // Go check for ui_PushLayout, ui_BeginDropdown, ui_BeginRow, etc that don't have - // a corresponding ui_Pop/ui_End* - // - // We use StringsEqualUpToLength here becuase its possible that - // the current layout used the Category + Identifier method - // for generating Layout->String. And if Identifier was a string - // that was edited within the scope of this layout, then - // Layout->String and LayoutName will no longer match. - // - // This is a compromise that will at least let us know if - // we aren't popping all our layouts correctly. - Assert(StringsEqualUpToLength(Layout->String, LayoutName, LayoutName.Length)); - - ui_ExpandToFitChildren(Layout); - - Interface->ActiveLayout = Interface->ActiveLayout->Parent; - - // NOTE(pjs): This indicates that the parent layout should - // expand to fit the layout that we just popped - if (Interface->ActiveLayout != 0 && - Interface->ActiveLayout->ChildrenHead == Layout) - { - ui_CommitBounds(Interface->ActiveLayout, Layout->Bounds); - } -} -static void -ui_PopLayout(ui_interface* Interface, gs_string Category, u32 Value) -{ - gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Value); - ui_PopLayout(Interface, Name); -} - -static ui_widget* -ui_BeginRow(ui_interface* Interface, u32 ColumnsMax) -{ - ui_widget* Layout = ui_PushLayout(Interface, MakeString("Row"), false); - ui_WidgetCreateColumns(Layout, ColumnsMax, Interface); - ui_WidgetInitUniformColumns(Layout); - return Layout; -} - -enum ui_column_size_rule -{ - UIColumnSize_Fixed, - UIColumnSize_Percent, - UIColumnSize_Fill, - UIColumnSize_MaxWidth, -}; - -struct ui_column_spec -{ - ui_column_size_rule Rule; - union - { - r32 Width; - r32 Percent; - }; -}; - -static ui_widget* -ui_BeginRow(ui_interface* Interface, u32 ColumnsMax, ui_column_spec* ColumnRules) -{ - ui_widget* Layout = ui_PushLayout(Interface, MakeString("Row"), false); - ui_WidgetCreateColumns(Layout, ColumnsMax, Interface); - - // First Pass, determine widths of each column, and how much space is left to be divided by the fill columns - // If a size is specified, it is stored in Column->XMax - r32 RowWidth = Rect2Width(Layout->Bounds); - r32 RemainingSpace = RowWidth; - u32 FillColumnsCount = 0; - for (u32 i = 0; i < Layout->ColumnsCount; i++) - { - ui_column_spec Spec = ColumnRules[i]; - ui_column* Column = Layout->Columns + i; - - switch (Spec.Rule) - { - case UIColumnSize_Fixed: - { - Column->XMax = Spec.Width; - RemainingSpace -= Column->XMax; - }break; - - case UIColumnSize_Percent: - { - Column->XMax = Spec.Percent * RowWidth; - RemainingSpace -= Column->XMax; - }break; - - case UIColumnSize_Fill: - { - FillColumnsCount += 1; - }break; - - case UIColumnSize_MaxWidth: - { - if (RemainingSpace >= Spec.Width) - { - Column->XMax = Spec.Width; - } - else - { - Column->XMax = RemainingSpace; - } - RemainingSpace -= Column->XMax; - }break; - - InvalidDefaultCase; - } - } - - r32 FillColumnWidth = RemainingSpace / FillColumnsCount; - - // Second Pass, specify the actual XMin and XMax of each column - r32 ColumnStartX = Layout->Bounds.Min.x; - for (u32 i = 0; i < Layout->ColumnsCount; i++) - { - ui_column_spec Spec = ColumnRules[i]; - ui_column* Column = Layout->Columns + i; - - r32 ColumnWidth = 0; - switch (Spec.Rule) - { - case UIColumnSize_Fixed: - case UIColumnSize_Percent: - case UIColumnSize_MaxWidth: - { - ColumnWidth = Column->XMax; - }break; - - case UIColumnSize_Fill: - { - ColumnWidth = FillColumnWidth; - }break; - } - - Column->XMin = ColumnStartX ; - Column->XMax = Column->XMin + Max(0, ColumnWidth); - ColumnStartX = Column->XMax; - } - - return Layout; -} - -static void -ui_EndRow(ui_interface* Interface) -{ - ui_PopLayout(Interface, MakeString("Row")); -} - -static rect2 -ui_LayoutRemaining(ui_widget Layout) -{ - rect2 Result = Layout.Bounds; - Result.Max.y = Layout.RowYAt; - return Result; -} - -// Widgets - -internal ui_eval_result -ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget, rect2 Bounds) -{ - ui_eval_result Result = {}; - - Widget->Bounds = Bounds; - SLLPushOrInit(Interface->ActiveLayout->ChildrenRoot, Interface->ActiveLayout->ChildrenHead, Widget); - Interface->ActiveLayout->ChildCount += 1; - ui_CommitBounds(Widget->Parent, Widget->Bounds); - - if (PointIsInRect(Widget->Parent->Bounds, Interface->Mouse.Pos) && - PointIsInRect(Widget->Bounds, Interface->Mouse.Pos)) - { - if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState)) - { - if (ui_WidgetIdsEqual(Interface->HotWidget, Widget->Id)) - { - Result.Clicked = true; - Interface->ActiveWidget = Widget->Id; - - if (ui_WidgetIsFlagSet(*Widget, UIWidgetFlag_Typable)) - { - Interface->CursorPosition = Widget->String.Length; - } - } - } - - if (Interface->HotWidget.ZIndex == 0 || - Interface->HotWidget.ZIndex <= Widget->Id.ZIndex) - { - Interface->HotWidget = Widget->Id; - Interface->HotWidgetFramesSinceUpdate = 0; - } - } - else - { - if (ui_WidgetIdsEqual(Interface->ActiveWidget, Widget->Id) && - MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState)) - { - Interface->ActiveWidget = {}; - } - } - - if (ui_WidgetIdsEqual(Interface->ActiveWidget, Widget->Id)) - { - // click & drag - if (MouseButtonHeldDown(Interface->Mouse.LeftButtonState)) - { - Result.Held = true; - Result.DragDelta = Interface->Mouse.Pos - Interface->Mouse.DownPos; - } - - if (ui_WidgetIsFlagSet(*Widget, UIWidgetFlag_Typable) && - Interface->TempInputString.Length > 0) - { - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - - Interface->CursorPosition = Clamp(0, Interface->CursorPosition, State->EditString.Length); - for (u32 i = 0; i < Interface->TempInputString.Length; i++) - { - if (Interface->TempInputString.Str[i] == '\b') - { - if (Interface->CursorPosition > 0) - { - State->EditString.Length -= 1; - } - } - else - { - OutChar(&State->EditString, Interface->TempInputString.Str[i]); - Interface->CursorPosition += 1; - } - } - } - } - - Assert(Widget->Parent != 0); - return Result; -} - -internal ui_eval_result -ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget) -{ - ui_widget* Layout = Interface->ActiveLayout; - rect2 Bounds = ui_ReserveBounds(Interface, Layout, true); - return ui_EvaluateWidget(Interface, Widget, Bounds); -} - -// -// Drawing Functions -// - -static r32 -ui_GetTextLineHeight(ui_interface Interface) -{ - r32 Result = Interface.Style.Font->PixelHeight + (2 * Interface.Style.Margin.y); - return Result; -} - -static void -ui_FillRect(ui_interface* Interface, rect2 Bounds, v4 Color) -{ - PushRenderQuad2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Color); -} - -static void -ui_OutlineRect(ui_interface* Interface, rect2 Bounds, r32 Thickness, v4 Color) -{ - PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color); -} - -internal void -ui_Label(ui_interface* Interface, gs_string String, rect2 Bounds, gs_string_alignment Alignment = Align_Left) -{ - DEBUG_TRACK_FUNCTION; - ui_widget* Widget = ui_CreateWidget(Interface, String); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_EvaluateWidget(Interface, Widget, Bounds); -} - -internal void -ui_Label(ui_interface* Interface, gs_string String, gs_string_alignment Alignment = Align_Left) -{ - DEBUG_TRACK_FUNCTION; - ui_widget* Widget = ui_CreateWidget(Interface, String); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_EvaluateWidget(Interface, Widget); -} - -internal void -ui_TextEntrySetFlags(ui_widget* Widget, gs_string EditString) -{ - Widget->String = EditString; - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Selectable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Typable); -} - -internal bool -ui_TextEntry(ui_interface* Interface, gs_string Identifier, gs_string* Value) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Identifier); - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - if (!State) - { - State = ui_CreateRetainedState(Interface, Widget); - } - PrintF(&State->EditString, "%S", *Value); - - ui_TextEntrySetFlags(Widget, State->EditString); - - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - bool StringEdited = !StringsEqual(*Value, State->EditString); - PrintF(Value, "%S", State->EditString); - - return StringEdited; -} - -internal u64 -ui_TextEntryU64(ui_interface* Interface, gs_string String, u64 CurrentValue) -{ - ui_widget* Widget = ui_CreateWidget(Interface, String); - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - if (!State) - { - State = ui_CreateRetainedState(Interface, Widget); - PrintF(&State->EditString, "%u", CurrentValue); - } - ui_TextEntrySetFlags(Widget, State->EditString); - - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - parse_uint_result ParseResult = ValidateAndParseUInt(State->EditString.ConstString); - u64 ValueResult = CurrentValue; - if (ParseResult.Success) - { - ValueResult = ParseResult.Value; - } - return ValueResult; -} - -internal r64 -ui_TextEntryR64(ui_interface* Interface, gs_string String, r64 CurrentValue) -{ - ui_widget* Widget = ui_CreateWidget(Interface, String); - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - if (!State) - { - State = ui_CreateRetainedState(Interface, Widget); - PrintF(&State->EditString, "%f", CurrentValue); - } - ui_TextEntrySetFlags(Widget, State->EditString); - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - parse_float_result ParseResult = ValidateAndParseFloat(State->EditString.ConstString); - r64 ValueResult = CurrentValue; - if (ParseResult.Success) - { - ValueResult = ParseResult.Value; - } - return ValueResult; -} - -internal ui_widget* -ui_CreateButtonWidget(ui_interface* Interface, gs_string Text) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); - return Widget; -} - -internal b32 -ui_Button(ui_interface* Interface, gs_string Text) -{ - ui_widget* Widget = ui_CreateButtonWidget(Interface, Text); - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - return Result.Clicked; -} - -internal b32 -ui_Button(ui_interface* Interface, gs_string Text, rect2 Bounds) -{ - ui_widget* Widget = ui_CreateButtonWidget(Interface, Text); - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget, Bounds); - return Result.Clicked; -} - -struct list_item_colors -{ - v4 Hover; - v4 Selected; - v4 BGColor; -}; - -inline v4 -ui_GetListItemBGColor(interface_config Style, u32 ElementIndex) -{ - v4 Result = Style.ListBGColors[ElementIndex % LIST_BG_COLORS_COUNT]; - return Result; -} - -static list_item_colors -ui_GetListItemColors(ui_interface* Interface, u32 ListItemIndex) -{ - list_item_colors Result = {}; - Result.Hover = Interface->Style.ListBGHover; - Result.Selected = Interface->Style.ListBGSelected; - Result.BGColor = ui_GetListItemBGColor(Interface->Style, ListItemIndex); - return Result; -} - -static b32 -ui_ListButton(ui_interface* Interface, gs_string Text, rect2 Bounds, u32 ListItemIndex) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - // TODO(pjs): Reimplement alternating color backgrounds - Widget->Bounds = Bounds; - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - return Result.Clicked; -} - -static b32 -ui_LayoutListButton(ui_interface* Interface, gs_string Text, u32 ListItemIndex) -{ - // TODO(pjs): Reimplement alternating colors - return ui_Button(Interface, Text); -} - -internal bool -ui_EvaluateDropdown(ui_interface* Interface, ui_widget* Widget, ui_eval_result EvalResult) -{ - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); - if (!State) - { - State = ui_CreateRetainedState(Interface, Widget); - } - - if (EvalResult.Clicked) - { - State->Value = !State->Value; - } - - if (State->Value) - { - ui_widget ParentLayout = *Interface->ActiveLayout; - - r32 SpaceAbove = Interface->WindowBounds.Max.y - Widget->Bounds.Max.y; - r32 SpaceBelow = Widget->Bounds.Min.y - Interface->WindowBounds.Min.y; - ui_layout_direction Direction = LayoutDirection_TopDown; - rect2 MenuBounds = {}; - - if (SpaceAbove > SpaceBelow) - { - r32 ParentLayoutMaxY = ParentLayout.Bounds.Max.y; - Direction = LayoutDirection_BottomUp; - MenuBounds = rect2{ - v2{ Widget->Bounds.Min.x - ParentLayout.Margin.x, Widget->Bounds.Max.y }, - v2{ Widget->Bounds.Max.x + ParentLayout.Margin.x, ParentLayoutMaxY } - }; - } - else - { - r32 ParentLayoutMinY = ParentLayout.Bounds.Min.y; - Direction = LayoutDirection_TopDown; - MenuBounds = rect2{ - v2{ Widget->Bounds.Min.x - ParentLayout.Margin.x, ParentLayoutMinY }, - v2{ Widget->Bounds.Max.x + ParentLayout.Margin.x, Widget->Bounds.Min.y } - }; - } - - ui_widget* Layout = ui_PushOverlayLayout(Interface, MenuBounds, Direction, MakeString("DropdownLayout")); - Layout->Margin.y = 0; - Layout->WidgetReference = Widget->Id; - ui_WidgetClearFlag(Layout, UIWidgetFlag_DrawOutline); - ui_WidgetSetChildrenPopover(Layout); - } - - return State->Value; -} - -internal bool -ui_BeginDropdown(ui_interface* Interface, gs_string Text, rect2 Bounds) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); - - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget, Bounds); - return ui_EvaluateDropdown(Interface, Widget, Result); -} - -internal bool -ui_BeginDropdown(ui_interface* Interface, gs_string Text) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - return ui_EvaluateDropdown(Interface, Widget, Result); -} - -internal void -ui_EndDropdown(ui_interface* Interface) -{ - gs_string LayoutName = MakeString("DropdownLayout"); - ui_widget* Layout = Interface->ActiveLayout; - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Layout->WidgetReference); - if (State) - { - bool IsOpen = State->Value; - ui_widget* Widget = Interface->ActiveLayout; - bool IsStillHot = StringsEqualUpToLength(Widget->String, LayoutName, LayoutName.Length); - if (IsOpen && IsStillHot) - { - ui_PopLayout(Interface, LayoutName); - } else if (IsOpen && !IsStillHot) - { - State->Value = false; - } - } -} - -internal r32 -ui_EvaluateRangeSlider(ui_interface* Interface, ui_widget* Widget, ui_eval_result EvalResult, r32 Value, r32 MinValue, r32 MaxValue) -{ - r32 NewValue = Value; - ui_widget_retained_state* State = ui_GetOrCreateRetainedState(Interface, Widget); - - if (EvalResult.Clicked) - { - State->InitialValueR32 = Value; - } - - if (EvalResult.Held) - { - r32 Percent = (Interface->Mouse.Pos.x - Widget->Bounds.Min.x) / Rect2Width(Widget->Bounds); - NewValue = LerpR32(Percent, MinValue, MaxValue); - } - - NewValue = Clamp(MinValue, NewValue, MaxValue); - Widget->FillPercent = RemapR32(NewValue, MinValue, MaxValue, 0, 1); - return NewValue; -} - -internal ui_widget* -ui_CreateRangeSliderWidget(ui_interface* Interface, gs_string Text, r32 Value) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawHorizontalFill); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); - Widget->String = PushStringF(Interface->PerFrameMemory, 128, "%f", Value); - InterfaceAssert(Interface->PerFrameMemory); - return Widget; -} - -internal r32 -ui_RangeSlider(ui_interface* Interface, gs_string Text, r32 Value, r32 ValueMin, r32 ValueMax) -{ - ui_widget* Widget = ui_CreateRangeSliderWidget(Interface, Text, Value); - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); - return ui_EvaluateRangeSlider(Interface, Widget, Result, Value, ValueMin, ValueMax); - -} - -internal r32 -ui_RangeSlider(ui_interface* Interface, gs_string Text, rect2 Bounds, r32 Value, r32 ValueMin, r32 ValueMax) -{ - ui_widget* Widget = ui_CreateRangeSliderWidget(Interface, Text, Value); - ui_eval_result Result = ui_EvaluateWidget(Interface, Widget, Bounds); - return ui_EvaluateRangeSlider(Interface, Widget, Result, Value, ValueMin, ValueMax); -} - -internal bool -ui_Toggle(ui_interface* Interface, gs_string Text, bool Value) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawHorizontalFill); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); - ui_eval_result Eval = ui_EvaluateWidget(Interface, Widget); - - bool Result = Eval.Clicked ? !Value : Value; - Widget->FillPercent = Result ? 1.0f : 0.0f; - return Result; -} - -internal bool -ui_ToggleText(ui_interface* Interface, gs_string Text, bool Value) -{ - ui_widget* Widget = ui_CreateWidget(Interface, Text); - ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawHorizontalFill); - ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); - ui_eval_result Eval = ui_EvaluateWidget(Interface, Widget); - - bool Result = Eval.Clicked ? !Value : Value; - Widget->FillPercent = Result ? 1.0f : 0.0f; - return Result; -} - -internal void -ui_BeginList(ui_interface* Interface, gs_string Text, u32 ViewportRows, u32 ElementCount) -{ - if (ElementCount < ViewportRows) - { - ViewportRows = ElementCount; - } - - ui_column_spec ColumnRules[] = { - { UIColumnSize_Fixed, 32 }, - { UIColumnSize_Fill, 0 }, - }; - ui_widget* Layout = ui_BeginRow(Interface, 2, ColumnRules); - ui_WidgetClearFlag(Layout, UIWidgetFlag_ExpandsToFitChildren); - - ui_widget_retained_state* State = ui_GetRetainedState(Interface, Layout->Id); - if (!State) - { - State = ui_CreateRetainedState(Interface, Layout); - State->InitialValueR32 = 1.0f; - } - - r32 LayoutHeight = Layout->RowHeight * ViewportRows; - switch (Layout->Parent->FillDirection) - { - case LayoutDirection_TopDown: - { - Layout->Bounds.Min.y = Layout->Bounds.Max.y - LayoutHeight; - }break; - - case LayoutDirection_BottomUp: - { - Layout->Bounds.Max.y = Layout->Bounds.Min.y + LayoutHeight; - }break; - - InvalidDefaultCase; - } - - // Create the scroll bar - // - // TODO(pjs): Maybe make this a vertical slider widget? - - ui_widget* SliderRegion = ui_CreateWidget(Interface, MakeString("Slider")); - ui_WidgetSetFlag(SliderRegion, UIWidgetFlag_DrawOutline); - ui_WidgetSetFlag(SliderRegion, UIWidgetFlag_DrawVerticalFill); - ui_WidgetSetFlag(SliderRegion, UIWidgetFlag_DrawFillAsHandle); - - ui_WidgetSetFlag(SliderRegion, UIWidgetFlag_Clickable); - - rect2 SliderBounds = ui_ReserveBounds(Interface, Layout, true); - SliderBounds.Min.y = Layout->Bounds.Min.y + Layout->Margin.y; - SliderBounds.Max.y = Layout->Bounds.Max.y - Layout->Margin.y; - - ui_eval_result SliderEval = ui_EvaluateWidget(Interface, SliderRegion, SliderBounds); - if (SliderEval.Clicked || SliderEval.Held) - { - r32 Percent = (Interface->Mouse.Pos.y - SliderRegion->Bounds.Min.y) / Rect2Height(SliderRegion->Bounds); - State->InitialValueR32 = Clamp01(Percent); - } - SliderRegion->FillPercent = State->InitialValueR32; - - // Create the viewport that offsets list contents (and at render time determines what is visible) - // - ui_widget* ViewportLayout = ui_PushLayout(Interface, MakeString("Contents")); - ui_WidgetSetFlag(ViewportLayout, UIWidgetFlag_DrawOutline); - ui_WidgetClearFlag(ViewportLayout, UIWidgetFlag_ExpandsToFitChildren); - ViewportLayout->FillDirection = LayoutDirection_TopDown; - - ViewportLayout->Bounds.Min.y = SliderBounds.Min.y; - ViewportLayout->Bounds.Max.y = SliderBounds.Max.y; - - s32 ScrollableElements = Max(0, ElementCount - ViewportRows); - ui_widget_retained_state* ViewportState = ui_GetOrCreateRetainedState(Interface, ViewportLayout); - ViewportState->ChildrenDrawOffset.x = 0; - r32 BaseOffset = 0; - r32 ScrollPct = 1.0 - State->InitialValueR32; - r32 RowsOffset = ScrollPct * ScrollableElements; - r32 ScrollOffset = (ViewportLayout->RowHeight - (Interface->Style.Margin.y)) * RowsOffset; - ViewportState->ChildrenDrawOffset.y = BaseOffset + ScrollOffset; -} - -internal void -ui_EndList(ui_interface* Interface) -{ - // Pop the Viewport Layout - ui_PopLayout(Interface, MakeString("Contents")); - // Pop the actual list layout - ui_EndRow(Interface); -} - -internal void -ui_BeginMousePopup(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Text) -{ - rect2 FollowMouseBounds = Rect2Translate(Bounds, Interface->Mouse.Pos); - ui_widget* Layout = ui_PushOverlayLayout(Interface, FollowMouseBounds, FillDir, MakeString("MousePopup")); - ui_WidgetSetFlag(Layout, UIWidgetFlag_DrawBackground); -} - -internal void -ui_EndMousePopup(ui_interface* Interface) -{ - ui_PopLayout(Interface, MakeString("MousePopup")); -} - -// -internal void -ui_BeginLabelRow(ui_interface* Interface, gs_string Label, u32 Count = 2) -{ - ui_BeginRow(Interface, Count); - ui_Label(Interface, Label); -} - -internal bool -ui_LabeledToggle(ui_interface* Interface, gs_string Label, bool Value) -{ - ui_BeginLabelRow(Interface, Label); - bool Result = ui_Toggle(Interface, Label, Value); - ui_EndRow(Interface); - return Result; -} - -internal r32 -ui_LabeledRangeSlider(ui_interface* Interface, gs_string Label, r32 Value, r32 ValueMin, r32 ValueMax) -{ - ui_BeginLabelRow(Interface, Label); - r32 Result = ui_RangeSlider(Interface, Label, Value, ValueMin, ValueMax); - ui_EndRow(Interface); - return Result; -} - -internal void -ui_LabeledTextEntry(ui_interface* Interface, gs_string Label, gs_string* Value) -{ - ui_BeginLabelRow(Interface, Label); - ui_TextEntry(Interface, Label, Value); - ui_EndRow(Interface); -} - - -internal u64 -ui_LabeledTextEntryU64(ui_interface* Interface, gs_string Label, u32 Value) -{ - ui_BeginLabelRow(Interface, Label); - u64 Result = ui_TextEntryU64(Interface, Label, Value); - ui_EndRow(Interface); - return Result; -} - -internal bool -ui_BeginLabeledDropdown(ui_interface* Interface, gs_string Label, gs_string DropdownValue) -{ - ui_BeginLabelRow(Interface, Label); - return ui_BeginDropdown(Interface, DropdownValue); -} - -internal void -ui_EndLabeledDropdown(ui_interface* Interface) -{ - ui_EndDropdown(Interface); - ui_EndRow(Interface); -} - -internal ui_interface -ui_InterfaceCreate(context Context, interface_config Style, gs_memory_arena* Permanent) -{ - ui_interface Result = {0}; - Result.Style = Style; - - gs_file FontFile = ReadEntireFile(Context.ThreadContext.FileHandler, ConstString("data/Anonymous Pro.ttf")); - Result.Style.Font = PushStruct(Permanent, bitmap_font); - *Result.Style.Font = TextFont_Create(FontFile, 512, Style.FontSize, Context, Permanent); - - Result.Style.RowHeight = ui_GetTextLineHeight(Result) + (2 * Result.Style.Margin.y); - - Result.WidgetsCountMax = 4096; - Result.Widgets = PushArray(Permanent, ui_widget, Result.WidgetsCountMax); - Result.PerFrameMemory = PushStruct(Permanent, gs_memory_arena); - *Result.PerFrameMemory = MemoryArenaCreate(KB(32), Bytes(8), Context.ThreadContext.Allocator, 0, 0, "Interface Per Frame Memory Arena"); - InterfaceAssert(Result.PerFrameMemory); - - Result.Permanent = Permanent; - - return Result; -} - -#define INTERFACE_H -#endif // INTERFACE_H \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_animation_timeline.h b/src/app/editor/panels/foldhaus_panel_animation_timeline.h deleted file mode 100644 index 822cf58..0000000 --- a/src/app/editor/panels/foldhaus_panel_animation_timeline.h +++ /dev/null @@ -1,1078 +0,0 @@ -// -// File: foldhaus_panel_animation_timeline.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H - -// Colors -global v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f}; - -// -struct animation_timeline_state -{ - frame_range VisibleRange; - handle SelectedBlockHandle; - animation_handle EditingAnimationHandle; - s32 SelectedAnimationLayer; - - animation_handle NextActiveAnim; -}; - -internal void -AnimationTimeline_SelectLayer(animation_timeline_state* TLState, s32 Layer) -{ - TLState->SelectedAnimationLayer = Layer; -} - -inline u32 -GetFrameFromPointInAnimationPanel(v2 Point, rect2 PanelBounds, frame_range VisibleRange) -{ - r32 HorizontalPercentOfBounds = (Point.x - PanelBounds.Min.x) / (PanelBounds.Max.x - PanelBounds.Min.x); - u32 VisibleFramesCount = GetFrameCount(VisibleRange); - u32 TimeAtPoint = (u32)(HorizontalPercentOfBounds * VisibleFramesCount) + VisibleRange.Min; - return TimeAtPoint; -} - -inline s32 -GetXPositionFromFrameInAnimationPanel (u32 Frame, rect2 PanelBounds, frame_range VisibleRange) -{ - r32 PercentOfTimeline = (r32)(Frame - VisibleRange.Min) / (r32)GetFrameCount(VisibleRange); - s32 XPositionAtFrame = (PercentOfTimeline * Rect2Width(PanelBounds)) + PanelBounds.Min.x; - return XPositionAtFrame; -} - -FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand) -{ - animation_timeline_state* PanelState = Panel_GetStateStruct(Panel, animation_timeline_state); - - handle SelectedBlockHandle = PanelState->SelectedBlockHandle; - animation* ActiveAnim = AnimationArray_GetSafe(State->AnimationSystem.Animations, PanelState->EditingAnimationHandle); - - if(SelectedBlockHandle.Index < ActiveAnim->Blocks_.Count && - ActiveAnim->Blocks_.Generations[SelectedBlockHandle.Index] == SelectedBlockHandle.Generation) - { - Animation_RemoveBlock(ActiveAnim, PanelState->SelectedBlockHandle); - PanelState->SelectedBlockHandle = {0}; - // TODO(pjs): Introduce an animation_block_selection in this file - // it should have a handle to the animation, block, and a HasSelection flag - // as it is now, you kind of always have the first block selected - } -} - -// -// Drag Time Marker -// - -OPERATION_STATE_DEF(drag_time_marker_operation_state) -{ - rect2 TimelineBounds; - s32 StartFrame; - s32 EndFrame; -}; - -OPERATION_RENDER_PROC(UpdateDragTimeMarker) -{ - drag_time_marker_operation_state* OpState = (drag_time_marker_operation_state*)Operation.OpStateMemory; - frame_range Range = { OpState->StartFrame, OpState->EndFrame }; - u32 FrameAtMouseX = GetFrameFromPointInAnimationPanel(Mouse.Pos, OpState->TimelineBounds, Range); - State->AnimationSystem.CurrentFrame = FrameAtMouseX; -} - -FOLDHAUS_INPUT_COMMAND_PROC(EndDragTimeMarker) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command DragTimeMarkerCommands [] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDragTimeMarker }, -}; - -internal void -StartDragTimeMarker(rect2 TimelineBounds, frame_range VisibleFrames, app_state* State) -{ - operation_mode* DragTimeMarkerMode = ActivateOperationModeWithCommands(&State->Modes, DragTimeMarkerCommands, UpdateDragTimeMarker); - - drag_time_marker_operation_state* OpState = CreateOperationState(DragTimeMarkerMode, - &State->Modes, - drag_time_marker_operation_state); - OpState->StartFrame = VisibleFrames.Min; - OpState->EndFrame = VisibleFrames.Max; - OpState->TimelineBounds = TimelineBounds; -} - -// -------------------- - -// -// Drag Animation Clip -// - -#define CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE 10 - -OPERATION_STATE_DEF(drag_animation_block_state) -{ - rect2 TimelineBounds; - animation_handle EditingAnimationHandle; - handle BlockHandle; - frame_range VisibleRange; - frame_range ClipRange; -}; - -internal u32 -AttemptToSnapPosition(u32 SnappingFrame, u32 SnapToFrame) -{ - u32 Result = SnappingFrame; - s32 SnapDistance = 5; - if (Abs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance) - { - Result = SnapToFrame; - } - return Result; -} - -OPERATION_RENDER_PROC(UpdateDragAnimationBlock) -{ - drag_animation_block_state* OpState = (drag_animation_block_state*)Operation.OpStateMemory; - - animation_array Animations = State->AnimationSystem.Animations; - animation_handle Handle = OpState->EditingAnimationHandle; - animation* ActiveAnim = AnimationArray_GetSafe(Animations, Handle); - - r32 ClipInitialStartFrameXPercent = FrameToPercentRange(OpState->ClipRange.Min, OpState->VisibleRange); - u32 ClipInitialStartFrameXPosition = LerpR32(ClipInitialStartFrameXPercent, - OpState->TimelineBounds.Min.x, - OpState->TimelineBounds.Max.x); - r32 ClipInitialEndFrameXPercent = FrameToPercentRange(OpState->ClipRange.Max, OpState->VisibleRange); - u32 ClipInitialEndFrameXPosition = LerpR32(ClipInitialEndFrameXPercent, - OpState->TimelineBounds.Min.x, - OpState->TimelineBounds.Max.x); - - u32 FrameAtMouseDownX = GetFrameFromPointInAnimationPanel(Mouse.DownPos, OpState->TimelineBounds, OpState->VisibleRange); - - u32 FrameAtMouseX = GetFrameFromPointInAnimationPanel(Mouse.Pos, OpState->TimelineBounds, OpState->VisibleRange); - s32 FrameOffset = (s32)FrameAtMouseX - (s32)FrameAtMouseDownX; - - animation_block* AnimationBlock = Animation_GetBlockFromHandle(ActiveAnim, OpState->BlockHandle); - if (!AnimationBlock) - { - EndCurrentOperationMode(State); - return; - } - - if (Abs(Mouse.DownPos.x - ClipInitialStartFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE) - { - s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset; - if (FrameOffset < 0) - { - for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) - { - animation_block OtherBlock = ActiveAnim->Blocks_.Values[i]; - NewStartFrame = AttemptToSnapPosition(NewStartFrame, OtherBlock.Range.Max); - } - } - else - { - if (NewStartFrame >= AnimationBlock->Range.Max) - { - NewStartFrame = AnimationBlock->Range.Max - 1; - } - } - AnimationBlock->Range.Min = NewStartFrame; - } - else if (Abs(Mouse.DownPos.x - ClipInitialEndFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE) - { - r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset; - if (FrameOffset > 0) - { - for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) - { - animation_block OtherBlock = ActiveAnim->Blocks_.Values[i]; - NewEndFrame = AttemptToSnapPosition(NewEndFrame, OtherBlock.Range.Min); - } - } - else - { - if(NewEndFrame <= AnimationBlock->Range.Min) - { - NewEndFrame = AnimationBlock->Range.Min + 1; - } - } - AnimationBlock->Range.Max = NewEndFrame; - } - else - { - u32 NewStartFrame = OpState->ClipRange.Min + FrameOffset; - u32 NewEndFrame = OpState->ClipRange.Max + FrameOffset; - for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) - { - animation_block OtherBlock = ActiveAnim->Blocks_.Values[i];; - - u32 SnapFramesAmount = 0; - if (FrameOffset > 0) - { - u32 FinalEndFrame = AttemptToSnapPosition(NewEndFrame, OtherBlock.Range.Min); - SnapFramesAmount = FinalEndFrame - NewEndFrame; - } - else if (FrameOffset < 0) - { - u32 FinalStartFrame = AttemptToSnapPosition(NewStartFrame, OtherBlock.Range.Max); - SnapFramesAmount = FinalStartFrame - NewStartFrame; - } - NewEndFrame += SnapFramesAmount; - NewStartFrame += SnapFramesAmount; - } - AnimationBlock->Range.Min = NewStartFrame; - AnimationBlock->Range.Max = NewEndFrame; - } - - s32 PlayableStartFrame = ActiveAnim->PlayableRange.Min; - s32 PlayableEndFrame = ActiveAnim->PlayableRange.Max; - AnimationBlock->Range.Min = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame); - AnimationBlock->Range.Max = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame); -} - -input_command DragAnimationBlockCommands [] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, 0 }, -}; - -internal void -SelectAndBeginDragAnimationBlock(animation_timeline_state* TimelineState, handle BlockHandle, frame_range VisibleRange, rect2 TimelineBounds, app_state* State) -{ - TimelineState->SelectedBlockHandle = BlockHandle; - - animation_handle Handle = TimelineState->EditingAnimationHandle; - animation_array Animations = State->AnimationSystem.Animations; - animation* ActiveAnim = AnimationArray_GetSafe(Animations, Handle); - - operation_mode* DragAnimationBlockMode = ActivateOperationModeWithCommands(&State->Modes, DragAnimationBlockCommands, UpdateDragAnimationBlock); - - animation_block* SelectedBlock = Animation_GetBlockFromHandle(ActiveAnim, BlockHandle); - drag_animation_block_state* OpState = CreateOperationState(DragAnimationBlockMode, - &State->Modes, - drag_animation_block_state); - OpState->TimelineBounds = TimelineBounds; - OpState->EditingAnimationHandle = Handle; - OpState->BlockHandle = BlockHandle; - OpState->VisibleRange = VisibleRange; - OpState->ClipRange = SelectedBlock->Range; -} -// ------------------- - -internal void -AnimationTimeline_AddAnimationBlockCommand(animation_timeline_state* TimelineState, app_state* State, context Context) -{ - animation_handle Handle = TimelineState->EditingAnimationHandle; - animation_array Animations = State->AnimationSystem.Animations; - animation* ActiveAnim = AnimationArray_GetSafe(Animations, Handle); - - s32 StartFrame = State->AnimationSystem.CurrentFrame; - s32 EndFrame = StartFrame + SecondsToFrames(3, State->AnimationSystem); - EndFrame = Clamp(0, EndFrame, ActiveAnim->PlayableRange.Max); - if ((EndFrame - StartFrame) > 0) - { - animation_pattern_handle PatternHandle = Patterns_IndexToHandle(0); - s32 Layer = TimelineState->SelectedAnimationLayer; - if (Layer < 0) - { - Layer = Animation_AddLayer(ActiveAnim, MakeString("[New Layer]"), BlendMode_Add, &State->AnimationSystem); - AnimationTimeline_SelectLayer(TimelineState, Layer); - } - Assert(Layer >= 0); - - handle NewBlockHandle = Animation_AddBlock(ActiveAnim, StartFrame, EndFrame, PatternHandle, Layer); - - TimelineState->SelectedBlockHandle = NewBlockHandle; - } else { - // TODO(pjs): we don't want to create a block of zero frames - // since you won't be able to delete it. What do we do here?? - } -} - -input_command AnimationTimeline_Commands[] = { - { KeyCode_X, KeyCode_Invalid, Command_Began, DeleteAnimationBlockCommand }, -}; -s32 AnimationTimeline_CommandsCount = 2; - -GSMetaTag(panel_init); -GSMetaTag(panel_type_animation_timeline); -internal void -AnimationTimeline_Init(panel* Panel, app_state* State, context Context) -{ - animation_handle Handle = State->AnimationSystem.ActiveFadeGroup.From; - - // TODO: :FreePanelMemory - animation_timeline_state* TimelineState = PushStruct(&State->Permanent, animation_timeline_state); - TimelineState->EditingAnimationHandle = Handle; - - if (IsValid(Handle)) { - animation_array Animations = State->AnimationSystem.Animations; - animation* ActiveAnim = AnimationArray_GetSafe(Animations, Handle); - TimelineState->VisibleRange = ActiveAnim->PlayableRange; - } - - Panel->StateMemory = StructToData(TimelineState, animation_timeline_state); -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_animation_timeline); -internal void -AnimationTimeline_Cleanup(panel* Panel, app_state* State) -{ - -} - -internal void -DrawFrameBar (animation_system* AnimationSystem, ui_interface Interface, frame_range VisibleFrames, rect2 BarBounds, app_state* State) -{ - gs_string TempString = PushString(State->Transient, 256); - - s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min; - - r32 BarHeight = Rect2Height(BarBounds); - r32 BarWidth = Rect2Width(BarBounds); - - // Mouse clicked inside frame nubmer bar -> change current frame on timeline - if (ui_MouseClickedRect(Interface, BarBounds)) - { - StartDragTimeMarker(BarBounds, VisibleFrames, State); - } - - PushRenderQuad2D(Interface.RenderBuffer, BarBounds.Min, BarBounds.Max, v4{.16f, .16f, .16f, 1.f}); - - // Frame Ticks - u32 TickCount = 10; - for (u32 Tick = 0; Tick < TickCount; Tick++) - { - r32 Percent = (r32)Tick / (r32)TickCount; - u32 Frame = PercentToFrameInRange(Percent, VisibleFrames); - PrintF(&TempString, "%d", Frame); - r32 FramePercent = FrameToPercentRange(Frame, VisibleFrames); - r32 FrameX = LerpR32(FramePercent, BarBounds.Min.x, BarBounds.Max.x); - v2 FrameTextPos = v2{FrameX, BarBounds.Min.y + 2}; - DrawString(Interface.RenderBuffer, TempString, Interface.Style.Font, FrameTextPos, WhiteV4, -1, GreenV4); - } - - // Time Slider - if (FrameIsInRange(VisibleFrames, AnimationSystem->CurrentFrame)) - { - r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, VisibleFrames); - r32 SliderX = LerpR32(FrameAtPercentVisibleRange, BarBounds.Min.x, BarBounds.Max.x); - - PrintF(&TempString, "%d", AnimationSystem->CurrentFrame); - - // space for each character + a margin on either side - r32 SliderWidth = (8 * TempString.Length) + 8; - r32 SliderHalfWidth = SliderWidth / 2.f; - v2 HeadMin = v2{SliderX - SliderHalfWidth, BarBounds.Min.y}; - v2 HeadMax = v2{SliderX + SliderHalfWidth, BarBounds.Max.y}; - PushRenderQuad2D(Interface.RenderBuffer, HeadMin, HeadMax, TimeSliderColor); - DrawString(Interface.RenderBuffer, TempString, Interface.Style.Font, HeadMin + v2{6, 4}, WhiteV4, -1, GreenV4); - } -} - -internal bool -MinMaxRangeSlider(v2 HandleValues, rect2 SliderBounds, r32 MinValue, r32 MaxValue, ui_interface Interface, v2* OutHandleValues) -{ - // Should Update only gets set to true when the user is finished interacting (ie. on mouse up) - // this allows the continuous use of the value of a handle while it is being dragged, and allows - // for you to know when exactly to update the stored value - - bool ShouldUpdate = false; - *OutHandleValues = HandleValues; - - v4 BGColor = v4{.16f, .16f, .16f, 1.f}; - v4 HandleColor = v4{.8f, .8f, .8f, 1.f}; - - v2 HandleDim = v2{25, Rect2Height(SliderBounds)}; - r32 MinHandleX = RemapR32(HandleValues.x, MinValue, MaxValue, SliderBounds.Min.x, SliderBounds.Max.x); - r32 MaxHandleX = RemapR32(HandleValues.y, MinValue, MaxValue, SliderBounds.Min.x, SliderBounds.Max.x); - rect2 MinHandleBounds = MakeRect2CenterDim(v2{ MinHandleX, Rect2Center(SliderBounds).y }, HandleDim); - rect2 MaxHandleBounds = MakeRect2CenterDim(v2{ MaxHandleX, Rect2Center(SliderBounds).y }, HandleDim); - - // Drag the handles - if (MouseButtonHeldDown(Interface.Mouse.LeftButtonState) || - MouseButtonTransitionedUp(Interface.Mouse.LeftButtonState)) - { - v2 MouseDragOffset = Interface.Mouse.Pos - Interface.Mouse.DownPos; - - // TODO(pjs): We need to make sure that the min handle is always the lower one, etc. - // TODO(pjs): We need to range clamp the handles - if (PointIsInRect(MinHandleBounds, Interface.Mouse.DownPos)) - { - MinHandleBounds = Rect2TranslateX(MinHandleBounds, MouseDragOffset.x); - } - else if (PointIsInRect(MaxHandleBounds, Interface.Mouse.DownPos)) - { - MaxHandleBounds = Rect2TranslateX(MaxHandleBounds, MouseDragOffset.x); - } - } - - // Draw Background - PushRenderQuad2D(Interface.RenderBuffer, SliderBounds.Min, SliderBounds.Max, BGColor); - - // Draw Handles - PushRenderQuad2D(Interface.RenderBuffer, MinHandleBounds.Min, MinHandleBounds.Max, HandleColor); - PushRenderQuad2D(Interface.RenderBuffer, MaxHandleBounds.Min, MaxHandleBounds.Max, HandleColor); - - // Update the output range value - r32 MinHandleXOut = Rect2Center(MinHandleBounds).x; - r32 MaxHandleXOut = Rect2Center(MaxHandleBounds).x; - - r32 MinHandleValue = RemapR32(MinHandleXOut, SliderBounds.Min.x, SliderBounds.Max.x, MinValue, MaxValue); - r32 MaxHandleValue = RemapR32(MaxHandleXOut, SliderBounds.Min.x, SliderBounds.Max.x, MinValue, MaxValue); - - *OutHandleValues = v2{ Min(MinHandleValue, MaxHandleValue), Max(MinHandleValue, MaxHandleValue) }; - - if (MouseButtonTransitionedUp(Interface.Mouse.LeftButtonState)) - { - ShouldUpdate = true; - } - - return ShouldUpdate; -} - - -internal frame_range -DrawTimelineRangeBar (animation_system* AnimationSystem, animation Animation, animation_timeline_state* TimelineState, ui_interface Interface, rect2 BarBounds) -{ - frame_range VisibleRangeAfterInteraction = {}; - r32 MinFrame = (r32)Animation.PlayableRange.Min; - r32 MaxFrame = (r32)Animation.PlayableRange.Max; - - v2 RangeHandles = v2{ (r32)TimelineState->VisibleRange.Min, (r32)TimelineState->VisibleRange.Max }; - - bool ApplyUpdate = MinMaxRangeSlider(RangeHandles, BarBounds, MinFrame, MaxFrame, Interface, &RangeHandles); - VisibleRangeAfterInteraction.Min = (s32)RangeHandles.x; - VisibleRangeAfterInteraction.Max = (s32)RangeHandles.y; - - if (ApplyUpdate) - { - TimelineState->VisibleRange = VisibleRangeAfterInteraction; - } - - return VisibleRangeAfterInteraction; -} - -#define LAYER_HEIGHT 52 - -internal void -DrawLayerMenu(animation_system* AnimationSystem, animation ActiveAnim, ui_interface Interface, rect2 PanelDim, u32* SelectedAnimationLayer) -{ - v2 LayerDim = { Rect2Width(PanelDim), LAYER_HEIGHT }; - v2 LayerListMin = PanelDim.Min + v2{0, 24}; - for (u32 i = 0; i < ActiveAnim.Layers.Count; i++) - { - anim_layer* Layer = ActiveAnim.Layers.Values + i; - - rect2 LayerBounds = {0}; - LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * i) }; - LayerBounds.Max = LayerBounds.Min + LayerDim; - - if (MouseButtonTransitionedDown(Interface.Mouse.LeftButtonState) && - PointIsInRect(LayerBounds, Interface.Mouse.Pos)) - { - *SelectedAnimationLayer = i; - } - - v2 LayerTextPos = { LayerBounds.Min.x + 6, LayerBounds.Max.y - 16}; - if (*SelectedAnimationLayer == i) - { - PushRenderBoundingBox2D(Interface.RenderBuffer, LayerBounds.Min, LayerBounds.Max, 1, WhiteV4); - } - DrawString(Interface.RenderBuffer, Layer->Name, Interface.Style.Font, LayerTextPos, WhiteV4, -1, GreenV4); - } -} - -PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback) -{ - Assert(ReturningFrom->TypeIndex == PanelType_FileView); - file_view_state* FileViewState = Panel_GetStateStruct(ReturningFrom, file_view_state); - gs_file_info FileInfo = FileViewState->SelectedFile; - - if (FileInfo.Path.Length > 0) - { - animation_handle NewAnimHandle = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, - State->Patterns, - Context, - FileInfo.Path); - State->AnimationSystem.ActiveFadeGroup.From = NewAnimHandle; - } -} - -internal void -PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_FUNCTION; - - animation_system* AnimSystem = &State->AnimationSystem; - ui_interface* Interface = &State->Interface; - ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("PlayBar Layout")); - - ui_FillRect(Interface, Bounds, Interface->Style.PanelBG); - ui_BeginRow(&State->Interface, 4); - { - if (ui_Button(Interface, MakeString("Pause"))) - { - AnimSystem->TimelineShouldAdvance = false; - } - - if (ui_Button(Interface, MakeString("Play"))) - { - AnimSystem->TimelineShouldAdvance = true; - } - - if (ui_Button(Interface, MakeString("Stop"))) - { - AnimSystem->TimelineShouldAdvance = false; - AnimSystem->CurrentFrame = 0; - } - } - ui_EndRow(&State->Interface); - ui_PopLayout(&State->Interface, MakeString("PlayBar Layout")); -} - -internal void -FrameCount_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_FUNCTION; - - ui_interface* Interface = &State->Interface; - gs_string TempString = PushString(State->Transient, 256); - - // :FrameRange - // frame_range VisibleFrames = TimelineState->VisibleRange; - - frame_range VisibleFrames = {}; - if (ActiveAnim) { - VisibleFrames = ActiveAnim->PlayableRange; - } - - s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min; - - ui_FillRect(Interface, Bounds, Interface->Style.PanelBG); - - // Frame Ticks - u32 TickCount = 10; - for (u32 Tick = 0; Tick < TickCount; Tick++) - { - r32 Percent = (r32)Tick / (r32)TickCount; - u32 Frame = PercentToFrameInRange(Percent, VisibleFrames); - PrintF(&TempString, "%d", Frame); - r32 FramePercent = FrameToPercentRange(Frame, VisibleFrames); - r32 FrameX = LerpR32(FramePercent, Bounds.Min.x, Bounds.Max.x); - v2 FrameTextPos = v2{FrameX, Bounds.Min.y + 2}; - DrawString(Interface->RenderBuffer, TempString, Interface->Style.Font, FrameTextPos, WhiteV4, -1, GreenV4); - } - - // Time Slider - s32 CurrentFrame = State->AnimationSystem.CurrentFrame; - if (FrameIsInRange(VisibleFrames, CurrentFrame)) - { - r32 FrameAtPercentVisibleRange = FrameToPercentRange(CurrentFrame, VisibleFrames); - r32 SliderX = LerpR32(FrameAtPercentVisibleRange, Bounds.Min.x, Bounds.Max.x); - - PrintF(&TempString, "%d", CurrentFrame); - - // space for each character + a margin on either side - r32 SliderWidth = (8 * TempString.Length) + 8; - r32 SliderHalfWidth = SliderWidth / 2.f; - v2 HeadMin = v2{SliderX - SliderHalfWidth, Bounds.Min.y}; - v2 HeadMax = v2{SliderX + SliderHalfWidth, Bounds.Max.y}; - PushRenderQuad2D(Interface->RenderBuffer, HeadMin, HeadMax, TimeSliderColor); - DrawString(Interface->RenderBuffer, TempString, Interface->Style.Font, HeadMin + v2{6, 4}, WhiteV4, -1, GreenV4); - } - - // Interaction - // Mouse clicked inside frame nubmer bar -> change current frame on timeline - if (ui_MouseClickedRect(*Interface, Bounds)) - { - StartDragTimeMarker(Bounds, VisibleFrames, State); - } -} - -internal bool -LayerList_DrawLayerButton (ui_interface* Interface, gs_string Name, rect2 Bounds, bool Selected) -{ - bool Result = ui_MouseClickedRect(*Interface, Bounds); - v2 TextPos = { Bounds.Min.x + 6, Bounds.Max.y - 16}; - - v4 BoxColor = WhiteV4; - bool DrawBox = Selected; - if (PointIsInRect(Bounds, Interface->Mouse.Pos)) - { - DrawBox = true; - BoxColor = PinkV4; - } - - if (DrawBox) - { - PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, 1, BoxColor); - } - DrawString(Interface->RenderBuffer, Name, Interface->Style.Font, TextPos, WhiteV4, -1, GreenV4); - return Result; -} - -internal void -LayerList_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_FUNCTION; - ui_interface* Interface = &State->Interface; - - ui_FillRect(Interface, Bounds, Interface->Style.PanelBG); - - v2 LayerDim = { Rect2Width(Bounds), LAYER_HEIGHT }; - rect2 LayerBounds = {0}; - LayerBounds.Min = Bounds.Min; - LayerBounds.Max = LayerBounds.Min + LayerDim; - - if (ActiveAnim) - { - v2 LayerTextPos = {}; - for (s32 i = 0; i < (s32)ActiveAnim->Layers.Count; i++) - { - anim_layer* Layer = ActiveAnim->Layers.Values + i; - - bool Selected = (TimelineState->SelectedAnimationLayer == i); - if (LayerList_DrawLayerButton(Interface, Layer->Name, LayerBounds, Selected)) - { - TimelineState->SelectedAnimationLayer = i; - } - LayerBounds = Rect2TranslateY(LayerBounds, LayerDim.y); - } - - if (LayerList_DrawLayerButton(Interface, MakeString("+ Add Layer"), LayerBounds, false)) - { - u32 NewLayer = Animation_AddLayer(ActiveAnim, MakeString("[New Layer]"), BlendMode_Add, &State->AnimationSystem); - } - } -} - -internal void -TimeRange_RenderBlock (rect2 BlockBounds, u32 BlockIndex, animation* ActiveAnim, handle SelectedBlockHandle, ui_interface* Interface, render_command_buffer* RenderBuffer) -{ - v4 BlockColor = BlackV4; - if (SelectedBlockHandle.Index == BlockIndex && SelectedBlockHandle.Generation == ActiveAnim->Blocks_.Generations[BlockIndex]) - { - BlockColor = TealV4; - } - - PushRenderQuad2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, BlockColor); - PushRenderBoundingBox2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, 1, WhiteV4); -} - -struct block_bounds_lut_entry -{ - rect2 Bounds; - u32 Index; -}; - -internal void -TimeRange_RenderBlockArray(block_bounds_lut_entry* Blocks, u32* LUT, u32 LUTCount, r32 HeightOffset, animation* ActiveAnim, handle SelectedBlockHandle, handle* DragBlockHandle, ui_interface* Interface, render_command_buffer* RenderBuffer) -{ - for (u32 i = 0; i < LUTCount; i++) - { - u32 BlockBoundsIndex = LUT[i]; - block_bounds_lut_entry Block = Blocks[BlockBoundsIndex]; - Block.Bounds.Max.y += HeightOffset; - - TimeRange_RenderBlock(Block.Bounds, Block.Index, ActiveAnim, SelectedBlockHandle, Interface, RenderBuffer); - - if (PointIsInRect(Block.Bounds, Interface->Mouse.Pos)) - { - DragBlockHandle->Index = Block.Index; - DragBlockHandle->Generation = ActiveAnim->Blocks_.Generations[Block.Index]; - } - } -} - -internal void -TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_FUNCTION; - - ui_interface* Interface = &State->Interface; - - // TODO(pjs): setting the timeline to show the entire range - // of the current animation until I reimplement the range - // slider bars - // :FrameRange - // frame_range ViewRange = TimelineState->VisibleRange; - frame_range ViewRange = {}; - if (ActiveAnim) - { - ViewRange = ActiveAnim->PlayableRange; - } - - handle SelectedBlockHandle = TimelineState->SelectedBlockHandle; - s32 CurrentFrame = State->AnimationSystem.CurrentFrame; - - // Animation Blocks - b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState); - handle DragBlockHandle = {0}; - if (ActiveAnim) - { - u32 BlocksCountMax = ActiveAnim->Blocks_.Count; - u32 BlocksCount = 0; - block_bounds_lut_entry* Blocks = PushArray(State->Transient, block_bounds_lut_entry, BlocksCountMax); - - u32 FrontBlocksCount = 0; - u32* FrontBlocks = PushArray(State->Transient, u32, BlocksCountMax); - u32 BackBlocksCount = 0; - u32* BackBlocks = PushArray(State->Transient, u32, BlocksCountMax); - - for (u32 l = 0; l < ActiveAnim->Layers.Count; l++) - { - BlocksCount = 0; - FrontBlocksCount = 0; - BackBlocksCount = 0; - - for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) - { - animation_block* AnimationBlockAt = ActiveAnim->Blocks_.Values + i; - if (AnimationBlockAt->Layer != l) continue; - - // If either end is in the range, we should draw it - b32 RangeIsVisible = (FrameIsInRange(ViewRange, AnimationBlockAt->Range.Min) || - FrameIsInRange(ViewRange, AnimationBlockAt->Range.Max)); - // If neither end is in the range, but the ends surround the visible range, - // we should still draw it. - RangeIsVisible |= (AnimationBlockAt->Range.Min <= ViewRange.Min && - AnimationBlockAt->Range.Max>= ViewRange.Max); - if (!RangeIsVisible) continue; - - r32 TimelineWidth = Rect2Width(Bounds); - - frame_range BlockAtRange = AnimationBlockAt->Range; - u32 ClampedBlockStartFrame = ClampFrameToRange(BlockAtRange.Min, ViewRange); - r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, ViewRange); - r32 StartPosition = TimelineWidth * StartFramePercent; - - u32 ClampedBlockEndFrame = ClampFrameToRange(BlockAtRange.Max, ViewRange); - r32 EndFramePercent = FrameToPercentRange(ClampedBlockEndFrame, ViewRange); - r32 EndPosition = TimelineWidth * EndFramePercent; - - r32 LayerYOffset = LAYER_HEIGHT * AnimationBlockAt->Layer; - - rect2 NewBlockBounds = {}; - NewBlockBounds.Min = Bounds.Min + v2{StartPosition, LayerYOffset}; - NewBlockBounds.Max = Bounds.Min + v2{EndPosition, LayerYOffset + LAYER_HEIGHT}; - - block_bounds_lut_entry NewBlock = {}; - NewBlock.Bounds = NewBlockBounds; - NewBlock.Index = i; - - // fast (implementation-wise) insert sort. - // TODO(PS): probably not great - for (u32 j = 0; j < BlocksCount; j++) - { - if (Blocks[j].Bounds.Min.x > NewBlock.Bounds.Min.x) - { - block_bounds_lut_entry Old = Blocks[j]; - Blocks[j] = NewBlock; - NewBlock = Old; - } - } - Blocks[BlocksCount++] = NewBlock; - } - - // BlockBounds are sorted by their render bounds from left to right - // This iterates over them to see if any on the same layer overlap, and if - // so, shrinks one of them, putting it in a new list - for (u32 i = 0; i < BlocksCount; i++) - { - if (i % 2 == 0) - { - BackBlocks[BackBlocksCount++] = i; - continue; - } - - bool ShortCandidate = false; - block_bounds_lut_entry Block = Blocks[i]; - if (i > 0) - { - block_bounds_lut_entry PrevBlock = Blocks[i - 1]; - rect2 Union = Rect2Union(PrevBlock.Bounds, Block.Bounds); - ShortCandidate |= Rect2Width(Union) > 0; - } - if (i < BlocksCount - 1) - { - block_bounds_lut_entry NextBlock = Blocks[i + 1]; - rect2 Union = Rect2Union(NextBlock.Bounds, Block.Bounds); - ShortCandidate |= Rect2Width(Union) > 0; - } - - if (ShortCandidate) - { - FrontBlocks[FrontBlocksCount++] = i; - } - else - { - BackBlocks[BackBlocksCount++] = i; - } - } - - TimeRange_RenderBlockArray(Blocks, BackBlocks, BackBlocksCount, 0, ActiveAnim, SelectedBlockHandle, &DragBlockHandle, Interface, RenderBuffer); - TimeRange_RenderBlockArray(Blocks, FrontBlocks, FrontBlocksCount, -15, ActiveAnim, SelectedBlockHandle, &DragBlockHandle, Interface, RenderBuffer); - } - } - - // Time Slider - if (FrameIsInRange(ViewRange, CurrentFrame)) - { - r32 FrameAtPercentVisibleRange = FrameToPercentRange(CurrentFrame, ViewRange); - r32 SliderX = LerpR32(FrameAtPercentVisibleRange, Bounds.Min.x, Bounds.Max.x); - rect2 SliderBounds = { - v2{ SliderX, Bounds.Min.y }, - v2{ SliderX + 1, Bounds.Max.y } - }; - ui_FillRect(Interface, SliderBounds, TimeSliderColor); - } - - // Interaction - if (MouseDownAndNotHandled) - { - if (Handle_IsValid(DragBlockHandle)) - { - MouseDownAndNotHandled = false; - SelectAndBeginDragAnimationBlock(TimelineState, DragBlockHandle, ViewRange, Bounds, State); - } - else if (PointIsInRect(Bounds, Interface->Mouse.Pos)) - { - TimelineState->SelectedBlockHandle = {0}; - } - } -} - -internal void -AnimInfoView_SaveAnimFile (gs_const_string Path, app_state* State, context Context) -{ - animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From; - animation ActiveAnim = *AnimationArray_GetSafe(State->AnimationSystem.Animations, ActiveAnimHandle); - - gs_string FileText = AnimSerializer_Serialize(ActiveAnim, State->Patterns, State->Transient); - - if (!WriteEntireFile(Context.ThreadContext.FileHandler, Path, StringToData(FileText))) - { - InvalidCodePath; - } -} - -PANEL_MODAL_OVERRIDE_CALLBACK(AnimInfoView_SaveAnimFileCallback) -{ - Assert(ReturningFrom->TypeIndex == PanelType_FileView); - file_view_state* FileViewState = Panel_GetStateStruct(ReturningFrom, file_view_state); - gs_file_info FileInfo = FileViewState->SelectedFile; - - AnimInfoView_SaveAnimFile(FileInfo.Path, State, Context); -} - -internal void -AnimationTimeline_SetActiveAnimation (animation_handle Handle, animation_timeline_state* TimelineState) -{ - TimelineState->NextActiveAnim = Handle; -} - -internal void -AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_FUNCTION; - animation_system* AnimSystem = &State->AnimationSystem; - - animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From; - ui_interface* Interface = &State->Interface; - ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout"), ActiveAnimHandle.Index); - - ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBG); - - gs_string AnimName = {}; - if (ActiveAnim) - { - AnimName = ActiveAnim->Name; - } else { - AnimName = MakeString("[None]"); - } - - if (ui_BeginLabeledDropdown(Interface, MakeString("Active Animation"), AnimName)) - { - for (u32 i = 0; i < AnimSystem->Animations.Count; i++) - { - animation Animation = AnimSystem->Animations.Values[i]; - if (ui_Button(Interface, Animation.Name)) - { - animation_handle NewHandle = {}; - NewHandle.Index = i; - AnimationTimeline_SetActiveAnimation(NewHandle, TimelineState); - } - } - } - ui_EndLabeledDropdown(&State->Interface); - - ui_BeginRow(Interface, 3); - { - if (ui_Button(Interface, MakeString("New"))) - { - animation_desc Desc = {}; - Desc.NameSize = 256; - Desc.LayersCount = 8; - Desc.BlocksCount = 8; - Desc.MinFrames = 0; - Desc.MaxFrames = SecondsToFrames(15, State->AnimationSystem); - - animation NewAnim = Animation_Create(Desc, &State->AnimationSystem); - animation_handle NewAnimHandle = AnimationArray_Push(&State->AnimationSystem.Animations, NewAnim); - AnimationTimeline_SetActiveAnimation(NewAnimHandle, TimelineState); - } - if (ActiveAnim && ui_Button(Interface, MakeString("Save"))) - { - // Save Animation File - // TODO(pjs): If you created the animation via the "new" button, there won't be a file attached. - // need to use the file browser to create a file - animation ActiveAnimation = *AnimationArray_GetSafe(State->AnimationSystem.Animations, ActiveAnimHandle); - - if (!ActiveAnimation.FileInfo.Path.Str) - { - panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context); - FileView_SetMode(FileBrowser, FileViewMode_Save); - Panel_PushModalOverride(Panel, FileBrowser, AnimInfoView_SaveAnimFileCallback); - } else { - AnimInfoView_SaveAnimFile(ActiveAnimation.FileInfo.Path, State, Context); - } - } - if (ui_Button(Interface, MakeString("Load"))) - { - panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context); - Panel_PushModalOverride(Panel, FileBrowser, LoadAnimationFileCallback); - } - - } - ui_EndRow(Interface); - - if (ActiveAnim) - { - ui_TextEntry(Interface, MakeString("Anim Name"), &ActiveAnim->Name); - - ui_Label(Interface, MakeString("Frame Range")); - ui_BeginRow(Interface, 3); - { - ActiveAnim->PlayableRange.Min = ui_TextEntryU64(Interface, MakeString("StartFrame"), ActiveAnim->PlayableRange.Min); - ActiveAnim->PlayableRange.Max = ui_TextEntryU64(Interface, MakeString("EndFrame"), ActiveAnim->PlayableRange.Max); - - } - ui_EndRow(Interface); - - ui_Label(Interface, MakeString("Layer")); - - s32 LayerIndex = TimelineState->SelectedAnimationLayer; - anim_layer* SelectedLayer = 0; - if (LayerIndex >= 0) - { - SelectedLayer = ActiveAnim->Layers.Values + LayerIndex; - - ui_TextEntry(Interface, MakeString("Layer Name"), &SelectedLayer->Name); - gs_string BlendStr = BlendModeStrings[SelectedLayer->BlendMode]; - if (ui_BeginLabeledDropdown(Interface, MakeString("Blend Mode"), BlendStr)) - { - for (u32 i = 0; i < BlendMode_Count; i++) - { - if (ui_Button(Interface, BlendModeStrings[i])) - { - SelectedLayer->BlendMode = (blend_mode)i; - } - } - } - ui_EndLabeledDropdown(Interface); - } - - ui_Label(Interface, MakeString("Pattern")); - - animation_block* SelectedBlock = Animation_GetBlockFromHandle(ActiveAnim, TimelineState->SelectedBlockHandle); - if (SelectedBlock) - { - animation_pattern BlockPattern = Patterns_GetPattern(State->Patterns, SelectedBlock->AnimationProcHandle); - - ui_BeginRow(Interface, 2); - ui_Label(Interface, MakeString("Selected Pattern")); - if (ui_BeginDropdown(Interface, MakeString(BlockPattern.Name, BlockPattern.NameLength))) - { - Interface->ActiveLayout->Bounds.Max.x += 128.0f; - Interface->ActiveLayout->Columns[0].XMax += 128.0f; - - ui_BeginList(Interface, MakeString("Patterns List"), 5, State->Patterns.Count); - for (u32 i = 0; i < State->Patterns.Count; i++) - { - animation_pattern Pattern = State->Patterns.Values[i]; - if (ui_Button(Interface, MakeString(Pattern.Name, Pattern.NameLength))) - { - SelectedBlock->AnimationProcHandle = Patterns_IndexToHandle(i); - } - } - ui_EndList(Interface); - } - ui_EndLabeledDropdown(Interface); - } - - if (ui_Button(Interface, MakeString("+ Add Block"))) - { - AnimationTimeline_AddAnimationBlockCommand(TimelineState, State, Context); - } - } - ui_PopLayout(Interface, MakeString("AnimInfo Layout")); -} - -internal void -SelectionInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - ui_FillRect(&State->Interface, Bounds, YellowV4); -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_animation_timeline); -internal void -AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_FUNCTION; - - animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state); - - animation* ActiveAnim = 0; - animation_handle Handle = State->AnimationSystem.ActiveFadeGroup.From; - TimelineState->NextActiveAnim = Handle; - if (IsValid(Handle)) - { - animation_array Animations = State->AnimationSystem.Animations; - ActiveAnim = AnimationArray_GetSafe(Animations, Handle); - TimelineState->EditingAnimationHandle = Handle; - } - - ui_FillRect(&State->Interface, PanelBounds, v4{.1f,.1f,.1f,1.f}); - - rect2 TimelineBounds, InfoBounds; - RectVSplitAtDistanceFromLeft(PanelBounds, 300, &InfoBounds, &TimelineBounds); - - rect2 LayersPanelBounds, TimeRangePanelBounds; - RectVSplitAtDistanceFromLeft(TimelineBounds, 200, &LayersPanelBounds, &TimeRangePanelBounds); - - r32 TitleBarHeight = State->Interface.Style.RowHeight; - // These are the actual rects we will draw in - rect2 PlayBarBounds, FrameCountBounds; - rect2 LayersBounds, TimeRangeBounds; - RectHSplitAtDistanceFromTop(LayersPanelBounds, TitleBarHeight, &PlayBarBounds, &LayersBounds); - RectHSplitAtDistanceFromTop(TimeRangePanelBounds, TitleBarHeight, &FrameCountBounds, &TimeRangeBounds); - - PlayBar_Render(TimelineState, PlayBarBounds, Panel, RenderBuffer, State, Context); - FrameCount_Render(TimelineState, ActiveAnim, FrameCountBounds, RenderBuffer, State, Context); - LayerList_Render(TimelineState, ActiveAnim, LayersBounds, Panel, RenderBuffer, State, Context); - TimeRange_Render(TimelineState, ActiveAnim, TimeRangeBounds, RenderBuffer, State, Context); - AnimInfoView_Render(TimelineState, ActiveAnim, InfoBounds, Panel, RenderBuffer, State, Context); - - if (!AnimHandlesAreEqual(TimelineState->NextActiveAnim, - Handle)) - { - State->AnimationSystem.ActiveFadeGroup.From = TimelineState->NextActiveAnim; - TimelineState->EditingAnimationHandle = TimelineState->NextActiveAnim; - TimelineState->SelectedAnimationLayer = -1; - } -} - -#define FOLDHAUS_PANEL_ANIMATION_TIMELINE_H -#endif // FOLDHAUS_PANEL_ANIMATION_TIMELINE_H \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_assembly_debug.h b/src/app/editor/panels/foldhaus_panel_assembly_debug.h deleted file mode 100644 index 4ef3599..0000000 --- a/src/app/editor/panels/foldhaus_panel_assembly_debug.h +++ /dev/null @@ -1,146 +0,0 @@ -// -// File: foldhaus_panel_assembly_debug.h -// Author: Peter Slattery -// Creation Date: 2021-01-15 -// -#ifndef FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H - -GSMetaTag(panel_init); -GSMetaTag(panel_type_file_view); -internal void -AssemblyDebug_Init(panel* Panel, app_state* State, context Context) -{ -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_file_view); -internal void -AssemblyDebug_Cleanup(panel* Panel, app_state* State) -{ - -} - -// TODO(pjs): This is really blumen specific -#define FSC(f,c) FlowerStripToChannel((f), (c)) -internal u8 -FlowerStripToChannel(u8 Flower, u8 Channel) -{ - Assert(Flower < 3); - Assert(Channel < 8); - - u8 Result = 0; - Result |= (Flower & 0x03) << 3; - Result |= (Channel & 0x07); - - return Result; -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_file_view); -internal void -AssemblyDebug_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - ui_interface* Interface = &State->Interface; - ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Assembly Debug Layout")); - - ui_BeginRow(Interface, 2); - { - if (ui_Button(Interface, MakeString("Assembly"))) - { - State->ShowingUserSpaceDebug = false; - } - - if (ui_Button(Interface, MakeString("User Space"))) - { - State->ShowingUserSpaceDebug = true; - } - } - ui_EndRow(Interface); - - if (State->ShowingUserSpaceDebug && State->UserSpaceDesc.CustomDebugUI) - { - US_CustomDebugUI(&State->UserSpaceDesc, Panel, PanelBounds, RenderBuffer, - State, Context); - } - else - { - InterfaceAssert(Interface->PerFrameMemory); - - State->AssemblyDebugState.AllAssemblies = ui_ToggleText(Interface, MakeString("All Assemblies"), State->AssemblyDebugState.AllAssemblies); - - gs_string OverrideStr = MakeString(OverrideTypeStrings[State->AssemblyDebugState.Override]); - if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr)) - { - for (u32 i = 0; i < ADS_Override_Count; i++) - { - if (ui_Button(Interface, MakeString(OverrideTypeStrings[i]))) - { - State->AssemblyDebugState.Override = (override_type)i; - } - } - } - ui_EndLabeledDropdown(Interface); - InterfaceAssert(Interface->PerFrameMemory); - - switch (State->AssemblyDebugState.Override) - { - case ADS_Override_TagWhite: - case ADS_Override_TagStripWhite: - { - ui_LabeledTextEntry(Interface, MakeString("Tag Name"), &State->AssemblyDebugState.TagName); - ui_LabeledTextEntry(Interface, MakeString("Tag Value"), &State->AssemblyDebugState.TagValue); - - if (State->AssemblyDebugState.Override == ADS_Override_TagStripWhite) - { - State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly); - - State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip); - } - }break; - - case ADS_Override_ChannelWhite: - { - u64 Board = 0; - u64 Strip = 0; - Board = ui_LabeledTextEntryU64(Interface, MakeString("Board"), Board); - Strip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), Strip); - - State->AssemblyDebugState.TargetChannel = FSC(Board, Strip); - }break; - - case ADS_Override_AllOff: - case ADS_Override_AllRed: - case ADS_Override_AllGreen: - case ADS_Override_AllBlue: - case ADS_Override_AllWhite: - { - State->AssemblyDebugState.Brightness = (u8)ui_LabeledRangeSlider(Interface, MakeString("Brightness"), (r32)State->AssemblyDebugState.Brightness, 0, 255); - State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly); - }break; - - case ADS_Override_AllHue: - { - State->AssemblyDebugState.TargetHue = (u32)ui_LabeledRangeSlider(Interface, MakeString("Hue"), (r32)State->AssemblyDebugState.TargetHue, 0, 360); - }break; - - default: - { - InterfaceAssert(Interface->PerFrameMemory); - - State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly); - - InterfaceAssert(Interface->PerFrameMemory); - - State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip); - - InterfaceAssert(Interface->PerFrameMemory); - }break; - } - } - - State->SendEmptyPackets = ui_LabeledToggle(Interface, MakeString("Send Empty Packets"), State->SendEmptyPackets); - ui_PopLayout(Interface, MakeString("Assembly Debug Layout")); -} - -#define FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H -#endif // FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_dmx_view.h b/src/app/editor/panels/foldhaus_panel_dmx_view.h deleted file mode 100644 index d7213ee..0000000 --- a/src/app/editor/panels/foldhaus_panel_dmx_view.h +++ /dev/null @@ -1,148 +0,0 @@ -// -// File: foldhaus_panel_dmx_view.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PANEL_DMX_VIEW_H - -struct universe_view_operation_state -{ - b32 MouseDown; - v2 DisplayOffset; - r32 Zoom; -}; - -input_command DMXView_Commands[] = {{}}; -s32 DMXView_CommandsCount = 0; - -GSMetaTag(panel_init); -GSMetaTag(panel_type_dmx_view); -internal void -DMXView_Init(panel* Panel, app_state* State, context Context) -{ - -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_dmx_view); -internal void -DMXView_Cleanup(panel* Panel, app_state* State) -{ - -} - -#if 0 - -// NOTE(Peter): Here to illustrate what old SACN Universe drawing looked like -// This won't actually function -// :NoLongerFunctionalSACNCodeButThatsOk -internal void -DrawSACNUniversePixels (render_command_buffer* RenderBuffer, sacn_universe* ToDraw, - v2 TopLeft, v2 Dimension) -{ - Assert(ToDraw); - - s32 PixelsPerRow = 21; - r32 PixelDim = Dimension.x / PixelsPerRow; - v2 PixelSize = v2{PixelDim, PixelDim}; - - v2 PixelRegister = TopLeft; - v4 DisplayColor = {0, 0, 0, 1}; - - s32 PixelsToDraw = ToDraw->SizeInSendBuffer - STREAM_HEADER_SIZE; - render_quad_batch_constructor BatchConstructor = PushRenderQuad2DBatch(RenderBuffer, PixelsToDraw); - - u8* ColorCursor = (u8*)ToDraw->StartPositionInSendBuffer + STREAM_HEADER_SIZE; - s32 PixelsDrawn = 0; - for (s32 i = 0; i < PixelsToDraw; i++) - { - PixelRegister.x = TopLeft.x + (PixelsDrawn % PixelsPerRow) * PixelDim; - PixelRegister.y = TopLeft.y - (PixelsDrawn / PixelsPerRow) * PixelDim; - - r32 Value = *ColorCursor++ / 255.f; - DisplayColor.r = Value; - DisplayColor.g = Value; - DisplayColor.b = Value; - - PushQuad2DOnBatch(&BatchConstructor, PixelRegister, PixelRegister + PixelSize, DisplayColor); - - ++PixelsDrawn; - } -} -#endif - -GSMetaTag(panel_render); -GSMetaTag(panel_type_dmx_view); -internal void -DMXView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ -#if 0 - // :NoLongerFunctionalSACNCodeButThatsOk - DEBUG_TRACK_SCOPE(DrawUniverseOutputDisplay); - - universe_view_operation_state* OpState = (universe_view_operation_state*)Operation.OpStateMemory; - - gs_string TitleBargs_string = InitializeEmptygs_string(PushArray(State->Transient, char, 64), 64); - - v2 DisplayArea_Dimension = v2{600, 600}; - - v2 DisplayContents_Offset = OpState->DisplayOffset; - - // - // TODO(Peter): I don't like this. Dragging the Universe view should be an operation mode, just - // like rotating the 3D view, but modes don't have access to the state of modes above them in the stack - // (and attempting to cast those states to the appropriate type seems risky) - // - // :NeedToPassStateDownModeChain - // - if (OpState->MouseDown) - { - DisplayContents_Offset += (Mouse.Pos - Mouse.DownPos); - } - - v2 DisplayArea_TopLeft = v2{300, (r32)RenderBuffer->ViewHeight - 50} + DisplayContents_Offset; - v2 UniverseDisplayDimension = v2{100, 100} * OpState->Zoom; - v2 Padding = v2{25, 50} * OpState->Zoom; - - v2 UniverseDisplayTopLeft = DisplayArea_TopLeft; - - sacn_universe_buffer* UniverseList = State->SACN.UniverseBuffer; - while(UniverseList) - { - for (s32 UniverseIdx = 0; - UniverseIdx < UniverseList->Used; - UniverseIdx++) - { - sacn_universe* Universe = UniverseList->Universes + UniverseIdx; - DrawSACNUniversePixels(RenderBuffer, Universe, UniverseDisplayTopLeft, UniverseDisplayDimension); - - - if (OpState->Zoom > .5f) - { - v2 TitleDisplayStart = UniverseDisplayTopLeft + v2{0, 12}; - PrintF(&TitleBargs_string, "Universe %d", Universe->Universe); - DrawString(RenderBuffer, TitleBargs_string, State->Interface.Font, - TitleDisplayStart, WhiteV4); - } - - UniverseDisplayTopLeft.x += UniverseDisplayDimension.x + Padding.x; - if (UniverseDisplayTopLeft.x > DisplayArea_TopLeft.x + DisplayArea_Dimension.x) - { - UniverseDisplayTopLeft.x = DisplayArea_TopLeft.x; - UniverseDisplayTopLeft.y -= UniverseDisplayDimension.y + Padding.y; - } - - if (UniverseDisplayTopLeft.y < DisplayArea_TopLeft.y - DisplayArea_Dimension.y) - { - break; - } - - } - UniverseList = UniverseList->Next; - } -#endif -} - - -#define FOLDHAUS_PANEL_DMX_VIEW_H -#endif // FOLDHAUS_PANEL_DMX_VIEW_H \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_file_view.h b/src/app/editor/panels/foldhaus_panel_file_view.h deleted file mode 100644 index 64b03d5..0000000 --- a/src/app/editor/panels/foldhaus_panel_file_view.h +++ /dev/null @@ -1,200 +0,0 @@ -// -// File: foldhaus_panel_file_view.h -// Author: Peter Slattery -// Creation Date: 2020-03-08 -// -#ifndef FOLDHAUS_PANEL_FILE_VIEW_H - -enum file_view_mode -{ - FileViewMode_Load, - FileViewMode_Save, -}; - -struct file_view_state -{ - file_view_mode Mode; - - gs_string WorkingDirectory; - gs_string DisplayDirectory; - - gs_memory_arena FileNamesArena; - gs_file_info_array FileNames; - - gs_file_info SelectedFile; -}; - -internal void -FileView_SetMode(panel* Panel, file_view_mode Mode) -{ - file_view_state* FileViewState = Panel_GetStateStruct(Panel, file_view_state); - FileViewState->Mode = Mode; -} - -internal void -FileView_Exit_(panel* FileViewPanel, app_state* State, context Context) -{ - // TODO(pjs): Free State->FileNamesArena - - Assert(FileViewPanel->IsModalOverrideFor != 0); - panel* ReturnTo = FileViewPanel->IsModalOverrideFor; - if (ReturnTo->ModalOverrideCB) - { - ReturnTo->ModalOverrideCB(FileViewPanel, State, Context); - } - Panel_PopModalOverride(ReturnTo, &State->PanelSystem); -} - -global input_command* FileView_Commands = 0; -s32 FileView_CommandsCount = 0; - -internal void -FileView_UpdateWorkingDirectory(gs_const_string WorkingDirectory, file_view_state* State, context Context) -{ - // NOTE(pjs): make sure we're only passing valid directory paths to the - // function - char LastChar = WorkingDirectory.Str[WorkingDirectory.Length - 1]; - Assert(LastChar == '\\' || LastChar == '/'); - MemoryArenaClear(&State->FileNamesArena); - - - gs_string SanitizedDir = PushString(Context.ThreadContext.Transient, WorkingDirectory.Length + 2); - SanitizePath(WorkingDirectory, &SanitizedDir, Context.ThreadContext.Transient); - if (SanitizedDir.Str[SanitizedDir.Length - 1] != '\\') - { - AppendPrintF(&SanitizedDir, "\\"); - } - - gs_const_string SanitizedDisplayDir = SanitizedDir.ConstString; - - gs_file_info NewWorkingDir = GetFileInfo(Context.ThreadContext.FileHandler, SanitizedDir.ConstString); - if (NewWorkingDir.IsDirectory) - { - AppendPrintF(&SanitizedDir, "*"); - NullTerminate(&SanitizedDir); - - State->FileNames = EnumerateDirectory(Context.ThreadContext.FileHandler, &State->FileNamesArena, SanitizedDir.ConstString, EnumerateDirectory_IncludeDirectories); - - // NOTE(pjs): we might be printing from State->WorkingDirectory to State->WorkingDirectory - // in some cases. Shouldn't be a problem but it is unnecessary - PrintF(&State->WorkingDirectory, "%S", SanitizedDir.ConstString); - PrintF(&State->DisplayDirectory, "%S", SanitizedDisplayDir); - } -} - -GSMetaTag(panel_init); -GSMetaTag(panel_type_file_view); -internal void -FileView_Init(panel* Panel, app_state* State, context Context) -{ - // TODO: :FreePanelMemory - file_view_state* FileViewState = PushStruct(&State->Permanent, file_view_state); - Panel->StateMemory = StructToData(FileViewState, file_view_state); - FileViewState->FileNamesArena = MemoryArenaCreate(MB(4), Bytes(8), Context.ThreadContext.Allocator, 0, 0, "File View - File Names Arena"); - - // TODO(pjs): this shouldn't be stored in permanent - FileViewState->DisplayDirectory = PushString(&State->Permanent, 1024); - FileViewState->WorkingDirectory = PushString(&State->Permanent, 1024); - - FileView_UpdateWorkingDirectory(ConstString(".\\"), FileViewState, Context); -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_file_view); -internal void -FileView_Cleanup(panel* Panel, app_state* State) -{ - -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_file_view); -internal void -FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - file_view_state* FileViewState = Panel_GetStateStruct(Panel, file_view_state); - - ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown, MakeString("FileView Layout")); - { - ui_BeginRow(&State->Interface, 3); - { - if (FileViewState->Mode == FileViewMode_Save) - { - if (ui_Button(&State->Interface, MakeString("Save"))) - { - if (!FileViewState->SelectedFile.Path.Str) - { - FileViewState->SelectedFile.Path = FileViewState->DisplayDirectory.ConstString; - } - - FileView_Exit_(Panel, State, Context); - } - } - - if (ui_Button(&State->Interface, MakeString("Exit"))) - { - FileView_Exit_(Panel, State, Context); - } - } - ui_EndRow(&State->Interface); - - // Header - if (ui_TextEntry(&State->Interface, MakeString("pwd"), &FileViewState->DisplayDirectory)) - { - // if last character is a slash, update pwd, and clear the filter string - // otherwise update the filter string - gs_string Pwd = FileViewState->DisplayDirectory; - char LastChar = Pwd.Str[Pwd.Length - 1]; - if (LastChar == '\\' || LastChar == '/') - { - FileView_UpdateWorkingDirectory(Pwd.ConstString, FileViewState, Context); - } - else - { - - } - } - - // File Display - ui_BeginList(&State->Interface, MakeString("Files"), 10, FileViewState->FileNames.Count); - for (u32 i = 0; i < FileViewState->FileNames.Count; i++) - { - gs_file_info File = FileViewState->FileNames.Values[i]; - - u32 LastSlashIndex = FindLast(File.Path, File.Path.Length - 2, '\\'); - gs_const_string FileName = Substring(File.Path, LastSlashIndex + 1, File.Path.Length); - gs_string PathString = PushString(State->Transient, FileName.Length); - PrintF(&PathString, "%S", FileName); - - if (ui_LayoutListButton(&State->Interface, PathString, i)) - { - if (File.IsDirectory) - { - FileView_UpdateWorkingDirectory(File.Path, FileViewState, Context); - } - else - { - FileViewState->SelectedFile = File; - switch (FileViewState->Mode) - { - case FileViewMode_Load: - { - FileView_Exit_(Panel, State, Context); - } break; - - case FileViewMode_Save: - { - - } break; - } - } - } - } - ui_EndList(&State->Interface); - } - ui_PopLayout(&State->Interface, MakeString("FileView Layout")); -} - - -#define FOLDHAUS_PANEL_FILE_VIEW_H -#endif // FOLDHAUS_PANEL_FILE_VIEW_H \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_hierarchy.h b/src/app/editor/panels/foldhaus_panel_hierarchy.h deleted file mode 100644 index 8731660..0000000 --- a/src/app/editor/panels/foldhaus_panel_hierarchy.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// File: foldhaus_panel_hierarchy.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PANEL_HIERARCHY_H - -input_command HierarchyView_Commands[] = {{}}; -s32 HierarchyView_CommandsCount = 0; - -GSMetaTag(panel_init); -GSMetaTag(panel_type_hierarchy); -internal void -HierarchyView_Init(panel* Panel, app_state* State, context Context) -{ - -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_hierarchy); -internal void -HierarchyView_Cleanup(panel* Panel, app_state* State) -{ - -} - -PANEL_MODAL_OVERRIDE_CALLBACK(LoadAssemblyCallback) -{ - Assert(ReturningFrom->TypeIndex == PanelType_FileView); - file_view_state* FileViewState = Panel_GetStateStruct(ReturningFrom, file_view_state); - gs_file_info FileInfo = FileViewState->SelectedFile; - - LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, FileInfo.Path, GlobalLogBuffer); -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_hierarchy); -internal void -HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - gs_string TempString = PushString(State->Transient, 256); - - ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Hierarchy Layout")); - ui_BeginList(&State->Interface, MakeString("Hierarchy List"), 10, State->Assemblies.Count + 1); - { - ui_column_spec Cols[2] = { - ui_column_spec{ UIColumnSize_Fill, 0 }, - ui_column_spec{ UIColumnSize_MaxWidth, 128 } - }; - for (u32 i = 0; i < State->Assemblies.Count; i++) - { - ui_BeginRow(&State->Interface, 2, &Cols[0]); - - assembly Assembly = State->Assemblies.Values[i]; - PrintF(&TempString, "%S", Assembly.Name); - - ui_Label(&State->Interface, TempString); - if (ui_Button(&State->Interface, MakeString("X"))) - { - UnloadAssembly(i, State, Context); - } - - ui_EndRow(&State->Interface); - } - - - ui_BeginRow(&State->Interface, 2, &Cols[0]); - ui_Label(&State->Interface, MakeString(" ")); - if (ui_Button(&State->Interface, MakeString("+ Add Assembly"))) - { - panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context); - FileView_SetMode(FileBrowser, FileViewMode_Load); - Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback); - } - ui_EndRow(&State->Interface); - } - ui_EndList(&State->Interface); - ui_PopLayout(&State->Interface, MakeString("Hierarchy Layout")); -} - - -#define FOLDHAUS_PANEL_HIERARCHY_H -#endif // FOLDHAUS_PANEL_HIERARCHY_H diff --git a/src/app/editor/panels/foldhaus_panel_message_log.h b/src/app/editor/panels/foldhaus_panel_message_log.h deleted file mode 100644 index 76d7d59..0000000 --- a/src/app/editor/panels/foldhaus_panel_message_log.h +++ /dev/null @@ -1,46 +0,0 @@ -/* date = April 12th 2021 4:47 pm */ - -#ifndef FOLDHAUS_PANEL_MESSAGE_LOG_H -#define FOLDHAUS_PANEL_MESSAGE_LOG_H - -GSMetaTag(panel_init); -GSMetaTag(panel_type_file_view); -internal void -MessageLog_Init(panel* Panel, app_state* State, context Context) -{ -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_file_view); -internal void -MessageLog_Cleanup(panel* Panel, app_state* State) -{ - -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_file_view); -internal void -MessageLog_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - ui_interface* Interface = &State->Interface; - ui_widget* Layout = ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Message Log Layout")); - - ui_BeginList(Interface, MakeString("Message Log List"), 10, GlobalLogBuffer->EntriesCount); - - log_buffer_iter Iter = Log_GetIter(GlobalLogBuffer); - while (true) - { - log_entry* At = Iter.At; - ui_Label(Interface, At->String); - if (!LogIter_CanAdvance(Iter)) - { - break; - } - LogIter_Advance(&Iter); - } - ui_EndList(Interface); - - ui_PopLayout(Interface, MakeString("Message Log Layout")); -} -#endif //FOLDHAUS_PANEL_MESSAGE_LOG_H diff --git a/src/app/editor/panels/foldhaus_panel_profiler.h b/src/app/editor/panels/foldhaus_panel_profiler.h deleted file mode 100644 index c0ecd79..0000000 --- a/src/app/editor/panels/foldhaus_panel_profiler.h +++ /dev/null @@ -1,360 +0,0 @@ -// -// File: foldhaus_panel_profiler.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PANEL_PROFILER_H - -input_command ProfilerView_Commands[] = {{}}; -s32 ProfilerView_CommandsCount = 0; - -GSMetaTag(panel_init); -GSMetaTag(panel_type_profiler); -internal void -ProfilerView_Init(panel* Panel, app_state* State, context Context) -{ - -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_profiler); -internal void -ProfilerView_Cleanup(panel* Panel, app_state* State) -{ - -} - -internal void -RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, debug_frame* VisibleFrame, gs_memory_arena* Transient) -{ - rect2 Bounds = ui_LayoutRemaining(*Layout); - r32 Width = Rect2Width(Bounds); - r32 DepthHeight = 32; - - s64 FrameStartCycles = VisibleFrame->FrameStartCycles; - r32 FrameTotalCycles = (r32)(VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles); - - r32 NextThreadTop = Bounds.Max.y; - - for (s32 t = 0; t < VisibleFrame->ThreadCount; t++) - { - debug_scope_record_list ThreadCalls = VisibleFrame->ThreadCalls[t]; - - gs_string String = PushString(Transient, 256); - - r32 ThreadScopeMin = Bounds.Max.y; - - //PrintF(&String, "Thread %d", ThreadCalls.ThreadId); - //ui_Label(Interface, String, rect2{ThreadScopeMin); - - r32 Hue = (r32)(t) / (r32)(VisibleFrame->ThreadCount); - Hue += (.5f * (t % 2)); - v4 ThreadHSV = v4{ 360.0f * Hue, .5f, 1.0f, 1.0f }; - v4 ThreadRGB = HSVToRGB(ThreadHSV); - - for (s32 i = 0; i < ThreadCalls.Count; i++) - { - scope_record* Record = ThreadCalls.Calls + i; - scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash); - s64 OffsetStart = Record->StartCycles - FrameStartCycles; - s64 OffsetEnd = Record->EndCycles - FrameStartCycles; - r32 PercentStart = (r32)(OffsetStart) / FrameTotalCycles; - r32 PercentEnd = (r32)(OffsetEnd) / FrameTotalCycles; - r32 PercentWidth = PercentEnd - PercentStart; - - rect2 ScopeBounds = { - v2{0, 0}, - v2{PercentWidth * Width, DepthHeight - 4}, - }; - v2 Offset = { - Bounds.Min.x + (PercentStart * Width), - NextThreadTop - ((Record->CallDepth + 1) * DepthHeight) - }; - ScopeBounds = Rect2Translate(ScopeBounds, Offset); - ThreadScopeMin = Min(ScopeBounds.Min.y, ThreadScopeMin); - - if (Rect2Width(ScopeBounds) >= 1) - { - v4 Color = ThreadRGB; - if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos)) - { - Color = GreenV4; - - ui_BeginMousePopup(Interface, rect2{ 25, 25, 300, 57 }, LayoutDirection_TopDown, MakeString("Hover")); - { - s64 Cycles = (Record->EndCycles - Record->StartCycles); - r32 PercentFrame = (r32)(Cycles) / FrameTotalCycles; - PrintF(&String, "%S : %.2f%% frame | %dcy", - Name->Name, - PercentFrame, - Cycles); - ui_Label(Interface, String); - } - ui_EndMousePopup(Interface); - } - - ui_FillRect(Interface, ScopeBounds, Color); - ui_OutlineRect(Interface, ScopeBounds, 1, BlackV4); - } - } - - NextThreadTop = ThreadScopeMin; - } -} - -internal void -RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, debug_frame* VisibleFrame, gs_memory_arena* Memory) -{ - char Backbuffer[256]; - gs_string String = MakeString(Backbuffer, 0, 256); - - ui_column_spec ColumnWidths[] = { - { UIColumnSize_Fixed, 256 }, - { UIColumnSize_Fixed, 128 }, - { UIColumnSize_Fixed, 128 }, - { UIColumnSize_Fixed, 128 }, - { UIColumnSize_Fixed, 128 }}; - ui_BeginRow(Interface, 5, &ColumnWidths[0]); - { - ui_Label(Interface, MakeString("Procedure")); - ui_Label(Interface, MakeString("% Frame")); - ui_Label(Interface, MakeString("Seconds")); - ui_Label(Interface, MakeString("Cycles")); - ui_Label(Interface, MakeString("Calls")); - } - ui_EndRow(Interface); - - s32 CountedScopes = 0; - for (s32 n = 0; n < VisibleFrame->ScopeNamesMax; n++) - { - scope_name NameEntry = VisibleFrame->ScopeNamesHash[n]; - if (NameEntry.Hash != 0) - { - CountedScopes += 1; - } - } - - ui_BeginList(Interface, MakeString("Scope List"), 10, CountedScopes); - ui_BeginRow(Interface, 5, &ColumnWidths[0]); - 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); - ui_Label(Interface, String); - - PrintF(&String, "%f%%", CollatedRecord->PercentFrameTime); - ui_Label(Interface, String); - - PrintF(&String, "%fs", CollatedRecord->TotalSeconds); - ui_Label(Interface, String); - - PrintF(&String, "%dcy", CollatedRecord->TotalCycles); - ui_Label(Interface, String); - - PrintF(&String, "%d", CollatedRecord->CallCount); - ui_Label(Interface, String); - } - } - ui_EndRow(Interface); - ui_EndList(Interface); -} - -struct mem_amt -{ - u64 OrigSize; - r64 Size; - char* Units; -}; - -internal mem_amt -GetMemAmt (u64 BytesCount) -{ - mem_amt Result = {}; - Result.OrigSize = BytesCount; - Result.Size = (r64)BytesCount; - Result.Units = "bytes"; - - u32 i = 0; - char* UnitList[] = { "kb", "mb", "gb", "tb" }; - while (Result.Size > 1024) { - Result.Size /= 1024.0; - Result.Units = UnitList[i++]; - } - - return Result; -} - -internal void -RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state* State, context Context, gs_memory_arena* Memory) -{ - gs_debug_allocations_list* DA = Context.ThreadContext.Allocator.DEBUGAllocList; - - gs_string TempString = PushString(State->Transient, 256); - - mem_amt MemFootprint = GetMemAmt(DA->AllocationsSizeTotal); - u64 AllocCount = DA->AllocationsCount; - - PrintF(&TempString, "Total Memory Size: %.2f %s | Allocations: %lld", MemFootprint.Size, MemFootprint.Units, AllocCount); - ui_Label(Interface, TempString); - - ui_column_spec ColumnWidths[] = { - { UIColumnSize_Fill, 0 }, - { UIColumnSize_Fixed,256 }, - }; - ui_BeginRow(Interface, 2, &ColumnWidths[0]); - { - ui_Label(Interface, MakeString("Location")); - ui_Label(Interface, MakeString("Alloc Size")); - } - ui_EndRow(Interface); - - ui_BeginList(Interface, MakeString("Alloc List"), 10, DA->AllocationsCount); - ui_BeginRow(Interface, 2, &ColumnWidths[0]); - - for (gs_debug_memory_allocation* A = DA->Root; - A && A->Next != 0; - A = A->Next) - { - gs_const_string Str = ConstString(A->Loc.File); - u64 LastSlash = FindLastFromSet(Str, "\\/"); - gs_const_string JustFileName = Substring(Str, LastSlash + 1, Str.Length); - PrintF(&TempString, "%s:%s(%d)", JustFileName.Str, A->Loc.Function, A->Loc.Line); - ui_Label(Interface, TempString); - - mem_amt Amt = GetMemAmt(A->Size); - - PrintF(&TempString, "%.2f %s", Amt.Size, Amt.Units); - ui_Label(Interface, TempString); - } - ui_EndRow(Interface); - ui_EndList(Interface); -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_profiler); -internal void -ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - gs_memory_arena* Memory = State->Transient; - gs_string String = PushString(Memory, 256); - - v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 }; - - r32 FrameListHeight = 64; - rect2 FrameListBounds, ProcListBounds; - RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds); - rect2 FrameListInner = RectInset(FrameListBounds, 4); - - s32 FramesToDisplay = DEBUG_FRAME_COUNT; - if (FramesToDisplay != 0) - { - r32 SingleFrameStep = Rect2Width(FrameListInner) / FramesToDisplay; - r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2); - - ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4); - if (MouseButtonHeldDown(Context.Mouse.LeftButtonState)) - { - if (PointIsInRect(FrameListBounds, Context.Mouse.Pos)) - { - v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos); - s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep); - if (ClosestFrameIndex >= 0 && ClosestFrameIndex < FramesToDisplay) - { - GlobalDebugServices->RecordFrames = false; - GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex; - } - } - } - - rect2 FrameBounds = MakeRect2MinDim(FrameListInner.Min, v2{SingleFrameWidth, Rect2Height(FrameListInner)}); - for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++) - { - rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep); - s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F); - if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; } - v4 Color = FrameColors[Clamp(0, FramesAgo, 3)]; - ui_FillRect(&State->Interface, PositionedFrameBounds, Color); - } - } - - ui_widget* Layout = ui_PushLayout(&State->Interface, ProcListBounds, LayoutDirection_TopDown, MakeString("Profiler Layout")); - - debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices); - if (VisibleFrame) - { - ui_BeginRow(&State->Interface, 4); - { - s64 FrameStartCycles = VisibleFrame->FrameStartCycles; - s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles; - u32 CurrentDebugFrame = GlobalDebugServices->CurrentDebugFrame - 1; - PrintF(&String, "Frame %d", CurrentDebugFrame); - ui_Label(&State->Interface, String); - - PrintF(&String, "Total Cycles: %lld", FrameTotalCycles); - ui_Label(&State->Interface, String); - - // NOTE(NAME): Skipping a space for aesthetic reasons, not functional, and could - // be removed, or used for something else - ui_ReserveBounds(&State->Interface, Layout, true); - - if (ui_Button(&State->Interface, MakeString("Resume Recording"))) - { - GlobalDebugServices->RecordFrames = true; - } - } - ui_EndRow(&State->Interface); - } - - ui_BeginRow(&State->Interface, 8); - { - if (ui_Button(&State->Interface, MakeString("Profiler"))) - { - GlobalDebugServices->Interface.FrameView = DebugUI_Profiler; - } - if (ui_Button(&State->Interface, MakeString("List View"))) - { - GlobalDebugServices->Interface.FrameView = DebugUI_ScopeList; - } - if (ui_Button(&State->Interface, MakeString("Memory"))) - { - GlobalDebugServices->Interface.FrameView = DebugUI_MemoryView; - } - } - ui_EndRow(&State->Interface); - - switch (GlobalDebugServices->Interface.FrameView) - { - case DebugUI_Profiler: - { - if (VisibleFrame) - { - RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory); - } - }break; - - case DebugUI_ScopeList: - { - if (VisibleFrame) - { - RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory); - } - }break; - - case DebugUI_MemoryView: - { - RenderProfiler_MemoryView(&State->Interface, Layout, State, Context, Memory); - }break; - - InvalidDefaultCase; - } - - ui_PopLayout(&State->Interface, MakeString("Profiler Layout")); -} - - -#define FOLDHAUS_PANEL_PROFILER_H -#endif // FOLDHAUS_PANEL_PROFILER_H diff --git a/src/app/editor/panels/foldhaus_panel_sculpture_view.h b/src/app/editor/panels/foldhaus_panel_sculpture_view.h deleted file mode 100644 index 474d5ca..0000000 --- a/src/app/editor/panels/foldhaus_panel_sculpture_view.h +++ /dev/null @@ -1,244 +0,0 @@ -// -// File: foldhaus_panel_sculpture_view.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PANEL_SCULPTURE_VIEW_H - -// Definitions - -#define PIXEL_TO_WORLD_SCALE 0.01f - -// - -struct sculpture_view_panel_state -{ - camera Camera; -}; - -// 3D Mouse View - -OPERATION_STATE_DEF(mouse_rotate_view_operation_state) -{ - v4 CameraStartPos; - camera* Camera; -}; - -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 = M44RotationX(-TotalDeltaPos.y * PIXEL_TO_WORLD_SCALE); - m44 YRotation = M44RotationY(TotalDeltaPos.x * PIXEL_TO_WORLD_SCALE); - m44 Combined = XRotation * YRotation; - - OpState->Camera->Position = (Combined * OpState->CameraStartPos).xyz; -} - -FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -input_command MouseRotateViewCommands [] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, End3DViewMouseRotate}, -}; - -FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate) -{ - sculpture_view_panel_state* PanelState = Panel_GetStateStruct(Panel, sculpture_view_panel_state); - - operation_mode* RotateViewMode = ActivateOperationModeWithCommands(&State->Modes, MouseRotateViewCommands, Update3DViewMouseRotate); - mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode, - &State->Modes, - mouse_rotate_view_operation_state); - OpState->CameraStartPos = ToV4Point(PanelState->Camera.Position); - OpState->Camera = &PanelState->Camera; -} - -// ---------------- - -GSMetaTag(panel_commands); -GSMetaTag(panel_type_sculpture_view); -global input_command SculptureView_Commands[] = { - { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate }, -}; -global s32 SculptureView_CommandsCount = 1; - -GSMetaTag(panel_init); -GSMetaTag(panel_type_sculpture_view); -internal void -SculptureView_Init(panel* Panel, app_state* State, context Context) -{ - sculpture_view_panel_state* PanelState = PushStruct(&State->Permanent, sculpture_view_panel_state); - - PanelState->Camera.FieldOfView = 45.0f; - PanelState->Camera.AspectRatio = RectAspectRatio(State->WindowBounds); - PanelState->Camera.Near = .1f; - PanelState->Camera.Far = 800.0f; - PanelState->Camera.Position = v3{0, 0, 400}; - PanelState->Camera.LookAt = v3{0, 0, 0}; - - Panel->StateMemory = StructToData(PanelState, sculpture_view_panel_state); -} - -GSMetaTag(panel_cleanup); -GSMetaTag(panel_type_sculpture_view); -internal void -SculptureView_Cleanup(panel* Panel, app_state* State) -{ - -} - - -struct draw_leds_job_data -{ - v4 CameraPosition; - led_buffer LedBuffer; - s32 StartIndex; - s32 OnePastLastIndex; - render_quad_batch_constructor* Batch; - quad_batch_constructor_reserved_range BatchReservedRange; - r32 LEDHalfWidth; -}; - -internal void -DrawLedsInBuffer(led_buffer LedBuffer, s32 StartIndex, s32 OnePastLastIndex, render_quad_batch_constructor* Batch, quad_batch_constructor_reserved_range ReservedRange, r32 LedHalfWidth) -{ - s32 TrisUsed = 0; - - v4 P0_In = v4{-LedHalfWidth, -LedHalfWidth, 0, 1}; - v4 P1_In = v4{LedHalfWidth, -LedHalfWidth, 0, 1}; - v4 P2_In = v4{LedHalfWidth, LedHalfWidth, 0, 1}; - v4 P3_In = v4{-LedHalfWidth, LedHalfWidth, 0, 1}; - - v2 UV0 = v2{0, 0}; - v2 UV1 = v2{1, 0}; - v2 UV2 = v2{1, 1}; - v2 UV3 = v2{0, 1}; - - Assert(OnePastLastIndex <= (s32)LedBuffer.LedCount); - for (s32 LedIndex = StartIndex; LedIndex < OnePastLastIndex; LedIndex++) - { - pixel PixelColor = LedBuffer.Colors[LedIndex]; - v4 Color = v4{PixelColor.R / 255.f, PixelColor.G / 255.f, PixelColor.B / 255.f, 1.0f}; - - v4 Position = LedBuffer.Positions[LedIndex]; - v4 PositionOffset = ToV4Vec(Position.xyz); - v4 P0 = P0_In + PositionOffset; - v4 P1 = P1_In + PositionOffset; - v4 P2 = P2_In + PositionOffset; - v4 P3 = P3_In + PositionOffset; - - SetTri3DInBatch(Batch, ReservedRange.Start + TrisUsed++, P0, P1, P2, UV0, UV1, UV2, Color, Color, Color); - SetTri3DInBatch(Batch, ReservedRange.Start + TrisUsed++, P0, P2, P3, UV0, UV2, UV3, Color, Color, Color); - } -} - -internal void -DrawLEDsInBufferRangeJob (gs_thread_context Context, gs_data JobData) -{ - DEBUG_TRACK_FUNCTION; - draw_leds_job_data* Data = (draw_leds_job_data*)JobData.Memory; - DrawLedsInBuffer(Data->LedBuffer, Data->StartIndex, Data->OnePastLastIndex, Data->Batch, Data->BatchReservedRange, Data->LEDHalfWidth); -} - -internal void -DrawQuad(render_command_buffer* RenderBuffer, v4 C, r32 Rad, v4 Color) -{ - v4 P0 = C + v4{-Rad,-Rad,0,0}; - v4 P1 = C + v4{ Rad,-Rad,0,0}; - v4 P2 = C + v4{ Rad,Rad,0,0}; - v4 P3 = C + v4{ -Rad,Rad,0,0}; - PushRenderQuad3D(RenderBuffer, P0, P1, P2, P3, Color); -} - -internal v2 -SculptureView_WorldToScreenPosition(v4 WorldPosition, camera Camera, rect2 PanelBounds) -{ - v2 Result = {0}; - - r32 PanelW = Rect2Width(PanelBounds); - r32 PanelH = Rect2Height(PanelBounds); - - m44 Matrix = GetCameraPerspectiveProjectionMatrix(Camera) * GetCameraModelViewMatrix(Camera); - v4 WorldPos = Matrix * WorldPosition; - - // this is the Perspective Divide - v2 ProjectedPos = WorldPos.xy / WorldPos.w; - - // Projection gets us in a range [-1, 1], and we want [0, width] - ProjectedPos.x = ((ProjectedPos.x / 2) * PanelW) + (PanelW / 2); - ProjectedPos.y = ((ProjectedPos.y / 2) * PanelH) + (PanelH / 2); - - Result = ProjectedPos + PanelBounds.Min; - return Result; -} - -GSMetaTag(panel_render); -GSMetaTag(panel_type_sculpture_view); -internal void -SculptureView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -{ - DEBUG_TRACK_SCOPE(RenderSculpture); - sculpture_view_panel_state* PanelState = Panel_GetStateStruct(Panel, sculpture_view_panel_state); - PanelState->Camera.AspectRatio = RectAspectRatio(PanelBounds); - - PushRenderPerspective(RenderBuffer, PanelBounds, PanelState->Camera); - - u32 MaxLEDsPerJob = 2048; - render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal); - - u32 FocusPixel = 100; - - for (u32 BufferIndex = 0; BufferIndex < State->LedSystem.BuffersCount; BufferIndex++) - { - led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, BufferIndex); - u32 JobsNeeded = U32DivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob); - u32 NextLEDIndex = 0; - for (u32 Job = 0; Job < JobsNeeded; Job++) - { - gs_data Data = PushSize(State->Transient, sizeof(draw_leds_job_data)); - draw_leds_job_data* JobData = (draw_leds_job_data*)Data.Memory; - JobData->LedBuffer = *LedBuffer; - JobData->StartIndex = NextLEDIndex; - JobData->OnePastLastIndex = Min(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount); - s32 JobLedCount = JobData->OnePastLastIndex - JobData->StartIndex; - JobData->Batch = &RenderLEDsBatch; - JobData->BatchReservedRange = ReserveRangeInQuadConstructor(JobData->Batch, JobLedCount * 2); - JobData->LEDHalfWidth = .5f; - JobData->CameraPosition = ToV4Point(PanelState->Camera.Position); -#if 1 - Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, (thread_proc*)DrawLEDsInBufferRangeJob, Data, ConstString("Sculpture Draw LEDS")); -#else - DrawLedsInBuffer(JobData->LedBuffer, JobData->StartIndex, JobData->OnePastLastIndex, JobData->Batch, JobData->BatchReservedRange, JobData->LEDHalfWidth); -#endif - NextLEDIndex = JobData->OnePastLastIndex; - } - } - - // TODO(Peter): I don't like the fact that setting an orthographic view inside a panel render function - // needs to relyon the window bounds rather than the panel bounds. Ideally the panel only needs to know where - // itself is, and nothing else. - PushRenderOrthographic(RenderBuffer, State->WindowBounds); - if (State->Assemblies.Count > 0) - { - assembly Assembly = State->Assemblies.Values[0]; - led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, Assembly.LedBufferIndex); - - v4 LedPosition = LedBuffer->Positions[FocusPixel]; - v2 LedOnScreenPosition = SculptureView_WorldToScreenPosition(LedPosition, PanelState->Camera, PanelBounds); - - gs_string Tempgs_string = PushString(State->Transient, 256); - PrintF(&Tempgs_string, "Hot Id: %u, ZIndex: %u | Active Id: %u", State->Interface.HotWidget.Id, - State->Interface.HotWidget.ZIndex,State->Interface.ActiveWidget.Id); - DrawString(RenderBuffer, Tempgs_string, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4, -1, GreenV4); - - } - Context.GeneralWorkQueue->CompleteQueueWork(Context.GeneralWorkQueue, Context.ThreadContext); -} - -#define FOLDHAUS_PANEL_SCULPTURE_VIEW_H -#endif // FOLDHAUS_PANEL_SCULPTURE_VIEW_H \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_types.cpp b/src/app/editor/panels/foldhaus_panel_types.cpp deleted file mode 100644 index db28c35..0000000 --- a/src/app/editor/panels/foldhaus_panel_types.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// -// File: foldhaus_panel_types.cpp -// Author: Peter Slattery -// Creation Date: 2020-10-17 -// -#ifndef FOLDHAUS_PANEL_TYPES_CPP -global s32 GlobalPanelDefsCount = 8; -global panel_definition GlobalPanelDefs[] = { - { "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount }, - { "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount }, - { "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands, AnimationTimeline_CommandsCount }, - { "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount }, - { "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount }, - { "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount }, - { "Assembly Debug", 14, AssemblyDebug_Init, AssemblyDebug_Cleanup, AssemblyDebug_Render, 0, 0 }, - { "Message Log", 11, MessageLog_Init, MessageLog_Cleanup, MessageLog_Render, 0, 0 }, -}; -#define FOLDHAUS_PANEL_TYPES_CPP -#endif // FOLDHAUS_PANEL_TYPES_CPP \ No newline at end of file diff --git a/src/app/editor/panels/foldhaus_panel_types.h b/src/app/editor/panels/foldhaus_panel_types.h deleted file mode 100644 index 559bc43..0000000 --- a/src/app/editor/panels/foldhaus_panel_types.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// File: foldhaus_panel_types.h -// Author: Peter Slattery -// Creation Date: 2020-10-17 -// -#ifndef FOLDHAUS_PANEL_TYPES_H -enum panel_type { - PanelType_FileView, - PanelType_SculptureView, - PanelType_AnimationTimeline, - PanelType_DMXView, - PanelType_HierarchyView, - PanelType_ProfilerView, - PanelType_AssemblyDebug, - PanelType_MessageLog -}; -#define FOLDHAUS_PANEL_TYPES_H -#endif // FOLDHAUS_PANEL_TYPES_H \ No newline at end of file diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h deleted file mode 100644 index f0011f2..0000000 --- a/src/app/engine/animation/foldhaus_animation.h +++ /dev/null @@ -1,843 +0,0 @@ -// -// File: foldhaus_animation.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_ANIMATION - -#define ANIMATION_PROC(name) void name(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -typedef ANIMATION_PROC(animation_proc); - -struct frame_range -{ - s32 Min; - s32 Max; -}; - -struct animation_pattern_handle -{ - s32 IndexPlusOne; -}; - -// NOTE(pjs): An animation block is a time range paired with an -// animation_pattern (see below). While a timeline's current time -// is within the range of a block, that particular block's animation -// will run -struct animation_block -{ - frame_range Range; - animation_pattern_handle AnimationProcHandle; - u32 Layer; -}; - -struct animation_block_array -{ - u32* Generations; - animation_block* Values; - u32 Count; - u32 CountMax; -}; - -enum blend_mode -{ - BlendMode_Overwrite, - BlendMode_Add, - BlendMode_Multiply, - BlendMode_Count, -}; - -// TODO(pjs): This really doesn't belong here -global gs_string BlendModeStrings[] = { - MakeString("Overwrite"), - MakeString("Add"), - MakeString("Multiply"), - MakeString("Count"), -}; - -struct anim_layer -{ - gs_string Name; - blend_mode BlendMode; -}; - -struct anim_layer_array -{ - anim_layer* Values; - u32 Count; - u32 CountMax; -}; - -// NOTE(pjs): An animation is a stack of layers, each of which -// is a timeline of animation blocks. -struct animation -{ - gs_string Name; - - anim_layer_array Layers; - animation_block_array Blocks_; - - frame_range PlayableRange; - - // The information / path to the file where this animation is to be saved / where it is loaded from - gs_file_info FileInfo; -}; - -struct animation_handle -{ - s32 Index; -}; - -struct animation_handle_array -{ - u32 Count; - animation_handle* Handles; -}; - -internal animation_handle InvalidAnimHandle () { return { -1 }; } -internal bool IsValid (animation_handle H) { return H.Index >= 0; } -internal void Clear (animation_handle* H) { H->Index = -1; } -internal bool AnimHandlesAreEqual (animation_handle A, animation_handle B) -{ - return A.Index == B.Index; -} - -struct animation_array -{ - animation* Values; - u32 Count; - u32 CountMax; -}; - -struct animation_layer_frame -{ - animation_block Hot; - bool HasHot; - - animation_block NextHot; - bool HasNextHot; - - r32 NextHotOpacity; - - blend_mode BlendMode; -}; - -// NOTE(pjs): This is an evaluated frame - across all layers in an -// animation, these are the blocks that need to be run -struct animation_frame -{ - animation_layer_frame* Layers; - u32 LayersCount; -}; - -enum animation_repeat_mode -{ - AnimationRepeat_Single, - AnimationRepeat_Loop, - AnimationRepeat_Invalid, -}; - -global gs_const_string AnimationRepeatModeStrings[] = { - ConstString("Repeat Single"), - ConstString("Loop"), - ConstString("Invalid"), -}; - -struct animation_fade_group -{ - animation_handle From; - animation_handle To; - r32 FadeElapsed; - r32 FadeDuration; -}; - -#define ANIMATION_SYSTEM_LAYERS_MAX 128 -#define ANIMATION_SYSTEM_BLOCKS_MAX 128 -struct animation_system -{ - gs_memory_arena* Storage; - animation_array Animations; - - animation_repeat_mode RepeatMode; - animation_handle_array Playlist; - u32 PlaylistAt; - r32 PlaylistFadeTime; - - // NOTE(Peter): The frame currently being displayed/processed. you - // can see which frame you're on by looking at the time slider on the timeline - // panel - animation_fade_group ActiveFadeGroup; - - r32 SecondsOnCurrentFrame; - s32 CurrentFrame; - s32 LastUpdatedFrame; - r32 SecondsPerFrame; - b32 TimelineShouldAdvance; - u32 UpdatesThisFrame; - - // Settings - bool Multithreaded; -}; - -// NOTE(pjs): A Pattern is a named procedure which can be used as -// an element of an animation. Patterns are sequenced on a timeline -// and blended via layers to create an animation -struct animation_pattern -{ - char* Name; - s32 NameLength; - animation_proc* Proc; - bool Multithreaded; -}; - -struct animation_pattern_array -{ - animation_pattern* Values; - u32 Count; - u32 CountMax; -}; - -// Serialization - -enum animation_field -{ - AnimField_FileIdent, - AnimField_AnimName, - AnimField_LayersCount, - AnimField_BlocksCount, - - AnimField_PlayableRange, - AnimField_PlayableRangeMin, - AnimField_PlayableRangeMax, - - AnimField_LayersArray, - AnimField_Layer, - AnimField_LayerName, - AnimField_LayerBlendMode, - - AnimField_BlocksArray, - AnimField_Block, - AnimField_BlockFrameRange, - AnimField_BlockFrameRangeMin, - AnimField_BlockFrameRangeMax, - AnimField_BlockLayerIndex, - AnimField_BlockAnimName, - - AnimField_Count, -}; - -global gs_const_string AnimationFieldStrings[] = { - ConstString("lumenarium_animation_file"), // AnimField_FileIdent - ConstString("animation_name"),// AnimField_AnimName - ConstString("layers_count"),// AnimField_LayersCount - ConstString("blocks_count"),// AnimField_BlocksCount - - ConstString("playable_range"),// AnimField_PlayableRange - ConstString("min"),// AnimField_PlayableRangeMin - ConstString("max"),// AnimField_PlayableRangeMax - - ConstString("layers"),// AnimField_LayersArray - ConstString("layer"),// AnimField_Layer - ConstString("name"),// AnimField_LayerName - ConstString("blend"),// AnimField_LayerBlendMode - - ConstString("blocks"),// AnimField_BlocksArray - ConstString("block"),// AnimField_Block - ConstString("frame_range"),// AnimField_BlockFrameRange - ConstString("min"),// AnimField_BlockFrameRangeMin - ConstString("max"),// AnimField_BlockFrameRangeMax - ConstString("layer_index"),// AnimField_BlockLayerIndex - ConstString("animation_name"),// AnimField_BlockAnimName -}; - - -////////////////////////// -// -// Patterns List - -internal animation_pattern_array -Patterns_Create(gs_memory_arena* Arena, s32 CountMax) -{ - animation_pattern_array Result = {0}; - Result.CountMax = CountMax; - Result.Values = PushArray(Arena, animation_pattern, Result.CountMax); - return Result; -} - -#define PATTERN_MULTITHREADED true -#define PATTERN_SINGLETHREADED false - -#define Patterns_PushPattern(array, proc, multithread) \ -Patterns_PushPattern_((array), (proc), Stringify(proc), sizeof(Stringify(proc)) - 1, (multithread)) - -internal void -Patterns_PushPattern_(animation_pattern_array* Array, animation_proc* Proc, char* Name, u32 NameLength, bool Multithreaded) -{ - Assert(Array->Count < Array->CountMax); - - animation_pattern Pattern = {0}; - Pattern.Name = Name; - Pattern.NameLength = NameLength; - Pattern.Proc = Proc; - Pattern.Multithreaded = Multithreaded; - - Array->Values[Array->Count++] = Pattern; -} - -internal animation_pattern_handle -Patterns_IndexToHandle(s32 Index) -{ - animation_pattern_handle Result = {}; - Result.IndexPlusOne = Index + 1; - return Result; -} - -internal bool -IsValid(animation_pattern_handle Handle) -{ - bool Result = Handle.IndexPlusOne > 0; - return Result; -} - -internal animation_pattern -Patterns_GetPattern(animation_pattern_array Patterns, animation_pattern_handle Handle) -{ - animation_pattern Result = {0}; - if (Handle.IndexPlusOne > 0) - { - u32 Index = Handle.IndexPlusOne - 1; - Assert(Index < Patterns.Count); - Result = Patterns.Values[Index]; - } - return Result; -} - -////////////////////////// -// -// Anim Block Array - -internal animation_block_array -AnimBlockArray_Create(gs_memory_arena* Storage, u32 CountMax) -{ - animation_block_array Result = {0}; - Result.CountMax = Max(CountMax, 32); - Result.Values = PushArray(Storage, animation_block, Result.CountMax); - Result.Generations = PushArray(Storage, u32, Result.CountMax); - return Result; -} - -internal handle -AnimBlockArray_Push(animation_block_array* Array, animation_block Value) -{ - Assert(Array->Count < Array->CountMax); - handle Result = {0}; - Result.Index = Array->Count++; - // NOTE(pjs): pre-increment so that generation 0 is always invalid - Result.Generation = ++Array->Generations[Result.Index]; - - Array->Values[Result.Index] = Value; - - return Result; -} - -internal void -AnimBlockArray_Remove(animation_block_array* Array, handle Handle) -{ - Assert(Handle.Index < Array->Count); - Assert(Handle_IsValid(Handle)); - Array->Generations[Handle.Index]++; -} - -internal void -AnimBlockArray_RemoveAt(animation_block_array* Array, u32 Index) -{ - Assert(Index < Array->Count); - - handle Handle = {}; - Handle.Index = Index; - Handle.Generation = Array->Generations[Index]; - AnimBlockArray_Remove(Array, Handle); -} - -////////////////////////// -// -// Anim Layers Array - -internal anim_layer_array -AnimLayerArray_Create(gs_memory_arena* Storage, u32 CountMax) -{ - anim_layer_array Result = {0}; - Result.CountMax = Max(CountMax, 32); - Result.Values = PushArray(Storage, anim_layer, Result.CountMax); - return Result; -} - -internal u32 -AnimLayerArray_Push(anim_layer_array* Array, anim_layer Value) -{ - Assert(Array->Count < Array->CountMax); - u32 Index = Array->Count++; - Array->Values[Index] = Value; - return Index; -} - -internal void -AnimLayerArray_Remove(anim_layer_array* Array, u32 Index) -{ - Assert(Index < Array->Count); - for (u32 i = Index; i < Array->Count - 1; i++) - { - Array->Values[i] = Array->Values[i + 1]; - } -} - -////////////////////////// -// -// Animation Array - -internal animation_array -AnimationArray_Create(gs_memory_arena* Storage, u32 CountMax) -{ - animation_array Result = {0}; - Result.CountMax = CountMax; - Result.Values = PushArray(Storage, animation, Result.CountMax); - return Result; -} - -internal animation_handle -AnimationArray_Push(animation_array* Array, animation Value) -{ - Assert(Array->Count < Array->CountMax); - animation_handle Result = {0}; - Result.Index = Array->Count++; - Array->Values[Result.Index] = Value; - return Result; -} - -internal animation* -AnimationArray_Get(animation_array Array, animation_handle Handle) -{ - DEBUG_TRACK_FUNCTION; - - animation* Result = 0; - if (IsValid(Handle) && Handle.Index < (s32)Array.Count) - { - Result = Array.Values + Handle.Index; - } - return Result; -} - -internal animation* -AnimationArray_GetSafe(animation_array Array, animation_handle Handle) -{ - Assert(IsValid(Handle)); - Assert(Handle.Index < (s32)Array.Count); - return AnimationArray_Get(Array, Handle); -} - -////////////////////////// -// -// Animation - -typedef struct animation_desc -{ - u32 NameSize; - char* Name; - - u32 LayersCount; - u32 BlocksCount; - - u32 MinFrames; - u32 MaxFrames; -} animation_desc; - -internal animation -Animation_Create(animation_desc Desc, animation_system* System) -{ - animation Result = {}; - u32 NameLen = Desc.NameSize; - if (Desc.Name) - { - NameLen = Max(CStringLength(Desc.Name), NameLen); - Result.Name = PushStringF(System->Storage, NameLen, "%s", Desc.Name); - } else { - Result.Name = PushStringF(System->Storage, NameLen, "[New Animation]"); - } - - Result.Layers = AnimLayerArray_Create(System->Storage, Desc.LayersCount); - Result.Blocks_ = AnimBlockArray_Create(System->Storage, Desc.BlocksCount); - Result.PlayableRange.Min = Desc.MinFrames; - Result.PlayableRange.Max = Desc.MaxFrames; - return Result; -} - -internal handle -Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, animation_pattern_handle AnimationProcHandle, u32 LayerIndex) -{ - Assert(LayerIndex < Animation->Layers.Count); - - animation_block NewBlock = {0}; - NewBlock.Range.Min = StartFrame; - NewBlock.Range.Max = EndFrame; - NewBlock.AnimationProcHandle = AnimationProcHandle; - NewBlock.Layer = LayerIndex; - - handle Handle = AnimBlockArray_Push(&Animation->Blocks_, NewBlock); - return Handle; -} - -internal void -Animation_RemoveBlock(animation* Animation, handle AnimHandle) -{ - AnimBlockArray_Remove(&Animation->Blocks_, AnimHandle); -} - -internal animation_block* -Animation_GetBlockFromHandle(animation* Animation, handle AnimHandle) -{ - animation_block* Result = 0; - - if (AnimHandle.Generation != 0 && - Animation->Blocks_.Generations[AnimHandle.Index] == AnimHandle.Generation) - { - Result = Animation->Blocks_.Values + AnimHandle.Index; - } - - return Result; -} - -internal u32 -Animation_AddLayer(animation* Animation, anim_layer Layer) -{ - return AnimLayerArray_Push(&Animation->Layers, Layer); -} - -internal u32 -Animation_AddLayer (animation* Animation, gs_string Name, blend_mode BlendMode, animation_system* System) -{ - anim_layer NewLayer = {0}; - NewLayer.Name = PushStringF(System->Storage, 256, "%S", Name); - NewLayer.BlendMode = BlendMode; - - return Animation_AddLayer(Animation, NewLayer); -} - -internal void -Animation_RemoveLayer (animation* Animation, u32 LayerIndex) -{ - AnimLayerArray_Remove(&Animation->Layers, LayerIndex); - for (u32 i = Animation->Blocks_.Count - 1; i >= 0; i--) - { - animation_block* Block = Animation->Blocks_.Values + i; - if (Block->Layer > LayerIndex) - { - Block->Layer -= 1; - } - else if (Block->Layer == LayerIndex) - { - AnimBlockArray_RemoveAt(&Animation->Blocks_, i); - } - } -} - -////////////////////////// -// -// - -internal u32 -SecondsToFrames(r32 Seconds, animation_system System) -{ - u32 Result = Seconds * (1.0f / System.SecondsPerFrame); - return Result; -} - -inline frame_range -FrameRange_Overlap(frame_range A, frame_range B) -{ - frame_range Result = {}; - -} - -inline bool -FrameIsInRange(frame_range Range, s32 Frame) -{ - bool Result = (Frame >= Range.Min) && (Frame <= Range.Max); - return Result; -} - -internal u32 -GetFrameCount(frame_range Range) -{ - u32 Result = (u32)Max(0, Range.Max - Range.Min); - return Result; -} - -internal r32 -FrameToPercentRange(s32 Frame, frame_range Range) -{ - r32 Result = (r32)(Frame - Range.Min); - Result = Result / GetFrameCount(Range); - return Result; -} - -internal s32 -PercentToFrameInRange(r32 Percent, frame_range Range) -{ - s32 Result = Range.Min + (s32)(Percent * GetFrameCount(Range)); - return Result; -} - -internal s32 -ClampFrameToRange(s32 Frame, frame_range Range) -{ - s32 Result = Frame; - if (Result < Range.Min) - { - Result = Range.Min; - } - else if (Result > Range.Max) - { - Result = Range.Max; - } - return Result; -} - -// Blocks - -// Layers - -// Fade Group - -internal bool -AnimationFadeGroup_ShouldRender (animation_fade_group FadeGroup) -{ - return IsValid(FadeGroup.From); -} - -internal void -AnimationFadeGroup_Advance(animation_fade_group* Group) -{ - Group->From = Group->To; - Clear(&Group->To); - Group->FadeElapsed = 0; - Group->FadeDuration = 0; -} - -internal void -AnimationFadeGroup_Update(animation_fade_group* Group, r32 DeltaTime) -{ - if (IsValid(Group->To)) - { - r32 FadeBefore = Group->FadeElapsed; - Group->FadeElapsed += DeltaTime; - - if (Group->FadeElapsed >= Group->FadeDuration) - { - AnimationFadeGroup_Advance(Group); - } - } -} - -internal void -AnimationFadeGroup_FadeTo(animation_fade_group* Group, animation_handle To, r32 Duration) -{ - if (IsValid(Group->From)) - { - // complete current fade if there is one in progress - if (IsValid(Group->To)) - { - AnimationFadeGroup_Advance(Group); - } - - Group->To = To; - Group->FadeDuration = Duration; - } - else - { - Group->From = To; - } -} - -// System - -struct animation_system_desc -{ - gs_memory_arena* Storage; - u32 AnimArrayCount; - r32 SecondsPerFrame; -}; - -internal animation_system -AnimationSystem_Init(animation_system_desc Desc) -{ - animation_system Result = {}; - Result.Storage = Desc.Storage; - Result.Animations = AnimationArray_Create(Result.Storage, Desc.AnimArrayCount); - Result.SecondsPerFrame = Desc.SecondsPerFrame; - - Clear(&Result.ActiveFadeGroup.From); - Clear(&Result.ActiveFadeGroup.To); - Result.ActiveFadeGroup.FadeElapsed = 0; - - // Settings - Result.Multithreaded = false; - - return Result; -} - -internal animation* -AnimationSystem_GetActiveAnimation(animation_system* System) -{ - return AnimationArray_Get(System->Animations, System->ActiveFadeGroup.From); -} - -internal animation_frame -AnimationSystem_CalculateAnimationFrame(animation_system* System, - animation* Animation, - gs_memory_arena* Arena) -{ - DEBUG_TRACK_FUNCTION; - - animation_frame Result = {0}; - Result.LayersCount = Animation->Layers.Count; - Result.Layers = PushArray(Arena, animation_layer_frame, Result.LayersCount); - ZeroArray(Result.Layers, animation_layer_frame, Result.LayersCount); - - for (u32 l = 0; l < Animation->Layers.Count; l++) - { - animation_layer_frame* Layer = Result.Layers + l; - Layer->BlendMode = Animation->Layers.Values[l].BlendMode; - } - - for (u32 i = 0; i < Animation->Blocks_.Count; i++) - { - animation_block Block = Animation->Blocks_.Values[i]; - - if (FrameIsInRange(Block.Range, System->CurrentFrame)) - { - animation_layer_frame* Layer = Result.Layers + Block.Layer; - if (Layer->HasHot) - { - // NOTE(pjs): With current implementation, we don't allow - // animations to hvae more than 2 concurrent blocks in the - // timeline - Assert(!Layer->HasNextHot); - - // NOTE(pjs): Make sure that Hot comes before NextHot - if (Layer->Hot.Range.Min < Block.Range.Min) - { - Layer->NextHot = Block; - } - else - { - Layer->NextHot = Layer->Hot; - Layer->Hot = Block; - } - Layer->HasNextHot = true; - - frame_range BlendRange = {}; - BlendRange.Min = Layer->NextHot.Range.Min; - BlendRange.Max = Layer->Hot.Range.Max; - Layer->NextHotOpacity = FrameToPercentRange(System->CurrentFrame, BlendRange); - } - else - { - Layer->Hot = Block; - Layer->NextHotOpacity = 0.0f; - Layer->HasHot = true; - } - } - } - - return Result; -} - -internal void -AnimationSystem_Update(animation_system* System, r32 DeltaTime) -{ - if (!System->TimelineShouldAdvance) { return; } - if (!AnimationFadeGroup_ShouldRender(System->ActiveFadeGroup)) { return; } - - System->UpdatesThisFrame = 0; - - AnimationFadeGroup_Update(&System->ActiveFadeGroup, DeltaTime); - - animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System); - if (ActiveAnim) - { - System->SecondsOnCurrentFrame += DeltaTime; - while (System->SecondsOnCurrentFrame > System->SecondsPerFrame) - { - System->CurrentFrame += 1; - System->SecondsOnCurrentFrame -= System->SecondsPerFrame; - System->UpdatesThisFrame += 1; - } - - // Loop back to the beginning - if (System->CurrentFrame > ActiveAnim->PlayableRange.Max) - { - // NOTE(PS): There's no long term reason why this needs to be true - // but I don't want to implement dealing with PlayableRanges that - // don't start at zero right now becuse there's literally no reason - // I can think of where that's useful. - Assert(ActiveAnim->PlayableRange.Min == 0); - - s32 FramesPastEnd = System->CurrentFrame; - while (FramesPastEnd > ActiveAnim->PlayableRange.Max) - { - FramesPastEnd -= ActiveAnim->PlayableRange.Max; - } - - switch (System->RepeatMode) - { - case AnimationRepeat_Single: - { - System->CurrentFrame = 0; - }break; - - case AnimationRepeat_Loop: - { - Assert(System->Playlist.Count > 0); - u32 NextIndex = System->PlaylistAt; - System->PlaylistAt = (System->PlaylistAt + 1) % System->Playlist.Count; - animation_handle Next = System->Playlist.Handles[NextIndex]; - - AnimationFadeGroup_FadeTo(&System->ActiveFadeGroup, - Next, - System->PlaylistFadeTime); - System->CurrentFrame = 0; - }break; - - InvalidDefaultCase; - } - } - } -} - -internal void -AnimationSystem_FadeToPlaylist(animation_system* System, animation_handle_array Playlist) -{ - System->Playlist = Playlist; - System->PlaylistAt = 0; - - if (System->Playlist.Count > 0) - { - AnimationFadeGroup_FadeTo(&System->ActiveFadeGroup, Playlist.Handles[0], System->PlaylistFadeTime); - } -} - -inline bool -AnimationSystem_NeedsRender(animation_system System) -{ - bool Result = (System.CurrentFrame != System.LastUpdatedFrame); - return Result; -} - -inline r32 -AnimationSystem_GetCurrentTime(animation_system System) -{ - r32 Result = System.CurrentFrame * System.SecondsPerFrame; - return Result; -} - -#define FOLDHAUS_ANIMATION -#endif // FOLDHAUS_ANIMATION \ No newline at end of file diff --git a/src/app/engine/animation/foldhaus_animation_renderer.cpp b/src/app/engine/animation/foldhaus_animation_renderer.cpp deleted file mode 100644 index 6f7d243..0000000 --- a/src/app/engine/animation/foldhaus_animation_renderer.cpp +++ /dev/null @@ -1,375 +0,0 @@ -// -// File: foldhaus_animation_renderer.cpp -// Author: Peter Slattery -// Creation Date: 2020-11-14 -// -#ifndef FOLDHAUS_ANIMATION_RENDERER_CPP - -internal pixel -LedBlend_Overwrite(pixel PixelA, pixel PixelB, u8* UserData) -{ - r32 MagB = (r32)(PixelB.R + PixelB.G + PixelB.B) / (255 * 3); - - pixel Result = {}; - Result.R = (u8)LerpR32(MagB, PixelA.R, PixelB.R); - Result.G = (u8)LerpR32(MagB, PixelA.G, PixelB.G); - Result.B = (u8)LerpR32(MagB, PixelA.B, PixelB.B); - -#if 0 - pixel Result = PixelB; - if (PixelB.R == 0 && - PixelB.G == 0 && - PixelB.B == 0) - { - Result = PixelA; - } -#endif - return Result; -} - -internal pixel -LedBlend_Lerp(pixel PixelA, pixel PixelB, u8* UserData) -{ - r32 BOpacity = *(r32*)UserData; - - pixel Result = {}; - - r32 AOpacity = 1.0f - BOpacity; - Result.R = (u8)((PixelA.R * AOpacity) + (PixelB.R * BOpacity)); - Result.G = (u8)((PixelA.G * AOpacity) + (PixelB.G * BOpacity)); - Result.B = (u8)((PixelA.B * AOpacity) + (PixelB.B * BOpacity)); - return Result; -} - -internal pixel -LedBlend_Add(pixel PixelA, pixel PixelB, u8* UserData) -{ - pixel Result = {}; - - u32 R = (u32)PixelA.R + (u32)PixelB.R; - u32 G = (u32)PixelA.G + (u32)PixelB.G; - u32 B = (u32)PixelA.B + (u32)PixelB.B; - - Result.R = (u8)Min(R, (u32)255); - Result.G = (u8)Min(G, (u32)255); - Result.B = (u8)Min(B, (u32)255); - - return Result; -} - -internal pixel -LedBlend_Multiply(pixel PixelA, pixel PixelB, u8* UserData) -{ - pixel Result = {}; - - r32 DR = (r32)PixelA.R / 255.f; - r32 DG = (r32)PixelA.G / 255.f; - r32 DB = (r32)PixelA.B / 255.f; - - r32 SR = (r32)PixelB.R / 255.f; - r32 SG = (r32)PixelB.G / 255.f; - r32 SB = (r32)PixelB.B / 255.f; - - Result.R = (u8)((DR * SR) * 255.f); - Result.G = (u8)((DG * SG) * 255.f); - Result.B = (u8)((DB * SB) * 255.f); - - return Result; -} - -internal pixel -LedBlend_Overlay(pixel PixelA, pixel PixelB, u8* UserData) -{ - pixel Result = {}; - return Result; -} - -internal led_blend_proc* -LedBlend_GetProc(blend_mode BlendMode) -{ - led_blend_proc* Result = 0; - switch (BlendMode) - { - case BlendMode_Overwrite: { Result = LedBlend_Overwrite; }break; - case BlendMode_Add: { Result = LedBlend_Add; }break; - case BlendMode_Multiply: { Result = LedBlend_Multiply; }break; - InvalidDefaultCase; - } - return Result; -} - -struct pattern_args -{ - assembly Assembly; - gs_memory_arena* Transient; - u8* UserData; -}; - -struct render_anim_to_led_buffer_job_data -{ - animation_pattern Pattern; - led_buffer Buffer; - led_buffer_range BufferRange; - pattern_args PatternArgs; - r32 SecondsIntoBlock; -}; - -internal void -AnimationSystem_RenderAnimationToLedBufferJob(gs_thread_context Context, gs_data Data) -{ - render_anim_to_led_buffer_job_data JobData = *(render_anim_to_led_buffer_job_data*)Data.Memory; - JobData.Pattern.Proc(&JobData.Buffer, - JobData.BufferRange, - JobData.PatternArgs.Assembly, - JobData.SecondsIntoBlock, - JobData.PatternArgs.Transient, - JobData.PatternArgs.UserData); -} - -#define MULTITHREAD_PATTERN_RENDERING 1 - -internal void -AnimationSystem_BeginRenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, animation_pattern_array Patterns, pattern_args PatternArgs, - context Context) -{ - DEBUG_TRACK_FUNCTION; - - u32 FramesIntoBlock = System->CurrentFrame - Block.Range.Min; - r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame; - - animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle); - Assert(Pattern.Proc); - - if (System->Multithreaded && Pattern.Multithreaded) - { - u32 JobsCount = 4; - u32 LedsPerJob = Buffer->LedCount / JobsCount; - - for (u32 i = 0; i < JobsCount; i++) - { - gs_data Data = PushSize(Context.ThreadContext.Transient, sizeof(render_anim_to_led_buffer_job_data)); - render_anim_to_led_buffer_job_data* JobData = (render_anim_to_led_buffer_job_data*)Data.Memory; - JobData->Pattern = Pattern; - JobData->Buffer = *Buffer; - JobData->BufferRange.First = LedsPerJob * i; - JobData->BufferRange.OnePastLast = LedsPerJob * (i + 1); - JobData->PatternArgs = PatternArgs; - JobData->SecondsIntoBlock = SecondsIntoBlock; - - Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, - (thread_proc*)AnimationSystem_RenderAnimationToLedBufferJob, - Data, - ConstString("Render Pattern To Buffer")); - } - } - else - { - led_buffer_range Range = {}; - Range.First = 0; - Range.OnePastLast = Buffer->LedCount; - - Pattern.Proc(Buffer, Range, PatternArgs.Assembly, SecondsIntoBlock, PatternArgs.Transient, PatternArgs.UserData); - } -} - -internal void -AnimationSystem_EndRenderBlockToLedBuffer (animation_system* System, context Context) -{ - if (System->Multithreaded) - { - Context.GeneralWorkQueue->CompleteQueueWork(Context.GeneralWorkQueue, Context.ThreadContext); - } -} - -// NOTE(pjs): This mirrors animation_layer_frame to account -// for overlapping -struct layer_led_buffer -{ - led_buffer HotBuffer; - led_buffer NextHotBuffer; -}; - -internal led_buffer -RenderAnimationToLedBuffer (animation_system* System, - pattern_args PatternArgs, - animation_frame CurrFrame, - layer_led_buffer* LayerBuffers, - led_buffer* AssemblyLedBuffer, - animation_pattern_array Patterns, - gs_memory_arena* Transient, - context Context) -{ - DEBUG_TRACK_FUNCTION; - - led_buffer AccBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient); - - // Create the LayerLEDBuffers - for (u32 Layer = 0; Layer < CurrFrame.LayersCount; Layer++) - { - layer_led_buffer TempBuffer = {}; - - if (CurrFrame.Layers[Layer].HasHot) - { - TempBuffer.HotBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient); - - if (CurrFrame.Layers[Layer].HasNextHot) - { - TempBuffer.NextHotBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient); - } - } - - LayerBuffers[Layer] = TempBuffer; - } - - // Render Each layer's block to the appropriate temp buffer - for (u32 Layer = 0; Layer < CurrFrame.LayersCount; Layer++) - { - animation_layer_frame LayerFrame = CurrFrame.Layers[Layer]; - if (LayerFrame.HasHot) - { - led_buffer TempBuffer = LayerBuffers[Layer].HotBuffer; - animation_block Block = LayerFrame.Hot; - AnimationSystem_BeginRenderBlockToLedBuffer(System, Block, &TempBuffer, Patterns, PatternArgs, Context); - } - - if (LayerFrame.HasNextHot) - { - led_buffer TempBuffer = LayerBuffers[Layer].NextHotBuffer; - animation_block Block = LayerFrame.NextHot; - AnimationSystem_BeginRenderBlockToLedBuffer(System, Block, &TempBuffer, Patterns, PatternArgs, Context); - } - - AnimationSystem_EndRenderBlockToLedBuffer(System, Context); - } - - // Blend together any layers that have a hot and next hot buffer - for (u32 Layer = 0; Layer < CurrFrame.LayersCount; Layer++) - { - animation_layer_frame LayerFrame = CurrFrame.Layers[Layer]; - layer_led_buffer LayerBuffer = LayerBuffers[Layer]; - if (LayerFrame.HasNextHot) - { - LedBuffer_Blend(LayerBuffer.HotBuffer, - LayerBuffer.NextHotBuffer, - &LayerBuffer.HotBuffer, - LedBlend_Lerp, - (u8*)&LayerFrame.NextHotOpacity); - } - } - - // Consolidate Temp Buffers back into AssemblyLedBuffer - // We do this in reverse order so that they go from top to bottom - for (u32 Layer = 0; Layer < CurrFrame.LayersCount; Layer++) - { - if (CurrFrame.Layers[Layer].HasHot) - { - led_blend_proc* Blend = LedBlend_GetProc(CurrFrame.Layers[Layer].BlendMode); - LedBuffer_Blend(AccBuffer, - LayerBuffers[Layer].HotBuffer, - &AccBuffer, - Blend, - 0); - } - } - - return AccBuffer; -} - -internal void -AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Assemblies, - led_system* LedSystem, - animation_pattern_array Patterns, - gs_memory_arena* Transient, - context Context, - u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - r32 FrameTime = AnimationSystem_GetCurrentTime(*System); - -#if 1 - animation_array Animations = System->Animations; - animation_fade_group FadeGroup = System->ActiveFadeGroup; - - animation* FromAnim = AnimationArray_Get(Animations, FadeGroup.From); - animation_frame FromFrame = AnimationSystem_CalculateAnimationFrame(System, FromAnim, Transient); - layer_led_buffer* FromLayerBuffers = PushArray(Transient, layer_led_buffer, FromFrame.LayersCount); - - animation* ToAnim = AnimationArray_Get(Animations, FadeGroup.To); - animation_frame ToFrame = {0}; - layer_led_buffer* ToLayerBuffers = 0; - if (ToAnim) - { - ToFrame = AnimationSystem_CalculateAnimationFrame(System, ToAnim, Transient); - ToLayerBuffers = PushArray(Transient, layer_led_buffer, ToFrame.LayersCount); - } - - for (u32 AssemblyIndex = 0; AssemblyIndex < Assemblies.Count; AssemblyIndex++) - { - assembly Assembly = Assemblies.Values[AssemblyIndex]; - led_buffer* AssemblyLedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex); - - pattern_args PatternArgs = {}; - PatternArgs.Assembly = Assembly; - PatternArgs.Transient = Transient; - PatternArgs.UserData = UserData; - - led_buffer FromBuffer = RenderAnimationToLedBuffer(System, - PatternArgs, - FromFrame, - FromLayerBuffers, - AssemblyLedBuffer, - Patterns, - Transient, - Context); - led_buffer ConsolidatedBuffer = FromBuffer; - - if (ToAnim) { - led_buffer ToBuffer = RenderAnimationToLedBuffer(System, - PatternArgs, - ToFrame, - ToLayerBuffers, - AssemblyLedBuffer, - Patterns, - Transient, - Context); - - r32 BlendPercent = FadeGroup.FadeElapsed / FadeGroup.FadeDuration; - LedBuffer_Blend(FromBuffer, ToBuffer, &ConsolidatedBuffer, LedBlend_Lerp, (u8*)&BlendPercent); - } - - LedBuffer_Copy(ConsolidatedBuffer, AssemblyLedBuffer); - } - -#else - - animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System); - animation_frame CurrFrame = AnimationSystem_CalculateAnimationFrame(System, ActiveAnim, Transient); - - for (u32 AssemblyIndex = 0; AssemblyIndex < Assemblies.Count; AssemblyIndex++) - { - assembly Assembly = Assemblies.Values[AssemblyIndex]; - led_buffer* AssemblyLedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex); - - pattern_args PatternArgs = {}; - PatternArgs.Assembly = Assembly; - PatternArgs.Transient = Transient; - PatternArgs.UserData = UserData; - - led_buffer AccBuffer = RenderAnimationToLedBuffer(System, - PatternArgs, - CurrFrame, - LayerBuffers, - AssemblyLedBuffer, - Patterns, - Transient); - LedBuffer_Copy(AccBuffer, AssemblyLedBuffer); - } - -#endif - - System->LastUpdatedFrame = System->CurrentFrame; -} - -#define FOLDHAUS_ANIMATION_RENDERER_CPP -#endif // FOLDHAUS_ANIMATION_RENDERER_CPP \ No newline at end of file diff --git a/src/app/engine/animation/foldhaus_animation_serializer.cpp b/src/app/engine/animation/foldhaus_animation_serializer.cpp deleted file mode 100644 index 55a4422..0000000 --- a/src/app/engine/animation/foldhaus_animation_serializer.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// -// File: foldhaus_animation_serializer.cpp -// Author: Peter Slattery -// Creation Date: 2020-10-04 -// -#ifndef FOLDHAUS_ANIMATION_SERIALIZER_CPP - -internal gs_string -AnimSerializer_Serialize(animation Anim, animation_pattern_array Patterns, gs_memory_arena* Arena) -{ - serializer Serializer = {0}; - Serializer.String = PushString(Arena, 4096); - Serializer.Identifiers = AnimationFieldStrings; - Serializer.IdentifiersCount = AnimField_Count; - - Serializer_WriteF(&Serializer, "%S;\n", AnimationFieldStrings[AnimField_FileIdent]); - Serializer_WriteStringValue(&Serializer, AnimField_AnimName, Anim.Name.ConstString); - Serializer_WriteValue(&Serializer, AnimField_LayersCount, Anim.Layers.Count); - Serializer_WriteValue(&Serializer, AnimField_BlocksCount, Anim.Blocks_.Count); - - Serializer_OpenStruct(&Serializer, AnimField_PlayableRange); - { - Serializer_WriteValue(&Serializer, AnimField_PlayableRangeMin, (u32)Anim.PlayableRange.Min); - Serializer_WriteValue(&Serializer, AnimField_PlayableRangeMax, (u32)Anim.PlayableRange.Max); - } - Serializer_CloseStruct(&Serializer); - - Serializer_OpenStruct(&Serializer, AnimField_LayersArray); - for (u32 i = 0; i < Anim.Layers.Count; i++) - { - anim_layer LayerAt = Anim.Layers.Values[i]; - Serializer_OpenStruct(&Serializer, AnimField_Layer); - { - Serializer_WriteStringValue(&Serializer, AnimField_LayerName, LayerAt.Name.ConstString); - Serializer_WriteStringValue(&Serializer, AnimField_LayerBlendMode, BlendModeStrings[LayerAt.BlendMode].ConstString); - } - Serializer_CloseStruct(&Serializer); - } - Serializer_CloseStruct(&Serializer); - - - Serializer_OpenStruct(&Serializer, AnimField_BlocksArray); - for (u32 i = 0; i < Anim.Blocks_.Count; i++) - { - // TODO(pjs): Handle free'd animation blocks - animation_block AnimationBlockAt = Anim.Blocks_.Values[i]; - - animation_pattern Animation = Patterns_GetPattern(Patterns, AnimationBlockAt.AnimationProcHandle); - - Serializer_OpenStruct(&Serializer, AnimField_Block); - { - Serializer_OpenStruct(&Serializer, AnimField_BlockFrameRange); - { - Serializer_WriteValue(&Serializer, AnimField_BlockFrameRangeMin, (u32)AnimationBlockAt.Range.Min); - Serializer_WriteValue(&Serializer, AnimField_BlockFrameRangeMax, (u32)AnimationBlockAt.Range.Max); - } - Serializer_CloseStruct(&Serializer); - - Serializer_WriteValue(&Serializer, AnimField_BlockLayerIndex, AnimationBlockAt.Layer); - Serializer_WriteStringValue(&Serializer, AnimField_BlockAnimName, ConstString(Animation.Name)); - } - Serializer_CloseStruct(&Serializer); - } - Serializer_CloseStruct(&Serializer); - - return Serializer.String; -} - -internal animation -AnimParser_Parse(gs_string File, gs_memory_arena* Arena, animation_pattern_array AnimPatterns) -{ - animation Result = {0}; - - parser Parser = {0}; - Parser.String = File; - Parser.At = Parser.String.Str; - Parser.Identifiers = AnimationFieldStrings; - Parser.IdentifiersCount = AnimField_Count; - Parser.Arena = Arena; - - if (Parser_ReadString(&Parser, AnimationFieldStrings[AnimField_FileIdent])) - { - Result.Name = Parser_ReadStringValue(&Parser, AnimField_AnimName); - - u32 LayersNeeded = Parser_ReadU32Value(&Parser, AnimField_LayersCount); - u32 BlocksNeeded = Parser_ReadU32Value(&Parser, AnimField_BlocksCount); - Result.Layers = AnimLayerArray_Create(Arena, LayersNeeded); - Result.Blocks_ = AnimBlockArray_Create(Arena, BlocksNeeded); - - if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange)) - { - Result.PlayableRange.Min = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMin); - Result.PlayableRange.Max = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMax); - - if (Parser_ReadCloseStruct(&Parser)) - { - // TODO(pjs): Error - } - } - else - { - // TODO(pjs): Error - } - - if (Parser_ReadOpenStruct(&Parser, AnimField_LayersArray)) - { - while (!Parser_ReadCloseStruct(&Parser)) - { - anim_layer Layer = {0}; - if (Parser_ReadOpenStruct(&Parser, AnimField_Layer)) - { - Layer.Name = Parser_ReadStringValue(&Parser, AnimField_LayerName); - - gs_string BlendModeName = Parser_ReadStringValue(&Parser, AnimField_LayerBlendMode); - for (u32 i = 0; i < BlendMode_Count; i++) - { - if (StringsEqual(BlendModeName, BlendModeStrings[i])) - { - Layer.BlendMode = (blend_mode)i; - break; - } - } - - if (Parser_ReadCloseStruct(&Parser)) - { - Animation_AddLayer(&Result, Layer); - } - else - { - // TODO(pjs): Error - } - } - } - } - - if (Parser_ReadOpenStruct(&Parser, AnimField_BlocksArray)) - { - while(!Parser_ReadCloseStruct(&Parser)) - { - animation_block Block = {0}; - - if (Parser_ReadOpenStruct(&Parser, AnimField_Block)) - { - if (Parser_ReadOpenStruct(&Parser, AnimField_BlockFrameRange)) - { - Block.Range.Min = Parser_ReadU32Value(&Parser, AnimField_BlockFrameRangeMin); - Block.Range.Max = Parser_ReadU32Value(&Parser, AnimField_BlockFrameRangeMax); - - Parser_ReadCloseStruct(&Parser); - } - else - { - // TODO(pjs): Error - } - - Block.Layer = Parser_ReadU32Value(&Parser, AnimField_BlockLayerIndex); - - // TODO(pjs): AnimName -> Animation Proc Handle - gs_string AnimName = Parser_ReadStringValue(&Parser, AnimField_BlockAnimName); - Block.AnimationProcHandle = {0}; - for (u32 i = 0; i < AnimPatterns.Count; i++) - { - animation_pattern Pattern = AnimPatterns.Values[i]; - if (StringEqualsCharArray(AnimName.ConstString, Pattern.Name, Pattern.NameLength)) - { - Block.AnimationProcHandle = Patterns_IndexToHandle(i); - break; - } - } - Assert(IsValid(Block.AnimationProcHandle)); - if (Parser_ReadCloseStruct(&Parser)) - { - AnimBlockArray_Push(&Result.Blocks_, Block); - } - else - { - // TODO(pjs): Error - } - } - } - } - } - return Result; -} -internal animation -AnimParser_Parse(gs_data File, gs_memory_arena* Arena, animation_pattern_array AnimPatterns) -{ - gs_string FileString = MakeString((char*)File.Memory, File.Size); - return AnimParser_Parse(FileString, Arena, AnimPatterns); -} - -internal animation_handle -AnimationSystem_LoadAnimationFromFile(animation_system* System, animation_pattern_array AnimPatterns, context Context, gs_const_string FilePath) -{ - animation_handle NewAnimHandle = InvalidAnimHandle(); - gs_file AnimFile = ReadEntireFile(Context.ThreadContext.FileHandler, FilePath); - if (AnimFile.Size > 0) - { - animation NewAnim = AnimParser_Parse(AnimFile.Data, System->Storage, AnimPatterns); - NewAnim.FileInfo = AnimFile.FileInfo; - NewAnim.FileInfo.Path = PushStringF(System->Storage, AnimFile.FileInfo.Path.Length, "%S", AnimFile.FileInfo.Path).ConstString; - NewAnimHandle = AnimationArray_Push(&System->Animations, NewAnim); - } - return NewAnimHandle; -} -#define FOLDHAUS_ANIMATION_SERIALIZER_CPP -#endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP \ No newline at end of file diff --git a/src/app/engine/artnet/artnet.h b/src/app/engine/artnet/artnet.h deleted file mode 100644 index 88a7725..0000000 --- a/src/app/engine/artnet/artnet.h +++ /dev/null @@ -1,10 +0,0 @@ -// -// File: artnet.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -/* For future artnet implementation */ -#ifndef ARTNET_H - -#define ARTNET_H -#endif // ARTNET_H diff --git a/src/app/engine/assembly/foldhaus_assembly.cpp b/src/app/engine/assembly/foldhaus_assembly.cpp deleted file mode 100644 index 0e383f0..0000000 --- a/src/app/engine/assembly/foldhaus_assembly.cpp +++ /dev/null @@ -1,283 +0,0 @@ -// -// File: foldhaus_assembly.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_ASSEMBLY_CPP - -/////////////////////////// -// -// Assembly Array -// -/////////////////////////// - -internal assembly_array -AssemblyArray_Create(u32 CountMax, gs_memory_arena* Storage) -{ - assembly_array Result = {0}; - Result.CountMax = CountMax; - Result.Values = PushArray(Storage, assembly, Result.CountMax); - return Result; -} - -internal u32 -AssemblyArray_Push(assembly_array* Array, assembly Assembly) -{ - Assert(Array->Count < Array->CountMax); - u32 Index = Array->Count++; - Array->Values[Index] = Assembly; - Array->Values[Index].AssemblyIndex = Index; - return Index; -} - -internal assembly* -AssemblyArray_Take(assembly_array* Array) -{ - u32 Index = AssemblyArray_Push(Array, {}); - assembly* Result = Array->Values + Index; - return Result; -} - -internal void -AssemblyArray_RemoveAt(assembly_array* Array, u32 Index) -{ - u32 LastAssemblyIndex = --Array->Count; - Array->Values[Index] = Array->Values[LastAssemblyIndex]; -} - -typedef bool assembly_array_filter_proc(assembly A); -bool AssemblyFilter_OutputsViaSACN(assembly A) { return A.OutputMode == NetworkProtocol_SACN; } -bool AssemblyFilter_OutputsViaUART(assembly A) { return A.OutputMode == NetworkProtocol_UART; } - -internal assembly_array -AssemblyArray_Filter(assembly_array Array, assembly_array_filter_proc* Filter, gs_memory_arena* Storage) -{ - assembly_array Result = AssemblyArray_Create(Array.Count, Storage); - - for (u32 i = 0; i < Array.Count; i++) - { - assembly At = Array.Values[i]; - if (Filter(At)) - { - AssemblyArray_Push(&Result, At); - } - } - - return Result; -} - -/////////////////////////// -// -// LedSystem -// -/////////////////////////// - -internal led_system -LedSystem_Create(gs_allocator PlatformMemory, u32 BuffersMax) -{ - led_system Result = {}; - Result.PlatformMemory = PlatformMemory; - // TODO(Peter): Since we have access to PlatformMemory, just realloc Buffers when we fill it up - Result.BuffersCountMax = BuffersMax; - Result.Buffers = AllocArray(PlatformMemory, led_buffer, Result.BuffersCountMax, "led system"); - return Result; -} - -internal u32 -LedSystemTakeFreeBuffer(led_system* System, u32 LedCount) -{ - s32 Result = -1; - - if (System->BuffersCount < System->BuffersCountMax) - { - Result = System->BuffersCount++; - } - else - { - // NOTE(Peter): Look for a buffer that's flagged as empty - for (u32 i = 0; i < System->BuffersCount; i++) - { - if (System->Buffers[i].LedCount == 0 - && System->Buffers[i].Colors == 0 - && System->Buffers[i].Positions == 0) - { - Result = i; - break; - } - } - Assert(Result >= 0); // NOTE(Peter): We ran out of room for led buffers - } - - led_buffer* Buffer = &System->Buffers[Result]; - Buffer->A = MemoryArenaCreate(KB(16),Bytes(8),System->PlatformMemory,0,0,"Led Buffer Arena"); - Buffer->LedCount = LedCount; - Buffer->Colors = PushArray(&Buffer->A, pixel, Buffer->LedCount); - Buffer->Positions = PushArray(&Buffer->A, v4, Buffer->LedCount); - - System->LedsCountTotal += LedCount; - - return (u32)Result; -} - -internal void -LedSystemFreeBuffer(led_system* System, u32 BufferIndex) -{ - Assert(BufferIndex < System->BuffersCountMax); - led_buffer* Buffer = &System->Buffers[BufferIndex]; - MemoryArenaFree(&Buffer->A); - System->LedsCountTotal -= Buffer->LedCount; - *Buffer = {}; -} - -internal void -LedBufferSetLed(led_buffer* Buffer, u32 Led, v4 Position) -{ - Assert(Led < Buffer->LedCount); - Buffer->Positions[Led] = Position; -} - -internal u32 -Assembly_ConstructStrip(assembly* Assembly, led_buffer* LedBuffer, v2_strip* StripAt, strip_gen_data GenData, v4 RootPosition, u32 LedStartIndex, u32 LedLUTStartIndex) -{ - u32 LedsAdded = 0; - - switch (GenData.Method) - { - case StripGeneration_InterpolatePoints: - { - strip_gen_interpolate_points InterpPoints = GenData.InterpolatePoints; - v4 WS_StripStart = RootPosition + ToV4Point(InterpPoints.StartPosition * Assembly->Scale); - v4 WS_StripEnd = RootPosition + ToV4Point(InterpPoints.EndPosition * Assembly->Scale); - - v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)InterpPoints.LedCount; - for (u32 Step = 0; Step < InterpPoints.LedCount; Step++) - { - s32 LedIndex = LedStartIndex + LedsAdded++; - v4 LedPosition = WS_StripStart + (SingleStep * Step); - LedBufferSetLed(LedBuffer, LedIndex, LedPosition); - StripAt->LedLUT[Step + LedLUTStartIndex] = LedIndex; - } - }break; - - case StripGeneration_Sequence: - { - strip_gen_sequence Sequence = GenData.Sequence; - for (u32 i = 0; i < Sequence.ElementsCount; i++) - { - strip_gen_data SegmentGenData = Sequence.Elements[i]; - LedsAdded += Assembly_ConstructStrip(Assembly, LedBuffer, StripAt, SegmentGenData, RootPosition, LedStartIndex + LedsAdded, LedsAdded); - } - }break; - - InvalidDefaultCase; - } - - return LedsAdded; -} - -internal void -ConstructAssemblyFromDefinition (assembly* Assembly, led_system* LedSystem) -{ - Assembly->LedBufferIndex = LedSystemTakeFreeBuffer(LedSystem, Assembly->LedCountTotal); - led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex); - - v4 RootPosition = ToV4Vec(Assembly->Center); - - // Add Leds - u32 LedsAdded = 0; - for (u32 StripIdx = 0; StripIdx < Assembly->StripCount; StripIdx++) - { - v2_strip* StripAt = &Assembly->Strips[StripIdx]; - StripAt->LedLUT = PushArray(&Assembly->Arena, u32, StripAt->LedCount); - - strip_gen_data GenData = StripAt->GenerationData; - LedsAdded += Assembly_ConstructStrip(Assembly, LedBuffer, StripAt, GenData, RootPosition, LedsAdded, 0); - } -} - -internal assembly* -LoadAssembly (assembly_array* Assemblies, led_system* LedSystem, gs_memory_arena* Scratch, context Context, gs_const_string Path, log_buffer* GlobalLog) -{ - assembly* NewAssembly = 0; - - gs_file AssemblyFile = ReadEntireFile(Context.ThreadContext.FileHandler, Path); - if (FileNoError(AssemblyFile)) - { - gs_string AssemblyFileText = MakeString((char*)AssemblyFile.Memory); - - s32 IndexOfLastSlash = FindLast(Path, '\\'); - gs_const_string FileName = Substring(Path, IndexOfLastSlash + 1, Path.Length); - - NewAssembly = AssemblyArray_Take(Assemblies); - NewAssembly->Arena = MemoryArenaCreate(MB(4), Bytes(8), Context.ThreadContext.Allocator, 0, 0, "Assembly Arena"); - - parser AssemblyParser = ParseAssemblyFile(NewAssembly, FileName, AssemblyFileText, Scratch); - if (AssemblyParser.Success) - { - ConstructAssemblyFromDefinition(NewAssembly, LedSystem); - } - else - { - MemoryArenaFree(&NewAssembly->Arena); - Assemblies->Count -= 1; - } - - for (parser_error* ErrorAt = AssemblyParser.ErrorsRoot; - ErrorAt != 0; - ErrorAt = ErrorAt->Next) - { - Log_Error(GlobalLogBuffer, ErrorAt->Message.Str); - } - - } - else - { - Log_Error(GlobalLog, "Unable to load assembly file"); - } - - return NewAssembly; -} - -internal void -UnloadAssembly (u32 AssemblyIndex, app_state* State, context Context) -{ - Assert(AssemblyIndex < State->Assemblies.Count); - assembly* Assembly = &State->Assemblies.Values[AssemblyIndex]; - LedSystemFreeBuffer(&State->LedSystem, Assembly->LedBufferIndex); - MemoryArenaFree(&Assembly->Arena); - AssemblyArray_RemoveAt(&State->Assemblies, AssemblyIndex); -} - -// Querying Assemblies - -internal led_strip_list -AssemblyStripsGetWithTagValue(assembly Assembly, gs_const_string TagName, gs_const_string TagValue, gs_memory_arena* Storage) -{ - led_strip_list Result = {0}; - // TODO(pjs): @Optimization - // We can probably come back here and do this allocation procedurally, or in buckets, or with - // a linked list. But for now, I just want to get this up and running - Result.CountMax = Assembly.StripCount; - Result.StripIndices = PushArray(Storage, u32, Result.CountMax); - - u64 NameHash = HashDJB2ToU32(StringExpand(TagName)); - u64 ValueHash = 0; - if (TagValue.Length > 0) - { - ValueHash = HashDJB2ToU32(StringExpand(TagValue)); - } - - for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++) - { - v2_strip StripAt = Assembly.Strips[StripIndex]; - if (AssemblyStrip_HasTagValue(StripAt, NameHash, ValueHash)) - { - Result.StripIndices[Result.Count++] = StripIndex; - } - } - - return Result; -} - -#define FOLDHAUS_ASSEMBLY_CPP -#endif // FOLDHAUS_ASSEMBLY_CPP \ No newline at end of file diff --git a/src/app/engine/assembly/foldhaus_assembly.h b/src/app/engine/assembly/foldhaus_assembly.h deleted file mode 100644 index b1b9db9..0000000 --- a/src/app/engine/assembly/foldhaus_assembly.h +++ /dev/null @@ -1,298 +0,0 @@ -// -// File: foldhaus_assembly.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_ASSEMBLY_H - -enum network_protocol -{ - NetworkProtocol_SACN, - NetworkProtocol_ArtNet, - NetworkProtocol_UART, - - NetworkProtocol_Count, -}; - -union pixel -{ - struct - { - u8 R; - u8 G; - u8 B; - }; - u8 Channels[3]; -}; - -struct led_buffer -{ - // NOTE(PS): This is just a tracking structure, - // that enables allocations for a particular buffer - // to occur all in contiguous memory - // and should not be pushed to after the initial - // allocation - gs_memory_arena A; - - u32 LedCount; - pixel* Colors; - v4* Positions; -}; - -struct led_buffer_range -{ - u32 First; - u32 OnePastLast; -}; - -struct led_system -{ - gs_allocator PlatformMemory; - - u32 BuffersCountMax; - u32 BuffersCount; - led_buffer* Buffers; - - u32 LedsCountTotal; -}; - -struct v2_tag -{ - u64 NameHash; - u64 ValueHash; -}; - -struct strip_sacn_addr -{ - s32 StartUniverse; - s32 StartChannel; -}; - -struct strip_uart_addr -{ - u8 Channel; - - gs_string ComPort; - // This may not be used based on the value of the parent - // assembly's NetworkPortMode field -}; - -enum strip_gen_method -{ - StripGeneration_InterpolatePoints, - StripGeneration_Sequence, - - StripGeneration_Count, -}; - -typedef struct strip_gen_data strip_gen_data; - -struct strip_gen_interpolate_points -{ - v3 StartPosition; - v3 EndPosition; - u32 LedCount; -}; - -struct strip_gen_sequence -{ - strip_gen_data* Elements; - u32 ElementsCount; -}; - -struct strip_gen_data -{ - strip_gen_method Method; - - strip_gen_interpolate_points InterpolatePoints; - strip_gen_sequence Sequence; -}; - -struct v2_strip -{ - s32 ControlBoxID; // TODO(Peter): I don't think we need this anymore - - strip_sacn_addr SACNAddr; - strip_uart_addr UARTAddr; - - strip_gen_data GenerationData; - - u32 LedCount; - u32* LedLUT; - - u32 TagsCount; - v2_tag* Tags; -}; - -struct led_strip_list -{ - u32 Count; - u32 CountMax; - u32* StripIndices; -}; - -enum network_port_mode -{ - // This enum defines the scope which contains what network - // port each address should be sent over. - - NetworkPortMode_GlobalPort, - // GlobalPort means that the port is defined in the assembly structure - - NetworkPortMode_PortPerStrip, - // PortPerStrip means that the address stored in the strip structure - // should be used, and each strip might have a different port - - NetworkPortMode_Count, -}; - -struct assembly -{ - gs_memory_arena Arena; - - u32 AssemblyIndex; - gs_string Name; - gs_string FilePath; - - r32 Scale; - v3 Center; - v3 MinLedPos, MaxLedPos; - s32 LedCountTotal; - u32 LedBufferIndex; - - u32 StripCount; - v2_strip* Strips; - - network_protocol OutputMode; - network_port_mode NetPortMode; - gs_string UARTComPort; -}; - -struct assembly_array -{ - u32 CountMax; - u32 Count; - assembly* Values; -}; - -typedef pixel led_blend_proc(pixel A, pixel B, u8* UserData); - -internal led_buffer* -LedSystemGetBuffer(led_system* System, u32 Index) -{ - led_buffer* Result = &System->Buffers[Index]; - return Result; -} - -internal void -LedBuffer_ClearToBlack(led_buffer* Buffer) -{ - for (u32 i = 0; i < Buffer->LedCount; i++) - { - Buffer->Colors[i].R = 0; - Buffer->Colors[i].G = 0; - Buffer->Colors[i].B = 0; - } -} - -internal void -LedBuffer_Copy(led_buffer From, led_buffer* To) -{ - DEBUG_TRACK_FUNCTION; - - Assert(From.LedCount == To->LedCount); - u32 LedCount = To->LedCount; - for (u32 i = 0; i < LedCount; i++) - { - To->Colors[i] = From.Colors[i]; - } -} - -internal void -LedBuffer_Blend(led_buffer A, led_buffer B, led_buffer* Dest, led_blend_proc* BlendProc, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - Assert(A.LedCount == B.LedCount); - Assert(Dest->LedCount == A.LedCount); - Assert(BlendProc); - - u32 LedCount = Dest->LedCount; - for (u32 i = 0; i < LedCount; i++) - { - pixel PA = A.Colors[i]; - pixel PB = B.Colors[i]; - Dest->Colors[i] = BlendProc(PA, PB, UserData); - } -} - -internal led_buffer -LedBuffer_CreateCopyCleared (led_buffer Buffer, gs_memory_arena* Arena) -{ - DEBUG_TRACK_FUNCTION; - - led_buffer Result = {}; - Result.LedCount = Buffer.LedCount; - Result.Positions = Buffer.Positions; - Result.Colors = PushArray(Arena, pixel, Buffer.LedCount); - LedBuffer_ClearToBlack(&Result); - return Result; -} - -internal u32 -StripGenData_CountLeds(strip_gen_data Data) -{ - u32 Result = 0; - - switch (Data.Method) - { - case StripGeneration_InterpolatePoints: - { - Result += Data.InterpolatePoints.LedCount; - }break; - - case StripGeneration_Sequence: - { - for (u32 i = 0; i < Data.Sequence.ElementsCount; i++) - { - Result += StripGenData_CountLeds(Data.Sequence.Elements[i]); - } - }break; - - InvalidDefaultCase; - } - - return Result; -} - -internal bool -AssemblyStrip_HasTagValue(v2_strip Strip, u64 NameHash, u64 ValueHash) -{ - bool Result = false; - for (u32 i = 0; i < Strip.TagsCount; i++) - { - v2_tag TagAt = Strip.Tags[i]; - if (TagAt.NameHash == NameHash) - { - // NOTE(pjs): We can pass an empty string to the Value parameter, - // and it will match all values of Tag - if (ValueHash == 0 || ValueHash == TagAt.ValueHash) - { - Result = true; - break; - } - } - } - return Result; -} - -internal bool -AssemblyStrip_HasTagValueSLOW(v2_strip Strip, char* Name, char* Value) -{ - u64 NameHash = HashDJB2ToU32(Name); - u64 ValueHash = HashDJB2ToU32(Value); - return AssemblyStrip_HasTagValue(Strip, NameHash, ValueHash); -} - -#define FOLDHAUS_ASSEMBLY_H -#endif // FOLDHAUS_ASSEMBLY_H \ No newline at end of file diff --git a/src/app/engine/assembly/foldhaus_assembly_debug.h b/src/app/engine/assembly/foldhaus_assembly_debug.h deleted file mode 100644 index ffe33ed..0000000 --- a/src/app/engine/assembly/foldhaus_assembly_debug.h +++ /dev/null @@ -1,238 +0,0 @@ -// -// File: foldhaus_assembly_debug.h -// Author: Peter Slattery -// Creation Date: 2021-01-15 -// -#ifndef FOLDHAUS_ASSEMBLY_DEBUG_H - -enum override_type -{ - ADS_Override_None, - - ADS_Override_Strip, - ADS_Override_SoloStrip, - ADS_Override_AllRed, - ADS_Override_AllGreen, - ADS_Override_AllBlue, - ADS_Override_AllOff, - ADS_Override_AllWhite, - ADS_Override_AllHue, - ADS_Override_TagWhite, - ADS_Override_TagStripWhite, - ADS_Override_ChannelWhite, - - ADS_Override_Count, -}; - -global gs_const_string OverrideTypeStrings[] = { - LitString("Override_None"), - LitString("Override_Strip"), - LitString("Override_SoloStrip" ), - LitString("Override_AllRed" ), - LitString("Override_AllGreen" ), - LitString("Override_AllBlue" ), - LitString("ADS_Override_AllOff" ), - LitString("ADS_Override_AllWhite" ), - LitString("ADS_Override_AllHue" ), - LitString("ADS_Override_TagWhite" ), - LitString("ADS_Override_TagStripWhite" ), - LitString("ADS_Override_ChannelWhite," ), - LitString("Override_Count"), -}; - -struct assembly_debug_state -{ - override_type Override; - - bool AllAssemblies; - u32 TargetAssembly; - u32 TargetStrip; - - gs_string TagName; - gs_string TagValue; - - u32 TargetHue; - pixel TargetColor; - - u32 TargetChannel; - - u8 Brightness; -}; - -internal assembly_debug_state -AssemblyDebug_Create(gs_memory_arena* Storage) -{ - assembly_debug_state Result = {}; - Result.TagName = PushString(Storage, 256); - Result.TagValue = PushString(Storage, 256); - return Result; -} - -internal void -AssemblyDebug_OverrideStripWithColor(v2_strip Strip, led_buffer LedBuffer, pixel Color) -{ - for (u32 i = 0; i < Strip.LedCount; i++) - { - u32 LedIdx = Strip.LedLUT[i]; - LedBuffer.Colors[LedIdx] = Color; - } -} - -internal void -AssemblyDebug_OverrideWithColor(assembly Assembly, led_buffer LedBuffer, pixel Color) -{ - for (u32 s = 0; s < Assembly.StripCount; s++) - { - v2_strip Strip = Assembly.Strips[s]; - AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, Color); - } -} - -internal void -AssemblyDebug_OverrideTagValueWithColor(assembly Assembly, led_buffer LedBuffer, pixel Color, gs_string TagName, gs_string TagValue) -{ - u64 NameHash = HashDJB2ToU32(StringExpand(TagName)); - u64 ValueHash = HashDJB2ToU32(StringExpand(TagValue)); - - for (u32 s = 0; s < Assembly.StripCount; s++) - { - v2_strip Strip = Assembly.Strips[s]; - if (AssemblyStrip_HasTagValue(Strip, NameHash, ValueHash)) - { - AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, Color); - } - } -} - -internal void -AssemblyDebug_OverrideOutputForAssembly(assembly_debug_state State, led_system LedSystem, - assembly Assembly) -{ - led_buffer LedBuffer = LedSystem.Buffers[Assembly.LedBufferIndex]; - - u8 V = State.Brightness; - - switch (State.Override) - { - case ADS_Override_Strip: - { - v2_strip Strip = Assembly.Strips[State.TargetStrip]; - AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, State.TargetColor); - }break; - - case ADS_Override_SoloStrip: - { - for (u32 s = 0; s < Assembly.StripCount; s++) - { - v2_strip Strip = Assembly.Strips[s]; - - pixel Color = pixel{0,0,0}; - if (s == State.TargetStrip) - { - Color = State.TargetColor; - } - - AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, Color); - } - }break; - - case ADS_Override_AllRed: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{V, 0, 0}); - }break; - - case ADS_Override_AllGreen: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, V, 0}); - }break; - - case ADS_Override_AllBlue: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, V}); - }break; - - case ADS_Override_AllOff: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0}); - }break; - - case ADS_Override_AllWhite: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{V, V, V}); - }break; - - case ADS_Override_AllHue: - { - v4 HSV = v4{(r32)State.TargetHue, 1, 1, 1}; - v4 RGB = HSVToRGB(HSV); - pixel P = V4ToRGBPixel(RGB); - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, P); - }break; - - case ADS_Override_TagWhite: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0}); - AssemblyDebug_OverrideTagValueWithColor(Assembly, LedBuffer, pixel{255, 255, 255}, State.TagName, State.TagValue); - - }break; - - case ADS_Override_TagStripWhite: - { - u64 NameHash = HashDJB2ToU32(StringExpand(State.TagName)); - u64 ValueHash = HashDJB2ToU32(StringExpand(State.TagValue)); - - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0}); - - v2_strip Strip = Assembly.Strips[State.TargetStrip]; - if (AssemblyStrip_HasTagValue(Strip, NameHash, ValueHash)) - { - AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, - pixel{255, 255, 255}); - } - }break; - - case ADS_Override_ChannelWhite: - { - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0}); - for (u32 s = 0; s < Assembly.StripCount; s++) - { - v2_strip Strip = Assembly.Strips[s]; - if (Strip.UARTAddr.Channel == State.TargetChannel) - { - AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, pixel{255, 255, 255}); - } - } - }break; - - case ADS_Override_None: - { - }break; - - InvalidDefaultCase; - } -} - -internal void -AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assemblies, led_system LedSystem) -{ - if (State.Override == ADS_Override_None) return; - State.TargetColor = pixel{255,255,255}; - - if (State.AllAssemblies) - { - for (u32 i = 0; i < Assemblies.Count; i++) - { - assembly Assembly = Assemblies.Values[i]; - AssemblyDebug_OverrideOutputForAssembly(State, LedSystem, Assembly); - } - } - else - { - assembly Assembly = Assemblies.Values[State.TargetAssembly]; - AssemblyDebug_OverrideOutputForAssembly(State, LedSystem, Assembly); - } -} - - -#define FOLDHAUS_ASSEMBLY_DEBUG_H -#endif // FOLDHAUS_ASSEMBLY_DEBUG_H \ No newline at end of file diff --git a/src/app/engine/assembly/foldhaus_assembly_parser.cpp b/src/app/engine/assembly/foldhaus_assembly_parser.cpp deleted file mode 100644 index dbeb890..0000000 --- a/src/app/engine/assembly/foldhaus_assembly_parser.cpp +++ /dev/null @@ -1,336 +0,0 @@ -// -// File: foldhaus_assembly_parser.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_ASSEMBLY_PARSER_CPP - -// TODO(pjs): This is good for meta generation -// ie. It would be great to have -// // enum ident enum prefix -// BEGIN_GEN_ENUM(assembly_field, AssemblyField_) -// // value name gen string of the value name the paired string identifier -// ADD_ENUM_VALUE(AssemblyName, DO_GEN_STRING, "assembly_name") -// ADD_ENUM_VALUE(AssemblyScale, DO_GEN_STRING, "assembly_scale") -// END_GEN_ENUM(assembly_field) - -enum assembly_field -{ - AssemblyField_AssemblyName, - AssemblyField_AssemblyScale, - AssemblyField_AssemblyCenter, - AssemblyField_LedStripCount, - AssemblyField_OutputMode, - - AssemblyField_LedStrip, - - AssemblyField_OutputSACN, - AssemblyField_SACN_StartUniverse, - AssemblyField_SACN_StartChannel, - - AssemblyField_OutputUART, - AssemblyField_UART_Channel, - AssemblyField_UART_ComPort, - - AssemblyField_PointPlacementType, - - AssemblyField_InterpolatePoints, - AssemblyField_Start, - AssemblyField_End, - AssemblyField_LedCount, - - AssemblyField_SegmentSequence, - AssemblyField_SegmentSequenceLength, - AssemblyField_Segment, - - AssemblyField_TagsCount, - AssemblyField_Tag, - AssemblyField_Name, - AssemblyField_Value, - - AssemblyField_Count, -}; - -global gs_const_string AssemblyFieldIdentifiers[] = { - ConstString("assembly_name"), // AssemblyField_AssemblyName - ConstString("assembly_scale"), // AssemblyField_AssemblyScale - ConstString("assembly_center"), // AssemblyField_AssemblyCenter - ConstString("led_strip_count"), // AssemblyField_LedStripCount - ConstString("output_mode"), // AssemblyField_OutputMode - - ConstString("led_strip"), // AssemblyField_LedStrip - - ConstString("output_sacn"), // AssemblyField_OutputSACN - ConstString("start_universe"), // AssemblyField_SACN_StartUniverse - ConstString("start_channel"), // AssemblyField_SACN_StartChannel - - ConstString("output_uart"), // AssemblyField_OutputUART - ConstString("channel"), // AssemblyField_UART_Channel - ConstString("com_port"), // AssemblyField_UART_ComPort - - ConstString("point_placement_type"), // AssemblyField_PointPlacementType - - ConstString("interpolate_points"), // AssemblyField_InterpolatePoints - ConstString("start"), // AssemblyField_Start - ConstString("end"), // AssemblyField_End - ConstString("led_count"), // AssemblyField_LedCount - - ConstString("segment_sequence"), // AssemblyField_SegmentSequence - ConstString("segment_count"), // AssemblyField_SegmentSequenceLength - ConstString("segment"), // AssemblyField_Segment - - ConstString("tags_count"), // AssemblyField_TagCount - ConstString("tag"), // AssemblyField_Tag - ConstString("name"), // AssemblyField_Name - ConstString("value"), // AssemblyField_Value -}; - -internal void -StripSetTag(v2_strip* Strip, u32 TagIndex, gs_const_string TagName, gs_const_string TagValue) -{ - Assert(TagIndex < Strip->TagsCount); - v2_tag* TagAt = &Strip->Tags[TagIndex]; - TagAt->NameHash = HashDJB2ToU32(StringExpand(TagName)); - TagAt->ValueHash = HashDJB2ToU32(StringExpand(TagValue)); -} - -internal strip_sacn_addr -AssemblyParser_ReadSACNAddr(parser* Parser, assembly Assembly) -{ - strip_sacn_addr Result = {0}; - - if (Parser_ReadOpenStruct(Parser, AssemblyField_OutputSACN)) - { - Result.StartUniverse = Parser_ReadU32Value(Parser, AssemblyField_SACN_StartUniverse); - Result.StartChannel = Parser_ReadU32Value(Parser, AssemblyField_SACN_StartChannel); - - if (!Parser_ReadCloseStruct(Parser)) - { - //TokenizerPushError(&Tokenizer, "Struct doesn't close where expected"); - } - } - - return Result; -} - -internal strip_uart_addr -AssemblyParser_ReadUARTAddr(parser* Parser, assembly Assembly) -{ - strip_uart_addr Result = {0}; - - if (Parser_ReadOpenStruct(Parser, AssemblyField_OutputUART)) - { - Result.Channel = (u8)Parser_ReadU32Value(Parser, AssemblyField_UART_Channel); - - bool HasNetPort = Parser_ReadStringValue(Parser, AssemblyField_UART_ComPort, &Result.ComPort, true); - if (Assembly.NetPortMode == NetworkPortMode_PortPerStrip && !HasNetPort) - { - Parser_PushErrorF(Parser, "NetPortMode for assembly is PortPerStrip, but this strip doesn't have an output port."); - } - - if (!Parser_ReadCloseStruct(Parser)) - { - Parser_PushErrorF(Parser, "Struct doesn't close where expected"); - } - } - - return Result; -} - -internal void -AssemblyParser_ReadTag(parser* Parser, v2_strip* StripAt, u32 TagIndex) -{ - if (Parser_ReadOpenStruct(Parser, AssemblyField_Tag)) - { - // TODO(Peter): Need to store the gs_string somewhere we can look it up for display in the interface - // right now they are stored in temp memory and won't persist - gs_string TagName = Parser_ReadStringValue(Parser, AssemblyField_Name); - gs_string TagValue = Parser_ReadStringValue(Parser, AssemblyField_Value); - StripSetTag(StripAt, TagIndex, TagName.ConstString, TagValue.ConstString); - if (!Parser_ReadCloseStruct(Parser)) - { - Parser_PushErrorF(Parser, "Tag struct doesn't close where expected"); - } - } - else - { - Parser_PushErrorF(Parser, "Expected a tag struct, but none was found."); - } -} - - -internal void -AssemblyParser_ReadTagList(parser* Parser, v2_strip* StripAt, assembly* Assembly) -{ - StripAt->TagsCount = Parser_ReadU32Value(Parser, AssemblyField_TagsCount); - // NOTE(pjs): Always add one tag to the input to leave room for the assembly name - StripAt->TagsCount += 1; - StripAt->Tags = PushArray(&Assembly->Arena, v2_tag, StripAt->TagsCount); - - StripSetTag(StripAt, 0, ConstString("assembly"), Assembly->Name.ConstString); - - for (u32 Tag = 1; Tag < StripAt->TagsCount; Tag++) - { - AssemblyParser_ReadTag(Parser, StripAt, Tag); - } -} - -internal strip_gen_data AssemblyParser_ReadStripGenData(parser* Parser, assembly* Assembly); - -internal strip_gen_interpolate_points -AssemblyParser_ReadInterpolatePoints(parser* Parser) -{ - strip_gen_interpolate_points Result = {0}; - if (Parser_ReadOpenStruct(Parser, AssemblyField_InterpolatePoints)) - { - Result.StartPosition = Parser_ReadV3Value(Parser, AssemblyField_Start); - Result.EndPosition = Parser_ReadV3Value(Parser, AssemblyField_End); - Result.LedCount = Parser_ReadU32Value(Parser, AssemblyField_LedCount); - if (!Parser_ReadCloseStruct(Parser)) - { - // TODO(pjs): - } - } - else - { - // TODO(pjs): - } - return Result; -} - -internal strip_gen_sequence -AssemblyParser_ReadSequence(parser* Parser, assembly* Assembly) -{ - strip_gen_sequence Result = {0}; - if (Parser_ReadOpenStruct(Parser, AssemblyField_SegmentSequence)) - { - Result.ElementsCount = Parser_ReadU32Value(Parser, AssemblyField_SegmentSequenceLength); - Result.Elements = PushArray(&Assembly->Arena, strip_gen_data, Result.ElementsCount); - for (u32 i = 0; i < Result.ElementsCount; i++) - { - Result.Elements[i] = AssemblyParser_ReadStripGenData(Parser, Assembly); - } - if (!Parser_ReadCloseStruct(Parser)) - { - // TODO(pjs): - } - } - else - { - // TODO(pjs): - } - return Result; -} - -internal strip_gen_data -AssemblyParser_ReadStripGenData(parser* Parser, assembly* Assembly) -{ - strip_gen_data Result = {}; - - if (Parser_ReadOpenStruct(Parser, AssemblyField_Segment)) - { - gs_string PointPlacementType = Parser_ReadStringValue(Parser, AssemblyField_PointPlacementType); - - // TODO(pjs): We want to store enum strings in some unified way - // :EnumStringsGen - if (StringsEqual(PointPlacementType.ConstString, ConstString("InterpolatePoints"))) - { - Result.Method = StripGeneration_InterpolatePoints; - Result.InterpolatePoints = AssemblyParser_ReadInterpolatePoints(Parser); - } - else if (StringsEqual(PointPlacementType.ConstString, - ConstString("SegmentSequence"))) - { - Result.Method = StripGeneration_Sequence; - Result.Sequence = AssemblyParser_ReadSequence(Parser, Assembly); - } - else - { - Parser_PushErrorF(Parser, "Incorrect Point Placement Type found for segment"); - } - - if (!Parser_ReadCloseStruct(Parser)) - { - Parser_PushErrorF(Parser, "Strip Gen Data did not close the struct where expected"); - } - } - - return Result; -} - -internal parser -ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileText, gs_memory_arena* Transient) -{ - Assembly->LedCountTotal = 0; - - parser Parser = {0}; - Parser.FileName = FileName; - Parser.String = FileText; - Parser.Identifiers = &AssemblyFieldIdentifiers[0]; - Parser.IdentifiersCount = AssemblyField_Count; - Parser.At = Parser.String.Str; - Parser.LineStart = Parser.At; - Parser.Arena = &Assembly->Arena; - Parser.Transient = Transient; - Parser.Success = true; - - Assembly->Name = Parser_ReadStringValue(&Parser, AssemblyField_AssemblyName); - Assembly->Scale = Parser_ReadR32Value(&Parser, AssemblyField_AssemblyScale); - Assembly->Center = Parser_ReadV3Value(&Parser, AssemblyField_AssemblyCenter) * Assembly->Scale; - Assembly->StripCount = Parser_ReadU32Value(&Parser, AssemblyField_LedStripCount); - Assembly->Strips = PushArray(&Assembly->Arena, v2_strip, Assembly->StripCount); - - gs_string OutputModeString = Parser_ReadStringValue(&Parser, AssemblyField_OutputMode); - if (StringsEqual(OutputModeString.ConstString, ConstString("UART"))) - { - Assembly->OutputMode = NetworkProtocol_UART; - if (Parser_ReadStringValue(&Parser, AssemblyField_UART_ComPort, &Assembly->UARTComPort, true)) - { - Assembly->NetPortMode = NetworkPortMode_GlobalPort; - } - else - { - Assembly->NetPortMode = NetworkPortMode_PortPerStrip; - } - } - else if (StringsEqual(OutputModeString.ConstString, ConstString("SACN"))) - { - Assembly->OutputMode = NetworkProtocol_SACN; - } - else - { - Parser_PushErrorF(&Parser, "Invalid output mode specified for assembly."); - Parser.Success = false; - } - - for (u32 i = 0; i < Assembly->StripCount; i++) - { - v2_strip* StripAt = Assembly->Strips + i; - if (Parser_ReadOpenStruct(&Parser, AssemblyField_LedStrip)) - { - StripAt->SACNAddr = AssemblyParser_ReadSACNAddr(&Parser, *Assembly); - StripAt->UARTAddr = AssemblyParser_ReadUARTAddr(&Parser, *Assembly); - StripAt->GenerationData = AssemblyParser_ReadStripGenData(&Parser, Assembly); - StripAt->LedCount = StripGenData_CountLeds(StripAt->GenerationData); - AssemblyParser_ReadTagList(&Parser, StripAt, Assembly); - - Assembly->LedCountTotal += StripAt->LedCount; - - if (!Parser_ReadCloseStruct(&Parser)) - { - Parser_PushErrorF(&Parser, "Strip struct doesn't close where expected"); - Parser.Success = false; - } - } - else - { - Parser_PushErrorF(&Parser, "Expected a strip struct but none was found"); - Parser.Success = false; - } - } - - return Parser; -} - -#define FOLDHAUS_ASSEMBLY_PARSER_CPP -#endif // FOLDHAUS_ASSEMBLY_PARSER_CPP \ No newline at end of file diff --git a/src/app/engine/foldhaus_addressed_data.h b/src/app/engine/foldhaus_addressed_data.h deleted file mode 100644 index e2db91e..0000000 --- a/src/app/engine/foldhaus_addressed_data.h +++ /dev/null @@ -1,108 +0,0 @@ -// -// File: foldhaus_addressed_data.h -// Author: Peter Slattery -// Creation Date: 2020-10-01 -// -// addressed_data_buffer is a generic buffer of data that also contains information -// regarding how it should be sent to a sculpture. -// This decouples the encoding step from the sending step. -// -#ifndef FOLDHAUS_ADDRESSED_DATA_H - -enum data_buffer_address_type -{ - AddressType_NetworkIP, - AddressType_ComPort, - AddressType_Invalid, -}; - -struct addressed_data_buffer -{ - union - { - struct - { - u8* Memory; - u32 MemorySize; - }; - gs_data Data; - }; - - data_buffer_address_type AddressType; - - // IP Address - platform_socket_handle SendSocket; - u32 V4SendAddress; - u32 SendPort; - - // COM - gs_const_string ComPort; - - addressed_data_buffer* Next; -}; - -struct addressed_data_buffer_list -{ - gs_memory_arena* Arena; - addressed_data_buffer* Root; - addressed_data_buffer* Head; -}; - -internal void -AddressedDataBufferList_Clear(addressed_data_buffer_list* List) -{ - List->Root = 0; - List->Head = 0; - MemoryArenaClear(List->Arena); -} - -internal addressed_data_buffer* -AddressedDataBufferList_PushEmpty(addressed_data_buffer_list* List) -{ - addressed_data_buffer* Result = PushStruct(List->Arena, addressed_data_buffer); - *Result = {0}; - Result->Next = 0; - Result->MemorySize = 0; - Result->Memory = 0; - - SLLPushOrInit(List->Root, List->Head, Result); - - return Result; -} - -internal addressed_data_buffer* -AddressedDataBufferList_Push(addressed_data_buffer_list* List, u32 BufferSize) -{ - addressed_data_buffer* Result = AddressedDataBufferList_PushEmpty(List); - Result->MemorySize = BufferSize; - Result->Memory = PushArray(List->Arena, u8, Result->MemorySize); - return Result; -} - -internal void -AddressedDataBuffer_SetNetworkAddress(addressed_data_buffer* Buffer, platform_socket_handle SendSocket, u32 V4SendAddress, u32 SendPort) -{ - Buffer->AddressType = AddressType_NetworkIP; - Buffer->SendSocket = SendSocket; - Buffer->V4SendAddress = V4SendAddress; - Buffer->SendPort = SendPort; -} - -internal void -AddressedDataBuffer_SetCOMPort(addressed_data_buffer* Buffer, gs_const_string ComPort) -{ - Buffer->AddressType = AddressType_ComPort; - Buffer->ComPort = ComPort; -} - -internal addressed_data_buffer_list -AddressedDataBufferList_Create(gs_thread_context TC) -{ - addressed_data_buffer_list Result = {}; - Result.Arena = AllocStruct(TC.Allocator, gs_memory_arena, "Addressed Data"); - *Result.Arena = MemoryArenaCreate(KB(256), Bytes(8), TC.Allocator, 0, 0, "Addressed Data Buffer List Arena"); - return Result; -} - -#define FOLDHAUS_ADDRESSED_DATA_H -#endif // FOLDHAUS_ADDRESSED_DATA_H \ No newline at end of file diff --git a/src/app/engine/foldhaus_log.h b/src/app/engine/foldhaus_log.h deleted file mode 100644 index 3d538b2..0000000 --- a/src/app/engine/foldhaus_log.h +++ /dev/null @@ -1,126 +0,0 @@ -/* date = April 12th 2021 4:25 pm */ - -#ifndef FOLDHAUS_LOG_H -#define FOLDHAUS_LOG_H - -enum log_entry_type -{ - LogEntry_Message, - LogEntry_Error, -}; - -struct log_entry -{ - log_entry_type Type; - gs_string String; -}; - -struct log_buffer -{ - gs_memory_arena* Arena; - - u64 EntriesCount; - u64 NextEntry; - log_entry* Entries; -}; - -struct log_buffer_iter -{ - log_buffer* Buffer; - u64 Start; - u64 IndexAt; - log_entry* At; -}; - -internal log_buffer -Log_Init(gs_memory_arena* A, u64 Count) -{ - log_buffer Result = {}; - Result.Arena = A; - Result.EntriesCount = Count; - Result.Entries = PushArray(A, log_entry, Result.EntriesCount); - - u64 LogStringLength = 512; - u64 LogStringBufferSize = LogStringLength * Result.EntriesCount; - char* LogStringBuffer = PushArray(A, char, LogStringBufferSize); - char* LogStringBufferAt = LogStringBuffer; - for (u32 i = 0; i < Result.EntriesCount; i++) - { - Result.Entries[i].String = MakeString(LogStringBufferAt, 0, LogStringLength); - LogStringBufferAt += LogStringLength; - } - - return Result; -} - -internal u64 -Log_GetNextIndex(log_buffer Log, u64 At) -{ - u64 Result = At + 1; - if (Result >= Log.EntriesCount) - { - Result = 0; - } - return Result; -} - -internal log_entry* -Log_TakeNextEntry(log_buffer* Log) -{ - log_entry* Result = Log->Entries + Log->NextEntry; - Log->NextEntry = Log_GetNextIndex(*Log, Log->NextEntry); - return Result; -} - -internal void -Log_PrintFVarArgs(log_buffer* Log, log_entry_type Type, char* Format, va_list Args) -{ - log_entry* NextEntry = Log_TakeNextEntry(Log); - NextEntry->String.Length = 0; - NextEntry->Type = Type; - PrintFArgsList(&NextEntry->String, Format, Args); - NullTerminate(&NextEntry->String); - -#if DEBUG - OutputDebugStringA(NextEntry->String.Str); -#endif -} - -#define Log_Message(log, fmt, ...) Log_PrintF(log, LogEntry_Message, fmt, __VA_ARGS__) -#define Log_Error(log, fmt, ...) Log_PrintF(log, LogEntry_Error, fmt, __VA_ARGS__) -internal void -Log_PrintF(log_buffer* Log, log_entry_type Type, char* Format, ...) -{ - va_list Args; - va_start(Args, Format); - Log_PrintFVarArgs(Log, Type, Format, Args); - va_end(Args); -} - -internal log_buffer_iter -Log_GetIter(log_buffer* Buffer) -{ - log_buffer_iter Result = {}; - Result.Buffer = Buffer; - Result.Start = Buffer->NextEntry; - Result.IndexAt = Result.Start; - Result.At = Result.Buffer->Entries + Result.IndexAt; - return Result; -} - -internal bool -LogIter_CanAdvance(log_buffer_iter Iter) -{ - u64 Next = Log_GetNextIndex(*Iter.Buffer, Iter.IndexAt); - bool Result = Next != Iter.Start; - return Result; -} - -internal void -LogIter_Advance(log_buffer_iter* Iter) -{ - Iter->IndexAt = Log_GetNextIndex(*Iter->Buffer, Iter->IndexAt); - Iter->At = Iter->Buffer->Entries + Iter->IndexAt; -} - -#endif //FOLDHAUS_LOG_H diff --git a/src/app/engine/foldhaus_network_ordering.h b/src/app/engine/foldhaus_network_ordering.h deleted file mode 100644 index cc9634d..0000000 --- a/src/app/engine/foldhaus_network_ordering.h +++ /dev/null @@ -1,154 +0,0 @@ -// -// File: foldhaus_network_ordering.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_NETWORK_ORDERING_H - -// Packs a u8 to a known big endian buffer -inline u8* -PackB1(u8* ptr, u8 val) -{ - *ptr = val; - return ptr + sizeof(val); -} - -//Unpacks a u8 from a known big endian buffer -inline u8 -UpackB1(const u8* ptr) -{ - return *ptr; -} - -//Packs a u8 to a known little endian buffer -inline u8* -PackL1(u8* ptr, u8 val) -{ - *ptr = val; - return ptr + sizeof(val); -} - -//Unpacks a u8 from a known little endian buffer -inline u8 -UpackL1(const u8* ptr) -{ - return *ptr; -} - -//Packs a u16 to a known big endian buffer -inline u16 -PackB2(u16 Value) -{ - u16 Result = 0; - u8* Array = (u8*)&Result; - Array[1] = (u8)(Value & 0xFF); - Array[0] = (u8)((Value & 0xFF00) >> 8); - return Result; -} - -inline u8* -PackB2(u8* ptr, u16 val) -{ - ptr[1] = (u8)(val & 0xff); - ptr[0] = (u8)((val & 0xff00) >> 8); - return ptr + sizeof(val); -} - -//Unpacks a u16 from a known big endian buffer -inline u16 -UpackB2(const u8* ptr) -{ - return (u16)(ptr[1] | ptr[0] << 8); -} - -//Packs a u16 to a known little endian buffer -inline u8* -PackL2(u8* ptr, u16 val) -{ - *((u16*)ptr) = val; - return ptr + sizeof(val); -} - -//Unpacks a u16 from a known little endian buffer -inline u16 -UpackL2(const u8* ptr) -{ - return *((u16*)ptr); -} - -//Packs a u32 to a known big endian buffer -inline u8* -PackB4(u8* ptr, u32 val) -{ - ptr[3] = (u8) (val & 0xff); - ptr[2] = (u8)((val & 0xff00) >> 8); - ptr[1] = (u8)((val & 0xff0000) >> 16); - ptr[0] = (u8)((val & 0xff000000) >> 24); - return ptr + sizeof(val); -} - -//Unpacks a u32 from a known big endian buffer -inline u32 -UpackB4(const u8* ptr) -{ - return (u32)(ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24)); -} - -//Packs a u32 to a known little endian buffer -inline u8* -PackL4(u8* ptr, u32 val) -{ - *((u32*)ptr) = val; - return ptr + sizeof(val); -} - -//Unpacks a u32 from a known little endian buffer -inline u32 -UpackL4(const u8* ptr) -{ - return *((u32*)ptr); -} - -//Packs a u64 to a known big endian buffer -inline u8* -PackB8(u8* ptr, u64 val) -{ - ptr[7] = (u8) (val & 0xff); - ptr[6] = (u8)((val & 0xff00) >> 8); - ptr[5] = (u8)((val & 0xff0000) >> 16); - ptr[4] = (u8)((val & 0xff000000) >> 24); - ptr[3] = (u8)((val & 0xff00000000) >> 32); - ptr[2] = (u8)((val & 0xff0000000000) >> 40); - ptr[1] = (u8)((val & 0xff000000000000) >> 48); - ptr[0] = (u8)((val & 0xff00000000000000) >> 56); - return ptr + sizeof(val); -} - -//Unpacks a uint64 from a known big endian buffer -inline u64 -UpackB8(const u8* ptr) -{ - return ((u64)ptr[7]) | (((u64)ptr[6]) << 8) | (((u64)ptr[5]) << 16) | - (((u64)ptr[4]) << 24) | (((u64)ptr[3]) << 32) | - (((u64)ptr[2]) << 40) | (((u64)ptr[1]) << 48) | - (((u64)ptr[0]) << 56); -} - -//Packs a u64 to a known little endian buffer -inline u8* -PackL8(u8* ptr, u64 val) -{ - *((u64*)ptr) = val; - return ptr + sizeof(val); -} - -//Unpacks a u64 from a known little endian buffer -inline u64 -UpackL8(const u8* ptr) -{ - return *((u64*)ptr); -} - - -#define FOLDHAUS_NETWORK_ORDERING_H -#endif // FOLDHAUS_NETWORK_ORDERING_H \ No newline at end of file diff --git a/src/app/engine/foldhaus_serializer.h b/src/app/engine/foldhaus_serializer.h deleted file mode 100644 index 34ac831..0000000 --- a/src/app/engine/foldhaus_serializer.h +++ /dev/null @@ -1,588 +0,0 @@ -// -// File: foldhaus_serializer.h -// Author: Peter Slattery -// Creation Date: 2020-10-09 -// -#ifndef FOLDHAUS_SERIALIZER_H - -struct serializer -{ - gs_string String; - u32 Indent; - gs_const_string* Identifiers; - u32 IdentifiersCount; -}; - -internal gs_const_string -Serializer_GetIdent(serializer* Serializer, u32 Index) -{ - gs_const_string Result = Serializer->Identifiers[Index]; - return Result; -} - -// Serializing - -internal void -Serializer_WriteIndent(serializer* Serializer) -{ - for (u32 i = 0; i < Serializer->Indent; i++) - { - AppendPrintF(&Serializer->String, " "); - } -} - -internal void -Serializer_WriteF(serializer* Serializer, char* Format, ...) -{ - Serializer_WriteIndent(Serializer); - - va_list Args; - va_start(Args, Format); - PrintFArgsList(&Serializer->String, Format, Args); - va_end(Args); -} - -internal void -Serializer_OpenStruct(serializer* Serializer, gs_const_string StructName) -{ - Serializer_WriteF(Serializer, "%S:{\n", StructName); - Serializer->Indent++; -} - -internal void -Serializer_OpenStruct(serializer* Serializer, u32 StructIdentifier) -{ - gs_const_string Ident = Serializer_GetIdent(Serializer, StructIdentifier); - Serializer_WriteF(Serializer, "%S:{\n", Ident); - Serializer->Indent++; -} - -internal void -Serializer_CloseStruct(serializer* Serializer) -{ - Serializer->Indent--; - Serializer_WriteF(Serializer, "};\n"); -} - -internal void -Serializer_WriteValue(serializer* Serializer, gs_const_string Ident, gs_const_string Value) -{ - Serializer_WriteF(Serializer, "%S: %S;\n", Ident, Value); -} - -internal void -Serializer_WriteValue(serializer* Serializer, u32 IdentIndex, gs_const_string Value) -{ - gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex); - Serializer_WriteValue(Serializer, Ident, Value); -} - -internal void -Serializer_WriteValue(serializer* Serializer, gs_const_string Ident, u32 Value) -{ - Serializer_WriteF(Serializer, "%S: %d;\n", Ident, Value); -} - -internal void -Serializer_WriteValue(serializer* Serializer, u32 IdentIndex, u32 Value) -{ - gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex); - Serializer_WriteValue(Serializer, Ident, Value); -} - -internal void -Serializer_WriteValue(serializer* Serializer, gs_const_string Ident, r32 Value) -{ - Serializer_WriteF(Serializer, "%S: %f;\n", Ident, Value); -} - -internal void -Serializer_WriteValue(serializer* Serializer, u32 IdentIndex, r32 Value) -{ - gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex); - Serializer_WriteValue(Serializer, Ident, Value); -} - -internal void -Serializer_WriteStringValue(serializer* Serializer, gs_const_string Ident, gs_const_string Value) -{ - Serializer_WriteF(Serializer, "%S: \"%S\";\n", Ident, Value); -} - -internal void -Serializer_WriteStringValue(serializer* Serializer, u32 IdentIndex, gs_const_string Value) -{ - gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex); - Serializer_WriteStringValue(Serializer, Ident, Value); -} - -internal void -Serializer_WriteV3Value(serializer* Serializer, gs_const_string Ident, v3 Value) -{ - Serializer_WriteF(Serializer, "%S: (%f, %f, %f);\n", Ident, Value.x, Value.y, Value.z); -} - -internal void -Serializer_WriteV3Value(serializer* Serializer, u32 IdentIndex, v3 Value) -{ - gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex); - Serializer_WriteV3Value(Serializer, Ident, Value); -} - -// Parsing - -struct parser_error -{ - gs_string Message; - - gs_const_string FileName; - u32 LineNumber; - - parser_error* Next; -}; - -struct parser -{ - gs_const_string FileName; - - gs_string String; - - gs_const_string* Identifiers; - u32 IdentifiersCount; - - u32 Line; - - char* LineStart; - char* At; - - gs_memory_arena* Arena; - gs_memory_arena* Transient; - - parser_error* ErrorsRoot; - parser_error* ErrorsHead; - - bool Success; -}; - -internal void -Parser_PushErrorF(parser* Parser, char* Format, ...) -{ - parser_error* Error = PushStruct(Parser->Transient, parser_error); - Error->FileName = Parser->FileName; - Error->LineNumber = Parser->Line; - - Error->Message = PushString(Parser->Transient, 1024); - PrintF(&Error->Message, "Error:\n"); - - va_list Args; - va_start(Args, Format); - PrintFArgsList(&Error->Message, Format, Args); - va_end(Args); - - AppendPrintF(&Error->Message, "\n\tFile: %S\n\tLine: %d\n", - Error->FileName, Error->LineNumber); - NullTerminate(&Error->Message); - - SLLPushOrInit(Parser->ErrorsRoot, Parser->ErrorsHead, Error); -} - -internal gs_const_string -Parser_GetIdent(parser Parser, u32 Index) -{ - gs_const_string Result = Parser.Identifiers[Index]; - return Result; -} - -internal bool -Parser_AtValidPosition(parser Parser) -{ - u64 Offset = Parser.At - Parser.String.Str; - bool Result = (Offset < Parser.String.Length); - return Result; -} - -internal void -Parser_AdvanceChar(parser* P) -{ - if (IsNewline(P->At[0])) - { - P->Line += 1; - P->LineStart = P->At + 1; - - if ((P->At[0] == '\n' && P->At[1] == '\r') || - (P->At[0] == '\r' && P->At[1] == '\n')) - { - P->At++; - P->At++; - } - else if (P->At[0] == '\n') - { - P->At++; - } - else - { - // TODO(pjs): Not sure this is actually invalid - InvalidCodePath; - } - } - else - { - P->At++; - } -} - -internal void -Parser_EatWhitespace(parser* P) -{ - while(Parser_AtValidPosition(*P) && IsNewlineOrWhitespace(P->At[0])) - { - Parser_AdvanceChar(P); - } -} - -internal void -Parser_EatToNewLine(parser* P) -{ - while(Parser_AtValidPosition(*P) && !IsNewline(P->At[0])) - { - Parser_AdvanceChar(P); - } - Parser_EatWhitespace(P); -} - -internal bool -Parser_AdvanceIfTokenEquals(parser* P, gs_const_string Value) -{ - bool Result = true; - - char* PAt = P->At; - char* VAt = Value.Str; - while (*VAt != 0) - { - if (*PAt != *VAt) - { - Result = false; - break; - } - PAt += 1; - VAt += 1; - } - - // TODO(Peter): What if the token is a subset of Value? ie. this would return true for - // T->At = hello_world and Value = hello_ - // But the next token we read would fail - - if (Result) - { - P->At = PAt; - Parser_EatWhitespace(P); - } - return Result; -} - -internal bool -Parser_AdvanceIfLineEnd(parser* P) -{ - bool Result = Parser_AdvanceIfTokenEquals(P, ConstString(";")); - return Result; -} - -internal bool -Parser_ReadString(parser* P, gs_const_string String) -{ - // string; - bool Result = Parser_AdvanceIfTokenEquals(P, String); - Result &= Parser_AdvanceIfLineEnd(P); - return Result; -} - -internal bool -Parser_ReadString(parser* P, u32 IdentIndex) -{ - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - return Parser_ReadString(P, Ident); -} - -internal bool -Parser_ReadStringValue(parser* P, gs_const_string Ident, gs_string* Output, bool ShouldNullTerminate = false) -{ - Assert(Output != 0); - - // ident: "value"; - bool Result = false; - if (Parser_AdvanceIfTokenEquals(P, Ident) && - Parser_AdvanceIfTokenEquals(P, ConstString(":")) && - Parser_AdvanceIfTokenEquals(P, ConstString("\""))) - { - gs_const_string FileString = {0}; - FileString.Str = P->At; - - while (Parser_AtValidPosition(*P) && P->At[0] != '"') - { - Parser_AdvanceChar(P); - } - - FileString.Length = P->At - FileString.Str; - if (Parser_AdvanceIfTokenEquals(P, ConstString("\"")) && - Parser_AdvanceIfLineEnd(P)) - { - u32 StringLength = FileString.Length; - if (ShouldNullTerminate) - { - StringLength += 1; - } - - Result = true; - *Output = PushStringF(P->Arena, StringLength, "%S", FileString); - if (ShouldNullTerminate) - { - NullTerminate(Output); - } - } - else - { - Parser_PushErrorF(P, "String doesn't have a closing quote, or line doesn't end with a semicolon"); - } - } - - return Result; -} - -internal bool -Parser_ReadStringValue(parser* P, u32 IdentIndex, gs_string* Result, bool ShouldNullTerminate = false) -{ - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - return Parser_ReadStringValue(P, Ident, Result, ShouldNullTerminate); -} - -internal gs_string -Parser_ReadStringValue(parser* P, gs_const_string Ident, bool ShouldNullTerminate = false) -{ - gs_string Result = {0}; - Parser_ReadStringValue(P, Ident, &Result, ShouldNullTerminate); - return Result; -} - -internal gs_string -Parser_ReadStringValue(parser* P, u32 IdentIndex, bool ShouldNullTerminate = false) -{ - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - return Parser_ReadStringValue(P, Ident, ShouldNullTerminate); -} - -internal bool -Parser_ReadOpenStruct(parser* P, gs_const_string Ident) -{ - // ident: { - bool Result = Parser_AdvanceIfTokenEquals(P, Ident); - Result &= Parser_AdvanceIfTokenEquals(P, ConstString(":")); - Result &= Parser_AdvanceIfTokenEquals(P, ConstString("{")); - return Result; -} - -internal bool -Parser_ReadOpenStruct(parser* P, u32 IdentIndex) -{ - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - return Parser_ReadOpenStruct(P, Ident); -} - -internal bool -Parser_ReadCloseStruct(parser* P) -{ - // } - bool Result = Parser_AdvanceIfTokenEquals(P, ConstString("}")); - Result &= Parser_AdvanceIfLineEnd(P); - return Result; -} - -internal bool -Parser_ReadNumberString(parser* P, gs_const_string* Output) -{ - Assert(Output != 0); - - bool Success = false; - - if (IsNumericExtended(P->At[0])) - { - char* NumStart = P->At; - while(Parser_AtValidPosition(*P) && IsNumericExtended(P->At[0])) - { - Parser_AdvanceChar(P); - } - - Output->Str = NumStart; - Output->Length = P->At - NumStart; - Success = true; - } - - return Success; -} - -internal gs_const_string -Parser_ReadNumberString(parser* P) -{ - gs_const_string Result = {0}; - Parser_ReadNumberString(P, &Result); - return Result; -} - -internal bool -Parser_ReadU32Value(parser* P, gs_const_string Ident, u32* Result) -{ - // ident: value; - bool Success = false; - - if (Parser_AdvanceIfTokenEquals(P, Ident) && - Parser_AdvanceIfTokenEquals(P, ConstString(":"))) - { - gs_const_string NumStr = Parser_ReadNumberString(P); - if (Parser_AdvanceIfLineEnd(P)) - { - *Result = (u32)ParseInt(NumStr); - Success = true; - } - else - { - Parser_PushErrorF(P, "U32 Value doesn't end with semicolon"); - } - } - - return Success; -} - -internal u32 -Parser_ReadU32Value(parser* P, gs_const_string Ident) -{ - u32 Result = 0; - Parser_ReadU32Value(P, Ident, &Result); - return Result; -} - -internal u32 -Parser_ReadU32Value(parser* P, u32 IdentIndex) -{ - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - return Parser_ReadU32Value(P, Ident); -} - -internal bool -Parser_ReadR32(parser* P, r32* Result) -{ - bool Success = false; - gs_const_string NumStr = {0}; - if (Parser_ReadNumberString(P, &NumStr)) - { - *Result = (r32)ParseFloat(NumStr); - Success = true; - } - return Success; -} - -internal r32 -Parser_ReadR32(parser* P) -{ - r32 Result = 0; - Parser_ReadR32(P, &Result); - return Result; -} - -internal bool -Parser_ReadR32Value(parser* P, gs_const_string Ident, r32* Result) -{ - // ident: value; - bool Success = false; - if (Parser_AdvanceIfTokenEquals(P, Ident) && - Parser_AdvanceIfTokenEquals(P, ConstString(":"))) - { - r32 Value = Parser_ReadR32(P); - if (Parser_AdvanceIfLineEnd(P)) - { - *Result = Value; - Success = true; - } - else - { - Parser_PushErrorF(P, "R32 Value doesn't end with semicolon"); - } - } - - return Success; -} - -internal r32 -Parser_ReadR32Value(parser* P, gs_const_string Ident) -{ - r32 Result = 0; - Parser_ReadR32Value(P, Ident, &Result); - return Result; -} - -internal r32 -Parser_ReadR32Value(parser* P, u32 IdentIndex) -{ - r32 Result = 0; - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - Parser_ReadR32Value(P, Ident, &Result); - return Result; -} - -internal bool -Parser_ReadV3Value(parser* P, gs_const_string Ident, v3* Result) -{ - Assert(Result != 0); - bool Success = false; - if (Parser_AdvanceIfTokenEquals(P, Ident) && - Parser_AdvanceIfTokenEquals(P, ConstString(":")) && - Parser_AdvanceIfTokenEquals(P, ConstString("("))) - { - r32 X = Parser_ReadR32(P); - if (!Parser_AdvanceIfTokenEquals(P, ConstString(","))) - { - Parser_PushErrorF(P, "V3 Value doesn't have comma separated values"); - } - - r32 Y = Parser_ReadR32(P); - if (!Parser_AdvanceIfTokenEquals(P, ConstString(","))) - { - Parser_PushErrorF(P, "V3 Value doesn't have comma separated values"); - } - - r32 Z = Parser_ReadR32(P); - if (Parser_AdvanceIfTokenEquals(P, ConstString(")")) && - Parser_AdvanceIfLineEnd(P)) - { - Result->x = X; - Result->y = Y; - Result->z = Z; - Success = true; - } - else - { - Parser_PushErrorF(P, "V3 Value doesn't end correctly"); - } - } - - return Success; -} - -internal v3 -Parser_ReadV3Value(parser* P, gs_const_string Ident) -{ - v3 Result = {0}; - Parser_ReadV3Value(P, Ident, &Result); - return Result; -} - -internal v3 -Parser_ReadV3Value(parser* P, u32 IdentIndex) -{ - v3 Result = {0}; - gs_const_string Ident = Parser_GetIdent(*P, IdentIndex); - Parser_ReadV3Value(P, Ident, &Result); - return Result; -} - - -#define FOLDHAUS_SERIALIZER_H -#endif // FOLDHAUS_SERIALIZER_H \ No newline at end of file diff --git a/src/app/engine/sacn/foldhaus_sacn.h b/src/app/engine/sacn/foldhaus_sacn.h deleted file mode 100644 index ae29913..0000000 --- a/src/app/engine/sacn/foldhaus_sacn.h +++ /dev/null @@ -1,411 +0,0 @@ -// -// File: sacn.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef SACN_H - -#define NETWORKINTID_INVALID -1 - -#define DEFAULT_STREAMING_ACN_PORT 5568 - -#define IP_ADDRESS_BYTES 16 -#define STARTCODE_DMX 0 - -/* - * a description of the address space being used - */ -#define PREAMBLE_SIZE_ADDR 0 -#define POSTAMBLE_SIZE_ADDR 2 -#define ACN_IDENTIFIER_ADDR 4 -#define ROOT_FLAGS_AND_LENGTH_ADDR 16 -#define ROOT_VECTOR_ADDR 18 -#define CID_ADDR 22 -#define FRAMING_FLAGS_AND_LENGTH_ADDR 38 -#define FRAMING_VECTOR_ADDR 40 -#define SOURCE_NAME_ADDR 44 -#define PRIORITY_ADDR 108 -#define RESERVED_ADDR 109 -#define SEQ_NUM_ADDR 111 -#define OPTIONS_ADDR 112 -#define UNIVERSE_ADDR 113 -#define DMP_FLAGS_AND_LENGTH_ADDR 115 -#define DMP_VECTOR_ADDR 117 -#define DMP_ADDRESS_AND_DATA_ADDR 118 -#define FIRST_PROPERTY_ADDRESS_ADDR 119 -#define ADDRESS_INC_ADDR 121 -#define PROP_COUNT_ADDR 123 -#define START_CODE_ADDR 125 -#define PROP_VALUES_ADDR (START_CODE_ADDR + 1) - -/* - * common sizes - */ -#define STREAM_HEADER_SIZE 126 -#define STREAM_BODY_SIZE 512 - -#define SOURCE_NAME_SIZE 64 -#define RLP_PREAMBLE_SIZE 16 -#define RLP_POSTAMBLE_SIZE 0 -#define ACN_IDENTIFIER_SIZE 12 - -/* - * data definitions - */ -#define ACN_IDENTIFIER "ASC-E1.17\0\0\0" -#define ROOT_VECTOR 4 -#define FRAMING_VECTOR 2 -#define DMP_VECTOR 2 -#define ADDRESS_AND_DATA_FORMAT 0xa1 -#define ADDRESS_INC 1 -#define DMP_FIRST_PROPERTY_ADDRESS_FORCE 0 -#define RESERVED_VALUE 0 - -//for support of the early draft -#define DRAFT_STREAM_HEADER_SIZE 90 -#define DRAFT_SOURCE_NAME_SIZE 32 - -//for support of the early draft -#define DRAFT_ROOT_VECTOR 3 - -const u32 VHD_MAXFLAGBYTES = 7; //The maximum amount of bytes used to pack the flags, len, and vector -const u32 VHD_MAXLEN = 0x0fffff; //The maximum packet length is 20 bytes long -const u32 VHD_MAXMINLENGTH = 4095; //The highest length that will fit in the "smallest" length pack - -//Defines for the VHD flags -const u8 VHD_L_FLAG = 0x80; -const u8 VHD_V_FLAG = 0x40; -const u8 VHD_H_FLAG = 0x20; -const u8 VHD_D_FLAG = 0x10; - -#define CID_Bytes 16 -struct cid -{ - u8 Bytes[CID_Bytes]; -}; - -struct streaming_acn -{ - platform_socket_handle SendSocket; - cid CID; - s32 SequenceIterator; -}; - -/////////////////////////////////////////////// -// -// SACN Data Header Functions -// -/////////////////////////////////////////////// - -internal void -SetStreamHeaderSequence_ (u8* Buffer, u8 Sequence, b32 Draft) -{ - DEBUG_TRACK_FUNCTION; - PackB1(Buffer + SEQ_NUM_ADDR, Sequence); -} - -internal void -VHD_PackFlags_(u8* Buffer, b32 InheritVec, b32 InheritHead, b32 InheritData) -{ - u8* Cursor = Buffer; - u8 NewByte = UpackB1(Cursor) & 0x8f; - - if (!InheritVec) { NewByte |= VHD_V_FLAG; } - if (!InheritHead) { NewByte |= VHD_H_FLAG; } - if (!InheritData) { NewByte |= VHD_D_FLAG; } - - PackB1(Cursor, NewByte); -} - -internal u8* -VHD_PackLength_(u8* Buffer, u32 Length, b32 IncludeLength) -{ - u8* Cursor = Buffer; - u32 AdjustedLength = Length; - if (IncludeLength) - { - if (Length + 1 > VHD_MAXMINLENGTH) - { - AdjustedLength += 2; - } - else - { - AdjustedLength += 1; - } - } - - // Mask out the length bits to keep flags intact - u8 NewByte = UpackB1(Cursor) & 0x70; - if (AdjustedLength > VHD_MAXMINLENGTH) - { - NewByte |= VHD_L_FLAG; - } - - u8 PackBuffer[4]; - PackB4(PackBuffer, AdjustedLength); - if (AdjustedLength <= VHD_MAXMINLENGTH) - { - NewByte |= (PackBuffer[2] & 0x0f); - Cursor = PackB1(Cursor, NewByte); - Cursor = PackB1(Cursor, PackBuffer[3]); - } - else - { - NewByte |= (PackBuffer[1] & 0x0f); - Cursor = PackB1(Cursor, PackBuffer[2]); - Cursor = PackB1(Cursor, PackBuffer[3]); - } - - return Cursor; -} - -internal cid -gs_stringToCID_ (const char* gs_string) -{ - cid Result = {}; - - const char* Src = gs_string; - u8* Dest = &Result.Bytes[0]; - b32 FirstNibble = true; - - while(*Src && (Dest - &Result.Bytes[0] < CID_Bytes)) - { - u8 Offset = 0; - if ((*Src >= 0x30) && (*Src <= 0x39)){ Offset = 0x30; } - else if ((*Src >= 0x41) && (*Src <= 0x46)) { Offset = 0x37; } - else if ((*Src >= 0x61) && (*Src <= 0x66)) { Offset = 0x66; } - - if (Offset != 0) - { - if (FirstNibble) - { - *Dest = (u8)(*Src - Offset); - *Dest <<= 4; - FirstNibble = false; - } - else - { - *Dest |= (*Src - Offset); - Dest++; - FirstNibble = true; - } - } - Src++; - } - - return Result; -} - -internal void -InitStreamHeader (u8* Buffer, s32 BufferSize, - u16 SlotCount, - u8 StartCode, - u16 Universe, - u8 Priority, - u16 Reserved, - u8 Options, - const char* SourceName, - cid CID - ) -{ - // TODO(pjs): Replace packing with gs_memory_cursor - - u8* Cursor = Buffer; - - // Preamble Size - Cursor = PackB2(Cursor, RLP_PREAMBLE_SIZE); - Cursor = PackB2(Cursor, RLP_POSTAMBLE_SIZE); - - CopyMemoryTo(ACN_IDENTIFIER, Cursor, ACN_IDENTIFIER_SIZE); - Cursor += ACN_IDENTIFIER_SIZE; - - // TODO(Peter): If you never use this anywhere else, go back and remove the parameters - VHD_PackFlags_(Cursor, false, false, false); - Cursor = VHD_PackLength_(Cursor, - STREAM_HEADER_SIZE - RLP_PREAMBLE_SIZE + SlotCount, - false); - - // root vector - Cursor = PackB4(Cursor, ROOT_VECTOR); - - // CID Pack - for (s32 i = 0; i < CID_Bytes; i++) - { - *Cursor++ = CID.Bytes[i]; - } - - VHD_PackFlags_(Cursor, false, false, false); - Cursor = VHD_PackLength_(Cursor, - STREAM_HEADER_SIZE - FRAMING_FLAGS_AND_LENGTH_ADDR + SlotCount, - false); - - // framing vector - Cursor = PackB4(Cursor, FRAMING_VECTOR); - - // framing source name - // :Check - CopyMemoryTo(SourceName, (char*)Cursor, SOURCE_NAME_SIZE); - Cursor[SOURCE_NAME_SIZE - 1] = '\0'; - Cursor += SOURCE_NAME_SIZE; - - // priority - Cursor = PackB1(Cursor, Priority); - - // reserved - Cursor = PackB2(Cursor, Reserved); - - // Sequence # is always set to 0/NONE at the beginning, but it is incremented when sending data - Cursor = PackB1(Cursor, 0); - - // Options - Cursor = PackB1(Cursor, Options); - - // Universe - Cursor = PackB2(Cursor, Universe); - - VHD_PackFlags_(Cursor, false, false, false); - Cursor = VHD_PackLength_(Cursor, - STREAM_HEADER_SIZE - DMP_FLAGS_AND_LENGTH_ADDR + SlotCount, - false); - - // DMP Vector - Cursor = PackB1(Cursor, DMP_VECTOR); - - // DMP Address and data type - Cursor = PackB1(Cursor, ADDRESS_AND_DATA_FORMAT); - - // DMP first property address - Cursor = PackB1(Cursor, 0); - - // DMP Address Increment - Cursor = PackB1(Cursor, ADDRESS_INC); - - // Property Value Count -- Includes one byte for start code - Cursor = PackB2(Cursor, SlotCount + 1); - - Cursor = PackB1(Cursor, StartCode); - - Assert(Cursor - Buffer == STREAM_HEADER_SIZE); - -} - -// -// New SACN -// - -internal streaming_acn -SACN_Initialize (context Context) -{ - streaming_acn SACN = {}; - - s32 Multicast_TimeToLive = 20; - SACN.SendSocket = Context.PlatformGetSocketHandle(Multicast_TimeToLive); - SACN.CID = gs_stringToCID_ ("{67F9D986-544E-4abb-8986-D5F79382586C}"); - - return SACN; -} - -internal void -SACN_Cleanup(streaming_acn* SACN, context Context) -{ -} - -internal void -SACN_UpdateSequence (streaming_acn* SACN) -{ - // Never use 0 after the first one - if (++SACN->SequenceIterator == 0) - { - ++SACN->SequenceIterator; - } -} - -internal void -SACN_PrepareBufferHeader (s32 Universe, u8* Buffer, s32 BufferSize, s32 SizeReservedForHeader, streaming_acn SACN) -{ - Assert(SizeReservedForHeader == STREAM_HEADER_SIZE); - Assert(Buffer && BufferSize > 0); - - s32 Priority = 0; - InitStreamHeader(Buffer, BufferSize, STREAM_BODY_SIZE, STARTCODE_DMX, Universe, Priority, 0, 0, "Lumenarium", SACN.CID); - SetStreamHeaderSequence_(Buffer, SACN.SequenceIterator, false); -} - -internal u32 -SACN_GetUniverseSendAddress(s32 Universe) -{ - u8 MulticastAddressBuffer[4] = {}; - MulticastAddressBuffer[0] = 239; - MulticastAddressBuffer[1] = 255; - MulticastAddressBuffer[2] = (u8)((Universe & 0xff00) >> 8); // high bit - MulticastAddressBuffer[3] = (u8)((Universe & 0x00ff)); // low bit - - u32 V4Address = (u32)UpackB4(MulticastAddressBuffer); - return V4Address; -} - -internal u64 -SACN_FillBufferWithLeds(u8* BufferStart, u32 BufferSize, v2_strip Strip, u64 LedsPlaced, led_buffer LedBuffer) -{ - u8* DestChannel = BufferStart; - u64 FirstLed = LedsPlaced; - u64 LedsToAdd = Min(Strip.LedCount - LedsPlaced, STREAM_BODY_SIZE / 3); - u64 OnePastLastLed = FirstLed + LedsToAdd; - for (u32 i = FirstLed; i < OnePastLastLed; i++) - { - u32 LedIndex = Strip.LedLUT[i]; - pixel Color = LedBuffer.Colors[LedIndex]; - - DestChannel[0] = Color.R; - DestChannel[1] = Color.G; - DestChannel[2] = Color.B; - DestChannel += 3; - } - return LedsToAdd; -} - -internal void -SACN_BuildOutputData(streaming_acn* SACN, addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem) -{ - SACN_UpdateSequence(SACN); - - // TODO(pjs): 512 is a magic number - make it a constant? - s32 BufferHeaderSize = STREAM_HEADER_SIZE; - s32 BufferBodySize = STREAM_BODY_SIZE; - s32 BufferSize = BufferHeaderSize + BufferBodySize; - - for (u32 AssemblyIdx = 0; AssemblyIdx < Assemblies.Count; AssemblyIdx++) - { - assembly Assembly = Assemblies.Values[AssemblyIdx]; - led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex); - - for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++) - { - v2_strip StripAt = Assembly.Strips[StripIdx]; - - // NOTE(PS): This isn't actually invalid, we just haven't needed to implement - // something more complex than only allowing strips to start at the first - // channel of a universe - Assert(StripAt.SACNAddr.StartChannel == 1); - - u32 UniverseAt = StripAt.SACNAddr.StartUniverse; - u64 LedsPlaced = 0; - while (LedsPlaced < StripAt.LedCount) - { - u32 V4SendAddress = SACN_GetUniverseSendAddress(UniverseAt); - u32 SendPort = DEFAULT_STREAMING_ACN_PORT; - - addressed_data_buffer* Data = AddressedDataBufferList_Push(Output, BufferSize); - AddressedDataBuffer_SetNetworkAddress(Data, SACN->SendSocket, V4SendAddress, SendPort); - - SACN_PrepareBufferHeader(UniverseAt, Data->Memory, Data->MemorySize, BufferHeaderSize, *SACN); - LedsPlaced += SACN_FillBufferWithLeds(Data->Memory + BufferHeaderSize, BufferBodySize, StripAt, LedsPlaced, *LedBuffer); - - UniverseAt += 1; - } - } - } -} - -#define SACN_H -#endif // SACN_H \ No newline at end of file diff --git a/src/app/engine/uart/foldhaus_uart.cpp b/src/app/engine/uart/foldhaus_uart.cpp deleted file mode 100644 index b6ea3fb..0000000 --- a/src/app/engine/uart/foldhaus_uart.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// -// File: foldhaus_uart.cpp -// Author: Peter Slattery -// Creation Date: 2020-10-10 -// -#ifndef FOLDHAUS_UART_CPP - - -internal void -UART_SetChannelBuffer_Create(gs_memory_cursor* WriteCursor, uart_channel ChannelSettings, v2_strip Strip, led_buffer LedBuffer) -{ - // NOTE(pjs): This is just here because the information is duplicated and I want to be sure - // to catch the error where they are different - Assert(ChannelSettings.PixelsCount == Strip.LedCount); - - uart_header* Header = MemoryCursorPushStruct(WriteCursor, uart_header); - UART_FillHeader(Header, Strip.UARTAddr.Channel, UART_SET_CHANNEL_WS2812); - - uart_channel* Channel = MemoryCursorPushStruct(WriteCursor, uart_channel); - *Channel = ChannelSettings; - - for (u32 i = 0; i < Channel->PixelsCount; i++) - { - u32 LedIndex = Strip.LedLUT[i]; - pixel Color = LedBuffer.Colors[LedIndex]; - - u8* OutputPixel = MemoryCursorPushArray(WriteCursor, u8, 3); - - // TODO(pjs): Use the Output mask -#if 1 - OutputPixel[0] = Color.R; - OutputPixel[1] = Color.G; - OutputPixel[2] = Color.B; -#else - OutputPixel[0] = 255; - OutputPixel[1] = 255; - OutputPixel[2] = 255; -#endif - if (Channel->ElementsCount == 4) - { - // TODO(pjs): Calculate white from the RGB components? - // Generally we just need a good way to handle the white channel, - // both in the renderer and in output - - //OutputPixel[Channel->WhiteIndex] = Color.W; - } - } - - uart_footer* Footer = MemoryCursorPushStruct(WriteCursor, uart_footer); - UART_FillFooter(Footer, (u8*)Header); -} - -internal void -UART_DrawAll_Create(gs_memory_cursor* WriteCursor) -{ - uart_header* Header = MemoryCursorPushStruct(WriteCursor, uart_header); - UART_FillHeader(Header, 1, UART_DRAW_ALL); - - uart_footer* Footer = MemoryCursorPushStruct(WriteCursor, uart_footer); - UART_FillFooter(Footer, (u8*)Header); -} - -internal void -UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem, gs_memory_arena* Transient) -{ - uart_channel ChannelSettings = {0}; - ChannelSettings.ElementsCount = 3; - ChannelSettings.ColorPackingOrder = 36; - - // NOTE(pjs): This is the minimum size of every UART message. SetChannelBuffer messages will - // be bigger than this, but their size is based on the number of pixels in each channel - u32 MessageBaseSize = UART_MESSAGE_MIN_SIZE; - - for (u32 AssemblyIdx = 0; AssemblyIdx < Assemblies.Count; AssemblyIdx++) - { - assembly Assembly = Assemblies.Values[AssemblyIdx]; - led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex); - - struct strips_to_data_buffer - { - gs_const_string ComPort; - - u32* StripIndices; - u32 StripIndicesCount; - u32 StripIndicesCountMax; - - u64 LedCount; - - u8** ChannelsStart; - - strips_to_data_buffer* Next; - }; - - u32 BuffersNeededCount = 0; - strips_to_data_buffer* BuffersNeededHead = 0; - strips_to_data_buffer* BuffersNeededTail = 0; - - for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++) - { - v2_strip StripAt = Assembly.Strips[StripIdx]; - - // If there is a buffer for this com port already created - // we use that - strips_to_data_buffer* BufferSelected = 0; - for (strips_to_data_buffer* At = BuffersNeededHead; - At!= 0; - At = At->Next) - { - if (StringsEqual(At->ComPort, StripAt.UARTAddr.ComPort.ConstString)) - { - BufferSelected = At; - break; - } - } - - // if no existing buffer for this com port - // create a new one - if (!BufferSelected) - { - BufferSelected = PushStruct(Transient, strips_to_data_buffer); - *BufferSelected = {}; - BufferSelected->ComPort = StripAt.UARTAddr.ComPort.ConstString; - // we don't know at this point how many indices per - // com port so just make enough room to fit all the strips - // if necessary - BufferSelected->StripIndicesCountMax = Assembly.StripCount; - BufferSelected->StripIndices = PushArray(Transient, u32, BufferSelected->StripIndicesCountMax); - BufferSelected->LedCount = 0; - BufferSelected->Next = 0; - - SLLPushOrInit(BuffersNeededHead, BuffersNeededTail, BufferSelected); - BuffersNeededCount += 1; - } - - Assert(BufferSelected->StripIndicesCount < BufferSelected->StripIndicesCountMax); - u32 Index = BufferSelected->StripIndicesCount++; - BufferSelected->StripIndices[Index] = StripIdx; - BufferSelected->LedCount += StripAt.LedCount; - } - - for (strips_to_data_buffer* At = BuffersNeededHead; - At!= 0; - At = At->Next) - { - u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages - TotalBufferSize += MessageBaseSize; // DrawAll message - TotalBufferSize += ChannelSettings.ElementsCount * At->LedCount; // pixels * channels per pixel - - At->ChannelsStart = PushArray(Transient, u8*, At->StripIndicesCount); - - addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize); - gs_const_string ComPort = At->ComPort; - AddressedDataBuffer_SetCOMPort(Buffer, ComPort); - - gs_memory_cursor WriteCursor = MemoryCursorCreate(Buffer->Memory, Buffer->MemorySize); - - for (u32 i = 0; i < At->StripIndicesCount; i++) - { - u32 StripIdx = At->StripIndices[i]; - v2_strip StripAt = Assembly.Strips[StripIdx]; - - ChannelSettings.PixelsCount = StripAt.LedCount; - UART_SetChannelBuffer_Create(&WriteCursor, ChannelSettings, StripAt, *LedBuffer); - } - - UART_DrawAll_Create(&WriteCursor); - } - } -} - - -#define FOLDHAUS_UART_CPP -#endif // FOLDHAUS_UART_CPP \ No newline at end of file diff --git a/src/app/engine/uart/foldhaus_uart.h b/src/app/engine/uart/foldhaus_uart.h deleted file mode 100644 index 63067ba..0000000 --- a/src/app/engine/uart/foldhaus_uart.h +++ /dev/null @@ -1,88 +0,0 @@ -// -// File: foldhaus_uart.h -// Author: Peter Slattery -// Creation Date: 2020-10-01 -// -#ifndef FOLDHAUS_UART_H - -enum uart_record_type -{ - UART_SET_CHANNEL_WS2812 = 1, - UART_DRAW_ALL = 2, -}; - -// NOTE(pjs): these are data packet structures and need to have 1 byte packing -#pragma pack(push, 1) - -struct uart_header -{ - s8 MagicNumber[4]; - u8 Channel; - u8 RecordType; -}; - -struct uart_channel -{ - u8 ElementsCount; - u8 ColorPackingOrder; - u16 PixelsCount; -}; - -struct uart_footer -{ - u32 CRC; -}; - -#pragma pack(pop) - -#define UART_MESSAGE_MIN_SIZE sizeof(uart_header) + sizeof(uart_channel) + sizeof(uart_footer) - -global u32 UART_CRCTable[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -internal void -UART_FillHeader(uart_header* Header, u8 Channel, u8 RecordType) -{ - Header->MagicNumber[0] = 'U'; - Header->MagicNumber[1] = 'P'; - Header->MagicNumber[2] = 'X'; - Header->MagicNumber[3] = 'L'; - - Header->Channel = Channel; - Header->RecordType = RecordType; -} - -internal u32 -UART_CalculateCRC(u8* BufferStart, u8* BufferEnd) -{ - // Calculate the CRC - u32 CRC = 0xFFFFFFFF; - u32 BytesCount = (u8*)BufferEnd - BufferStart; - for (u32 i = 0; i < BytesCount; i++) - { - u8 At = BufferStart[i]; -#if 0 - // Cameron's Version - CRC = UART_CRCTable[(CRC ^ At) & 0x0F] ^ (CRC >> 4); - CRC = UART_CRCTable[(CRC ^ (At >> 4)) & 0x0F] ^ (CRC >> 4); -#else - // https://github.com/simap/pixelblaze_output_expander/blob/master/firmware/Core/Src/uart.c - u32 TableIndex = (CRC ^ At) & 0xFF; - CRC = (UART_CRCTable[TableIndex] ^ (CRC >> 8)) & 0xFFFFFFFF; -#endif - } - - CRC = CRC ^ 0xFFFFFFFF; - return CRC; -} - -internal void -UART_FillFooter(uart_footer* Footer, u8* BufferStart) -{ - Footer->CRC = UART_CalculateCRC(BufferStart, (u8*)Footer); -} - -#define FOLDHAUS_UART_H -#endif // FOLDHAUS_UART_H \ No newline at end of file diff --git a/src/app/engine/user_space.cpp b/src/app/engine/user_space.cpp deleted file mode 100644 index 7e401df..0000000 --- a/src/app/engine/user_space.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// File: userspace.cpp -// Author: Peter Slattery -// Creation Date: 2021-01-30 -// -#ifndef USERSPACE_CPP - -internal void -US_LoadPatterns(user_space_desc* Desc, app_state* State, context Context) -{ - if (Desc->LoadPatterns) - { - Desc->LoadPatterns(State); - } -} - -internal void -US_CustomInit(user_space_desc* Desc, app_state* State, context Context) -{ - if (Desc->CustomInit) - { - Desc->UserData = Desc->CustomInit(State, Context); - } -} - -internal void -US_CustomUpdate(user_space_desc* Desc, app_state* State, context* Context) -{ - if (Desc->CustomUpdate) - { - Desc->CustomUpdate(Desc->UserData, State, Context); - } -} - -internal void -US_CustomDebugUI(user_space_desc* Desc, panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, - app_state* State, context Context) -{ - if (Desc->CustomDebugUI) - { - Desc->CustomDebugUI(Desc->UserData, Panel, PanelBounds, RenderBuffer, State, Context); - } -} - -internal void -US_CustomCleanup(user_space_desc* Desc, app_state* State, context Context) -{ - if (Desc->CustomCleanup) - { - Desc->CustomCleanup(Desc->UserData, State, Context); - } -} - - -#define USERSPACE_CPP -#endif // USERSPACE_CPP \ No newline at end of file diff --git a/src/app/engine/user_space.h b/src/app/engine/user_space.h deleted file mode 100644 index 5373fcb..0000000 --- a/src/app/engine/user_space.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// File: userspace.h -// Author: Peter Slattery -// Creation Date: 2021-01-30 -// -#ifndef USERSPACE_H - -#define US_LOAD_PATTERNS(name) void name(app_state* State) -typedef US_LOAD_PATTERNS(us_load_patterns_proc); - -#define US_CUSTOM_INIT(name) gs_data name (app_state* State, context Context) -typedef US_CUSTOM_INIT(us_custom_init_proc); - -#define US_CUSTOM_UPDATE(name) void name(gs_data UserData, app_state* State, context* Context) -typedef US_CUSTOM_UPDATE(us_custom_update_proc); - -#define US_CUSTOM_DEBUG_UI(name) void name(gs_data UserData, panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) -typedef US_CUSTOM_DEBUG_UI(us_custom_debug_ui); - -#define US_CUSTOM_CLEANUP(name) void name(gs_data UserData, app_state* State, context Context) -typedef US_CUSTOM_CLEANUP(us_custom_cleanup_proc); - -typedef struct user_space_desc -{ - us_load_patterns_proc* LoadPatterns; - us_custom_init_proc* CustomInit; - us_custom_update_proc* CustomUpdate; - us_custom_debug_ui* CustomDebugUI; - us_custom_cleanup_proc* CustomCleanup; - - gs_data UserData; -} user_space_desc; - -#define USERSPACE_H -#endif // USERSPACE_H \ No newline at end of file diff --git a/src/app/foldhaus_app.cpp b/src/app/foldhaus_app.cpp deleted file mode 100644 index 94d8073..0000000 --- a/src/app/foldhaus_app.cpp +++ /dev/null @@ -1,200 +0,0 @@ -// -// File: foldhaus_app.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_APP_CPP - -#include "foldhaus_platform.h" -#include "foldhaus_app.h" - -RELOAD_STATIC_DATA(ReloadStaticData) -{ - GlobalDebugServices = DebugServices; - GlobalLogBuffer = LogBuffer; - if (AppReady) - { - app_state* State = (app_state*)Context.MemoryBase; - State->PanelSystem.PanelDefs = GlobalPanelDefs; - State->PanelSystem.PanelDefsCount = GlobalPanelDefsCount; - - gs_data UserData = State->UserSpaceDesc.UserData; - State->UserSpaceDesc = BlumenLumen_UserSpaceCreate(); - if (UserData.Memory && !State->UserSpaceDesc.UserData.Memory) - { - State->UserSpaceDesc.UserData = UserData; - } - US_LoadPatterns(&State->UserSpaceDesc, State, Context); - } -} - -INITIALIZE_APPLICATION(InitializeApplication) -{ - Context->MemorySize = sizeof(app_state); - Context->MemoryBase = Alloc(Context->ThreadContext.Allocator, Context->MemorySize, "Memory Base"); - app_state* State = (app_state*)Context->MemoryBase; - *State = {}; - - State->Permanent = MemoryArenaCreate(MB(4), Bytes(8), Context->ThreadContext.Allocator,0, 0, "Permanent"); - State->Transient = Context->ThreadContext.Transient; - State->Assemblies = AssemblyArray_Create(8, &State->Permanent); - - State->CommandQueue = CommandQueue_Create(&State->Permanent, 32); - - animation_system_desc AnimSysDesc = {}; - AnimSysDesc.Storage = &State->Permanent; - AnimSysDesc.AnimArrayCount = 32; - AnimSysDesc.SecondsPerFrame = 1.0f / 24.0f; - State->AnimationSystem = AnimationSystem_Init(AnimSysDesc); - - if (!Context->Headless) - { - interface_config IConfig = {0}; - IConfig.FontSize = 14; - IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f }; - IConfig.ButtonColor_Inactive = BlackV4; - IConfig.ButtonColor_Active = v4{ .1f, .1f, .1f, 1.f }; - IConfig.ButtonColor_Selected = v4{ .3f, .3f, .3f, 1.f }; - IConfig.TextColor = WhiteV4; - IConfig.ListBGColors[0] = v4{ .16f, .16f, .16f, 1.f }; - IConfig.ListBGColors[1] = v4{ .18f, .18f, .18f, 1.f }; - IConfig.ListBGHover = v4{ .22f, .22f, .22f, 1.f }; - IConfig.ListBGSelected = v4{ .44f, .44f, .44f, 1.f }; - IConfig.Margin = v2{5, 5}; - State->Interface = ui_InterfaceCreate(*Context, IConfig, &State->Permanent); - - PanelSystem_Init(&State->PanelSystem, GlobalPanelDefs, GlobalPanelDefsCount, &State->Permanent); - - } - - State->SACN = SACN_Initialize(*Context); - - State->LedSystem = LedSystem_Create(Context->ThreadContext.Allocator, 128); - State->AssemblyDebugState = AssemblyDebug_Create(&State->Permanent); - State->AssemblyDebugState.Brightness = 255; - State->AssemblyDebugState.Override = ADS_Override_None; - - State->Modes = OperationModeSystemInit(&State->Permanent, Context->ThreadContext); - - ReloadStaticData(*Context, GlobalDebugServices, GlobalLogBuffer, true); - US_CustomInit(&State->UserSpaceDesc, State, *Context); - - if (!Context->Headless) - { - // NOTE(pjs): This just sets up the default panel layout - panel* RootPanel = PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, *Context); - SplitPanel(RootPanel, .25f, PanelSplit_Horizontal, &State->PanelSystem, State, *Context); - - panel* AnimPanel = RootPanel->Bottom; - Panel_SetType(AnimPanel, &State->PanelSystem, PanelType_AnimationTimeline, State, *Context); - - panel* TopPanel = RootPanel->Top; - SplitPanel(TopPanel, .5f, PanelSplit_Vertical, &State->PanelSystem, State, *Context); - - panel* LeftPanel = TopPanel->Left; - SplitPanel(LeftPanel, .5f, PanelSplit_Vertical, &State->PanelSystem, State, *Context); - - panel* Profiler = LeftPanel->Right; - Panel_SetType(Profiler, &State->PanelSystem, PanelType_MessageLog, State, *Context); - - panel* Hierarchy = LeftPanel->Left; - Panel_SetType(Hierarchy, &State->PanelSystem, PanelType_AssemblyDebug, State, *Context); - - } - - State->RunEditor = !Context->Headless; -} - -internal void -BuildAssemblyData (app_state* State, context Context, addressed_data_buffer_list* OutputData) -{ - -#define SEND_DATA -#ifdef SEND_DATA - // NOTE(pjs): Building data buffers to be sent out to the sculpture - // This array is used on the platform side to actually send the information - assembly_array SACNAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaSACN, State->Transient); - assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient); - SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem); - UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient); -#endif -} - -UPDATE_AND_RENDER(UpdateAndRender) -{ - DEBUG_TRACK_FUNCTION; - app_state* State = (app_state*)Context->MemoryBase; - - // 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 - // zero the Transient arena when we clear it so it wouldn't be a problem, but it is technically - // incorrect to clear the arena, and then access the memory later. - MemoryArenaClear(State->Transient); - Assert(State->UserSpaceDesc.UserData.Memory != 0); - - if (State->RunEditor) - { - Editor_Update(State, Context, InputQueue); - } - - AnimationSystem_Update(&State->AnimationSystem, Context->DeltaTime); - if (AnimationSystem_NeedsRender(State->AnimationSystem)) - { - Assert(State->UserSpaceDesc.UserData.Memory != 0); - AnimationSystem_RenderToLedBuffers(&State->AnimationSystem, - State->Assemblies, - &State->LedSystem, - State->Patterns, - State->Transient, - *Context, - State->UserSpaceDesc.UserData.Memory); - } - - Assert(State->UserSpaceDesc.UserData.Memory != 0); - US_CustomUpdate(&State->UserSpaceDesc, State, Context); - Assert(State->UserSpaceDesc.UserData.Memory != 0); - - AssemblyDebug_OverrideOutput(State->AssemblyDebugState, - State->Assemblies, - State->LedSystem); - - if (State->RunEditor) - { - Editor_Render(State, Context, RenderBuffer); - } - ResetWorkQueue(Context->GeneralWorkQueue); - - Assert(State->UserSpaceDesc.UserData.Memory != 0); - BuildAssemblyData(State, *Context, OutputData); - - // NOTE(PS): We introduced this in order to test some things on the - // blumen lumen circuit boards, to see if they were getting out - // of sync - if (State->SendEmptyPackets) { - for (addressed_data_buffer* At = OutputData->Root; - At != 0; - At = At->Next) - { - ZeroMemoryBlock(At->Memory, At->MemorySize); - } - } -} - -CLEANUP_APPLICATION(CleanupApplication) -{ - app_state* State = (app_state*)Context.MemoryBase; - - for (u32 i = 0; i < State->Assemblies.Count; i++) - { - assembly Assembly = State->Assemblies.Values[i]; - led_buffer LedBuffer = State->LedSystem.Buffers[Assembly.LedBufferIndex]; - AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0}); - } - BuildAssemblyData(State, Context, OutputData); - - US_CustomCleanup(&State->UserSpaceDesc, State, Context); - SACN_Cleanup(&State->SACN, Context); -} - -#define FOLDHAUS_APP_CPP -#endif // FOLDHAUS_APP_CPP \ No newline at end of file diff --git a/src/app/foldhaus_app.h b/src/app/foldhaus_app.h deleted file mode 100644 index 5666c95..0000000 --- a/src/app/foldhaus_app.h +++ /dev/null @@ -1,128 +0,0 @@ -// -// File: foldhaus_app.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_APP_H - -#include "../meta/gs_meta_include.h" -#include "../meta/gs_meta_lexer.h" - -#include "engine/foldhaus_serializer.h" - -#include "../gs_libs/gs_font.h" - -#include "editor/interface.h" - -#include "engine/foldhaus_network_ordering.h" - -#include "engine/assembly/foldhaus_assembly.h" - -#include "ss_blumen_lumen/gfx_math.h" - -#include "engine/assembly/foldhaus_assembly_parser.cpp" -#include "engine/assembly/foldhaus_assembly_debug.h" - -#include "engine/sacn/foldhaus_sacn.h" -#include "engine/uart/foldhaus_uart.h" -#include "engine/uart/foldhaus_uart.cpp" - -typedef struct app_state app_state; - -typedef struct panel panel; - -#include "editor/foldhaus_command_dispatch.h" -#include "editor/foldhaus_operation_mode.h" - -// 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 "editor/foldhaus_panel.h" - -#include "engine/animation/foldhaus_animation.h" -#include "engine/animation/foldhaus_animation_serializer.cpp" -#include "engine/animation/foldhaus_animation_renderer.cpp" - -#include "engine/user_space.h" -#include "ss_blumen_lumen/phrase_hue_map.h" -#include "ss_blumen_lumen/blumen_lumen.h" - -struct app_state -{ - gs_memory_arena Permanent; - gs_memory_arena* Transient; - - // Engine - // - network_protocol NetworkProtocol; - streaming_acn SACN; - led_system LedSystem; - assembly_array Assemblies; - assembly_debug_state AssemblyDebugState; - animation_system AnimationSystem; - animation_pattern_array Patterns; - - // Interface - // - rect2 WindowBounds; - - operation_mode_system Modes; - input_command_queue CommandQueue; - - ui_interface Interface; - panel_system PanelSystem; - panel* HotPanel; - - user_space_desc UserSpaceDesc; - bool ShowingUserSpaceDebug; - - bool RunEditor; - bool SendEmptyPackets; -}; - -internal void OpenColorPicker(app_state* State, v4* Address); - -#include "engine/assembly/foldhaus_assembly.cpp" - -internal assembly* -LoadAssembly(gs_const_string Path, app_state* State, context Context) -{ - return LoadAssembly(&State->Assemblies, - &State->LedSystem, - State->Transient, - Context, - Path, - GlobalLogBuffer); -} - -#include "engine/user_space.cpp" - -#include "ss_blumen_lumen/sdf.h" -#include "patterns/blumen_patterns.h" -#include "ss_blumen_lumen/blumen_lumen.cpp" - -internal void -EndCurrentOperationMode(app_state* State) -{ - DeactivateCurrentOperationMode(&State->Modes); -} - -#include "editor/panels/foldhaus_panel_types.h" - -#include "editor/panels/foldhaus_panel_file_view.h" -#include "editor/panels/foldhaus_panel_sculpture_view.h" -#include "editor/panels/foldhaus_panel_profiler.h" -#include "editor/panels/foldhaus_panel_dmx_view.h" -#include "editor/panels/foldhaus_panel_animation_timeline.h" -#include "editor/panels/foldhaus_panel_hierarchy.h" -#include "editor/panels/foldhaus_panel_assembly_debug.h" -#include "editor/panels/foldhaus_panel_message_log.h" - -#include "editor/panels/foldhaus_panel_types.cpp" - -#include "editor/foldhaus_interface.cpp" -#include "editor/foldhaus_editor_draw.h" -#include "editor/foldhaus_editor.cpp" - -#define FOLDHAUS_APP_H -#endif // FOLDHAUS_APP_H \ No newline at end of file diff --git a/src/app/foldhaus_debug.h b/src/app/foldhaus_debug.h deleted file mode 100644 index 8a66201..0000000 --- a/src/app/foldhaus_debug.h +++ /dev/null @@ -1,474 +0,0 @@ -// -// File: foldhaus_debug.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -// DESCRIPTION: -// This file contains profiling capabilities for both the engine and app -// -#ifndef FOLDHAUS_DEBUG_H - -#define SCOPE_NAME_LENGTH 256 -struct scope_record -{ - u32 NameHash; - s64 StartCycles; - s64 EndCycles; - s32 CallDepth; -}; - -struct collated_scope_record -{ - u32 NameHash; - s64 TotalCycles; - s32 CallCount; - - r32 PercentFrameTime; - r32 TotalSeconds; - - r32 AverageSecondsPerCall; -}; - -#define SCOPE_NAME_BUFFER_LENGTH 128 -struct scope_name -{ - u32 Hash; - gs_string Name; - char Buffer[SCOPE_NAME_BUFFER_LENGTH]; -}; - -struct debug_scope_record_list -{ - s32 ThreadId; - s32 Max; - s32 Count; - scope_record* Calls; - - s32 CurrentScopeCallDepth; -}; - -#define DEBUG_FRAME_GROW_SIZE 8102 -struct debug_frame -{ - s64 FrameStartCycles; - s64 FrameEndCycles; - - s32 ScopeNamesMax; - s32 ScopeNamesCount; - scope_name* ScopeNamesHash; - - s32 ThreadCount; - debug_scope_record_list* ThreadCalls; - - s32 CollatedScopesMax; - collated_scope_record* CollatedScopes; -}; - -enum debug_ui_view -{ - DebugUI_Profiler, - DebugUI_ScopeList, - DebugUI_MemoryView, - - DebugUI_Count, -}; - -struct debug_interface -{ - s32 FrameView; -}; - -typedef s32 debug_get_thread_id(); -typedef s64 debug_timing_proc(); -typedef u8* debug_alloc(s32 ElementSize, s32 ElementCount); -typedef u8* debug_realloc(u8* Memory, s32 OldSize, s32 NewSize); - -#define HISTOGRAM_DEPTH 10 -struct debug_histogram_entry -{ - char ScopeName_[SCOPE_NAME_LENGTH]; - gs_string ScopeName; - - u32 PerFrame_Cycles[HISTOGRAM_DEPTH]; - u32 PerFrame_CallCount[HISTOGRAM_DEPTH]; - s32 CurrentFrame; - - // NOTE(Peter): Cached Values, recalculated ever frame - u32 Average_Cycles; - u32 Average_CallCount; - u32 Total_Cycles; - u32 Total_CallCount; -}; - -#if DEBUG -# define DEBUG_FRAME_COUNT 128 -#else -# define DEBUG_FRAME_COUNT 0 -#endif - -struct debug_services -{ - s64 PerformanceCountFrequency; - - b32 RecordFrames; - s32 CurrentDebugFrame; - debug_frame* Frames; - - debug_interface Interface; - - gs_thread_context Ctx; - gs_memory_arena A; - - debug_get_thread_id* GetThreadId; - debug_timing_proc* GetWallClock; -}; - -internal void -InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32 ScopeCallsMax, debug_services* Services) -{ - Frame->ScopeNamesMax = NameHashMax; - Frame->ScopeNamesHash = PushArray(&Services->A, scope_name, NameHashMax); - - // NOTE(Peter): We use the same size as scope names because we're only storing a single instance - // per scope. If ScopeNamesMax can't hold all the scopes, this will never get filled and - // we should assert and recompile with a resized NameHashMax - Frame->CollatedScopesMax = NameHashMax; - Frame->CollatedScopes = PushArray(&Services->A, collated_scope_record, NameHashMax); - - for (s32 i = 0; i < Frame->ScopeNamesMax; i++) - { - scope_name* Entry = Frame->ScopeNamesHash + i; - Entry->Name = MakeString(Entry->Buffer, 0, SCOPE_NAME_BUFFER_LENGTH); - } - - Frame->ThreadCount = ThreadCount; - Frame->ThreadCalls = PushArray(&Services->A, debug_scope_record_list, ThreadCount); - - for (s32 i = 0; i < ThreadCount; i++) - { - Frame->ThreadCalls[i].Max = ScopeCallsMax; - Frame->ThreadCalls[i].Count = 0; - Frame->ThreadCalls[i].Calls = PushArray(&Services->A, scope_record, ScopeCallsMax); - Frame->ThreadCalls[i].CurrentScopeCallDepth = 0; - Frame->ThreadCalls[i].ThreadId = 0; - } - - for (s32 c = 0; c < Frame->CollatedScopesMax; c++) - { - Frame->CollatedScopes[c].NameHash = 0; - } -} - -internal void -StartDebugFrame(debug_frame* Frame, debug_services* Services) -{ - Frame->FrameStartCycles = Services->GetWallClock(); - for (s32 i = 0; i < Frame->ThreadCount; i++) - { - Frame->ThreadCalls[i].Count = 0; - Frame->ThreadCalls[i].CurrentScopeCallDepth = 0; - } - - for (s32 c = 0; c < Frame->CollatedScopesMax; c++) - { - s32 Hash = Frame->CollatedScopes[c].NameHash; - Frame->CollatedScopes[c] = {}; - Frame->CollatedScopes[c].NameHash = Hash; - } -} - -internal void -InitDebugServices_OffMode (debug_services* Services, - s64 PerformanceCountFrequency, - debug_timing_proc* GetWallClock, - debug_get_thread_id* GetThreadId, - gs_thread_context Ctx, - s32 ThreadCount) -{ - *Services = {0}; - - Services->Ctx = Ctx; - Services->GetWallClock = GetWallClock; - Services->GetThreadId = GetThreadId; - - Services->RecordFrames = false; - Services->Frames = 0; - - Services->CurrentDebugFrame = 0; - Services->PerformanceCountFrequency = PerformanceCountFrequency; -} - - -internal void -InitDebugServices_DebugMode (debug_services* Services, - s64 PerformanceCountFrequency, - debug_timing_proc* GetWallClock, - debug_get_thread_id* GetThreadId, - gs_thread_context Ctx, - s32 ThreadCount) -{ - Services->Ctx = Ctx; - Services->GetWallClock = GetWallClock; - Services->GetThreadId = GetThreadId; - - Services->RecordFrames = true; - - Services->CurrentDebugFrame = 0; - Services->A = MemoryArenaCreate(MB(64), Bytes(8), Ctx.Allocator, 0, 0, "Debug Services Allocator"); - - s32 NameHashMax = 4096; - s32 ScopeCallsMax = 4096; - Services->Frames = PushArray(&Services->A, debug_frame, DEBUG_FRAME_COUNT); - for (s32 i = 0; i < DEBUG_FRAME_COUNT; i++) - { - InitializeDebugFrame(&Services->Frames[i], NameHashMax, ThreadCount, ScopeCallsMax, Services); - } - - Services->PerformanceCountFrequency = PerformanceCountFrequency; -} - -internal debug_frame* -GetCurrentDebugFrame (debug_services* Services) -{ - debug_frame* Result = Services->Frames + Services->CurrentDebugFrame; - return Result; -} - -internal debug_frame* -GetLastDebugFrame(debug_services* Services) -{ - if (!Services->Frames) return 0; - - s32 Index = (Services->CurrentDebugFrame - 1); - if (Index < 0) { Index += DEBUG_FRAME_COUNT; } - debug_frame* Result = Services->Frames + Index; - return Result; -} - -internal s32 -GetIndexForNameHash(debug_frame* Frame, u32 NameHash) -{ - s32 Result = -1; - - for (s32 Offset = 0; Offset < Frame->ScopeNamesMax; Offset++) - { - u32 Index = (NameHash + Offset) % Frame->ScopeNamesMax; - if (Frame->ScopeNamesHash[Index].Hash == NameHash) - { - Result = Index; - break; - } - } - - // NOTE(Peter): Its not technically wrong to return a -1 here, just means we didn't find it. - // At the time of writing however, this function is only being called in contexts where we - // know there should be an entry in the Name table, so a -1 actually indicates a problem. - Assert(Result >= 0); - return Result; -} - -internal debug_scope_record_list* -GetScopeListForThreadInFrame(debug_services* Services, debug_frame* Frame) -{ - debug_scope_record_list* List = 0; - - s32 CurrentThreadId = Services->GetThreadId(); - for (s32 Offset = 0; Offset < Frame->ThreadCount; Offset++) - { - s32 Index = (CurrentThreadId + Offset) % Frame->ThreadCount; - if (Frame->ThreadCalls[Index].ThreadId == CurrentThreadId) - { - List = Frame->ThreadCalls + Index; - break; - } - else if (Frame->ThreadCalls[Index].ThreadId == 0) - { - Frame->ThreadCalls[Index].ThreadId = CurrentThreadId; - List = Frame->ThreadCalls + Index; - break; - } - } - - Assert(List); - return List; -} - -internal void -CollateThreadScopeCalls (debug_scope_record_list* ThreadRecords, debug_frame* Frame) -{ - for (s32 i = 0; i < ThreadRecords->Count; i++) - { - scope_record Record = ThreadRecords->Calls[i]; - s32 Index = GetIndexForNameHash (Frame, Record.NameHash); - collated_scope_record* CollatedRecord = Frame->CollatedScopes + Index; - - if (CollatedRecord->NameHash != Record.NameHash) - { - CollatedRecord->NameHash = Record.NameHash; - CollatedRecord->TotalCycles = 0; - CollatedRecord->CallCount = 0; - } - - CollatedRecord->TotalCycles += Record.EndCycles - Record.StartCycles; - CollatedRecord->CallCount += 1; - } -} - -internal void -EndDebugFrame (debug_services* Services) -{ - debug_frame* ClosingFrame = GetCurrentDebugFrame(Services); - ClosingFrame->FrameEndCycles = Services->GetWallClock(); - - s64 FrameTotalCycles = ClosingFrame->FrameEndCycles - ClosingFrame->FrameStartCycles; - - for (s32 t = 0; t < ClosingFrame->ThreadCount; t++) - { - CollateThreadScopeCalls(ClosingFrame->ThreadCalls + t, ClosingFrame); - } - - s32 ScopeNamesCount = 0; - for (s32 n = 0; n < ClosingFrame->ScopeNamesMax; n++) - { - if (ClosingFrame->ScopeNamesHash[n].Hash != 0) - { - collated_scope_record* CollatedRecord = ClosingFrame->CollatedScopes + n; - CollatedRecord->TotalSeconds = (r32)CollatedRecord->TotalCycles / (r32)Services->PerformanceCountFrequency; - CollatedRecord->PercentFrameTime = (r32)CollatedRecord->TotalCycles / (r32)FrameTotalCycles; - CollatedRecord->AverageSecondsPerCall = CollatedRecord->TotalSeconds / CollatedRecord->CallCount; - ScopeNamesCount += 1; - } - } - ClosingFrame->ScopeNamesCount = ScopeNamesCount; - - s32 FramesCount = DEBUG_FRAME_COUNT; - if (FramesCount > 0) - { - Services->CurrentDebugFrame = (Services->CurrentDebugFrame + 1) % FramesCount; - } - StartDebugFrame(&Services->Frames[Services->CurrentDebugFrame], Services); -} - -internal u32 -HashScopeName (char* ScopeName) -{ - // djb2 hash - u32 Hash = 5381; - char* C = ScopeName; - while(*C) - { - Hash = ((Hash << 5) + Hash) + *C; - C++; - } - return Hash; -} - -internal scope_name* -GetOrAddNameHashEntry(debug_frame* Frame, u32 NameHash) -{ - scope_name* Result = 0; - - for (s32 Offset = 0; Offset < Frame->ScopeNamesMax; Offset++) - { - u32 Index = (NameHash + Offset) % Frame->ScopeNamesMax; - if ((Frame->ScopeNamesHash[Index].Hash == 0) || (Frame->ScopeNamesHash[Index].Hash == NameHash)) - { - Result = Frame->ScopeNamesHash + Index; - break; - } - } - - return Result; -} - -internal u32 -BeginTrackingScopeAndGetNameHash (debug_services* Services, char* ScopeName) -{ - debug_frame* CurrentFrame = GetCurrentDebugFrame(Services); - debug_scope_record_list* ThreadList = GetScopeListForThreadInFrame(Services, CurrentFrame); - - ThreadList->CurrentScopeCallDepth++; - - u32 NameHash = HashScopeName(ScopeName); - scope_name* Entry = GetOrAddNameHashEntry(CurrentFrame, NameHash); - if (Entry->Hash == 0) // If its new - { - Entry->Hash = NameHash; - // TODO(Peter): need to initialize all entry name gs_strings to point at the buffer - // This will break eventually. when it does, do this ^^^^ when on startup - PrintF(&Entry->Name, "%s", ScopeName); - } - - return NameHash; -} - -internal void -PushScopeTimeOnFrame (debug_services* Services, s32 NameHash, u64 StartCycles, u64 EndCycles) -{ - debug_frame* CurrentFrame = GetCurrentDebugFrame(Services); - debug_scope_record_list* ThreadList = GetScopeListForThreadInFrame(Services, CurrentFrame); - - if (ThreadList->Count >= ThreadList->Max) - { - s32 NewMax = (ThreadList->Max + DEBUG_FRAME_GROW_SIZE); - FreeArray(Services->Ctx.Allocator, ThreadList->Calls, scope_record, ThreadList->Max); - ThreadList->Calls = AllocArray(Services->Ctx.Allocator, scope_record, NewMax, "Debug Frame"); - ThreadList->Max = NewMax; - } - - Assert(ThreadList->Count < ThreadList->Max); - - s32 EntryIndex = ThreadList->Count++; - scope_record* Record = ThreadList->Calls + EntryIndex; - Record->NameHash = NameHash; - Record->StartCycles = StartCycles; - Record->EndCycles = EndCycles; - Record->CallDepth = --ThreadList->CurrentScopeCallDepth; -} - -internal r32 DEBUGGetSecondsElapsed (s64 Start, s64 End, r32 PerformanceCountFrequency) -{ - r32 Result = ((r32)(End - Start) / (r32)PerformanceCountFrequency); - return Result; -} - -#if DEBUG -#define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices) -#define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices) -#else -#define DEBUG_TRACK_FUNCTION -#define DEBUG_TRACK_SCOPE(name) -#endif -struct scope_tracker -{ - s64 ScopeStart; - u32 ScopeNameHash; - debug_services* DebugServices; - - scope_tracker(char* ScopeName, debug_services* DebugServices) - { - if (DebugServices->RecordFrames) - { - this->ScopeNameHash = BeginTrackingScopeAndGetNameHash(DebugServices, ScopeName); - this->ScopeStart = DebugServices->GetWallClock(); - this->DebugServices = DebugServices; - } - else - { - this->DebugServices = 0; - } - } - - ~scope_tracker() - { - if (this->DebugServices) // NOTE(Peter): If DebugServices == 0, then we werent' recording this frame - { - s64 ScopeEnd = this->DebugServices->GetWallClock(); - PushScopeTimeOnFrame(this->DebugServices, this->ScopeNameHash, this->ScopeStart, ScopeEnd); - } - } -}; - - -#define FOLDHAUS_DEBUG_H -#endif // FOLDHAUS_DEBUG_H \ No newline at end of file diff --git a/src/app/foldhaus_log.h b/src/app/foldhaus_log.h deleted file mode 100644 index dea66da..0000000 --- a/src/app/foldhaus_log.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// File: foldhaus_log.h -// Author: Peter Slattery -// Creation Date: 2020-02-05 -// -#ifndef FOLDHAUS_LOG_H - -enum log_entry_type -{ - LogEntry_Message, - LogEntry_Error, -}; - -struct log_entry -{ - gs_string Message; - log_entry_type Type; -}; - -#define LOG_ENTRIES_MAX 256 -struct event_log -{ - log_entry Entries[LOG_ENTRIES_MAX]; - // Circular buffer head position - u32 NextEntry; -}; - -#define LogMessage(_Log, _Message) PushLogEntry(_Log, MakeString(_Message), LogEntry_Message) -#define LogError(_Log, _Message) PushLogEntry(_Log, MakeString(_Message), LogEntry_Error) - -internal void -PushLogEntry(event_log* Log, gs_string Message, log_entry_type Type) -{ - u32 NewLogIndex = Log->NextEntry++; - if (Log->NextEntry >= LOG_ENTRIES_MAX) - { - Log->NextEntry = 0; - } - - log_entry* NewEntry = Log->Entries + NewLogIndex; - NewEntry->Message = Message; - NewEntry->Type = Type; -} - -#define FOLDHAUS_LOG_H -#endif // FOLDHAUS_LOG_H \ No newline at end of file diff --git a/src/app/foldhaus_platform.h b/src/app/foldhaus_platform.h deleted file mode 100644 index 14e1ae5..0000000 --- a/src/app/foldhaus_platform.h +++ /dev/null @@ -1,255 +0,0 @@ -// -// File: foldhaus_platform.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_PLATFORM_H - -// TODO Remove -#include -#include - -#include "..\gs_libs\gs_types.h" -#include "..\gs_libs\gs_types.cpp" -#include "..\gs_libs\gs_path.h" - -struct handle -{ - u32 Generation; - u32 Index; -}; - -inline bool -Handle_IsValid(handle Handle) -{ - bool Result = (Handle.Generation != 0); - return Result; -} - -#include "..\gs_libs\gs_string.h" -#include "..\gs_libs\gs_csv.h" - -#include "engine/foldhaus_log.h" -global log_buffer* GlobalLogBuffer; - -#include "foldhaus_debug.h" -global debug_services* GlobalDebugServices; - -//#include "..\gs_libs\gs_vector_matrix.h" -#include "..\gs_libs\gs_input.h" - -struct platform_network_address -{ - s32 Family; - u16 Port; - u32 Address; -}; - -typedef s32 platform_socket_handle; -typedef s32 platform_network_address_handle; - -#include "foldhaus_renderer.h" -#include "engine/foldhaus_addressed_data.h" - -typedef struct context context; - -// Application Functions - -// TODO(pjs): TEMP -typedef void temp_job_req_proc(gs_thread_context* Ctx, u8* Memory); -struct temp_job_req -{ - temp_job_req_proc* Proc; - u8* Memory; -}; -// This isn't necessarily temp but I'm not sure it goes here -#define PACKETS_MAX 32 -struct packet_ringbuffer -{ - gs_data Values[PACKETS_MAX]; - u32 ReadHead; - u32 WriteHead; -}; - -#define INITIALIZE_APPLICATION(name) void name(context* Context) -typedef INITIALIZE_APPLICATION(initialize_application); - -#define UPDATE_AND_RENDER(name) void name(context* Context, input_queue InputQueue, render_command_buffer* RenderBuffer, addressed_data_buffer_list* OutputData) -typedef UPDATE_AND_RENDER(update_and_render); - -#define RELOAD_STATIC_DATA(name) void name(context Context, debug_services* DebugServices, log_buffer* LogBuffer, bool AppReady) -typedef RELOAD_STATIC_DATA(reload_static_data); - -#define CLEANUP_APPLICATION(name) void name(context Context, addressed_data_buffer_list* OutputData) -typedef CLEANUP_APPLICATION(cleanup_application); - -// Platform Functions - -struct window_info -{ - char* Name; - s32 Width; - s32 Height; -}; - -typedef struct window window; - -#define PLATFORM_MEMORY_NO_ERROR 0 -enum platform_memory_error -{ - PlatformMemory_NoError, - PlatformMemory_FileNotFound, - - PlatformMemory_UnknownError, // You should implement handling this when you see it -}; - -struct data -{ - u8* Base; - u64 Size; -}; - -struct platform_memory_result -{ - data Data; - platform_memory_error Error; -}; - -struct system_path -{ - char* Path; - s32 PathLength; - s32 IndexOfLastSlash; -}; - -struct texture_buffer -{ - u8* Memory; - s32 Width; - s32 Height; - s32 Pitch; - s32 BytesPerPixel; -}; - -#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height) -typedef PLATFORM_GET_GPU_TEXTURE_HANDLE(platform_get_gpu_texture_handle); - -#define PLATFORM_GET_SOCKET_HANDLE(name) platform_socket_handle name(s32 Multicast_TimeToLive) -typedef PLATFORM_GET_SOCKET_HANDLE(platform_get_socket_handle); - -// Font -struct platform_font_info -{ - s32 PixelHeight; - s32 Ascent, Descent, Leading; - s32 MaxCharWidth; - s32 CodepointStart; - s32 CodepointOnePastLast; -}; - -enum font_weight -{ - FontWeight_Invalid = 0, - FontWeight_Thin = 100, - FontWeight_ExtraLight = 200, - FontWeight_Light = 300, - FontWeight_Normal = 400, - FontWeight_Medium = 500, - FontWeight_SemiBold = 600, - FontWeight_Bold = 700, - FontWeight_ExtraBold = 800, - FontWeight_Heavy = 900, -}; - -#define GET_FONT_INFO(name) platform_font_info name(char* FontName, s32 PixelHeight, font_weight FontWeight, b32 Italic, b32 Underline, b32 Strikeout) -typedef GET_FONT_INFO(platform_get_font_info); - -#define DRAW_FONT_CODEPOINT(name) void name(u8* DestBuffer, s32 DestBufferWidth, s32 DestBufferHeight, u32 XOffset, u32 YOffset, char Codepoint, platform_font_info FontInfo, u32* OutWidth, u32* OutHeight) -typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint); - -// Worker Threads - -#define PLATFORM_THREAD_COUNT 3 - -RESET_WORK_QUEUE(ResetWorkQueue) -{ - for (u32 i = 0; i < Queue->JobsMax; i++) - { - Queue->Jobs[i].Data = {0}; - Queue->Jobs[i].WorkProc = 0; - } - - Queue->JobsCount = 0; - Queue->NextJobIndex = 0; - Queue->JobsCompleted = 0; -} - -// Time - -internal r32 -GetSecondsElapsed (s64 Start, s64 End, s64 PerformanceCountFrequency) -{ - r32 Result = ((r32)(End - Start) / (r32) PerformanceCountFrequency); - return Result; -} - -typedef struct system_time -{ - u64 NanosSinceEpoch; - - s32 Year; - s32 Month; - s32 Day; - s32 Hour; // [0:23] - s32 Minute; - s32 Second; -} system_time; - -internal r64 -SecondsElapsed(system_time Start, system_time End) -{ - u64 N = End.NanosSinceEpoch - Start.NanosSinceEpoch; - r64 S = (r64)N * NanosToSeconds; - return S; -} - -struct context -{ - gs_thread_context ThreadContext; - - u8* MemoryBase; - u32 MemorySize; - - b32 WindowIsVisible; - rect2 WindowBounds; - r64 TotalTime; - r32 DeltaTime; - mouse_state Mouse; - - // Application Services - initialize_application* InitializeApplication; - reload_static_data* ReloadStaticData; - update_and_render* UpdateAndRender; - cleanup_application* CleanupApplication; - - platform_thread_manager* ThreadManager; - platform_socket_manager* SocketManager; - - // Platform Services - gs_work_queue* GeneralWorkQueue; - - platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle; - platform_get_font_info* PlatformGetFontInfo; - platform_draw_font_codepoint* PlatformDrawFontCodepoint; - - platform_get_socket_handle* PlatformGetSocketHandle; - - system_time SystemTime_Last; - system_time SystemTime_Current; - - // - bool Headless; -}; - -#define FOLDHAUS_PLATFORM_H -#endif // FOLDHAUS_PLATFORM_H \ No newline at end of file diff --git a/src/app/foldhaus_renderer.cpp b/src/app/foldhaus_renderer.cpp deleted file mode 100644 index 51c2579..0000000 --- a/src/app/foldhaus_renderer.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// -// File: foldhaus_renderer.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_RENDERER_CPP - -internal render_command_buffer -AllocateRenderCommandBuffer (u8* Memory, s32 Size, gs_thread_context Ctx) -{ - render_command_buffer Result = {}; - Result.CommandMemory = Memory; - Result.CommandMemorySize = Size; - Result.CommandMemoryUsed = 0; - Result.Ctx = Ctx; - return Result; -} -internal render_command_buffer -AllocateRenderCommandBuffer(u32 MemorySize, - gs_memory_arena* Arena, - gs_thread_context Ctx) -{ - u8* Memory = PushSize(Arena, MemorySize).Memory; - return AllocateRenderCommandBuffer(Memory, MemorySize, Ctx); -} - -internal void -Render3DQuadBatch (u8* CommandData, s32 TriCount) -{ - DEBUG_TRACK_FUNCTION; - - v4* Vertecies = (v4*)(CommandData + BATCH_3D_VERTECIES_OFFSET(TriCount)); - v2* UVs = (v2*)(CommandData + BATCH_3D_UVS_OFFSET(TriCount)); - v4* Colors = (v4*)(CommandData + BATCH_3D_COLORS_OFFSET(TriCount)); - -#if IMMEDIATE_MODE_RENDERING - - for (s32 Tri = 0; Tri < TriCount; Tri++) - { - v4 P0 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 0)]; - v4 P1 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 1)]; - v4 P2 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 2)]; - v2 UV0 = UVs[BATCH_3D_UV_INDEX(Tri, 0)]; - v2 UV1 = UVs[BATCH_3D_UV_INDEX(Tri, 1)]; - v2 UV2 = UVs[BATCH_3D_UV_INDEX(Tri, 2)]; - v4 C0 = Colors[BATCH_3D_COLOR_INDEX(Tri, 0)]; - v4 C1 = Colors[BATCH_3D_COLOR_INDEX(Tri, 1)]; - v4 C2 = Colors[BATCH_3D_COLOR_INDEX(Tri, 2)]; - - OpenGLDraw3DTri(P0, P1, P2, UV0, UV1, UV2, C0, C1, C2); - } -#else - OpenGLRenderTriBuffer((u8*)Vertecies, 4, (u8*)UVs, 2, (u8*)Colors, 4, TriCount * 3); -#endif -} - -internal void -Render2DQuadBatch (u8* CommandData, s32 QuadCount) -{ - DEBUG_TRACK_FUNCTION; - - v2* Vertecies = (v2*)(CommandData + BATCH_2D_VERTECIES_OFFSET(QuadCount)); - v2* UVs = (v2*)(CommandData + BATCH_2D_UVS_OFFSET(QuadCount)); - v4* Colors = (v4*)(CommandData + BATCH_2D_COLORS_OFFSET(QuadCount)); - -#if IMMEDIATE_MODE_RENDERING - for (s32 Quad = 0; Quad < QuadCount; Quad++) - { - for (s32 Tri = 0; Tri < 2; Tri++) - { - v2 P0 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 0)]; - v2 P1 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 1)]; - v2 P2 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 2)]; - v2 UV0 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 0)]; - v2 UV1 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 1)]; - v2 UV2 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 2)]; - v4 C0 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 0)]; - v4 C1 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 1)]; - v4 C2 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 2)]; - - OpenGLDraw2DTri(P0, P1, P2, UV0, UV1, UV2, C0, C1, C2); - } - } -#else - OpenGLRenderTriBuffer((u8*)Vertecies, 2, (u8*)UVs, 2, (u8*)Colors, 4, QuadCount * 2 * 3); -#endif -} - -internal void -RenderCommandBuffer (render_command_buffer CommandBuffer) -{ - DEBUG_TRACK_FUNCTION; - - glMatrixMode(GL_TEXTURE_2D); - glLoadIdentity(); - - glClearColor(0.1f, 0.1f, 0.1f, 1); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glDisable(GL_TEXTURE_2D); - b32 GLTextureEnabled = false; - - u8* CurrentPosition = CommandBuffer.CommandMemory; - while(CurrentPosition < CommandBuffer.CommandMemory + CommandBuffer.CommandMemoryUsed) - { - render_command_header* CommandHeader = (render_command_header*)CurrentPosition; - CurrentPosition += sizeof(render_command_header); - switch (CommandHeader->Type) - { - case RenderCommand_render_command_set_render_mode: - { - DEBUG_TRACK_SCOPE(SetRenderMode); - - render_command_set_render_mode* Command = (render_command_set_render_mode*)(CommandHeader + 1); - - glViewport(Command->ViewOffsetX, Command->ViewOffsetY, - Command->ViewWidth, Command->ViewHeight); - - LoadModelView(Command->ModelView.Array); - LoadProjection(Command->Projection.Array); - - if (Command->UseDepthBuffer) - { - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - } - else - { - glDisable(GL_DEPTH_TEST); - } - - CurrentPosition += sizeof(render_command_set_render_mode); - }break; - - case RenderCommand_render_command_clear_screen: - { - DEBUG_TRACK_SCOPE(RendererClearScreen); - - render_command_clear_screen* Command = (render_command_clear_screen*)(CommandHeader + 1); - - ClearRenderBuffer(); - - CurrentPosition += sizeof(render_command_clear_screen); - }break; - - case RenderCommand_render_batch_command_quad_2d: - { - render_batch_command_quad_2d* Command = (render_batch_command_quad_2d*)(CommandHeader + 1); - - if (GLTextureEnabled) { glDisable(GL_TEXTURE_2D); GLTextureEnabled = false; } - u8* CommandData = (u8*)(Command + 1); - Render2DQuadBatch(CommandData, Command->QuadCount); - - CurrentPosition += sizeof(render_batch_command_quad_2d) + Command->DataSize; - }break; - - case RenderCommand_render_batch_command_quad_3d: - { - render_batch_command_quad_3d* Command = (render_batch_command_quad_3d*)(CommandHeader + 1); - - if (GLTextureEnabled) { glDisable(GL_TEXTURE_2D); GLTextureEnabled = false; } - u8* CommandData = (u8*)(Command + 1); - Render3DQuadBatch(CommandData, Command->QuadCount * 2); - - CurrentPosition += sizeof(render_batch_command_quad_3d) + Command->DataSize; - }break; - - case RenderCommand_render_batch_command_texture_2d: - { - render_batch_command_texture_2d* Command = (render_batch_command_texture_2d*)(CommandHeader + 1); - - if (!GLTextureEnabled) { glEnable(GL_TEXTURE_2D); GLTextureEnabled = true; } - Assert(Command->Texture.Handle > 0); - glBindTexture(GL_TEXTURE_2D, Command->Texture.Handle); - u8* CommandData = (u8*)(Command + 1); - Render2DQuadBatch(CommandData, Command->QuadCount); - - CurrentPosition += sizeof(render_batch_command_texture_2d) + Command->DataSize; - }break; - - default: - { - InvalidCodePath; - }break; - } - } -} - -internal void -ClearRenderBuffer (render_command_buffer* Buffer) -{ - Buffer->CommandMemoryUsed = 0; -} - -#define FOLDHAUS_RENDERER_CPP -#endif // FOLDHAUS_RENDERER_CPP \ No newline at end of file diff --git a/src/app/foldhaus_renderer.h b/src/app/foldhaus_renderer.h deleted file mode 100644 index 6e48836..0000000 --- a/src/app/foldhaus_renderer.h +++ /dev/null @@ -1,719 +0,0 @@ -// -// File: foldhaus_renderer.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef FOLDHAUS_RENDERER_H - -#define IMMEDIATE_MODE_RENDERING 0 - -struct camera -{ - r32 FieldOfView; - r32 AspectRatio; - r32 Near, Far; - v3 Position; - v3 LookAt; -}; - -inline m44 -GetCameraModelViewMatrix (camera Camera) -{ - m44 RotationMatrix = M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt)); - m44 PositionMatrix = M44Translation(ToV4Point(-Camera.Position)); - m44 ModelViewMatrix = RotationMatrix * PositionMatrix; - return ModelViewMatrix; -} - -inline m44 -GetCameraPerspectiveProjectionMatrix(camera Camera) -{ - m44 Result = M44ProjectionPerspective(Camera.FieldOfView, Camera.AspectRatio, Camera.Near, Camera.Far); - return Result; -} - -internal m44 -GetCameraMatrix(camera Camera) -{ - m44 ModelView = GetCameraModelViewMatrix(Camera); - m44 Projection = GetCameraPerspectiveProjectionMatrix(Camera); - m44 Result = Projection * ModelView; - return Result; -} - -internal v2 -ProjectWorldPointToScreen(v4 WorldSpacePoint, camera Camera, rect2 WindowBounds) -{ - v2 WindowExtents = v2{Rect2Width(WindowBounds), Rect2Height(WindowBounds)}; - v4 ProjectedPosition = GetCameraMatrix(Camera) * WorldSpacePoint; - ProjectedPosition.xyz /= ProjectedPosition.w; - v2 ScreenPosition = V2MultiplyPairwise(ProjectedPosition.xy, (WindowExtents / 2)) + (WindowExtents / 2); - - return ScreenPosition; -} - -internal v4_ray -ProjectScreenPointToWorldRay(v2 ScreenPoint, camera Camera, rect2 WindowBounds) -{ - v4_ray Result = {0}; - - r32 TanFOVOverTwo = TanR32(DegToRadR32(Camera.FieldOfView / 2.0f)); - r32 Aspect = RectAspectRatio(WindowBounds); - - r32 NormalizedX = ScreenPoint.x / Rect2Width(WindowBounds); - r32 NormalizedY = ScreenPoint.y / Rect2Height(WindowBounds); - - r32 CenteredX = (2.0f * NormalizedX) - 1.0f; - r32 CenteredY = (2.0f * NormalizedY) - 1.0f; - - r32 ScaledX = CenteredX * Aspect; - r32 ScaledY = CenteredY; - - r32 CameraX = ScaledX * TanFOVOverTwo; - r32 CameraY = ScaledY * TanFOVOverTwo; - - r32 Near = Camera.Near; - r32 Far = Camera.Far; - v3 MousePointOnNearPlane = v3{CameraX, CameraY, -1} * Near; - v3 MousePointOnFarPlane = v3{CameraX, CameraY, -1} * Far; - - v4 MouseRayDirection = ToV4Vec(V3Normalize(MousePointOnFarPlane - MousePointOnNearPlane)); - m44 CameraTransform = M44Transpose(M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt))); - - Result.Origin = ToV4Point(Camera.Position); - Result.Direction = CameraTransform * MouseRayDirection; - - return Result; -} - -// Render Commands -// Discriminated Union -enum render_command_type -{ - RenderCommand_Invalid, - - RenderCommand_render_command_clear_screen, - RenderCommand_render_command_set_render_mode, - - RenderCommand_render_batch_command_quad_2d, - RenderCommand_render_batch_command_quad_3d, - RenderCommand_render_batch_command_texture_2d, - - RenderCommand_render_command_texture_3d, - - RenderCommand_Count -}; - -struct render_command_header -{ - render_command_type Type; -}; - -// NOTE(Peter): Just to keep with the rest of the system -struct render_command_clear_screen {}; - -struct render_quad_2d -{ - v2 Min, Max; -}; - -struct render_quad_3d -{ - v4 P0, P1, P2, P3; -}; - -struct render_texture -{ - u8* Memory; - s32 Handle; - s32 Width; - s32 Height; - s32 BytesPerPixel; - s32 Stride; -}; - -#define BATCH_3D_SIZE(tricount) (((sizeof(v4) + sizeof(v2) + sizeof(v4)) * 3) * tricount) -#define BATCH_3D_VERTECIES_OFFSET(tricount) (0 * tricount) -#define BATCH_3D_UVS_OFFSET(tricount) (BATCH_3D_VERTECIES_OFFSET(tricount) + ((sizeof(v4) * 3) * tricount)) -#define BATCH_3D_COLORS_OFFSET(tricount) (BATCH_3D_UVS_OFFSET(tricount) + ((sizeof(v2) * 3) * tricount)) -#define BATCH_3D_VERTEX_INDEX(tri, v) ((tri * 3) + v) -#define BATCH_3D_UV_INDEX(tri, v) ((tri * 3) + v) -#define BATCH_3D_COLOR_INDEX(tri, v) ((tri * 3) + v) - -#define BATCH_2D_SIZE(quadcount) (((sizeof(v2) + sizeof(v2) + sizeof(v4)) * 3) * 2 * quadcount) -#define BATCH_2D_VERTECIES_OFFSET(quadcount) (0 * quadcount) -#define BATCH_2D_UVS_OFFSET(quadcount) (BATCH_2D_VERTECIES_OFFSET(quadcount) + ((sizeof(v2) * 3) * 2 * quadcount)) -#define BATCH_2D_COLORS_OFFSET(quadcount) (BATCH_2D_UVS_OFFSET(quadcount) + ((sizeof(v2) * 3) * 2 * quadcount)) -#define BATCH_2D_VERTEX_INDEX(quad, tri, v) ((quad * 6) + (tri * 3) + v) -#define BATCH_2D_UV_INDEX(quad, tri, v) ((quad * 6) + (tri * 3) + v) -#define BATCH_2D_COLOR_INDEX(quad, tri, v) ((quad * 6) + (tri * 3) + v) - -struct render_quad_batch_constructor -{ - s32 Max; - s32 Count; - - v4* Vertecies; - v2* UVs; - v4* ColorsV; -}; - -struct render_batch_command_quad_2d -{ - s32 QuadCount; - s32 DataSize; - // NOTE(Peter): The data immediately follows the command in memory -}; - -struct render_batch_command_quad_3d -{ - s32 QuadCount; - s32 DataSize; - // NOTE(Peter): The data immediately follows the command in memory -}; - -struct render_command_texture_2d -{ - render_quad_2d Quad; - render_quad_2d UV; - v4 Color; - render_texture Texture; -}; - -struct render_batch_command_texture_2d -{ - s32 QuadCount; - s32 DataSize; - render_texture Texture; -}; - -struct render_command_texture_3d -{ - render_quad_3d Quad; - v4 Color; - render_texture Texture; -}; - -struct render_command_set_render_mode -{ - m44 ModelView; - m44 Projection; - r32 ViewOffsetX, ViewOffsetY; - r32 ViewWidth, ViewHeight; - b32 UseDepthBuffer; -}; - -typedef u8* renderer_realloc(u8* Base, s32 CurrentSize, s32 NewSize); - -#define COMMAND_BUFFER_MIN_GROW_SIZE MB(2) - -struct render_command_buffer -{ - u8* CommandMemory; - s32 CommandMemoryUsed; - s32 CommandMemorySize; - - gs_thread_context Ctx; - - s32 ViewWidth; - s32 ViewHeight; -}; - -/// -// Utility -/// - -internal u32 -PackColorStructU8 (u8 R, u8 G, u8 B, u8 A) -{ - u32 Result = (u32)(A << 24 | - R << 16 | - G << 8 | - B<< 0); - return Result; -} - -internal u32 -PackColorStructR32 (r32 In_R, r32 In_G, r32 In_B, r32 In_A) -{ - Assert ((In_R >= 0.0f && In_R <= 1.0f) && - (In_G >= 0.0f && In_G <= 1.0f) && - (In_B >= 0.0f && In_B <= 1.0f) && - (In_A >= 0.0f && In_A <= 1.0f)); - - u8 R = (u8)(255 * In_R); - u8 G = (u8)(255 * In_G); - u8 B = (u8)(255 * In_B); - u8 A = (u8)(255 * In_A); - - u32 Result = (u32)(A << 24 | - R << 16 | - G << 8 | - B<< 0); - return Result; -} - -internal void -ResizeBufferIfNecessary(render_command_buffer* Buffer, s32 DataSize) -{ - if (Buffer->CommandMemoryUsed + DataSize > Buffer->CommandMemorySize) - { - // NOTE(Peter): If this becomes a problem just go back to the original solution of - // NewSize = Buffer->CommandMemorySize + (2 * DataSize); - s32 SpaceAvailable = Buffer->CommandMemorySize - Buffer->CommandMemoryUsed; - s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point - s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE); - s32 NewSize = Buffer->CommandMemorySize + AdditionSize; - - Free(Buffer->Ctx.Allocator, Buffer->CommandMemory, Buffer->CommandMemorySize); - Buffer->CommandMemory = Alloc(Buffer->Ctx.Allocator, NewSize, "Renderer"); - Buffer->CommandMemorySize = NewSize; - } -} - -// Batch - -internal s32 -PushQuad3DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* Constructor, u8* MemStart, s32 TriCount, s32 DataSize, b32 UseIntegerColor = false) -{ - Constructor->Max = TriCount; - Constructor->Count = 0; - - Constructor->Vertecies = (v4*)(MemStart + BATCH_3D_VERTECIES_OFFSET(TriCount)); - Constructor->UVs = (v2*)(MemStart + BATCH_3D_UVS_OFFSET(TriCount)); - Constructor->ColorsV = (v4*)(MemStart + BATCH_3D_COLORS_OFFSET(TriCount)); - - Buffer->CommandMemoryUsed += DataSize; - return DataSize; -} - -internal s32 -PushQuad2DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* Constructor, s32 QuadCount, s32 DataSize, u8* MemStart) -{ - ZeroMemoryBlock(MemStart, DataSize); - - Constructor->Max = QuadCount; - Constructor->Count = 0; - - Constructor->Vertecies = (v4*)(MemStart + BATCH_2D_VERTECIES_OFFSET(QuadCount)); - Constructor->UVs = (v2*)(MemStart + BATCH_2D_UVS_OFFSET(QuadCount)); - Constructor->ColorsV = (v4*)(MemStart + BATCH_2D_COLORS_OFFSET(QuadCount)); - - Buffer->CommandMemoryUsed += DataSize; - return DataSize; -} - -internal s32 -ThreadSafeIncrementQuadConstructorCount (render_quad_batch_constructor* Constructor) -{ - s32 Result = InterlockedIncrement((long*)&Constructor->Count); - // NOTE(Peter): Have to decrement the value by one. - // Interlocked Increment acts as (++Constructor->Count), not (Constructor->Count++) which - // is what we wanted; - // This was causing the first triangle to be garbage data. - Result -= 1; - return Result; -} - -struct quad_batch_constructor_reserved_range -{ - s32 Start; - s32 OnePastLast; -}; - -internal quad_batch_constructor_reserved_range -ReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded) -{ - quad_batch_constructor_reserved_range Result = {}; - Result.OnePastLast = Constructor->Count + TrisNeeded; - Constructor->Count = Result.OnePastLast; - Result.Start = Result.OnePastLast - TrisNeeded; - return Result; -} - -internal quad_batch_constructor_reserved_range -ThreadSafeReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded) -{ - quad_batch_constructor_reserved_range Result = {}; - Result.OnePastLast = InterlockedAdd((long*)&Constructor->Count, TrisNeeded); - Result.Start = Result.OnePastLast - TrisNeeded; - return Result; -} - -inline void -SetTri3DInBatch (render_quad_batch_constructor* Constructor, s32 TriIndex, - v4 P0, v4 P1, v4 P2, - v2 UV0, v2 UV1, v2 UV2, - v4 C0, v4 C1, v4 C2) -{ - //Assert(P0.w != 0 && P1.w != 0 && P2.w != 0); // Passing vectors, rather than positions. Will draw wrong - - // Vertecies - Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 0)] = P0; - Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 1)] = P1; - Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 2)] = P2; - - // UVs - Constructor->UVs[BATCH_3D_UV_INDEX(TriIndex, 0)] = UV0; - Constructor->UVs[BATCH_3D_UV_INDEX(TriIndex, 1)] = UV1; - Constructor->UVs[BATCH_3D_UV_INDEX(TriIndex, 2)] = UV1; - - // Color V0 - Constructor->ColorsV[BATCH_3D_COLOR_INDEX(TriIndex, 0)] = C0; - Constructor->ColorsV[BATCH_3D_COLOR_INDEX(TriIndex, 1)] = C1; - Constructor->ColorsV[BATCH_3D_COLOR_INDEX(TriIndex, 2)] = C2; -} - - -inline void -PushTri3DOnBatch (render_quad_batch_constructor* Constructor, - v4 P0, v4 P1, v4 P2, - v2 UV0, v2 UV1, v2 UV2, - v4 C0, v4 C1, v4 C2) -{ - DEBUG_TRACK_FUNCTION; - // TODO(Peter): I think we avoid doing cross thread filling of a batch so do we need this? - s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor); - SetTri3DInBatch(Constructor, Tri, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2); -}; - -internal void -PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color) -{ - Assert(Constructor->Count + 2 <= Constructor->Max); - PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color, Color, Color); - PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color, Color, Color); -} - -internal void -PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, - v4 P0, v4 P1, v4 P2, v4 P3, - v2 UV0, v2 UV1, v2 UV2, v2 UV3, - v4 C0, v4 C1, v4 C2, v4 C3) -{ - Assert(Constructor->Count <= Constructor->Max); - PushTri3DOnBatch(Constructor, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2); - PushTri3DOnBatch(Constructor, P0, P2, P3, UV0, UV2, UV3, C0, C2, C3); -} - -internal void -PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v4 Color) -{ - PushQuad3DOnBatch(Constructor, P0, P1, P2, P3, v2{0, 0}, v2{1, 1}, Color); -} - -internal void -PushQuad2DOnBatch (render_quad_batch_constructor* Constructor, - v2 P0, v2 P1, v2 P2, v2 P3, - v2 UV0, v2 UV1, v2 UV2, v2 UV3, - v4 C0, v4 C1, v4 C2, v4 C3) -{ - DEBUG_TRACK_FUNCTION; - - s32 Quad = ThreadSafeIncrementQuadConstructorCount(Constructor); - v2* Vertecies = (v2*)Constructor->Vertecies; - - // Tri 1 - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 0, 0)] = P0; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 0, 1)] = P1; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 0, 2)] = P2; - - // Tri 2 - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 1, 0)] = P0; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 1, 1)] = P2; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 1, 2)] = P3; - - // Tri 1 UVs - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 0, 0)] = UV0; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 0, 1)] = UV1; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 0, 2)] = UV2; - // Tri 2 UVs - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 1, 0)] = UV0; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 1, 1)] = UV2; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 1, 2)] = UV3; - - // Tri 1 Colors - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 0, 0)] = C0; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 0, 1)] = C1; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 0, 2)] = C2; - // Tri 2 Colors - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 1, 0)] = C0; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 1, 1)] = C2; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 1, 2)] = C3; -} - -internal void -PushQuad2DOnBatch (render_quad_batch_constructor* Constructor, v2 P0, v2 P1, v2 P2, v2 P3, v2 UVMin, v2 UVMax, v4 Color) -{ - DEBUG_TRACK_FUNCTION; - - s32 Quad = ThreadSafeIncrementQuadConstructorCount(Constructor); - v2* Vertecies = (v2*)Constructor->Vertecies; - - // Tri 1 - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 0, 0)] = P0; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 0, 1)] = P1; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 0, 2)] = P2; - - // Tri 2 - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 1, 0)] = P0; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 1, 1)] = P2; - Vertecies[BATCH_2D_VERTEX_INDEX(Quad, 1, 2)] = P3; - - // Tri 1 UVs - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 0, 0)] = UVMin; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 0, 1)] = v2{UVMax.x, UVMin.y}; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 0, 2)] = UVMax; - // Tri 2 UVs - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 1, 0)] = UVMin; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 1, 1)] = UVMax; - Constructor->UVs[BATCH_2D_UV_INDEX(Quad, 1, 2)] = v2{UVMin.x, UVMax.y}; - - // Tri 1 Colors - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 0, 0)] = Color; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 0, 1)] = Color; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 0, 2)] = Color; - // Tri 2 Colors - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 1, 0)] = Color; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 1, 1)] = Color; - Constructor->ColorsV[BATCH_2D_COLOR_INDEX(Quad, 1, 2)] = Color; -} - -internal void -PushQuad2DOnBatch (render_quad_batch_constructor* Constructor, v2 Min, v2 Max, v4 Color) -{ - PushQuad2DOnBatch(Constructor, v2{Min.x, Min.y}, v2{Max.x, Min.y}, v2{Max.x, Max.y}, v2{Min.x, Max.y}, - v2{0, 0}, v2{1, 1}, Color); -} - -internal void -PushQuad2DOnBatch (render_quad_batch_constructor* Constructor, rect2 Rect, v4 Color) -{ - PushQuad2DOnBatch(Constructor, v2{Rect.Min.x, Rect.Min.y}, v2{Rect.Max.x, Rect.Min.y}, v2{Rect.Max.x, Rect.Max.y}, v2{Rect.Min.x, Rect.Max.y}, - v2{0, 0}, v2{1, 1}, Color); -} - -internal void -PushLine2DOnBatch (render_quad_batch_constructor* Constructor, v2 P0, v2 P1, r32 Thickness, v4 Color) -{ - r32 HalfThickness = Thickness / 2.0f; - v2 Perpendicular = V2Normalize(V2PerpendicularCCW(P1 - P0)) * HalfThickness; - - PushQuad2DOnBatch(Constructor, P0 - Perpendicular, P1 - Perpendicular, P1 + Perpendicular, P0 + Perpendicular, - v2{0, 0}, v2{1, 1}, Color); -} - -// Commands -#define PushRenderCommand(buffer, type) (type*) PushRenderCommand_(buffer, RenderCommand_##type, sizeof(type) + sizeof(render_command_header)) - -internal u8* -PushRenderCommand_ (render_command_buffer* CommandBuffer, render_command_type CommandType, s32 CommandSize) -{ - ResizeBufferIfNecessary(CommandBuffer, CommandSize); - Assert(CommandBuffer->CommandMemoryUsed + CommandSize <= CommandBuffer->CommandMemorySize); - - render_command_header* Header = (render_command_header*)(CommandBuffer->CommandMemory + CommandBuffer->CommandMemoryUsed); - Header->Type = CommandType; - - u8* Result = (u8*)(Header + 1); - CommandBuffer->CommandMemoryUsed += CommandSize; - - return Result; -} - -internal render_command_set_render_mode* -PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight, camera Camera) -{ - render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode); - - Command->ModelView = M44Transpose(GetCameraModelViewMatrix(Camera)); - Command->Projection = M44Transpose(GetCameraPerspectiveProjectionMatrix(Camera)); - - Command->ViewOffsetX = (r32)OffsetX; - Command->ViewOffsetY = (r32)OffsetY; - Command->ViewWidth = (r32)ViewWidth; - Command->ViewHeight = (r32)ViewHeight; - - Command->UseDepthBuffer = true; - - return Command; -} - -internal void -PushRenderPerspective(render_command_buffer* Buffer, rect2 Viewport, camera Camera) -{ - PushRenderPerspective(Buffer, Viewport.Min.x, Viewport.Min.y, Rect2Width(Viewport), Rect2Height(Viewport), Camera); -} - -internal void -PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight) -{ - render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode); - Command->ModelView = M44Identity(); - Command->Projection = M44ProjectionOrtho((r32)ViewWidth, (r32)ViewHeight, 0, 100, ViewWidth, 0, ViewHeight, 0); - - Command->ViewOffsetX = (r32)OffsetX; - Command->ViewOffsetY = (r32)OffsetY; - Command->ViewWidth = ViewWidth; - Command->ViewHeight = ViewHeight; - - Command->UseDepthBuffer = false;; -} - -internal void -PushRenderOrthographic(render_command_buffer* Buffer, rect2 Viewport) -{ - PushRenderOrthographic(Buffer, Viewport.Min.x, Viewport.Min.y, Rect2Width(Viewport), Rect2Height(Viewport)); -} - -internal void -PushRenderClearScreen (render_command_buffer* Buffer) -{ - render_command_clear_screen* Command = PushRenderCommand(Buffer, render_command_clear_screen); -} - -internal render_quad_batch_constructor -PushRenderQuad2DBatch(render_command_buffer* Buffer, s32 QuadCount) -{ - s32 DataSize = BATCH_2D_SIZE(QuadCount); - ResizeBufferIfNecessary(Buffer, DataSize + sizeof(render_batch_command_quad_2d)); - Assert(Buffer->CommandMemoryUsed + DataSize <= Buffer->CommandMemorySize); - - render_quad_batch_constructor Result = {}; - - render_batch_command_quad_2d* Command = PushRenderCommand(Buffer, render_batch_command_quad_2d); - Command->QuadCount = QuadCount; - Command->DataSize = PushQuad2DBatch(Buffer, &Result, QuadCount, DataSize, (u8*)(Command + 1)); - - return Result; -} - -internal void -PushRenderQuad2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 Color) -{ - render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 1); - PushQuad2DOnBatch(&Batch, Min, Max, Color); -} - -internal void -PushRenderQuad2D (render_command_buffer* Buffer, rect2 Rect, v4 Color) -{ - render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 1); - PushQuad2DOnBatch(&Batch, Rect.Min, Rect.Max, Color); -} - -internal void -PushRenderQuad2DClipped (render_command_buffer* Buffer, rect2 Rect, rect2 ClippingBox, v4 Color) -{ - rect2 Clipped = Rect2Union(Rect, ClippingBox); - render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 1); - PushQuad2DOnBatch(&Batch, Clipped.Min, Clipped.Max, Color); -} - -internal void -PushRenderQuad2D(render_command_buffer* Buffer, v2 P0, v2 P1, v2 P2, v2 P3, v4 Color) -{ - render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 1); - PushQuad2DOnBatch(&Batch, P0, P1, P2, P3, v2{0,0}, v2{1,1}, Color); -} - -internal void -PushRenderLine2D (render_command_buffer* Buffer, v2 P0, v2 P1, r32 Thickness, v4 Color) -{ - render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 1); - PushLine2DOnBatch(&Batch, P0, P1, Thickness, Color); -} - - -internal render_quad_batch_constructor -PushRenderQuad3DBatch(render_command_buffer* Buffer, s32 QuadCount) -{ - s32 TriCount = QuadCount * 2; - s32 DataSize = BATCH_3D_SIZE(TriCount); - ResizeBufferIfNecessary(Buffer, DataSize + sizeof(render_batch_command_quad_3d)); - Assert(Buffer->CommandMemoryUsed + DataSize <= Buffer->CommandMemorySize); - - render_quad_batch_constructor Result = {}; - - render_batch_command_quad_3d* Command = PushRenderCommand(Buffer, render_batch_command_quad_3d); - Command->QuadCount = QuadCount; - Command->DataSize = PushQuad3DBatch(Buffer, &Result, (u8*)(Command + 1), TriCount, DataSize); - - return Result; -} - -internal void -PushRenderQuad3D (render_command_buffer* Buffer, v4 A, v4 B, v4 C, v4 D, v4 Color) -{ - render_quad_batch_constructor Batch = PushRenderQuad3DBatch(Buffer, 1); - PushQuad3DOnBatch(&Batch, A, B, C, D, Color); -} - -internal void -PushRenderCameraFacingQuad (render_command_buffer* Buffer, v4 Center, v2 Dimensions, v4 Color) -{ - // TODO(Peter): Turn this into an actual camera facing quad - v4 A = v4{Center.x - Dimensions.x, Center.y - Dimensions.y, Center.z, Center.w}; - v4 B = v4{Center.x + Dimensions.x, Center.y - Dimensions.y, Center.z, Center.w}; - v4 C = v4{Center.x + Dimensions.x, Center.y + Dimensions.y, Center.z, Center.w}; - v4 D = v4{Center.x - Dimensions.x, Center.y + Dimensions.y, Center.z, Center.w}; - - PushRenderQuad3D(Buffer, A, B, C, D, Color); -} - -internal render_quad_batch_constructor -PushRenderTexture2DBatch(render_command_buffer* Buffer, s32 QuadCount, - render_texture Texture) -{ - s32 DataSize = BATCH_2D_SIZE(QuadCount); - ResizeBufferIfNecessary(Buffer, DataSize); - Assert(Buffer->CommandMemoryUsed + DataSize <= Buffer->CommandMemorySize); - - render_quad_batch_constructor Result = {}; - - render_batch_command_texture_2d* Command = PushRenderCommand(Buffer, render_batch_command_texture_2d); - Command->QuadCount = QuadCount; - Command->DataSize = PushQuad2DBatch(Buffer, &Result, QuadCount, DataSize, (u8*)(Command + 1)); - Command->Texture = Texture; - - return Result; -} - -internal render_quad_batch_constructor -PushRenderTexture2DBatch (render_command_buffer* Buffer, s32 QuadCount, - u8* TextureMemory, s32 TextureHandle, s32 TextureWidth, s32 TextureHeight, - s32 TextureBytesPerPixel, s32 TextureStride) -{ - render_texture Texture = render_texture{ - TextureMemory, - TextureHandle, - TextureWidth, - TextureHeight, - TextureBytesPerPixel, - TextureStride}; - return PushRenderTexture2DBatch(Buffer, QuadCount, Texture); -} - -internal void -PushRenderTexture2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 Color, - v2 UVMin, v2 UVMax, - render_texture* Texture) -{ - render_quad_batch_constructor Batch = PushRenderTexture2DBatch(Buffer, 1, *Texture); - PushQuad2DOnBatch(&Batch, v2{Min.x, Min.y}, v2{Max.x, Min.y}, v2{Max.x, Max.y}, v2{Min.x, Max.y}, - UVMin, UVMax, Color); -} - -internal void -PushRenderBoundingBox2D (render_command_buffer* Buffer, v2 Min, v2 Max, r32 Thickness, v4 Color) -{ - render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 4); - PushQuad2DOnBatch(&Batch, Min, v2{Min.x + Thickness, Max.y}, Color); - PushQuad2DOnBatch(&Batch, v2{Min.x, Max.y - Thickness}, Max, Color); - PushQuad2DOnBatch(&Batch, v2{Max.x - Thickness, Min.y}, Max, Color); - PushQuad2DOnBatch(&Batch, Min, v2{Max.x, Min.y + Thickness}, Color); -} - - -#define FOLDHAUS_RENDERER_H -#endif // FOLDHAUS_RENDERER_H \ No newline at end of file diff --git a/src/app/generated/foldhaus_nodes_generated.h b/src/app/generated/foldhaus_nodes_generated.h deleted file mode 100644 index 8e9f0f8..0000000 --- a/src/app/generated/foldhaus_nodes_generated.h +++ /dev/null @@ -1,32 +0,0 @@ -enum node_type -{ - NodeType_SolidColorProc, - NodeType_RevolvingDiscs, - NodeType_VerticalColorFadeProc, - NodeType_Count, -}; - -static node_specification_ NodeSpecifications[] = { -{ NodeType_SolidColorProc, {"SolidColorProc", 14}, gsm_StructType_solid_color_data }, -{ NodeType_RevolvingDiscs, {"RevolvingDiscs", 14}, gsm_StructType_revolving_discs_data }, -{ NodeType_VerticalColorFadeProc, {"VerticalColorFadeProc", 21}, gsm_StructType_vertical_color_fade_data }, -}; - -void CallNodeProc(node_type Type, u8* NodeData) -{ - switch(Type) { - case NodeType_SolidColorProc: - { - SolidColorProc((solid_color_data*)NodeData); - } break; - case NodeType_RevolvingDiscs: - { - RevolvingDiscs((revolving_discs_data*)NodeData); - } break; - case NodeType_VerticalColorFadeProc: - { - VerticalColorFadeProc((vertical_color_fade_data*)NodeData); - } break; - } -} - diff --git a/src/app/generated/foldhaus_panels_generated.h b/src/app/generated/foldhaus_panels_generated.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/generated/gs_meta_generated_typeinfo.h b/src/app/generated/gs_meta_generated_typeinfo.h deleted file mode 100644 index 9477f54..0000000 --- a/src/app/generated/gs_meta_generated_typeinfo.h +++ /dev/null @@ -1,110 +0,0 @@ -enum gsm_meta_tag_type -{ - MetaTag_panel_type_file_view, - MetaTag_panel_type_node_graph, - MetaTag_node_output, - MetaTag_node_struct, - MetaTag_panel_cleanup, - MetaTag_node_input, - MetaTag_panel_init, - MetaTag_panel_type_animation_timeline, - MetaTag_panel_commands, - MetaTag_panel_type_sculpture_view, - MetaTag_node_proc, - MetaTag_panel_type_hierarchy, - MetaTag_panel_type_profiler, - MetaTag_panel_render, - MetaTag_panel_type_dmx_view, -}; -gsm_meta_tag MetaTaggs_strings[] = { - { "panel_type_file_view", 20 }, - { "panel_type_node_graph", 21 }, - { "node_output", 11 }, - { "node_struct", 11 }, - { "panel_cleanup", 13 }, - { "node_input", 10 }, - { "panel_init", 10 }, - { "panel_type_animation_timeline", 29 }, - { "panel_commands", 14 }, - { "panel_type_sculpture_view", 25 }, - { "node_proc", 9 }, - { "panel_type_hierarchy", 20 }, - { "panel_type_profiler", 19 }, - { "panel_render", 12 }, - { "panel_type_dmx_view", 19 }, -}; -enum gsm_struct_type -{ - gsm_StructType_r32, - gsm_StructType_solid_color_data, - gsm_StructType_v4, - gsm_StructType_float, - gsm_StructType_color_buffer, - gsm_StructType_pixel, - gsm_StructType_u8, - gsm_StructType_s32, - gsm_StructType_revolving_discs_data, - gsm_StructType_vertical_color_fade_data, - gsm_StructType_Count, -}; - -static gsm_struct_member_type_info StructMembers_v4[] = { - { "x", 1, (u64)&((v4*)0)->x, {}, 0}, - { "y", 1, (u64)&((v4*)0)->y, {}, 0}, - { "z", 1, (u64)&((v4*)0)->z, {}, 0}, - { "w", 1, (u64)&((v4*)0)->w, {}, 0}, - { "r", 1, (u64)&((v4*)0)->r, {}, 0}, - { "g", 1, (u64)&((v4*)0)->g, {}, 0}, - { "b", 1, (u64)&((v4*)0)->b, {}, 0}, - { "a", 1, (u64)&((v4*)0)->a, {}, 0}, - { "xy", 2, (u64)&((v4*)0)->xy, {}, 0}, - { "yz", 2, (u64)&((v4*)0)->yz, {}, 0}, - { "xyz", 3, (u64)&((v4*)0)->xyz, {}, 0}, - { "z", 1, (u64)&((v4*)0)->z, {}, 0}, - { "E", 1, (u64)&((v4*)0)->E, {}, 0}, -}; -static gsm_struct_member_type_info StructMembers_pixel[] = { - { "R", 1, (u64)&((pixel*)0)->R, {}, 0}, - { "G", 1, (u64)&((pixel*)0)->G, {}, 0}, - { "B", 1, (u64)&((pixel*)0)->B, {}, 0}, - { "Channels", 8, (u64)&((pixel*)0)->Channels, {}, 0}, -}; -static gsm_struct_member_type_info StructMembers_color_buffer[] = { - { "LedPositions", 12, (u64)&((color_buffer*)0)->LedPositions, {}, 0}, - { "Colors", 6, (u64)&((color_buffer*)0)->Colors, {}, 0}, - { "LEDCount", 8, (u64)&((color_buffer*)0)->LEDCount, {}, 0}, -}; -static gsm_struct_member_type_info StructMembers_solid_color_data[] = { - { "Color", 5, (u64)&((solid_color_data*)0)->Color, {MetaTag_node_input, }, 1}, - { "Result", 6, (u64)&((solid_color_data*)0)->Result, {MetaTag_node_output, }, 1}, -}; -static gsm_struct_member_type_info StructMembers_revolving_discs_data[] = { - { "Rotation", 8, (u64)&((revolving_discs_data*)0)->Rotation, {MetaTag_node_input, }, 1}, - { "ThetaZ", 6, (u64)&((revolving_discs_data*)0)->ThetaZ, {MetaTag_node_input, }, 1}, - { "ThetaY", 6, (u64)&((revolving_discs_data*)0)->ThetaY, {MetaTag_node_input, }, 1}, - { "DiscWidth", 9, (u64)&((revolving_discs_data*)0)->DiscWidth, {MetaTag_node_input, }, 1}, - { "InnerRadius", 11, (u64)&((revolving_discs_data*)0)->InnerRadius, {MetaTag_node_input, }, 1}, - { "OuterRadius", 11, (u64)&((revolving_discs_data*)0)->OuterRadius, {MetaTag_node_input, }, 1}, - { "Color", 5, (u64)&((revolving_discs_data*)0)->Color, {MetaTag_node_input, }, 1}, - { "Result", 6, (u64)&((revolving_discs_data*)0)->Result, {MetaTag_node_output, }, 1}, -}; -static gsm_struct_member_type_info StructMembers_vertical_color_fade_data[] = { - { "Color", 5, (u64)&((vertical_color_fade_data*)0)->Color, {MetaTag_node_input, }, 1}, - { "Min", 3, (u64)&((vertical_color_fade_data*)0)->Min, {MetaTag_node_input, }, 1}, - { "Max", 3, (u64)&((vertical_color_fade_data*)0)->Max, {MetaTag_node_input, }, 1}, - { "Result", 6, (u64)&((vertical_color_fade_data*)0)->Result, {MetaTag_node_output, }, 1}, -}; - -static gsm_struct_type_info StructTypes[] = { - { gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 }, - { gsm_StructType_solid_color_data, "solid_color_data", 16, 32, 0, 0, StructMembers_solid_color_data, 2 }, - { gsm_StructType_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 5 }, - { gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 }, - { gsm_StructType_color_buffer, "color_buffer", 12, 16, 0, 0, StructMembers_color_buffer, 3 }, - { gsm_StructType_pixel, "pixel", 5, 0, 0, 0, StructMembers_pixel, 2 }, - { gsm_StructType_u8, "u8", 2, 0, 0, 0, 0, 0 }, - { gsm_StructType_s32, "s32", 3, 0, 0, 0, 0, 0 }, - { gsm_StructType_revolving_discs_data, "revolving_discs_data", 20, 56, 0, 0, StructMembers_revolving_discs_data, 8 }, - { gsm_StructType_vertical_color_fade_data, "vertical_color_fade_data", 24, 40, 0, 0, StructMembers_vertical_color_fade_data, 4 }, -}; -static gsm_u32 StructTypesCount = 12; diff --git a/src/app/patterns/blumen_patterns.h b/src/app/patterns/blumen_patterns.h deleted file mode 100644 index 6530ccd..0000000 --- a/src/app/patterns/blumen_patterns.h +++ /dev/null @@ -1,879 +0,0 @@ -// -// File: blumen_patterns.h -// Author: Peter Slattery -// Creation Date: 2021-01-15 -// -#ifndef BLUMEN_PATTERNS_H - -#define FLOWER_COLORS_COUNT 12 - -internal void -Pattern_None(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - // just here so you can fade in from black -} - -internal void -Pattern_AltBloomMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - v3 SphereCenter = Assembly.Center - v3{0, -150, 0}; - r32 SphereRadius = Time; - r32 SphereBrightness = 1; - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - r32 Sphere = SDF_SphereNormalized(P, SphereCenter, SphereRadius); - Sphere = Clamp01(-Sphere); - Leds->Colors[LedIndex] = V4ToRGBPixel(WhiteV4 * Sphere); - } -} - -internal void -Pattern_HueShift(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - r32 Height = SinR32(Time) * 25; - - r32 CycleLength = 5.0f; - r32 CycleProgress = FractR32(Time / CycleLength); - r32 CycleBlend = (SinR32(Time) * .5f) + .5f; - -#if 0 - phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3]; - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - v4 HSV = {}; - if (CycleProgress < .25f) - { - r32 P = CycleProgress * 4; - HSV = V4Lerp(C0, - } - else if (CycleProgress >= .25f && CycleProgress < .5f) - { - - } - else if (CycleProgress >= .5f && CycleProgress < .75f) - { - - } - else if (CycleProgress >= .75f) - { - - } -#endif - - v4 HSV = { CycleProgress * 360, 1, 1, 1 }; - v4 RGB = HSVToRGB(HSV); - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v4 Pos = Leds->Positions[LedIndex]; - r32 Dist = Pos.y - Height; - - //v4 HSV = { (ModR32(Dist, 25) / 25) * 360, 1, 1, 1 }; - //v4 RGB = HSVToRGB(HSV); - - u8 R = (u8)(RGB.x * 255); - u8 G = (u8)(RGB.y * 255); - u8 B = (u8)(RGB.z * 255); - - Leds->Colors[LedIndex].R = R; - Leds->Colors[LedIndex].G = G; - Leds->Colors[LedIndex].B = B; - } -} - -internal void -Pattern_Rainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - r32 HueBase = ModR32(Time * 50, 360); - - r32 CycleLength = 5.0f; - r32 CycleProgress = FractR32(Time / CycleLength); - r32 CycleBlend = (SinR32(Time) * .5f) + .5f; - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v4 Pos = Leds->Positions[LedIndex]; - r32 Hue = HueBase + Pos.y + Pos.x; - v4 HSV = { Hue, 1, 1, 1 }; - v4 RGB = HSVToRGB(HSV); - - Leds->Colors[LedIndex] = V4ToRGBPixel(RGB); - } -} - -internal void -Pattern_RadialRainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) }); - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v2 Vector = v2{ - Leds->Positions[LedIndex].x, - Leds->Positions[LedIndex].z - }; - Vector = V2Normalize(Vector); - - r32 Angle = V2Dot(RefVector, Vector); - - v4 HSV = { (Angle * 30) + (Time * 10), 1, 1, 1 }; - v4 RGB = HSVToRGB(HSV); - - Leds->Colors[LedIndex] = V4ToRGBPixel(RGB); - } -} - -internal void -Pattern_BasicFlowers(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3]; - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++) - { - v2_strip Strip = Assembly.Strips[StripIndex]; - r32 CycleT = ModR32(Time, 10) * 20; - - for (u32 i = 0; i < Strip.LedCount; i++) - { - u32 LedIndex = Strip.LedLUT[i]; - v4 P = Leds->Positions[LedIndex]; - - r32 T = ModR32(P.y + CycleT, 200) / 200.f; - T = Clamp01(T); - - v4 Color = {}; - if (T < 0.5f) - { - Color = V4Lerp(T * 2, C0, C1); - } - else - { - Color = V4Lerp((T - 0.5f) * 2, C1, C2); - } - Leds->Colors[LedIndex] = V4ToRGBPixel(Color); - } - } -} - -internal void -Pattern_WavyOptions(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 C0, v4 C1, v4 C2) -{ - r32 Top = 120 + (SinR32(Time) * 10); - r32 Mid = 70 + (CosR32(Time * 2.13) * 20); - r32 Bot = 0; - - r32 TopD = Top - Mid; - r32 BotD = Mid - Bot; - r32 MidD = Min(TopD, BotD); - - //r32 MaxFadeDistance = 10; - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - - r32 PercentTop = Clamp01(1.0f - ((Top - P.y) / TopD)); - - r32 PercentMid = Clamp01(1.0f - Abs(P.y - Mid) / MidD); - r32 N = Noise3D((P / 17) + v3{Time, -Time, 0}); - N = Clamp01(N) * 2; - N = Smoothstep(N); - N *= N; - N = Smoothstep(N); - N *= 1.0f - PowR32(1.0f - PercentMid, 4); - PercentMid = Clamp01(PercentMid + N); - - r32 PercentBot = Clamp01(1.0f - ((P.y - Bot) / BotD)); - - v4 TopC = (C0 * PercentTop); - v4 MidC = (C1 * PercentMid); - v4 BotC = (C2 * PercentBot); - - v4 C = {}; - if (PercentTop > PercentMid && PercentTop > PercentBot) - { - C = C0; - } - else if (PercentMid > PercentBot) - { - C = C1; - } - else - { - C = C2; - } - - r32 ScaleFactor = PercentTop + PercentMid + PercentBot; - C = (TopC + MidC + BotC) / ScaleFactor; - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } -} - -internal void -Pattern_Wavy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - Pattern_WavyOptions(Leds, Range, Assembly, Time, Transient, UserData, 1, C0, C1, C2); -} - -internal void -Pattern_PatchyOptions(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 C0, v4 C1, v4 C2) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - - r32 BaseGA = 50.000f * (1 / Granularity); - r32 BaseGB = 135.20f * (1 / Granularity); - r32 BaseGC = 260.74f * (1 / Granularity); - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v4 P = Leds->Positions[LedIndex]; - r32 LedRange = 300.0f; - r32 ScaleFactor = 1.0f / LedRange; - v3 Pp = P.xyz + v3{150, 100, 0}; - - r32 NoiseA = Noise3D((Pp / BaseGA) + v3{0, 0, Time}); - NoiseA = PowR32(NoiseA, 3); - NoiseA = Smoothstep(NoiseA); - - r32 NoiseB = Noise3D((Pp / BaseGB) + v3{Time * 0.5f, 0, 0}); - NoiseB = PowR32(NoiseB, 3); - NoiseB = Smoothstep(NoiseB); - -#if 1 - r32 NoiseC = Noise3D((Pp / BaseGC) + v3{Time * 0.5f, 0, 0}); - NoiseC = PowR32(NoiseC, 3); - NoiseC = Smoothstep(NoiseC); -#else - r32 NoiseC = 0; -#endif - - v4 C = (C0 * NoiseA) + (C1 * NoiseB) + (C2 * NoiseC); - C /= (NoiseA + NoiseB + NoiseC); - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } -} - -internal void -Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - Time = Time * BLState->PatternSpeed; - Pattern_PatchyOptions(Leds, Range, Assembly, Time, Transient, UserData, 5, C0, C1, C2); -} - -internal r32 -Leafy_BandSDF(v3 P, gs_random_series* Random, r32 Time) -{ - r32 MinBandThickness = 5; - r32 MaxBandThickness = 10; - r32 MaxTransitionPeriod = 120.0f; - - r32 BandTransitionPeriod = NextRandomUnilateral(Random) * MaxTransitionPeriod; - r32 BandTransitionBias = (1 - Clamp(0, (Time / (MaxTransitionPeriod / 2)), 0.7f)); // approaches 0.5 over time - BandTransitionPeriod *= BandTransitionBias; - - r32 BandPercent = ModR32(Time, BandTransitionPeriod) / BandTransitionPeriod; - BandPercent = Smoothstep(BandPercent); - r32 BandY = -150 + (BandPercent * 290); - - r32 ThickRand = NextRandomUnilateral(Random); - // 1 - 4((ThickRand - .5)^2) - distribution curve - ThickRand = 1.0f - ((4 * PowR32(ThickRand, 2)) - (4 * ThickRand) + 1); - r32 BandThickness = MinBandThickness + (ThickRand * (MaxBandThickness - MinBandThickness)); - - // BandBrightness = 1 - ((2x - 1) ^ 8) where x is BandPercent - r32 BandBrightness = 1.0f - PowR32((2 * BandPercent) - 1, 8); - BandBrightness *= RemapR32(NextRandomUnilateral(Random), 0, 1, .25f, 1); - r32 Result = 1 - Clamp01(Abs(P.y - BandY) / BandThickness); - Result *= BandBrightness; - return Result; -} - -internal void -Pattern_Leafy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed * .3f; - - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v4 P = Leds->Positions[LedIndex]; - - v4 C = {}; - r32 B = 0; - - // NOTE(PS): initializing the Random seed inside the Led Loop - // so that the bands are consistently calculated for each led - // ie. each time you calculate a band, the random numbers requested - // will always be the same - gs_random_series Random = InitRandomSeries(24601); - u32 BandCount = 25; - for (u32 Band = 0; Band < BandCount; Band++) - { - B += Leafy_BandSDF(P.xyz, &Random, Time); - } - B = Clamp01(B); - - C = WhiteV4 * B; - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } -} - -internal void -Pattern_LeafyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v4 P = Leds->Positions[LedIndex]; - v3 Pp = P.xyz + v3{150, 100, 0}; - - r32 NoiseA = Fbm3D((Pp / 18), Time * 0.25f); - NoiseA = Smoothstep(NoiseA); - - r32 NoiseB = Noise3D((Pp / 35) + v3{0, 0, Time * 0.5f}); - NoiseB = PowR32(NoiseB, 3); - NoiseB = Smoothstep(NoiseB); - - r32 NoiseC = Noise3D((Pp / 25) + v3{0, 0, Time * 4}); - r32 CPresence = SinR32((P.y / 50) - Time) + (0.8f * SinR32((P.y / 25) - (Time * 5.0f))); - CPresence = RemapR32(CPresence, -1.8, 1.8, 0, 1); - CPresence = PowR32(CPresence, 4); - NoiseC *= CPresence; - - v4 C = (C0 * NoiseA * 0.5f) + (C1 * NoiseB) + (C2 * NoiseC); - C *= 1.0f / (NoiseA + NoiseB + NoiseC); - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } -} - -internal void -Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; -} - -internal void -Pattern_VerticalLines(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - gs_random_series Random = InitRandomSeries(24601); - - r32 LightSpeedMin = 1; - r32 LightSpeedMax = 5; - - s32 LightTailLength = 60; - for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++) - { - v2_strip Strip = Assembly.Strips[StripIndex]; - - r32 LightStartHeight = NextRandomUnilateral(&Random); - r32 LightSpeed = LerpR32(NextRandomUnilateral(&Random), - LightSpeedMin, - LightSpeedMax); - r32 LightCurrentHeight = LightStartHeight + (LightSpeed * Time * 0.1f); - s32 StartIndex = (s32)(LightCurrentHeight * (r32)Strip.LedCount) % Strip.LedCount; - - for (s32 i = 0; i < LightTailLength; i++) - { - s32 StripLedIndex = StartIndex + i; - if (StripLedIndex >= (s32)Strip.LedCount) continue; - - u32 LedIndex = Strip.LedLUT[StripLedIndex]; - r32 PctTail = ((r32)i / (r32)LightTailLength); - v4 C = WhiteV4 * PctTail; - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } - } -} - -internal void -Pattern_RotaryOptions(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 BGColor, v4 FGColor) -{ - DEBUG_TRACK_FUNCTION; - - gs_random_series Random = InitRandomSeries((u32)(24601 * (Assembly.Center.x + 1.032f))); - -#define SphereCount 32 - v3 SphereCenter[SphereCount]; - - r32 G = RemapR32(Granularity, 1, 5, .75f, 2); - r32 MaxHeightOffset = 250; - r32 MaxSpeed = 10; - r32 SphereRotationRadius = 3.0f; - r32 SphereRadius = 2.0f / G; - for (u32 i = 0; i < SphereCount; i++) - { - r32 SphereSeedA = NextRandomUnilateral(&Random); - SphereSeedA = PowR32(SphereSeedA, 2); - r32 SphereSeedB = NextRandomBilateral(&Random); - r32 SphereSpeed = NextRandomUnilateral(&Random) * MaxSpeed; - - r32 SphereTime = Time + SphereSpeed; - r32 HeightOffset = 150 - (SphereSeedA * MaxHeightOffset); - r32 RotationOffset = SphereTime + SphereSeedB * TauR32; - r32 SphereRotationDir = NextRandomBilateral(&Random) < 0 ? -1 : 1; - v3 SpherePosOffset = v3{ - SinR32(RotationOffset * SphereRotationDir) * (SphereRotationRadius * 2), - HeightOffset, - CosR32(RotationOffset * SphereRotationDir) * (SphereRotationRadius * 2) - }; - SphereCenter[i] = Assembly.Center + SpherePosOffset; - } - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - - r32 Dist = 10000000; - for (u32 i = 0; i < SphereCount; i++) - { - r32 SphereSDF = Abs(SDF_Sphere(P, SphereCenter[i], SphereRadius)); - SphereSDF = SphereSDF / SphereRadius; - Dist = Min(Dist, SphereSDF); - } - - v4 C = BGColor; - if (Dist <= 1) - { - r32 Brightness = Clamp01(SphereRadius - Dist); - C = V4Lerp(Brightness, BGColor, FGColor); - } - - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } -} - -internal void -Pattern_Rotary(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - Pattern_RotaryOptions(Leds, Range, Assembly, Time, Transient, UserData, .25f, BlackV4, WhiteV4); -} - -internal void -Pattern_AllOnMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - pixel White = V4ToRGBPixel(WhiteV4); - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - Leds->Colors[LedIndex] = White; - } -} - -internal void -Pattern_BulbMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - r32 Top = 141; - r32 BulbRange = 50; - - pixel White = V4ToRGBPixel(WhiteV4); - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - - r32 BulbSDF = 1 - Clamp01(((Top - P.y) - BulbRange) / BulbRange); - r32 N = Noise3D((P / 17) + v3{Time, -Time, 0}); - N = Clamp01(N) * 2; - N = Smoothstep(N); - N *= N; - N = Smoothstep(N); - N *= 1.0f - PowR32(1.0f - BulbSDF, 4); - BulbSDF += N; - BulbSDF = Clamp01(BulbSDF); - v4 C = WhiteV4 * BulbSDF; - Leds->Colors[LedIndex] = V4ToRGBPixel(C); - } -} - -internal v4 -GenPatchyColor(v3 P, r32 Time, v4 C0, v4 C1, v4 C2) -{ - r32 LedRange = 300.0f; - r32 ScaleFactor = 1.0f / LedRange; - v3 Pp = P + v3{150, 100, 0}; - - r32 ScaleA = 1; - r32 NoiseA = Noise3D(((Pp / 38) + v3{0, 0, Time}) * ScaleA); - NoiseA = PowR32(NoiseA, 3); - NoiseA = Smoothstep(NoiseA); - - r32 ScaleBP = 2; - r32 ScaleB = 15; - r32 NoiseBP = Noise3D(((Pp / 13) + v3{ 0, Time * -0.33f, 0}) * ScaleBP); - NoiseBP = PowR32(NoiseBP, 3); - r32 NoiseB = Noise3D(((Pp / 75) + v3{Time * 0.5f, 0, 0}) * ScaleB); - NoiseB = PowR32(NoiseB, 3); - NoiseB = Smoothstep(NoiseB) * NoiseBP; - - r32 ScaleC = 1.5; - r32 NoiseCP = Noise3D(((Pp / 132) + v3{Time * -0.33f, 0, 0}) * 0.5f); - r32 NoiseC = Noise3D(((Pp / 164) + v3{Time * 0.25f, 0, 0}) * ScaleC); - NoiseC = PowR32(NoiseC, 3); - NoiseC = Smoothstep(NoiseC) * NoiseCP; - - v4 C = (C0 * NoiseA) + (C1 * NoiseB) + (C2 * NoiseC); - C /= (NoiseA + NoiseB + NoiseC); - return C; -} - -internal r32 -GenVerticalStrips(v3 P, r32 Time) -{ - v2 Right = v2{1, 0}; - v2 Pa = V2Normalize(v2{P.x, P.z}); - r32 Angle = .5f + (.5f * V2Dot(Pa, Right)); - - r32 HOffset = 70.0f; - r32 O = 50.0f; - r32 C = 10.0f; - - r32 X = Angle; - r32 Y = P.y; - r32 I = FloorR32(Y / C) * C; - I += (X * HOffset) + (Time * 25); - - r32 V = FractR32(I / O); - V = 2.0f * (0.5f - Abs(V - 0.5f)); - Assert(V >= 0 && V <= 1); - - return V; -} - -internal v4 -GenVerticalLeaves(v3 P, r32 Time, v4 C0, v4 C1, v4 C2) -{ - r32 A = GenVerticalStrips(P, Time * .25f); - r32 B = GenVerticalStrips(P * .3f, Time); - r32 C = GenVerticalStrips(P * .25f, Time * 2); - - v4 R = (C0 * A) + (C1 * B) + (C2 * C); - R /= A + B + C; - return R; -} - -internal void -AddIn_WavesPattern(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 C0, v4 C1, v4 C2) -{ - DEBUG_TRACK_FUNCTION; - - v4 C2P = C2 * 255; - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - - v4 C = v4{ - (r32)Leds->Colors[LedIndex].R, - (r32)Leds->Colors[LedIndex].G, - (r32)Leds->Colors[LedIndex].B, - 1 - }; - - r32 Offset = -250; - r32 Width = 30; - r32 Bands = 0; - for (u32 i = 1; i <= 1; i++) - { - P.x = FloorR32(P.x); - P.z = FloorR32(P.z); - - v3 P0 = v3{P.x + (23.124f * i), 0, P.z - (-12.34f * i) + Time}; - r32 S = Fbm3D(P0 * .005f, Time) * 250; - S += ModR32((Time * 100) - (150 * i), 400); - - r32 Y = (P.y - Offset); - r32 V = (Width - Abs(Y - S)) / Width; - V = Clamp01(V); - - Bands += V; - } - - C = V4Lerp(Bands, C * .5f, C2P); - - Leds->Colors[LedIndex] = pixel{(u8)C.r, (u8)C.g, (u8)C.b}; - } -} - -internal r32 -GenDotBands(v3 P, r32 Time) -{ - r32 RowHeight = 25; - r32 DotRadius = 20; - - r32 Y = P.y + 150; - s32 Row = (s32)FloorR32(Y / RowHeight); - r32 RowH = Abs(FractR32(Y / RowHeight)); - r32 DotDistY = Max(0, .5f - RowH) * 2; - - r32 Angle = (V2Dot(V2Normalize(v2{P.x, P.z}), v2{1,0}) * .5f) + .5f; - r32 DotDistX = Abs(ModR32(Angle, .2f)); - - r32 DotDist = SqrtR32(PowR32(DotDistX, 2) + PowR32(RowH, 2)); - r32 B = (DotRadius - DotDist) / DotRadius; - B = Clamp01(DotDist); - - return DotDistY; - -} - -internal void -Pattern_VoicePattern(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - Time = Time * BLState->PatternSpeed * Hue.Speed;; - - switch (Hue.Pattern) - { - case HuePattern_Wavy: - { - Pattern_WavyOptions(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, C0, C1, C0); - }break; - - default: - { - Pattern_PatchyOptions(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, C0, C1, C2); - }break; - } - - -} - -internal void -Pattern_VoiceAddIns(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - Time = Time * BLState->PatternSpeed * Hue.Speed;; - - switch (Hue.AddIn) - { - case AddIn_Rotary: - { - Pattern_RotaryOptions(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, BlackV4, C2); - }break; - - case AddIn_Waves: - { - AddIn_WavesPattern(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, C0, C1, C2); - }break; - - case AddIn_None: - default: - { - }break; - } -} - -internal void -Pattern_StemSolid(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - - pixel WhiteMask = V4ToRGBPixel(WhiteV4); - - led_strip_list Stem = BLState->StemStrips[Assembly.AssemblyIndex]; - for (u32 s = 0; s < Stem.Count; s++) - { - u32 StripIndex = Stem.StripIndices[s]; - v2_strip Strip = Assembly.Strips[StripIndex]; - for (u32 i = 0; i < Strip.LedCount; i++) - { - u32 LedIndex = Strip.LedLUT[i]; - Leds->Colors[LedIndex] = WhiteMask; - } - } -} - -internal void -Pattern_PrimaryHue(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly); - v4 C0 = RGBFromPhraseHue(Hue.Hue0); - v4 C1 = RGBFromPhraseHue(Hue.Hue1); - v4 C2 = RGBFromPhraseHue(Hue.Hue2); - - pixel HueOut = V4ToRGBPixel(C0); - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - Leds->Colors[LedIndex] = HueOut; - } -} - -internal void -Pattern_GrowFadeMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - r32 Period = 10.0f; // seconds - r32 ElapsedPct = FractR32(Time / Period); - - r32 ElapsedPctGrow = PowR32(ElapsedPct * 2, 2); - r32 ElapsedPctFade = Clamp01((ElapsedPct * 2) - 1); - - r32 Radius = 300 * ElapsedPctGrow; - - v3 Origin = Assembly.Center - v3{0, 150, 0}; - - r32 Brightness = Smoothstep(1.0f - ElapsedPctFade); - - pixel COutside = V4ToRGBPixel(BlackV4); - pixel CInside = V4ToRGBPixel(WhiteV4 * Brightness); - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - r32 Dist = V3Mag(P - Origin); - if (Dist < Radius) - { - Leds->Colors[LedIndex] = CInside; - } - else - { - Leds->Colors[LedIndex] = COutside; - } - } -} - -internal void -Pattern_RainbowLoadingBar(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData; - Time = Time * BLState->PatternSpeed; - - // constants - r32 Period = 5.0f; // seconds - r32 CSpeed = 16.0f; - r32 HIncrement = CSpeed * Period; - r32 HOffset = CSpeed * Period; - r32 MaxSphereRadius = 300; - - // sphere - r32 ElapsedPct = FractR32(Time / Period); - r32 ElapsedPctGrow = PowR32(ElapsedPct, 2); - r32 Radius = MaxSphereRadius * ElapsedPctGrow; - v3 Origin = Assembly.Center - v3{0, 150, 0}; - - // colors - r32 T = Time * CSpeed; - r32 TimeStep0 = T; - r32 TimeStep1 = T + HOffset; - r32 Hue0 = FloorR32(TimeStep0 / HIncrement) * HIncrement; - r32 Hue1 = FloorR32(TimeStep1 / HIncrement) * HIncrement; - v4 H0 = v4{ModR32(Hue0, 360), 1, 1, 1}; - v4 H1 = v4{ModR32(Hue1, 360), 1, 1, 1}; - pixel C0 = V4ToRGBPixel(HSVToRGB(H0)); - pixel C1 = V4ToRGBPixel(HSVToRGB(H1)); - - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - v3 P = Leds->Positions[LedIndex].xyz; - r32 Dist = V3Mag(P - Origin); - if (Dist < Radius) - { - Leds->Colors[LedIndex] = C1; - } - else - { - Leds->Colors[LedIndex] = C0; - } - } -} - -internal void -Pattern_Blue(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData) -{ - pixel Blue = pixel{0, 0, 255}; - for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++) - { - Leds->Colors[LedIndex] = Blue; - } -} - -#define BLUMEN_PATTERNS_H -#endif // BLUMEN_PATTERNS_H \ No newline at end of file diff --git a/src/app/platform_osx/gs_osx.mm b/src/app/platform_osx/gs_osx.mm deleted file mode 100644 index a95c79f..0000000 --- a/src/app/platform_osx/gs_osx.mm +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include "gs_osx_memory.mm" -#include "gs_osx_window.mm" -#include "gs_osx_fileio.mm" -#include "gs_osx_lib.mm" -#include "gs_osx_opengl.mm" -#include "gs_osx_time.mm" - -static void -gsosx_ProcessWindowEvents(NSApplication* App, NSWindow* Window) -{ - // Process Events - while (true) - { - NSEvent* Event = [App nextEventMatchingMask: NSEventMaskAny untilDate: [NSDate distantPast] inMode: NSDefaultRunLoopMode dequeue: YES]; - if (!Event) { break; } - - switch([Event type]) - { - case NSEventTypeKeyUp: - case NSEventTypeKeyDown: - { - // TODO: Handle Key Presses - }break; - - // TODO: Mouse Input - - default: - { - [App sendEvent: Event]; - }break; - } - } -} - -int main(int ArgCount, char** Args) -{ - NSApplication* Application = [NSApplication sharedApplication]; - [Application setActivationPolicy: NSApplicationActivationPolicyRegular]; - - gsosx_ApplicationDelegate* Delegate = [[gsosx_ApplicationDelegate alloc] init]; - [Application setDelegate: Delegate]; - - int WindowWidth = 1024; - int WindowHeight = 768; - id AppName = @"Lumenarium"; - NSWindow* Window = gsosx_CreateWindow(Application, WindowWidth, WindowHeight, AppName); - - // A really cryptic way of asking the window to open - [Window makeKeyAndOrderFront: Application]; - - NSOpenGLContext* OpenGLContext = gsoo_CreateOpenGLContext(Window, WindowWidth, WindowHeight, true); - - gsosx_time_info TimeInfo = gsosx_InitTime(); - double TargetSecondsPerFrame = 1.0 / 60; - uint64_t LastFrameEnd = gsosx_GetTime(TimeInfo); - while (true) - { - gsosx_ProcessWindowEvents(Application, Window); - - glClearColor(1, 0, 1, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - gsoo_SwapBuffers(OpenGLContext); - - uint64_t ThisFrameEnd = gsosx_GetTime(TimeInfo); - double FrameSeconds = gsosx_GetSecondsElapsed(LastFrameEnd, ThisFrameEnd, TimeInfo); - double SleepSeconds = TargetSecondsPerFrame - FrameSeconds; - if (SleepSeconds > 0) - { - gsosx_Sleep(SleepSeconds, TimeInfo); - } - } - - return (0); -} diff --git a/src/app/platform_osx/gs_osx_fileio.mm b/src/app/platform_osx/gs_osx_fileio.mm deleted file mode 100644 index c5ce939..0000000 --- a/src/app/platform_osx/gs_osx_fileio.mm +++ /dev/null @@ -1,63 +0,0 @@ -#include - -static uint32_t -gsosx_GetLastFileWriteTime(char* Path) -{ - int32_t Result = 0; - struct stat FileStat = {0}; - if (stat(Path, &FileStat) == 0) - { - Result = FileStat.st_mtimespec.tv_sec; - } - else - { - // TODO: Asserts - } - return Result; -} - -static uint32_t -gsosx_GetFilesize(char* Path) -{ - uint32_t Result = 0; - - int FileHandle = open(Path, O_RDONLY); - struct stat FileStat = {0}; - fstat(FileHandle, &FileStat); - close(FileHandle); - - Result = (uint32_t)FileStat.st_size; - return Result; -} - -static bool -gsosx_LoadFileIntoMemory(char* Path, uint32_t FileSize, uint8_t* FileMemory) -{ - bool Result = false; - int FileHandle = open(Path, O_RDONLY); - - struct stat FileStat = {0}; - fstat(FileHandle, &FileStat); - if (FileStat.st_size <= FileSize) - { - read(FileHandle, FileMemory, FileSize); - Result = true; - } - close(FileHandle); - - return Result; -} - -static bool -gsosx_WriteEntireFile(char* Path, uint32_t FileSize, uint8_t* FileMemory) -{ - bool Result = false; - int FileHandle = open(Path, O_WRONLY | O_CREAT, 0777); - ssize_t SizeWritten = write(FileHandle, FileMemory, FileSize); - if (SizeWritten == FileSize) - { - Result = true; - } - close(FileHandle); - return Result; -} \ No newline at end of file diff --git a/src/app/platform_osx/gs_osx_lib.mm b/src/app/platform_osx/gs_osx_lib.mm deleted file mode 100644 index 8758af3..0000000 --- a/src/app/platform_osx/gs_osx_lib.mm +++ /dev/null @@ -1,30 +0,0 @@ -#include - -static void* -gsosx_LoadDLL(char* Path) -{ - void* LibHandle = 0; - - LibHandle = dlopen(Path, RTLD_LAZY); - if (LibHandle) - { - dlerror(); // Clear Last Error - } - else - { - LibHandle = 0; - } - - return LibHandle; -} - -#define gsosx_GetProcAddress(libHandle, type, name) (type*)dlsym((libHandle), name) - -static void -gsosx_UnloadDLL(void* LibHandle) -{ - if (LibHandle) - { - dlclose(LibHandle); - } -} \ No newline at end of file diff --git a/src/app/platform_osx/gs_osx_memory.mm b/src/app/platform_osx/gs_osx_memory.mm deleted file mode 100644 index 67b904a..0000000 --- a/src/app/platform_osx/gs_osx_memory.mm +++ /dev/null @@ -1,30 +0,0 @@ -#include - -static uint8_t* -gsosx_Alloc(size_t Size) -{ - uint8_t* Result = 0; - char* StartAddress = (char*)0; - int Prot = PROT_READ | PROT_WRITE; - int Flags = MAP_PRIVATE | MAP_ANON; - Result = (uint8_t*)mmap(StartAddress, Size, Prot, Flags, -1, 0); - return Result; -} - -static void -gsosx_Free(uint8_t* Base, uint32_t Size) -{ - munmap((void*)Base, (size_t)Size); -} - -static uint8_t* -gsosx_Realloc(uint8_t* Base, uint32_t OldSize, uint32_t NewSize) -{ - uint8_t* Result = gsosx_Alloc(NewSize); - for (int32_t i = 0; i < OldSize; i++) - { - Result[i] = Base[i]; - } - gsosx_Free(Base, OldSize ); - return Result; -} \ No newline at end of file diff --git a/src/app/platform_osx/gs_osx_opengl.mm b/src/app/platform_osx/gs_osx_opengl.mm deleted file mode 100644 index 4f6cfe4..0000000 --- a/src/app/platform_osx/gs_osx_opengl.mm +++ /dev/null @@ -1,65 +0,0 @@ -#include - -struct gsoo_opengl_state -{ - NSOpenGLContext* Context; -}; - -@interface gsoo_OpenGLView: NSOpenGLView @end -@implementation gsoo_OpenGLView : NSOpenGLView - - (void) - reshape - { - // TODO: framebufferWidth and Height were globals in the code I was pulling from - // Need some way to get the new window height in here. - CGRect FrameRect = self.frame; - glViewport(0, 0, FrameRect.size.width, FrameRect.size.height); - //glViewport(0, 0, framebufferWidth, framebufferHeight); - } -@end - -static NSOpenGLContext* -gsoo_CreateOpenGLContext(NSWindow* Window, uint32_t Width, uint32_t Height, int32_t EnableVSync) -{ - NSOpenGLContext* Result = 0; - NSOpenGLPixelFormatAttribute PixelFormatAttributes[] = { - NSOpenGLPFAClosestPolicy, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFASampleBuffers, - 0, - 0 - }; - - NSOpenGLPixelFormat* PixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes: PixelFormatAttributes]; - Result = [[NSOpenGLContext alloc] initWithFormat: PixelFormat shareContext: 0]; - - if (!Result) - { - // TODO: Assert/Handle - return 0; - } - - [Result makeCurrentContext]; - GLint VSync = EnableVSync; - [Result setValues: &VSync forParameter: NSOpenGLCPSwapInterval]; - - // Set Backbuffer Resolution - GLint BackbufferDimensions[] = { Width, Height }; - CGLSetParameter(Result.CGLContextObj, kCGLCPSurfaceBackingSize, BackbufferDimensions); - CGLEnable(Result.CGLContextObj, kCGLCESurfaceBackingSize); - - // - gsoo_OpenGLView* View = [[gsoo_OpenGLView alloc] init]; - [Window setContentView: View]; - [View setOpenGLContext: Result]; - [View setPixelFormat: PixelFormat]; - [Result setView: View]; - - return Result; -} - -static void -gsoo_SwapBuffers(NSOpenGLContext* OpenGLContext) -{ - [OpenGLContext flushBuffer]; -} \ No newline at end of file diff --git a/src/app/platform_osx/gs_osx_time.mm b/src/app/platform_osx/gs_osx_time.mm deleted file mode 100644 index 734e268..0000000 --- a/src/app/platform_osx/gs_osx_time.mm +++ /dev/null @@ -1,46 +0,0 @@ -#include - -static const uint64_t NANOS_PER_USEC = 1000ULL; -static const uint64_t NANOS_PER_MILLISEC = 1000ULL * NANOS_PER_USEC; -static const uint64_t NANOS_PER_SEC = 1000ULL * NANOS_PER_MILLISEC; - -struct gsosx_time_info -{ - uint64_t StartTimeAbsolute; - mach_timebase_info_data_t MachTimeInfo; -}; - -static gsosx_time_info -gsosx_InitTime() -{ - gsosx_time_info Result = {0}; - Result.StartTimeAbsolute = mach_absolute_time(); - mach_timebase_info(&Result.MachTimeInfo); - return Result; -} - -static uint64_t -gsosx_GetTime(gsosx_time_info TimeInfo) -{ - uint64_t Result = mach_absolute_time() - TimeInfo.StartTimeAbsolute; - return Result; -} - -static double -gsosx_GetSecondsElapsed(uint64_t Start, uint64_t End, gsosx_time_info TimeInfo) -{ - double Result = 0; - double Elapsed = (double)(End - Start); - Result = Elapsed * (double)(TimeInfo.MachTimeInfo.numer) / (double)NANOS_PER_SEC / (double)TimeInfo.MachTimeInfo.denom; - return Result; -} - -static void -gsosx_Sleep(double Seconds, gsosx_time_info TimeInfo) -{ - // NOTE(Peter): This isn't entirely precise, and can vary by up to 500 microseconds. We could implement a sleep combined witha busy wait - // to get more precise sleeping. Do this if necessary - uint64_t WaitTimeAbs = Seconds / (double)TimeInfo.MachTimeInfo.numer * (double)NANOS_PER_SEC * (double)TimeInfo.MachTimeInfo.denom; - uint64_t NowAbs = mach_absolute_time(); - mach_wait_until(NowAbs + WaitTimeAbs); -} \ No newline at end of file diff --git a/src/app/platform_osx/gs_osx_window.mm b/src/app/platform_osx/gs_osx_window.mm deleted file mode 100644 index eefafd3..0000000 --- a/src/app/platform_osx/gs_osx_window.mm +++ /dev/null @@ -1,78 +0,0 @@ -@interface gsosx_ApplicationDelegate : NSObject @end - -@implementation gsosx_ApplicationDelegate : NSObject - - (void) - applicationDidFinishLaunching: (NSNotification *)notification - { - [NSApp stop: nil]; - NSAutoreleasePool* Pool = [[NSAutoreleasePool alloc] init]; - - [Pool drain]; - } - - - (NSApplicationTerminateReply) - applicationShouldTerminate: (NSApplication*) sender - { - return NO; - } - - - (void) - dealloc - { - [super dealloc]; - } -@end - -@interface gsosx_WindowDelegate: NSObject @end -@implementation gsosx_WindowDelegate : NSObject - - (BOOL) - windowShouldClose: (id)sender - { - // TODO(Peter): Stop Application Running? - NSLog(@"Close button pressed"); - return NO; - } - - - (void) - windowDidBecomeKey: (NSNotification*)notification - { - // TODO: ??? - } - - - (void) - windowDisResignKey: (NSNotification*)notification - { - // TODO: ??? - } -@end - -static NSWindow* -gsosx_CreateWindow(NSApplication* App, int Width, int Height, id Title) -{ - int WindowStyleMask = NSWindowStyleMaskClosable; - NSRect WindowRect = NSMakeRect(0, 0, Width, Height); - - NSWindow* Window = [[NSWindow alloc] initWithContentRect: WindowRect styleMask: WindowStyleMask backing: NSBackingStoreBuffered defer: YES]; - Window.styleMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable; - - gsosx_WindowDelegate* WindowDelegate = [[gsosx_WindowDelegate alloc] init]; - - [Window setOpaque: YES]; - [Window setDelegate: WindowDelegate]; - [Window setTitle: Title]; - - NSMenu* MenuBar = [NSMenu alloc]; - NSMenuItem* AppMenuItem = [NSMenuItem alloc]; - [MenuBar addItem: AppMenuItem]; - [App setMainMenu: MenuBar]; - - NSMenu* AppMenu = [NSMenu alloc]; - id QuitTitle = [@"Quit " gs_stringByAppendinggs_string: Title]; - id QuitMenuItem = [[NSMenuItem alloc] initWithTitle: QuitTitle action: @selector(terminate:) keyEquivalent: @"q"]; - [AppMenu addItem: QuitMenuItem]; - [AppMenuItem setSubmenu: AppMenu]; - - [App activateIgnoringOtherApps: YES]; - - return Window; -} diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp deleted file mode 100644 index d281552..0000000 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ /dev/null @@ -1,786 +0,0 @@ -// -// File: win32_foldhaus.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef WIN32_FOLDHAUS_CPP - -#include -#include -#include -#include -#include - -#include "../../meta/gs_meta_include.h" -#include "../foldhaus_platform.h" - -#include "../../gs_libs/gs_win32.cpp" -#include "win32_foldhaus_utils.h" -#include "win32_foldhaus_memory.h" -#include "win32_foldhaus_fileio.h" -#include "win32_foldhaus_dll.h" -#include "win32_foldhaus_timing.h" -#include "win32_foldhaus_work_queue.h" -#include "win32_foldhaus_serial.h" -#include "win32_foldhaus_socket.h" -#include "win32_foldhaus_mouse.h" - -#include "../foldhaus_renderer.cpp" - -#include "win32_test_code.cpp" - -global b32 Running = false; -global b32 WindowIsActive = false; - -char DLLName[] = "foldhaus.dll"; -char WorkingDLLName[] = "foldhaus_temp.dll"; -char DLLLockFileName[] = "lock.tmp"; - -window MainWindow; - -PLATFORM_GET_GPU_TEXTURE_HANDLE(Win32GetGPUTextureHandle) -{ - s32 Handle = SubmitTexture(Memory, Width, Height); - return Handle; -} - -HDC FontDrawingDC; -HBITMAP FontBitmap; -HFONT CurrentFont; - -GET_FONT_INFO(Win32GetFontInfo) -{ - platform_font_info Result = {}; - - FontDrawingDC = CreateCompatibleDC(NULL); - SetBkColor(FontDrawingDC, RGB(0, 0, 0)); - SetTextColor(FontDrawingDC, RGB(255, 255, 255)); - FontBitmap = CreateCompatibleBitmap(FontDrawingDC, PixelHeight * 2, PixelHeight * 2); - HGDIOBJ SelectObjectResult = SelectObject(FontDrawingDC, FontBitmap); - - CurrentFont = CreateFont(PixelHeight, 0, 0, 0, - FontWeight, - Italic, - Underline, - Strikeout, - ANSI_CHARSET, - OUT_OUTLINE_PRECIS, - CLIP_DEFAULT_PRECIS, - PROOF_QUALITY, - FIXED_PITCH, - FontName); - SelectFont(FontDrawingDC, CurrentFont); - - TEXTMETRIC WindowsFontMetrics = {}; - if (GetTextMetrics(FontDrawingDC, &WindowsFontMetrics)) - { - Result.PixelHeight = WindowsFontMetrics.tmHeight; - Result.Ascent = WindowsFontMetrics.tmAscent; - Result.Descent = WindowsFontMetrics.tmDescent; - Result.Leading = WindowsFontMetrics.tmExternalLeading; - Result.MaxCharWidth = WindowsFontMetrics.tmMaxCharWidth; - Result.CodepointStart = WindowsFontMetrics.tmFirstChar; - Result.CodepointOnePastLast = WindowsFontMetrics.tmLastChar + 1; - } - - return Result; -} - -DRAW_FONT_CODEPOINT(Win32DrawFontCodepoint) -{ - SIZE CodepointSize = {}; - if (GetTextExtentPoint32(FontDrawingDC, &Codepoint, 1, &CodepointSize)) - { - *OutWidth = CodepointSize.cx; - *OutHeight = CodepointSize.cy; - - RECT TextRect = {}; - TextRect.left = 0; - TextRect.right = *OutWidth; - TextRect.top = 0; - TextRect.bottom = *OutHeight; - - int Error = DrawText(FontDrawingDC, &Codepoint, 1, &TextRect, DT_LEFT | DT_NOCLIP | DT_TOP); - - u8* Row = DestBuffer + (YOffset * (DestBufferWidth * 4)); - COLORREF PixelColor; - for (u32 Y = 0; Y < *OutHeight; Y++) - { - // NOTE(Peter): XOffset * 4 b/c its 4 bytes per pixel. - u8* Channel = (u8*)Row + (XOffset * 4); - for (u32 X = 0; X < *OutWidth; X++) - { - PixelColor = GetPixel(FontDrawingDC, X + TextRect.left, TextRect.bottom - Y); - Assert(PixelColor != CLR_INVALID); - u8 RValue = GetRValue(PixelColor); - *Channel++ = RValue; - *Channel++ = RValue; - *Channel++ = RValue; - *Channel++ = RValue; - } - Row += DestBufferWidth * 4; - } - - } -} - -LRESULT CALLBACK -HandleWindowEvents (HWND WindowHandle, UINT Msg, WPARAM WParam, LPARAM LParam) -{ - LRESULT Result = 0; - - switch (Msg) - { - case WM_SIZE: - { - Win32UpdateWindowDimension(&MainWindow); - //Win32ResizeDIBSection(&GlobalBackbuffer, MainWindow.Info.Width, MainWindow.Info.Height); - }break; - - case WM_CLOSE: - { - Result = DefWindowProc(WindowHandle, Msg, WParam, LParam); - Running = false; - }break; - - case WM_DESTROY: - { - }break; - - case WM_PAINT: - { - PAINTSTRUCT PaintStruct; - HDC DeviceContext; - b32 PaintResult; - - DeviceContext = BeginPaint(WindowHandle, &PaintStruct); - PaintResult = EndPaint(WindowHandle, &PaintStruct); - }break; - - case WM_ACTIVATE: - { - WindowIsActive = (LOWORD(WParam) == WA_ACTIVE || LOWORD(WParam) == WA_CLICKACTIVE); - }break; - - default: - { - Result = DefWindowProc(WindowHandle, Msg, WParam, LParam); - } - } - - return Result; -} - -internal void -HandleWindowMessage (MSG Message, window* Window, input_queue* InputQueue, mouse_state* Mouse) -{ - switch (Message.message) - { - case WM_MOUSEWHEEL: - { - Mouse->Scroll = GET_WHEEL_DELTA_WPARAM(Message.wParam); - }break; - - case WM_LBUTTONDOWN: - { - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - AddInputEventEntry(InputQueue, KeyCode_MouseLeftButton, false, true, - ShiftDown, AltDown, CtrlDown, false); - - Mouse->LeftButtonState |= KeyState_IsDown; - Mouse->DownPos = Mouse->Pos; - - // :Win32MouseEventCapture - // NOTE(Peter): We capture events when the mouse goes down so that - // if the user drags outside the window, we still get the mouse up - // event and can process it. Otherwise, we can get into cases where - // an event was started, didn't end, but the user can click again and - // try to start the event again. - // We relase event capture on mouse up. - SetCapture(Window->Handle); - }break; - - case WM_MBUTTONDOWN: - { - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - AddInputEventEntry(InputQueue, KeyCode_MouseMiddleButton, false, true, - ShiftDown, AltDown, CtrlDown, false); - Mouse->MiddleButtonState = KeyState_IsDown & ~KeyState_WasDown; - - // :Win32MouseEventCapture - SetCapture(Window->Handle); - }break; - - case WM_RBUTTONDOWN: - { - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - AddInputEventEntry(InputQueue, KeyCode_MouseRightButton, false, true, - ShiftDown, AltDown, CtrlDown, false); - Mouse->RightButtonState = KeyState_IsDown & ~KeyState_WasDown; - Mouse->DownPos = Mouse->Pos; - - // :Win32MouseEventCapture - SetCapture(Window->Handle); - }break; - - case WM_LBUTTONUP: - { - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - AddInputEventEntry(InputQueue, KeyCode_MouseLeftButton, true, false, - ShiftDown, AltDown, CtrlDown, false); - Mouse->LeftButtonState &= ~KeyState_IsDown; - - // :Win32MouseEventCapture - ReleaseCapture(); - }break; - - case WM_MBUTTONUP: - { - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - AddInputEventEntry(InputQueue, KeyCode_MouseMiddleButton, true, false, - ShiftDown, AltDown, CtrlDown, false); - Mouse->MiddleButtonState = ~KeyState_IsDown & KeyState_WasDown; - - // :Win32MouseEventCapture - ReleaseCapture(); - }break; - - case WM_RBUTTONUP: - { - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - AddInputEventEntry(InputQueue, KeyCode_MouseRightButton, true, false, - ShiftDown, AltDown, CtrlDown, false); - Mouse->RightButtonState = ~KeyState_IsDown & KeyState_WasDown; - - // :Win32MouseEventCapture - ReleaseCapture(); - }break; - - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_KEYDOWN: - case WM_KEYUP: - { -#if 0 - int VirtualKey = (int)Message.wParam; - key_code Key = Win32GetKeyCode(VirtualKey, true, false); - s32 KeyIndex = (int)Key; - - b32 KeyWasDown = (Message.lParam & (1 << 30)) != 0; - b32 KeyIsDown = (Message.lParam & (1 << 31)) == 0; - - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - // New Input Queue - AddInputEventEntry(InputQueue, Key, KeyWasDown, KeyIsDown, - ShiftDown, AltDown, CtrlDown, false); -#endif - TranslateMessage(&Message); - DispatchMessage(&Message); - }break; - - case WM_CHAR: - { - char VirtualKey = (char)Message.wParam; - key_code Key = CharToKeyCode(VirtualKey); - s32 KeyIndex = (int)Key; - - b32 KeyWasDown = (Message.lParam & (1 << 30)) != 0; - b32 KeyIsDown = (Message.lParam & (1 << 31)) == 0; - - b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000; - b32 AltDown = GetKeyState(VK_MENU) & 0x8000; - b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000; - - // New Input Queue - AddInputEventEntry(InputQueue, Key, KeyWasDown, KeyIsDown, - ShiftDown, AltDown, CtrlDown, false); - }break; - - default: - { - TranslateMessage(&Message); - DispatchMessage(&Message); - }break; - } -} - -internal void -DebugPrint (char* Format, ...) -{ - char Buffer[256]; - gs_string StringBuffer = MakeString(Buffer, 256); - va_list Args; - va_start(Args, Format); - Log_PrintFVarArgs(GlobalLogBuffer, LogEntry_Message, Format, Args); - va_end(Args); -} - -internal void -SetApplicationLinks (context* Context, win32_dll_refresh DLL, gs_work_queue* WorkQueue) -{ - if (DLL.IsValid) - { - Context->InitializeApplication = (initialize_application*)GetProcAddress(DLL.DLL, "InitializeApplication"); - Context->ReloadStaticData = (reload_static_data*)GetProcAddress(DLL.DLL, "ReloadStaticData"); - Context->UpdateAndRender = (update_and_render*)GetProcAddress(DLL.DLL, "UpdateAndRender"); - Context->CleanupApplication = (cleanup_application*)GetProcAddress(DLL.DLL, "CleanupApplication"); - } - else - { - Context->InitializeApplication = 0; - Context->ReloadStaticData = 0; - Context->UpdateAndRender = 0; - Context->CleanupApplication = 0; - } -} - -internal void -Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt) -{ - DEBUG_TRACK_FUNCTION; - - u32 BuffersSent = 0; - u32 DataSizeSent = 0; - - switch(BufferAt->AddressType) - { - case AddressType_NetworkIP: - { - Win32Socket_SendTo(BufferAt->SendSocket, - BufferAt->V4SendAddress, - BufferAt->SendPort, - (const char*)BufferAt->Memory, - BufferAt->MemorySize, - 0); - }break; - - case AddressType_ComPort: - { - if (BufferAt->ComPort.Length > 0) - { - HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 2000000, 8, NOPARITY, 1, Context.Transient); - if (SerialPort != INVALID_HANDLE_VALUE) - { - if (Win32SerialPort_Write(SerialPort, BufferAt->Data)) - { - BuffersSent += 1; - DataSizeSent += BufferAt->Data.Size; - } - else - { - Win32SerialArray_Close(BufferAt->ComPort); - } - } - } - else - { -#if 0 - Log_Message(GlobalLogBuffer, - "Skipping data buffer because its COM Port isn't set"); -#endif - } - }break; - - InvalidDefaultCase; - } -} - -internal void -Win32_SendAddressedDataBuffer_Job(gs_thread_context Context, gs_data Arg) -{ - addressed_data_buffer* OutputData = (addressed_data_buffer*)Arg.Memory; - Win32_SendAddressedDataBuffer(Context, OutputData); -} - -internal bool -ReloadAndLinkDLL(win32_dll_refresh* DLL, context* Context, gs_work_queue* WorkQueue, bool ShouldError, bool AppReady) -{ - bool Success = false; - if (HotLoadDLL(DLL)) - { - SetApplicationLinks(Context, *DLL, WorkQueue); - Context->ReloadStaticData(*Context, GlobalDebugServices, GlobalLogBuffer, AppReady); - Success = true; - Log_Message(GlobalLogBuffer, "Reloaded DLL\n"); - } - else if(ShouldError) - { - Log_Error(GlobalLogBuffer, "Unable to load application DLL at startup.\nAborting\n"); - } - return Success; -} - -internal gs_const_string -GetExePath(HINSTANCE HInstance, gs_thread_context ThreadContext) -{ - gs_const_string Result = {}; - - u32 Error = 0; - u32 PathSize = MAX_PATH; - char* Path = PushArray(ThreadContext.Transient, char, PathSize); - DWORD Length = GetModuleFileNameA(HInstance, Path, PathSize); - - if (Length) - { - Error = GetLastError(); - if (Error == ERROR_INSUFFICIENT_BUFFER) { - // PathSize wasn't long enough - // TODO(pjs): handle this case - InvalidCodePath; - } - - Result.Str = Path; - Result.Length = (u64)Length; - } - else - { - Error = GetLastError(); - InvalidCodePath; - } - - return Result; -} - -internal bool -SetWorkingDirectory(HINSTANCE HInstance, gs_thread_context ThreadContext) -{ - bool Result = false; - - gs_const_string ExePath = GetExePath(HInstance, ThreadContext); - gs_string ScratchPath = PushString(ThreadContext.Transient, ExePath.Length + 128); - gs_string WorkingDirectory = PushString(ThreadContext.Transient, ExePath.Length + 128); - - while (WorkingDirectory.Length == 0) - { - s64 LastSlash = FindLastFromSet(ExePath, "\\/"); - if (LastSlash < 0) break; - - ExePath = Substring(ExePath, 0, LastSlash); - PrintF(&ScratchPath, "%S\\data", ExePath); - NullTerminate(&ScratchPath); - - gs_file_info PathInfo = GetFileInfo(ThreadContext.FileHandler, ScratchPath.ConstString); - if (PathInfo.Path.Length > 0 && - PathInfo.IsDirectory) { - PrintF(&WorkingDirectory, "%S", ExePath); - NullTerminate(&WorkingDirectory); - } - } - - if (WorkingDirectory.Length > 0) - { - Log_Message(GlobalLogBuffer, - "Setting Working Directory \n%S \n", - WorkingDirectory.ConstString); - Result = SetCurrentDirectory(WorkingDirectory.Str); - if (!Result) - { - u32 Error = GetLastError(); - InvalidCodePath; - } - } - else - { - Log_Error(GlobalLogBuffer, "Error, no data folder found\n"); - } - - return Result; -} - -#include "../../gs_libs/gs_path.h" - -internal void -Win32_SendOutputData(gs_thread_context ThreadContext, addressed_data_buffer_list OutputData) -{ - bool Multithread = true; - if (Multithread) - { - for (addressed_data_buffer* At = OutputData.Root; - At != 0; - At = At->Next) - { - gs_data ProcArg = {}; - ProcArg.Memory = (u8*)At; - ProcArg.Size = sizeof(addressed_data_buffer); - Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffer_Job, ProcArg, ConstString("Send UART Data")); - } - } - else - { - for (addressed_data_buffer* At = OutputData.Root; - At != 0; - At = At->Next) - { - gs_data ProcArg = {}; - ProcArg.Memory = (u8*)At; - ProcArg.Size = sizeof(addressed_data_buffer); - Win32_SendAddressedDataBuffer_Job(ThreadContext, ProcArg); - } - } - -} - -// Time -internal system_time -Win32GetSystemTime() -{ - system_time Result = {}; - - SYSTEMTIME WinLocalTime; - GetLocalTime(&WinLocalTime); - - SYSTEMTIME WinSysTime; - FILETIME WinSysFileTime; - GetSystemTime(&WinSysTime); - if (SystemTimeToFileTime((const SYSTEMTIME*)&WinSysTime, &WinSysFileTime)) - { - ULARGE_INTEGER SysTime = {}; - SysTime.LowPart = WinSysFileTime.dwLowDateTime; - SysTime.HighPart = WinSysFileTime.dwHighDateTime; - - Result.NanosSinceEpoch = SysTime.QuadPart; - Result.Year = WinLocalTime.wYear; - Result.Month = WinLocalTime.wMonth; - Result.Day = WinLocalTime.wDay; - Result.Hour = WinLocalTime.wHour; - Result.Minute = WinLocalTime.wMinute; - Result.Second = WinLocalTime.wSecond; - } - else - { - u32 Error = GetLastError(); - InvalidCodePath; - } - - return Result; -} - -int WINAPI -WinMain ( - HINSTANCE HInstance, - HINSTANCE HPrevInstance, - PSTR CmdLineArgs, - INT NCmdShow - ) -{ - gs_thread_context ThreadContext = Win32CreateThreadContext(); - - gs_memory_arena PlatformPermanent = MemoryArenaCreate(MB(4), - Bytes(8), ThreadContext.Allocator, - 0, - 0, - "Platform Memory"); - - GlobalLogBuffer = AllocStruct(ThreadContext.Allocator, log_buffer, "Global Log Buffer"); - *GlobalLogBuffer = Log_Init(&PlatformPermanent, 32); - - if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1; - - context Context = {}; - Context.ThreadContext = ThreadContext; - Context.SystemTime_Current = Win32GetSystemTime(); - - gs_const_string Args = ConstString((char*)CmdLineArgs); - if (StringsEqual(Args, ConstString("-headless"))) - { - Log_Message(GlobalLogBuffer, "Running Headless\n"); - Context.Headless = true; - } - - if (!Context.Headless) - { - MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents); - Win32UpdateWindowDimension(&MainWindow); - - win32_opengl_window_info OpenGLWindowInfo = {}; - OpenGLWindowInfo.ColorBits = 32; - OpenGLWindowInfo.AlphaBits = 8; - OpenGLWindowInfo.DepthBits = 0; - CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow); - } - - s64 PerformanceCountFrequency = GetPerformanceFrequency(); - s64 LastFrameEnd = GetWallClock(); - r32 TargetSecondsPerFrame = 1 / 30.0f; - r32 LastFrameSecondsElapsed = 0.0f; - - GlobalDebugServices = PushStruct(&PlatformPermanent, debug_services); -#if DEBUG - InitDebugServices_DebugMode(GlobalDebugServices, - PerformanceCountFrequency, - GetWallClock, - Win32GetThreadId, - Context.ThreadContext, - PLATFORM_THREAD_COUNT + 1); -#else - InitDebugServices_OffMode(GlobalDebugServices, - PerformanceCountFrequency, - GetWallClock, - Win32GetThreadId, - Context.ThreadContext, - PLATFORM_THREAD_COUNT + 1); -#endif - - input_queue InputQueue = InputQueue_Create(&PlatformPermanent, 32); - - Win32WorkQueue_Init(&PlatformPermanent, PLATFORM_THREAD_COUNT); - - // Platform functions - Context.GeneralWorkQueue = &Win32WorkQueue.WorkQueue; - Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle; - Context.PlatformGetSocketHandle = Win32GetSocketHandle; - Context.PlatformGetFontInfo = Win32GetFontInfo; - Context.PlatformDrawFontCodepoint = Win32DrawFontCodepoint; - - Context.ThreadManager = PushStruct(&PlatformPermanent, platform_thread_manager); - *Context.ThreadManager = CreatePlatformThreadManager(Win32CreateThread, Win32KillThread); - - Context.SocketManager = PushStruct(&PlatformPermanent, platform_socket_manager); - *Context.SocketManager = CreatePlatformSocketManager(Win32ConnectSocket, Win32CloseSocket, Win32SocketQueryStatus, Win32SocketPeek, Win32SocketReceive, Win32SocketSend); - - win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName); - if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true, false)) { return -1; } - - Mouse_Init(); - - Win32SocketSystem_Init(&PlatformPermanent); - - Win32SerialArray_Create(&PlatformPermanent); - - render_command_buffer RenderBuffer = {}; - if (!Context.Headless) - { - RenderBuffer = AllocateRenderCommandBuffer(MB(12), &PlatformPermanent, ThreadContext); - } - - addressed_data_buffer_list OutputData = AddressedDataBufferList_Create(ThreadContext); - - Context.InitializeApplication(&Context); - - system_time StartTime = Win32GetSystemTime(); - - Running = true; - Context.WindowIsVisible = true; - while (Running) - { - if (GlobalDebugServices->RecordFrames) - { - EndDebugFrame(GlobalDebugServices); - } - - DEBUG_TRACK_SCOPE(MainLoop); - - { - Context.SystemTime_Last = Context.SystemTime_Current; - Context.SystemTime_Current = Win32GetSystemTime(); - -#define PRINT_SYSTEM_TIME 0 -#if PRINT_SYSTEM_TIME - gs_string T = PushStringF(Context.ThreadContext.Transient, - 256, - "%d %d %d - %lld\n", - Context.SystemTime_Current.Hour, - Context.SystemTime_Current.Minute, - Context.SystemTime_Current.Second, - Context.SystemTime_Current.NanosSinceEpoch); - - u64 NanosElapsed = Context.SystemTime_Current.NanosSinceEpoch - StartTime.NanosSinceEpoch; - r64 SecondsElapsed = (r64)NanosElapsed * NanosToSeconds; - - Log_Message(GlobalLogBuffer, - "%lld %f Seconds \n", - NanosElapsed, - SecondsElapsed); -#endif - } - - ResetInputQueue(&InputQueue); - - ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false, true); - - AddressedDataBufferList_Clear(&OutputData); - - if (!Context.Headless) - { - Mouse_Update(MainWindow, &Context); - MSG Message; - while (PeekMessageA(&Message, MainWindow.Handle, 0, 0, PM_REMOVE)) - { - DEBUG_TRACK_SCOPE(PeekWindowsMessages); - HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse); - } - - Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}}; - RenderBuffer.ViewWidth = MainWindow.Width; - RenderBuffer.ViewHeight = MainWindow.Height; - } - - Context.DeltaTime = LastFrameSecondsElapsed; - Context.TotalTime += (r64)Context.DeltaTime; - - Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData); - - Win32_SendOutputData(ThreadContext, OutputData); - - if (!Context.Headless) - { - RenderCommandBuffer(RenderBuffer); - ClearRenderBuffer(&RenderBuffer); - - Mouse_Advance(&Context); - - HDC DeviceContext = GetDC(MainWindow.Handle); - SwapBuffers(DeviceContext); - ReleaseDC(MainWindow.Handle, DeviceContext); - } - - Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext); - - s64 FinishedWorkTime = GetWallClock(); - r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency); - - while (SecondsElapsed < TargetSecondsPerFrame) - { - DEBUG_TRACK_SCOPE(UnusedTime); - u32 SleepTime = 1000.0f * (TargetSecondsPerFrame - SecondsElapsed); - Sleep(SleepTime); - SecondsElapsed = GetSecondsElapsed(LastFrameEnd, GetWallClock(), PerformanceCountFrequency); - } - - LastFrameSecondsElapsed = SecondsElapsed; - LastFrameEnd = GetWallClock(); - } - - Context.CleanupApplication(Context, &OutputData); - Win32_SendOutputData(ThreadContext, OutputData); - Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext); - - Win32WorkQueue_Cleanup(); - Win32SocketSystem_Cleanup(); - - return 0; -} - -#define WIN32_FOLDHAUS_CPP -#endif // WIN32_FOLDHAUS_CPP \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_dll.h b/src/app/platform_win32/win32_foldhaus_dll.h deleted file mode 100644 index 396f15e..0000000 --- a/src/app/platform_win32/win32_foldhaus_dll.h +++ /dev/null @@ -1,162 +0,0 @@ -// -// File: win32_foldhaus_dll.h -// Author: Peter Slattery -// Creation Date: 2020-02-04 -// -// -// NOTE: Relies on having imported foldhaus_platform.h prior to this file -// -#ifndef WIN32_FOLDHAUS_DLL_H - -// DLL -struct win32_dll_refresh -{ - FILETIME LastWriteTime; - HMODULE DLL; - - bool IsValid; - - char SourceDLLPath[MAX_PATH]; - char WorkingDLLPath[MAX_PATH]; - char LockFilePath[MAX_PATH]; -}; - -internal int -Win32DLLgs_stringLength(char* gs_string) -{ - char* At = gs_string; - while (*At) { At++; }; - return At - gs_string; -} - -internal int -Win32DLLConcatgs_strings(int ALength, char* A, int BLength, char* B, int DestLength, char* Dest) -{ - char* Dst = Dest; - char* AAt = A; - int ALengthToCopy = ALength < DestLength ? ALength : DestLength; - for (s32 a = 0; a < ALength; a++) - { - *Dst++ = *AAt++; - } - char* BAt = B; - int DestLengthRemaining = DestLength - (Dst - Dest); - int BLengthToCopy = BLength < DestLengthRemaining ? BLength : DestLength; - for (s32 b = 0; b < BLengthToCopy; b++) - { - *Dst++ = *BAt++; - } - int DestLengthOut = Dst - Dest; - int NullTermIndex = DestLengthOut < DestLength ? DestLengthOut : DestLength; - Dest[NullTermIndex] = 0; - return DestLengthOut; -} - -internal void -GetApplicationPath(system_path* Result) -{ - Assert(Result->Path); - Result->PathLength = GetModuleFileNameA(0, Result->Path, Result->PathLength); - - u32 CharactersScanned = 0; - u32 IndexOfLastSlash = 0; - char *Scan = Result->Path; - while(*Scan) - { - if (*Scan == '\\') - { - Result->IndexOfLastSlash = CharactersScanned + 1; - } - Scan++; - CharactersScanned++; - } -} - -internal b32 -LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult) -{ - b32 Success = false; - Assert(DLLResult->DLL == 0); - - DLLResult->DLL = LoadLibraryA(DLLName); - if (DLLResult->DLL) - { - Success = true; - DLLResult->IsValid = true; - } - - return Success; -} - -internal void -UnloadApplicationDLL(win32_dll_refresh* DLL) -{ - if (DLL->DLL) - { - FreeLibrary(DLL->DLL); - } - DLL->DLL = 0; - DLL->IsValid = false; -} - -internal win32_dll_refresh -InitializeDLLHotReloading(char* SourceDLLName, - char* WorkingDLLFileName, - char* LockFileName) -{ - win32_dll_refresh Result = {}; - Result.IsValid = false; - - system_path ExePath = {}; - ExePath.PathLength = MAX_PATH; - ExePath.Path = (char*)VirtualAlloc(NULL, ExePath.PathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - GetApplicationPath(&ExePath); - - Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path, - Win32DLLgs_stringLength(SourceDLLName), SourceDLLName, - MAX_PATH, Result.SourceDLLPath); - Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path, - Win32DLLgs_stringLength(WorkingDLLFileName), WorkingDLLFileName, - MAX_PATH, Result.WorkingDLLPath); - Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path, - Win32DLLgs_stringLength(LockFileName), LockFileName, - MAX_PATH, Result.LockFilePath); - - Win32Free((u8*)ExePath.Path, ExePath.PathLength, 0); - return Result; - -} - -internal b32 -HotLoadDLL(win32_dll_refresh* DLL) -{ - b32 DidReload = false; - - FILETIME UpdatedLastWriteTime = {}; - WIN32_FIND_DATA FindData = {}; - HANDLE FileHandle = FindFirstFileA(DLL->SourceDLLPath, &FindData); - if (FileHandle != INVALID_HANDLE_VALUE) - { - UpdatedLastWriteTime = FindData.ftLastWriteTime; - FindClose(FileHandle); - } - - if (CompareFileTime(&UpdatedLastWriteTime, &DLL->LastWriteTime)) - { - WIN32_FILE_ATTRIBUTE_DATA Ignored; - if (!GetFileAttributesEx(DLL->LockFilePath, GetFileExInfoStandard, &Ignored)) - { - UnloadApplicationDLL(DLL); - CopyFileA(DLL->SourceDLLPath, DLL->WorkingDLLPath, FALSE); - LoadApplicationDLL(DLL->WorkingDLLPath, DLL); - DLL->LastWriteTime = UpdatedLastWriteTime; - DidReload = true; - } - } - - return DidReload; -} - - -#define WIN32_FOLDHAUS_DLL_H -#endif // WIN32_FOLDHAUS_DLL_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_fileio.h b/src/app/platform_win32/win32_foldhaus_fileio.h deleted file mode 100644 index 906d947..0000000 --- a/src/app/platform_win32/win32_foldhaus_fileio.h +++ /dev/null @@ -1,283 +0,0 @@ -// -// File: win32_foldhaus_fileio.h -// Author: Peter Slattery -// Creation Date: 2020-02-04 -// -// -// NOTE: Relies on having imported foldhaus_platform.h prior to this file -// -#ifndef WIN32_FOLDHAUS_FILEIO_H - -internal u64 -Win32HighLowToU64(u32 LowPart, u32 HighPart) -{ - ULARGE_INTEGER Time = {}; - Time.LowPart = LowPart; - Time.HighPart = HighPart; - u64 Result = Time.QuadPart; - return Result; -} - -internal u64 -Win32FileTimeToU64(FILETIME FileTime) -{ - u64 Result = Win32HighLowToU64(FileTime.dwLowDateTime, FileTime.dwHighDateTime); - return Result; -} - -GET_FILE_INFO(Win32GetFileInfo) -{ - Assert(IsNullTerminated(Path)); - gs_file_info Result = {}; - HANDLE FileHandle = CreateFileA(Path.Str, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (FileHandle != INVALID_HANDLE_VALUE) - { - Result.Path = Path; - Result.FileSize = (u64)GetFileSize(FileHandle, NULL) + 1; - FILETIME CreationTime, LastWriteTime; - if (GetFileTime(FileHandle, &CreationTime, (LPFILETIME)0, &LastWriteTime)) - { - Result.CreationTime = Win32FileTimeToU64(CreationTime); - Result.LastWriteTime = Win32FileTimeToU64(LastWriteTime); - } - else - { - PrintLastError(); - } - CloseHandle(FileHandle); - } - else - { - DWORD FileAttr = GetFileAttributes(Path.Str); - if (FileAttr != INVALID_FILE_ATTRIBUTES && - (FileAttr & FILE_ATTRIBUTE_DIRECTORY)) - { - Result.Path = Path; - Result.IsDirectory = true; - } - else - { - // Path is not a file or directory - } - } - return Result; -} - -READ_ENTIRE_FILE(Win32ReadEntireFile) -{ - Assert(DataIsNonEmpty(Memory)); - Assert(IsNullTerminated(Path)); - - gs_file Result = {0}; - u32 Error = 0; - Result.FileInfo.Path = Path; - - HANDLE FileHandle = CreateFileA(Path.Str, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (FileHandle != INVALID_HANDLE_VALUE) - { - DWORD BytesRead = 0; - if (ReadFile(FileHandle, (LPVOID)Memory.Memory, Memory.Size - 1, (LPDWORD)(&BytesRead), NULL)) - { - Memory.Memory[Memory.Size - 1] = 0; - Result.Data = Memory; - - gs_string AbsolutePath = PushString(FileHandler.Transient, 512); - AbsolutePath.Length = GetFullPathNameA(Path.Str, AbsolutePath.Size, AbsolutePath.Str, NULL); - if (AbsolutePath.Length == 0) - { - Error = GetLastError(); - InvalidCodePath; - } - Result.FileInfo.AbsolutePath = AbsolutePath.ConstString; - } - else - { - // NOTE(Peter): If we get to this error case, it means that the file exists, - // and was successfully opened, but we can't read from it. I'm choosing to - // treat this as a legitimate error at this point. - gs_string Message = Win32DumpErrorAndPrepareMessageBoxString(FileHandler.Transient, "Attempting to read file: %S", Path); - if (MessageBox(NULL, Message.Str, "Error", MB_OK) == IDOK) - { - PostQuitMessage(-1); - } - } - CloseHandle(FileHandle); - } - else - { - - } - - return Result; -} - -WRITE_ENTIRE_FILE(Win32WriteEntireFile) -{ - Assert(DataIsNonEmpty(Data)); - Assert(IsNullTerminated(Path)); - - bool Success = false; - HANDLE FileHandle = CreateFileA(Path.Str, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (FileHandle != INVALID_HANDLE_VALUE) - { - DWORD BytesWritten = 0; - if (WriteFile(FileHandle, Data.Memory, Data.Size, &BytesWritten, NULL)) - { - Success = (BytesWritten == Data.Size); - } - else - { - gs_string Message = Win32DumpErrorAndPrepareMessageBoxString(FileHandler.Transient, "Attempting to write to file: %S", Path); - MessageBox(NULL, Message.Str, "Error", MB_OK); - } - CloseHandle(FileHandle); - } - else - { - - } - - return Success; -} - -internal FILETIME -GetFileLastWriteTime(char* Path) -{ - FILETIME Result = {}; - - WIN32_FIND_DATA FindData = {}; - HANDLE FileHandle = FindFirstFileA(Path, &FindData); - - if (FileHandle != INVALID_HANDLE_VALUE) - { - Result = FindData.ftLastWriteTime; - FindClose(FileHandle); - } - else - { - // TODO(Peter): :ErrorLogging - } - - return Result; -} - -struct temp_file_list_entry -{ - gs_file_info Info; - temp_file_list_entry* Next; -}; - -struct temp_file_list -{ - temp_file_list_entry* First; - temp_file_list_entry* Last; -}; - -internal void -Win32SetFileInfoFromFindFileData(gs_file_info* Info, WIN32_FIND_DATA FindFileData, gs_const_string SearchPath, gs_memory_arena* Storage) -{ - u32 FileNameLength = CharArrayLength(FindFileData.cFileName); - - Info->FileSize = Win32HighLowToU64(FindFileData.nFileSizeLow, FindFileData.nFileSizeHigh); - Info->CreationTime = Win32FileTimeToU64(FindFileData.ftCreationTime); - Info->LastWriteTime = Win32FileTimeToU64(FindFileData.ftLastWriteTime); - Info->IsDirectory = HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY); - - // NOTE(Peter): String Storage - // Storing the string in the final storage means we don't have to copy the string later, and all - // strings will be continguous in memory at the calling site, though they will be before the array - gs_string FileName = PushString(Storage, SearchPath.Length + FileNameLength + 2); - PrintF(&FileName, "%S%.*s", SearchPath, FileName.Size, FindFileData.cFileName); - if (Info->IsDirectory) - { - AppendPrintF(&FileName, "\\"); - } - NullTerminate(&FileName); - - Info->Path = FileName.ConstString; -} - -internal u32 -Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list* TempList, gs_const_string Path, gs_memory_arena* Storage, b32 Flags) -{ - u32 FilesCount = 0; - Assert(Path.Str[Path.Length - 1] != '\\' && - Path.Str[Path.Length - 1] != '/'); - gs_const_string SearchPath = Path; - - gs_const_string SearchPathDir = SearchPath; - s64 LastSlash = FindLastFromSet(SearchPath, "\\/"); - if (LastSlash >= 0) - { - SearchPathDir = Substring(SearchPath, 0, LastSlash + 1); - } - - WIN32_FIND_DATA FindFileData; - HANDLE SearchHandle = FindFirstFile(Path.Str, &FindFileData); - if (SearchHandle != INVALID_HANDLE_VALUE) - { - do - { - b32 AddFile = true; - - if (HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) - { - gs_const_string SubDirName = ConstString(FindFileData.cFileName); - bool IsNav = (StringsEqual(SubDirName, ConstString(".")) || - StringsEqual(SubDirName, ConstString(".."))); - - if (HasFlag(Flags, EnumerateDirectory_Recurse)) - { - if (!IsNav) - { - gs_string SubDirectoryPath = PushString(FileHandler.Transient, SearchPath.Length + SubDirName.Length + 3); - PrintF(&SubDirectoryPath, "%S%S/*\0", SearchPath, SubDirName); - FilesCount += Win32EnumerateDirectoryIntoTempList(FileHandler, TempList, SubDirectoryPath.ConstString, - Storage, Flags); - } - } - - AddFile = HasFlag(Flags, EnumerateDirectory_IncludeDirectories); - } - - if (AddFile) - { - temp_file_list_entry* File = PushStruct(FileHandler.Transient, temp_file_list_entry); - *File = {0}; - Win32SetFileInfoFromFindFileData(&File->Info, FindFileData, SearchPathDir, Storage); - SLLPushOrInit(TempList->First, TempList->Last, File); - FilesCount += 1; - } - }while(FindNextFile(SearchHandle, &FindFileData)); - } - else - { - PrintLastError(); - } - - return FilesCount; -} - -ENUMERATE_DIRECTORY(Win32EnumerateDirectory) -{ - Assert(IsNullTerminated(Path)); - gs_file_info_array Result = {}; - - temp_file_list TempList = {}; - Result.MaxCount = Win32EnumerateDirectoryIntoTempList(FileHandler, &TempList, Path, Storage, Flags); - - Result.Values = PushArray(Storage, gs_file_info, Result.MaxCount); - for (temp_file_list_entry* FileAt = TempList.First; - FileAt != 0; - FileAt = FileAt->Next) - { - // NOTE(Peter): We don't copy the file name here because its already in Storage. - // See String Storage note above ^^ - Result.Values[Result.Count++] = FileAt->Info; - } - - return Result; -} - -#define WIN32_FOLDHAUS_FILEIO_H -#endif // WIN32_FOLDHAUS_FILEIO_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_memory.h b/src/app/platform_win32/win32_foldhaus_memory.h deleted file mode 100644 index 6dbce1c..0000000 --- a/src/app/platform_win32/win32_foldhaus_memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* date = May 10th 2021 11:48 pm */ - -#ifndef GS_MEMORY_WIN32_H -#define GS_MEMORY_WIN32_H - -PLATFORM_ALLOC(Win32Alloc) -{ - u8* Result = (u8*)VirtualAlloc(NULL, Size, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); - if (ResultSize) *ResultSize = Size; - return Result; -} - -PLATFORM_FREE(Win32Free) -{ - VirtualFree(Base, 0, MEM_RELEASE); -} - -internal gs_allocator -CreatePlatformAllocator() -{ - return AllocatorCreate(Win32Alloc, Win32Free, 0); -} - -#endif //GS_MEMORY_WIN32_H diff --git a/src/app/platform_win32/win32_foldhaus_mouse.h b/src/app/platform_win32/win32_foldhaus_mouse.h deleted file mode 100644 index 0dbc3d4..0000000 --- a/src/app/platform_win32/win32_foldhaus_mouse.h +++ /dev/null @@ -1,118 +0,0 @@ -// -// File: win32_mouse.h -// Author: Peter Slattery -// Creation Date: 2021-01-10 -// -#ifndef WIN32_MOUSE_H - -HCURSOR CursorArrow; -HCURSOR CursorPointer; -HCURSOR CursorLoading; -HCURSOR CursorHArrows; -HCURSOR CursorVArrows; -HCURSOR CursorDTopLeftArrows; -HCURSOR CursorDTopRightArrows; - -HCURSOR CurrentCursor; - -// NOTE(Peter): Only meant to take one of the values specified below: -// IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM, -// IDC_ICON, IDC_NO, IDC_SIZE, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, -// IDC_SIZEWE, IDC_UPARROW, IDC_WAIT -internal HCURSOR -Win32LoadSystemCursor(char* CursorIdentifier) -{ - u32 Error = 0; - HCURSOR Result = LoadCursorA(NULL, CursorIdentifier); - if (Result == NULL) - { - Error = GetLastError(); - InvalidCodePath; - } - return Result; -} - -internal void -Mouse_Init() -{ - CursorArrow = Win32LoadSystemCursor(IDC_ARROW); - CursorPointer = Win32LoadSystemCursor(IDC_HAND); - CursorLoading = Win32LoadSystemCursor(IDC_WAIT); - CursorHArrows = Win32LoadSystemCursor(IDC_SIZEWE); - CursorVArrows = Win32LoadSystemCursor(IDC_SIZENS); - CursorDTopLeftArrows = Win32LoadSystemCursor(IDC_SIZENWSE); - CursorDTopRightArrows = Win32LoadSystemCursor(IDC_SIZENESW); -} - -internal void -Mouse_Update(window Window, context* Context) -{ - POINT Pos; - GetCursorPos (&Pos); - ScreenToClient(Window.Handle, &Pos); - - Context->Mouse.Scroll = 0; - Context->Mouse.OldPos = Context->Mouse.Pos; - Context->Mouse.Pos = v2{(r32)Pos.x, (r32)Window.Height - Pos.y}; - Context->Mouse.DeltaPos = Context->Mouse.Pos - Context->Mouse.OldPos; - - if (KeyIsDown(Context->Mouse.LeftButtonState)) - { - SetKeyWasDown(Context->Mouse.LeftButtonState); - } - else - { - SetKeyWasUp(Context->Mouse.LeftButtonState); - } - - if (KeyIsDown(Context->Mouse.MiddleButtonState)) - { - SetKeyWasDown(Context->Mouse.MiddleButtonState); - } - else - { - SetKeyWasUp(Context->Mouse.MiddleButtonState); - } - - - if (KeyIsDown(Context->Mouse.RightButtonState)) - { - SetKeyWasDown(Context->Mouse.RightButtonState); - } - else - { - SetKeyWasUp(Context->Mouse.RightButtonState); - } -} - - -internal void -Mouse_Advance(context* Context) -{ - Context->Mouse.LeftButtonState = GetMouseButtonStateAdvanced(Context->Mouse.LeftButtonState); - Context->Mouse.MiddleButtonState = GetMouseButtonStateAdvanced(Context->Mouse.MiddleButtonState); - Context->Mouse.RightButtonState = GetMouseButtonStateAdvanced(Context->Mouse.RightButtonState); - - HCURSOR NewCursor = 0; - switch (Context->Mouse.CursorType) - { - case CursorType_Arrow: { NewCursor = CursorArrow; } break; - case CursorType_Pointer: { NewCursor = CursorPointer; }break; - case CursorType_Loading: { NewCursor = CursorLoading; }break; - case CursorType_HArrows: { NewCursor = CursorHArrows; }break; - case CursorType_VArrows: { NewCursor = CursorVArrows; }break; - case CursorType_DTopLeftArrows: { NewCursor = CursorDTopLeftArrows; }break; - case CursorType_DTopRightArrows: { NewCursor = CursorDTopRightArrows; }break; - - InvalidDefaultCase; - } - if (NewCursor != CurrentCursor) - { - CurrentCursor = NewCursor; - SetCursor(NewCursor); - } -} - - -#define WIN32_MOUSE_H -#endif // WIN32_MOUSE_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_serial.h b/src/app/platform_win32/win32_foldhaus_serial.h deleted file mode 100644 index 4b309c8..0000000 --- a/src/app/platform_win32/win32_foldhaus_serial.h +++ /dev/null @@ -1,380 +0,0 @@ -// -// File: win32_serial.h -// Author: Peter Slattery -// Creation Date: 2020-10-01 -// -#ifndef WIN32_SERIAL_H - -global u32 Win32SerialHandlesCountMax; -global HANDLE* Win32SerialHandles; -global gs_string* Win32SerialPortNames; -global s32* Win32SerialPortFilled; - -DCB -Win32SerialPort_GetState(HANDLE ComPortHandle) -{ - DEBUG_TRACK_FUNCTION; - DCB ControlSettings = {0}; - ZeroStruct(&ControlSettings); - ControlSettings.DCBlength = sizeof(ControlSettings); - - bool Success = GetCommState(ComPortHandle, &ControlSettings); - Assert(Success); - - return ControlSettings; -} - -void -Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits) -{ - DEBUG_TRACK_FUNCTION; - DCB ControlSettings = Win32SerialPort_GetState(ComPortHandle); - - // TODO(pjs): Validate BaudRate - There's only certain rates that are valid right? - ControlSettings.BaudRate = BaudRate; - - if (Parity == NOPARITY) - { - ControlSettings.Parity = Parity; - ControlSettings.fParity = 0; - } - if (Parity == EVENPARITY || Parity == ODDPARITY) - { - ControlSettings.Parity = Parity; - ControlSettings.fParity = 1; - } - - ControlSettings.StopBits = StopBits; - ControlSettings.ByteSize = ByteSize; - - ControlSettings.fBinary = true; - - ControlSettings.fOutxCtsFlow = false; - ControlSettings.fOutxDsrFlow = false; - ControlSettings.fDtrControl = DTR_CONTROL_DISABLE; - ControlSettings.fDsrSensitivity = 0; - ControlSettings.fRtsControl = RTS_CONTROL_DISABLE; - ControlSettings.fOutX = false; - ControlSettings.fInX = false; - - ControlSettings.fErrorChar = 0; - ControlSettings.fNull = false; - ControlSettings.fAbortOnError = false; - ControlSettings.wReserved = false; - ControlSettings.XonLim = 2; - ControlSettings.XoffLim = 4; - ControlSettings.XonChar = 0x13; - ControlSettings.XoffChar = 0x19; - ControlSettings.EvtChar = 0; - - bool Success = SetCommState(ComPortHandle, &ControlSettings); -} - -gs_const_string_array -Win32SerialPorts_List(gs_memory_arena* Arena, gs_memory_arena* Transient) -{ - gs_const_string_array Result = {}; - - DWORD SizeNeeded0 = 0; - DWORD CountReturned0 = 0; - EnumPorts(NULL, 1, 0, 0, &SizeNeeded0, &CountReturned0); - Assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); - - DWORD SizeNeeded1 = 0; - DWORD CountReturned1 = 0; - PORT_INFO_1* PortsArray = (PORT_INFO_1*)PushSize(Transient, SizeNeeded0).Memory; - if (EnumPorts(NULL, - 1, - (u8*)PortsArray, - SizeNeeded0, - &SizeNeeded1, - &CountReturned1)) - { - Result.CountMax = (u64)CountReturned1; - Result.Strings = PushArray(Arena, gs_const_string, Result.CountMax); - - for (; Result.Count < Result.CountMax; Result.Count++) - { - u64 Index = Result.Count; - u64 StrLen = CStringLength(PortsArray[Index].pName); - gs_string Str = PushString(Arena, StrLen); - PrintF(&Str, "%.*s", StrLen, PortsArray[Index].pName); - Result.Strings[Result.Count] = Str.ConstString; - } - } - - return Result; -} - -bool -Win32SerialPort_Exists(char* PortName, gs_memory_arena* Transient) -{ - bool Result = false; - if (PortName != 0) - { - gs_const_string PortIdent = ConstString(PortName); - u32 IdentBegin = FindLast(PortIdent, '\\') + 1; - PortIdent = Substring(PortIdent, IdentBegin, PortIdent.Length); - - gs_const_string_array PortsAvailable = Win32SerialPorts_List(Transient, Transient); - - for (u64 i = 0; i < PortsAvailable.Count; i++) - { - gs_const_string AvailablePortName = PortsAvailable.Strings[i]; - if (StringsEqualUpToLength(AvailablePortName, PortIdent, PortIdent.Length)) - { - Result = true; - break; - } - } - } - return Result; -} - -HANDLE -Win32SerialPort_Open(char* PortName, gs_memory_arena* Transient) -{ - DEBUG_TRACK_FUNCTION; - HANDLE ComPortHandle = INVALID_HANDLE_VALUE;; - - if (Win32SerialPort_Exists(PortName, Transient)) - { - - ComPortHandle = CreateFile(PortName, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, // Default Security Attr - OPEN_EXISTING, - 0, // Not overlapped I/O - NULL); - - bool HasError = false; - - if (ComPortHandle != INVALID_HANDLE_VALUE) - { - COMMTIMEOUTS Timeouts = { 0 }; - Timeouts.ReadIntervalTimeout = 0; // in milliseconds - Timeouts.ReadTotalTimeoutConstant = 0; // in milliseconds - Timeouts.ReadTotalTimeoutMultiplier = 0; // in milliseconds - Timeouts.WriteTotalTimeoutConstant = 0; // in milliseconds - Timeouts.WriteTotalTimeoutMultiplier = 0; // in milliseconds - - HasError = !SetCommTimeouts(ComPortHandle, &Timeouts); - } - else - { - HasError = true; - } - - if (HasError) - { - // Error - s32 Error = GetLastError(); - switch (Error) - { - case ERROR_INVALID_FUNCTION: - case ERROR_NO_SUCH_DEVICE: - case ERROR_FILE_NOT_FOUND: - { - // NOTE(PS): The outer scope should handle these cases - ComPortHandle = INVALID_HANDLE_VALUE; - }break; - - InvalidDefaultCase; - } - } - } - - return ComPortHandle; -} - -void -Win32SerialPort_Close(HANDLE PortHandle) -{ - CloseHandle(PortHandle); -} - -bool -Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer) -{ - DEBUG_TRACK_FUNCTION; - Assert(PortHandle != INVALID_HANDLE_VALUE); - bool Success = false; - - DWORD BytesWritten = 0; - if (WriteFile(PortHandle, Buffer.Memory, Buffer.Size, &BytesWritten, NULL)) - { - Success = (BytesWritten == Buffer.Size); - if (!Success) - { - Log_Error(GlobalLogBuffer, "Error: Entire buffer not written.\n"); - } - } - else - { - Log_Error(GlobalLogBuffer, "Error: Unable to write to port\n"); - s32 Error = GetLastError(); - switch (Error) - { - case ERROR_OPERATION_ABORTED: - case ERROR_GEN_FAILURE: - { - // NOTE(pjs): Probably means that the serial port became invalid - // ie. the usb stick was removed - }break; - - case ERROR_ACCESS_DENIED: - { - // ?? - }break; - - case ERROR_NO_SUCH_DEVICE: - { - }break; - - case ERROR_INVALID_HANDLE: - InvalidDefaultCase; - } - } - - return Success; -} - -bool -Win32SerialPort_SetRead(HANDLE PortHandle) -{ - bool Status = SetCommMask(PortHandle, EV_RXCHAR); - return Status; -} - -u32 -Win32SerialPort_ReadMessageWhenReady(HANDLE PortHandle, gs_data Data) -{ - u32 ReadSize = 0; - - DWORD EventMask = 0; - bool Status = WaitCommEvent(PortHandle, &EventMask, NULL); - if (Status) - { - DWORD NoBytesRead = 0; - do - { - u8 Byte = 0; - Status = ReadFile(PortHandle, &Byte, sizeof(char), &NoBytesRead, NULL); - Data.Memory[ReadSize] = Byte; - ReadSize++; - } - while (NoBytesRead > 0 && ReadSize < Data.Size); - } - //Read data and store in a buffer - - return ReadSize; -} - -///////////////////////// -// Win32SerialArray - -void -Win32SerialArray_Create(gs_memory_arena* A) -{ - DEBUG_TRACK_FUNCTION; - - Win32SerialHandlesCountMax = 32; - - Win32SerialHandles = PushArray(A, HANDLE, Win32SerialHandlesCountMax); - Win32SerialPortNames = PushArray(A, gs_string, Win32SerialHandlesCountMax); - Win32SerialPortFilled = PushArray(A, s32, Win32SerialHandlesCountMax); - - u64 PortNameSize = 256; - u64 PortNameBufferSize = PortNameSize * Win32SerialHandlesCountMax; - char* PortNameBuffer = PushArray(A, char, PortNameBufferSize); - for (u32 i = 0; i < Win32SerialHandlesCountMax; i++) - { - char* NameBase = PortNameBuffer + (PortNameSize * i); - Win32SerialPortNames[i] = MakeString(NameBase, 0, PortNameSize); - Win32SerialPortFilled[i] = 0; - } -} - -void -Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName) -{ - DEBUG_TRACK_FUNCTION; - - bool Found = false; - for (u32 i = 0; i < Win32SerialHandlesCountMax; i++) - { - bool WasFilled = InterlockedCompareExchange((LONG volatile*)Win32SerialPortFilled + i, 1, 0); - if (!WasFilled) - { - Win32SerialHandles[i] = SerialHandle; - PrintF(&Win32SerialPortNames[i], "%S", PortName); - Found = true; - break; - } - } - Assert(Found); -} - -void -Win32SerialArray_Pop(u32 Index) -{ - bool WasFilled = InterlockedCompareExchange((LONG volatile*)Win32SerialPortFilled + Index, 0, 1); - Assert(WasFilled); - Win32SerialPortFilled[Index] = false; - Win32SerialHandles[Index] = INVALID_HANDLE_VALUE; -} - -HANDLE -Win32SerialArray_Get(gs_const_string PortName) -{ - DEBUG_TRACK_FUNCTION; - - HANDLE PortHandle = INVALID_HANDLE_VALUE; - for (u32 i = 0; i < Win32SerialHandlesCountMax; i++) - { - if (Win32SerialPortFilled[i] && - StringsEqual(Win32SerialPortNames[i].ConstString, PortName)) - { - PortHandle = Win32SerialHandles[i]; - break; - } - } - return PortHandle; -} - -HANDLE -Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits, gs_memory_arena* Transient) -{ - DEBUG_TRACK_FUNCTION; - - HANDLE PortHandle = Win32SerialArray_Get(PortName); - if (PortHandle == INVALID_HANDLE_VALUE) - { - Assert(IsNullTerminated(PortName)); - PortHandle = Win32SerialPort_Open(PortName.Str, Transient); - if (PortHandle != INVALID_HANDLE_VALUE) - { - Win32SerialPort_SetState(PortHandle, BaudRate, ByteSize, Parity, StopBits); - Win32SerialArray_Push(PortHandle, PortName); - } - } - return PortHandle; -} - -void -Win32SerialArray_Close(gs_const_string PortName) -{ - for (u32 i = 0; i < Win32SerialHandlesCountMax; i++) - { - if (Win32SerialPortFilled[i] && StringsEqual(Win32SerialPortNames[i].ConstString, PortName)) - { - Win32SerialPort_Close(Win32SerialHandles[i]); - Win32SerialArray_Pop(i); - break; - } - } -} - -#define WIN32_SERIAL_H -#endif // WIN32_SERIAL_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_socket.h b/src/app/platform_win32/win32_foldhaus_socket.h deleted file mode 100644 index 1f05067..0000000 --- a/src/app/platform_win32/win32_foldhaus_socket.h +++ /dev/null @@ -1,539 +0,0 @@ -// -// File: win32_foldhaus_socket.h -// Author: Peter Slattery -// Creation Date: 2020-10-03 -// -#ifndef WIN32_FOLDHAUS_SOCKET_H - -struct win32_socket -{ - SOCKET Socket; -}; - -struct win32_socket_array -{ - win32_socket* Values; - s32 CountMax; - s32 Count; -}; - -global WSADATA WSAData; -global win32_socket_array Win32Sockets; - -////////////////////// -// -// Win32 Socket Array - -internal win32_socket_array -Win32SocketArray_Create(u32 CountMax, gs_memory_arena* Storage) -{ - win32_socket_array Result = {}; - Result.CountMax = CountMax; - Result.Values = PushArray(Storage, win32_socket, CountMax); - return Result; -} - -internal s32 -Win32SocketArray_Take(win32_socket_array* Array) -{ - Assert(Array->Count < Array->CountMax); - s32 Result = Array->Count++; - win32_socket* Socket = Array->Values + Result; - *Socket = {0}; - return Result; -} - -internal win32_socket* -Win32SocketArray_Get(win32_socket_array Array, s32 Index) -{ - Assert(Index < Array.Count); - win32_socket* Result = Array.Values + Index; - return Result; -} - -////////////////////// -// -// Win32 Sockets - -internal win32_socket -Win32Socket_Create(s32 AddressFamily, s32 Type, s32 Protocol) -{ - win32_socket Result = {0}; - Result.Socket = socket(AddressFamily, Type, Protocol); - if (Result.Socket == INVALID_SOCKET) - { - s32 Error = WSAGetLastError(); - InvalidCodePath; - } - return Result; -} - -internal void -Win32Socket_Bind(win32_socket* Socket, s32 AddressFamily, char* Address, s32 Port) -{ - sockaddr_in Service = {0}; - Service.sin_family = AddressFamily; - Service.sin_addr.s_addr = inet_addr(Address); - Service.sin_port = htons(Port); - - s32 Result = bind(Socket->Socket, (SOCKADDR*)&Service, sizeof(Service)); - if (Result == SOCKET_ERROR) - { - s32 Error = WSAGetLastError(); - InvalidCodePath; - } -} - -internal win32_socket -Win32Socket_ConnectToAddress(char* Address, char* DefaultPort) -{ - win32_socket Result = {}; - - addrinfo Hints = {0}; - Hints.ai_family = AF_UNSPEC; - Hints.ai_socktype = SOCK_STREAM; - Hints.ai_protocol = IPPROTO_TCP; - - addrinfo* PotentialConnections; - s32 Error = getaddrinfo(Address, DefaultPort, &Hints, &PotentialConnections); - if (Error == 0) - { - for (addrinfo* InfoAt = PotentialConnections; InfoAt != NULL; InfoAt = InfoAt->ai_next) - { - win32_socket Socket = Win32Socket_Create(InfoAt->ai_family, InfoAt->ai_socktype, InfoAt->ai_protocol); - if (Socket.Socket == INVALID_SOCKET) - { - Error = WSAGetLastError(); - InvalidCodePath; - } - - Error = connect(Socket.Socket, InfoAt->ai_addr, (int)InfoAt->ai_addrlen); - if (Error == SOCKET_ERROR) - { - closesocket(Socket.Socket); - continue; - } - else - { - Result = Socket; - break; - } - } - } - else - { - Error = WSAGetLastError(); - InvalidCodePath; - } - - freeaddrinfo(PotentialConnections); - - return Result; -} - -internal bool -Win32ConnectSocket(platform_socket_manager* Manager, platform_socket* Socket) -{ - bool Result = false; - - addrinfo Hints = {0}; - Hints.ai_family = AF_UNSPEC; - Hints.ai_socktype = SOCK_STREAM; - Hints.ai_protocol = IPPROTO_TCP; - - addrinfo* PotentialConnections; - s32 Error = getaddrinfo(Socket->Addr, Socket->Port, &Hints, &PotentialConnections); - if (Error == 0) - { - for (addrinfo* InfoAt = PotentialConnections; InfoAt != NULL; InfoAt = InfoAt->ai_next) - { - SOCKET SocketHandle = socket(InfoAt->ai_family, InfoAt->ai_socktype, InfoAt->ai_protocol); - if (SocketHandle == INVALID_SOCKET) - { - Error = WSAGetLastError(); - InvalidCodePath; - } - - // If iMode == 0, blocking is enabled - // if iMode != 0, non-blocking mode is enabled - u_long iMode = 0; - Error = ioctlsocket(SocketHandle, FIONBIO, &iMode); - if (Error != NO_ERROR) - { - InvalidCodePath; - } - - Error = connect(SocketHandle, InfoAt->ai_addr, (int)InfoAt->ai_addrlen); - if (Error == SOCKET_ERROR) - { - u32 Status = WSAGetLastError(); - if (Status == WSAEWOULDBLOCK) - { - // Non-blocking sockets -#if 0 - TIMEVAL Timeout = { 0, 500 }; - fd_set SocketSet = {}; - FD_ZERO(&SocketSet); - FD_SET(SocketHandle, &SocketSet); - Assert(FD_ISSET(SocketHandle, &SocketSet)); - Status = select(0, &SocketSet, 0, 0, (const TIMEVAL*)&Timeout); - if (Status == SOCKET_ERROR) - { - - } - else if (Status == 0) - { - } - else - { - - } -#endif - } - else - { - closesocket(SocketHandle); - continue; - } - } - - Socket->PlatformHandle = (u8*)Win32Alloc(sizeof(SOCKET), 0, 0); - *(SOCKET*)Socket->PlatformHandle = SocketHandle; - Result = true; - break; - } - } - else - { - Error = WSAGetLastError(); - InvalidCodePath; - } - - if (!Result) - { - Assert(Socket->PlatformHandle == 0); - } - - freeaddrinfo(PotentialConnections); - return Result; -} - -internal bool -Win32CloseSocket(platform_socket_manager* Manager, platform_socket* Socket) -{ - SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; - closesocket(*Win32Sock); - Win32Free((u8*)Socket->PlatformHandle, sizeof(SOCKET), 0); - *Socket = {}; - return true; -} - -internal bool -Win32SocketQueryStatus(platform_socket_manager* Manager, platform_socket* Socket) -{ - SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; - bool Result = (*Win32Sock != INVALID_SOCKET); - return Result; -} - -internal u32 -Win32SocketPeek(platform_socket_manager* Manager, platform_socket* Socket) -{ - u32 Result = 0; - s32 Flags = MSG_PEEK; - SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; - char Temp[4]; - u32 TempSize = 4; - - //Log_Message(GlobalLogBuffer, "Pre Peek..."); - //s32 BytesQueued = recv(*Win32Sock, Temp, TempSize, Flags); - u_long BytesQueued = 0; - ioctlsocket(*Win32Sock, FIONREAD, &BytesQueued); - //Log_Message(GlobalLogBuffer, "Post Peek\n"); - - if (BytesQueued != SOCKET_ERROR) - { - Result = (u32)BytesQueued; - } - else - { - s32 Error = WSAGetLastError(); - switch (Error) - { - case WSAEWOULDBLOCK: - { - // NOTE(PS): This case covers non-blocking sockets - // if we peek and there's nothing there, it returns - // this error code. MSDN says its a non-fatal error - // and the operation should be retried later - Result = 0; - } break; - - case WSAENOTCONN: - case WSAECONNRESET: - case WSAECONNABORTED: - { - CloseSocket(Manager, Socket); - }break; - - InvalidDefaultCase; - } - } - return (s32)Result; -} - -internal gs_data -Win32SocketReceive(platform_socket_manager* Manager, platform_socket* Socket, gs_memory_arena* Storage) -{ - // TODO(pjs): Test this first code path when you have data running - it should - // get the actual size of the data packet being sent -#if 0 - gs_data Result = {}; - s32 BytesQueued = Win32Socket_PeekGetTotalSize(Socket); - if (BytesQueued > 0) - { - Result = PushSizeToData(Storage, BytesQueued); - s32 Flags = 0; - s32 BytesReceived = recv(Socket->Socket, (char*)Result.Memory, Result.Size, Flags); - Assert(BytesReceived == BytesQueued); - } - return Result; -#else - gs_data Result = PushSize(Storage, 1024); - s32 Flags = 0; - SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; - s32 BytesReceived = recv(*Win32Sock, (char*)Result.Memory, Result.Size, Flags); - if (BytesReceived == SOCKET_ERROR) - { - // TODO(pjs): Error logging - s32 Error = WSAGetLastError(); - InvalidCodePath; - } - Result.Size = BytesReceived; - return Result; -#endif -} - - -internal s32 -Win32SocketSend(platform_socket_manager* Manager, platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags) -{ - SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; - - sockaddr_in SockAddress = {}; - SockAddress.sin_family = AF_INET; - SockAddress.sin_port = HostToNetU16(Port); - SockAddress.sin_addr.s_addr = HostToNetU32(Address); - - s32 LengthSent = sendto(*Win32Sock, (char*)Data.Memory, Data.Size, Flags, (sockaddr*)&SockAddress, sizeof(sockaddr_in)); - - //Log_Message(GlobalLogBuffer, "Attempting To Send Network Data: "); - if (LengthSent == SOCKET_ERROR) - { - s32 Error = WSAGetLastError(); - switch (Error) - { - case WSAEWOULDBLOCK: - { - // NOTE(PS): This covers non-blocking sockets - // In this case the message should be tried again - LengthSent = 0; - //Log_Message(GlobalLogBuffer, "Not sent, buffered\n"); - }break; - - case WSAECONNABORTED: - case WSAENETUNREACH: - case WSAECONNRESET: - case WSAENOTCONN: - { - if (CloseSocket(Manager, Socket)) - { - Log_Error(GlobalLogBuffer, "Error: %d\n", Error); - Error = 0; - } - }break; - - InvalidDefaultCase; - } - } - else - { - Log_Message(GlobalLogBuffer, "Sent\n"); - } - - return LengthSent; -} - -internal s32 -Win32Socket_SetOption(win32_socket* Socket, s32 Level, s32 Option, const char* OptionValue, s32 OptionLength) -{ - int Error = setsockopt(Socket->Socket, Level, Option, OptionValue, OptionLength); - if (Error == SOCKET_ERROR) - { - Error = WSAGetLastError(); - // TODO(Peter): :ErrorLogging - } - - return Error; -} - -internal s32 -Win32Socket_SetOption(platform_socket_handle SocketHandle, s32 Level, s32 Option, const char* OptionValue, s32 OptionLength) -{ - win32_socket* Socket = Win32SocketArray_Get(Win32Sockets, (s32)SocketHandle); - return Win32Socket_SetOption(Socket, Level, Option, OptionValue, OptionLength); -} - - -internal s32 -Win32Socket_SendTo(platform_socket_handle SocketHandle, u32 Address, u32 Port, const char* Buffer, s32 BufferLength, s32 Flags) -{ - win32_socket* Socket = Win32SocketArray_Get(Win32Sockets, (s32)SocketHandle); - - sockaddr_in SockAddress = {}; - SockAddress.sin_family = AF_INET; - SockAddress.sin_port = HostToNetU16(Port); - SockAddress.sin_addr.s_addr = HostToNetU32(Address); - - s32 LengthSent = sendto(Socket->Socket, Buffer, BufferLength, Flags, (sockaddr*)&SockAddress, sizeof(sockaddr_in)); - - if (LengthSent == SOCKET_ERROR) - { - s32 Error = WSAGetLastError(); - switch (Error) - { - case WSAENETUNREACH: - { - Log_Message(GlobalLogBuffer, - "Non Critical Error: WSAENETUNREACH \n"); - } break; - - default: - { - Log_Error(GlobalLogBuffer, "Error: %d \n", Error); - InvalidCodePath; - } break; - } - } - - return LengthSent; -} - -internal void -Win32Socket_SetListening(win32_socket* Socket) -{ - if (listen(Socket->Socket, SOMAXCONN) == SOCKET_ERROR) - { - // TODO(pjs): Error logging - s32 Error = WSAGetLastError(); - InvalidCodePath; - } -} - -internal s32 -Win32Socket_PeekGetTotalSize(win32_socket* Socket) -{ - s32 Flags = MSG_PEEK; - char Temp[4]; - s32 BytesQueued = recv(Socket->Socket, Temp, 4, Flags); - if (BytesQueued == SOCKET_ERROR) - { - // TODO(pjs): Error logging - s32 Error = WSAGetLastError(); - BytesQueued = 0; - } - return BytesQueued; -} - -internal gs_data -Win32Socket_Receive(win32_socket* Socket, gs_memory_arena* Storage) -{ -#if 0 - gs_data Result = {}; - s32 BytesQueued = Win32Socket_PeekGetTotalSize(Socket); - if (BytesQueued > 0) - { - Result = PushSizeToData(Storage, BytesQueued); - s32 Flags = 0; - s32 BytesReceived = recv(Socket->Socket, (char*)Result.Memory, Result.Size, Flags); - Assert(BytesReceived == BytesQueued); - } - return Result; -#else - gs_data Result = PushSize(Storage, 1024); - s32 Flags = 0; - s32 BytesReceived = recv(Socket->Socket, (char*)Result.Memory, Result.Size, Flags); - if (BytesReceived == SOCKET_ERROR) - { - // TODO(pjs): Error logging - s32 Error = WSAGetLastError(); - switch (Error) - { - case WSAECONNABORTED: - case WSANOTINITIALISED: - break; - - case WSAENOTCONN: - { - - }break; - InvalidDefaultCase; - } - } - Result.Size = BytesReceived; - return Result; -#endif -} - -internal void -Win32Socket_Close(win32_socket* Socket) -{ - closesocket(Socket->Socket); - Socket->Socket = INVALID_SOCKET; -} - -internal void -Win32Socket_CloseArray(win32_socket_array Array) -{ - for (s32 i = 0; i < Array.Count; i++) - { - win32_socket* Socket = Array.Values + i; - Win32Socket_Close(Socket); - } -} - -////////////////////// -// -// Win32 Socket System - -internal void -Win32SocketSystem_Init(gs_memory_arena* Arena) -{ - WSAStartup(MAKEWORD(2, 2), &WSAData); - Win32Sockets = Win32SocketArray_Create(16, Arena); -} - -internal void -Win32SocketSystem_Cleanup() -{ - Win32Socket_CloseArray(Win32Sockets); - - s32 CleanupResult = 0; - do { - CleanupResult = WSACleanup(); - }while(CleanupResult == SOCKET_ERROR); -} - -PLATFORM_GET_SOCKET_HANDLE(Win32GetSocketHandle) -{ - s32 Result = Win32SocketArray_Take(&Win32Sockets); - s32 Error = 0; - win32_socket* Socket = Win32SocketArray_Get(Win32Sockets, Result); - *Socket = Win32Socket_Create(AF_INET, SOCK_DGRAM, 0); - Error = Win32Socket_SetOption(Socket, IPPROTO_IP, IP_MULTICAST_TTL, - (const char*)(&Multicast_TimeToLive), sizeof(Multicast_TimeToLive)); - return (platform_socket_handle)Result; -} - -#define WIN32_FOLDHAUS_SOCKET_H -#endif // WIN32_FOLDHAUS_SOCKET_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_timing.h b/src/app/platform_win32/win32_foldhaus_timing.h deleted file mode 100644 index dee60bf..0000000 --- a/src/app/platform_win32/win32_foldhaus_timing.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// File: win32_foldhaus_timing.h -// Author: Peter Slattery -// Creation Date: 2020-02-04 -// -// -// NOTE: Relies on having imported foldhaus_platform.h prior to this file -// -#ifndef WIN32_FOLDHAUS_TIMING_H - -internal s64 -GetPerformanceFrequency () -{ - LARGE_INTEGER Frequency; - if (!QueryPerformanceFrequency(&Frequency)) - { - s32 Error = GetLastError(); - // TODO(Peter): I'm waiting to see an error actually occur here - // to know what it could possibly be. - InvalidCodePath; - } - return (s64)Frequency.QuadPart; -} - -internal s64 -GetWallClock () -{ -#if 0 - s64 Result = __rdtsc(); - return Result; -#else - LARGE_INTEGER Time; - if (!QueryPerformanceCounter(&Time)) - { - s32 Error = GetLastError(); - // TODO(Peter): I'm waiting to see an error actually occur here - // to know what it could possibly be. - InvalidCodePath; - } - return (s64)Time.QuadPart; -#endif -} - - -#define WIN32_FOLDHAUS_TIMING_H -#endif // WIN32_FOLDHAUS_TIMING_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_utils.h b/src/app/platform_win32/win32_foldhaus_utils.h deleted file mode 100644 index c1a4579..0000000 --- a/src/app/platform_win32/win32_foldhaus_utils.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// File: win32_foldhaus_utils.h -// Author: Peter Slattery -// Creation Date: 2020-10-01 -// -#ifndef WIN32_FOLDHAUS_UTILS_H - -internal gs_string -Win32DumpErrorAndPrepareMessageBoxString(gs_memory_arena* Arena, char* Format, ...) -{ - s32 Error = GetLastError(); - gs_string ErrorDump = PushString(Arena, 4096); - PrintF(&ErrorDump, - R"FOO(Win32 Error: %s\n -Error Code: %d\n - )FOO", - __FUNCTION__, - Error); - - va_list Args; - va_start(Args, Format); - PrintFArgsList(&ErrorDump, Format, Args); - va_end(Args); - - gs_data ErrorDumpData = StringToData(ErrorDump); - - HANDLE FileHandle = CreateFileA("./crashdump.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (FileHandle != INVALID_HANDLE_VALUE) - { - DWORD BytesWritten = 0; - if (WriteFile(FileHandle, ErrorDumpData.Memory, ErrorDumpData.Size, &BytesWritten, NULL)) - { - - } - CloseHandle(FileHandle); - } - - AppendPrintF(&ErrorDump, "Program will attempt to continue. See crashdump.txt for info"); - NullTerminate(&ErrorDump); - - return ErrorDump; -} - -DEBUG_PRINT(Win32DebugPrint) -{ - Log_Message(GlobalLogBuffer, "%S", Message); -} - -#define PrintLastError() PrintLastError_(__FILE__, __LINE__) -internal void -PrintLastError_(char* File, u32 Line) -{ - char DebugStringData[256]; - gs_string DebugString = MakeString(DebugStringData, 0, 256); - u32 Error = GetLastError(); - Log_Error(GlobalLogBuffer, "%s Line %d: Win32 Error %d\n\0", File, Line, Error); -} - - -internal HINSTANCE -GetHInstance() -{ - HINSTANCE Result = GetModuleHandle(NULL); - if (Result == NULL) - { - PrintLastError(); - } - return Result; -} - - -#define WIN32_FOLDHAUS_UTILS_H -#endif // WIN32_FOLDHAUS_UTILS_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_foldhaus_work_queue.h b/src/app/platform_win32/win32_foldhaus_work_queue.h deleted file mode 100644 index 7c56418..0000000 --- a/src/app/platform_win32/win32_foldhaus_work_queue.h +++ /dev/null @@ -1,250 +0,0 @@ -// -// File: win32_foldhaus_work_queue.h -// Author: Peter Slattery -// Creation Date: 2020-10-01 -// -#ifndef WIN32_FOLDHAUS_WORK_QUEUE_H - -struct worker_thread_entry -{ - b32 IsValid; - u32 Index; -}; - -struct worker_thread_info -{ - gs_thread_context ThreadContext; - HANDLE Handle; - gs_work_queue* Queue; -}; - -struct win32_work_queue -{ - u32 ThreadCount; - worker_thread_info* Threads; - gs_work_queue WorkQueue; -}; - -worker_thread_info* WorkerThreads; -win32_work_queue Win32WorkQueue; - -internal s32 -Win32GetThreadId() -{ - s32 Result = GetCurrentThreadId(); - return Result; -} - -internal gs_thread_context -Win32CreateThreadContext(gs_memory_arena* Transient = 0) -{ - gs_thread_context Result = {0}; - Result.ThreadInfo.ThreadID = Win32GetThreadId(); - Result.Allocator = CreatePlatformAllocator(); - if (Transient != 0) - { - Result.Transient = Transient; - } - else - { - Result.Transient = AllocStruct(Result.Allocator, gs_memory_arena, "Work Queue"); - *Result.Transient = MemoryArenaCreate(MB(4), Bytes(8), Result.Allocator, 0, 0, "Tctx Transient"); - } - Result.FileHandler = CreateFileHandler(Win32GetFileInfo, - Win32ReadEntireFile, - Win32WriteEntireFile, - Win32EnumerateDirectory, - Result.Transient); - - Result.DebugOutput.Print = Win32DebugPrint; - - return Result; -} - -PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue) -{ -#if DEBUG - // NOTE(Peter): Just prints out the names of all the pending jobs if we end up - // overflowing the buffer - if (Queue->JobsCount >= Queue->JobsMax) - { - gs_string DebugString = MakeString((char*)malloc(256), 256); - for (u32 i = 0; i < Queue->JobsCount; i++) - { - Log_Message(GlobalLogBuffer, "%d %s \n", i, Queue->Jobs[i].JobName); - } - } -#endif - Assert(Queue->JobsCount < Queue->JobsMax); - - gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount; - Job->WorkProc = WorkProc; - Job->Data = Data; -#if DEBUG - Job->JobName = JobName; -#endif - - // Complete Past Writes before Future Writes - _WriteBarrier(); - _mm_sfence(); - - ++Queue->JobsCount; - ReleaseSemaphore(Queue->SemaphoreHandle, 1, 0); -} - -internal worker_thread_entry -CompleteAndTakeNextJob(gs_work_queue* Queue, worker_thread_entry Completed, gs_thread_context Context) -{ - if (Completed.IsValid) - { - InterlockedIncrement((LONG volatile*)&Queue->JobsCompleted); - } - - worker_thread_entry Result = {}; - Result.IsValid = false; - - u32 OriginalNextJobIndex = Queue->NextJobIndex; - while (OriginalNextJobIndex < Queue->JobsCount) - { - u32 Index = InterlockedCompareExchange((LONG volatile*)&Queue->NextJobIndex, - OriginalNextJobIndex + 1, - OriginalNextJobIndex); - if (Index == OriginalNextJobIndex) - { - Result.Index = Index; - Result.IsValid = true; - break; - } - OriginalNextJobIndex = Queue->NextJobIndex; - } - - return Result; -} - -COMPLETE_QUEUE_WORK(Win32DoQueueWorkUntilDone) -{ - worker_thread_entry Entry = {}; - Entry.IsValid = false; - while (Queue->JobsCompleted < Queue->JobsCount) - { - Entry = CompleteAndTakeNextJob(Queue, Entry, Context); - if (Entry.IsValid) - { - Queue->Jobs[Entry.Index].WorkProc(Context, Queue->Jobs[Entry.Index].Data); - } - } -} - -DWORD WINAPI -WorkerThreadProc (LPVOID InputThreadInfo) -{ - worker_thread_info* ThreadInfo = (worker_thread_info*)InputThreadInfo; - ThreadInfo->ThreadContext = Win32CreateThreadContext(); - - worker_thread_entry Entry = {}; - Entry.IsValid = false; - while (true) - { - MemoryArenaClear(ThreadInfo->ThreadContext.Transient); - Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry, ThreadInfo->ThreadContext); - if (Entry.IsValid) - { - ThreadInfo->Queue->Jobs[Entry.Index].WorkProc(ThreadInfo->ThreadContext, - ThreadInfo->Queue->Jobs[Entry.Index].Data); - } - else - { - WaitForSingleObjectEx(ThreadInfo->Queue->SemaphoreHandle, INFINITE, 0); - } - } - - return 0; -} - -DWORD WINAPI -Win32ThreadProcWrapper(LPVOID ThreadInfo) -{ - platform_thread* Thread = (platform_thread*)ThreadInfo; - gs_thread_context Ctx = Win32CreateThreadContext(); - Thread->Proc(&Ctx, Thread->UserData); - - // TODO(pjs): Destroy Thread Context - // TODO(pjs): How do we notify the thread manager this thread belongs to that it is free? - // Probaby put a pointer to the thread manager in the platform_thread struct - // so we can update the tracking structure? - - return 0; -} - -CREATE_THREAD(Win32CreateThread) -{ - Thread->Proc = Proc; - Thread->UserData = UserData; - - // TODO(pjs): ugh, allocation out in the middle of nowhere - HANDLE* ThreadHandle = AllocStruct(Ctx.Allocator, HANDLE, "Create Thread"); - *ThreadHandle = CreateThread(0, 0, Win32ThreadProcWrapper, (void*)Thread, 0, 0); - // TODO(pjs): Error checking on the created thread - - Thread->PlatformHandle = (u8*)ThreadHandle; - - return true; -} - -KILL_THREAD(Win32KillThread) -{ - HANDLE* ThreadHandle = (HANDLE*)Thread->PlatformHandle; - TerminateThread(ThreadHandle, 0); - - // TODO(pjs): see allocation out in the middle of nowhere in Win32CreateThread - Win32Free((void*)Thread->PlatformHandle, sizeof(HANDLE), 0); - - // TODO(pjs): Error checking - return true; -} - -internal void -Win32WorkQueue_Init(gs_memory_arena* Arena, u32 ThreadCount) -{ - if (ThreadCount > 0) - { - Win32WorkQueue.ThreadCount = ThreadCount; - Win32WorkQueue.Threads = PushArray(Arena, worker_thread_info, ThreadCount); - } - - gs_work_queue WQ = {}; - WQ.SemaphoreHandle = CreateSemaphoreEx(0, 0, ThreadCount, 0, 0, SEMAPHORE_ALL_ACCESS);; - WQ.JobsMax = 512; - WQ.Jobs = PushArray(Arena, gs_threaded_job, WQ.JobsMax); - WQ.NextJobIndex = 0; - WQ.PushWorkOnQueue = Win32PushWorkOnQueue; - WQ.CompleteQueueWork = Win32DoQueueWorkUntilDone; - - Win32WorkQueue.WorkQueue = WQ; - - // ID = 0 is reserved for this thread - for (u32 i = 0; i < ThreadCount; i++) - { - worker_thread_info* T = Win32WorkQueue.Threads + i; - T->Queue = &Win32WorkQueue.WorkQueue; - T->Handle = CreateThread(0, 0, &WorkerThreadProc, (void*)T, 0, 0); - } -} - -internal void -Win32WorkQueue_Cleanup() -{ - u32 Error = 0; - for (u32 Thread = 0; Thread < Win32WorkQueue.ThreadCount; Thread++) - { - u32 Success = TerminateThread(Win32WorkQueue.Threads[Thread].Handle, 0); - if (!Success) - { - Error = GetLastError(); - InvalidCodePath; - } - } -} - -#define WIN32_FOLDHAUS_WORK_QUEUE_H -#endif // WIN32_FOLDHAUS_WORK_QUEUE_H \ No newline at end of file diff --git a/src/app/platform_win32/win32_test_code.cpp b/src/app/platform_win32/win32_test_code.cpp deleted file mode 100644 index 8c23153..0000000 --- a/src/app/platform_win32/win32_test_code.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// File: win32_test_code.cpp -// Author: Peter Slattery -// Creation Date: 2021-01-10 -// -#ifndef WIN32_TEST_CODE_CPP - -#if 0 -internal void -Win32_TestCode_UART(gs_thread_context ThreadContext) -{ - u32 LedCount = 48; - u32 MessageBaseSize = sizeof(uart_header) + sizeof(uart_channel) + sizeof(uart_footer); - MessageBaseSize += sizeof(u8) * 3 * LedCount; - gs_data MessageBuffer = PushSizeToData(ThreadContext.Transient); - - gs_memory_cursor WriteCursor = CreateMemoryCursor(MessageBuffer); - - uart_header* Header = PushStructOnCursor(WriteCursor, uart_header); - UART_FillHeader(Header, Strip.UARTAddr.Channel, UART_SET_CHANNEL_WS2812); - uart_channel* Channel = PushStructOnCursor(WriteCursor, uart_channel); - *Channel = ChannelSettings; - - for (u32 i = 0; i < LedCount; i++) - { - u8* OutputPixel = PushArrayOnCursor(WriteCursor, u8, 3); - OutputPixel[Channel->RedIndex] = (u8)(i); - OutputPixel[Channel->GreenIndex] = 0; - OutputPixel[Channel->BlueIndex] = 0; - } - - uart_footer* Footer = PushStructOnCursor(WriteCursor, uart_footer); - UART_FillFooter(Footer, (u8*)Header); -} -#endif - -win32_socket ListenSocket; -HANDLE ListenThread; - -DWORD WINAPI -Win32_TestCode_ListenThreadProc(LPVOID ThreadData) -{ - gs_thread_context Ctx = Win32CreateThreadContext(); - - temp_job_req* Req = (temp_job_req*)ThreadData; - - while (true) - { - Req->Proc(&Ctx, Req->Memory); - } -} - -internal void -Win32_TestCode_SocketReading(gs_thread_context ThreadContext, temp_job_req* Req) -{ - ListenSocket = Win32Socket_ConnectToAddress("127.0.0.1", "20185"); - u8* Arg = (u8*)Req; - ListenThread = CreateThread(0, 0, &Win32_TestCode_ListenThreadProc, Arg, 0, 0); -} - -internal void -BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) -{ - packet_ringbuffer* MicPacketBuffer = (packet_ringbuffer*)UserData; - - gs_data Data = Win32Socket_Receive(&ListenSocket, Ctx->Transient); - if (Data.Size > 0) - { - OutputDebugStringA("Listened"); - MicPacketBuffer->Values[MicPacketBuffer->WriteHead++] = Data; - if (MicPacketBuffer->WriteHead >= PACKETS_MAX) - { - MicPacketBuffer->WriteHead = 0; - } - } -} - -internal void -Win32_TestCode_SocketReading_Cleanup() -{ - TerminateThread(ListenThread, 0); - Win32Socket_Close(&ListenSocket); -} - -#define WIN32_TEST_CODE_CPP -#endif // WIN32_TEST_CODE_CPP \ No newline at end of file diff --git a/src/app/ss_blumen_lumen/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp deleted file mode 100644 index 08ac0e0..0000000 --- a/src/app/ss_blumen_lumen/blumen_lumen.cpp +++ /dev/null @@ -1,1155 +0,0 @@ -// -// File: blumen_lumen.cpp -// Author: Peter Slattery -// Creation Date: 2021-01-23 -// -#ifndef BLUMEN_LUMEN_CPP - -internal animation_handle_array -LoadAllAnimationsInDir(gs_const_string Path, blumen_lumen_state* BLState, app_state* State, context Context) -{ - animation_handle_array Result = {}; - - gs_thread_context Ctx = Context.ThreadContext; - gs_file_info_array FilesInDir = EnumerateDirectory(Ctx.FileHandler, State->Transient, Path, 0); - - Result.Count = FilesInDir.Count; - Result.Handles = PushArray(&State->Permanent, animation_handle, Result.Count); - - for (u32 i = 0; i < FilesInDir.Count; i++) - { - gs_file_info File = FilesInDir.Values[i]; - Result.Handles[i] = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, - State->Patterns, - Context, - File.Path); - } - - return Result; -} - -internal s32 -GetCCIndex (assembly Assembly, blumen_lumen_state* BLState) -{ - s32 Result = 0; - - u64 AssemblyNameHash = HashDJB2ToU32(StringExpand(Assembly.Name)); - for (u32 i = 0; i < BLState->AssemblyNameToClearCoreMapCount; i++) - { - if (AssemblyNameHash == BLState->AssemblyNameToClearCore_Names[i]) - { - Result = (s32)i; - break; - } - } - - return Result; -} - -internal void -DEBUG_AppendText(gs_string Str, gs_thread_context Ctx) -{ - gs_const_string DebugPath = ConstString("data/debug_motor_changes.txt"); - gs_file DebugFile = ReadEntireFile(Ctx.FileHandler, - DebugPath); - gs_string NewString = PushString(Ctx.Transient, DebugFile.Size + Str.Size + 16); - if (DebugFile.Size > 0) - { - PrintF(&NewString, "%.*s\nENTRY:\n", DebugFile.Size, (char*)DebugFile.Memory); - } - AppendPrintF(&NewString, "%S\n", Str.ConstString); - NullTerminate(&NewString); - - if (!WriteEntireFile(Ctx.FileHandler, DebugPath, StringToData(NewString))) - { - InvalidCodePath; - } -} - -internal void -DEBUG_SentMotorCommand(motor_packet Packet, gs_thread_context Ctx) -{ - Log_Message(GlobalLogBuffer, - "Motor Command Sent\nRequested Positions: %d %d %d\n", - Packet.FlowerPositions[0], - Packet.FlowerPositions[1], - Packet.FlowerPositions[2]); -} - -internal void -DEBUG_ReceivedMotorPositions(blumen_lumen_state* BLState, - motor_status_packet NewPos, - gs_thread_context Ctx) -{ - motor_packet LastPos = BLState->LastKnownMotorState; - bool PosChanged = (LastPos.FlowerPositions[0] != NewPos.Pos.FlowerPositions[0] || - LastPos.FlowerPositions[1] != NewPos.Pos.FlowerPositions[1] || - LastPos.FlowerPositions[2] != NewPos.Pos.FlowerPositions[2]); - - if (PosChanged) - { - Log_Message(GlobalLogBuffer, - "Motor Status Received\nCurrent Positions: %d %d %d\n", - NewPos.Pos.FlowerPositions[0], - NewPos.Pos.FlowerPositions[1], - NewPos.Pos.FlowerPositions[2]); - } -} - -internal void -DEBUG_ReceivedTemperature(temp_packet Temp, gs_thread_context Ctx) -{ - Log_Message(GlobalLogBuffer, - "\nTemperature: %d\n", - Temp.Temperature); -} - -internal void -BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) -{ - mic_listen_job_data* Data = (mic_listen_job_data*)UserData; - - gs_data Msg = {}; - - u8 WeathermanIPAddr[4] = {}; - WeathermanIPAddr[0] = 127; - WeathermanIPAddr[1] = 0; - WeathermanIPAddr[2] = 0; - WeathermanIPAddr[3] = 1; - - u32 WeathermanIPV4 = (u32)UpackB4(WeathermanIPAddr); - u32 WeathermanPort = 20185; - - platform_socket_handle_ ListenSocket = {0}; - - while (*Data->Running) - { - if (!SocketQueryStatus(Data->SocketManager, ListenSocket)) - { - Data->IsConnected = false; - if (SocketHandleIsValid(ListenSocket)) - { - Log_Message(GlobalLogBuffer, "Disconnected from Python Server\n"); - CloseSocket(Data->SocketManager, ListenSocket); - } - ListenSocket = CreateSocket(Data->SocketManager, "127.0.0.1", "20185"); - if (ListenSocket.Index != 0) - { - Log_Message(GlobalLogBuffer, "Connected to Python Server\n"); - Data->IsConnected = true; - } - } - - if (SocketQueryStatus(Data->SocketManager, ListenSocket)) - { - if (SocketPeek(Data->SocketManager, ListenSocket)) - { - Msg = SocketRecieve(Data->SocketManager, ListenSocket, Ctx->Transient); - if (Msg.Size > 0) - { - MessageQueue_Write(Data->IncomingMsgQueue, Msg); - } - } - - while (MessageQueue_CanRead(*Data->OutgoingMsgQueue)) - { - Msg = MessageQueue_Peek(Data->OutgoingMsgQueue); - - u32 Address = WeathermanIPV4; - u32 Port = WeathermanPort; - s32 Flags = 0; - s32 LengthSent = SocketSend(Data->SocketManager, ListenSocket, Address, Port, Msg, Flags); - if (LengthSent != 0) - { - // if we actually sent the message, THEN we pull it off the - // message queue - MessageQueue_Read(Data->OutgoingMsgQueue); - } else { - break; - } - } - } - } - - CloseSocket(Data->SocketManager, ListenSocket); -} - -internal void -BlumenLumen_SetPatternMode(bl_pattern_mode Mode, r32 FadeDuration, animation_system* System, blumen_lumen_state* BLState) -{ - BLState->PatternMode = Mode; - animation_handle_array Playlist = BLState->ModeAnimations[Mode]; - System->RepeatMode = AnimationRepeat_Loop; - System->PlaylistFadeTime = FadeDuration; - AnimationSystem_FadeToPlaylist(System, Playlist); -} - -internal void -BlumenLumen_LoadPatterns(app_state* State) -{ - animation_pattern_array* Patterns = &State->Patterns; - if (Patterns->CountMax == 0) - { - *Patterns = Patterns_Create(&State->Permanent, 32); - } - - Patterns->Count = 0; - Patterns_PushPattern(Patterns, Pattern_None, PATTERN_SINGLETHREADED); - Patterns_PushPattern(Patterns, Pattern_HueShift, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_Rainbow, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_Wavy, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_Patchy, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_Leafy, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_LeafyPatchy, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_WavyPatchy, PATTERN_SINGLETHREADED); - Patterns_PushPattern(Patterns, Pattern_VerticalLines, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_Rotary, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_AllOnMask, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_BulbMask, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_VoicePattern, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_VoiceAddIns, PATTERN_MULTITHREADED); - - Patterns_PushPattern(Patterns, Pattern_StemSolid, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_PrimaryHue, PATTERN_MULTITHREADED); - - Patterns_PushPattern(Patterns, Pattern_GrowFadeMask, PATTERN_MULTITHREADED); - Patterns_PushPattern(Patterns, Pattern_RainbowLoadingBar, PATTERN_MULTITHREADED); - - Patterns_PushPattern(Patterns, Pattern_Blue, PATTERN_MULTITHREADED); -} - -internal void -AppendPrintDate(gs_string* WriteStr, system_time Time) -{ - AppendPrintF(WriteStr, "%d-%d-%d : %d:%d:%d\n\n", - Time.Year, Time.Month, Time.Day, - Time.Hour, Time.Minute, Time.Second); -} - -internal void -BlumenLumen_AppendBootupLog(app_state* State, blumen_lumen_state* BLState, context Context) -{ - gs_thread_context Ctx = Context.ThreadContext; - gs_const_string BootupLogPath = ConstString("lumenarium_boot_log.log"); - - gs_file BootLog = ReadEntireFile(Ctx.FileHandler, BootupLogPath); - gs_string WriteStr = {}; - - // we don't want the log file getting huge - // if it gets above some threshold, instead of appending, - // copy what there is to an _old file, and start this one over - // - // The thinking is that without the copy operation, when we reached - // our threshold, we'd overwrite the whole log. If something went - // wrong at that point, we'd have nothing to go on. This way, there is - // always some historical data present on the system - // - if (BootLog.Size < MB(4)) - { - WriteStr = PushString(State->Transient, BootLog.Size + 1024); - } - else - { - if (!WriteEntireFile(Ctx.FileHandler, ConstString("lumenarium_boot_log_old.log"), - BootLog.Data)) - { - InvalidCodePath; - } - WriteStr = PushString(State->Transient, 1024); - } - - - // Copy old entries in - if (BootLog.Size > 0) - { - PrintF(&WriteStr, "%.*s", BootLog.Size, BootLog.Memory); - } - - // New Entry - AppendPrintF(&WriteStr, "Lumenarium Restarted\n"); - AppendPrintF(&WriteStr, "* Time: "); - AppendPrintDate(&WriteStr, Context.SystemTime_Current); - - gs_data Data = StringToData(WriteStr); - WriteEntireFile(Ctx.FileHandler, BootupLogPath, Data); -} - -internal void -BlumenLumen_UpdateLog(app_state* State, blumen_lumen_state* BLState, context Context) -{ - if (!BLState->ShouldUpdateLog) return; - - gs_string FileStr = PushString(State->Transient, 1024); - AppendPrintF(&FileStr, "Lumenarium Status\n"); - - AppendPrintF(&FileStr, "Last Updated At:"); - AppendPrintDate(&FileStr, Context.SystemTime_Current); - AppendPrintF(&FileStr, "\n\n"); - - animation* CurrAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem); - AppendPrintF(&FileStr, "Curr Animation: %S\n", CurrAnim->Name); - - bool IsPlaying = State->AnimationSystem.TimelineShouldAdvance; - AppendPrintF(&FileStr, "\tIs Playing: %s\n", - IsPlaying ? "True" : "False"); - - char* Connected = BLState->MicListenJobData.IsConnected ? "Connected" : "Disconnected"; - AppendPrintF(&FileStr, "Connected to Python: %s\n", Connected); - - u8 MP0 = BLState->LastKnownMotorState.FlowerPositions[0]; - u8 MP1 = BLState->LastKnownMotorState.FlowerPositions[1]; - u8 MP2 = BLState->LastKnownMotorState.FlowerPositions[2]; - AppendPrintF(&FileStr, "Last Known Motor State: %d %d %d\n", MP0, MP1, MP2); - - time_range MotorRange = {}; - if (SystemTimeIsInTimeRangeList(Context.SystemTime_Current, - MotorOpenTimes, - MotorOpenTimesCount, - &MotorRange)) - { - AppendPrintF(&FileStr, "\tIn Motor-Open Time Range: ( %d:%d - %d:%d)\n", - MotorRange.StartHour, MotorRange.StartMinute, - MotorRange.EndHour, MotorRange.EndMinute); - } - else - { - AppendPrintF(&FileStr, "\tIn Motor-Open Time Range: None\n"); - } - - char* PatternMode = 0; - switch (BLState->PatternMode) - { - case BlumenPattern_Standard: { PatternMode = "Standard"; } break; - case BlumenPattern_VoiceCommand: { PatternMode = "Voice Command"; } break; - case BlumenPattern_NoControl: { PatternMode = "No Control: Someone's doing the Awaken sequence!"; } break; - } - AppendPrintF(&FileStr, "Pattern Mode: %s\n", PatternMode); - - phrase_hue LastHuePhrase = BLState->LastHuePhrase; - AppendPrintF(&FileStr, "Last Mic Phrase: %S\n", LastHuePhrase.Phrase); - - AppendPrintF(&FileStr, "Pattern Speed: %f\n", BLState->PatternSpeed); - - AppendPrintF(&FileStr, "Pattern Brightness: %f\n", BLState->BrightnessPercent); - - time_range RangeIn = {}; - if (SystemTimeIsInTimeRangeList(Context.SystemTime_Current, - LedOnTimes, - LedOnTimesCount, - &RangeIn)) - { - AppendPrintF(&FileStr, "\tIn Leds-On Time Range: ( %d:%d - %d:%d)\n", - RangeIn.StartHour, RangeIn.StartMinute, - RangeIn.EndHour, RangeIn.EndMinute); - } - else - { - AppendPrintF(&FileStr, "\tIn Leds-On Time Range: None\n"); - } - - AppendPrintF(&FileStr, "\tTemp Dimming: %s\n", - Blumen_TempShouldDimLeds(BLState) ? "On" : "Off"); - - AppendPrintF(&FileStr, "Last Temp Received: %d\n", BLState->LastTemperatureReceived); - - gs_data LogMem = StringToData(FileStr); - if (!WriteEntireFile(Context.ThreadContext.FileHandler, ConstString("lumenarium_status.log"), LogMem)) - { - InvalidCodePath; - } -} - -internal gs_data -BlumenLumen_CustomInit(app_state* State, context Context) -{ - // This is memory for any custom data that we want to use - // as a part of a particular sculpture. - // By returning it from here, it will be sent as an argument to - // the sculpture's CustomUpdate function; - gs_data Result = {}; - - Result = PushSize(&State->Permanent, sizeof(blumen_lumen_state)); - - blumen_lumen_state* BLState = (blumen_lumen_state*)Result.Memory; - BLState->Running = true; - BLState->BrightnessPercent = 1; - MessageQueue_Init(&BLState->IncomingMsgQueue, &State->Permanent); - MessageQueue_Init(&BLState->OutgoingMsgQueue, &State->Permanent); - - BLState->MicListenJobData.Running = &BLState->Running; - BLState->MicListenJobData.SocketManager = Context.SocketManager; - BLState->MicListenJobData.IncomingMsgQueue = &BLState->IncomingMsgQueue; - BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue; - - BLState->PatternSpeed = GlobalAnimSpeed; - -#if 1 - BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData, Context.ThreadContext); -#endif - - assembly* Flower0 = LoadAssembly(Flower0AssemblyPath, State, Context); - assembly* Flower1 = LoadAssembly(Flower1AssemblyPath, State, Context); - assembly* Flower2 = LoadAssembly(Flower2AssemblyPath, State, Context); - - for (u32 i = 0; i < BL_FLOWER_COUNT; i++) - { - assembly Assembly = State->Assemblies.Values[i]; - BLState->StemStrips[Assembly.AssemblyIndex] = AssemblyStripsGetWithTagValue(Assembly, ConstString("section"), ConstString("stem"), &State->Permanent); - } - - BLState->AssemblyNameToClearCoreMapCount = 3; - BLState->AssemblyNameToClearCore_Names = PushArray(&State->Permanent, - u64, - BLState->AssemblyNameToClearCoreMapCount); - BLState->AssemblyNameToClearCore_Names[0] = HashDJB2ToU32(StringExpand(Flower2->Name)); - BLState->AssemblyNameToClearCore_Names[1] = HashDJB2ToU32(StringExpand(Flower1->Name)); - BLState->AssemblyNameToClearCore_Names[2] = HashDJB2ToU32(StringExpand(Flower0->Name)); - - gs_file_handler FileHandler = Context.ThreadContext.FileHandler; - gs_file ColorPhraseCSVFile = ReadEntireFile(FileHandler, PhraseMapCSVPath); - if (ColorPhraseCSVFile.Memory != 0) - { - gs_const_string ColorPhraseMapStr = DataToString(ColorPhraseCSVFile.Data); - gscsv_sheet ColorPhraseSheet = CSV_Parse(ColorPhraseMapStr, - { PhraseMapCSVSeparator }, - State->Transient); - - BLState->PhraseHueMap = PhraseHueMap_GenFromCSV(ColorPhraseSheet, - &State->Permanent); - } - -#if 0 - animation_handle DemoPatternsAnim = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, - State->Patterns, - Context, - ConstString("data/demo_patterns.foldanim")); - State->AnimationSystem.ActiveFadeGroup.From = DemoPatternsAnim; -#else - - BLState->ModeAnimations[BlumenPattern_Standard] = LoadAllAnimationsInDir(AmbientPatternFolder, BLState, State, Context); - BLState->ModeAnimations[BlumenPattern_VoiceCommand] = LoadAllAnimationsInDir(VoicePatternFolder, BLState, State, Context); - AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, State->Patterns, Context, ConstString("data/blumen_animations/anim_demo.foldanim")); - - BlumenLumen_SetPatternMode(BlumenPattern_Standard, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState); - - BLState->AwakenHandle = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, - State->Patterns, - Context, - ConstString("data/blumen_animations/awaken.foldanim")); - BLState->OffAnimHandle = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, - State->Patterns, - Context, - ConstString("data/blumen_animations/off_anim.foldanim")); - -#endif - State->AnimationSystem.TimelineShouldAdvance = true; - - BLState->StandardPatternHues.Granularity = 1; - BLState->StandardPatternHues.Speed = 1; - BLState->StandardPatternHues.AddIn = AddIn_Rotary; - BLState->StandardPatternHues.Pattern = HuePattern_Wavy; - - BLState->DebugHue.Hue0.HSV = v4{0, 1, 1, 1}; - BLState->DebugHue.Hue1.HSV = v4{0, 1, 1, 1}; - BLState->DebugHue.Hue2.HSV = v4{0, 1, 1, 1}; - - BlumenLumen_AppendBootupLog(State, BLState, Context); - return Result; -} - -internal void -BlumenLumen_UpdateMotorState(blumen_lumen_state* BLState, motor_status_packet Motor, context Context) -{ - DEBUG_ReceivedMotorPositions(BLState, Motor, Context.ThreadContext); - - motor_packet LastPos = BLState->LastKnownMotorState; - motor_packet CurrPos = Motor.Pos; - for (u32 i = 0; i < BL_FLOWER_COUNT; i++) - { - if (LastPos.FlowerPositions[i] != CurrPos.FlowerPositions[i]) - { - BLState->LastTimeMotorStateChanged[i] = Context.SystemTime_Current.NanosSinceEpoch; - } - } - - BLState->LastKnownMotorState = Motor.Pos; - BLState->ShouldUpdateLog = true; -} - -internal void -BlumenLumen_ApplyNextHotHue(blumen_lumen_state* BLState, context Context, gs_string* DebugStr, app_state* State) -{ - // if we are in standard color mode, shift all flowers to the new color - // otherwise, only shift the next flower in the sequence to the new color - phrase_hue NewHue = BLState->NextHotHue; - Log_Message(GlobalLogBuffer, "Switching To: %S\n", NewHue.Phrase); - - - if (BLState->PatternMode == BlumenPattern_Standard || - NewHue.OverrideAll) - { - BlumenLumen_SetNextHue(BLState, 0, NewHue); - BlumenLumen_SetNextHue(BLState, 1, NewHue); - BlumenLumen_SetNextHue(BLState, 2, NewHue); - } - else - { - u32 AssemblyIdx = BLState->LastAssemblyColorSet; - BlumenLumen_SetNextHue(BLState, AssemblyIdx, NewHue); - BLState->LastAssemblyColorSet = (BLState->LastAssemblyColorSet + 1) % 3; - } - - BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState); - BLState->TimeLastSetToVoiceMode = Context.SystemTime_Current; - BLState->LastHuePhrase = NewHue; - BLState->ShouldUpdateLog = true; - BLState->InPhraseReceptionMode = false; -} - -internal void -BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) -{ - DEBUG_TRACK_FUNCTION; - - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; - BLState->ShouldUpdateLog = false; - - gs_string DebugStr = PushString(State->Transient, 256); - - while (MessageQueue_CanRead(BLState->IncomingMsgQueue)) - { - gs_data PacketData = MessageQueue_Read(&BLState->IncomingMsgQueue); - if (PacketData.Memory == 0) continue; - - blumen_packet Packet = *(blumen_packet*)PacketData.Memory; - switch (Packet.Type) { - case PacketType_PatternCommand: - { - microphone_packet Mic = Packet.MicPacket; - u64 NameHash = HashDJB2ToU32(Mic.AnimationFileName); - u32 NameLen = CStringLength(Mic.AnimationFileName); - - phrase_hue NewHue = PhraseHueMap_Find(BLState->PhraseHueMap, NameHash); - if (NewHue.Phrase.Length > 0) - { - bool IsLonger = (BLState->NextHotHue.Phrase.Length < NewHue.Phrase.Length); - bool IsntInPhraseReceptionMode = !BLState->InPhraseReceptionMode; - if (IsLonger || IsntInPhraseReceptionMode) - { - Log_Message(GlobalLogBuffer, "Queueing: %S\n", NewHue.Phrase); - - BLState->NextHotHue = NewHue; - if (SecondsElapsed(BLState->TimePhraseReceptionBegan, - Context->SystemTime_Current) > PhrasePriorityMessageGroupingTime) - { - BLState->TimePhraseReceptionBegan = Context->SystemTime_Current; - BLState->InPhraseReceptionMode = true; - } - BLState->TimeLastPhraseReceived = Context->SystemTime_Current; - } - } - }break; - - case PacketType_MotorState: - { - motor_status_packet Motor = Packet.MotorStatusPacket; - - // NOTE(pjs): Python sends multi-byte integers in little endian - // order. Have to unpack - u8* T = (u8*)&Motor.Temperature; - Motor.Temperature = (T[0] << 8 | - T[1] << 0); - - BlumenLumen_UpdateMotorState(BLState, Motor, *Context); - }break; - - case PacketType_Temperature: - { - temp_packet Temp = Packet.TempPacket; - BLState->LastTemperatureReceived = Temp.Temperature; - DEBUG_ReceivedTemperature(Temp, Context->ThreadContext); - BLState->ShouldUpdateLog = true; - }break; - - InvalidDefaultCase; - } - } - - - - if (BLState->InPhraseReceptionMode) - { - r32 SecondsSincePhraseBegan = SecondsElapsed(BLState->TimePhraseReceptionBegan, Context->SystemTime_Current); - if (SecondsSincePhraseBegan > PhrasePriorityMessageGroupingTime) - { - BlumenLumen_ApplyNextHotHue(BLState, *Context, &DebugStr, State); - } - } - - BlumenLumen_AdvanceHueFade(BLState, *Context); - - // Update next frames Hues - if (!BLState->DebugOverrideHue) - { - r32 AnimTime = AnimationSystem_GetCurrentTime(State->AnimationSystem); - AnimTime = (r32)Context->TotalTime; - r32 BaseTime = AnimTime * BLState->PatternSpeed; - - r32 ColorSpeed = 1; //.001; - r32 ColorOscSpeed = .05 * ColorSpeed; - r32 ColorRelOscSpeed = 1 * ColorSpeed;; - r32 ColorOscillation = (SinR32(BaseTime * ColorOscSpeed) + 1) / 2; - r32 ColorRelationship = 30 + (((1 + SinR32(BaseTime * ColorRelOscSpeed)) / 2) * 300); - - r32 H0 = ModR32(ColorOscillation * 360, 360); - r32 H1 = ModR32(BaseTime + ColorRelationship, 360); - // TODO(PS): use our new HSV lerp - r32 H2 = LerpR32(.3f, H0, H1); - - BLState->StandardPatternHues.Hue0.HSV = v4{ H0, 1, 1, 1 }; - BLState->StandardPatternHues.Hue1.HSV = v4{ H1, 1, 1, 1 }; - BLState->StandardPatternHues.Hue2.HSV = v4{ H2, 1, 1, 1 }; - - // Transition back to standard mode after some time - if (BLState->PatternMode == BlumenPattern_VoiceCommand) - { - u64 LastChangeClock = BLState->TimeLastSetToVoiceMode.NanosSinceEpoch; - u64 NowClocks = Context->SystemTime_Current.NanosSinceEpoch; - s64 NanosSinceChange = NowClocks - LastChangeClock; - r64 SecondsSinceChange = (r64)NanosSinceChange * NanosToSeconds; - - if (SecondsSinceChange > VoiceCommandSustainDuration) - { - BlumenLumen_SetPatternMode(BlumenPattern_Standard, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState); - BLState->ShouldUpdateLog = true; - } - } - - } - else - { - BLState->StandardPatternHues = BLState->DebugHue; - AnimationSystem_FadeToPlaylist(&State->AnimationSystem, BLState->ModeAnimations[BlumenPattern_VoiceCommand]); - - } - - // Open / Close the Motor - if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue) && - !BLState->IgnoreTimeOfDay_MotorState) - { - bool SendMotorCommand = false; - - u64 NanosSinceLastSend = Context->SystemTime_Current.NanosSinceEpoch - BLState->LastSendTime.NanosSinceEpoch; - r32 SecondsSinceLastSend = (r64)NanosSinceLastSend * NanosToSeconds; - bool ShouldSendCurrentState = SecondsSinceLastSend >= MotorResendStatePeriod; - - bl_motor_state_value NewMotorState = MotorState_Closed; - bool SendOpen = false; - for (u32 i = 0; i < MotorOpenTimesCount; i++) - { - time_range Range = MotorOpenTimes[i]; - bool CurrTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Current, Range); - if (CurrTimeInRange) { - NewMotorState = MotorState_Open; - } - } - - if (NewMotorState != BLState->LastSendState) - { - ShouldSendCurrentState = true; - } - - if (ShouldSendCurrentState) - { - BLState->LastSendTime = Context->SystemTime_Current; - BLState->LastSendState = NewMotorState; - - blumen_packet Packet = {}; - Packet.Type = PacketType_MotorState; - Packet.MotorPacket.FlowerPositions[0] = NewMotorState; - Packet.MotorPacket.FlowerPositions[1] = NewMotorState; - Packet.MotorPacket.FlowerPositions[2] = NewMotorState; - gs_data Msg = StructToData(&Packet, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); - - DEBUG_SentMotorCommand(Packet.MotorPacket, Context->ThreadContext); - } - } - - // When a motor state changes to being open, wait to turn Upper Leds on - // in order to hide the fact that they are turning off - motor_packet CurrMotorPos = BLState->LastKnownMotorState; - u64 NowNanos = Context->SystemTime_Current.NanosSinceEpoch; - for (u32 i = 0; i < BL_FLOWER_COUNT; i++) - { - // have to map from "assembly load order" to - // the order that the clear core is referencing the - // motors by - assembly Assembly = State->Assemblies.Values[i]; - u64 AssemblyCCIndex = GetCCIndex(Assembly, BLState); - u8 MotorPos = CurrMotorPos.FlowerPositions[AssemblyCCIndex]; - - if ((MotorPos == MotorState_Open || MotorPos == MotorState_MostlyOpen) && - !BLState->ShouldDimUpperLeds[i]) - { - u64 ChangedNanos = BLState->LastTimeMotorStateChanged[i]; - u64 NanosSinceChanged = NowNanos - ChangedNanos; - r64 SecondsSinceChanged = (r64)NanosSinceChanged * NanosToSeconds; - if (SecondsSinceChanged > TurnUpperLedsOffAfterMotorCloseCommandDelay) - { - BLState->ShouldDimUpperLeds[i] = true; - } - else - { - BLState->ShouldDimUpperLeds[i] = false; - } - } - else if (MotorPos == MotorState_Closed || - MotorPos == MotorState_HalfOpen) - { - BLState->ShouldDimUpperLeds[i] = false; - - bool SendMotorCommand = false; - - u64 NanosSinceLastSend = Context->SystemTime_Current.NanosSinceEpoch - BLState->LastSendTime.NanosSinceEpoch; - r32 SecondsSinceLastSend = (r64)NanosSinceLastSend * NanosToSeconds; - bool ShouldSendCurrentState = SecondsSinceLastSend >= MotorResendStatePeriod; - - bl_motor_state_value NewMotorState = MotorState_Closed; - bool SendOpen = false; - for (u32 j = 0; j < MotorOpenTimesCount; j++) - { - time_range Range = MotorOpenTimes[j]; - bool CurrTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Current, Range); - if (CurrTimeInRange) { - NewMotorState = MotorState_Open; - } - } - - - if (NewMotorState != BLState->LastSendState) - { - ShouldSendCurrentState = true; - } - - if (ShouldSendCurrentState) - { - BLState->LastSendTime = Context->SystemTime_Current; - BLState->LastSendState = NewMotorState; - - blumen_packet Packet = {}; - Packet.Type = PacketType_MotorState; - Packet.MotorPacket.FlowerPositions[0] = NewMotorState; - Packet.MotorPacket.FlowerPositions[1] = NewMotorState; - Packet.MotorPacket.FlowerPositions[2] = NewMotorState; - gs_data Msg = StructToData(&Packet, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); - - DEBUG_SentMotorCommand(Packet.MotorPacket, Context->ThreadContext); - } - } - } - - // NOTE(PS): If the flowers are mostly open or full open - // we mask off the top leds to prevent them from overheating - // while telescoped inside the flower - for (u32 a = 0; a < BL_FLOWER_COUNT; a++) - { - assembly Assembly = State->Assemblies.Values[a]; - if (!BLState->ShouldDimUpperLeds[a]) continue; - - led_buffer Buffer = State->LedSystem.Buffers[Assembly.LedBufferIndex]; - led_strip_list TopStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("section"), ConstString("inner_bloom"), State->Transient); - for (u32 s = 0; s < TopStrips.Count; s++) - { - u32 SIndex = TopStrips.StripIndices[s]; - v2_strip Strip = Assembly.Strips[SIndex]; - for (u32 l = 0; l < Strip.LedCount; l++) - { - u32 LIndex = Strip.LedLUT[l]; - Buffer.Colors[LIndex] = {0}; - } - } - } - - if (!BLState->IgnoreTimeOfDay_LedDimming) - { - bool TimelineShouldAdvance = false; - r32 OverrideBrightness = 0.0f; - - time_range RangeIn = {}; - if (SystemTimeIsInTimeRangeList(Context->SystemTime_Current, - LedOnTimes, - LedOnTimesCount, - &RangeIn) || - DEBUGIgnoreLedOnTimeRange) - { - - if (Blumen_TempShouldDimLeds(BLState)) - { - OverrideBrightness = HighTemperatureBrightnessPercent; - } - else - { - OverrideBrightness = FullBrightnessPercent; - } - TimelineShouldAdvance = true; - } - - State->AnimationSystem.TimelineShouldAdvance = TimelineShouldAdvance; - BLState->BrightnessPercent = OverrideBrightness; - } - - // Dim the leds based on temp data - b8 ShouldDim = (State->AnimationSystem.UpdatesThisFrame > 0); - if (BLState->BrightnessPercent == 0) ShouldDim = true; - if (BLState->DEBUG_IgnoreWeatherDimmingLeds) ShouldDim = false; - if (ShouldDim) - { - led_buffer B0 = State->LedSystem.Buffers[0]; - pixel P0 = B0.Colors[0]; - - for (u32 i = 0; i < State->LedSystem.BuffersCount; i++) - { - led_buffer Buffer = State->LedSystem.Buffers[i]; - for (u32 j = 0; j < Buffer.LedCount; j++) - { - pixel* Color = Buffer.Colors + j; - Color->R = Color->R * BLState->BrightnessPercent; - Color->G = Color->G * BLState->BrightnessPercent; - Color->B = Color->B * BLState->BrightnessPercent; - } - } - - led_buffer B1 = State->LedSystem.Buffers[0]; - pixel P1 = B1.Colors[0]; - } - - // Send Status Packet - { - system_time LastSendTime = BLState->LastStatusUpdateTime; - r64 NanosSinceLastSend = ((r64)Context->SystemTime_Current.NanosSinceEpoch - (r64)LastSendTime.NanosSinceEpoch); - r64 SecondsSinceLastSend = NanosSinceLastSend * NanosToSeconds; - if (SecondsSinceLastSend >= STATUS_PACKET_FREQ_SECONDS) - { - BLState->LastStatusUpdateTime = Context->SystemTime_Current; - Log_Message(GlobalLogBuffer, "Attempting to Send Lumenarium Status\n"); - - blumen_packet Packet = {}; - Packet.Type = PacketType_LumenariumStatus; - Packet.StatusPacket.NextMotorEventType = 0; - Packet.StatusPacket.NextEventTime = 0; - - animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem); - if (ActiveAnim) - { - CopyMemoryTo(ActiveAnim->Name.Str, Packet.StatusPacket.AnimFileName, - Min(ActiveAnim->Name.Length, 32)); - Packet.StatusPacket.AnimFileName[ActiveAnim->Name.Length] = 0; - } - - gs_data Msg = StructToData(&Packet, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); - - // there's no new information here, but by updating the log here, - // we're updating it at some infrequent but regular period that isnt - // every single frame - BLState->ShouldUpdateLog = true; - } - } - - BlumenLumen_UpdateLog(State, BLState, *Context); -} - -US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; - ui_interface* I = &State->Interface; - - ui_BeginRow(I, BlumenDebug_Count); - for (u32 i = 0; i < BlumenDebug_Count; i++) - { - if (ui_Button(I, MakeString(BlDebugUiModeStrings[i]))) - { - BLState->DebugMode = (bl_debug_ui_mode)i; - } - } - ui_EndRow(I); - - switch (BLState->DebugMode) - { - case BlumenDebug_Motors: - { - motor_packet PendingPacket = BLState->DEBUG_PendingMotorPacket; - - BLState->IgnoreTimeOfDay_MotorState = ui_ToggleText(I, MakeString("Motors Ignore Time Limit"), BLState->IgnoreTimeOfDay_MotorState); - - for (u32 MotorIndex = 0; MotorIndex < BL_FLOWER_COUNT; MotorIndex++) - { - gs_string Label = PushStringF(State->Transient, 32, "Motor %d", MotorIndex); - ui_BeginRow(I, 5); - { - ui_Label(I, Label); - - bool IsClosed = PendingPacket.FlowerPositions[MotorIndex] == MotorState_Closed; - if (ui_ToggleText(I, MakeString("Closed (1)"), IsClosed)) - { - PendingPacket.FlowerPositions[MotorIndex] = MotorState_Closed; - } - bool IsHOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_HalfOpen; - if (ui_ToggleText(I, MakeString("Half Open (3)"), IsHOpen)) - { - PendingPacket.FlowerPositions[MotorIndex] = MotorState_HalfOpen; - } - bool IsMOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_MostlyOpen; - if (ui_ToggleText(I, MakeString("Mostly Open (4)"), IsMOpen)) - { - PendingPacket.FlowerPositions[MotorIndex] = MotorState_MostlyOpen; - } - bool IsOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_Open; - if (ui_ToggleText(I, MakeString("Open (2)"), IsOpen)) - { - PendingPacket.FlowerPositions[MotorIndex] = MotorState_Open; - } - } - ui_EndRow(I); - } - BLState->DEBUG_PendingMotorPacket = PendingPacket; - - if (ui_Button(I, MakeString("Send Motor Packet"))) - { - blumen_packet Packet = {}; - Packet.Type = PacketType_MotorState; - Packet.MotorPacket = BLState->DEBUG_PendingMotorPacket; - gs_data Msg = StructToData(&Packet, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); - DEBUG_SentMotorCommand(Packet.MotorPacket, Context.ThreadContext); - - } - - motor_packet MotorPos = BLState->LastKnownMotorState; - ui_Label(I, MakeString("Current Motor Positions")); - { - for (u32 i = 0; i < BL_FLOWER_COUNT; i++) - { - ui_BeginRow(I, 2); - gs_string MotorStr = PushStringF(State->Transient, 32, - "Motor %d", - i); - ui_Label(I, MotorStr); - - gs_string StateStr = {}; - switch (MotorPos.FlowerPositions[i]) - { - case MotorState_Closed: { - StateStr = MakeString("Closed"); - } break; - case MotorState_HalfOpen: { - StateStr = MakeString("Half Open"); - } break; - case MotorState_MostlyOpen: { - StateStr = MakeString("Mostly Open"); - } break; - case MotorState_Open: { - StateStr = MakeString("Open"); - } break; - - default: - { - StateStr = MakeString("Invalid Value"); - } break; - } - - ui_Label(I, StateStr); - ui_EndRow(I); - } - } - - ui_Label(I, MakeString("Set Internal Motor State:")); - if (ui_Button(I, MakeString("Closed"))) - { - motor_status_packet Motor = {}; - Motor.Pos.FlowerPositions[0] = MotorState_Closed; - Motor.Pos.FlowerPositions[1] = MotorState_Closed; - Motor.Pos.FlowerPositions[2] = MotorState_Closed; - Motor.Temperature = 16; - - BlumenLumen_UpdateMotorState(BLState, Motor, Context); - } - if (ui_Button(I, MakeString("Open"))) - { - motor_status_packet Motor = {}; - Motor.Pos.FlowerPositions[0] = MotorState_Open; - Motor.Pos.FlowerPositions[1] = MotorState_Open; - Motor.Pos.FlowerPositions[2] = MotorState_Open; - Motor.Temperature = 16; - - BlumenLumen_UpdateMotorState(BLState, Motor, Context); - } - } break; - - case BlumenDebug_Leds: - { - BLState->DEBUG_IgnoreWeatherDimmingLeds = ui_LabeledToggle(I, MakeString("Ignore Weather Dimming Leds"), BLState->DEBUG_IgnoreWeatherDimmingLeds); - - BLState->IgnoreTimeOfDay_LedDimming = ui_ToggleText(I, MakeString("Leds Ignore Time Limit"), BLState->IgnoreTimeOfDay_LedDimming); - - if (ui_BeginLabeledDropdown(I, MakeString("Phrase"), MakeString(BLState->PendingPhrase.Phrase))) - { - u32 ListCount = BLState->PhraseHueMap.Count; - ui_BeginList(I, MakeString("Phrase List"), 5, ListCount); - for (u32 i = 0; i < ListCount; i++) - { - gs_string Str = MakeString(BLState->PhraseHueMap.Phrases[i]); - if (ui_Button(I, Str)) - { - BLState->PendingPhrase = PhraseHueMap_Get(BLState->PhraseHueMap, i); - BLState->DebugHue = BLState->PendingPhrase; - } - } - ui_EndList(I); - } - ui_EndLabeledDropdown(I); - if (ui_Button(I, MakeString("Say Phrase"))) - { - gs_string DebugStr = PushString(State->Transient, 256); - BLState->NextHotHue = BLState->PendingPhrase; - BlumenLumen_ApplyNextHotHue(BLState, Context, &DebugStr, State); - } - - ui_Label(I, MakeString("Phrase Constructor")); - BLState->DebugOverrideHue = ui_ToggleText(I, MakeString("Override Hue"), BLState->DebugOverrideHue); - if (BLState->DebugOverrideHue) - { - phrase_hue PHue = BLState->DebugHue; - PHue.Hue0.HSV.x = (r64)ui_LabeledRangeSlider(I, MakeString("Hue0"), (r32)PHue.Hue0.HSV.x, 0, 360); - PHue.Hue1.HSV.x = (r64)ui_LabeledRangeSlider(I, MakeString("Hue1"), (r32)PHue.Hue1.HSV.x, 0, 360); - PHue.Hue2.HSV.x = (r64)ui_LabeledRangeSlider(I, MakeString("Hue2"), (r32)PHue.Hue2.HSV.x, 0, 360); - PHue.Granularity = (u32)ui_LabeledRangeSlider(I, MakeString("Granularity"), (r32)PHue.Granularity, 0, 5); - PHue.Speed = ui_LabeledRangeSlider(I, MakeString("Speed"), PHue.Speed, 0, 4); - - gs_string PatternOptions[HuePattern_Count] = {}; - PatternOptions[HuePattern_Patchy] = MakeString("patchy"); - PatternOptions[HuePattern_Wavy] = MakeString("wavy"); - - gs_string CPattern = PatternOptions[PHue.Pattern]; - if (ui_BeginLabeledDropdown(I, MakeString("Pattern"), CPattern)) - { - for (u32 i = 0; i < HuePattern_Count; i++) - { - if (ui_Button(I, PatternOptions[i])) - { - PHue.Pattern = i; - } - } - } - ui_EndLabeledDropdown(I); - - - gs_string AddInOptions[AddIn_Count] = {}; - AddInOptions[AddIn_None] = MakeString("NA"); - AddInOptions[AddIn_Waves] = MakeString("waves"); - AddInOptions[AddIn_Rotary] = MakeString("rotary"); - - gs_string CAddIn = AddInOptions[PHue.AddIn]; - if (ui_BeginLabeledDropdown(I, MakeString("Add In"), CAddIn)) - { - for (u32 i = 0; i < AddIn_Count; i++) - { - if (ui_Button(I, AddInOptions[i])) - { - PHue.AddIn = i; - } - } - } - ui_EndLabeledDropdown(I); - BLState->DebugHue = PHue; - } - - - InterfaceAssert(I->PerFrameMemory); - }break; - - case BlumenDebug_Awaken: - { - ui_Label(I, MakeString("Step 1:")); - ui_Label(I, MakeString("Leds off, flowers closed")); - if (ui_Button(I, MakeString("Prepare"))) - { - // motors closed - blumen_packet M = {}; - M.Type = PacketType_MotorState; - M.MotorPacket.FlowerPositions[0] = MotorState_Closed; - M.MotorPacket.FlowerPositions[1] = MotorState_Closed; - M.MotorPacket.FlowerPositions[2] = MotorState_Closed; - gs_data D = StructToData(&M, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, D); - - // animation - State->AnimationSystem.RepeatMode = AnimationRepeat_Single; - AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup, - BLState->OffAnimHandle, - VoiceCommandFadeDuration); - - BLState->PatternMode = BlumenPattern_NoControl; - BLState->IgnoreTimeOfDay_LedDimming = true; - BLState->IgnoreTimeOfDay_MotorState = true; - } - - ui_Label(I, MakeString("Step 2:")); - if (ui_Button(I, MakeString("Begin Light Show"))) - { - AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup, - BLState->AwakenHandle, - VoiceCommandFadeDuration); - } - - ui_Label(I, MakeString("Step 3:")); - if (ui_Button(I, MakeString("Open Flowers"))) - { - // motors closed - blumen_packet M = {}; - M.Type = PacketType_MotorState; - M.MotorPacket.FlowerPositions[0] = MotorState_Open; - M.MotorPacket.FlowerPositions[1] = MotorState_Open; - M.MotorPacket.FlowerPositions[2] = MotorState_Open; - gs_data D = StructToData(&M, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, D); - } - - ui_Label(I, MakeString("Step 4:")); - ui_Label(I, MakeString("Resets Lumenarium")); - if (ui_Button(I, MakeString("Complete"))) - { - BLState->IgnoreTimeOfDay_LedDimming = false; - BLState->IgnoreTimeOfDay_MotorState = false; - BlumenLumen_SetPatternMode(BlumenPattern_Standard, GlobalAnimTransitionSpeed, &State->AnimationSystem, - BLState); - } - }break; - - InvalidDefaultCase; - } -} - -US_CUSTOM_CLEANUP(BlumenLumen_CustomCleanup) -{ - blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; - BLState->Running = false; -} - -internal user_space_desc -BlumenLumen_UserSpaceCreate() -{ - user_space_desc Result = {}; - Result.LoadPatterns = BlumenLumen_LoadPatterns; - Result.CustomInit = BlumenLumen_CustomInit; - Result.CustomUpdate = BlumenLumen_CustomUpdate; - Result.CustomDebugUI = BlumenLumen_DebugUI; - Result.CustomCleanup = BlumenLumen_CustomCleanup; - return Result; -} - -#define BLUMEN_LUMEN_CPP -#endif // BLUMEN_LUMEN_CPP diff --git a/src/app/ss_blumen_lumen/blumen_lumen.h b/src/app/ss_blumen_lumen/blumen_lumen.h deleted file mode 100644 index fb04238..0000000 --- a/src/app/ss_blumen_lumen/blumen_lumen.h +++ /dev/null @@ -1,393 +0,0 @@ -// -// File: blumen_lumen.h -// Author: Peter Slattery -// Creation Date: 2021-01-15 -// -#ifndef BLUMEN_LUMEN_H - -#include "message_queue.h" - -enum bl_debug_ui_mode -{ - BlumenDebug_Motors, - BlumenDebug_Leds, - BlumenDebug_Awaken, - - BlumenDebug_Count, -}; - -char* BlDebugUiModeStrings[] = { - "Motors", - "Leds", - "Awaken", -}; - -enum bl_pattern_mode -{ - BlumenPattern_Standard, - BlumenPattern_VoiceCommand, - BlumenPattern_NoControl, - - BlumenPattern_Count, -}; - -enum bl_python_packet_type -{ - PacketType_Invalid = 0, - PacketType_PatternCommand = 1, - PacketType_MotorState = 2, - PacketType_Temperature = 3, - PacketType_LumenariumStatus = 4, -}; - -enum bl_motor_state_value -{ - MotorState_Invalid = 0, - - MotorState_Closed = 1, - MotorState_Open = 2, - MotorState_HalfOpen = 3, - MotorState_MostlyOpen = 4, -}; - -#pragma pack(push, 1) -typedef struct motor_packet -{ - u8 FlowerPositions[3]; -} motor_packet; - -typedef struct motor_status_packet -{ - motor_packet Pos; - u8 MotorStatus[3]; - u16 Temperature; - -} motor_status_packet; - -typedef struct microphone_packet -{ - b8 ChangeAnimation; - char AnimationFileName[32]; - b8 SetLayer; - char LayerName[32]; - r32 LayerOpacity; - b8 SetLayerParamColor; - char LayerParamColor[7]; - r32 OverrideDuration; -} microphone_packet; - -typedef struct temp_packet -{ - s8 Temperature; -} temp_packet; - -enum motor_event_type -{ - MotorEvent_Close = 0, - MotorEvent_Open = 1, -}; - -typedef struct status_packet -{ - u8 NextMotorEventType; - // u16 Padding; - u32 NextEventTime; - - char AnimFileName[32]; -} status_packet; - -typedef struct blumen_packet -{ - u8 Type; - union - { - motor_packet MotorPacket; - motor_status_packet MotorStatusPacket; - microphone_packet MicPacket; - temp_packet TempPacket; - status_packet StatusPacket; - }; -} blumen_packet; - -#pragma pack(pop) - -// TODO(pjs): Refactor this -> blumen_network_job_state -struct mic_listen_job_data -{ - bool* Running; - - platform_socket_manager* SocketManager; - blumen_network_msg_queue* IncomingMsgQueue; - - blumen_network_msg_queue* OutgoingMsgQueue; - - // Status - bool IsConnected; -}; - -typedef struct time_range -{ - s32 StartHour; - s32 StartMinute; - - s32 EndHour; - s32 EndMinute; -} time_range; - -internal bool -SystemTimeIsBeforeTime(system_time SysTime, s32 Hour, s32 Minute) -{ - bool Result = false; - if (SysTime.Hour == Hour) { - Result = SysTime.Minute < Minute; - } else { - Result = SysTime.Hour < Hour; - } - return Result; -} - -internal bool -SystemTimeIsAfterTime(system_time SysTime, s32 Hour, s32 Minute) -{ - bool Result = false; - if (SysTime.Hour == Hour) { - Result = SysTime.Minute >= Minute; - } else { - Result = SysTime.Hour > Hour; - } - return Result; -} - -internal bool -SystemTimeIsInTimeRange(system_time SysTime, time_range Range) -{ - bool Result = false; - - bool IsAfterStartTime = SystemTimeIsAfterTime(SysTime, Range.StartHour, Range.StartMinute); - bool IsBeforeEndTime = SystemTimeIsBeforeTime(SysTime, Range.EndHour, Range.EndMinute); - Result = IsAfterStartTime && IsBeforeEndTime; - - return Result; -} - -internal bool -SystemTimeIsInTimeRangeList(system_time SysTime, time_range* Ranges, u32 RangesCount, time_range* RangeOut = 0) -{ - bool Result = false; - for (u32 i = 0; i < RangesCount; i++) - { - time_range Range = Ranges[i]; - bool CurrTimeInRange = SystemTimeIsInTimeRange(SysTime, Range); - if (CurrTimeInRange) - { - Result = true; - if (RangeOut != 0) { - *RangeOut = Range; - } - break; - } - } - return Result; -} - -#include "blumen_lumen_settings.h" - -struct blumen_lumen_state -{ - bool Running; - - blumen_network_msg_queue IncomingMsgQueue; - blumen_network_msg_queue OutgoingMsgQueue; - - temp_job_req JobReq; - - led_strip_list StemStrips[BL_FLOWER_COUNT]; - - platform_thread_handle MicListenThread; - mic_listen_job_data MicListenJobData; - - motor_packet LastKnownMotorState; - u64 LastTimeMotorStateChanged[BL_FLOWER_COUNT]; - b8 ShouldDimUpperLeds[BL_FLOWER_COUNT]; - - // NOTE(pjs): Based on temperature data from weatherman - // dim the leds. - r32 BrightnessPercent; - s8 LastTemperatureReceived; - system_time LastStatusUpdateTime; - - system_time LastSendTime; - bl_motor_state_value LastSendState; - - phrase_hue StandardPatternHues; - r32 AssemblyColorsTransitionTimeLeft[BL_FLOWER_COUNT]; - phrase_hue NextAssemblyColors[BL_FLOWER_COUNT]; - phrase_hue AssemblyColors[BL_FLOWER_COUNT]; - u32 LastAssemblyColorSet; - - // The indices of this array are the index the clear core uses to - // represent a motor. - // The values of the array are the names Lumenarium uses to - // represent assemblies. - // - u32 AssemblyNameToClearCoreMapCount; - u64* AssemblyNameToClearCore_Names; - - bl_pattern_mode PatternMode; - animation_handle_array ModeAnimations[BlumenPattern_Count]; - animation_handle OffAnimHandle; - animation_handle AwakenHandle; - - phrase_hue_map PhraseHueMap; - - bool InPhraseReceptionMode; - phrase_hue NextHotHue; - system_time TimePhraseReceptionBegan; - system_time TimeLastPhraseReceived; - - system_time TimeLastSetToVoiceMode; - phrase_hue LastHuePhrase; - - r32 PatternSpeed; - - // Debug - bl_debug_ui_mode DebugMode; - - motor_packet DEBUG_PendingMotorPacket; - bool DEBUG_IgnoreWeatherDimmingLeds; - - bool ShouldUpdateLog; - bool IgnoreTimeOfDay_LedDimming; - bool IgnoreTimeOfDay_MotorState; - - phrase_hue PendingPhrase; - - bool DebugOverrideHue; - phrase_hue DebugHue; -}; - -internal bool -Blumen_TempShouldDimLeds(blumen_lumen_state* BLState) -{ - bool Result = BLState->LastTemperatureReceived > MinHighTemperature; - return Result; -} - -#include "message_queue.cpp" - -internal void -BlumenLumen_SetNextHue(blumen_lumen_state* BLState, u32 AssemblyIndex, phrase_hue Hue) -{ -#if 1 - BLState->NextAssemblyColors[AssemblyIndex] = Hue; - BLState->AssemblyColorsTransitionTimeLeft[AssemblyIndex] = PhraseHueFadeInDuration; -#else - BLState->AssemblyColors[AssemblyIndex] = Hue; -#endif -} - -internal void -BlumenLumen_AdvanceHueFade(blumen_lumen_state* BLState, context Context) -{ - for (u32 i = 0; i < BL_FLOWER_COUNT; i++) - { - r32 T = BLState->AssemblyColorsTransitionTimeLeft[i]; - if (T > 0) - { - T -= Context.DeltaTime; - if (T <= 0) - { - BLState->AssemblyColors[i] = BLState->NextAssemblyColors[i]; - } - BLState->AssemblyColorsTransitionTimeLeft[i] = T; - } - } -} - -internal phrase_hue -BlumenLumen_GetCurrentHue(blumen_lumen_state* BLState, assembly Assembly) -{ - phrase_hue Result = {}; - - switch (BLState->PatternMode) - { - case BlumenPattern_NoControl: - case BlumenPattern_Standard: - { - Result = BLState->StandardPatternHues; - }break; - - case BlumenPattern_VoiceCommand: - { - u32 i = Assembly.AssemblyIndex % 3; - r32 T = BLState->AssemblyColorsTransitionTimeLeft[i]; - if (T > 0) - { - T = Clamp(T / PhraseHueFadeInDuration, 0, 1); - Result = LerpPhraseHue(T, BLState->NextAssemblyColors[i], BLState->AssemblyColors[i]); - } else { - Result = BLState->AssemblyColors[i]; - } - }break; - } - - return Result; -} - - - - - - - - - - - - - - - - -// If you change anything, exit lumenarium if its running -// then in this application hit f1 to compile then -// go to remedybg (the debugger) and hit f5 - - -// don't touch this -u8 LastPosition = 1; - -u8 ClosedValue = 1; -u8 OpenValue = 2; - - -r64 MotorTimeElapsed = 0; -r64 OpenClosePeriod = 15.0f; - - - - - - - - - - - - - - - - - - - - - - - - - - -#define BLUMEN_LUMEN_H -#endif // BLUMEN_LUMEN_H \ No newline at end of file diff --git a/src/app/ss_blumen_lumen/blumen_lumen_settings.h b/src/app/ss_blumen_lumen/blumen_lumen_settings.h deleted file mode 100644 index 59d4767..0000000 --- a/src/app/ss_blumen_lumen/blumen_lumen_settings.h +++ /dev/null @@ -1,135 +0,0 @@ -/* date = March 27th 2021 2:50 pm */ - -#ifndef BLUMEN_LUMEN_SETTINGS_H -#define BLUMEN_LUMEN_SETTINGS_H - -// Hey you never know, might need to change this some day lololol -// The number of flowers in the sculpture. Used to size all sorts of -// arrays. Maybe don't touch this unless you really know what you're doing? -#define BL_FLOWER_COUNT 3 - -// The path to the three flower assembly files -// PS is 90% sure you don't need to touch these ever -gs_const_string Flower0AssemblyPath = ConstString("data/ss_blumen_one.fold"); -gs_const_string Flower1AssemblyPath = ConstString("data/ss_blumen_two.fold"); -gs_const_string Flower2AssemblyPath = ConstString("data/ss_blumen_three.fold"); - -// The path to the phrase map CSV. Can be an absolute path, or relative -// to the app_run_tree folder -gs_const_string PhraseMapCSVPath = ConstString("C:/projects/flowers-sound/flower_codes.tsv"); -char PhraseMapCSVSeparator = '\t'; - -// Search Strings for which folders to find ambient animation files and -// voice animation files in. -// these search patterns should always end in *.foldanim so they only -// return valid animation files -gs_const_string AmbientPatternFolder = ConstString("data/blumen_animations/ambient_patterns/*.foldanim"); -gs_const_string VoicePatternFolder = ConstString("data/blumen_animations/audio_responses/*.foldanim"); - -// The times of day when the motors should be open. -// -// @TimeFormat: documentation follows -// these are in the format { Start_Hour, Start_Minute, End_Hour, End_Minute } -// Hours are in the range 0-23 inclusive -// Minutes are in the range 0-59 inclusive -// -// NOTE: There is no need to modify the MotorOpenTimesCount variable - -// it is a compile time constant that gets calculated automatically -global time_range MotorOpenTimes[] = { - { 8, 00, 12, 00 }, // 8:00am to 12:00pm - { 12, 30, 18, 00 }, // 12:30pm to 06:00pm - { 18, 30, 22, 00 }, // 6:30pm to 10:00pm -}; -global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); // do not edit - -// Lumenarium repeatedly resends the current motor state to the python -// server. This variable determines how much time elapses between each -// message. -global r32 MotorResendStatePeriod = 90.0f; // seconds - -// The times of day when the leds should be on -// Search for @TimeFormat to find documentation -global time_range LedOnTimes[] = { - { 17, 00, 23, 59 }, - { 00, 00, 06, 30 }, -}; -global u32 LedOnTimesCount = CArrayLength(LedOnTimes); // do not edit -global b8 DEBUGIgnoreLedOnTimeRange = false; - -// How long it takes to fade from the default pattern to the -// voice activated pattern -r32 VoiceCommandFadeDuration = 0.5f; // in seconds - -// How long the voice activated pattern will remain active -// without additional voice commands, before fading back to -// default behaviour. -// ie. -// if this is set to 30 seconds, upon receiving a voice command -// lumenarium will fade to the requested pattern/color palette -// and then wait 30 seconds before fading back to the original -// pattern. If, in that 30 second window, another voice command -// is issued, lumenarium will reset the 30 second counter. -r64 VoiceCommandSustainDuration = 120.0; // in seconds - -// When we send a Motor Close command, we don't want the upper leds to -// immediately turn off. Instead, we want to wait until the flower is -// at least some of the way closed. This variable dictates how long -// we wait for. -// For example: -// 1. We send a 'motor close' command to the clear core -// 2. the clear core sends back a 'motor closed' state packet -// 3. We begin a timer -// 4. When the timer reaches the value set in this variable, -// we turn the upper leds off. -// -// NOTE: This is not a symmetric operation. When we send a 'motor open' -// command, we want to immediately turn the upper leds on so they appear -// to have been on the whole time. -r64 TurnUpperLedsOffAfterMotorCloseCommandDelay = 120.0; // in seconds - - -// NOTE: Temperature & Time of Day Based Led Brightness Settings - -// The temperature above which we dim the leds to -// HighTemperatureBrightnessPercent (below) -// -// NOTE: this is an 8bit signed integer so its range is -// -128 to 127, not that we should need either of those extremes for -// this, but just a note that you can't just put anything in here. -s8 MinHighTemperature = 26; - -// The percent brightness we set leds to during high temperatures. -// A value in the range 0:1 inclusive -// This is multiplied by each pixels R, G, & B channels before being -// sent. So if it is set to .1f, then the maximum brightness value sent -// to any channel of any pixel will be 25 (255 * .1 = 25). -r32 HighTemperatureBrightnessPercent = 0.25f; - -// The percent brightness we set leds to when no other conditions apply -// A value in the range 0:1 inclusive. -// Probably wants to be something high like 1 but we might want to -// lower it for heat reasons? -r32 FullBrightnessPercent = 0.50f; - -// A global modifier so Joerg can just slow all the patterns right down -// XD -// This is a percent - so 1 is full speed, 0.1f is 1/10 full speed and -// 2 is 2x as fast. -r32 GlobalAnimSpeed = 1.0f; - -// How long it takes to fade from one animation to the next. -// This is used both for transitioning between animation files -// as well as transitioning from Standard pattern mode to voice -// activated mode -r32 GlobalAnimTransitionSpeed = 0.0f; - -// how long it takes to fade from the old voice hue to the new one -r32 PhraseHueFadeInDuration = 0.01f; // seconds - -r64 PhrasePriorityMessageGroupingTime = 0.1f; - -// How often should Lumenarium send its status to the python server? -// -#define STATUS_PACKET_FREQ_SECONDS 10 // in seconds - -#endif //BLUMEN_LUMEN_SETTINGS_H diff --git a/src/app/ss_blumen_lumen/gfx_math.h b/src/app/ss_blumen_lumen/gfx_math.h deleted file mode 100644 index 34b667d..0000000 --- a/src/app/ss_blumen_lumen/gfx_math.h +++ /dev/null @@ -1,461 +0,0 @@ -/* date = March 31st 2021 2:19 am */ - -#ifndef GFX_MATH_H -#define GFX_MATH_H - -internal r32 -Smoothstep(r32 T) -{ - r32 Result = (T * T * (3 - (2 * T))); - return Result; -} -internal r32 -Smoothstep(r32 T, r32 A, r32 B) -{ - return LerpR32(Smoothstep(T), A, B); -} -internal v3 -Smoothstep(v3 P) -{ - v3 R = {}; - R.x = Smoothstep(P.x); - R.y = Smoothstep(P.y); - R.z = Smoothstep(P.z); - return R; -} - -internal v3 -AbsV3(v3 P) -{ - v3 Result = {}; - Result.x = Abs(P.x); - Result.y = Abs(P.y); - Result.z = Abs(P.z); - return Result; -} - -internal v2 -FloorV2(v2 P) -{ - v2 Result = {}; - Result.x = FloorR32(P.x); - Result.y = FloorR32(P.y); - return Result; -} -internal v3 -FloorV3(v3 P) -{ - v3 Result = {}; - Result.x = FloorR32(P.x); - Result.y = FloorR32(P.y); - Result.z = FloorR32(P.z); - return Result; -} - -internal v2 -FractV2(v2 P) -{ - v2 Result = {}; - Result.x = FractR32(P.x); - Result.y = FractR32(P.y); - return Result; -} -internal v3 -FractV3(v3 P) -{ - v3 Result = {}; - Result.x = FractR32(P.x); - Result.y = FractR32(P.y); - Result.z = FractR32(P.z); - return Result; -} - -internal v2 -SinV2(v2 P) -{ - v2 Result = {}; - Result.x = SinR32(P.x); - Result.y = SinR32(P.y); - return Result; -} -internal v3 -SinV3(v3 P) -{ - v3 Result = {}; - Result.x = SinR32(P.x); - Result.y = SinR32(P.y); - Result.y = SinR32(P.z); - return Result; -} - -internal r32 -Hash1(v2 P) -{ - v2 Result = FractV2( P * 0.3183099f ) * 50.f; - return FractR32(P.x * P.y * (P.x + P.y)); -} - -internal r32 -Hash1(r32 N) -{ - return FractR32(N * 17.0f * FractR32(N * 0.3183099f)); -} - -internal v2 -Hash2(r32 N) -{ - v2 P = V2MultiplyPairwise(SinV2(v2{N,N+1.0f}), v2{43758.5453123f,22578.1459123f}); - return FractV2(P); -} - -internal v2 -Hash2(v2 P) -{ - v2 K = v2{ 0.3183099f, 0.3678794f }; - v2 Kp = v2{K.y, K.x}; - v2 R = V2MultiplyPairwise(P, K) + Kp; - return FractV2( K * 16.0f * FractR32( P.x * P.y * (P.x + P.y))); -} - -internal v3 -Hash3(v2 P) -{ - v3 Q = v3{}; - Q.x = V2Dot(P, v2{127.1f, 311.7f}); - Q.y = V2Dot(P, v2{267.5f, 183.3f}); - Q.z = V2Dot(P, v2{419.2f, 371.9f}); - return FractV3(SinV3(Q) * 43758.5453f); -} - -internal r32 -HashV3ToR32(v3 P) -{ - v3 Pp = FractV3(P * 0.3183099f + v3{0.1f, 0.1f, 0.1f}); - Pp *= 17.0f; - r32 Result = FractR32(Pp.x * Pp.y * Pp.z * (Pp.x + Pp.y + Pp.z)); - return Result; -} - -internal r32 -Random(v2 N) -{ - v2 V = v2{12.9898f, 4.1414f}; - return FractR32(SinR32(V2Dot(N, V)) * 43758.5453); -} - -internal r32 -Noise2D(v2 P) -{ - v2 IP = FloorV2(P); - v2 U = FractV2(P); - U = V2MultiplyPairwise(U, U); - U = V2MultiplyPairwise(U, ((U * 2.0f) + v2{-3, -3})); - - r32 A = LerpR32(U.x, Random(IP), Random(IP + v2{1.0f, 0})); - r32 B = LerpR32(U.x, Random(IP + v2{0, 1}), Random(IP + v2{1, 1})); - r32 Res = LerpR32(U.y, A, B); - - return Res * Res; -} - -internal r32 -Noise3D(v3 P) -{ - P = AbsV3(P); - v3 PFloor = FloorV3(P); - v3 PFract = FractV3(P); - v3 F = Smoothstep(PFract); - - r32 Result = LerpR32(F.z, - LerpR32(F.y, - LerpR32(F.x, - HashV3ToR32(PFloor + v3{0, 0, 0}), - HashV3ToR32(PFloor + v3{1, 0, 0})), - LerpR32(F.x, - HashV3ToR32(PFloor + v3{0, 1, 0}), - HashV3ToR32(PFloor + v3{1, 1, 0}))), - LerpR32(F.y, - LerpR32(F.x, - HashV3ToR32(PFloor + v3{0, 0, 1}), - HashV3ToR32(PFloor + v3{1, 0, 1})), - LerpR32(F.x, - HashV3ToR32(PFloor + v3{0, 1, 1}), - HashV3ToR32(PFloor + v3{1, 1, 1})))); - - Assert(Result >= 0 && Result <= 1); - return Result; -} - -internal r32 -Noise3D_(v3 Pp) -{ - v3 P = FloorV3(Pp); - v3 W = FractV3(Pp); - - //v3 U = W * W * W * (W * (W * 6.0f - 15.0f) + 10.0f); - v3 U = V3MultiplyPairwise(W, W * 6.0f - v3{15, 15, 15}); - U = U + v3{10, 10, 10}; - U = V3MultiplyPairwise(U, W); - U = V3MultiplyPairwise(U, W); - U = V3MultiplyPairwise(U, W); - - r32 N = P.x + 317.0f * P.y + 157.0f * P.z; - - r32 A = Hash1(N + 0.0f); - r32 B = Hash1(N + 1.0f); - r32 C = Hash1(N + 317.0f); - r32 D = Hash1(N + 317.0f); - r32 E = Hash1(N + 157.0f); - r32 F = Hash1(N + 158.0f); - r32 G = Hash1(N + 474.0f); - r32 H = Hash1(N + 475.0f); - - r32 K0 = A; - r32 K1 = B - A; - r32 K2 = C - A; - r32 K3 = E - A; - r32 K4 = A - B - C + D; - r32 K5 = A - C - E + G; - r32 K6 = A - B - E + F; - r32 K7 = A + B + C - D + E - F - G + H; - - return -1.0f + 2.0f * (K0 + - K1 * U.x + - K2 * U.y + - K3 * U.z + - K4 * U.x * U.y + - K5 * U.y + U.z + - K6 * U.z * U.x + - K7 * U.x * U.y * U.z); -} - -internal r32 -Fbm2D(v2 P) -{ - r32 R = 0; - r32 Amp = 1.0; - r32 Freq = 1.0; - for (u32 i = 0; i < 3; i++) - { - R += Amp * Noise2D(P * Freq); - Amp *= 0.5f; - Freq *= 1.0f / 0.5f; - } - return R; -} - -global m44 M3 = m44{ - 0.00f, 0.80f, 0.60f, 0, - -0.80f, 0.36f, -0.48f, 0, - -0.60f, -0.48f, 0.64f, 0, - 0, 0, 0, 1 -}; - -internal r32 -Fbm3D(v3 P) -{ - v3 X = P; - r32 F = 2.0f; - r32 S = 0.5f; - r32 A = 0.0f; - r32 B = 0.5f; - for (u32 i = 0; i < 4; i++) - { - r32 N = Noise3D(X); - A += B * N; - B *= S; - v4 Xp = M3 * ToV4Point(X); - X = Xp.xyz * F; - } - - return A; -} - -internal r32 -Fbm3D(v3 P, r32 T) -{ - v3 Tt = v3{T, T, T}; - r32 SinT = SinR32(T); - v3 Tv = v3{SinT, SinT, SinT}; - v3 Pp = P; - r32 F = 0.0; - - F += 0.500000f * Noise3D(Pp + Tt); Pp = Pp * 2.02; - //F += 0.031250f * Noise3D(Pp); Pp = Pp * 2.01; - F += 0.300000f * Noise3D(Pp - Tt); Pp = Pp * 2.03; - F += 0.125000f * Noise3D(Pp); Pp = Pp * 2.01; - F += 0.062500f * Noise3D(Pp + Tt); Pp = Pp * 2.04; - //F += 0.015625f * Noise3D(Pp + Tv); - r32 D = 0.9875f; - - F = F / D; - return F; -} - -internal r32 -Voronoise(v2 P, r32 U, r32 V) -{ - r32 K = 1.0f + 63.0f + PowR32(1.0f - V, 6.0f); - - v2 I = FloorV2(P); - v2 F = FractV2(P); - - v2 A = v2{0, 0}; - for (s32 y = -2; y <= 2; y++) - { - for (s32 x = -2; x <= 2; x++) - { - v2 G = v2{(r32)x, (r32)y}; - v3 O = V3MultiplyPairwise(Hash3(I + G), v3{U, U, 1.0f}); - v2 D = G - F + O.xy; - r32 W = PowR32(1.0f - Smoothstep(V2Mag(D), 0.0f, 1.414f), K); - A += v2{O.z * W, W}; - } - } - - return A.x / A.y; -} - - -v4 RGBToHSV(v4 In) -{ - v4 Result = {}; - - r32 Min = Min(In.r, Min(In.g, In.b)); - r32 Max = Max(In.r, Max(In.g, In.b)); - - r32 V = Max; - r32 Delta = Max - Min; - r32 S = 0; - r32 H = 0; - if( Max != 0 ) - { - S = Delta / Max; - - if( In.r == Max ) - { - H = ( In.g - In.b ) / Delta; // between yellow & magenta - } - else if( In.g == Max ) - { - H = 2 + ( In.b - In.r ) / Delta; // between cyan & yellow - } - else - { - H = 4 + ( In.r - In.g ) / Delta; // between magenta & cyan - } - H *= 60; // degrees - if( H < 0 ) - H += 360; - Result = v4{H, S, V, 1}; - } - else - { - // r = g = b = 0 - // s = 0, v is undefined - S = 0; - H = -1; - Result = v4{H, S, 1, 1}; - } - - return Result; -} - -v4 HSVToRGB (v4 In) -{ - float Hue = In.x; - /* -while (Hue > 360.0f) { Hue -= 360.0f; } - while (Hue < 0.0f) { Hue += 360.0f; } - */ - Hue = ModR32(Hue, 360.0f); - if (Hue < 0) { Hue += 360.0f; } - if (Hue == MinR32) { Hue = 0; } - if (Hue == MaxR32) { Hue = 360; } - Assert(Hue >= 0 && Hue < 360); - - float Sat = In.y; - float Value = In.z; - - float hh, p, q, t, ff; - long i; - v4 Result = {}; - Result.a = In.a; - - if(Sat <= 0.0f) { // < is bogus, just shuts up warnings - Result.r = Value; - Result.g = Value; - Result.b = Value; - return Result; - } - hh = Hue; - if(hh >= 360.0f) hh = 0.0f; - hh /= 60.0f; - i = (long)hh; - ff = hh - i; - p = Value * (1.0f - Sat); - q = Value * (1.0f - (Sat * ff)); - t = Value * (1.0f - (Sat * (1.0f - ff))); - - switch(i) { - case 0: - {Result.r = Value; - Result.g = t; - Result.b = p; - }break; - - case 1: - { - Result.r = q; - Result.g = Value; - Result.b = p; - }break; - - case 2: - { - Result.r = p; - Result.g = Value; - Result.b = t; - }break; - - case 3: - { - Result.r = p; - Result.g = q; - Result.b = Value; - }break; - - case 4: - { - Result.r = t; - Result.g = p; - Result.b = Value; - }break; - - case 5: - default: - { - Result.r = Value; - Result.g = p; - Result.b = q; - }break; - } - - return Result; -} - -internal pixel -V4ToRGBPixel(v4 C) -{ - C.x = Clamp01(C.x); - C.y = Clamp01(C.y); - C.z = Clamp01(C.z); - - pixel Result = {}; - Result.R = (u8)(C.x * 255); - Result.G = (u8)(C.y * 255); - Result.B = (u8)(C.z * 255); - return Result; -} - -#endif //GFX_MATH_H diff --git a/src/app/ss_blumen_lumen/message_queue.cpp b/src/app/ss_blumen_lumen/message_queue.cpp deleted file mode 100644 index 4d4211d..0000000 --- a/src/app/ss_blumen_lumen/message_queue.cpp +++ /dev/null @@ -1,83 +0,0 @@ - -internal void -MessageQueue_Init(blumen_network_msg_queue* Queue, gs_memory_arena* Arena) -{ - gs_data MessageQueueData = PushSize(Arena, DEFAULT_QUEUE_ENTRY_SIZE * BLUMEN_MESSAGE_QUEUE_COUNT); - gs_memory_cursor C = MemoryCursorCreateFromData(MessageQueueData); - - for (u32 i = 0; i < BLUMEN_MESSAGE_QUEUE_COUNT; i++) - { - Queue->Buffers[i] = MemoryCursorPushSize(&C, DEFAULT_QUEUE_ENTRY_SIZE); - } -} - -internal bool -MessageQueue_CanWrite(blumen_network_msg_queue Queue) -{ - bool Result = ((Queue.WriteHead >= Queue.ReadHead) || - (Queue.WriteHead < Queue.ReadHead)); - return Result; -} - -internal bool -MessageQueue_Write(blumen_network_msg_queue* Queue, gs_data Msg) -{ - Assert(Msg.Size <= DEFAULT_QUEUE_ENTRY_SIZE); - - u32 Index = Queue->WriteHead; - Assert(Index >= 0 && - Index < BLUMEN_MESSAGE_QUEUE_COUNT); - - gs_data* Dest = Queue->Buffers + Index; - CopyMemoryTo(Msg.Memory, Dest->Memory, Msg.Size); - Dest->Size = Msg.Size; - - // NOTE(pjs): We increment write head at the end of writing so that - // a reader thread doesn't pull the message off before we've finished - // filling it out - Queue->WriteHead = (Queue->WriteHead + 1) % BLUMEN_MESSAGE_QUEUE_COUNT; - return true; -} - -internal bool -MessageQueue_CanRead(blumen_network_msg_queue Queue) -{ - bool Result = (Queue.ReadHead != Queue.WriteHead); - return Result; -} - -internal gs_data -MessageQueue_Peek(blumen_network_msg_queue* Queue) -{ - gs_data Result = {}; - u32 ReadIndex = Queue->ReadHead; - if (ReadIndex >= BLUMEN_MESSAGE_QUEUE_COUNT) - { - ReadIndex = 0; - } - Result = Queue->Buffers[ReadIndex]; - return Result; -} - -internal gs_data -MessageQueue_Read(blumen_network_msg_queue* Queue) -{ - gs_data Result = {}; - u32 ReadIndex = Queue->ReadHead++; - if (ReadIndex >= BLUMEN_MESSAGE_QUEUE_COUNT) - { - Queue->ReadHead = 0; - ReadIndex = 0; - } - Result = Queue->Buffers[ReadIndex]; - return Result; -} - -internal void -MessageQueue_Clear(blumen_network_msg_queue* Queue) -{ - while (MessageQueue_CanRead(*Queue)) - { - MessageQueue_Read(Queue); - } -} diff --git a/src/app/ss_blumen_lumen/message_queue.h b/src/app/ss_blumen_lumen/message_queue.h deleted file mode 100644 index a450b54..0000000 --- a/src/app/ss_blumen_lumen/message_queue.h +++ /dev/null @@ -1,17 +0,0 @@ -/* date = March 27th 2021 3:07 pm */ - -#ifndef MESSAGE_QUEUE_H -#define MESSAGE_QUEUE_H - -#define BLUMEN_MESSAGE_QUEUE_COUNT 32 -typedef struct blumen_network_msg_queue -{ - gs_data Buffers[BLUMEN_MESSAGE_QUEUE_COUNT]; - u32 WriteHead; - u32 ReadHead; -} blumen_network_msg_queue; - -// KB(1) is just bigger than any packet we send. Good for now -#define DEFAULT_QUEUE_ENTRY_SIZE KB(1) - -#endif //MESSAGE_QUEUE_H diff --git a/src/app/ss_blumen_lumen/phrase_hue_map.h b/src/app/ss_blumen_lumen/phrase_hue_map.h deleted file mode 100644 index 3b2af84..0000000 --- a/src/app/ss_blumen_lumen/phrase_hue_map.h +++ /dev/null @@ -1,283 +0,0 @@ -/* date = March 27th 2021 1:55 pm */ - -#ifndef PHRASE_HUE_MAP_H -#define PHRASE_HUE_MAP_H - -enum p_hue_flag -{ - Hue_Value = 0, - Hue_White = 1, - Hue_Black = 2, -}; - -enum p_hue_pattern -{ - HuePattern_Patchy, - HuePattern_Wavy, - - HuePattern_Count, -}; - -enum p_hue_add_in -{ - AddIn_None, - AddIn_Waves, - AddIn_Rotary, - - AddIn_Count, -}; - -typedef struct p_hue -{ - v4 HSV; -} p_hue; - -typedef struct phrase_hue_map -{ - u64 CountMax; - u64 Count; - gs_const_string* Phrases; - u64* PhraseHashes; - p_hue* Hue0; - p_hue* Hue1; - p_hue* Hue2; - u32* Gran; // granularity - r32* Speed; - u8* Pattern; - u8* AddIn; - bool* OverrideAll; -} phrase_hue_map; - -typedef struct phrase_hue -{ - gs_const_string Phrase; - u64 PhraseHash; - p_hue Hue0; - p_hue Hue1; - p_hue Hue2; - u32 Granularity; - r32 Speed; - u8 Pattern; - u8 AddIn; - bool OverrideAll; -} phrase_hue; - -internal p_hue -LerpPHue(r32 T, p_hue A, p_hue B) -{ - p_hue Result = {}; - - if (Abs(A.HSV.x - B.HSV.x) < 180.0f) - { - Result.HSV.x = LerpR64(T, A.HSV.x, B.HSV.x); - } - else if (B.HSV.x > A.HSV.x) - { - Result.HSV.x = LerpR64(T, A.HSV.x, B.HSV.x - 360.0f); - } - else - { - Result.HSV.x = LerpR64(T, A.HSV.x - 360.0f, B.HSV.x); - } - if (Result.HSV.x < 360) Result.HSV.x += 360; - if (Result.HSV.x > 360) Result.HSV.x -= 360; - Result.HSV.x = Clamp(0, Result.HSV.x, 360); - Result.HSV.y = LerpR32(T, A.HSV.y, B.HSV.y); - Result.HSV.z = LerpR32(T, A.HSV.z, B.HSV.z); - Result.HSV.w = LerpR32(T, A.HSV.w, B.HSV.w); - - return Result; -} - -internal phrase_hue -LerpPhraseHue(r32 T, phrase_hue A, phrase_hue B) -{ - phrase_hue Result = {}; - Result.Hue0 = LerpPHue(T, A.Hue0, B.Hue0); - Result.Hue1 = LerpPHue(T, A.Hue1, B.Hue1); - Result.Hue2 = LerpPHue(T, A.Hue2, B.Hue2); - Result.Granularity = (u32)LerpR32(T, (r32)A.Granularity, (r32)B.Granularity); - Result.Speed = LerpR32(T, A.Speed, B.Speed); - - if (T < .5f) { - Result.Phrase = A.Phrase; - Result.PhraseHash = A.PhraseHash; - Result.Pattern = A.Pattern; - Result.AddIn = A.AddIn; - } - else { - Result.Phrase = B.Phrase; - Result.PhraseHash = B.PhraseHash; - Result.Pattern = B.Pattern; - Result.AddIn = B.AddIn; - } - - return Result; -} - -internal p_hue -CreateHueFromString(gs_const_string Str) -{ - p_hue Result = {}; - if (Str.Str[0] == 'b') { - Result.HSV = v4{0, 0, 0, 1 }; - } else if (Str.Str[0] == 'w') { - Result.HSV = v4{0, 0, 1, 1 };; - } else { - parse_float_result Parsed = ValidateAndParseFloat(Str); - if (!Parsed.Success) - { - Log_Error(GlobalLogBuffer, "Failed to Parse CSV Float\n"); - Parsed.Value = 0.0; - } - Result.HSV = v4{ (r32)Parsed.Value, 1, 1, 1 }; - - } - return Result; -} - -internal v4 -RGBFromPhraseHue (p_hue H) -{ - v4 Result = H.HSV; - Result = HSVToRGB(Result); - return Result; -} - -internal phrase_hue_map -PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena) -{ - phrase_hue_map Result = {}; - if (Sheet.RowCount == 0) return Result; - - Result.CountMax = Sheet.RowCount - 1; // we don't include the header row - Result.Phrases = PushArray(Arena, gs_const_string, Result.CountMax); - Result.PhraseHashes = PushArray(Arena, u64, Result.CountMax); - Result.Hue0 = PushArray(Arena, p_hue, Result.CountMax); - Result.Hue1 = PushArray(Arena, p_hue, Result.CountMax); - Result.Hue2 = PushArray(Arena, p_hue, Result.CountMax); - Result.Gran = PushArray(Arena, u32, Result.CountMax); - Result.Pattern = PushArray(Arena, u8, Result.CountMax); - Result.Speed = PushArray(Arena, r32, Result.CountMax); - Result.AddIn = PushArray(Arena, u8, Result.CountMax); - Result.OverrideAll = PushArray(Arena, bool, Result.CountMax); - - // this lets us tightly pack phrase_hues even if there is a - // row in the csv that is empty or invalid - s32 DestOffset = 0; - for (u32 Row = 1; Row < Sheet.RowCount; Row++) - { - s32 Index = (Row - 1) - DestOffset; - Assert(Index >= 0 && Index < Result.CountMax); - - gs_const_string Phrase = CSVSheet_GetCell(Sheet, - 0, Row); - gs_const_string Hue0Str = CSVSheet_GetCell(Sheet, 1, Row); - gs_const_string Hue1Str = CSVSheet_GetCell(Sheet, 2, Row); - gs_const_string Hue2Str = CSVSheet_GetCell(Sheet, 3, Row); - gs_const_string Homonyms = CSVSheet_GetCell(Sheet, 4, Row); - gs_const_string Granularity = CSVSheet_GetCell(Sheet, 5, Row); - gs_const_string Speed = CSVSheet_GetCell(Sheet, 6, Row); - gs_const_string Pattern = CSVSheet_GetCell(Sheet, 7, Row); - gs_const_string AddIn = CSVSheet_GetCell(Sheet, 8, Row); - gs_const_string OverrideAll = CSVSheet_GetCell(Sheet, 9, Row); - - // essential parameters - if (Phrase.Length == 0 || - Hue0Str.Length == 0 || - Hue1Str.Length == 0 || - Hue2Str.Length == 0) - { - DestOffset++; - continue; - } - - Result.Phrases[Index] = PushStringF(Arena, Phrase.Length, "%S", Phrase).ConstString; - for (u64 i = 0; i < Result.Phrases[Index].Length; i++) - { - char C = Result.Phrases[Index].Str[i]; - if (IsAlpha(C)) - { - Result.Phrases[Index].Str[i] = ToLower(C); - } - } - - u64 PhraseHash = HashDJB2ToU32(StringExpand(Result.Phrases[Index])); - - Result.PhraseHashes[Index] = PhraseHash; - Result.Hue0[Index] = CreateHueFromString(Hue0Str); - Result.Hue1[Index] = CreateHueFromString(Hue1Str); - Result.Hue2[Index] = CreateHueFromString(Hue2Str); - - parse_float_result ParsedSpeed = ValidateAndParseFloat(Speed); - if (!ParsedSpeed.Success) - { - ParsedSpeed.Value = 1.0; - } - Result.Speed[Index] = ParsedSpeed.Value; - - if (StringsEqual(Pattern, ConstString("wavy"))) - { - Result.Pattern[Index] = HuePattern_Wavy; - } else { - Result.Pattern[Index] = HuePattern_Patchy; - } - - if (StringsEqual(AddIn, ConstString("waves"))) - { - Result.AddIn[Index] = AddIn_Waves; - } else if (StringsEqual(AddIn, ConstString("rotary"))) { - Result.AddIn[Index] = AddIn_Rotary; - } else { - Result.AddIn[Index] = AddIn_None; - } - - parse_uint_result ParsedGranularity = ValidateAndParseUInt(Granularity); - if (!ParsedGranularity.Success) - { - ParsedGranularity.Value = 1; - } - Result.Gran[Index] = ParsedGranularity.Value; - - Result.OverrideAll[Index] = StringsEqualUpToLength(OverrideAll, ConstString("yes"), 3); - } - - Result.Count = Result.CountMax + DestOffset; - - return Result; -} - -internal phrase_hue -PhraseHueMap_Get(phrase_hue_map Map, u32 Index) -{ - Assert(Index < Map.Count); - phrase_hue Result = {}; - Result.Phrase = Map.Phrases[Index]; - Result.PhraseHash = Map.PhraseHashes[Index]; - Result.Hue0 = Map.Hue0[Index]; - Result.Hue1 = Map.Hue1[Index]; - Result.Hue2 = Map.Hue2[Index]; - Result.Granularity = Map.Gran[Index]; - Result.Speed = Map.Speed[Index]; - Result.AddIn = Map.AddIn[Index]; - Result.Pattern = Map.Pattern[Index]; - Result.OverrideAll = Map.OverrideAll[Index]; - return Result; -} - -internal phrase_hue -PhraseHueMap_Find(phrase_hue_map Map, u64 PhraseHash) -{ - phrase_hue Result = {}; - for (u32 i = 0; i < Map.Count; i++) - { - if (Map.PhraseHashes[i] == PhraseHash) - { - Result = PhraseHueMap_Get(Map, i); - break; - } - } - return Result; -} - -#endif //PHRASE_HUE_MAP_H diff --git a/src/app/ss_blumen_lumen/sdf.h b/src/app/ss_blumen_lumen/sdf.h deleted file mode 100644 index 58e40e9..0000000 --- a/src/app/ss_blumen_lumen/sdf.h +++ /dev/null @@ -1,20 +0,0 @@ -/* date = March 29th 2021 10:41 pm */ - -#ifndef SDF_H -#define SDF_H - -internal r32 -SDF_Sphere(v3 Point, v3 Center, r32 Radius) -{ - r32 Result = V3Mag(Point - Center) - Radius; - return Result; -} - -internal r32 -SDF_SphereNormalized(v3 Point, v3 Center, r32 Radius) -{ - r32 Result = SDF_Sphere(Point, Center, Radius) / Radius; - return Result; -} - -#endif //SDF_H diff --git a/src_v2/core/lumenarium_core.h b/src/core/lumenarium_core.h similarity index 100% rename from src_v2/core/lumenarium_core.h rename to src/core/lumenarium_core.h diff --git a/src_v2/core/lumenarium_core_assert.h b/src/core/lumenarium_core_assert.h similarity index 100% rename from src_v2/core/lumenarium_core_assert.h rename to src/core/lumenarium_core_assert.h diff --git a/src_v2/core/lumenarium_core_file.h b/src/core/lumenarium_core_file.h similarity index 100% rename from src_v2/core/lumenarium_core_file.h rename to src/core/lumenarium_core_file.h diff --git a/src_v2/core/lumenarium_core_hash.h b/src/core/lumenarium_core_hash.h similarity index 100% rename from src_v2/core/lumenarium_core_hash.h rename to src/core/lumenarium_core_hash.h diff --git a/src_v2/core/lumenarium_core_memory.h b/src/core/lumenarium_core_memory.h similarity index 100% rename from src_v2/core/lumenarium_core_memory.h rename to src/core/lumenarium_core_memory.h diff --git a/src_v2/core/lumenarium_core_random.h b/src/core/lumenarium_core_random.h similarity index 100% rename from src_v2/core/lumenarium_core_random.h rename to src/core/lumenarium_core_random.h diff --git a/src_v2/core/lumenarium_core_socket.h b/src/core/lumenarium_core_socket.h similarity index 100% rename from src_v2/core/lumenarium_core_socket.h rename to src/core/lumenarium_core_socket.h diff --git a/src_v2/core/lumenarium_core_string.h b/src/core/lumenarium_core_string.h similarity index 100% rename from src_v2/core/lumenarium_core_string.h rename to src/core/lumenarium_core_string.h diff --git a/src_v2/core/lumenarium_core_threads.h b/src/core/lumenarium_core_threads.h similarity index 100% rename from src_v2/core/lumenarium_core_threads.h rename to src/core/lumenarium_core_threads.h diff --git a/src_v2/core/lumenarium_core_time.h b/src/core/lumenarium_core_time.h similarity index 100% rename from src_v2/core/lumenarium_core_time.h rename to src/core/lumenarium_core_time.h diff --git a/src_v2/core/lumenarium_core_types.h b/src/core/lumenarium_core_types.h similarity index 100% rename from src_v2/core/lumenarium_core_types.h rename to src/core/lumenarium_core_types.h diff --git a/src_v2/core/lumenarium_core_window.h b/src/core/lumenarium_core_window.h similarity index 100% rename from src_v2/core/lumenarium_core_window.h rename to src/core/lumenarium_core_window.h diff --git a/src_v2/editor/graphics/lumenarium_editor_graphics.h b/src/editor/graphics/lumenarium_editor_graphics.h similarity index 100% rename from src_v2/editor/graphics/lumenarium_editor_graphics.h rename to src/editor/graphics/lumenarium_editor_graphics.h diff --git a/src_v2/editor/graphics/lumenarium_editor_opengl.h b/src/editor/graphics/lumenarium_editor_opengl.h similarity index 100% rename from src_v2/editor/graphics/lumenarium_editor_opengl.h rename to src/editor/graphics/lumenarium_editor_opengl.h diff --git a/src_v2/editor/lumenarium_editor.c b/src/editor/lumenarium_editor.c similarity index 100% rename from src_v2/editor/lumenarium_editor.c rename to src/editor/lumenarium_editor.c diff --git a/src_v2/editor/lumenarium_editor.h b/src/editor/lumenarium_editor.h similarity index 100% rename from src_v2/editor/lumenarium_editor.h rename to src/editor/lumenarium_editor.h diff --git a/src_v2/editor/lumenarium_editor_renderer.c b/src/editor/lumenarium_editor_renderer.c similarity index 100% rename from src_v2/editor/lumenarium_editor_renderer.c rename to src/editor/lumenarium_editor_renderer.c diff --git a/src_v2/editor/lumenarium_editor_renderer.h b/src/editor/lumenarium_editor_renderer.h similarity index 100% rename from src_v2/editor/lumenarium_editor_renderer.h rename to src/editor/lumenarium_editor_renderer.h diff --git a/src_v2/editor/lumenarium_editor_sculpture_visualizer.c b/src/editor/lumenarium_editor_sculpture_visualizer.c similarity index 100% rename from src_v2/editor/lumenarium_editor_sculpture_visualizer.c rename to src/editor/lumenarium_editor_sculpture_visualizer.c diff --git a/src_v2/editor/lumenarium_editor_sculpture_visualizer_shaders.h b/src/editor/lumenarium_editor_sculpture_visualizer_shaders.h similarity index 100% rename from src_v2/editor/lumenarium_editor_sculpture_visualizer_shaders.h rename to src/editor/lumenarium_editor_sculpture_visualizer_shaders.h diff --git a/src_v2/editor/lumenarium_editor_ui.c b/src/editor/lumenarium_editor_ui.c similarity index 100% rename from src_v2/editor/lumenarium_editor_ui.c rename to src/editor/lumenarium_editor_ui.c diff --git a/src_v2/editor/lumenarium_editor_ui.h b/src/editor/lumenarium_editor_ui.h similarity index 100% rename from src_v2/editor/lumenarium_editor_ui.h rename to src/editor/lumenarium_editor_ui.h diff --git a/src_v2/editor/lumenarium_editor_ui_shaders.h b/src/editor/lumenarium_editor_ui_shaders.h similarity index 100% rename from src_v2/editor/lumenarium_editor_ui_shaders.h rename to src/editor/lumenarium_editor_ui_shaders.h diff --git a/src_v2/engine/lumenarium_engine.c b/src/engine/lumenarium_engine.c similarity index 100% rename from src_v2/engine/lumenarium_engine.c rename to src/engine/lumenarium_engine.c diff --git a/src_v2/engine/lumenarium_engine_assembly.c b/src/engine/lumenarium_engine_assembly.c similarity index 100% rename from src_v2/engine/lumenarium_engine_assembly.c rename to src/engine/lumenarium_engine_assembly.c diff --git a/src_v2/engine/lumenarium_engine_assembly.h b/src/engine/lumenarium_engine_assembly.h similarity index 100% rename from src_v2/engine/lumenarium_engine_assembly.h rename to src/engine/lumenarium_engine_assembly.h diff --git a/src_v2/engine/lumenarium_engine_output.c b/src/engine/lumenarium_engine_output.c similarity index 100% rename from src_v2/engine/lumenarium_engine_output.c rename to src/engine/lumenarium_engine_output.c diff --git a/src_v2/engine/lumenarium_engine_output.h b/src/engine/lumenarium_engine_output.h similarity index 100% rename from src_v2/engine/lumenarium_engine_output.h rename to src/engine/lumenarium_engine_output.h diff --git a/src_v2/engine/output/lumenarium_output_sacn.c b/src/engine/output/lumenarium_output_sacn.c similarity index 100% rename from src_v2/engine/output/lumenarium_output_sacn.c rename to src/engine/output/lumenarium_output_sacn.c diff --git a/src_v2/engine/output/lumenarium_output_sacn.h b/src/engine/output/lumenarium_output_sacn.h similarity index 100% rename from src_v2/engine/output/lumenarium_output_sacn.h rename to src/engine/output/lumenarium_output_sacn.h diff --git a/src_v2/engine/output/lumenarium_output_uart.c b/src/engine/output/lumenarium_output_uart.c similarity index 100% rename from src_v2/engine/output/lumenarium_output_uart.c rename to src/engine/output/lumenarium_output_uart.c diff --git a/src_v2/engine/output/lumenarium_output_uart.h b/src/engine/output/lumenarium_output_uart.h similarity index 100% rename from src_v2/engine/output/lumenarium_output_uart.h rename to src/engine/output/lumenarium_output_uart.h diff --git a/src/gs_libs/gs_bucket.h b/src/gs_libs/gs_bucket.h deleted file mode 100644 index a9281dd..0000000 --- a/src/gs_libs/gs_bucket.h +++ /dev/null @@ -1,103 +0,0 @@ -// -// gs_bucket.h - cpp template implementation of a growable, freeable list -// Author: Peter Slattery -// Date: December 30, 2019 -// -// The key difference between gs_list.h and gs_bucket.h is that gs_bucket.h keeps everything -// sequential (new elements are appended to the end, free elements are filled in from the end), -// whereas gs_list.h maintiains a free list and deals with holes in the list - -template -struct gs_bucket_bucket -{ - T* Contents; -}; - -#define GS_LIST_DEFAULT_BUCKET_SIZE 256 - -template -class gs_bucket { - public: - u32 BucketSize; - u32 BucketCount; - gs_bucket_bucket* Buckets; - - u32 Used; - - void GrowBucket(); - - T* GetElementAtIndex(u32 Index); - T* TakeElement(); - u32 PushElementOnBucket(T Ele); - - void FreeElementAtIndex(u32 Index); -}; - -template -void gs_bucket::GrowBucket() -{ - if (this->BucketSize == 0) - { - this->BucketSize = GS_LIST_DEFAULT_BUCKET_SIZE; - } - - this->BucketCount += 1; - this->Buckets = (gs_bucket_bucket*)realloc(this->Buckets, sizeof(gs_bucket_bucket) * this->BucketCount); - gs_bucket_bucket* NewBucket = this->Buckets + (this->BucketCount - 1); - NewBucket->Contents = (T*)malloc(sizeof(T) * this->BucketSize); -} - -template -T* gs_bucket::GetElementAtIndex(u32 Index) -{ - Assert(Index < this->BucketSize * this->BucketCount); - Assert(Index < this->Used); - - u32 BucketIndex = Index / this->BucketSize; - u32 IndexInBucket = Index % this->BucketSize; - - T* Result = this->Buckets[BucketIndex].Contents + IndexInBucket; - - return Result; -} - -template -T* gs_bucket::TakeElement() -{ - if (this->Used >= this->BucketSize * this->BucketCount) - { - this->GrowBucket(); - } - - u32 Index = this->Used++; - T* Result = this->GetElementAtIndex(Index); - - return Result; -} - -template -u32 gs_bucket::PushElementOnBucket(T Ele) -{ - u32 ResultIndex = 0; - - if (this->Used >= this->BucketSize * this->BucketCount) - { - this->GrowBucket(); - } - - ResultIndex = this->Used++; - T* FreeElement = this->GetElementAtIndex(ResultIndex); - *FreeElement = Ele; - - return ResultIndex; -} - -template -void gs_bucket::FreeElementAtIndex(u32 Index) -{ - Assert(Index < this->BucketSize * this->BucketCount); - - T* ToFillIn = this->GetElementAtIndex(Index); - T* ToFree = this->GetElementAtIndex(--this->Used); - *ToFillIn = *ToFree; -} diff --git a/src/gs_libs/gs_csv.h b/src/gs_libs/gs_csv.h deleted file mode 100644 index 6969d4c..0000000 --- a/src/gs_libs/gs_csv.h +++ /dev/null @@ -1,214 +0,0 @@ -/* date = March 24th 2021 5:53 pm */ - -#ifndef GS_CSV_H -#define GS_CSV_H - -struct gscsv_cell -{ - gs_const_string Value; -}; - -struct gscsv_row -{ - u64* CellIndices; -}; - -struct gscsv_sheet -{ - char SeparatorChar; - gscsv_cell* Cells; - gscsv_row* Rows; - u64 RowCount; - u64 ColumnCount; -}; - -struct gscsv_sheet_desc -{ - char SeparatorChar; -}; - -struct gscsv_parser -{ - gs_const_string Str; - u64 At; - u64 Line; -}; - -internal void -CSVParser_Reset(gscsv_parser* Parser) -{ - Parser->At = 0; -} - -internal char -CSVParser_CharAt(gscsv_parser Parser) -{ - char Result = Parser.Str.Str[Parser.At]; - return Result; -} - -internal bool -CSVParser_CanAdvance(gscsv_parser Parser) { - bool Result = Parser.At < Parser.Str.Length; - return Result; -} - -internal void -CSVParser_Advance(gscsv_parser* Parser) -{ - if (CSVParser_CanAdvance(*Parser)) { - if (IsNewline(CSVParser_CharAt(*Parser))) - { - Parser->Line += 1; - } - Parser->At += 1; - } -} - -internal void -CSVParser_AdvancePastChar(gscsv_parser* Parser, char Char) -{ - while (CSVParser_CanAdvance(*Parser) && CSVParser_CharAt(*Parser) != Char) - { - CSVParser_Advance(Parser); - } - - if (CSVParser_CanAdvance(*Parser)) - { - Assert(CSVParser_CharAt(*Parser) == Char); - CSVParser_Advance(Parser); - } -} - -internal u64 -CSVParser_AdvancePastSeparatorOrNewline(gscsv_parser* Parser, char SeparatorChar) -{ - u64 PointBeforeSeparator = 0; - - while (CSVParser_CanAdvance(*Parser) && - !(CSVParser_CharAt(*Parser) == SeparatorChar || - IsNewline(CSVParser_CharAt(*Parser)))) - { - CSVParser_Advance(Parser); - } - - PointBeforeSeparator = Parser->At; - - if (CSVParser_CanAdvance(*Parser)) - { - while(IsNewline(CSVParser_CharAt(*Parser))) { - CSVParser_Advance(Parser); - } - if (CSVParser_CharAt(*Parser) == SeparatorChar) - { - CSVParser_Advance(Parser); - } - } - - return PointBeforeSeparator; -} - -internal gscsv_cell -CSVCell_Init(gs_const_string File, u64 CellStart, u64 CellEnd) -{ - gscsv_cell Result = {}; - Result.Value = Substring(File, CellStart, CellEnd); - return Result; -} - -internal void -CSVRow_PushCell(gscsv_row* Row, u64 CellIndex, u64 ColumnIndex) -{ - Row->CellIndices[ColumnIndex] = CellIndex; -} - -internal gscsv_sheet -CSV_Parse(gs_const_string File, gscsv_sheet_desc Desc, gs_memory_arena* Arena) -{ - gscsv_sheet Result = {}; - - gscsv_parser Parser = {}; - Parser.Str = File; - Parser.At = 0; - Parser.Line = 0; - - // Count Tabs in first line - u64 Columns = 0; - while (CSVParser_CanAdvance(Parser) && !IsNewline(CSVParser_CharAt(Parser))) - { - char At = CSVParser_CharAt(Parser); - if (At == Desc.SeparatorChar) { - Columns += 1; - } - CSVParser_Advance(&Parser); - } - // NOTE(PS): Add one on the end because the last column won't end in a SeparatorChar, - // it ends in a newline - Columns += 1; - CSVParser_Reset(&Parser); - - // Count New Lines - u64 Rows = 0; - while (CSVParser_CanAdvance(Parser)) - { - char At = CSVParser_CharAt(Parser); - if (IsNewline(At)) - { - Rows++; - while (CSVParser_CanAdvance(Parser) && IsNewline(CSVParser_CharAt(Parser))) - { - CSVParser_Advance(&Parser); - } - } else { - CSVParser_Advance(&Parser); - } - } - // NOTE(PS): Adding a row becuase the last row will just end in the EOF - Rows += 1; - CSVParser_Reset(&Parser); - - // Allocate Result - Result.SeparatorChar = Desc.SeparatorChar; - Result.RowCount = Rows; - Result.ColumnCount = Columns; - Result.Cells = PushArray(Arena, gscsv_cell, Result.RowCount * Result.ColumnCount); - Result.Rows = PushArray(Arena, gscsv_row, Result.RowCount); - - // for rows, parse row - // for cells parse cells - for (u64 r = 0; r < Result.RowCount; r++) - { - u64 RowIndex = r; - gscsv_row* Row = Result.Rows + RowIndex; - Row->CellIndices = PushArray(Arena, u64, Result.ColumnCount); - - for (u64 c = 0; c < Result.ColumnCount; c++) - { - u64 CellIndex = (r * Result.ColumnCount) + c; - u64 CellStart = Parser.At; - u64 CellEnd = CSVParser_AdvancePastSeparatorOrNewline(&Parser, Desc.SeparatorChar); - - Result.Cells[CellIndex] = CSVCell_Init(Parser.Str, CellStart, CellEnd); - CSVRow_PushCell(Row, CellIndex, c); - } - } - - return Result; -} - -internal gs_const_string -CSVSheet_GetCell(gscsv_sheet Sheet, u64 Column, u64 Row) -{ - gs_const_string Result = {}; - - if (Row < Sheet.RowCount && Column < Sheet.ColumnCount) - { - u64 CellIndex = (Row * Sheet.ColumnCount) + Column; - Result = Sheet.Cells[CellIndex].Value; - } - - return Result; -} - - -#endif //GS_CSV_H diff --git a/src/gs_libs/gs_font.h b/src/gs_libs/gs_font.h deleted file mode 100644 index e26a681..0000000 --- a/src/gs_libs/gs_font.h +++ /dev/null @@ -1,167 +0,0 @@ -// -// File: gs_font.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef GS_FONT_H - -struct codepoint_bitmap -{ - s32 XOffset, YOffset; - s32 Width, Height; - s32 BitmapX, BitmapY; - v2 UVMin, UVMax; -}; - -struct bitmap_font -{ - char* Name; - s32 PixelHeight; - s32 Ascent; - s32 Descent; - s32 Leading; - s32 MaxCharWidth; - - u32 CodepointDictionarySize; - u32 CodepointDictionaryCount; - char* CodepointKeys; - codepoint_bitmap* CodepointValues; - - u8* BitmapMemory; - u32 BitmapWidth; - u32 BitmapHeight; - u32 BitmapBytesPerPixel; - u32 BitmapStride; - s32 BitmapTextureHandle; -}; - -#define GLYPH_SKIRT 1 -internal void -GetNextCodepointOffset (bitmap_font* Font, u32* X, u32* Y) -{ - s32 LastCodepointIndex = Font->CodepointDictionaryCount - 1; - if (LastCodepointIndex >= 0) - { - codepoint_bitmap BitmapInfo = Font->CodepointValues[LastCodepointIndex]; - - u32 TempX = BitmapInfo.BitmapX + BitmapInfo.Width + GLYPH_SKIRT; - u32 TempY = BitmapInfo.BitmapY; - if (TempX + Font->MaxCharWidth > Font->BitmapWidth) - { - TempX = 0; - TempY += BitmapInfo.Height + GLYPH_SKIRT; - } - - Assert(TempX >= 0 && TempX < (u32)Font->BitmapWidth); - Assert(TempY >= 0 && TempY < (u32)Font->BitmapHeight); - - *X = TempX; - *Y = TempY; - } - else - { - *X = 0; - *Y = 0; - } -} - -internal void -AddCodepointToFont (bitmap_font* Font, char Codepoint, - s32 XOffset, s32 YOffset, s32 Width, s32 Height, - s32 BitmapX, s32 BitmapY) -{ - Assert(Font->CodepointDictionaryCount < Font->CodepointDictionarySize); - - char* Key = Font->CodepointKeys + Font->CodepointDictionaryCount; - codepoint_bitmap* Value = Font->CodepointValues + Font->CodepointDictionaryCount; - Font->CodepointDictionaryCount++; - - *Key = Codepoint; - Value->XOffset = XOffset; - Value->YOffset = YOffset; - Value->Width = Width; - Value->Height = Height; - Value->BitmapX = BitmapX; - Value->BitmapY = BitmapY; - Value->UVMin = v2{(r32)BitmapX / (r32)Font->BitmapWidth, (r32)BitmapY / (r32)Font->BitmapHeight}; - Value->UVMax = - Value->UVMin + v2{(r32)Width / (r32)Font->BitmapWidth, (r32)Height / (r32)Font->BitmapHeight}; -} - -internal s32 -GetIndexForCodepoint (bitmap_font Font, char Codepoint) -{ - s32 Result = -1; - for (u32 i = 0; i < Font.CodepointDictionaryCount; i++) - { - if (Font.CodepointKeys[i] == Codepoint) - { - Result = i; - break; - } - } - return Result; -} - -inline s32 -NewLineYOffset (bitmap_font Font) -{ - s32 Result = Font.Ascent + Font.Descent; - return Result; -} - - -internal bitmap_font -TextFont_Create(gs_file FontFile, u32 BitmapDim, u32 FontSize, context Context, gs_memory_arena* Arena) -{ - bitmap_font Result = {}; - Assert(FileNoError(FontFile)); - - Result.BitmapWidth = BitmapDim; - Result.BitmapHeight = BitmapDim; - Result.BitmapBytesPerPixel = 4; - Result.BitmapStride = Result.BitmapWidth * Result.BitmapBytesPerPixel; - u32 BitmapSize = Result.BitmapWidth * Result.BitmapHeight * Result.BitmapBytesPerPixel; - Result.BitmapMemory = PushArray(Arena, u8, BitmapSize); - ZeroMemoryBlock(Result.BitmapMemory, BitmapSize); - - platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize, FontWeight_Normal, false, false, false); - Result.PixelHeight = FontInfo.PixelHeight; - Result.Ascent = FontInfo.Ascent; - Result.Descent = FontInfo.Descent; - Result.Leading = FontInfo.Leading; - Result.MaxCharWidth = FontInfo.MaxCharWidth; - - Result.CodepointDictionarySize = (FontInfo.CodepointOnePastLast - FontInfo.CodepointStart); - Result.CodepointDictionaryCount = 0; - Result.CodepointKeys = PushArray(Arena, char, Result.CodepointDictionarySize); - Result.CodepointValues = PushArray(Arena, codepoint_bitmap, Result.CodepointDictionarySize); - - for (s32 Codepoint = FontInfo.CodepointStart; - Codepoint < FontInfo.CodepointOnePastLast; - Codepoint++) - { - - u32 CodepointX, CodepointY; - GetNextCodepointOffset(&Result, &CodepointX, &CodepointY); - - u32 CodepointW, CodepointH; - Context.PlatformDrawFontCodepoint( - Result.BitmapMemory, - Result.BitmapWidth, - Result.BitmapHeight, - CodepointX, CodepointY, - Codepoint, FontInfo, - &CodepointW, &CodepointH); - - AddCodepointToFont(&Result, Codepoint, 0, 0, CodepointW, CodepointH, CodepointX, CodepointY); - } - - Result.BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Result.BitmapMemory, - Result.BitmapWidth, Result.BitmapHeight); - - return Result; -} - -#define GS_FONT_H -#endif // GS_FONT_H \ No newline at end of file diff --git a/src/gs_libs/gs_input.h b/src/gs_libs/gs_input.h deleted file mode 100644 index f0c1c79..0000000 --- a/src/gs_libs/gs_input.h +++ /dev/null @@ -1,671 +0,0 @@ -// -// File: gs_input.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef GS_INPUT_H -enum key_code -{ - KeyCode_Invalid, - - KeyCode_Esc, - - KeyCode_Space, - KeyCode_Tab, - KeyCode_CapsLock, - KeyCode_LeftShift, KeyCode_RightShift, - KeyCode_LeftCtrl, KeyCode_RightCtrl, - KeyCode_Fn, - KeyCode_Alt, - KeyCode_PageUp, KeyCode_PageDown, - KeyCode_Backspace, KeyCode_Delete, - KeyCode_Enter, - - // Function Keys - KeyCode_F0, KeyCode_F1, KeyCode_F2, KeyCode_F3, KeyCode_F4, KeyCode_F5, KeyCode_F6, KeyCode_F7, - KeyCode_F8, KeyCode_F9, KeyCode_F10, KeyCode_F11, KeyCode_F12, - - // Letters - KeyCode_a, KeyCode_b, KeyCode_c, KeyCode_d, KeyCode_e, KeyCode_f, KeyCode_g, KeyCode_h, - KeyCode_i, KeyCode_j, KeyCode_k, KeyCode_l, KeyCode_m, KeyCode_n, KeyCode_o, KeyCode_p, - KeyCode_q, KeyCode_r, KeyCode_s, KeyCode_t, KeyCode_u, KeyCode_v, KeyCode_w, KeyCode_x, - KeyCode_y, KeyCode_z, - - KeyCode_A, KeyCode_B, KeyCode_C, KeyCode_D, KeyCode_E, KeyCode_F, KeyCode_G, KeyCode_H, - KeyCode_I, KeyCode_J, KeyCode_K, KeyCode_L, KeyCode_M, KeyCode_N, KeyCode_O, KeyCode_P, - KeyCode_Q, KeyCode_R, KeyCode_S, KeyCode_T, KeyCode_U, KeyCode_V, KeyCode_W, KeyCode_X, - KeyCode_Y, KeyCode_Z, - - // Numbers - KeyCode_0, KeyCode_1, KeyCode_2, KeyCode_3, KeyCode_4, KeyCode_5, KeyCode_6, KeyCode_7, - KeyCode_8, KeyCode_9, - - KeyCode_Num0, KeyCode_Num1, KeyCode_Num2, KeyCode_Num3, KeyCode_Num4, KeyCode_Num5, - KeyCode_Num6, KeyCode_Num7, KeyCode_Num8, KeyCode_Num9, - - // Symbols - KeyCode_Bang, KeyCode_At, KeyCode_Pound, KeyCode_Dollar, KeyCode_Percent, KeyCode_Carrot, - KeyCode_Ampersand, KeyCode_Star, KeyCode_LeftParen, KeyCode_RightParen, KeyCode_Minus, KeyCode_Plus, - KeyCode_Equals, KeyCode_Underscore, KeyCode_LeftBrace, KeyCode_RightBrace, KeyCode_LeftBracket, - KeyCode_RightBracket, KeyCode_Colon, KeyCode_SemiColon, KeyCode_SingleQuote, KeyCode_DoubleQuote, - KeyCode_ForwardSlash, KeyCode_Backslash, KeyCode_Pipe, KeyCode_Comma, KeyCode_Period, - KeyCode_QuestionMark, KeyCode_LessThan, KeyCode_GreaterThan, KeyCode_Tilde, KeyCode_BackQuote, - - // Arrows - KeyCode_UpArrow, - KeyCode_DownArrow, - KeyCode_LeftArrow, - KeyCode_RightArrow, - - // Mouse - // NOTE(Peter): Including this here so we can utilize the same KeyDown, KeyUp etc. functions - KeyCode_MouseLeftButton, - KeyCode_MouseMiddleButton, - KeyCode_MouseRightButton, - - KeyCode_Count, -}; - -internal char -CharacterFromKeyCode (key_code Code) -{ - char Result = 0; - - switch (Code) - { - case KeyCode_Space: { Result = ' '; }break; - case KeyCode_Tab: { Result = '\t'; }break; - - // Letters - case KeyCode_a: { Result = 'a'; }break; - case KeyCode_b: { Result = 'b'; }break; - case KeyCode_c: { Result = 'c'; }break; - case KeyCode_d: { Result = 'd'; }break; - case KeyCode_e: { Result = 'e'; }break; - case KeyCode_f: { Result = 'f'; }break; - case KeyCode_g: { Result = 'g'; }break; - case KeyCode_h: { Result = 'h'; }break; - case KeyCode_i: { Result = 'i'; }break; - case KeyCode_j: { Result = 'j'; }break; - case KeyCode_k: { Result = 'k'; }break; - case KeyCode_l: { Result = 'l'; }break; - case KeyCode_m: { Result = 'm'; }break; - case KeyCode_n: { Result = 'n'; }break; - case KeyCode_o: { Result = 'o'; }break; - case KeyCode_p: { Result = 'p'; }break; - case KeyCode_q: { Result = 'q'; }break; - case KeyCode_r: { Result = 'r'; }break; - case KeyCode_s: { Result = 's'; }break; - case KeyCode_t: { Result = 't'; }break; - case KeyCode_u: { Result = 'u'; }break; - case KeyCode_v: { Result = 'v'; }break; - case KeyCode_w: { Result = 'w'; }break; - case KeyCode_x: { Result = 'x'; }break; - case KeyCode_y: { Result = 'y'; }break; - case KeyCode_z: { Result = 'z'; }break; - - case KeyCode_A: { Result = 'A'; }break; - case KeyCode_B: { Result = 'B'; }break; - case KeyCode_C: { Result = 'C'; }break; - case KeyCode_D: { Result = 'D'; }break; - case KeyCode_E: { Result = 'E'; }break; - case KeyCode_F: { Result = 'F'; }break; - case KeyCode_G: { Result = 'G'; }break; - case KeyCode_H: { Result = 'H'; }break; - case KeyCode_I: { Result = 'I'; }break; - case KeyCode_J: { Result = 'J'; }break; - case KeyCode_K: { Result = 'K'; }break; - case KeyCode_L: { Result = 'L'; }break; - case KeyCode_M: { Result = 'M'; }break; - case KeyCode_N: { Result = 'N'; }break; - case KeyCode_O: { Result = 'O'; }break; - case KeyCode_P: { Result = 'P'; }break; - case KeyCode_Q: { Result = 'Q'; }break; - case KeyCode_R: { Result = 'R'; }break; - case KeyCode_S: { Result = 'S'; }break; - case KeyCode_T: { Result = 'T'; }break; - case KeyCode_U: { Result = 'U'; }break; - case KeyCode_V: { Result = 'V'; }break; - case KeyCode_W: { Result = 'W'; }break; - case KeyCode_X: { Result = 'X'; }break; - case KeyCode_Y: { Result = 'Y'; }break; - case KeyCode_Z: { Result = 'Z'; }break; - - // Numbers - case KeyCode_0: { Result = '0'; }break; - case KeyCode_1: { Result = '1'; }break; - case KeyCode_2: { Result = '2'; }break; - case KeyCode_3: { Result = '3'; }break; - case KeyCode_4: { Result = '4'; }break; - case KeyCode_5: { Result = '5'; }break; - case KeyCode_6: { Result = '6'; }break; - case KeyCode_7: { Result = '7'; }break; - case KeyCode_8: { Result = '8'; }break; - case KeyCode_9: { Result = '9'; }break; - - case KeyCode_Num0: { Result = '0'; }break; - case KeyCode_Num1: { Result = '1'; }break; - case KeyCode_Num2: { Result = '2'; }break; - case KeyCode_Num3: { Result = '3'; }break; - case KeyCode_Num4: { Result = '4'; }break; - case KeyCode_Num5: { Result = '5'; }break; - case KeyCode_Num6: { Result = '6'; }break; - case KeyCode_Num7: { Result = '7'; }break; - case KeyCode_Num8: { Result = '8'; }break; - case KeyCode_Num9: { Result = '9'; }break; - - // Symbols - case KeyCode_Bang: { Result = '!'; }break; - case KeyCode_At: { Result = '@'; }break; - case KeyCode_Pound: { Result = '#'; }break; - case KeyCode_Dollar: { Result = '$'; }break; - case KeyCode_Percent: { Result = '%'; }break; - case KeyCode_Carrot: { Result = '^'; }break; - case KeyCode_Ampersand: { Result = '&'; }break; - case KeyCode_Star: { Result = '*'; }break; - case KeyCode_LeftParen: { Result = '('; }break; - case KeyCode_RightParen: { Result = ')'; }break; - case KeyCode_Minus: { Result = '-'; }break; - case KeyCode_Plus: { Result = '+'; }break; - case KeyCode_Equals: { Result = '='; }break; - case KeyCode_Underscore: { Result = '_'; }break; - case KeyCode_LeftBrace: { Result = '['; }break; - case KeyCode_RightBrace: { Result = ']'; }break; - case KeyCode_LeftBracket: { Result = '{'; }break; - case KeyCode_RightBracket: { Result = '}'; }break; - case KeyCode_Colon: { Result = ':'; }break; - case KeyCode_SemiColon: { Result = ';'; }break; - case KeyCode_SingleQuote: { Result = '\''; }break; - case KeyCode_DoubleQuote: { Result = '"'; }break; - case KeyCode_ForwardSlash: { Result = '/'; }break; - case KeyCode_Backslash: { Result = '\\'; }break; - case KeyCode_Pipe: { Result = '|'; }break; - case KeyCode_Comma: { Result = ','; }break; - case KeyCode_Period: { Result = '.'; }break; - case KeyCode_QuestionMark: { Result = '?'; }break; - case KeyCode_LessThan: { Result = '<'; }break; - case KeyCode_GreaterThan: { Result = '>'; }break; - case KeyCode_Tilde: { Result = '~'; }break; - case KeyCode_BackQuote: { Result = '`'; }break; - } - - Assert(Result != 0); - return Result; -} - -enum modifier_flags -{ - Modifier_Shift = 1 << 0, - Modifier_Ctrl = 1 << 1, - Modifier_Alt = 1 << 2, - Modifier_Sys = 1 << 3, // NOTE(Peter): this is the windows key -}; - -#define INPUT_FRAME_STRING_LENGTH 32 -struct input_frame -{ - b32 KeysDown[(int)KeyCode_Count]; - s32 StringInputUsed; - char StringInput[INPUT_FRAME_STRING_LENGTH]; - s32 MouseX, MouseY, MouseScroll; -}; - -struct input -{ - input_frame Frames[2]; - input_frame* New; - input_frame* Old; - s32 MouseDownX, MouseDownY; -}; - -enum key_state_flags -{ - KeyState_WasDown = 1 << 0, - KeyState_IsDown = 1 << 1, -}; - -#define KeyWasDown(event) ((event & KeyState_WasDown) > 0) -#define KeyIsDown(event) ((event & KeyState_IsDown) > 0) - -#define SetKeyDown(key) (key |= KeyState_IsDown) -#define SetKeyWasDown(key) (key |= KeyState_WasDown) -#define SetKeyUp(key) (key &= ~KeyState_IsDown) -#define SetKeyWasUp(key) (key &= ~KeyState_WasDown) - -struct input_entry -{ - key_code Key; - b32 State; - b32 Modifiers; -}; - -struct input_queue -{ - s32 QueueSize; - s32 QueueUsed; - input_entry* Entries; -}; - -enum cursor_type -{ - CursorType_Arrow, - CursorType_Pointer, - CursorType_Loading, - CursorType_HArrows, - CursorType_VArrows, - CursorType_DTopLeftArrows, - CursorType_DTopRightArrows, - CursorType_Count, -}; - -struct mouse_state -{ - s32 Scroll; - - v2 Pos; - v2 OldPos; - v2 DeltaPos; - v2 DownPos; - - b32 LeftButtonState; - b32 MiddleButtonState; - b32 RightButtonState; - - - - cursor_type CursorType; -}; - -internal input_queue -InputQueue_Create (u8* Memory, s32 MemorySize) -{ - input_queue Result = {}; - s32 EntriesCount = MemorySize / sizeof(input_entry); - Result.QueueSize = EntriesCount; - Result.QueueUsed = 0; - Result.Entries = (input_entry*)Memory; - return Result; -} -internal input_queue -InputQueue_Create(gs_memory_arena* Arena, u32 CountMax) -{ - input_queue Result = {0}; - if (CountMax > 0) - { - s32 Size = sizeof(input_entry) * 32; - u8* Memory = PushSize(Arena, Size).Memory; - Result = InputQueue_Create(Memory, Size); - } - return Result; -} - -internal void -ResetInputQueue (input_queue* Queue) -{ - Queue->QueueUsed = 0; -} - -internal void InitializeInput (input* Input); -internal void SwapInputBuffers (input* Input); - -internal void -InitializeInput (input* Input) -{ - *(Input) = {}; - Input->New = &Input->Frames[0]; - Input->Old = &Input->Frames[1]; -} - -internal void -SwapInputBuffers (input* Input) -{ - input_frame* NowOld = Input->New; - Input->New = Input->Old; - Input->Old = NowOld; - - for (s32 Key = 0; Key < KeyCode_Count; Key++) { Input->New->KeysDown[Key] = Input->Old->KeysDown[Key]; } - Input->New->StringInputUsed = 0; -} - -internal b32 -KeyDown (input Input, key_code Key) -{ - return Input.New->KeysDown[Key]; -} - -internal b32 -KeyTransitionedDown (input Input, key_code Key) -{ - return Input.New->KeysDown[Key] && !Input.Old->KeysDown[Key]; -} - -internal b32 -KeyTransitionedUp (input Input, key_code Key) -{ - return !Input.New->KeysDown[Key] && Input.Old->KeysDown[Key]; -} - -internal void -AddInputEventEntry (input_queue* Queue, key_code Key, - b32 WasDown, b32 IsDown, b32 ShiftDown, b32 AltDown, b32 CtrlDown, b32 SysDown) -{ - Assert(Queue->QueueUsed < Queue->QueueSize); - - input_entry* Entry = Queue->Entries + Queue->QueueUsed++; - Entry->Key = Key; - - Entry->State = (key_state_flags)0; - if (WasDown) { Entry->State |= KeyState_WasDown; } - if (IsDown) { Entry->State |= KeyState_IsDown; } - - Entry->Modifiers = 0; - if (ShiftDown) { Entry->Modifiers |= Modifier_Shift; } - if (CtrlDown) { Entry->Modifiers |= Modifier_Ctrl; } - if (AltDown) { Entry->Modifiers |= Modifier_Alt; } - if (SysDown) { Entry->Modifiers |= Modifier_Sys; } -} - -internal b32 -KeyTransitionedDown (input_entry Entry) -{ - return (!KeyWasDown(Entry.State) && KeyIsDown(Entry.State)); -} - -internal b32 -KeyTransitionedUp (input_entry Entry) -{ - return (KeyWasDown(Entry.State) && !KeyIsDown(Entry.State)); -} - -internal b32 -KeyHeldDown (input_entry Entry) -{ - return (KeyWasDown(Entry.State) && KeyIsDown(Entry.State)); -} - -internal b32 -MouseButtonTransitionedDown (b32 MouseButtonState) -{ - return (!KeyWasDown(MouseButtonState) && KeyIsDown(MouseButtonState)); -} - -internal b32 -MouseButtonTransitionedUp (b32 MouseButtonState) -{ - return (KeyWasDown(MouseButtonState) && !KeyIsDown(MouseButtonState)); -} - -internal b32 -MouseButtonHeldDown (b32 MouseButtonState) -{ - b32 WasDown = KeyWasDown(MouseButtonState); - b32 IsDown = KeyIsDown(MouseButtonState); - return (WasDown && IsDown); -} - -inline b32 -GetMouseButtonStateAdvanced (b32 ButtonState) -{ - b32 Result = ButtonState; - if (ButtonState & KeyState_WasDown && - !((ButtonState & KeyState_IsDown) > 0)) - { - Result= 0; - } - else if (ButtonState & KeyState_IsDown) - { - Result |= KeyState_WasDown; - } - return Result; -} - -internal char -KeyCodeToChar(key_code Code) -{ - char Result = 0; - - switch (Code) - { - case KeyCode_Space: { Result = ' '; } break; - case KeyCode_Tab: { Result = '\t'; } break; - case KeyCode_Enter: { Result = '\n'; } break; - case KeyCode_Backspace: { Result = '\b'; } break; - - case KeyCode_a: { Result = 'a'; } break; - case KeyCode_b: { Result = 'b'; } break; - case KeyCode_c: { Result = 'c'; } break; - case KeyCode_d: { Result = 'd'; } break; - case KeyCode_e: { Result = 'e'; } break; - case KeyCode_f: { Result = 'f'; } break; - case KeyCode_g: { Result = 'g'; } break; - case KeyCode_h: { Result = 'h'; } break; - case KeyCode_i: { Result = 'i'; } break; - case KeyCode_j: { Result = 'j'; } break; - case KeyCode_k: { Result = 'k'; } break; - case KeyCode_l: { Result = 'l'; } break; - case KeyCode_m: { Result = 'm'; } break; - case KeyCode_n: { Result = 'n'; } break; - case KeyCode_o: { Result = 'o'; } break; - case KeyCode_p: { Result = 'p'; } break; - case KeyCode_q: { Result = 'q'; } break; - case KeyCode_r: { Result = 'r'; } break; - case KeyCode_s: { Result = 's'; } break; - case KeyCode_t: { Result = 't'; } break; - case KeyCode_u: { Result = 'u'; } break; - case KeyCode_v: { Result = 'v'; } break; - case KeyCode_w: { Result = 'w'; } break; - case KeyCode_x: { Result = 'x'; } break; - case KeyCode_y: { Result = 'y'; } break; - case KeyCode_z: { Result = 'z'; } break; - case KeyCode_A: { Result = 'A'; } break; - case KeyCode_B: { Result = 'B'; } break; - case KeyCode_C: { Result = 'C'; } break; - case KeyCode_D: { Result = 'D'; } break; - case KeyCode_E: { Result = 'E'; } break; - case KeyCode_F: { Result = 'F'; } break; - case KeyCode_G: { Result = 'G'; } break; - case KeyCode_H: { Result = 'H'; } break; - case KeyCode_I: { Result = 'I'; } break; - case KeyCode_J: { Result = 'J'; } break; - case KeyCode_K: { Result = 'K'; } break; - case KeyCode_L: { Result = 'L'; } break; - case KeyCode_M: { Result = 'M'; } break; - case KeyCode_N: { Result = 'N'; } break; - case KeyCode_O: { Result = 'O'; } break; - case KeyCode_P: { Result = 'P'; } break; - case KeyCode_Q: { Result = 'Q'; } break; - case KeyCode_R: { Result = 'R'; } break; - case KeyCode_S: { Result = 'S'; } break; - case KeyCode_T: { Result = 'T'; } break; - case KeyCode_U: { Result = 'U'; } break; - case KeyCode_V: { Result = 'V'; } break; - case KeyCode_W: { Result = 'W'; } break; - case KeyCode_X: { Result = 'X'; } break; - case KeyCode_Y: { Result = 'Y'; } break; - case KeyCode_Z: { Result = 'Z'; } break; - - case KeyCode_Num0: - case KeyCode_0: { Result = '0'; } break; - case KeyCode_Num1: - case KeyCode_1: { Result = '1'; } break; - case KeyCode_Num2: - case KeyCode_2: { Result = '2'; } break; - case KeyCode_Num3: - case KeyCode_3: { Result = '3'; } break; - case KeyCode_Num4: - case KeyCode_4: { Result = '4'; } break; - case KeyCode_Num5: - case KeyCode_5: { Result = '5'; } break; - case KeyCode_Num6: - case KeyCode_6: { Result = '6'; } break; - case KeyCode_Num7: - case KeyCode_7: { Result = '7'; } break; - case KeyCode_Num8: - case KeyCode_8: { Result = '8'; } break; - case KeyCode_Num9: - case KeyCode_9: { Result = '9'; } break; - - case KeyCode_Bang: { Result = '!'; } break; - case KeyCode_At: { Result = '@'; } break; - case KeyCode_Pound: { Result = '#'; } break; - case KeyCode_Dollar: { Result = '$'; } break; - case KeyCode_Percent: { Result = '%'; } break; - case KeyCode_Carrot: { Result = '^'; } break; - case KeyCode_Ampersand: { Result = '&'; } break; - case KeyCode_Star: { Result = '*'; } break; - case KeyCode_LeftParen: { Result = '('; } break; - case KeyCode_RightParen: { Result = ')'; } break; - case KeyCode_Minus: { Result = '-'; } break; - case KeyCode_Plus: { Result = '+'; } break; - case KeyCode_Equals: { Result = '='; } break; - case KeyCode_Underscore: { Result = '_'; } break; - case KeyCode_LeftBrace: { Result = '{'; } break; - case KeyCode_RightBrace: { Result = '}'; } break; - case KeyCode_LeftBracket: { Result = '['; } break; - case KeyCode_RightBracket: { Result = ']'; } break; - case KeyCode_Colon: { Result = ':'; } break; - case KeyCode_SemiColon: { Result = ';'; } break; - case KeyCode_SingleQuote: { Result = '\''; } break; - case KeyCode_DoubleQuote: { Result = '"'; } break; - case KeyCode_ForwardSlash: { Result = '/'; } break; - case KeyCode_Backslash: { Result = '\\'; } break; - case KeyCode_Pipe: { Result = '|'; } break; - case KeyCode_Comma: { Result = ','; } break; - case KeyCode_Period: { Result = '.'; } break; - case KeyCode_QuestionMark: { Result = '?'; } break; - case KeyCode_LessThan: { Result = '<'; } break; - case KeyCode_GreaterThan: { Result = '>'; } break; - case KeyCode_Tilde: { Result = '~'; } break; - case KeyCode_BackQuote: { Result = '`'; } break; - - default: { Result = 0; } break; - } - - return Result; -} - -internal bool -KeyCodeHasChar(key_code Code) -{ - bool Result = KeyCodeToChar(Code) != 0; - return Result; -} - - -internal key_code -CharToKeyCode(char C) -{ - key_code Result = KeyCode_Invalid; - - switch (C) - { - case ' ': { Result = KeyCode_Space; } break; - case '\t': { Result = KeyCode_Tab; } break; - case '\n': { Result = KeyCode_Enter; } break; - case '\b': { Result = KeyCode_Backspace; } break; - - case 'a': { Result = KeyCode_a; } break; - case 'b': { Result = KeyCode_b; } break; - case 'c': { Result = KeyCode_c; } break; - case 'd': { Result = KeyCode_d; } break; - case 'e': { Result = KeyCode_e; } break; - case 'f': { Result = KeyCode_f; } break; - case 'g': { Result = KeyCode_g; } break; - case 'h': { Result = KeyCode_h; } break; - case 'i': { Result = KeyCode_i; } break; - case 'j': { Result = KeyCode_j; } break; - case 'k': { Result = KeyCode_k; } break; - case 'l': { Result = KeyCode_l; } break; - case 'm': { Result = KeyCode_m; } break; - case 'n': { Result = KeyCode_n; } break; - case 'o': { Result = KeyCode_o; } break; - case 'p': { Result = KeyCode_p; } break; - case 'q': { Result = KeyCode_q; } break; - case 'r': { Result = KeyCode_r; } break; - case 's': { Result = KeyCode_s; } break; - case 't': { Result = KeyCode_t; } break; - case 'u': { Result = KeyCode_u; } break; - case 'v': { Result = KeyCode_v; } break; - case 'w': { Result = KeyCode_w; } break; - case 'x': { Result = KeyCode_x; } break; - case 'y': { Result = KeyCode_y; } break; - case 'z': { Result = KeyCode_z; } break; - case 'A': { Result = KeyCode_A; } break; - case 'B': { Result = KeyCode_B; } break; - case 'C': { Result = KeyCode_C; } break; - case 'D': { Result = KeyCode_D; } break; - case 'E': { Result = KeyCode_E; } break; - case 'F': { Result = KeyCode_F; } break; - case 'G': { Result = KeyCode_G; } break; - case 'H': { Result = KeyCode_H; } break; - case 'I': { Result = KeyCode_I; } break; - case 'J': { Result = KeyCode_J; } break; - case 'K': { Result = KeyCode_K; } break; - case 'L': { Result = KeyCode_L; } break; - case 'M': { Result = KeyCode_M; } break; - case 'N': { Result = KeyCode_N; } break; - case 'O': { Result = KeyCode_O; } break; - case 'P': { Result = KeyCode_P; } break; - case 'Q': { Result = KeyCode_Q; } break; - case 'R': { Result = KeyCode_R; } break; - case 'S': { Result = KeyCode_S; } break; - case 'T': { Result = KeyCode_T; } break; - case 'U': { Result = KeyCode_U; } break; - case 'V': { Result = KeyCode_V; } break; - case 'W': { Result = KeyCode_W; } break; - case 'X': { Result = KeyCode_X; } break; - case 'Y': { Result = KeyCode_Y; } break; - case 'Z': { Result = KeyCode_Z; } break; - - case '0': { Result = KeyCode_0; } break; - case '1': { Result = KeyCode_1; } break; - case '2': { Result = KeyCode_2; } break; - case '3': { Result = KeyCode_3; } break; - case '4': { Result = KeyCode_4; } break; - case '5': { Result = KeyCode_5; } break; - case '6': { Result = KeyCode_6; } break; - case '7': { Result = KeyCode_7; } break; - case '8': { Result = KeyCode_8; } break; - case '9': { Result = KeyCode_9; } break; - - case '!': { Result = KeyCode_Bang; } break; - case '@': { Result = KeyCode_At; } break; - case '#': { Result = KeyCode_Pound; } break; - case '$': { Result = KeyCode_Dollar; } break; - case '%': { Result = KeyCode_Percent; } break; - case '^': { Result = KeyCode_Carrot; } break; - case '&': { Result = KeyCode_Ampersand; } break; - case '*': { Result = KeyCode_Star; } break; - case '(': { Result = KeyCode_LeftParen; } break; - case ')': { Result = KeyCode_RightParen; } break; - case '-': { Result = KeyCode_Minus; } break; - case '+': { Result = KeyCode_Plus; } break; - case '=': { Result = KeyCode_Equals; } break; - case '_': { Result = KeyCode_Underscore; } break; - case '{': { Result = KeyCode_LeftBrace; } break; - case '}': { Result = KeyCode_RightBrace; } break; - case '[': { Result = KeyCode_LeftBracket; } break; - case ']': { Result = KeyCode_RightBracket; } break; - case ':': { Result = KeyCode_Colon; } break; - case ';': { Result = KeyCode_SemiColon; } break; - case '\'': { Result = KeyCode_SingleQuote; } break; - case '"': { Result = KeyCode_DoubleQuote; } break; - case '/': { Result = KeyCode_ForwardSlash; } break; - case '\\': { Result = KeyCode_Backslash; } break; - case '|': { Result = KeyCode_Pipe; } break; - case ',': { Result = KeyCode_Comma; } break; - case '.': { Result = KeyCode_Period; } break; - case '?': { Result = KeyCode_QuestionMark; } break; - case '<': { Result = KeyCode_LessThan; } break; - case '>': { Result = KeyCode_GreaterThan; } break; - case '~': { Result = KeyCode_Tilde; } break; - case '`': { Result = KeyCode_BackQuote; } break; - - default: { Result = KeyCode_Invalid; } break; - } - - return Result; -} - -#define GS_INPUT_H -#endif // GS_INPUT_H \ No newline at end of file diff --git a/src/gs_libs/gs_language.h b/src/gs_libs/gs_language.h deleted file mode 100644 index 3e31391..0000000 --- a/src/gs_libs/gs_language.h +++ /dev/null @@ -1,477 +0,0 @@ -#ifndef GS_LANGUAGE_H - -#if 0 -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) -#include - -// TODO(Peter): Get rid of math.h -#include - -#elif defined(__APPLE__) && defined(__MAC__) -// TODO(Peter): - -#else // Std lib -#include - -#endif - -#define internal static -#define local_persist static -#define global_variable static - - -#if !defined(GS_TYPES) - -#define GSINT64(s) (s) ## L -#define GSUINT64(s) (s) ## UL - -typedef signed char b8; -typedef short int b16; -typedef int b32; -typedef long long int b64; - -typedef unsigned char u8; -typedef unsigned short int u16; -typedef unsigned int u32; -typedef unsigned long long int u64; - -typedef signed char s8; -typedef short int s16; -typedef int s32; -typedef long long int s64; - -typedef float r32; -typedef double r64; - -#endif - -#ifndef _STDINT - -#define INT8_MIN (-128) -#define INT16_MIN (-32767-1) -#define INT32_MIN (-2147483647-1) -#define INT64_MIN (-GSINT64(9223372036854775807)-1) - -#define INT8_MAX (127) -#define INT16_MAX (32767) -#define INT32_MAX (2147483647) -#define INT64_MAX (GSINT64(9223372036854775807)) - -#define UINT8_MAX (255) -#define UINT16_MAX (65535) -#define UINT32_MAX (4294967295U) -#define UINT64_MAX (GSUINT64(18446744073709551615)) - -#endif // _STDINT - -#define FLOAT_MIN (1.175494351e-38F) -#define FLOAT_MAX (3.402823466e+38F) -#define DOUBLE_MIN (2.2250738585072014e-308) -#define DOUBLE_MAX (1.7976931348623158e+308) - -#define Kilobytes(Value) ((Value) * 1024) -#define Megabytes(Value) (Kilobytes(Value) * 1024) -#define Gigabytes(Value) (Megabytes(Value) * 1024) -#define Terabytes(Value) (Gigabytes(Value) * 1024) - -#ifndef PI -#define PI 3.14159265359 -#endif - -#define TAU 6.2831853071 -#define PI_OVER_180 0.01745329251f - -#define GS_TYPES -#endif - - -#if DEBUG - -static void DebugPrint(char* Format, ...); - -#if !defined(Assert) -// NOTE(peter): this writes to address 0 which is always illegal and will cause a crash -#define Assert(expression) \ -if((expression)) \ -{ \ -}else{ \ -volatile int* p = 0; \ -*p = 5; \ -} -#endif - -#define DEBUG_IF(condition) if (condition) - -#define InvalidCodePath Assert(0) -#define InvalidDefaultCase default: { Assert(0); } -#define DebugBreak __debugbreak() - -#define STBI_ASSERT(x) Assert(x) - -#ifdef GS_TEST_SUTE -#define TestClean(v, c) SuccessCount += Test(v, c, &TestCount) -internal s32 -Test(b32 Result, char* Description, s32* Count) -{ - char* Passed = (Result ? "Success" : "Failed"); - if (!Result) - DebugPrint("%s:\n................................................%s\n\n", Description, Passed); - - *Count = *Count + 1; - return (Result ? 1 : 0); -} -#endif // GS_TEST_SUTE - -#ifndef GS_LANGUAGE_NO_PROFILER_DEFINES -#ifndef DEBUG_TRACK_SCOPE -#define DEBUG_TRACK_SCOPE(a) -#endif // DEBUG_TRACK_SCOPE -#ifndef DEBUG_TRACK_FUNCTION -#define DEBUG_TRACK_FUNCTION -#endif // DEBUG_TRACK_FUNCTION -#endif // GS_LANGUAGE_NO_PROFILER_DEFINES - -#else - -#define Assert(expression) -#define InvalidCodePath -#define DEBUG_IF(condition) - -#ifndef GS_LANGUAGE_NO_PROFILER_DEFINES -#ifndef DEBUG_TRACK_SCOPE -#define DEBUG_TRACK_SCOPE(a) -#endif // DEBUG_TRACK_SCOPE -#ifndef DEBUG_TRACK_FUNCTION -#define DEBUG_TRACK_FUNCTION -#endif // DEBUG_TRACK_FUNCTION -#endif // GS_LANGUAGE_NO_PROFILER_DEFINES - -#endif // DEBUG - -#ifndef GS_LANGUAGE_MATH - -#define GSArrayLength(arr) (sizeof(arr) / sizeof(arr[0])) - -#define GSZeroStruct(data) GSZeroMemory_((u8*)(&(data)), sizeof(data)) -#define GSZeroMemory(mem, size) GSZeroMemory_((u8*)(mem), (size)) -#define GSZeroArray(arr, type, count) GSZeroMemory_((u8*)(arr), (sizeof(type) * count)) -static void -GSZeroMemory_ (u8* Memory, s32 Size) -{ - for (int i = 0; i < Size; i++) { Memory[i] = 0; } -} - -#define GSMemCopy(from, to, size) GSMemCopy_((u8*)from, (u8*)to, size) -static void -GSMemCopy_ (u8* From, u8* To, s32 Size) -{ - for (int i = 0; i < Size; i++) { To[i] = From[i]; } -} - -#define GSMemSet(buffer, value, size) GSMemSet_((u8*)buffer, value, size) -internal void -GSMemSet_ (u8* Buffer, u8 Value, s32 Length) -{ - u8* Cursor = Buffer; - for (s32 i = 0; i < Length; i++) - { - *Cursor++ = Value; - } -} - -#define GSMinDef(type) static type GSMin(type A, type B) { return (A < B ? A : B); } -GSMinDef(s8) -GSMinDef(s16) -GSMinDef(s32) -GSMinDef(s64) -GSMinDef(u8) -GSMinDef(u16) -GSMinDef(u32) -GSMinDef(u64) -GSMinDef(r32) -GSMinDef(r64) -#undef GSMinDef - -#define GSMaxDef(type) static type GSMax(type A, type B) { return (A > B ? A : B); } -GSMaxDef(s8) -GSMaxDef(s16) -GSMaxDef(s32) -GSMaxDef(s64) -GSMaxDef(u8) -GSMaxDef(u16) -GSMaxDef(u32) -GSMaxDef(u64) -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; \ -} -GSClampDef(s8) -GSClampDef(s16) -GSClampDef(s32) -GSClampDef(s64) -GSClampDef(u8) -GSClampDef(u16) -GSClampDef(u32) -GSClampDef(u64) -GSClampDef(r32) -GSClampDef(r64) -#undef GSClampDef - -#define GSClamp01Def(type) static type GSClamp01(type V) { \ -type Min = 0; type Max = 1; \ -type Result = V; \ -if (V < Min) { Result = Min; } \ -if (V > Max) { Result = Max; } \ -return Result; \ -} -GSClamp01Def(r32) -GSClamp01Def(r64) -#undef GSClamp01Def - -#define GSAbsDef(type) static type GSAbs(type A) { return (A < 0 ? -A : A); } -GSAbsDef(s8) -GSAbsDef(s16) -GSAbsDef(s32) -GSAbsDef(s64) -GSAbsDef(r32) -GSAbsDef(r64) -#undef GSAbsDef - -#define GSPowDef(type) static type GSPow(type N, s32 Power) { \ -type Result = N; \ -for(s32 i = 1; i < Power; i++) { Result *= N; } \ -return Result; \ -} -GSPowDef(s8) -GSPowDef(s16) -GSPowDef(s32) -GSPowDef(s64) -GSPowDef(u8) -GSPowDef(u16) -GSPowDef(u32) -GSPowDef(u64) -GSPowDef(r32) -GSPowDef(r64) -#undef GSPowDef - - -#define GSLerpDef(type) type GSLerp(type A, type B, type Percent) { return (A * (1.0f - Percent))+(B * Percent);} -GSLerpDef(r32) -GSLerpDef(r64) -#undef GSLerpDef - -static r32 GSSqrt(r32 V) -{ - r32 Result = _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(V))); - return Result; -} -#if 0 -// TODO(Peter): Need a way to split the input into two f32's to supply to _mm_sqrt_sd -static r64 GSSqrt(r64 V) -{ - r64 Result = _mm_cvtsd_f64(_mm_sqrt_sd(_mm_set_sd(V))); - return Result; -} -#endif - -static r32 DegreesToRadians (r32 Degrees) { return Degrees * PI_OVER_180; } -static r64 DegreesToRadians (r64 Degrees) { return Degrees * PI_OVER_180; } - -#define GSIsPowerOfTwoDef(type) static type IsPowerOfTwo(type V) { return (V & (V - 1)) == 0; } -GSIsPowerOfTwoDef(u8); -GSIsPowerOfTwoDef(u16); -GSIsPowerOfTwoDef(u32); -GSIsPowerOfTwoDef(u64); -#undef GSIsPowerOfTwoDef - -#define GSIsOddDef(type) inline type IsOdd(type V) { return (V & 1); } -GSIsOddDef(u8); -GSIsOddDef(u16); -GSIsOddDef(u32); -GSIsOddDef(u64); -GSIsOddDef(s8); -GSIsOddDef(s16); -GSIsOddDef(s32); -GSIsOddDef(s64); -#undef GSIsOddDef - -#define GSIntDivideRoundUpDef(type) static type IntegerDivideRoundUp (type A, type B) { r32 Result = (r32)A / (r32)B; Result += .99999f; return (type)Result; } -GSIntDivideRoundUpDef(u8); -GSIntDivideRoundUpDef(u16); -GSIntDivideRoundUpDef(u32); -GSIntDivideRoundUpDef(u64); -GSIntDivideRoundUpDef(s8); -GSIntDivideRoundUpDef(s16); -GSIntDivideRoundUpDef(s32); -GSIntDivideRoundUpDef(s64); -#undef GSIntDivideRoundUpDef - -#define GSRemapDef(type) \ -static type GSRemap(type Value, type OldMin, type OldMax, type NewMin, type NewMax) { \ -type Result = (Value - OldMin) / (OldMax - OldMin); \ -Result = (Result * (NewMax - NewMin)) + NewMin; \ -return Result; \ -} -GSRemapDef(u8); -GSRemapDef(u16); -GSRemapDef(u32); -GSRemapDef(u64); -GSRemapDef(s8); -GSRemapDef(s16); -GSRemapDef(s32); -GSRemapDef(s64); -GSRemapDef(r32); -GSRemapDef(r64); -#undef GSRemapDef - -static r32 -GSFloor(r32 Value) -{ - return floor(Value); -} - -static r32 -GSFract(r32 Value) -{ - return Value - GSFloor(Value); -} - -static r32 -GSModF(r32 Value, r32 Int) -{ - r32 Div = Value / Int; - r32 Fract = GSAbs(GSFract(Div)); - return Int * Fract; -} - -#define GSTrigFunctionDef(name, type, func) static type name(type V) { return func(V); } -GSTrigFunctionDef(GSSin, r32, sinf); -GSTrigFunctionDef(GSSin, r64, sin); -GSTrigFunctionDef(GSCos, r32, cosf); -GSTrigFunctionDef(GSCos, r64, cos); -GSTrigFunctionDef(GSTan, r32, tanf); -GSTrigFunctionDef(GSTan, r64, tan); -#undef GSTrigFunctionDef - -static u8 -RoundToNearestPowerOfTwo (u8 V) -{ - u8 Result = 0; - - if (IsPowerOfTwo(V)) - { - Result = V; - } - else - { - Result = V - 1; - Result |= Result >> 1; - Result |= Result >> 2; - Result |= Result >> 4; - Result += 1; - } - - return Result; -} - -static u16 -RoundToNearestPowerOfTwo (u16 V) -{ - u16 Result = 0; - - if (IsPowerOfTwo(V)) - { - Result = V; - } - else - { - Result = V - 1; - Result |= Result >> 1; - Result |= Result >> 2; - Result |= Result >> 4; - Result |= Result >> 8; - Result += 1; - } - - return Result; -} - -static u32 -RoundToNearestPowerOfTwo (u32 V) -{ - u32 Result = 0; - - if (IsPowerOfTwo(V)) - { - Result = V; - } - else - { - Result = V - 1; - Result |= Result >> 1; - Result |= Result >> 2; - Result |= Result >> 4; - Result |= Result >> 8; - Result |= Result >> 16; - Result += 1; - } - - return Result; -} - -static u64 -RoundToNearestPowerOfTwo (u64 V) -{ - u64 Result = 0; - - if (IsPowerOfTwo(V)) - { - Result = V; - } - else - { - Result = V - 1; - Result |= Result >> 1; - Result |= Result >> 2; - Result |= Result >> 4; - Result |= Result >> 8; - Result |= Result >> 16; - Result |= Result >> 32; - Result += 1; - } - - return Result; -} - -#define GS_LANGUAGE_MATH -#endif // GS_LANGUAGE_MATH - -static u32 -HostToNetU32(u32 In) -{ - unsigned char *s = (unsigned char *)&In; - u32 Result = (u32)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); - return Result; -} - -static u16 -HostToNetU16(u16 In) -{ - unsigned char *s = (unsigned char *)&In; - u16 Result = (u16)(s[0] << 8 | s[1]); - return Result; -} - -#define GS_LANGUAGE_H -#endif \ No newline at end of file diff --git a/src/gs_libs/gs_list.h b/src/gs_libs/gs_list.h deleted file mode 100644 index 20926f0..0000000 --- a/src/gs_libs/gs_list.h +++ /dev/null @@ -1,247 +0,0 @@ -// -// gs_list.h - cpp template implementation of a growable, freeable list -// Author: Peter Slattery -// Date: December 30, 2019 -// -// The key difference between gs_list.h and gs_bucket.h is that gs_bucket.h keeps everything -// sequential (new elements are appended to the end, free elements are filled in from the end), -// whereas gs_list.h maintiains a free list and deals with holes in the list - -struct gs_list_handle -{ - // NOTE(Peter): A generation of 0 in a handle denotes an invalid handle - u32 Generation; - u32 Index; -}; - -#define ListHandleIsInvalid(handle) ((handle).Generation == 0) -#define ListHandleIsValid(handle) ((handle).Generation != 0) - -internal b32 -GSListHandlesAreEqual(gs_list_handle A, gs_list_handle B) -{ - b32 Result = (A.Index == B.Index) && (A.Generation == B.Generation); - return Result; -} - -struct gs_free_list -{ - u8* NextFreeEntry; -}; - -template -struct gs_list_entry -{ - gs_list_handle Handle; - gs_free_list Free; - T Value; -}; - -#define EntryIsFree(entry) ((entry)->Free.NextFreeEntry != 0) - -template -struct gs_list_bucket -{ - gs_list_entry* Contents; -}; - -#define GS_LIST_DEFAULT_BUCKET_SIZE 256 - -template -class gs_list { - public: - u32 BucketCapacity; - u32 BucketCount; - gs_list_bucket* Buckets; - gs_list_entry FreeList; - - u32 Used; - - // NOTE(Peter): this is just here so we can get the next entry which is - // not a part of the free list but is still unused. - // It shouldn't be used outside of the actual list implementation. - u32 OnePastLastUsed; - - gs_list(); - gs_list(u32 BucketSize); - - void GrowList(); - - gs_list_entry* GetEntryAtIndex(u32 Index); - - T* GetElementAtIndex(u32 Index); - T* GetElementWithHandle(gs_list_handle Handle); - - gs_list_entry* TakeFreeEntry(); - T* TakeElement(); - gs_list_handle PushElementOnList(T Ele); - - void FreeElementAtIndex(u32 Index); - void FreeElementWithHandle(gs_list_handle Handle); -}; - -template -gs_list::gs_list() -{ - this->BucketCapacity = GS_LIST_DEFAULT_BUCKET_SIZE; - this->BucketCount = 0; - this->Buckets = 0; - this->FreeList.Free.NextFreeEntry = (u8*)&this->FreeList; - this->Used = 0; - this->OnePastLastUsed = 0; -} - -template -gs_list::gs_list(u32 BucketCapacity) -{ - this->BucketCapacity = BucketCapacity; - this->BucketCount = 0; - this->Buckets = 0; - this->FreeList.Free.NextFreeEntry = (u8*)&this->FreeList; - this->Used = 0; - this->OnePastLastUsed = 0; -} - -template -void gs_list::GrowList() -{ - if (this->BucketCapacity == 0) - { - this->BucketCapacity = GS_LIST_DEFAULT_BUCKET_SIZE; - } - - this->BucketCount += 1; - this->Buckets = (gs_list_bucket*)realloc(this->Buckets, sizeof(gs_list_bucket) * this->BucketCount); - gs_list_bucket* NewBucket = this->Buckets + (this->BucketCount - 1); - NewBucket->Contents = (gs_list_entry*)malloc(sizeof(gs_list_entry) * this->BucketCapacity); - - u32 IndexOffset = (this->BucketCount - 1) * this->BucketCapacity; - for (u32 i = 0; i < this->BucketCapacity; i++) - { - NewBucket->Contents[i].Handle.Index = IndexOffset + i; - NewBucket->Contents[i].Handle.Generation = 0; - } -} - -template -gs_list_entry* gs_list::GetEntryAtIndex(u32 Index) -{ - gs_list_entry* Result = 0; - - u32 BucketIndex = Index / this->BucketCapacity; - u32 IndexInBucket = Index % this->BucketCapacity; - - Assert(BucketIndex < this->BucketCount); - Assert(IndexInBucket < this->BucketCapacity); // this should always be true no matter what - - Result = this->Buckets[BucketIndex].Contents + IndexInBucket; - return Result; - -} - -template -T* gs_list::GetElementAtIndex(u32 Index) -{ - T* Result = 0; - gs_list_entry* Entry = this->GetEntryAtIndex(Index); - Result = &Entry->Value; - return Result; -} - -template -T* gs_list::GetElementWithHandle(gs_list_handle Handle) -{ - T* Result = 0; - gs_list_entry* Entry = this->GetEntryAtIndex(Handle.Index); - if (Entry->Handle.Generation == Handle.Generation) - { - Result = &Entry->Value; - } - return Result; -} - -template -gs_list_entry* gs_list::TakeFreeEntry() -{ - gs_list_entry* FreeEntry = (gs_list_entry*)this->FreeList.Free.NextFreeEntry; - if (FreeEntry == 0 || this->BucketCapacity == 0 || this->BucketCount == 0) - { - this->FreeList.Free.NextFreeEntry = (u8*)&this->FreeList; - FreeEntry = (gs_list_entry*)this->FreeList.Free.NextFreeEntry; - } - - this->FreeList.Free.NextFreeEntry = FreeEntry->Free.NextFreeEntry; - if (FreeEntry == &this->FreeList) - { - if (this->Used >= this->BucketCapacity * this->BucketCount) - { - this->GrowList(); - } - FreeEntry = this->GetEntryAtIndex(this->OnePastLastUsed++); - } - Assert(FreeEntry != 0); - - FreeEntry->Handle.Generation++; - FreeEntry->Free.NextFreeEntry = 0; - - this->Used++; - - return FreeEntry; -} - -template -T* gs_list::TakeElement() -{ - T* Result = 0; - - gs_list_entry* FreeEntry = this->TakeFreeEntry(); - Result = &FreeEntry->Value; - - return Result; -} - -template -gs_list_handle gs_list::PushElementOnList(T Ele) -{ - gs_list_handle Result = {0}; - - gs_list_entry* FreeEntry = this->TakeFreeEntry(); - FreeEntry->Value = Ele; - Result = FreeEntry->Handle; - - return Result; -} - -template -void gs_list::FreeElementAtIndex(u32 Index) -{ - Assert(Index < this->BucketCapacity * this->BucketCount); - - gs_list_entry* EntryToFree = this->GetEntryAtIndex(Index); - - // If the entry has a value in NextFreeEntry, then it is already free - Assert(EntryToFree->Free.NextFreeEntry == 0); - - EntryToFree->Free.NextFreeEntry = this->FreeList.Free.NextFreeEntry; - this->FreeList.Free.NextFreeEntry = (u8*)EntryToFree; - - this->Used--; -} - -template -void gs_list::FreeElementWithHandle(gs_list_handle Handle) -{ - Assert(Handle.Index < this->BucketCapacity * this->BucketCount); - - gs_list_entry* EntryToFree = this->GetEntryAtIndex(Handle.Index); - - // If the entry has a value in NextFreeEntry, then it is already free - Assert(EntryToFree->Free.NextFreeEntry == 0); - - if (EntryToFree->Handle.Generation == Handle.Generation) - { - EntryToFree->Free.NextFreeEntry = this->FreeList.Free.NextFreeEntry; - this->FreeList.Free.NextFreeEntry = (u8*)EntryToFree; - this->Used--; - } -} diff --git a/src/gs_libs/gs_memory.h b/src/gs_libs/gs_memory.h deleted file mode 100644 index d72ac56..0000000 --- a/src/gs_libs/gs_memory.h +++ /dev/null @@ -1,528 +0,0 @@ -/* date = May 10th 2021 10:19 pm */ - -#ifndef GS_MEMORY_H -#define GS_MEMORY_H - -#if !defined(Assert) -# define Assert(c) -#endif - -#if !defined(InvalidCodePath) -# define InvalidCodePath -#endif - -#if !defined(GS_MEMORY_PROFILE_FUNC) -# define GS_MEMORY_PROFILE_FUNC -#endif - -#define MemoryClearArray(b,t,s) MemoryClear((u8*)(b), sizeof(t) * (s)) -internal void -MemoryClear(u8* Base, u64 Size) -{ - for (u64 i = 0; i < Size; i++) Base[i] = 0; -} - -#ifndef DEBUG_LOC - -typedef struct gs_debug_loc -{ - char* File; - char* Function; - u32 Line; -} gs_debug_loc; - -# define DEBUG_LOC gs_debug_loc{ (char*)__FILE__, (char*)__FUNCTION__, __LINE__ } - -#endif -// -// Debug Info -// - -typedef struct gs_debug_memory_allocation -{ - gs_debug_loc Loc; - u64 ArenaHash; - u64 Size; - - struct gs_debug_memory_allocation* Next; -} gs_debug_memory_allocation; - -typedef struct gs_debug_arena_info -{ - char* ArenaName; - u64 AllocationsCount; - u64 TotalSize; -} gs_debug_arena_info; - -typedef struct gs_debug_allocations_list -{ - gs_debug_memory_allocation* Root; - gs_debug_memory_allocation* Head; - u64 AllocationsSizeTotal; - u64 AllocationsCount; - - u64 ArenaHashesCount; - u64* ArenaHashes; - gs_debug_arena_info* ArenaInfos; -} gs_debug_allocations_list; - -// -// Allocator -// - -#define PLATFORM_ALLOC(name) void* name(u64 Size, u64* ResultSize, u8* UserData) -typedef PLATFORM_ALLOC(platform_alloc); - -#define PLATFORM_FREE(name) void name(void* Base, u64 Size, u8* UserData) -typedef PLATFORM_FREE(platform_free); - -typedef struct gs_allocator -{ - platform_alloc* PAlloc; - platform_free* PFree; - u8* UserData; - - gs_debug_allocations_list* DEBUGAllocList; -} gs_allocator; - -PLATFORM_ALLOC(AllocNoOp) -{ - GS_MEMORY_PROFILE_FUNC; - if (ResultSize) *ResultSize = 0; - return 0; -} - -PLATFORM_FREE(FreeNoOp) -{ - GS_MEMORY_PROFILE_FUNC; - return; -} - -internal u64 -GSMemoryHash(char* Str, u64 Len) -{ - u64 Hash = 5381; - for (u32 i = 0; i < Len; i++) - { - Hash = ((Hash << 5) + Hash) + Str[i]; - } - return Hash; -} - -#define Alloc(a,s,an) Alloc_((a),(s),DEBUG_LOC, (char*)(an)).Memory -#define AllocStruct(a,t,an) (t*)Alloc_((a),sizeof(t),DEBUG_LOC, (char*)(an)).Memory -#define AllocArray(a,t,c,an) (t*)Alloc_((a),sizeof(t)*(c),DEBUG_LOC, (char*)(an)).Memory -#define AllocData(a,s,an) Alloc_((a),(s),DEBUG_LOC, (char*)(an)) - -internal gs_data -Alloc_(gs_allocator A, u64 Size, gs_debug_loc Loc, char* ArenaName) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_data Result = {}; - Result.Memory = (u8*)A.PAlloc(Size, &Result.Size, A.UserData); - - // Debug - { - u64 ArenaHash = GSMemoryHash(ArenaName, CStringLength(ArenaName)); - - gs_debug_memory_allocation* Allocation = (gs_debug_memory_allocation*)A.PAlloc(sizeof(gs_debug_memory_allocation*), 0, A.UserData); - Allocation->Loc = Loc; - Allocation->Size = Size; - Allocation->ArenaHash = ArenaHash; - SLLPushOrInit(A.DEBUGAllocList->Root, A.DEBUGAllocList->Head, Allocation); - - A.DEBUGAllocList->AllocationsSizeTotal += Size; - A.DEBUGAllocList->AllocationsCount += 1; - - u64 ArenaStartIndex = ArenaHash % A.DEBUGAllocList->ArenaHashesCount; - u64 ArenaIndex = ArenaStartIndex; - while (A.DEBUGAllocList->ArenaHashes[ArenaIndex] != 0 && - A.DEBUGAllocList->ArenaHashes[ArenaIndex] != ArenaHash) - { - ArenaIndex = (ArenaIndex + 1) % A.DEBUGAllocList->ArenaHashesCount; - - // NOTE(PS): this means you've created enough arena's to fill up every - // slot in the arena hash table. Go increase the size of of DEBUG_ALLOCATOR_ARENA_MAX - Assert(ArenaIndex != ArenaStartIndex); - } - - if (A.DEBUGAllocList->ArenaHashes[ArenaIndex] == 0) - { - A.DEBUGAllocList->ArenaHashes[ArenaIndex] = ArenaHash; - - gs_debug_arena_info AI = {}; - AI.ArenaName = ArenaName; - A.DEBUGAllocList->ArenaInfos[ArenaIndex] = AI; - } - - A.DEBUGAllocList->ArenaInfos[ArenaIndex].AllocationsCount += 1; - A.DEBUGAllocList->ArenaInfos[ArenaIndex].TotalSize += Size; - } - - - - return Result; -} - -#define AllocString(a,s,l) AllocString_((a), (s), DEBUG_LOC, (l)) -internal gs_string -AllocString_(gs_allocator A, u64 Size, gs_debug_loc Loc, char* LocString) -{ - gs_string Result = {}; - Result.Str = (char*)Alloc_(A, sizeof(char)*Size, Loc, LocString).Memory; - Result.Length = 0; - Result.Size = Size; - return Result; -} - -#define Free(a,b,s) Free_((a),(b),(s),DEBUG_LOC) -#define FreeStruct(a,b,t) Free_((a),(u8*)(b),sizeof(t),DEBUG_LOC) -#define FreeArray(a,b,t,c) Free_((a),(u8*)(b),sizeof(t)*(c),DEBUG_LOC) -internal void -Free_(gs_allocator A, u8* Base, u64 Size, gs_debug_loc Loc) -{ - GS_MEMORY_PROFILE_FUNC; - - A.PFree(Base, Size, A.UserData); -} - -// NOTE(PS): cast function and struct pointers to proper data types -// for convenience -#define AllocatorCreate(a,f,u) AllocatorCreate_((platform_alloc*)(a),(platform_free*)(f),(u8*)(u)) -internal gs_allocator -AllocatorCreate_(platform_alloc* PAlloc, platform_free* PFree, u8* UserData) -{ - gs_allocator Result = {}; - Result.PAlloc = PAlloc; - Result.PFree = PFree; - Result.UserData = UserData; - - if (!PAlloc) Result.PAlloc = AllocNoOp; - if (!PFree) Result.PFree = FreeNoOp; - - // @DEBUG -#define DEBUG_ALLOCATOR_ARENA_MAX 256 - Result.DEBUGAllocList = (gs_debug_allocations_list*)PAlloc(sizeof(gs_debug_allocations_list*), 0, UserData); - - Result.DEBUGAllocList->ArenaHashesCount = DEBUG_ALLOCATOR_ARENA_MAX; - Result.DEBUGAllocList->ArenaHashes = (u64*)PAlloc(sizeof(u64*) * DEBUG_ALLOCATOR_ARENA_MAX, 0, UserData); - Result.DEBUGAllocList->ArenaInfos = (gs_debug_arena_info*)PAlloc(sizeof(gs_debug_arena_info) * DEBUG_ALLOCATOR_ARENA_MAX, 0, UserData); - return Result; -} - -// -// Memory Cursor -// - -typedef struct gs_memory_cursor -{ - gs_data Data; - u64 Position; -} gs_memory_cursor; - -internal gs_memory_cursor -MemoryCursorCreate(u8* Base, u64 Size) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_memory_cursor Result = {}; - Result.Data.Memory = Base; - Result.Data.Size = Size; - Result.Position = 0; - - return Result; -} -internal gs_memory_cursor -MemoryCursorCreateFromData(gs_data Data) -{ - GS_MEMORY_PROFILE_FUNC; - return MemoryCursorCreate(Data.Memory, Data.Size); -} - -internal u64 -MemoryCursorRoomLeft(gs_memory_cursor Cursor) -{ - GS_MEMORY_PROFILE_FUNC; - - u64 Result = 0; - if (Cursor.Data.Size >= Cursor.Position) - { - Result = Cursor.Data.Size - Cursor.Position; - } - return Result; -} - -internal bool -MemoryCursorHasRoom(gs_memory_cursor Cursor) -{ - GS_MEMORY_PROFILE_FUNC; - - u64 RoomLeft = MemoryCursorRoomLeft(Cursor); - bool Result = RoomLeft > 0; - return Result; -} - -internal bool -MemoryCursorCanPush(gs_memory_cursor Cursor, u64 Size) -{ - GS_MEMORY_PROFILE_FUNC; - - u64 RoomLeft = MemoryCursorRoomLeft(Cursor); - bool Result = RoomLeft >= Size; - return Result; -} - -#define MemoryCursorPushSize(c,s) MemoryCursorPushSize_((c),(s)) -#define MemoryCursorPushStruct(c,s) (s*)MemoryCursorPushSize_((c),sizeof(s)).Memory -#define MemoryCursorPushArray(c,s,l) (s*)MemoryCursorPushSize_((c),sizeof(s)*(l)).Memory -internal gs_data -MemoryCursorPushSize_(gs_memory_cursor* C, u64 Size) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_data Result = {0}; - if (MemoryCursorCanPush(*C, Size)) - { - Result.Memory = C->Data.Memory + C->Position; - Result.Size = Size, - C->Position += Size; - } - return Result; -} - -internal gs_data -MemoryCursorAlign(gs_memory_cursor* C, u64 Alignment) -{ - GS_MEMORY_PROFILE_FUNC; - - u64 Position = RoundUpTo64(C->Position, Alignment); - if (Position > C->Data.Size) - { - Position = C->Data.Size; - } - u64 AlignmentDist = Position - C->Position; - gs_data Result = MemoryCursorPushSize_(C, AlignmentDist); - return Result; -} - -#define MemoryCursorWriteValue(c,t,v) *PushStructOnCursor((c),(t)) = (v) -internal void -MemoryCursorWriteBuffer(gs_memory_cursor* C, gs_data Buffer) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_data Dest = MemoryCursorPushSize(C, Buffer.Size); - if (Dest.Size == Buffer.Size) - { - CopyMemoryTo(Buffer.Memory, Dest.Memory, Buffer.Size); - } -} - -internal void -MemoryCursorPopSize(gs_memory_cursor* C, u64 Size) -{ - GS_MEMORY_PROFILE_FUNC; - - u64 SizeToPop = Size; - if (SizeToPop > C->Position) - { - SizeToPop = C->Position; - } - - C->Position -= SizeToPop; -} - -internal void -MemoryCursorReset(gs_memory_cursor* C) -{ - GS_MEMORY_PROFILE_FUNC; - - C->Position = 0; -} - -// -// Memory Arena -// - -typedef struct gs_memory_cursor_sll -{ - gs_memory_cursor Cursor; - struct gs_memory_cursor_sll* Next; -} gs_memory_cursor_sll; - -typedef struct gs_memory_arena -{ - u64 ChunkSize; - u64 Alignment; - char* ArenaName; - - gs_memory_cursor_sll* CursorsRoot; - gs_memory_cursor_sll* CursorsHead; - - struct gs_memory_arena* Parent; - gs_allocator Allocator; - u8* UserData; - // TODO: some sort of GrowArena function -} gs_memory_arena; - -internal gs_memory_arena -MemoryArenaCreate(u64 ChunkSize, u64 Alignment, gs_allocator Allocator, gs_memory_arena* Parent, u8* UserData, char* Name) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_memory_arena Result = {}; - Result.ChunkSize = ChunkSize; - Result.Alignment = Alignment; - Result.Allocator = Allocator; - Result.Parent = Parent; - Result.UserData = UserData; - Result.ArenaName = Name; - - return Result; -} - -internal gs_data PushSize_(gs_memory_arena* Arena, u64 Size, gs_debug_loc Loc); - -internal gs_memory_cursor* -MemoryArenaPushCursor(gs_memory_arena* Arena, u64 MinSize, gs_debug_loc Loc) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_memory_cursor* Result = 0; - - u64 CursorSize = MinSize; - if (CursorSize < Arena->ChunkSize) - { - CursorSize = Arena->ChunkSize; - } - u64 AllocSize = CursorSize + sizeof(gs_memory_cursor_sll); - - gs_data CursorMemory = {0}; - if (Arena->Parent) - { - CursorMemory = PushSize_(Arena->Parent, AllocSize, Loc); - } else if (Arena->UserData) { - // TODO(PS): implement custom MemoryArenaAllocCursor functionality - InvalidCodePath; - } else { - Assert(Arena->Allocator.PAlloc); - CursorMemory = Alloc_(Arena->Allocator, AllocSize, Loc, Arena->ArenaName); - } - - gs_memory_cursor_sll* CursorEntry = (gs_memory_cursor_sll*)CursorMemory.Memory; - if (!Arena->CursorsRoot) - { - Arena->CursorsRoot = CursorEntry; - } - if (Arena->CursorsHead) - { - Arena->CursorsHead->Next = CursorEntry; - } - Arena->CursorsHead = CursorEntry; - - u8* CursorBase = (u8*)(CursorEntry + 1); - CursorEntry->Cursor = MemoryCursorCreate(CursorBase, CursorSize); - Result = &CursorEntry->Cursor; - - return Result; -} - -#define PushSize(a,s) PushSize_((a), (s), DEBUG_LOC) -#define PushStruct(a,t) (t*)PushSize_((a), sizeof(t), DEBUG_LOC).Memory -#define PushArray(a,t,c) (t*)PushSize_((a), sizeof(t) * (c), DEBUG_LOC).Memory -#define PushString(a,c) gs_string{ PushArray((a),char,(c)), 0, (c) } - -internal gs_data -PushSize_(gs_memory_arena* Arena, u64 Size, gs_debug_loc Loc) -{ - GS_MEMORY_PROFILE_FUNC; - - gs_data Result = {0}; - if (Size > 0) - { - gs_memory_cursor* Cursor = 0; - for (gs_memory_cursor_sll* C = Arena->CursorsRoot; - C != 0; - C = C->Next) - { - if (MemoryCursorCanPush(C->Cursor, Size)) - { - Cursor = &C->Cursor; - break; - } - } - - // NOTE(PS): We didn't find a cursor with enough room - // for the allocation being requested - if (!Cursor) - { - Cursor = MemoryArenaPushCursor(Arena, Size, Loc); - } - Assert(Cursor); - Assert(MemoryCursorCanPush(*Cursor, Size)); - - Result = MemoryCursorPushSize(Cursor, Size); - - gs_data Alignment = MemoryCursorAlign(Cursor, Arena->Alignment); - Result.Size += Alignment.Size; - } - return Result; -} - -internal void -MemoryArenaClear(gs_memory_arena* Arena) -{ - GS_MEMORY_PROFILE_FUNC; - - for (gs_memory_cursor_sll* C = Arena->CursorsRoot; - C != 0; - C = C->Next) - { - MemoryCursorReset(&C->Cursor); - } -} - -internal void -MemoryArenaFree(gs_memory_arena* Arena) -{ - GS_MEMORY_PROFILE_FUNC; - - // NOTE(PS): If this isn't a base arena, we can't - // really free it. - // TODO(PS): Once we have the User Specified codepaths - // in, we can probably provide a way for the user to - // let us free a custom allocator - Assert(Arena->Allocator.PFree); - - gs_allocator A = Arena->Allocator; - gs_memory_cursor_sll* At = Arena->CursorsRoot; - while (At) - { - gs_memory_cursor_sll* NextAt = At->Next; - - u64 Size = At->Cursor.Data.Size + sizeof(gs_memory_cursor_sll); - Free(A, (u8*)At, Size); - - At = NextAt; - } - - Arena->CursorsRoot = 0; - Arena->CursorsHead = 0; -} - -#ifdef GS_PLATFORM_IMPLEMENTATION - -internal gs_allocator CreatePlatformAllocator(); - -# if PLATFORM_WINDOWS -# include "./gs_memory_win32.h" -# elif PLATFORM_OSX -# include "./gs_memory_osx.h" -# elif PLATFORM_LINUX -# include "./gs_memory_linux.h" -# endif - -#endif - -#endif //GS_MEMORY_H diff --git a/src/gs_libs/gs_memory_arena.h b/src/gs_libs/gs_memory_arena.h deleted file mode 100644 index e4bad68..0000000 --- a/src/gs_libs/gs_memory_arena.h +++ /dev/null @@ -1,615 +0,0 @@ -// File: gs_memory_arena.h -// Description: Single header file library that defines a push-only memory arena -// Author: Peter Slattery -// Date Created: 2019-12-22 -// -// -// ----------------- -// Set Up -// ----------------- -// -// Include 'gs_memory_arena.h' in a file and start using it! (Simple! Nice!) -// -// ----------------- -// Usage -// ----------------- -// Simply create a memory_arena and use PushSize, PushStruct, or PushArray -// to allocate out of it. -// See Example Program below. -// -// While there are options you can set (see Options below), the library adheres -// to a 'zero-is-initialization' policy, that is, a memory_arena initialized to -// zero, under all default options, will 'just work'. -// -// Alignment: -// By default, the Push functions use 4 byte alignment -// If you need to control the alignment of an allocation, there are variants of the -// Push functions that allow for this: PushSizeAligned, PushStructAligned, and PushArrayAligned -// These functions simply take a final parameter which specifies the alignment. -// Note: Alignment must be a power of two -// -// ----------------- -// Options -// ----------------- -// -// DEBUG: -// Define DEBUG for debug functionality. -// -// To override the default assert function define GSMem_Assert(expression) -// before inluding this file. -// -// GS_MEMORY_NO_STD_LIBS: -// if you don't want stdlib.h to be included, define GS_MEMORY_NO_STD_LIBS -// before including this file. -// Note that if you do this, zero-is-initialization will no longer work for -// memory_arenas. You must either: -// 1. Set each memory_arena's Alloc and Realloc so they can grow fields -// 2. Set each memory_arena's ExpansionRule to ExpansionRule_Disallowed -// If DEBUG is defined, the program will assert if one of the 2 rules above -// aren't followed. -// -// memory_arena.Alloc and memory_arena.Realloc -// By default, memory_arena's will use malloc and realloc to grow. -// You can override this by setting the Alloc and Realloc function pointers -// of a memory_arena. See the example program below for an implementation of this. -// -// GS_MEMORY_BUFFER_SIZE: -// This defines the minimum buffer size for memory_arena's. If an arena doesn't have -// room to fit an allocation, it will allocate a new buffer no smaller than GS_MEMORY_BUFFER_SIZE -// and place the allocation in the new buffer. -// By default this is 4096 bytes. To override, define GS_MEMORY_BUFFER_SIZE before including -// this file -// -// GS_MEMORY_TRACK_ALLOCATIONS: -// If you want to keep records of each allocation performed in every arena, define -// GS_MEMORY_TRACK_ALLOCATIONS before including this file. -// When defined, memory arenas gain fields that allow them to keep a list of every -// allocation they contain. It also adds a footer on the end of each allocation that -// can be checked to ensure there are no writes to allocations that overflow their bounds -// Note that calling ClearArena also clears this list -// You can then call AssertAllocationsNoOverflow occasionally throughout your program -// to check that no allocations have been written beyond their boundaries -// -// -// Example Program -// (this compiles - copy it into its own file though) -#if 0 -// #include "gs_memory_arena.h" - -// Places the characters 'gs' at the end of each allocation. This would allow for an external -// function to check that we haven't written past the end of an allocation -void* MallocWrapper(gs_mem_u32 Size) -{ - int SizeWithFooter = Size + (sizeof(char) * 2); - void* Result = malloc(SizeWithFooter); - char* Footer = (char*)(Result + Size); - Footer[0] = 'g'; - Footer[1] = 's'; - return Result; -} - -void* ReallocWrapper(void* Address, gs_mem_u32 Size) -{ - return realloc(Address, Size); -} - -int -main(int ArgCount, char** Args) -{ - memory_arena Arena = {}; - // Uncomment these lines for an example of how you can implement custom allocation functions - // Arena.Alloc = MallocWrapper; - // Arena.Realloc = ReallocWrapper; - - int ArrayLength = 10; - - int* A = PushArray(&Arena, int, ArrayLength); - int* B = PushArray(&Arena, int, ArrayLength); - int* C = PushArray(&Arena, int, ArrayLength); - int* D = PushArrayAligned(&Arena, int, ArrayLength, 8); - int* E = PushArrayAligned(&Arena, int, ArrayLength, 16); - - // Just ensure that we can actually write to each address of each array - for (s32 i = 0; i < ArrayLength; i++) - { - A[i] = i; - B[i] = i; - C[i] = i; - D[i] = i; - E[i] = i; - } - - ClearArena(&Arena); - - A = PushArray(&Arena, int, ArrayLength); - for (s32 i = 0; i < ArrayLength; i++) - { - A[i] = i; - } - - return 0; -} -#endif - -// ------------------- -// Begin Library -// ------------------- -#ifndef GS_MEMORY_ARENA_H - -#ifndef GS_MEMORY_NO_STD_LIBS - -// NOTE(Peter): We use this so that we can fall back on malloc and realloc -// in the event that a memory_arena needs to grow but doesn't have a -// alloc or realloc function pointer assigned to it. -// -// See GrowArena to see where this is used -// -#include - -#endif - -typedef unsigned char gs_mem_u8; -typedef unsigned int gs_mem_u32; - -typedef unsigned long long int gs_mem_u64; - -#if DEBUG -#if !defined(GSMem_Assert) -#define GSMem_Assert(expression) \ -if((expression)) { \ -}else{ \ -volatile int* p = 0; \ -*p = 5; \ -} - -#endif -#else -#define GSMem_Assert(expression) -#endif - -enum gs_memory_expansion_rule -{ - MemoryExpansion_Allowed, // Zero is initialization lets the memory grow on its own - MemoryExpansion_OnlyIfFunctionsProvided, - MemoryExpansion_Disallowed, - MemoryExpansion_Count, -}; - -// NOTE(Peter): -// This rule is only here to allow for taking arena snapshots. The problem this solves -// is if you take a snapshot while there are 'holes' in memory_buffers behind the -// most recently added memory_buffer, take a snapshot of that arena, then push something -// on that fits in one of those holes, we will fill the hole and be unable to track/free -// that addition via the snapshot construct. -// -// By requiring that allocations in a buffer only come from the most recent memory_buffer -// we can very easily rewind the buffer to the correct location. -// Hence FindAddress_InLastBufferOnly -enum gs_memory_find_address_rule -{ - FindAddress_InAnyBuffer, - FindAddress_InLastBufferOnly, - FindAddress_Count, -}; - -#define PLATFORM_ALLOC(name) u8* name(s32 Size) -typedef PLATFORM_ALLOC(platform_alloc); - -#define PLATFORM_FREE(name) b32 name(u8* Base, s32 Size) -typedef PLATFORM_FREE(platform_free); - -#define PLATFORM_REALLOC(name) u8* name(u8* Base, u32 OldSize, u32 NewSize) -typedef PLATFORM_REALLOC(platform_realloc); - -struct platform_memory_handler -{ - platform_alloc* Alloc; - platform_free* Free; - platform_realloc* Realloc; -}; - -#ifndef GS_MEMORY_BUFFER_SIZE -#define GS_MEMORY_BUFFER_SIZE 1024 -#endif - -#define GS_MEMORY_FOOTER_SIZE 4 -#define GS_MEMORY_FOOTER_0 'g' -#define GS_MEMORY_FOOTER_1 's' -#define GS_MEMORY_FOOTER_2 'p' -#define GS_MEMORY_FOOTER_3 's' - -struct tracked_allocation -{ - gs_mem_u8* Head; - gs_mem_u8* Footer; - char* File; - gs_mem_u32 LineNumber; -}; - -#define GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE 512 -struct tracked_allocation_buffer -{ - tracked_allocation Buffer[GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE]; -}; - -struct memory_buffer -{ - gs_mem_u8* Buffer; - gs_mem_u32 Size; - gs_mem_u32 Used; -}; - -struct memory_arena -{ - memory_buffer* Buffers; - gs_mem_u32 BuffersCount; - - gs_mem_u32 TotalUsed; - gs_mem_u32 TotalSize; - - gs_memory_find_address_rule FindAddressRule; - gs_memory_expansion_rule ExpansionRule; - - platform_memory_handler PlatformMemory; - -#ifdef GS_MEMORY_TRACK_ALLOCATIONS - tracked_allocation_buffer** AllocationBuffers; - gs_mem_u32 AllocationBuffersCount; - gs_mem_u32 AllocationsUsed; -#endif -}; - -struct address_and_buffer -{ - memory_buffer* Buffer; - gs_mem_u64 Address; - gs_mem_u32 SizeWithAlignment; -}; - -struct arena_snapshot -{ - gs_mem_u32 ArenaUsedAtSnapshot; - gs_mem_u32 HeadBufferUsedAtSnapshot; - gs_mem_u32 HeadBufferAtSnapshot; - memory_arena* Arena; - -#ifdef GS_MEMORY_TRACK_ALLOCATIONS - gs_mem_u32 AllocationsUsedAtSnapshot; -#endif -}; - -#define PlatformFreeArray(platform, base, type, count) PlatformFree((platform), (gs_mem_u8*)(base), sizeof(type) * (count)) -#define ArenaFree(arena, base, size) PlatformFree((arena).PlatformMemory, (gs_mem_u8*)(base), (gs_mem_u32)(size)) -static void -PlatformFree(platform_memory_handler Platform, gs_mem_u8* Base, gs_mem_u32 Size) -{ - Assert(Platform.Free != 0); - Platform.Free(Base, Size); -} - -#define PlatformAllocArray(platform, type, size) (type*)PlatformAlloc((platform), sizeof(type) * (size)) -#define ArenaAlloc(arena, size) PlatformAlloc((arena).PlatformMemory, (gs_mem_u32)(size)) -#define ArenaAllocStruct(arena, type) (type*)PlatformAlloc((arena).PlatformMemory, sizeof(type)) -#define ArenaAllocArray(arena, type, size) (type*)PlatformAlloc((arena).PlatformMemory, sizeof(type) * (size)) -static gs_mem_u8* -PlatformAlloc(platform_memory_handler Platform, gs_mem_u32 Size) -{ - Assert(Platform.Alloc != 0); - gs_mem_u8* Result = Platform.Alloc(Size); - return Result; -} - -#define ArenaRealloc(arena, base, oldSize, newSize) PlatformRealloc((arena).PlatformMemory, (gs_mem_u8*)(base), (gs_mem_u32)(oldSize), (gs_mem_u32)(newSize)) -#define ArenaReallocArray(arena, base, type, oldCount, newCount) (type*)PlatformRealloc((arena).PlatformMemory, (gs_mem_u8*)(base), sizeof(type) * oldCount, sizeof(type) * newCount) -static gs_mem_u8* -PlatformRealloc(platform_memory_handler Platform, gs_mem_u8* Head, gs_mem_u32 OldSize, gs_mem_u32 NewSize) -{ - gs_mem_u8* Result = 0; - if (Platform.Realloc != 0) - { - Result = Platform.Realloc(Head, OldSize, NewSize); - } - else if (Platform.Alloc != 0 && Platform.Free != 0) - { - Result = PlatformAlloc(Platform, NewSize); - if (Head != 0 && OldSize != 0) - { - CopyMemoryTo(Head, Result, OldSize); - PlatformFree(Platform, Head, OldSize); - } - } - else - { - InvalidCodePath; - } - return Result; -} - -static void -FreeMemoryArena(memory_arena* Arena) -{ - for (gs_mem_u32 i = 0; i < Arena->BuffersCount; i++) - { - memory_buffer* Buffer = Arena->Buffers + i; - PlatformFree(Arena->PlatformMemory, Buffer->Buffer, Buffer->Size); - } - PlatformFree(Arena->PlatformMemory, (u8*)Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount); -} - -inline gs_mem_u32 -GetAlignmentOffset (gs_mem_u64 Address, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask) -{ - gs_mem_u32 AlignmentOffset = 0; - if (Address & AlignmentMask) - { - AlignmentOffset = Alignment - (Address & AlignmentMask); - } - return AlignmentOffset; -} - -static address_and_buffer -GetAlignedAddressInBuffer(memory_buffer* Buffer, gs_mem_u32 Size, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask) -{ - address_and_buffer Result = {}; - - gs_mem_u64 HeadAddress = (gs_mem_u64)Buffer->Buffer + Buffer->Used; - gs_mem_u32 AlignmentOffset = GetAlignmentOffset(HeadAddress, Alignment, AlignmentMask); - gs_mem_u64 AlignedAddress = HeadAddress + AlignmentOffset; - - if (Buffer->Used + AlignmentOffset + Size <= Buffer->Size) - { - Result.Buffer = Buffer; - Result.Address = AlignedAddress; - Result.SizeWithAlignment = Size + AlignmentOffset; - } - - return Result; -} - -static address_and_buffer -FindAlignedAddressInBufferWithRoom(memory_arena* Arena, gs_mem_u32 Size, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask) -{ - address_and_buffer Result = {}; - for (gs_mem_u32 i = 0; i < Arena->BuffersCount; i++) - { - memory_buffer* At = Arena->Buffers + i; - GSMem_Assert(At); - - address_and_buffer AddressInCurrentBuffer = GetAlignedAddressInBuffer(At, Size, Alignment, AlignmentMask); - if (AddressInCurrentBuffer.Address != 0) - { - Result = AddressInCurrentBuffer; - break; - } - } - return Result; -} - -static memory_buffer* -GrowArena(memory_arena* Arena, gs_mem_u32 SizeNeeded) -{ - GSMem_Assert(Arena->ExpansionRule != MemoryExpansion_Disallowed); - - gs_mem_u32 NewBuffersCount = (Arena->BuffersCount + 1); -#if 0 - gs_mem_u32 OldBuffersSize = sizeof(memory_buffer) * Arena->BuffersCount; - gs_mem_u32 NewBuffersSize = sizeof(memory_buffer) * NewBuffersCount; -#endif - Arena->Buffers = ArenaReallocArray(*Arena, Arena->Buffers, memory_buffer, Arena->BuffersCount, NewBuffersCount); - Arena->BuffersCount = NewBuffersCount; - - memory_buffer* NewBuffer = Arena->Buffers + (Arena->BuffersCount - 1); - NewBuffer->Size = GS_MEMORY_BUFFER_SIZE; - if (SizeNeeded > NewBuffer->Size) - { - NewBuffer->Size = SizeNeeded; - } - - NewBuffer->Buffer = ArenaAllocArray(*Arena, gs_mem_u8, NewBuffer->Size); - NewBuffer->Used = 0; - - Arena->TotalSize += NewBuffer->Size; - return NewBuffer; -} - -#ifdef GS_MEMORY_TRACK_ALLOCATIONS - -#define DetermineAllocationSize(size) (size) + GS_MEMORY_FOOTER_SIZE -#define ClearAllocationsUsed(arena) (arena)->AllocationsUsed = 0 -#define ClearAllocationsUsedToSnapshot(arena, snapshot) \ -(arena)->AllocationsUsed = (snapshot).AllocationsUsedAtSnapshot; - -static void -TrackAllocation(memory_arena* Arena, gs_mem_u8* Head, gs_mem_u32 Size, char* Filename, gs_mem_u32 LineNumber) -{ - gs_mem_u32 AllocationsMax = Arena->AllocationBuffersCount * GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE; - if (Arena->AllocationsUsed >= AllocationsMax) - { - gs_mem_u32 NewAllocationBuffersCount = Arena->AllocationBuffersCount + 1; -#if 0 - gs_mem_u32 OldSize = Arena->AllocationBuffersCount * sizeof(void*); - gs_mem_u32 NewSize = NewAllocationBuffersCount * sizeof(void*); - Arena->AllocationBuffers = (tracked_allocation_buffer**)PlatformRealloc(Arena->PlatformMemory, - (gs_mem_u8*)Arena->AllocationBuffers, - OldSize, NewSize); -#else - Arena->AllocationBuffers = ArenaReallocArray(*Arena, Arena->AllocationBuffers, tracked_allocation_buffer*, Arena->AllocationBuffersCount, NewAllocationBuffersCount); -#endif - - Arena->AllocationBuffersCount = NewAllocationBuffersCount; - - gs_mem_u32 NewBufferIndex = Arena->AllocationBuffersCount - 1; - Arena->AllocationBuffers[NewBufferIndex] = ArenaAllocStruct(*Arena, tracked_allocation_buffer); - } - - gs_mem_u32 AllocationIndex = Arena->AllocationsUsed++; - gs_mem_u32 BufferIndex = AllocationIndex / GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE; - gs_mem_u32 IndexInBuffer = AllocationIndex % GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE; - tracked_allocation_buffer* Buffer = Arena->AllocationBuffers[BufferIndex]; - tracked_allocation* NewAllocationTracker = Buffer->Buffer + IndexInBuffer; - - NewAllocationTracker->Head = Head; - - NewAllocationTracker->Footer = Head + Size - GS_MEMORY_FOOTER_SIZE; - NewAllocationTracker->Footer[0] = GS_MEMORY_FOOTER_0; - NewAllocationTracker->Footer[1] = GS_MEMORY_FOOTER_1; - NewAllocationTracker->Footer[2] = GS_MEMORY_FOOTER_2; - NewAllocationTracker->Footer[3] = GS_MEMORY_FOOTER_3; - - NewAllocationTracker->File = Filename; - NewAllocationTracker->LineNumber = LineNumber; -} - -inline bool -VerifyAllocationNoOverflow (tracked_allocation Allocation) -{ - bool Result = ((Allocation.Footer[0] == GS_MEMORY_FOOTER_0) && - (Allocation.Footer[1] == GS_MEMORY_FOOTER_1) && - (Allocation.Footer[2] == GS_MEMORY_FOOTER_2) && - (Allocation.Footer[3] == GS_MEMORY_FOOTER_3)); - return Result; -} - -static void -AssertAllocationsNoOverflow (memory_arena Arena) -{ - for (gs_mem_u32 AllocationIndex = 0; - AllocationIndex< Arena.AllocationsUsed; - AllocationIndex++) - { - gs_mem_u32 BufferIndex = AllocationIndex / GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE; - gs_mem_u32 IndexInBuffer = AllocationIndex % GS_MEM_TRACKED_ALLOCATION_BUFFER_SIZE; - - tracked_allocation_buffer* Buffer = Arena.AllocationBuffers[BufferIndex]; - tracked_allocation Allocation = Buffer->Buffer[IndexInBuffer]; - - GSMem_Assert(VerifyAllocationNoOverflow(Allocation)); - } -} - -#define PushSize(arena, size) PushSize_((arena), (size), 4, __FILE__, __LINE__) -#define PushArray(arena, type, length) (type*)PushSize_((arena), sizeof(type) * length, 4, __FILE__, __LINE__) -#define PushStruct(arena, type) (type*)PushSize_((arena), sizeof(type), 4, __FILE__, __LINE__) -#define PushSizeAligned(arena, size, alignment) PushSize_((arena), (size), (alignment), __FILE__, __LINE__) -#define PushArrayAligned(arena, type, length, alignment) (type*)PushSize_((arena), sizeof(type) * length, (alignment), __FILE__, __LINE__) -#define PushStructAligned(arena, type, alignment) (type*)PushSize_((arena), sizeof(type), (alignment), __FILE__, __LINE__) - -#else // GS_MEMORY_TRACK_ALLOCATIONS - -#define AssertAllocationsNoOverflow(arena) -#define DetermineAllocationSize(size) size -#define ClearAllocationsUsed(arena) -#define ClearAllocationsUsedToSnapshot(arena, snapshot) - -#define TrackAllocation(arena, head, size, filename, linenumber) - -#define PushSize(arena, size) PushSize_((arena), (size)) -#define PushArray(arena, type, length) (type*)PushSize_((arena), sizeof(type) * length) -#define PushStruct(arena, type) (type*)PushSize_((arena), sizeof(type)) -#define PushSizeAligned(arena, size, alignment) PushSize_((arena), (size), (alignment)) -#define PushArrayAligned(arena, type, length, alignment) (type*)PushSize_((arena), sizeof(type) * length, (alignment)) -#define PushStructAligned(arena, type, alignment) (type*)PushSize_((arena), sizeof(type), (alignment)) - -#endif // GS_MEMORY_TRACK_ALLOCATIONS - -static gs_mem_u8* -PushSize_(memory_arena* Arena, gs_mem_u32 Size, gs_mem_u32 Alignment = 4, char* Filename = 0, gs_mem_u32 LineNumber = 0) -{ - // ie. Alignment = 4 = 100 (binary) - // 4 - 1 = 3 - // 100 - 1 = 011 which is a mask of the bits we don't want set in the start address - GSMem_Assert(IsPowerOfTwo(Alignment)); - gs_mem_u32 AlignmentMask = Alignment - 1; - - gs_mem_u32 AllocationSize = DetermineAllocationSize(Size); - - address_and_buffer ResultAddress = {}; - if (Arena->FindAddressRule == FindAddress_InAnyBuffer) - { - ResultAddress = FindAlignedAddressInBufferWithRoom(Arena, AllocationSize, Alignment, AlignmentMask); - } - else if (Arena->FindAddressRule == FindAddress_InLastBufferOnly - && Arena->BuffersCount > 0) - { - memory_buffer* LastBuffer = Arena->Buffers + Arena->BuffersCount - 1; - ResultAddress = GetAlignedAddressInBuffer(LastBuffer, Size, Alignment, AlignmentMask); - } - - if (ResultAddress.Address == 0) - { - memory_buffer* Buffer = GrowArena(Arena, AllocationSize); - ResultAddress = GetAlignedAddressInBuffer(Buffer, AllocationSize, Alignment, AlignmentMask); - } - GSMem_Assert(ResultAddress.Address != 0); - GSMem_Assert((ResultAddress.Address & AlignmentMask) == 0); - - gs_mem_u8* Result = (gs_mem_u8*)ResultAddress.Address; - ResultAddress.Buffer->Used += ResultAddress.SizeWithAlignment; - Arena->TotalUsed += ResultAddress.SizeWithAlignment; - - TrackAllocation(Arena, Result, AllocationSize, Filename, LineNumber); - - return Result; -} - -static void -ClearArena(memory_arena* Arena) -{ - for (gs_mem_u32 i = 0; i < Arena->BuffersCount; i++) - { - memory_buffer* At = Arena->Buffers + i; - At->Used = 0; - } - - Arena->TotalUsed = 0; - ClearAllocationsUsed(Arena); -} - -static arena_snapshot -TakeSnapshotOfArena(memory_arena* Arena) -{ - GSMem_Assert(Arena->FindAddressRule == FindAddress_InLastBufferOnly); - - arena_snapshot Result = {}; - Result.Arena = Arena; - Result.ArenaUsedAtSnapshot = Arena->TotalUsed; - if (Arena->BuffersCount > 0) - { - Result.HeadBufferAtSnapshot = Arena->BuffersCount - 1; - } - else - { - Result.HeadBufferAtSnapshot = 0; - } - - memory_buffer* HeadBuffer = Arena->Buffers + Result.HeadBufferAtSnapshot; - if (HeadBuffer) - { - Result.HeadBufferUsedAtSnapshot = HeadBuffer->Used; - } - - return Result; -} - -static void -ClearArenaToSnapshot(memory_arena* Arena, arena_snapshot Snapshot) -{ - GSMem_Assert(Arena == Snapshot.Arena); - - memory_buffer* HeadBufferAtSnapshot = Arena->Buffers + Snapshot.HeadBufferAtSnapshot; - if (HeadBufferAtSnapshot) - { - HeadBufferAtSnapshot->Used = Snapshot.HeadBufferUsedAtSnapshot; - - for (gs_mem_u32 i = Snapshot.HeadBufferAtSnapshot + 1; i < Arena->BuffersCount; i++) - { - memory_buffer* Buffer = Arena->Buffers + i; - Buffer->Used = 0; - } - } - - Arena->TotalUsed = Snapshot.ArenaUsedAtSnapshot; - ClearAllocationsUsedToSnapshot(Arena, Snapshot); -} -#define GS_MEMORY_ARENA_H -#endif // GS_MEMORY_ARENA_H \ No newline at end of file diff --git a/src/gs_libs/gs_path.h b/src/gs_libs/gs_path.h deleted file mode 100644 index ebcbb7b..0000000 --- a/src/gs_libs/gs_path.h +++ /dev/null @@ -1,106 +0,0 @@ -// -// File: gs_path.h -// Author: Peter Slattery -// Creation Date: 2021-03-06 -// -#ifndef GS_PATH_H - -internal gs_const_string -ClearString() -{ - gs_const_string R = {}; - R.Str = 0; - R.Length = 0; - return R; -} - -internal void -SanitizePath (gs_const_string Path, gs_string* Dest, gs_memory_arena* Scratch) -{ - Dest->Length = 0; - - // Put all slashes in the same format - s32 SlashCount = 0; - for (u64 i = 0; i < Path.Length; i++) - { - char At = Path.Str[i]; - if (At == '\\' || At == '/') { - SlashCount += 1; - } - } - - // we add one to slash count in case the last element is a file or - // doesn't end in a slash (even if it should) - u32 PathEleCountMax = SlashCount + 1; - u32 PathEleCount = 0; - gs_const_string* PathEle = PushArray(Scratch, gs_const_string, PathEleCountMax); - - u64 OnePastLastEleEnd = 0; - for (s64 i = 0; i < (s64)Path.Length; i++) - { - char At = Path.Str[i]; - if (At == '\\' || At == '/') - { - gs_const_string* NewEle = PathEle + PathEleCount++; - *NewEle = Substring(Path, OnePastLastEleEnd, i + 1); - OnePastLastEleEnd = i + 1; - } - } - - if (OnePastLastEleEnd != Path.Length) - { - gs_const_string* NewEle = PathEle + PathEleCount++; - *NewEle = Substring(Path, OnePastLastEleEnd, Path.Length); - OnePastLastEleEnd = Path.Length; - } - - // Remove redundant elements - for (u32 i = 0; i < PathEleCount; i++) - { - gs_const_string* At = PathEle + i; - bool ShouldRemove = false; - if (i != 0) - { - if (StringsEqual(*At, ConstString(".\\")) || - StringsEqual(*At, ConstString("./"))) - { - *At = ClearString(); - } - else if (StringsEqual(*At, ConstString("..\\")) || - StringsEqual(*At, ConstString("../"))) - { - PathEle[i - 1] = ClearString(); - if (i != 1) { - PathEle[i] = ClearString(); - } - } - } - } - - for (u32 i = 0; i < PathEleCount; i++) - { - if (PathEle[i].Str) { - AppendPrintF(Dest, "%S", PathEle[i]); - } - } - - // Put all slashes in the same format - for (u64 i = 0; i < Dest->Length; i++) - { - if (Dest->Str[i] == '/') { - Dest->Str[i] = '\\'; - } - } -} - -internal gs_const_string -SanitizePath (gs_const_string Path, gs_memory_arena* Scratch) -{ - gs_string Result = PushString(Scratch, Path.Length); - SanitizePath(Path, &Result, Scratch); - return Result.ConstString; -} - - -#define GS_PATH_H -#endif // GS_PATH_H \ No newline at end of file diff --git a/src/gs_libs/gs_profiler.h b/src/gs_libs/gs_profiler.h deleted file mode 100644 index 843c58f..0000000 --- a/src/gs_libs/gs_profiler.h +++ /dev/null @@ -1,275 +0,0 @@ -// -// File: gs_profiler.h -// Author: Peter Slattery -// Creation Date: 2020-05-11 -// -#ifndef GS_PROFILER_H - -internal s64 -GetWallClock() -{ - LARGE_INTEGER Time; - if (!QueryPerformanceCounter(&Time)) - { - s32 Error = GetLastError(); - // TODO(Peter): I'm waiting to see an error actually occur here - // to know what it could possibly be. - InvalidCodePath; - } - return (s64)Time.QuadPart; -} - -internal u64 -HashDJB2ToU64(char* String) -{ - u64 Hash = 5381; - char* C = String; - while(*C) - { - Hash = ((Hash << 5) + Hash) + *C++; - } - return Hash; -} - -struct scope_record -{ - u64 IdentifierHash; - s64 StartTime; - s64 EndTime; -}; - -struct scope_record_list -{ - scope_record* List; - u32 Count; - u32 MaxCount; - scope_record_list* Next; -}; - -struct collated_scope_record -{ - char* Identifier; - u64 CallCount; - u64 TotalCycles; - u64 LongestDuration; -}; - -#define COLLATED_SCOPES_HASH_SIZE 1024 -struct collated_scopes_hash_table -{ - u64* Hashes; - collated_scope_record* Scopes; - collated_scopes_hash_table* Next; -}; - -struct debug_services -{ - memory_arena Arena; - memory_arena Transient; - bool ShouldProfile; - - u32 CollatedScopesCount; - collated_scopes_hash_table* CollatedScopes; - - scope_record_list* ScopeRecordsHead; - scope_record_list* ScopeRecordsTail; -}; - -global_variable debug_services GlobalDebugServices = {0}; - -internal u64 -RegisterScope(debug_services* Services, char* Identifier) -{ - u64 Hash = HashDJB2ToU64(Identifier); - u32 Index = (u32)(Hash % COLLATED_SCOPES_HASH_SIZE); - - collated_scopes_hash_table* PrevTable = 0; - collated_scopes_hash_table* TableAt = Services->CollatedScopes; - while (TableAt != 0) - { - if (TableAt->Hashes[Index] == Hash || TableAt->Hashes[Index] == 0) - { - break; - } - PrevTable = TableAt; - TableAt = TableAt->Next; - } - - if (!TableAt) - { - collated_scopes_hash_table* NewTable = PushStruct(&Services->Arena, collated_scopes_hash_table); - NewTable->Hashes = PushArray(&Services->Arena, u64, COLLATED_SCOPES_HASH_SIZE); - GSZeroMemory(NewTable->Hashes, sizeof(u64) * COLLATED_SCOPES_HASH_SIZE); - NewTable->Scopes = PushArray(&Services->Arena, collated_scope_record, COLLATED_SCOPES_HASH_SIZE); - NewTable->Next = 0; - - if (PrevTable) - { - PrevTable->Next = NewTable; - } - else - { - Services->CollatedScopes = NewTable; - } - - TableAt = NewTable; - } - - if (TableAt->Hashes[Index] == 0) - { - // New Scope Being Registered - TableAt->Hashes[Index] = Hash; - TableAt->Scopes[Index] = {0}; - TableAt->Scopes[Index].Identifier = Identifier; - Services->CollatedScopesCount++; - } - else if (TableAt->Hashes[Index] != Hash) - { - InvalidCodePath; - } - - return Hash; -} - -internal void -PushScopeOnList(debug_services* Services, char* ScopeName, s64 Start, s64 End) -{ - if (!Services->ScopeRecordsTail || - Services->ScopeRecordsTail->Count >= Services->ScopeRecordsTail->MaxCount) - { - scope_record_list* NewTail = PushStruct(&Services->Arena, scope_record_list); - NewTail->MaxCount = 4096; - NewTail->List = PushArray(&Services->Arena, scope_record, NewTail->MaxCount); - NewTail->Count = 0; - NewTail->Next = 0; - - if (Services->ScopeRecordsHead) - { - Services->ScopeRecordsTail->Next = NewTail; - } - else - { - Services->ScopeRecordsHead = NewTail; - } - Services->ScopeRecordsTail = NewTail; - } - - u32 NewRecordIndex = Services->ScopeRecordsTail->Count++; - - scope_record* NewRecord = &Services->ScopeRecordsTail->List[NewRecordIndex]; - NewRecord->IdentifierHash = RegisterScope(Services, ScopeName); - NewRecord->StartTime = Start; - NewRecord->EndTime = End; -} - -#define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, &GlobalDebugServices) -struct scope_tracker -{ - s64 ScopeStart; - char* ScopeName; - debug_services* Services; - scope_tracker(char* ScopeName, debug_services* Services) - { - if (Services && Services->ShouldProfile) - { - this->ScopeName = ScopeName; - this->ScopeStart = GetWallClock(); - this->Services = Services; - } - else - { - this->Services = 0; - } - } - - ~scope_tracker() - { - if (this->Services != 0) - { - s64 ScopeEnd = GetWallClock(); - PushScopeOnList(&GlobalDebugServices, this->ScopeName, this->ScopeStart, ScopeEnd); - } - } -}; - -// -// Reporting -// - -internal collated_scope_record* -GetCollatedRecordForScope(debug_services* Services, u64 Hash) -{ - Assert(Services->CollatedScopes); - collated_scope_record* Result = 0; - u64 Index = Hash % COLLATED_SCOPES_HASH_SIZE; - - collated_scopes_hash_table* TableAt = Services->CollatedScopes; - while (TableAt != 0) - { - if (TableAt->Hashes[Index] == Hash) - { - Result = TableAt->Scopes + Index; - break; - } - TableAt = TableAt->Next; - } - return Result; -} - -internal void -CollateFrame(debug_services* Services) -{ - scope_record_list* ListAt = Services->ScopeRecordsHead; - while (ListAt != 0) - { - for (u32 i = 0; i < ListAt->Count; i++) - { - scope_record ScopeAt = ListAt->List[i]; - u64 ScopeAtDuration = ScopeAt.EndTime - ScopeAt.StartTime; - - collated_scope_record* CollatedScopeData = GetCollatedRecordForScope(Services, ScopeAt.IdentifierHash); - Assert(CollatedScopeData != 0); - CollatedScopeData->CallCount++; - CollatedScopeData->TotalCycles += ScopeAtDuration; - CollatedScopeData->LongestDuration = GSMax(ScopeAtDuration, CollatedScopeData->LongestDuration); - } - ListAt = ListAt->Next; - } - - u32 SortListCount = Services->CollatedScopesCount; - gs_radix_entry* SortList = PushArray(&Services->Transient, gs_radix_entry, SortListCount); - - u32 SortListAt = 0; - collated_scopes_hash_table* TableAt = Services->CollatedScopes; - while (TableAt != 0) - { - for (u32 i = 0; i < COLLATED_SCOPES_HASH_SIZE; i++) - { - if (TableAt->Hashes[i] == 0) { continue; } - SortList[SortListAt].ID = TableAt->Hashes[i]; - SortList[SortListAt].Radix = TableAt->Scopes[i].TotalCycles; - SortListAt += 1; - } - TableAt = TableAt->Next; - } - - RadixSortInPlace(SortList, SortListCount); - - for (s32 i = SortListCount - 1; i >= 0; i--) - { - u64 Hash = SortList[i].ID; - collated_scope_record* ScopeData = GetCollatedRecordForScope(Services, Hash); - - u64 AverageDuration = ScopeData->TotalCycles / ScopeData->CallCount; - - printf("Scope: %s\n", ScopeData->Identifier); - printf(" %d / %d\n", SortListCount - i, SortListCount); - printf(" Total Cycles: %lld\n", ScopeData->TotalCycles); - printf(" Call Count: %lld\n", ScopeData->CallCount); - printf(" Longest Duration: %lld\n", ScopeData->LongestDuration); - printf(" Average Duration: %lld\n", AverageDuration); - } -} - -#define GS_PROFILER_H -#endif // GS_PROFILER_H \ No newline at end of file diff --git a/src/gs_libs/gs_radix_sort.h b/src/gs_libs/gs_radix_sort.h deleted file mode 100644 index cf4464d..0000000 --- a/src/gs_libs/gs_radix_sort.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -gs_radix_sort.h - An implementation of radix sort for fixed size unsigned 32bit integer buffers - -*/ - -#ifndef GS_RADIX_SORT_H - -#if DEBUG -#if !defined(GSRad_Assert) -#define GSRad_Assert(expression) \ -if(!(expression)) { \ -*((int *)0) = 5; \ -} -#endif // !defined(GSRad_Assert) -#endif // DEBUG - -typedef unsigned int gs_rad_u32; -typedef unsigned int gs_rad_b32; - -struct gs_radix_entry -{ - gs_rad_u32 Radix; - gs_rad_u32 ID; -}; - -static void -RadixSortInPlace_ (gs_radix_entry* Data, gs_rad_u32 Start, gs_rad_u32 End, gs_rad_u32 Iteration) -{ - gs_rad_u32 Shift = Iteration; - gs_rad_u32 ZerosBoundary = Start; - gs_rad_u32 OnesBoundary = End - 1; - - for (gs_rad_u32 d = Start; d < End; d++) - { - gs_radix_entry Entry = Data[ZerosBoundary]; - gs_rad_u32 Place = (Entry.Radix >> Shift) & 0x1; - if (Place) - { - gs_radix_entry Evicted = Data[OnesBoundary]; - Data[OnesBoundary] = Entry; - Data[ZerosBoundary] = Evicted; - OnesBoundary -= 1; - } - else - { - ZerosBoundary += 1; - } - } - - if (Iteration > 0) - { - RadixSortInPlace_(Data, Start, ZerosBoundary, Iteration - 1); - RadixSortInPlace_(Data, ZerosBoundary, End, Iteration - 1); - } -} - -static void -RadixSortInPlace (gs_radix_entry* Data, gs_rad_u32 Count) -{ - gs_rad_u32 Highest = 0; - for (gs_rad_u32 i = 0; i < Count; i++) - { - if (Data[i].Radix > Highest) - { - Highest = Data[i].Radix; - } - } - - gs_rad_u32 Iterations = 0; - while (Highest > 1) - { - ++Iterations; - Highest = Highest >> 1; - } - - RadixSortInPlace_(Data, 0, Count, Iterations); -} - -#define GS_RADIX_SORT_H -#endif // GS_RADIX_SORT_H \ No newline at end of file diff --git a/src/gs_libs/gs_string.h b/src/gs_libs/gs_string.h deleted file mode 100644 index 6b4efca..0000000 --- a/src/gs_libs/gs_string.h +++ /dev/null @@ -1,318 +0,0 @@ -// TODO -/* -- InsertCharArrayIntoStringAt -- AppendChar -*/ -#ifndef GS_STRING_H -#include - -//////////////////////////////////////////////////////////////// -// String Tokenizing -//////////////////////////////////////////////////////////////// - -struct tokenizer -{ - char* At; - char* LineStart; - - char* Memory; - s32 MemoryLength; - u32 LineNumber; -}; - -enum token_type -{ - Token_Error, - - Token_LeftParen, - Token_RightParen, - Token_LeftSquareBracket, - Token_RightSquareBracket, - Token_LeftCurlyBracket, - Token_RightCurlyBracket, - Token_Semicolon, - Token_Operator, - Token_Comma, - Token_Period, - Token_PointerReference, - - Token_PoundDefine, // Must stay first preproc token type - Token_PoundUndef, - Token_PoundInclude, - Token_PoundIfDef, - Token_PoundIfNDef, - Token_PoundIf, - Token_PoundElif, - Token_PoundElse, - Token_PoundEndif, - Token_PoundError, - Token_PoundPragma, - Token_PoundLine, // Must stay Last Preproc Token Type - - Token_Number, - Token_Char, - Token_String, - Token_Identifier, - - Token_Comment, - Token_MultilineComment, - - Token_EndOfLine, - - Token_Unknown, - Token_EndOfStream, -}; - -char* TokenNames[] = { - "Token_Error", - "Token_LeftParen", - "Token_RightParen", - "Token_LeftSquareBracket", - "Token_RightSquareBracket", - "Token_LeftCurlyBracket", - "Token_RightCurlyBracket", - "Token_Semicolon", - "Token_Operator", - "Token_Comma", - "Token_Period", - "Token_PointerReference", - "Token_PoundDefine", - "Token_PoundUndef", - "Token_PoundInclude", - "Token_PoundIfDef", - "Token_PoundIfNDef", - "Token_PoundIf", - "Token_PoundElif", - "Token_PoundElse", - "Token_PoundEndif", - "Token_PoundError", - "Token_PoundPragma", - "Token_PoundLine", - "Token_Number", - "Token_Char", - "Token_String", - "Token_Identifier", - "Token_Comment", - "Token_MultilineComment", - "Token_EndOfLine", - "Token_Unknown", - "Token_EndOfStream", -}; - -struct token -{ - token_type Type; - u32 LineNumber; - gs_string Text; - token* Next; // TODO(Peter): Get rid of this -}; - -//////////////////////////////////////////////////////////////// -// String Function Declarations -//////////////////////////////////////////////////////////////// - -// Tokenizing -static void EatChar(tokenizer* T); -static b32 AtValidPosition(tokenizer Tokenizer); -static b32 AtValidToken(tokenizer Tokenizer); -static char* EatToNewLine(char* C); -static s32 EatToNewLine(tokenizer* T); -static char* EatPastNewLine(char* C); -static s32 EatPastNewLine(tokenizer* T); -static char* EatWhitespace(char* C); -static s32 EatWhitespace(tokenizer* T); -static char* EatToNonWhitespaceOrNewline(char* C); -static s32 EatToNonWhitespaceOrNewline(tokenizer* T); -static char* EatToWhitespace(char* C); -static s32 EatToWhitespace(tokenizer* T); -static char* EatToCharacter(char* C, char Char); -static s32 EatToCharacter(tokenizer* T, char Char); -static char* EatPastCharacter(char* C, char Char); -static s32 EatPastCharacter(tokenizer* T, char Char); -static char* EatNumber(char* C); -static s32 EatNumber(tokenizer* T); - -//////////////////////////////////////////////////////////////// -// Tokenizing -//////////////////////////////////////////////////////////////// - -static void -EatChar (tokenizer* T) -{ - if (AtValidPosition(*T)) - { - if (IsNewline(*T->At)) - { - T->LineNumber++; - T->At++; - T->LineStart = T->At; - } - else - { - T->At++; - } - } -} - -static b32 -AtValidPosition (tokenizer Tokenizer) -{ - b32 Result = (Tokenizer.At - Tokenizer.Memory) <= Tokenizer.MemoryLength; - return Result; -} - -static b32 -AtValidToken(tokenizer Tokenizer) -{ - b32 Result = *Tokenizer.At && Tokenizer.At < (Tokenizer.Memory + Tokenizer.MemoryLength); - return Result; -} - -static char* -EatToNewLine(char* C) -{ - char* Result = C; - while (*Result && !IsNewline(*Result)) - { - Result++; - } - return Result; -} - -static s32 -EatToNewLine(tokenizer* T) -{ - char* TStart = T->At; - while (AtValidPosition(*T) && !IsNewline(*T->At)) - { - EatChar(T); - } - return T->At - TStart; -} - -static char* -EatPastNewLine(char* C) -{ - char* Result = EatToNewLine(C); - while(*Result && IsNewline(*Result)) - { - Result++; - } - return Result; -} - -static s32 -EatPastNewLine(tokenizer* T) -{ - char* TStart = T->At; - - EatToNewLine(T); - while(AtValidPosition(*T) && IsNewline(*T->At)) - { - EatChar(T); - } - - return T->At - TStart; -} - -static char* -EatWhitespace(char* C) -{ - char* Result = C; - while (*Result && IsNewlineOrWhitespace(*Result)) { Result++; } - return Result; -} - -static s32 -EatWhitespace(tokenizer* T) -{ - char* TStart = T->At; - while (AtValidPosition(*T) && IsNewlineOrWhitespace(*T->At)) { EatChar(T); } - return T->At - TStart; -} - -static char* -EatToNonWhitespaceOrNewline(char* C) -{ - char* Result = C; - while (*Result && IsWhitespace(*Result)) { Result++; } - return Result; -} - -static s32 -EatToNonWhitespaceOrNewline(tokenizer* T) -{ - char* TStart = T->At; - while (AtValidPosition(*T) && IsWhitespace(*T->At)) { EatChar(T); } - return T->At - TStart; -} - -static char* -EatToWhitespace(char* C) -{ - char* Result = C; - while (*Result && !IsWhitespace(*Result)) { Result++; } - return Result; -} - -static s32 -EatToWhitespace(tokenizer* T) -{ - char* TStart = T->At; - while (AtValidPosition(*T) && !IsWhitespace(*T->At)) { EatChar(T); } - return T->At - TStart; -} - -static char* -EatToCharacter(char* C, char Char) -{ - char* Result = C; - while (*Result && *Result != Char) { Result++; } - return Result; -} - -static s32 -EatToCharacter(tokenizer* T, char Char) -{ - char* TStart = T->At; - while (AtValidPosition(*T) && *T->At != Char) { EatChar(T); } - return T->At - TStart; -} - -static char* -EatPastCharacter(char* C, char Char) -{ - char* Result = EatToCharacter(C, Char); - if (*Result && *Result == Char) { Result++; } - return Result; -} - -static s32 -EatPastCharacter(tokenizer* T, char Char) -{ - char* TStart = T->At; - EatToCharacter(T, Char); - if (AtValidPosition(*T) && *T->At == Char) { EatChar(T); } - return T->At - TStart; -} - -static char* -EatNumber(char* C) -{ - char* Result = C; - while (*Result && IsNumericExtended(*Result)) { Result++; } - return Result; -} - -static s32 -EatNumber(tokenizer* T) -{ - char* TStart = T->At; - while (AtValidPosition(*T) && IsNumericExtended(*T->At)) { EatChar(T); } - return T->At - TStart; -} - -#define GS_STRING_H -#endif // GS_STRING_H - - diff --git a/src/gs_libs/gs_string_builder.h b/src/gs_libs/gs_string_builder.h deleted file mode 100644 index 1102e97..0000000 --- a/src/gs_libs/gs_string_builder.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// File: gs_string_builder.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef GS_STRING_BUILDER_H - -#ifndef GS_STRING_BUILDER_NO_STDIO -#include -#endif - -#define STRING_BUILDER_BUFFER_CAPACITY 4096 -struct string_builder_buffer -{ - u8* BufferMemory; - string String; - string_builder_buffer* Next; -}; - -struct string_builder -{ - string_builder_buffer* Buffers; - string_builder_buffer* Head; -}; - -internal void -GrowStringBuilder(string_builder* StringBuilder) -{ - u8* BufferAndHeader = (u8*)malloc(sizeof(string_builder_buffer) + STRING_BUILDER_BUFFER_CAPACITY); - string_builder_buffer* NewBuffer = (string_builder_buffer*)BufferAndHeader; - *NewBuffer = {0}; - - NewBuffer->BufferMemory = (u8*)(NewBuffer + 1); - NewBuffer->String = MakeString((char*)NewBuffer->BufferMemory, 0, STRING_BUILDER_BUFFER_CAPACITY); - - if (!StringBuilder->Buffers) - { - StringBuilder->Buffers = NewBuffer; - StringBuilder->Head = NewBuffer; - } - else - { - StringBuilder->Head->Next = NewBuffer; - StringBuilder->Head = NewBuffer; - } -} - -internal void -Write(string Text, string_builder* StringBuilder) -{ - string TextLeft = Text; - - if (StringBuilder->Buffers == 0) - { - GrowStringBuilder(StringBuilder); - } - - while (TextLeft.Length > 0) - { - // Copy what there is room for - s32 SpaceAvailable = StringBuilder->Head->String.Max - StringBuilder->Head->String.Length; - - ConcatString(TextLeft, Min(SpaceAvailable, TextLeft.Length), &StringBuilder->Head->String); - TextLeft.Memory += SpaceAvailable; - TextLeft.Length -= SpaceAvailable; - - if (TextLeft.Length > 0) - { - GrowStringBuilder(StringBuilder); - } - } -} - -internal void -WriteF(string_builder* StringBuilder, char* Format, ...) -{ - MakeStringBuffer(Buffer, 256); - - va_list Args; - va_start(Args, Format); - Buffer.Length = PrintFArgsList(Buffer.Memory, Buffer.Max, Format, Args); - va_end(Args); - - Write(Buffer, StringBuilder); -} - -#ifndef GS_STRING_BUILDER_NO_STDIO - -internal void -WriteStringBuilderToFile(string_builder StringBuilder, FILE* WriteFile) -{ - string_builder_buffer* BufferAt = StringBuilder.Buffers; - while (BufferAt) - { - string String = BufferAt->String; - fwrite(String.Str, 1, String.Length, WriteFile); - BufferAt = BufferAt->Next; - } -} - -internal void -StdPrintStringBuilder(string_builder StringBuilder) -{ - string_builder_buffer* BufferAt = StringBuilder.Buffers; - while (BufferAt) - { - string String = BufferAt->String; - printf("%.*s", StringExpand(String)); - BufferAt = BufferAt->Next; - } -} - -#endif // GS_STRING_BUILDER_NO_STDIO - -#define GS_STRING_BUILDER_H -#endif // GS_STRING_BUILDER_H \ No newline at end of file diff --git a/src/gs_libs/gs_tests.h b/src/gs_libs/gs_tests.h deleted file mode 100644 index 7a38fb5..0000000 --- a/src/gs_libs/gs_tests.h +++ /dev/null @@ -1,72 +0,0 @@ -// -// File: gs_tests.h -// Author: Peter Slattery -// Creation Date: 2021-03-06 -// -#ifndef GS_TESTS_H - -int CStringLen(char* Str) -{ - char* At = Str; - while (*At != 0) { At++; } - int Result = At - Str; - return Result; -} - -struct test_ctx -{ - int TestsCount; - int TestsPassedCount; -}; - -static test_ctx TestCtx = {0}; - -static void -BeginTest(char* Name) -{ - int Length = CStringLen(Name); - int Spaces = 25 - Length; - if(Spaces < 0) - { - Spaces = 0; - } - printf("\"%s\" %.*s [", Name, Spaces, "------------------------------"); - TestCtx.TestsCount = 0; - TestCtx.TestsPassedCount = 0; -} - -static void -TestResult(bool Result) -{ - TestCtx.TestsCount += 1; - if (Result) { - TestCtx.TestsPassedCount += 1; - } - printf(Result ? "." : "X"); -} - -static void -EndTest(void) -{ - int Spaces = 10 - TestCtx.TestsCount; - if(Spaces < 0) { Spaces = 0; } - printf("]%.*s ", Spaces, " "); - printf("[%i/%i] %i passed, %i tests, ", - TestCtx.TestsPassedCount, TestCtx.TestsCount, - TestCtx.TestsPassedCount, TestCtx.TestsCount); - if(TestCtx.TestsCount == TestCtx.TestsPassedCount) - { - printf("SUCCESS ( )"); - } - else - { - printf("FAILED (X)"); - } - printf("\n"); -} - -#define Test(name) for(int _i_ = (BeginTest(name), 0); !_i_; _i_ += 1, EndTest()) - - -#define GS_TESTS_H -#endif // GS_TESTS_H \ No newline at end of file diff --git a/src/gs_libs/gs_types.cpp b/src/gs_libs/gs_types.cpp deleted file mode 100644 index bdf12c4..0000000 --- a/src/gs_libs/gs_types.cpp +++ /dev/null @@ -1,3577 +0,0 @@ -// -// File: gs_types.cpp -// Author: Peter Slattery -// Creation Date: 2020-04-18 -// -#ifndef GS_TYPES_CPP - -#define StructToData(ptr, type) StructToData_((u8*)(ptr), sizeof(type)) -internal gs_data -StructToData_(u8* Memory, u64 Size) -{ - gs_data Result = {0}; - Result.Memory = Memory; - Result.Size = Size; - return Result; -} - -internal u32 -U32DivideRoundUp (u32 A, u32 B) -{ - r32 Result = (r32)A / (r32)B; - Result += .99999f; - return (u32)Result; -} - -inline bool XOR(bool A, bool B) { return (A == !B); } -inline bool XOR(b8 A, b8 B) { return (A == !B); } -inline bool XOR(b32 A, b32 B) { return (A == !B); } -inline bool XOR(b64 A, b64 B) { return (A == !B); } - -internal u32 -RoundUpToMultiple(u32 Value, u32 MultipleOf) -{ - u32 Result = Value; - if (MultipleOf != 0) - { - u32 Remainder = Value % MultipleOf; - Result = Value + (MultipleOf - Remainder); - } - return Result; -} -internal u32 -RoundUpToPow2U32(u32 Value) -{ - u32 Result = Value - 1; - Result |= Result >> 1; - Result |= Result >> 2; - Result |= Result >> 4; - Result |= Result >> 8; - Result |= Result >> 16; - Result++; - return Result; -} -internal u32 -RoundUpToPow2U64(u64 Value) -{ - u64 Result = Value - 1; - Result |= Result >> 1; - Result |= Result >> 2; - Result |= Result >> 4; - Result |= Result >> 8; - Result |= Result >> 16; - Result |= Result >> 32; - Result++; - return Result; -} -internal u64 -RoundUpTo64(u64 Value, u64 Alignment) -{ - Value += Alignment - 1; - Value -= Value % Alignment; - return Value; -} - -internal u8 -PowU8(u8 X, u32 Power) -{ - u8 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal u16 -PowU16(u16 X, u32 Power) -{ - u16 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal u32 -PowU32(u32 X, u32 Power) -{ - u32 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal u64 -PowU64(u64 X, u32 Power) -{ - u64 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal s8 -PowS8(s8 X, u32 Power) -{ - s8 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal s16 -PowS16(s16 X, u32 Power) -{ - s16 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal s32 -PowS32(s32 X, u32 Power) -{ - s32 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal s64 -PowS64(s64 X, u32 Power) -{ - s64 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal r32 -PowR32(r32 X, u32 Power) -{ - r32 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} -internal r64 -PowR64(r64 X, u32 Power) -{ - r64 Result = X; - for (u32 i = 1; i < Power; i++) { Result *= X; } - return Result; -} - -internal u8 -LerpU8(r32 T, u8 A, u8 B) -{ - return (u8)((A * (1.0f - T)) + (B * T)); -} -internal u16 -LerpU16(r32 T, u16 A, u16 B) -{ - return (u16)((A * (1.0f - T)) + (B * T)); -} -internal u32 -LerpU32(r32 T, u32 A, u32 B) -{ - return (u32)((A * (1.0f - T)) + (B * T)); -} -internal u64 -LerpU64(r32 T, u64 A, u64 B) -{ - return (u64)((A * (1.0f - T)) + (B * T)); -} -internal s8 -LerpS8(r32 T, s8 A, s8 B) -{ - return (s8)((A * (1.0f - T)) + (B * T)); -} -internal s16 -LerpS16(r32 T, s16 A, s16 B) -{ - return (s16)((A * (1.0f - T)) + (B * T)); -} -internal s32 -LerpS32(r32 T, s32 A, s32 B) -{ - return (s32)((A * (1.0f - T)) + (B * T)); -} -internal s64 -LerpS64(r32 T, s64 A, s64 B) -{ - return (s64)((A * (1.0f - T)) + (B * T)); -} -internal r32 -LerpR32(r32 T, r32 A, r32 B) -{ - return (r32)((A * (1.0f - T)) + (B * T)); -} -internal r64 -LerpR64(r32 T, r64 A, r64 B) -{ - return (r64)((A * (1.0f - T)) + (B * T)); -} - -internal u8 -UnlerpU8(u8 Value, u8 Min, u8 Max) -{ - return (u8)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal u16 -UnlerpU16(u16 Value, u16 Min, u16 Max) -{ - return (u16)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal u32 -UnlerpU32(u32 Value, u32 Min, u32 Max) -{ - return (u32)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal u64 -UnlerpU64(u64 Value, u64 Min, u64 Max) -{ - return (u64)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal s8 -UnlerpS8(s8 Value, s8 Min, s8 Max) -{ - return (s8)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal s16 -UnlerpS16(s16 Value, s16 Min, s16 Max) -{ - return (s16)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal s32 -UnlerpS32(s32 Value, s32 Min, s32 Max) -{ - return (s32)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal s64 -UnlerpS64(s64 Value, s64 Min, s64 Max) -{ - return (s64)((r64)(Value - Min) / (r64)(Max - Min)); -} -internal r32 -UnlerpR32(r32 Value, r32 Min, r32 Max) -{ - return (Value - Min) / (Max - Min); -} -internal r64 -UnlerpR64(r64 Value, r64 Min, r64 Max) -{ - return (Value - Min) / (Max - Min); -} - - -internal u8 -RemapU8(u8 Value, u8 OldMin, u8 OldMax, u8 NewMin, u8 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - u8 Result = (u8)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal u16 -RemapU16(u16 Value, u16 OldMin, u16 OldMax, u16 NewMin, u16 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - u16 Result = (u16)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal u32 -RemapU32(u32 Value, u32 OldMin, u32 OldMax, u32 NewMin, u32 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - u32 Result = (u32)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal u64 -RemapU64(u64 Value, u64 OldMin, u64 OldMax, u64 NewMin, u64 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - u64 Result = (u64)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal s8 -RemapS8(s8 Value, s8 OldMin, s8 OldMax, s8 NewMin, s8 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - s8 Result = (s8)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal s16 -RemapS16(s16 Value, s16 OldMin, s16 OldMax, s16 NewMin, s16 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - s16 Result = (s16)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal s32 -RemapS32(s32 Value, s32 OldMin, s32 OldMax, s32 NewMin, s32 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - s32 Result = (s32)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal s64 -RemapS64(s64 Value, s64 OldMin, s64 OldMax, s64 NewMin, s64 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - s64 Result = (s64)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal r32 -RemapR32(r32 Value, r32 OldMin, r32 OldMax, r32 NewMin, r32 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r32 Result = (r32)((A * (NewMax - NewMin)) + NewMin); - return Result; -} -internal r64 -RemapR64(r64 Value, r64 OldMin, r64 OldMax, r64 NewMin, r64 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 Result = (r64)((A * (NewMax - NewMin)) + NewMin); - return Result; -} - -internal u8 -RemapClampedU8(u8 Value, u8 OldMin, u8 OldMax, u8 NewMin, u8 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - u8 Result = (u8)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal u16 -RemapClampedU16(u16 Value, u16 OldMin, u16 OldMax, u16 NewMin, u16 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - u16 Result = (u16)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal u32 -RemapClampedU32(u32 Value, u32 OldMin, u32 OldMax, u32 NewMin, u32 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - u32 Result = (u32)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal u64 -RemapClampedU64(u64 Value, u64 OldMin, u64 OldMax, u64 NewMin, u64 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - u64 Result = (u64)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal s8 -RemapClampedS8(s8 Value, s8 OldMin, s8 OldMax, s8 NewMin, s8 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - s8 Result = (s8)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal s16 -RemapClampedS16(s16 Value, s16 OldMin, s16 OldMax, s16 NewMin, s16 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - s16 Result = (s16)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal s32 -RemapClampedS32(s32 Value, s32 OldMin, s32 OldMax, s32 NewMin, s32 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - s32 Result = (s32)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal s64 -RemapClampedS64(s64 Value, s64 OldMin, s64 OldMax, s64 NewMin, s64 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - s64 Result = (s64)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal r32 -RemapClampedR32(r32 Value, r32 OldMin, r32 OldMax, r32 NewMin, r32 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - r32 Result = (r32)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} -internal r64 -RemapClampedR64(r64 Value, r64 OldMin, r64 OldMax, r64 NewMin, r64 NewMax) -{ - r64 A = (r64)(Value - OldMin) / (r64)(OldMax - OldMin); - r64 AClamped = Clamp01(A); - r64 UnclampedResult = ((AClamped * (NewMax - NewMin)) + NewMin); - r64 Result = (r64)Clamp(NewMin, UnclampedResult, NewMax); - return Result; -} - -internal r32 -FloorR32(r32 V) -{ - return (r32)((s64)V); -} -internal r64 -FloorR64(r64 V) -{ - return (r64)((s64)V); -} - -internal r32 -FractR32(r32 V) -{ - return V - FloorR32(V); -} -internal r64 -FractR64(r64 V) -{ - return V - FloorR64(V); -} - -internal r32 -SqrtR32(r32 V) -{ - return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(V))); -} -internal u32 -SqrtU32(u32 V) -{ - return sqrt(V); -} - -internal r32 -ModR32(r32 Value, r32 Int) -{ - r32 Div = Value / Int; - r32 Fract = Abs(FractR32(Div)); - return Int * Fract; -} -internal r64 -ModR64(r64 Value, r64 Int) -{ - r64 Div = Value / Int; - r64 Fract = Abs(FractR64(Div)); - return Int * Fract; -} - -internal r32 -SinR32(r32 Rad) -{ - return sinf(Rad); -} -internal r64 -SinR64(r64 Rad) -{ - return sin(Rad); -} - -internal r32 -CosR32(r32 Rad) -{ - return cosf(Rad); -} -internal r64 -CosR64(r64 Rad) -{ - return cos(Rad); -} - -internal r32 -TanR32(r32 Rad) -{ - return tanf(Rad); -} -internal r64 -TanR64(r64 Rad) -{ - return tan(Rad); -} - -internal r32 -ASinR32(r32 Rad) -{ - return asinf(Rad); -} -internal r64 -ASinR64(r64 Rad) -{ - return asin(Rad); -} - -internal r32 -ACosR32(r32 Rad) -{ - return acosf(Rad); -} -internal r64 -ACosR64(r64 Rad) -{ - return acos(Rad); -} - -internal r32 -ATanR32(r32 Rad) -{ - return atanf(Rad); -} -internal r64 -ATanR64(r64 Rad) -{ - return atan(Rad); -} - -/////////////////////////// -// -// Vector - -internal v2 -V2MultiplyPairwise(v2 A, v2 B) -{ - v2 Result = v2{ - A.x * B.x, - A.y * B.y, - }; - return Result; -} - -internal v3 -V3MultiplyPairwise(v3 A, v3 B) -{ - v3 Result = v3{ - A.x * B.x, - A.y * B.y, - A.z * B.z, - }; - return Result; -} - -internal v4 -V4MultiplyPairwise(v4 A, v4 B) -{ - v4 Result = v4{ - A.x * B.x, - A.y * B.y, - A.z * B.z, - A.w * B.w, - }; - return Result; -} - - -v2 operator- (v2 A) { return { -A.x, -A.y }; } -v3 operator- (v3 A) { return { -A.x, -A.y, -A.z }; } -v4 operator- (v4 A) { return { -A.x, -A.y, -A.z, -A.w }; } - -v2 operator+ (v2 A, v2 B) { return { A.x + B.x, A.y + B.y }; } -v3 operator+ (v3 A, v3 B) { return { A.x + B.x, A.y + B.y, A.z + B.z }; } -v4 operator+ (v4 A, v4 B) { return { A.x + B.x, A.y + B.y, A.z + B.z, A.w + B.w }; } - -v2 operator- (v2 A, v2 B) { return { A.x - B.x, A.y - B.y }; } -v3 operator- (v3 A, v3 B) { return { A.x - B.x, A.y - B.y, A.z - B.z }; } -v4 operator- (v4 A, v4 B) { return { A.x - B.x, A.y - B.y, A.z - B.z, A.w - B.w }; } - -void operator+= (v2& A, v2 B) { A.x += B.x; A.y += B.y; } -void operator+= (v3& A, v3 B) { A.x += B.x; A.y += B.y; A.z += B.z; } -void operator+= (v4& A, v4 B) { A.x += B.x; A.y += B.y; A.z += B.z; A.w += B.w; } - -void operator-= (v2& A, v2 B) { A.x -= B.x; A.y -= B.y; } -void operator-= (v3& A, v3 B) { A.x -= B.x; A.y -= B.y; A.z -= B.z; } -void operator-= (v4& A, v4 B) { A.x -= B.x; A.y -= B.y; A.z -= B.z; A.w -= B.w; } - -v2 operator* (v2 A, r32 B) { return { A.x * B, A.y * B }; } -v3 operator* (v3 A, r32 B) { return { A.x * B, A.y * B, A.z * B }; } -v4 operator* (v4 A, r32 B) { return { A.x * B, A.y * B, A.z * B, A.w * B }; } - -v2 operator/ (v2 A, r32 B) { return { A.x / B, A.y / B }; } -v3 operator/ (v3 A, r32 B) { return { A.x / B, A.y / B, A.z / B }; } -v4 operator/ (v4 A, r32 B) { return { A.x / B, A.y / B, A.z / B, A.w / B }; } - -void operator*= (v2& A, r32 B) { A.x *= B; A.y *= B; } -void operator*= (v3& A, r32 B) { A.x *= B; A.y *= B; A.z *= B; } -void operator*= (v4& A, r32 B) { A.x *= B; A.y *= B; A.z *= B; A.w *= B; } - -void operator/= (v2& A, r32 B) { A.x /= B; A.y /= B; } -void operator/= (v3& A, r32 B) { A.x /= B; A.y /= B; A.z /= B; } -void operator/= (v4& A, r32 B) { A.x /= B; A.y /= B; A.z /= B; A.w /= B; } - -bool operator == (v2 A, v2 B) { return ((A.x == B.x) && (A.y == B.y)); } -bool operator == (v3 A, v3 B) { return ((A.x == B.x) && (A.y == B.y) && (A.z == B.z)); } -bool operator == (v4 A, v4 B) { return ((A.x == B.x) && (A.y == B.y) && (A.z == B.z) && (A.w == B.w)); } - -bool operator != (v2 A, v2 B) { return !((A.x == B.x) && (A.y == B.y)); } -bool operator != (v3 A, v3 B) { return !((A.x == B.x) && (A.y == B.y) && (A.z == B.z)); } -bool operator != (v4 A, v4 B) { return !((A.x == B.x) && (A.y == B.y) && (A.z == B.z) && (A.w == B.w)); } - -internal v3 ToV3(v2 V, r32 Z = 0) { return v3{V.x, V.y, Z}; } -internal v4 V2ToV4(v2 V, r32 Z = 0, r32 W = 0) { return v4{V.x, V.y, Z, W}; } -internal v4 ToV4_(v3 V, r32 W) -{ - return v4{V.x, V.y, V.z, W}; -} -#define ToV4Point(v) ToV4_((v), 1.0f) // all points have a w value of 1 -#define ToV4Vec(v) ToV4_((v), 0.0f) // all vectors have a w value of 0 ie. they cannot be translated - -internal r32 V2MagSquared(v2 V) { return ((V.x * V.x) + (V.y * V.y)); } -internal r32 V3MagSquared(v3 V) { return ((V.x * V.x) + (V.y * V.y) + (V.z * V.z)); } -internal r32 V4MagSquared(v4 V) { return ((V.x * V.x) + (V.y * V.y) + (V.z * V.z) + (V.w * V.w)); } - -internal r32 V2Mag(v2 V) { return SqrtR32((V.x * V.x) + (V.y * V.y)); } -internal r32 V3Mag(v3 V) { return SqrtR32((V.x * V.x) + (V.y * V.y) + (V.z * V.z)); } -internal r32 V4Mag(v4 V) { return SqrtR32((V.x * V.x) + (V.y * V.y) + (V.z * V.z) + (V.w * V.w)); } - -internal r32 V2DistanceSquared(v2 A, v2 B) { return V2MagSquared(A - B); } -internal r32 V3DistanceSquared(v3 A, v3 B) { return V3MagSquared(A - B); } -internal r32 V4DistanceSquared(v4 A, v4 B) { return V4MagSquared(A - B); } - -internal r32 V2Distance(v2 A, v2 B) { return V2Mag(A - B); } -internal r32 V3Distance(v3 A, v3 B) { return V3Mag(A - B); } -internal r32 V4Distance(v4 A, v4 B) { return V4Mag(A - B); } - -internal v2 -V2Normalize(v2 A) -{ - r32 Magnitude = V2Mag(A); - return A / Magnitude; -} -internal v3 -V3Normalize(v3 A) -{ - r32 Magnitude = V3Mag(A); - return A / Magnitude; -} -internal v4 -V4Normalize(v4 A) -{ - r32 Magnitude = V4Mag(A); - return A / Magnitude; -} - -internal r32 V2Dot(v2 A, v2 B) { return ((A.x * B.x) + (A.y * B.y)); } -internal r32 V3Dot(v3 A, v3 B) { return ((A.x * B.x) + (A.y * B.y) + (A.z * B.z)); } -internal r32 V4Dot(v4 A, v4 B) { return ((A.x * B.x) + (A.y * B.y) + (A.z * B.z) + (A.w * B.w)); } - -internal v2 V2PerpendicularCW(v2 A) { return v2{A.y, -A.x}; } -internal v2 V2PerpendicularCCW(v2 A) { return v2{A.y, A.x}; } - -internal r32 -V2Cross(v2 A, v2 B) -{ - return ((A.x * B.y) - (A.y * B.x)); -} - -internal v3 -V3Cross(v3 A, v3 B) -{ - v3 Result = { - (A.y * B.z) - (A.z * B.y), - (A.z * B.x) - (A.x * B.z), - (A.x * B.y) - (A.y * B.x) - }; - return Result; -} - -internal v4 -V4Cross(v4 A, v4 B) -{ - v4 Result = { - (A.y * B.z) - (A.z * B.y), - (A.z * B.x) - (A.x * B.z), - (A.x * B.y) - (A.y * B.x), - 0 - }; - return Result; -} - -internal v2 -V2Lerp(r32 T, v2 A, v2 B) -{ - v2 Result = v2{ - LerpR32(T, A.x, B.x), - LerpR32(T, A.y, B.y), - }; - return Result; -} - -internal v3 -V3Lerp(r32 T, v3 A, v3 B) -{ - v3 Result = v3{ - LerpR32(T, A.x, B.x), - LerpR32(T, A.y, B.y), - LerpR32(T, A.z, B.z), - }; - return Result; -} - -internal v4 -V4Lerp(r32 T, v4 A, v4 B) -{ - v4 Result = v4{ - LerpR32(T, A.x, B.x), - LerpR32(T, A.y, B.y), - LerpR32(T, A.z, B.z), - LerpR32(T, A.w, B.w), - }; - return Result; -} - -internal v2 -V2Remap(v2 P, v2 OldMin, v2 OldMax, v2 NewMin, v2 NewMax) -{ - v2 Result = {0}; - Result.x = RemapR32(P.x, OldMin.x, OldMax.x, NewMin.x, NewMax.x); - Result.y = RemapR32(P.y, OldMin.y, OldMax.y, NewMin.y, NewMax.y); - return Result; -} - -internal v3 -V3Remap(v3 P, v3 OldMin, v3 OldMax, v3 NewMin, v3 NewMax) -{ - v3 Result = {0}; - Result.x = RemapR32(P.x, OldMin.x, OldMax.x, NewMin.x, NewMax.x); - Result.y = RemapR32(P.y, OldMin.y, OldMax.y, NewMin.y, NewMax.y); - Result.z = RemapR32(P.z, OldMin.z, OldMax.z, NewMin.z, NewMax.z); - return Result; -} - -internal v4 -V4Remap(v4 P, v4 OldMin, v4 OldMax, v4 NewMin, v4 NewMax) -{ - v4 Result = {0}; - Result.x = RemapR32(P.x, OldMin.x, OldMax.x, NewMin.x, NewMax.x); - Result.y = RemapR32(P.y, OldMin.y, OldMax.y, NewMin.y, NewMax.y); - Result.z = RemapR32(P.z, OldMin.z, OldMax.z, NewMin.z, NewMax.z); - Result.w = RemapR32(P.w, OldMin.w, OldMax.w, NewMin.w, NewMax.w); - return Result; -} - -internal v4 -V4RemapAsV3(v4 P, v4 OldMin, v4 OldMax, v4 NewMin, v4 NewMax) -{ - v4 Result = {0}; - Result.xyz = V3Remap(P.xyz, OldMin.xyz, OldMax.xyz, NewMin.xyz, NewMax.xyz); - Result.w = P.w; - return Result; -} - -/////////////////////////// -// -// Ranges - -internal rect2 MakeRect2MinDim(v2 Min, v2 Dim) -{ - rect2 Result = {0}; - Result.Min = Min; - Result.Max = Min + Dim; - return Result; -} - -internal rect2 MakeRect2CenterDim(v2 Center, v2 Dim) -{ - v2 HalfDim = Dim / 2; - rect2 Result = {0}; - Result.Min = Center - HalfDim; - Result.Max = Center + HalfDim; - return Result; -} - -internal b32 ValueInRangeR32(r32 Min, r32 Max, r32 V) -{ - return ((V >= Min) && (V <= Max)); -} - -internal b32 ValueInRange1(range1 Range, r32 V) -{ - return ValueInRangeR32(Range.Min, Range.Max, V); -} -internal b32 ValueInRange2(range2 Range, v2 V) -{ - return (ValueInRangeR32(Range.Min.x, Range.Max.x, V.x) && - ValueInRangeR32(Range.Min.y, Range.Max.y, V.y)); -} -internal b32 ValueInRange3(range3 Range, v3 V) -{ - return (ValueInRangeR32(Range.Min.x, Range.Max.x, V.x) && - ValueInRangeR32(Range.Min.y, Range.Max.y, V.y) && - ValueInRangeR32(Range.Min.z, Range.Max.z, V.z)); -} -internal b32 ValueInRange4(range4 Range, v4 V) -{ - return (ValueInRangeR32(Range.Min.x, Range.Max.x, V.x) && - ValueInRangeR32(Range.Min.y, Range.Max.y, V.y) && - ValueInRangeR32(Range.Min.z, Range.Max.z, V.z) && - ValueInRangeR32(Range.Min.w, Range.Max.w, V.w)); -} - -#define PointIsInRect(range, point) ValueInRange2((range), (point)) - -internal r32 Range1SizeX(range1 Range) { return Range.Max - Range.Min; } -internal r32 Range2SizeX(range2 Range) { return Range.Max.x - Range.Min.x; } -internal r32 Range3SizeX(range3 Range) { return Range.Max.x - Range.Min.x; } -internal r32 Range4SizeX(range4 Range) { return Range.Max.x - Range.Min.x; } - -#define Rect2Width(r) Range2SizeX((r)) - -internal r32 Range2SizeY(range2 Range) { return Range.Max.y - Range.Min.y; } -internal r32 Range3SizeY(range3 Range) { return Range.Max.y - Range.Min.y; } -internal r32 Range4SizeY(range4 Range) { return Range.Max.y - Range.Min.y; } - -#define Rect2Height(r) Range2SizeY((r)) - -internal r32 Range3SizeZ(range3 Range) { return Range.Max.z - Range.Min.z; } -internal r32 Range4SizeZ(range4 Range) { return Range.Max.z - Range.Min.z; } - -internal r32 Range4SizeW(range4 Range) { return Range.Max.w - Range.Min.w; } - -internal r32 Range1Center(range1 Range) { return (Range.Max + Range.Min) / 2.0f; } -internal v2 Range2Center(range2 Range) { return (Range.Max + Range.Min) / 2.0f; } -internal v3 Range3Center(range3 Range) { return (Range.Max + Range.Min) / 2.0f; } -internal v4 Range4Center(range4 Range) { return (Range.Max + Range.Min) / 2.0f; } - -#define Rect2Center(r) Range2Center((r)) - -internal range1 Range1Offset(range1 Range, r32 Delta) { return range1{ Range.Min + Delta, Range.Max + Delta }; } -internal range2 Range2Offset(range2 Range, v2 Delta) { return range2{ Range.Min + Delta, Range.Max + Delta }; } -internal range3 Range3Offset(range3 Range, v3 Delta) { return range3{ Range.Min + Delta, Range.Max + Delta }; } -internal range4 Range4Offset(range4 Range, v4 Delta) { return range4{ Range.Min + Delta, Range.Max + Delta }; } - -#define Rect2Translate(r, d) Range2Offset((r), (d)) -#define Rect2TranslateX(r, dx) Range2Offset((r), v2{(dx), 0}) -#define Rect2TranslateY(r, dy) Range2Offset((r), v2{0, (dy)}) - -internal v2 RectTopLeft(rect2 Rect) -{ - return v2{ Rect.Min.x, Rect.Max.y }; -} -internal v2 RectTopRight(rect2 Rect) -{ - return Rect.Max; -} -internal v2 RectBottomLeft(rect2 Rect) -{ - return Rect.Min; -} -internal v2 RectBottomRight(rect2 Rect) -{ - return v2{ Rect.Max.x, Rect.Min.y }; -} - -internal r32 AspectRatio(r32 Width, r32 Height) { return Width / Height; } -internal r32 RectAspectRatio(rect2 Rect) { return Range2SizeX(Rect) / Range2SizeY(Rect); } - -internal void -RectHSplit(rect2 Rect, r32 YValue, rect2* Top, rect2* Bottom) -{ - r32 ClampedYValue = Clamp(Rect.Min.y, YValue, Rect.Max.y); - Top->Max = Rect.Max; - Top->Min = { Rect.Min.x, ClampedYValue }; - Bottom->Max = { Rect.Max.x, ClampedYValue }; - Bottom->Min = Rect.Min; -} - -internal void -RectVSplit(rect2 Rect, r32 XValue, rect2* Left, rect2* Right) -{ - r32 ClampedXValue = Clamp(Rect.Min.x, XValue, Rect.Max.x); - Left->Max = { ClampedXValue, Rect.Max.y}; - Left->Min = Rect.Min; - Right->Max = Rect.Max; - Right->Min = { ClampedXValue, Rect.Min.y }; -} - -internal void -RectHSplitAtDistanceFromTop(rect2 Rect, r32 YDist, rect2* Top, rect2* Bottom) -{ - RectHSplit(Rect, Rect.Max.y - YDist, Top, Bottom); -} -internal void -RectHSplitAtDistanceFromBottom(rect2 Rect, r32 YDist, rect2* Top, rect2* Bottom) -{ - RectHSplit(Rect, Rect.Min.y + YDist, Top, Bottom); -} -internal void -RectVSplitAtDistanceFromRight(rect2 Rect, r32 XDist, rect2* Left, rect2* Right) -{ - RectVSplit(Rect, Rect.Max.x - XDist, Left, Right); -} -internal void -RectVSplitAtDistanceFromLeft(rect2 Rect, r32 XDist, rect2* Left, rect2* Right) -{ - RectVSplit(Rect, Rect.Min.x + XDist, Left, Right); -} -internal void -RectHSplitAtPercent(rect2 Rect, r32 YPercent, rect2* Top, rect2* Bottom) -{ - RectHSplit(Rect, LerpR32(YPercent, Rect.Min.y, Rect.Max.y), Top, Bottom); -} -internal void -RectVSplitAtPercent(rect2 Rect, r32 XPercent, rect2* Left, rect2* Right) -{ - RectVSplit(Rect, LerpR32(XPercent, Rect.Min.x, Rect.Max.x), Left, Right); -} - -internal rect2 -RectInset(rect2 Outer, v2 Amount) -{ - rect2 Result = { Outer.Min + Amount, Outer.Max - Amount }; - return Result; -} -internal rect2 -RectInset(rect2 Outer, r32 UniformAmount) -{ - return RectInset(Outer, v2{UniformAmount, UniformAmount}); -} - - -internal range1 -Range1Union(range1 A, range1 B) -{ - range1 Result = {}; - Result.Min = Max(A.Min, B.Min); - Result.Max = Min(A.Max, B.Max); - return Result; -} -#define Rect2Union(a,b) Range2Union((a), (b)) -internal range2 -Range2Union(range2 A, range2 B) -{ - range2 Result = {}; - Result.Min.x = Max(A.Min.x, B.Min.x); - Result.Min.y = Max(A.Min.y, B.Min.y); - Result.Max.x = Min(A.Max.x, B.Max.x); - Result.Max.y = Min(A.Max.y, B.Max.y); - - if (Rect2Width(Result) < 0) { Result.Min.x = Result.Max.x; } - if (Rect2Height(Result) < 0) { Result.Min.y = Result.Max.y; } - - return Result; -} -internal range3 -Range3Union(range3 A, range3 B) -{ - range3 Result = {}; - Result.Min.x = Max(A.Min.x, B.Min.x); - Result.Min.y = Max(A.Min.y, B.Min.y); - Result.Min.z = Max(A.Min.z, B.Min.z); - Result.Max.x = Min(A.Max.x, B.Max.x); - Result.Max.y = Min(A.Max.y, B.Max.y); - Result.Max.z = Min(A.Max.z, B.Max.z); - return Result; -} - -internal v2 -Rect2GetRectLocalPoint(rect2 Rect, v2 Point) -{ - v2 Result = Point - Rect.Min; - return Result; -} - -internal r32 -Rect2Area(rect2 Rect) -{ - r32 Result = Rect2Width(Rect) * Rect2Height(Rect); - return Result; -} - -internal v2 -Rect2BottomLeft(rect2 Rect) -{ - v2 Result = Rect.Min; - return Result; -} - -internal v2 -Rect2BottomRight(rect2 Rect) -{ - v2 Result = v2{ Rect.Max.x, Rect.Min.y }; - return Result; -} - -internal v2 -Rect2TopRight(rect2 Rect) -{ - v2 Result = Rect.Max; - return Result; -} - -internal v2 -Rect2TopLeft(rect2 Rect) -{ - v2 Result = v2{ Rect.Min.x, Rect.Max.y }; - return Result; -} - -/////////////////////////// -// -// Ray - -internal v4 -RayGetPointAlong(v4 RayOrigin, v4 RayDirection, r32 T) -{ - v4 Result = RayOrigin + (RayDirection * T); - return Result; -} - -internal r32 -RayPlaneIntersectionDistance(v4 RayOrigin, v4 RayDirection, v4 PlanePoint, v4 PlaneNormal) -{ - r32 T = 0.0f; - float Denominator = V4Dot(PlaneNormal, RayDirection); - if (Abs(Denominator) > 0.00001f) - { - T = V4Dot(PlanePoint - RayDirection, PlaneNormal) / Denominator; - } - return T; -} - -internal v4 -GetRayPlaneIntersectionPoint(v4 RayOrigin, v4 RayDirection, v4 PlanePoint, v4 PlaneNormal) -{ - v4 Result = {0}; - r32 T = RayPlaneIntersectionDistance(RayOrigin, RayDirection, PlanePoint, PlaneNormal); - if (T >= 0) - { - Result = RayGetPointAlong(RayOrigin, RayDirection, T); - } - return Result; -} -internal v4 -GetRayPlaneIntersectionPoint(v4_ray Ray, v4 PlanePoint, v4 PlaneNormal) -{ - return GetRayPlaneIntersectionPoint(Ray.Origin, Ray.Direction, PlanePoint, PlaneNormal); -} - -internal bool -RayIntersectsPlane(v4 RayOrigin, v4 RayDirection, v4 PlanePoint, v4 PlaneNormal, v4* OutPoint) -{ - bool Result = false; - r32 T = RayPlaneIntersectionDistance(RayOrigin, RayDirection, PlanePoint, PlaneNormal); - if (T >= 0) - { - Result = true; - *OutPoint = RayGetPointAlong(RayOrigin, RayDirection, T); - } - return Result; -} -internal bool -RayIntersectsPlane(v4_ray Ray, v4 PlanePoint, v4 PlaneNormal, v4* OutPoint) -{ - return RayIntersectsPlane(Ray.Origin, Ray.Direction, PlanePoint, PlaneNormal, OutPoint); -} - -/////////////////////////// -// -// Matrices - -internal m44 -M44Identity() -{ - m44 M = {0}; - M.AXx = 1.0f; - M.AYy = 1.0f; - M.AZz = 1.0f; - M.Tw = 1.0f; - return M; -} - -internal m44 -M44Transpose(m44 M) -{ - m44 Result = {0}; - for (u32 Y = 0; Y < 4; Y++) - { - for (u32 X = 0; X < 4; X++) - { - Result.Array[(X * 4) + Y] = M.Array[(Y * 4) + X]; - } - } - return Result; -} - -// Matrix * Matrix - -m44 operator* (m44 L, m44 R) -{ - m44 M = {0}; - - // ci ic ci ic ci ic i ic - M.AXx = (L.AXx * R.AXx) + (L.AYx * R.AXy) + (L.AZx * R.AXz) + (L.Tx * R.AXw); - M.AXy = (L.AXy * R.AXx) + (L.AYy * R.AXy) + (L.AZy * R.AXz) + (L.Ty * R.AXw); - M.AXz = (L.AXz * R.AXx) + (L.AYz * R.AXy) + (L.AZz * R.AXz) + (L.Tz * R.AXw); - M.AXw = (L.AXw * R.AXx) + (L.AYw * R.AXy) + (L.AZw * R.AXz) + (L.Tw * R.AXw); - - M.AYx = (L.AXx * R.AYx) + (L.AYx * R.AYy) + (L.AZx * R.AYz) + (L.Tx * R.AYw); - M.AYy = (L.AXy * R.AYx) + (L.AYy * R.AYy) + (L.AZy * R.AYz) + (L.Ty * R.AYw); - M.AYz = (L.AXz * R.AYx) + (L.AYz * R.AYy) + (L.AZz * R.AYz) + (L.Tz * R.AYw); - M.AYz = (L.AXw * R.AYx) + (L.AYw * R.AYy) + (L.AZw * R.AYz) + (L.Tw * R.AYw); - - M.AZx = (L.AXx * R.AZx) + (L.AYx * R.AZy) + (L.AZx * R.AZz) + (L.Tx * R.AZw); - M.AZy = (L.AXy * R.AZx) + (L.AYy * R.AZy) + (L.AZy * R.AZz) + (L.Ty * R.AZw); - M.AZz = (L.AXz * R.AZx) + (L.AYz * R.AZy) + (L.AZz * R.AZz) + (L.Tz * R.AZw); - M.AZw = (L.AXw * R.AZx) + (L.AYw * R.AZy) + (L.AZw * R.AZz) + (L.Tw * R.AZw); - - M.Tx = (L.AXx * R.Tx) + (L.AYx * R.Ty) + (L.AZx * R.Tz) + (L.Tx * R.Tw); - M.Ty = (L.AXy * R.Tx) + (L.AYy * R.Ty) + (L.AZy * R.Tz) + (L.Ty * R.Tw); - M.Tz = (L.AXz * R.Tx) + (L.AYz * R.Ty) + (L.AZz * R.Tz) + (L.Tz * R.Tw); - M.Tw = (L.AXw * R.Tx) + (L.AYw * R.Ty) + (L.AZw * R.Tz) + (L.Tw * R.Tw); - - return M; -} - -// Matrix * Vector - -v4 operator* (m44 M, v4 V) -{ - v4 Result = {0}; - Result.x = (V.x * M.AXx) + (V.y * M.AYx) + (V.z * M.AZx) + (V.w * M.Tx); - Result.y = (V.x * M.AXy) + (V.y * M.AYy) + (V.z * M.AZy) + (V.w * M.Ty); - Result.z = (V.x * M.AXz) + (V.y * M.AYz) + (V.z * M.AZz) + (V.w * M.Tz); - Result.w = (V.x * M.AXw) + (V.y * M.AYw) + (V.z * M.AZw) + (V.w * M.Tw); - return Result; -} - -internal m44 -M44Translation(v4 Offset) -{ - m44 Result = M44Identity(); - Result.Tx = Offset.x; - Result.Ty = Offset.y; - Result.Tz = Offset.z; - return Result; -} - -internal m44 -M44RotationX(r32 Radians) -{ - r32 CosRad = CosR32(Radians); - r32 SinRad = SinR32(Radians); - m44 Result = M44Identity(); - Result.AYy = CosRad; - Result.AZy = SinRad; - Result.AYz = -SinRad; - Result.AZz = CosRad; - return Result; -} - -internal m44 -M44RotationY(r32 Radians) -{ - r32 CosRad = CosR32(Radians); - r32 SinRad = SinR32(Radians); - m44 Result = M44Identity(); - Result.AXx = CosRad; - Result.AZx = SinRad; - Result.AXz = -SinRad; - Result.AZz = CosRad; - return Result; -} - -internal m44 -M44RotationZ(r32 Radians) -{ - r32 CosRad = CosR32(Radians); - r32 SinRad = SinR32(Radians); - m44 Result = M44Identity(); - Result.AXx = CosRad; - Result.AYx = -SinRad; - Result.AXy = SinRad; - Result.AYy = CosRad; - return Result; -} - -internal m44 -M44Rotation(v3 Radians) -{ - r32 CosX = CosR32(Radians.x); - r32 SinX = SinR32(Radians.x); - r32 CosY = CosR32(Radians.y); - r32 SinY = SinR32(Radians.y); - r32 CosZ = CosR32(Radians.z); - r32 SinZ = SinR32(Radians.z); - - m44 Result = {0}; - Result.AXx = CosY * CosZ; - Result.AXy = -(SinX * SinY * CosZ) + (CosX * SinZ); - Result.AXz = -(CosX * SinY * CosZ) - (SinX * SinZ); - Result.AXw = 0; - - Result.AYx = -(SinZ * CosY); - Result.AYy = (SinX * SinY * SinZ) + (CosX * CosZ); - Result.AYz = (CosX * SinY * SinZ) - (SinX * CosZ); - Result.AYw = 0; - - Result.AZx = SinY; - Result.AZy = SinX * CosY; - Result.AZz = CosX * CosY; - Result.AZw = 0; - - Result.Tx = 0; - Result.Ty = 0; - Result.Tz = 0; - Result.Tw = 1; - - return Result; -} - -internal m44 -M44Scale(v3 Scale) -{ - m44 Result = M44Identity(); - Result.AXx = Scale.x; - Result.AYy = Scale.y; - Result.AZz = Scale.z; - return Result; -} - -internal m44 -M44ScaleUniform(r32 Scale) -{ - m44 Result = M44Identity(); - Result.AXx = Scale; - Result.AYy = Scale; - Result.AZz = Scale; - return Result; -} - -internal m44 -M44CoordinateFrame(v4 Forward, v4 Right, v4 Up) -{ - m44 Result = {0}; - Result.AXx = Right.x; - Result.AYx = Right.y; - Result.AZx = Right.z; - Result.Tx = Right.w; - - Result.AXy = Up.x; - Result.AYy = Up.y; - Result.AZy = Up.z; - Result.Ty = Up.w; - - Result.AXz = Forward.x; - Result.AYz = Forward.y; - Result.AZz = Forward.z; - Result.Tz = Forward.w; - - Result.Tw = 1.0f; - return Result; -} - -internal m44 -M44ModelMatrix(v4 Forward, v4 Right, v4 Up, v4 Position) -{ - m44 RotationMatrix = M44CoordinateFrame(Forward, Right, Up); - m44 PositionMatrix = M44Translation(-Position); - m44 ModelViewMatrix = PositionMatrix * RotationMatrix; - return ModelViewMatrix; -} - -internal m44 -M44ProjectionOrtho(r32 Width, r32 Height, r32 Near, r32 Far, r32 Right, r32 Left, r32 Top, r32 Bottom) -{ - m44 Result = {0}; - Result.AXx = 2.0f / Width; - Result.AYy = 2.0f / Height; - Result.AZz = 2.0f / (Near - Far); - Result.AXw = -(Right + Left) / (Right - Left); - Result.AYw = -(Top + Bottom) / (Top - Bottom); - Result.AZw = -(Far + Near) / (Far - Near); - Result.Tw = 1; - return Result; -} - -internal m44 -M44ProjectionOrtho(r32 Aspect, r32 Scale, r32 Near, r32 Far) -{ - m44 Result = {0}; - r32 Width = Scale * Aspect; - r32 Height = Scale; - r32 Right = Width / 2.0f; - r32 Left = -Right; - r32 Top = Height / 2.0f; - r32 Bottom = -Top; - Result = M44ProjectionOrtho(Width, Height, Near, Far, Right, Left, Top, Bottom); - return Result; -} - -internal m44 -M44ProjectionInterfaceOrtho(r32 Width, r32 Height, r32 Near, r32 Far) -{ - m44 Result = {0}; - r32 Aspect = Width / Height; - r32 Right = Width; - r32 Left = 0; - r32 Top = Height; - r32 Bottom = 0; - Result = M44ProjectionOrtho(Width, Height, Near, Far, Right, Left, Top, Bottom); - return Result; -} - -internal m44 -M44ProjectionPerspective(r32 FieldOfViewDegrees, r32 AspectRatio, r32 Near, r32 Far) -{ - m44 Result = M44Identity(); - - // The perspective divide step involves dividing x and y by -z - // Making Tz = -1 will make Tw of the result = -z - Result.Tw = 0; - Result.AZw = -1; - - // Remap z' from the range [near clip : far clip] to [0 : 1] - r32 ViewRange = Far - Near; - Result.AZz = -((Far + Near) / ViewRange); - Result.Tz = -(2 * Near * Far) / ViewRange; - - // Adjust for field of view - adjust the x' and y coordinates based - // on how - r32 FovBasedScale = TanR32(DegToRadR32(FieldOfViewDegrees / 2)); - r32 Top = Near * FovBasedScale; - r32 Bottom = -Top; - r32 Right = Top * AspectRatio; - r32 Left = -Right; - Result.AXx = (2 * Near) / (Right - Left); - Result.AZx = (Right + Left) / (Right - Left); - Result.AYy = (2 * Near) / (Top - Bottom); - Result.AZy = (Top + Bottom) / (Top - Bottom); - - return Result; -} - -internal m44 -M44LookAt(v4 Position, v4 Target) -{ - // NOTE(Peter): the camera usually points along the -z axis, hence - // Forward = a ray that points from the target back towards your position - v4 Forward = V4Normalize(Position - Target); - v4 Right = V4Normalize(V4Cross(v4{0, 1, 0, 0}, Forward)); - v4 Up = V4Normalize(V4Cross(Forward, Right)); - m44 Result = M44CoordinateFrame(Forward, Right, Up); - return Result; -} - -/////////////////////////// -// -// Strings - -internal gs_const_string ConstString(char* Data, u64 Length) { return gs_const_string{Data, Length}; } -internal gs_const_string ConstString(char* Data) { return gs_const_string{Data, CStringLength(Data)}; } -internal gs_string MakeString(char* Data, u64 Length, u64 Size) -{ - Assert(Length <= Size); - gs_string Result = {0}; - Result.Str = Data; - Result.Length = Length; - Result.Size = Size; - return Result; -} -internal gs_string MakeString(char* Data, u64 Length) -{ - return MakeString(Data, Length, Length); -} -internal gs_string MakeString(char* Data) -{ - u64 StringLength = CStringLength(Data); - return MakeString(Data, StringLength, StringLength); -} -internal gs_string MakeString(gs_const_string ConstString) -{ - return MakeString(ConstString.Str, ConstString.Length); -} - -internal gs_data StringToData(gs_const_string String) -{ - gs_data Result = gs_data{0}; - Result.Memory = (u8*)String.Str; - Result.Size = String.Length * sizeof(char); - return Result; -} -internal gs_data StringToData(gs_string String) -{ - return StringToData(String.ConstString); -} -internal gs_const_string DataToString(gs_data Data) -{ - gs_const_string Result = {}; - Result.Str = (char*)Data.Memory; - Result.Length = Data.Size; - return Result; -} - -internal bool IsSlash(char C) { return ((C == '/') || (C == '\\')); } -internal bool IsUpper(char C) { return(('A' <= C) && (C <= 'Z')); } -internal bool IsLower(char C) { return(('a' <= C) && (C <= 'z')); } -internal bool IsWhitespace(char C) { return (C == ' ' || C == '\n' || C == '\r' || C == '\t' || C == '\f' || C == '\v'); } -internal bool IsNewline(char C) { return (C == '\n') || (C == '\r'); } -internal bool IsNewlineOrWhitespace (char C) { return IsNewline(C) || IsWhitespace(C); } -internal bool IsBase8(char C) { return (C >= '0' && C <= '7'); } -internal bool IsBase10(char C) { return (C >= '0' && C <= '9'); } -internal bool IsBase16(char C) { return (C >= '0' && C <= '9') || (C >= 'A' && C <= 'F'); } -internal bool IsNumericDecimal(char C) { return IsBase10(C) || (C == '.'); } -internal bool IsNumericExtended(char C) { return IsNumericDecimal(C) || (C == 'x') || (C == 'f') || (C == '-'); } -internal bool IsAlpha(char C) { return( (('a' <= C) && (C <= 'z')) || (('A' <= C) && (C <= 'Z')) || C == '_'); } -internal bool IsAlphaNumeric(char C) { return((('a' <= C) && (C <= 'z')) || (('A' <= C) && (C <= 'Z')) || (('0' <= C) && (C <= '9')) || C == '_'); } -internal bool IsOperator(char C) { - return ((C == '+') || (C == '-') || (C == '*') || (C == '/') || - (C == '=') || (C == '%') || (C == '<') || (C == '>')); -} - -internal char -ToUpper(char C) -{ - if ((C >= 'a') && (C <= 'z')) - { - C -= 'a' - 'A'; - } - return C; -} -internal char -ToLower(char C) -{ - if ((C >= 'A') && (C <= 'Z')) - { - C += 'a' - 'A'; - } - return C; -} -internal bool CharsEqualCaseInsensitive(char A, char B) { return ToLower(A) == ToLower(B); } - -internal u64 -CharArrayLength (char* CS) -{ - char* At = CS; - while (*At) { At++; } - return (u64)(At - CS); -} - -internal bool -IsNullTerminated(gs_const_string String) -{ - bool Result = false; - if (String.Str) - { - Result = (String.Str[String.Length] == 0); - } - return Result; -} -internal bool -IsNullTerminated(gs_string String) -{ - return IsNullTerminated(String.ConstString); -} - -internal char -GetChar(gs_const_string String, u64 I) -{ - char Result = 0; - if (I < String.Length) - { - Result = String.Str[I]; - } - return Result; -} -internal char -GetChar(gs_string String, u64 I) -{ - char Result = 0; - if (I < String.Length) - { - Result = String.Str[I]; - } - return Result; -} - -internal gs_const_string -GetStringPrefix(gs_const_string String, u64 Size) -{ - gs_const_string Result = String; - Result.Length = Min(Size, String.Length); - return Result; -} -internal gs_const_string -GetStringPostfix(gs_const_string String, u64 Size) -{ - gs_const_string Result = String; - u64 PostfixSize = Min(Size, String.Length); - Result.Str += (Result.Length - PostfixSize); - Result.Length = PostfixSize; - return Result; -} -internal gs_const_string -GetStringAfter(gs_const_string String, u64 Cut) -{ - gs_const_string Result = String; - u64 CutSize = Min(Cut, String.Length); - Result.Str += CutSize; - Result.Length -= CutSize; - return Result; -} -internal gs_string -GetStringAfter(gs_string String, u64 Cut) -{ - gs_string Result = {0}; - Result.ConstString = GetStringAfter(String.ConstString, Cut); - Result.Size = String.Size - Cut; - return Result; -} -internal gs_const_string -GetStringBefore(gs_const_string String, u64 Cut) -{ - gs_const_string Result = String; - Result.Length = Min(Cut, String.Length); - return Result; -} -internal gs_const_string -Substring(gs_const_string String, u64 First, u64 Last) -{ - gs_const_string Result = {0}; - Result.Str = String.Str + Min(First, String.Length); - Result.Length = Min(Last - First, String.Length); - return Result; -} -internal gs_const_string -Substring(gs_string String, u64 First, u64 Last) -{ - return Substring(String.ConstString, First, Last); -} - -internal s64 -FindFirst(gs_const_string String, u64 StartIndex, char C) -{ - s64 Result = -1; - for(u64 i = StartIndex; i < String.Length; i++) - { - if (String.Str[i] == C) { - Result = (s64)i; - break; - } - } - return Result; -} -internal s64 -FindFirst(gs_const_string String, char C) -{ - return FindFirst(String, 0, C); -} -internal s64 -FindFirst(gs_string String, u64 StartIndex, char C) -{ - return FindFirst(String.ConstString, StartIndex, C); -} -internal s64 -FindFirst(gs_string String, char C) -{ - return FindFirst(String.ConstString, 0, C); -} - -internal s64 -FindLast(char* String, s64 StartIndex, char C) -{ - s64 Result = -1; - s64 i = 0; - while (String[i] != 0 && i < StartIndex) - { - i++; - } - while (String[i]) - { - if (String[i] == C) - { - Result = i; - } - i++; - } - return Result; -} -internal s64 -FindLast(gs_const_string String, u64 StartIndex, char C) -{ - s64 Result = -1; - for(s64 i= StartIndex; i >= 0; i--) - { - if (String.Str[i] == C) { - Result = i; - break; - } - } - return (u64)Result; -} -internal s64 -FindLast(gs_const_string String, char C) -{ - return FindLast(String, String.Length - 1, C); -} -internal s64 -FindLast(gs_string String, u64 StartIndex, char C) -{ - return FindLast(String.ConstString, StartIndex, C); -} -internal s64 -FindLast(gs_string String, char C) -{ - return FindLast(String.ConstString, String.Length - 1, C); -} - -internal s64 -FindFirstFromSet(gs_const_string String, char* SetArray) -{ - gs_const_string Set = ConstString(SetArray); - s64 Result = -1; - - s64 CurrMin = String.Length; - for (u64 SetAt = 0; SetAt < Set.Length; SetAt++) - { - s64 Index = FindFirst(String, Set.Str[SetAt]); - if (Index >= 0 && Index < CurrMin) - { - CurrMin = Index; - } - } - - if (CurrMin < (s64)String.Length) - { - Result = CurrMin; - } - - return Result; -} - -internal s64 -FindLastFromSet(gs_const_string String, char* SetArray) -{ - gs_const_string Set = ConstString(SetArray); - s64 Result = -1; - for(s64 At = String.Length - 1; At >= 0; At--) - { - char CharAt = String.Str[At]; - for (u64 SetAt = 0; SetAt < Set.Length; SetAt++) - { - if (CharAt == Set.Str[SetAt]) - { - Result = (u64)At; - // NOTE(Peter): The alternative to this goto is a break in the inner loop - // followed by an if check in the outer loop, that must be evaluated - // every character you check. This is more efficient - goto find_first_from_set_complete; - } - } - } - find_first_from_set_complete: - return Result; -} - -internal bool -StringContains(gs_const_string Str, char C) -{ - bool Result = false; - for (u32 i = 0; i < Str.Length; i++) - { - if (Str.Str[i] == C) - { - Result = true; - break; - } - } - return Result; -} - -internal bool -StringsEqualUpToLength(gs_const_string A, gs_const_string B, u64 Length) -{ - bool Result = false; - if (A.Length >= Length && B.Length >= Length) - { - Result = true; - Length = Min(Length, A.Length); - for (u64 i = 0; i < Length; i++) - { - if (A.Str[i] != B.Str[i]) - { - Result = false; - break; - } - } - } - return Result; -} -internal bool -StringsEqual(gs_const_string A, gs_const_string B) -{ - bool Result = false; - if (A.Length == B.Length) - { - Result = StringsEqualUpToLength(A, B, A.Length); - } - return Result; -} -internal bool -StringEqualsCharArray(gs_const_string A, char* B, u64 Length) -{ - gs_const_string BStr = ConstString(B, Length); - return StringsEqual(A, BStr); -} -internal bool -StringEqualsCharArray(gs_const_string A, char* B) -{ - u64 Length = CStringLength(B); - return StringEqualsCharArray(A, B, Length); -} -internal bool -StringsEqualUpToLength(gs_string A, gs_string B, u64 Length) -{ - return StringsEqualUpToLength(A.ConstString, B.ConstString, Length); -} -internal bool -StringsEqual(gs_string A, gs_string B) -{ - return StringsEqual(A.ConstString, B.ConstString); -} -internal bool -StringEqualsCharArray(gs_string A, char* B, u64 Length) -{ - return StringEqualsCharArray(A.ConstString, B, Length); -} -internal bool -StringEqualsCharArray(gs_string A, char* B) -{ - return StringEqualsCharArray(A.ConstString, B); -} - -internal u64 -StringSizeLeft(gs_string String) -{ - u64 Result = String.Size - String.Length; - return Result; -} - -internal void -ReverseStringInPlace(gs_string* String) -{ - char* Start = String->Str; - char* End = String->Str + String->Length; - while (Start < End) - { - End--; - char Temp = End[0]; - End[0] = Start[0]; - Start[0] = Temp; - Start++; - } -} - -internal gs_const_string -GetCharSetForBase(u64 Base) -{ - gs_const_string Result = {0}; - switch(Base) - { - case 8: { Result = Base8Chars; }break; - case 10: { Result = Base10Chars; }break; - case 16: { Result = Base16Chars; }break; - InvalidDefaultCase; - } - return Result; -} -internal u64 -CharToUInt(char C, gs_const_string CharSet) -{ - return (u64)FindFirst(CharSet, C); -} -internal u64 -CharToUInt(char C) -{ - return (u64)CharToUInt(C, Base10Chars); -} -internal u64 -CharToUInt(char C, u64 Base) -{ - return CharToUInt(C, GetCharSetForBase(Base)); -} - -struct parse_uint_result -{ - b8 Success; - u64 Value; - u32 ParsedLength; -}; - -internal parse_uint_result -ValidateAndParseUInt(gs_const_string String, u64 Base = 10) -{ - parse_uint_result Result = {0}; - - gs_const_string CharSet = GetCharSetForBase(Base); - - bool StringIsValid = true; - for (u32 i = 0; i < String.Length; i++) - { - if (!StringContains(CharSet, String.Str[i])) - { - StringIsValid = false; - break; - } - } - - if (StringIsValid) - { - u64 Acc = 0; - u64 i = 0; - for (; i < String.Length; i++) - { - u64 CharIndex = FindFirst(CharSet, String.Str[i]); - if (CharIndex < CharSet.Length) - { - Acc = CharToUInt(String.Str[i], CharSet) + (Acc * Base); - } - else - { - break; - } - } - - Result.Success = true; - Result.Value = Acc; - Result.ParsedLength = i; - } - - return Result; -} - -internal u64 -ParseUInt(gs_const_string String, u64 Base = 10, u64* ParsedLength = 0) -{ - parse_uint_result ParseResult = ValidateAndParseUInt(String, Base); - Assert(ParseResult.Success); - if (ParsedLength) - { - *ParsedLength = ParseResult.ParsedLength; - } - return ParseResult.Value; -} -internal u64 -ParseUInt(u64 Length, char* String, u64 Base = 10, u64* ParsedLength = 0) -{ - return ParseUInt(ConstString(String, Length), Base, ParsedLength); -} -internal u64 -ParseUInt(char* String, u64 Base = 10, u64* ParsedLength = 0) -{ - return ParseUInt(LitString(String), Base, ParsedLength); -} - -internal s64 -ParseInt(gs_const_string String, u64 Base = 10, u64* ParsedLength = 0) -{ - s64 Result = 0; - u64 TempParsedLength = 0; - if (String.Str[0] == '-') - { - Result = -1 * (s64)ParseUInt(GetStringAfter(String, 1), Base, &TempParsedLength); - TempParsedLength += 1; - } - else - { - Result = (s64)ParseUInt(String, Base, &TempParsedLength); - } - if (ParsedLength != 0) - { - *ParsedLength = TempParsedLength; - } - return Result; -} -internal s64 -ParseInt(char* String, u64 Base = 10, u64* ParsedLength = 0) -{ - return ParseInt(LitString(String), Base, ParsedLength); -} - -struct parse_float_result -{ - b8 Success; - r64 Value; - u64 ParsedLength; -}; - -internal parse_float_result -ValidateAndParseFloat(gs_const_string String) -{ - parse_float_result Result = {0}; - Result.Success = false; - - // Validate - bool StringIsValid = true; - for (u64 i = 0; i < String.Length; i++) - { - if (!IsNumericDecimal(String.Str[i]) && String.Str[i] != '-') - { - StringIsValid = false; - break; - } - } - - if (StringIsValid) - { - s64 DecimalIndex = FindFirst(String, '.'); - u64 TempParsedLength = 0; - u64 PlacesAfterPoint = 0; - - gs_const_string IntegerString = GetStringBefore(String, DecimalIndex); - gs_const_string DecimalString = {}; - if (DecimalIndex >= 0) - { - DecimalString = GetStringAfter(String, DecimalIndex + 1); - } - - r32 Polarity = 1; - if (IntegerString.Str[0] == '-') - { - IntegerString = GetStringAfter(IntegerString, 1); - Polarity = -1; - } - - Result.Value = (r64)ParseInt(IntegerString, 10, &TempParsedLength); - - if (TempParsedLength == IntegerString.Length) - { - r64 AfterPoint = (r64)ParseUInt(DecimalString, 10, &PlacesAfterPoint); - r64 Decimal = (AfterPoint / PowR64(10, PlacesAfterPoint)); - Result.Value = Result.Value + Decimal; - Result.Value *= Polarity; - } - - Result.ParsedLength = TempParsedLength + PlacesAfterPoint; - if (DecimalIndex < (s64)String.Length) { Result.ParsedLength += 1; } - - Result.Success = true; - } - - return Result; -} - -internal r64 -ParseFloat(gs_const_string String, u64* ParsedLength = 0) -{ - parse_float_result Result = ValidateAndParseFloat(String); - Assert(Result.Success); - if (ParsedLength != 0) - { - *ParsedLength = Result.ParsedLength; - } - return Result.Value; -} -internal r64 -ParseFloat(char* String, u64* ParsedLength = 0) -{ - return ParseFloat(LitString(String), ParsedLength); -} - -internal u64 -AppendString(gs_string* Base, gs_const_string Appendix) -{ - u64 StartIndex = Base->Length; - u64 LengthAvailable = Base->Size - Base->Length; - u64 Written = 0; - for (; Written < Min(LengthAvailable, Appendix.Length); Written++) - { - Base->Str[StartIndex + Written] = Appendix.Str[Written]; - } - Base->Length += Written; - Assert(Base->Length <= Base->Size); - return Written; -} -internal u64 -AppendString(gs_string* Base, gs_string Appendix) -{ - return AppendString(Base, Appendix.ConstString); -} - -internal void -InsertAt(gs_string* Str, u64 Index, char C) -{ - if (Str->Length > Index) - { - for (u64 i = Str->Length; i > Index; i--) - { - Str->Str[i] = Str->Str[i - 1]; - } - } - - if (Index < Str->Size) - { - Str->Str[Index] = C; - Str->Length += 1; - Assert(Str->Length < Str->Size); - } -} - -internal void -RemoveAt(gs_string* Str, u64 Index) -{ - if (Str->Length > 0 && Index < Str->Length) - { - for (u64 i = Index; i < Str->Length - 1; i++) - { - Str->Str[i] = Str->Str[i + 1]; - } - Str->Length -= 1; - } -} - -internal void -NullTerminate(gs_string* String) -{ - if (String->Length < String->Size) - { - String->Str[String->Length] = 0; - } - else - { - String->Str[String->Length - 1] = 0; - } -} - -internal void -OutChar(gs_string* String, char C) -{ - if (String->Length < String->Size) - { - String->Str[String->Length++] = C; - } -} - -internal void -U64ToASCII(gs_string* String, u64 Value, u64 Base, gs_const_string Digits) -{ - u64 ValueRemaining = Value; - u64 At = 0; - do { - u64 Index = ValueRemaining % Base; - char Digit = Digits.Str[Index]; - OutChar(String, Digit); - ValueRemaining /= Base; - }while(ValueRemaining); - char* End = String->Str + String->Length; - ReverseStringInPlace(String); -} - -internal void -U64ToASCII(gs_string* String, u64 Value, u64 Base) -{ - U64ToASCII(String, Value, Base, GetCharSetForBase(Base)); -} - -internal void -R64ToASCII(gs_string* String, r64 Value, u64 Precision) -{ - if (Value < 0) - { - OutChar(String, '-'); - Value = Abs(Value); - } - u64 IntegerPart = (u64)Value; - // NOTE(Peter): If we don't use the inner string, when U64ToASCII reverses the characters - // it'll put the negative sign at the end. - gs_string IntegerString = GetStringAfter(*String, String->Length); - U64ToASCII(&IntegerString, IntegerPart, 10); - String->Length += IntegerString.Length; - Value -= IntegerPart; - if (Value > 0) - { - OutChar(String, '.'); - for (u64 i = 0; i < Precision; i++) - { - Value *= 10.0f; - u64 DecimalPlace = (u64)Value; - Value -= DecimalPlace; - OutChar(String, Base10Chars.Str[DecimalPlace]); - } - } -} - -internal s64 -ReadVarArgsSignedInteger (s32 Width, va_list* Args) -{ - s64 Result = 0; - switch (Width) - { - // NOTE(Peter): For Width lower than 4 bytes, the C++ spec specifies - // that it will get promoted to an int anyways - case 1: { Result = (s64)va_arg(*Args, s32); } break; - case 2: { Result = (s64)va_arg(*Args, s32); } break; - case 4: { Result = (s64)va_arg(*Args, s32); } break; - case 8: { Result = (s64)va_arg(*Args, s64); } break; - InvalidDefaultCase; - } - return Result; -} - -internal r64 -ReadVarArgsUnsignedInteger (s32 Width, va_list* Args) -{ - u64 Result = 0; - switch (Width) - { - // NOTE(Peter): For Width lower than 4 bytes, the C++ spec specifies - // that it will get promoted to an int anyways - case 1: { Result = (u64)va_arg(*Args, u32); } break; - case 2: { Result = (u64)va_arg(*Args, u32); } break; - case 4: { Result = (u64)va_arg(*Args, u32); } break; - case 8: { Result = (u64)va_arg(*Args, u64); } break; - InvalidDefaultCase; - } - return Result; -} - -internal r64 -ReadVarArgsFloat (s32 Width, va_list* Args) -{ - r64 Result = 0; - switch (Width) - { - case 4: { Result = (r64)va_arg(*Args, r64); } break; - case 8: { Result = (r64)va_arg(*Args, r64); } break; - InvalidDefaultCase; - } - return Result; -} - -internal s32 -PrintFArgsList (gs_string* String, char* Format, va_list Args) -{ - char* FormatAt = Format; - while (*FormatAt) - { - if (FormatAt[0] != '%') - { - if (FormatAt[0] == '\\') - { - OutChar(String, *FormatAt++); - } - else - { - OutChar(String, *FormatAt++); - } - } - else if (FormatAt[0] == '%' && FormatAt[1] == '%') // Print the % symbol - { - OutChar(String, '%'); - FormatAt += 2; - } - else - { - FormatAt++; - - // Flags - if (FormatAt[0] == '-') - { - FormatAt++; - } - else if (FormatAt[0] == '+') - { - FormatAt++; - } - else if (FormatAt[0] == ' ') - { - FormatAt++; - } - else if (FormatAt[0] == '#') - { - FormatAt++; - } - else if (FormatAt[0] == '0') - { - FormatAt++; - } - - // Width - b32 WidthSpecified = false; - s32 Width = 0; - - if (IsBase10(FormatAt[0])) - { - WidthSpecified = true; - u64 Parsed = 0; - AssertMessage("ParseInt assumes whole string is an integer"); - Width = (s32)ParseInt(FormatAt, 10, &Parsed); - FormatAt += Parsed; - } - else if (FormatAt[0] == '*') - { - WidthSpecified = true; - Width = va_arg(Args, s32); - Assert(Width >= 0); - FormatAt++; - } - - // Precision - b32 PrecisionSpecified = false; - s32 Precision = 0; - - if (FormatAt[0] == '.') - { - FormatAt++; - if (IsBase10(FormatAt[0])) - { - PrecisionSpecified = true; - - gs_const_string PrecisionStr = {}; - PrecisionStr.Str = FormatAt; - for (char* C = FormatAt; *FormatAt && IsBase10(*C); C++) - { - PrecisionStr.Length++; - } - u64 Parsed = 0; - Precision = (s32)ParseInt(PrecisionStr, 10, &Parsed); - FormatAt += Parsed; - } - else if (FormatAt[0] == '*') - { - PrecisionSpecified = true; - Precision = va_arg(Args, s32); - Assert(Precision >= 0); - FormatAt++; - } - } - - // Length - b32 LengthSpecified = false; - s32 Length = 4; - - if (FormatAt[0] == 'h' && FormatAt[1] == 'h') - { - LengthSpecified = true; - Length = 1; - FormatAt += 2; - } - else if (FormatAt[0] == 'h') - { - LengthSpecified = true; - Length = 2; - FormatAt++; - } - else if (FormatAt[0] == 'l' && FormatAt[1] == 'l') - { - LengthSpecified = true; - Length = 8; - FormatAt += 2; - } - else if (FormatAt[0] == 'l') - { - LengthSpecified = true; - Length = 4; - FormatAt++; - } - else if (FormatAt[0] == 'j') - { - LengthSpecified = true; - Length = 8; - FormatAt++; - } - else if (FormatAt[0] == 'z') - { - FormatAt++; - } - else if (FormatAt[0] == 't') - { - FormatAt++; - } - else if (FormatAt[0] == 'L') - { - FormatAt++; - } - - // Format Specifiers - gs_string StringRemaining = GetStringAfter(*String, String->Length); - Assert(StringRemaining.Length == 0); - if (FormatAt[0] == 'd' || FormatAt[0] == 'i') - { - s64 SignedInt = ReadVarArgsSignedInteger(Length, &Args); - if (SignedInt < 0) - { - OutChar(&StringRemaining, '-'); - SignedInt *= -1; - } - U64ToASCII(&StringRemaining, (u64)SignedInt, 10, Base10Chars); - } - else if (FormatAt[0] == 'u') - { - u64 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); - U64ToASCII(&StringRemaining, UnsignedInt, 10, Base10Chars); - } - else if (FormatAt[0] == 'o') - { - u32 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); - U64ToASCII(&StringRemaining, UnsignedInt, 8, Base8Chars); - } - else if (FormatAt[0] == 'x' || FormatAt[0] == 'X') - { - u32 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); - U64ToASCII(&StringRemaining, UnsignedInt, 16, Base16Chars); - } - else if (FormatAt[0] == 'f' || FormatAt[0] == 'F') - { - r64 Float = ReadVarArgsFloat(Length, &Args); - s32 AfterPoint = 6; - if (PrecisionSpecified) - { - AfterPoint = Precision; - } - R64ToASCII(&StringRemaining, Float, AfterPoint); - } - else if (FormatAt[0] == 'c') - { - char InsertChar = va_arg(Args, s32); - OutChar(&StringRemaining, InsertChar); - } - else if (FormatAt[0] == 's') - { - char* InsertString = va_arg(Args, char*); - - s32 InsertStringLength = CStringLength(InsertString); - if (PrecisionSpecified) - { - InsertStringLength = Min(InsertStringLength, Precision); - } - InsertStringLength = Min(StringSizeLeft(StringRemaining), InsertStringLength); - - for (s32 c = 0; c < InsertStringLength; c++) - { - OutChar(&StringRemaining, InsertString[c]); - } - } - else if (FormatAt[0] == 'S') - { - gs_const_string InsertString = va_arg(Args, gs_const_string); - - for (s32 c = 0; c < InsertString.Length; c++) - { - OutChar(&StringRemaining, InsertString.Str[c]); - } - } - else if (FormatAt[0] == 'p') - { - // TODO(Peter): Pointer Address - } - else - { - // NOTE(Peter): Non-specifier character found - InvalidCodePath; - } - - String->Length += StringRemaining.Length; - FormatAt++; - } - } - - return String->Length; -} - -internal void -PrintF (gs_string* String, char* Format, ...) -{ - va_list Args; - va_start(Args, Format); - String->Length = 0; - PrintFArgsList(String, Format, Args); - va_end(Args); -} -internal void -PrintF (gs_string* String, const char* Format, ...) -{ - // NOTE(Peter): This variant is here for clang/gcc - C++ spec doesn't allow - // implicit conversion from a const char* (a static c string) to char*, so this - // version of the function just provides the conversion so the compiler will be quiet - // without removing the other implementation, which is more useful - va_list Args; - va_start(Args, Format); - String->Length = 0; - PrintFArgsList(String, (char*)Format, Args); - va_end(Args); -} - -internal void -AppendPrintF (gs_string* String, char* Format, ...) -{ - va_list Args; - va_start(Args, Format); - PrintFArgsList(String, Format, Args); - va_end(Args); -} -internal void -AppendPrintF (gs_string* String, const char* Format, ...) -{ - // NOTE(Peter): This variant is here for clang/gcc - C++ spec doesn't allow - // implicit conversion from a const char* (a static c string) to char*, so this - // version of the function just provides the conversion so the compiler will be quiet - // without removing the other implementation, which is more useful - va_list Args; - va_start(Args, Format); - PrintFArgsList(String, (char*)Format, Args); - va_end(Args); -} - -/////////////////////////// -// -// Memory - -internal gs_data -CreateData(u8* Memory, u64 Size) -{ - gs_data Result = {Memory, Size}; - return Result; -} -internal bool -DataIsNonEmpty(gs_data Data) -{ - return ((Data.Size > 0) && (Data.Memory != 0)); -} - -#define PushStringF(a,l,f,...) PushStringF_((a),(l),(f), DEBUG_LOC, __VA_ARGS__) -internal gs_string -PushStringF_(gs_memory_arena* Arena, u32 MaxLength, char* Format, gs_debug_loc Loc, ...) -{ - gs_string Result = gs_string { - (char*)PushSize_(Arena, sizeof(char) * MaxLength, Loc).Memory, // Str - 0, // Length - MaxLength, // Size - }; - - va_list Args; - va_start(Args, Loc); - PrintFArgsList(&Result, Format, Args); - va_end(Args); - - return Result; -} - -internal gs_string -PushStringCopy(gs_memory_arena* Arena, gs_const_string String) -{ - gs_string Result = PushString(Arena, String.Length); - Result.Size = String.Length; - Result.Length = String.Length; - for (u32 i = 0; i < String.Length; i++) - { - Result.Str[i] = String.Str[i]; - } - return Result; -} - -/////////////////////////// -// -// Debug Print - -inline void -DebugPrint(debug_output Output, gs_const_string Message) -{ - Output.Print(Output, Message); -} - -inline void -DebugPrint(debug_output Output, char* Message) -{ - gs_const_string String = ConstString(Message); - Output.Print(Output, String); -} - -internal void -DebugPrintF(debug_output Output, char* Format, ...) -{ - gs_string Message = PushString(Output.Storage, 1024); - va_list Args; - va_start(Args, Format); - PrintFArgsList(&Message, Format, Args); - NullTerminate(&Message); - Output.Print(Output, Message.ConstString); -} - -#define HandlesAreEqual(ha, hb) ((ha.IndexInBuffer == hb.IndexInBuffer) && (ha.BufferIndex == hb.BufferIndex)) - -/////////////////////////// -// -// String Builder - -internal void -GrowStringBuilder_(gs_string_builder* StringBuilder) -{ - gs_string_builder_buffer* NewBuffer = PushStruct(StringBuilder->Arena, gs_string_builder_buffer); - NewBuffer->String = PushString(StringBuilder->Arena, StringBuilder->BufferSize); - SLLPushOrInit(StringBuilder->Root, StringBuilder->Head, NewBuffer); -} - -internal void -OutChar(gs_string_builder* Builder, char C) -{ - if (Builder->Head == 0 || Builder->Head->String.Length >= Builder->Head->String.Size) - { - GrowStringBuilder_(Builder); - } - OutChar(&Builder->Head->String, C); -} - -#if 0 -// TODO: If you need a string builder come back here, otherwise this can stay 0'd out -// was getting in the way -internal void -StringBuilderWriteFArgsList(gs_string_builder* Builder, char* Format, va_list Args) -{ - char* FormatAt = Format; - while (*FormatAt) - { - if (FormatAt[0] != '%') - { - if (FormatAt[0] == '\\') - { - FormatAt++; - Assert(IsBase8(FormatAt[0]) || // Octal Escape Sequences - \0 is in this set - FormatAt[0] == '\'' || - FormatAt[0] == '\"' || - FormatAt[0] == '\?' || - FormatAt[0] == '\\' || - FormatAt[0] == 'a' || // Audible Bell - FormatAt[0] == 'b' || // Backspace - FormatAt[0] == 'f' || // Form Feed - New Page - FormatAt[0] == 'n' || // Line Feed - New Line - FormatAt[0] == 'r' || // Carriage Return - FormatAt[0] == 't' || // Tab - FormatAt[0] == 'v'); // Vertical Tab - - // Not Handled (see cpp spec) \nnn \xnn \unnnn \Unnnnnnnn - Assert(FormatAt[0] != 'x' || FormatAt[0] != 'u' || FormatAt[0] != 'U'); - - if (IsBase8(FormatAt[0])) - { - // TODO(Peter): this should keep going until it finds a non-octal character code - // but the only one we really need is \0 atm so I'm just handling that one - Assert(FormatAt[0] == '0'); - OutChar(Builder, (char)0); - FormatAt++; - } - else - { - OutChar(Builder, *FormatAt++); - } - } - else - { - OutChar(Builder, *FormatAt++); - } - } - else if (FormatAt[0] == '%' && FormatAt[1] == '%') // Print the % symbol - { - OutChar(Builder, '%'); - FormatAt += 2; - } - else - { - FormatAt++; - - // Flags - if (FormatAt[0] == '-') - { - FormatAt++; - } - else if (FormatAt[0] == '+') - { - FormatAt++; - } - else if (FormatAt[0] == ' ') - { - FormatAt++; - } - else if (FormatAt[0] == '#') - { - FormatAt++; - } - else if (FormatAt[0] == '0') - { - FormatAt++; - } - - // Width - b32 WidthSpecified = false; - s32 Width = 0; - - if (IsBase10(FormatAt[0])) - { - WidthSpecified = true; - u64 Parsed = 0; - AssertMessage("ParseInt assumes whole string is an integer"); - Width = (s32)ParseInt(FormatAt, 10, &Parsed); - FormatAt += Parsed; - } - else if (FormatAt[0] == '*') - { - WidthSpecified = true; - Width = va_arg(Args, s32); - Assert(Width >= 0); - FormatAt++; - } - - // Precision - b32 PrecisionSpecified = false; - s32 Precision = 0; - - if (FormatAt[0] == '.') - { - FormatAt++; - if (IsBase10(FormatAt[0])) - { - - PrecisionSpecified = true; - u64 Parsed = 0; - AssertMessage("ParseInt assumes whole string is an integer"); - Precision = (s32)ParseInt(FormatAt, 10, &Parsed); - FormatAt += Parsed; - } - else if (FormatAt[0] == '*') - { - PrecisionSpecified = true; - Precision = va_arg(Args, s32); - Assert(Precision >= 0); - FormatAt++; - } - } - - // Length - b32 LengthSpecified = false; - s32 Length = 4; - - if (FormatAt[0] == 'h' && FormatAt[1] == 'h') - { - LengthSpecified = true; - LengthSpecified = 1; - FormatAt += 2; - } - else if (FormatAt[0] == 'h') - { - LengthSpecified = true; - LengthSpecified = 2; - FormatAt++; - } - else if (FormatAt[0] == 'l' && FormatAt[1] == 'l') - { - LengthSpecified = true; - LengthSpecified = 8; - FormatAt += 2; - } - else if (FormatAt[0] == 'l') - { - LengthSpecified = true; - LengthSpecified = 4; - FormatAt++; - } - else if (FormatAt[0] == 'j') - { - LengthSpecified = true; - LengthSpecified = 8; - FormatAt++; - } - else if (FormatAt[0] == 'z') - { - FormatAt++; - } - else if (FormatAt[0] == 't') - { - FormatAt++; - } - else if (FormatAt[0] == 'L') - { - FormatAt++; - } - - // Format Specifiers - gs_string StringRemaining = GetStringAfter(*String, String->Length); - Assert(StringRemaining.Length == 0); - if (FormatAt[0] == 'd' || FormatAt[0] == 'i') - { - s64 SignedInt = ReadVarArgsSignedInteger(Length, &Args); - if (SignedInt < 0) - { - OutChar(&StringRemaining, '-'); - SignedInt *= -1; - } - U64ToASCII(&StringRemaining, (u64)SignedInt, 10, Base10Chars); - } - else if (FormatAt[0] == 'u') - { - u32 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); - U64ToASCII(&StringRemaining, UnsignedInt, 10, Base10Chars); - } - else if (FormatAt[0] == 'o') - { - u32 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); - U64ToASCII(&StringRemaining, UnsignedInt, 8, Base8Chars); - } - else if (FormatAt[0] == 'x' || FormatAt[0] == 'X') - { - u32 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); - U64ToASCII(&StringRemaining, UnsignedInt, 16, Base16Chars); - } - else if (FormatAt[0] == 'f' || FormatAt[0] == 'F') - { - r64 Float = ReadVarArgsFloat(Length, &Args); - s32 AfterPoint = 6; - if (PrecisionSpecified) - { - AfterPoint = Precision; - } - R64ToASCII(&StringRemaining, Float, AfterPoint); - } - else if (FormatAt[0] == 'c') - { - char InsertChar = va_arg(Args, s32); - OutChar(&StringRemaining, InsertChar); - } - else if (FormatAt[0] == 's') - { - char* InsertString = va_arg(Args, char*); - - s32 InsertStringLength = CStringLength(InsertString); - if (PrecisionSpecified) - { - InsertStringLength = Min(InsertStringLength, Precision); - } - InsertStringLength = Min(StringSizeLeft(StringRemaining), InsertStringLength); - - for (s32 c = 0; c < InsertStringLength; c++) - { - OutChar(&StringRemaining, InsertString[c]); - } - } - else if (FormatAt[0] == 'S') - { - gs_const_string InsertString = va_arg(Args, gs_const_string); - - for (s32 c = 0; c < InsertString.Length; c++) - { - OutChar(&StringRemaining, InsertString.Str[c]); - } - } - else if (FormatAt[0] == 'p') - { - // TODO(Peter): Pointer Address - } - else - { - // NOTE(Peter): Non-specifier character found - InvalidCodePath; - } - - String->Length += StringRemaining.Length; - FormatAt++; - } - } - - return String->Length; -} - -internal void -StringBuilderWriteF(gs_string_builder* Builder, char* Format, ...) -{ - va_list Args; - va_start(Args, Format); - StringBuilderWriteFArgsList(Builder, Format, Args); - va_end(Args); -} - -#endif // String builder - -/////////////////////////// -// -// File Handler - -internal u64 -FileHandlerGetFileInfo_NoOp(gs_file_handler FileHandler, gs_const_string Path) -{ - return 0; -} - -internal gs_file -FileHandlerReadFile_NoOp(gs_const_string Path) -{ - return gs_file{0}; -} - -internal bool -FileHandlerWriteFile_NoOp(gs_const_string Path, gs_data Data) -{ - return false; -} - -internal gs_const_string_array -FileHandlerEnumerateDirectory_NoOp(gs_const_string Path, bool Recursive, bool IncludeDirs) -{ - return gs_const_string_array{0}; -} - -internal gs_file_handler -CreateFileHandler(file_handler_get_file_info* GetFileInfo, - file_handler_read_entire_file* ReadEntireFile, - file_handler_write_entire_file* WriteEntireFile, - file_handler_enumerate_directory* EnumerateDirectory, - gs_memory_arena* Transient) -{ - if (GetFileInfo == 0) - { - GetFileInfo = (file_handler_get_file_info*)FileHandlerGetFileInfo_NoOp; - } - if (ReadEntireFile == 0) - { - ReadEntireFile = (file_handler_read_entire_file*)FileHandlerReadFile_NoOp; - } - if (WriteEntireFile == 0) - { - WriteEntireFile = (file_handler_write_entire_file*)FileHandlerWriteFile_NoOp; - } - if (EnumerateDirectory == 0) - { - EnumerateDirectory = (file_handler_enumerate_directory*)FileHandlerEnumerateDirectory_NoOp; - } - gs_file_handler Result = {0}; - Result.GetFileInfo = GetFileInfo; - Result.ReadEntireFile = ReadEntireFile; - Result.WriteEntireFile = WriteEntireFile; - Result.EnumerateDirectory = EnumerateDirectory; - Result.Transient = Transient; - - return Result; -} - -internal gs_const_string -GetNullTerminatedPath(gs_file_handler FileHandler, gs_const_string Path) -{ - gs_const_string Result = {}; - if (!IsNullTerminated(Path)) - { - gs_string NullTermPath = PushString(FileHandler.Transient, Path.Length + 1); - PrintF(&NullTermPath, "%S", Path); - NullTerminate(&NullTermPath); - Result = NullTermPath.ConstString; - } - else - { - Result = Path; - } - return Result; -} - -internal gs_file_info -GetFileInfo(gs_file_handler FileHandler, gs_const_string Path) -{ - Assert(FileHandler.GetFileInfo != 0); - - Path = GetNullTerminatedPath(FileHandler, Path); - gs_file_info Result = FileHandler.GetFileInfo(FileHandler, Path); - return Result; -} - -internal gs_file -ReadEntireFile(gs_file_handler FileHandler, gs_const_string Path, gs_data Memory) -{ - Assert(FileHandler.ReadEntireFile != 0); - - Path = GetNullTerminatedPath(FileHandler, Path); - gs_file Result = FileHandler.ReadEntireFile(FileHandler, Path, Memory); - return Result; -} - -internal gs_file -ReadEntireFile(gs_file_handler FileHandler, gs_const_string Path) -{ - Assert(FileHandler.GetFileInfo != 0); - Assert(FileHandler.ReadEntireFile != 0); - - Path = GetNullTerminatedPath(FileHandler, Path); - gs_file Result = {0}; - gs_file_info FileInfo = FileHandler.GetFileInfo(FileHandler, Path); - if (FileInfo.FileSize > 0) - { - gs_data FileMemory = PushSize(FileHandler.Transient, FileInfo.FileSize); - Result = ReadEntireFile(FileHandler, Path, FileMemory); - } - return Result; -} - -internal bool -WriteEntireFile(gs_file_handler FileHandler, gs_const_string Path, gs_data Memory) -{ - Assert(FileHandler.WriteEntireFile != 0); - - Path = GetNullTerminatedPath(FileHandler, Path); - return FileHandler.WriteEntireFile(FileHandler, Path, Memory); -} - -internal gs_file_info_array -EnumerateDirectory(gs_file_handler FileHandler, gs_memory_arena* Storage, gs_const_string Path, u32 Flags) -{ - Assert(FileHandler.EnumerateDirectory != 0); - - Path = GetNullTerminatedPath(FileHandler, Path); - return FileHandler.EnumerateDirectory(FileHandler, Storage, Path, Flags); -} - -internal bool -FileNoError(gs_file File) -{ - bool Result = (File.Size > 0); - return Result; -} - -////////////////////////// -// -// Timing - -internal s64 -TimeHandlerGetWallClock(gs_time_handler TimeHandler) -{ - s64 Result = TimeHandler.GetWallClock(); - return Result; -} - -internal s64 -TimeHandlerGetSecondsElapsed(gs_time_handler TimeHandler, s64 StartCycles, s64 EndCycles) -{ - s64 Result = TimeHandler.GetSecondsElapsed(StartCycles, EndCycles); - return Result; -} - -////////////////////////// -// -// Thread Manager - -CREATE_THREAD(CreateThreadStub) -{ - return {}; -} - - -KILL_THREAD(KillThreadStub) -{ - return false; -} - -internal platform_thread_manager -CreatePlatformThreadManager(platform_create_thread* CreateThreadProc, - platform_kill_thread* KillThreadProc) -{ - platform_thread_manager Result = {}; - Result.CreateThreadProc = CreateThreadProc; - Result.KillThreadProc = KillThreadProc; - - if (!CreateThreadProc) - { - Result.CreateThreadProc = CreateThreadStub; - } - if (!KillThreadProc) - { - Result.KillThreadProc = KillThreadStub; - } - - return Result; -} - -internal platform_thread_handle -CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg, gs_thread_context Ctx) -{ - platform_thread_handle Result = {}; - - for (u32 i = 1; i < THREADS_MAX; i++) - { - if (!Manager->ThreadsUsed[i]) - { - Result.Index = i; - break; - } - } - Assert(Result.Index != 0); - - Manager->ThreadsUsed[Result.Index] = true; - Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg, Ctx); - - return Result; -} - -internal bool -KillThread(platform_thread_manager* Manager, platform_thread_handle Handle) -{ - Assert(Manager->ThreadsUsed[Handle.Index]); - - platform_thread* Thread = &Manager->Threads[Handle.Index]; - bool Result = Manager->KillThreadProc(Thread); - - if (Result) - { - Manager->ThreadsUsed[Handle.Index] = false; - Manager->Threads[Handle.Index] = {}; - } - - return Result; -} - - -////////////////////////// -// -// Socket Manager - -CONNECT_SOCKET(PlatformConnectSocket_Stub) -{ - return false; -} - -CLOSE_SOCKET(PlatformCloseSocket_Stub) -{ - return false; -} - -SOCKET_QUERY_STATUS(PlatformSocketQueryStatus_Stub) -{ - return false; -} - -SOCKET_PEEK(PlatformSocketPeek_Stub) -{ - return 0; -} - -SOCKET_RECEIVE(PlatformSocketRecieve_Stub) -{ - return {}; -} - -SOCKET_SEND(PlatformSocketSend_Stub) -{ - return false; -} - -internal platform_socket_manager -CreatePlatformSocketManager(platform_connect_socket* ConnectSocketProc, - platform_close_socket* CloseSocketProc, - platform_socket_query_status* SocketQueryStatusProc, - platform_socket_peek* SocketPeekProc, - platform_socket_receive* SocketRecieveProc, - platform_socket_send* SocketSendProc) -{ - platform_socket_manager Result = {}; - Result.ConnectSocketProc = ConnectSocketProc; - Result.CloseSocketProc = CloseSocketProc; - Result.SocketQueryStatusProc = SocketQueryStatusProc; - Result.SocketPeekProc = SocketPeekProc; - Result.SocketRecieveProc = SocketRecieveProc; - Result.SocketSendProc = SocketSendProc; - - if (!ConnectSocketProc) - { - Result.ConnectSocketProc = PlatformConnectSocket_Stub; - } - if (!CloseSocketProc) - { - Result.CloseSocketProc = PlatformCloseSocket_Stub; - } - if (!SocketQueryStatusProc) - { - Result.SocketQueryStatusProc = PlatformSocketQueryStatus_Stub; - } - if (!SocketPeekProc) - { - Result.SocketPeekProc = PlatformSocketPeek_Stub; - } - if (!SocketRecieveProc) - { - Result.SocketRecieveProc = PlatformSocketRecieve_Stub; - } - if (!SocketSendProc) - { - Result.SocketSendProc = PlatformSocketSend_Stub; - } - return Result; -} - -internal bool -SocketHandleIsValid(platform_socket_handle_ Handle) -{ - return Handle.Index != 0; -} - -internal platform_socket* -SocketManagerGetSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) -{ - platform_socket* Result = 0; - if (Manager->SocketsUsed[Handle.Index]) - { - platform_socket* Socket = &Manager->Sockets[Handle.Index]; - if (Socket->PlatformHandle != 0) - { - Result = Socket; - } - } - return Result; -} - -internal bool -ConnectSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) -{ - bool Result = false; - platform_socket* Socket = SocketManagerGetSocket(Manager, Handle); - if (Socket) - { - Result = Manager->ConnectSocketProc(Manager, Socket); - } - return Result; -} - -internal bool -RemoveSocket (platform_socket_manager* Manager, platform_socket_handle_ Handle) -{ - bool Result = Manager->SocketsUsed[Handle.Index]; - Manager->SocketsUsed[Handle.Index] = false; - return Result; -} - -internal platform_socket_handle_ -CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port) -{ - platform_socket_handle_ Result = {}; - for (u32 i = 1; i < SOCKETS_COUNT_MAX; i++) - { - if (!Manager->SocketsUsed[i]) - { - Result.Index = i; - Manager->SocketsUsed[i] = true; - break; - } - } - - Assert(Result.Index != 0); - platform_socket* Socket = &Manager->Sockets[Result.Index]; - Socket->Handle = Result; - CopyArray(Addr, Socket->Addr, char, CStringLength(Addr) + 1); - CopyArray(Port, Socket->Port, char, CStringLength(Port) + 1); - - bool Success = Manager->ConnectSocketProc(Manager, Socket); - if (!Success) - { - if (RemoveSocket(Manager, Result)) - { - Result = {}; - } - else - { - InvalidCodePath; - } - } - - return Result; -} - -internal bool -CloseSocket(platform_socket_manager* Manager, platform_socket* Socket) -{ - bool Result = false; - if (Socket) - { - if (Manager->CloseSocketProc(Manager, Socket)) - { - RemoveSocket(Manager, Socket->Handle); - *Socket = {}; - Result = true; - } - else - { - InvalidCodePath; - } - } - return Result; -} - -internal bool -CloseSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) -{ - bool Result = false; - platform_socket* Socket = SocketManagerGetSocket(Manager, Handle); - return CloseSocket(Manager, Socket); -} - -// NOTE(pjs): returns true if the socket is connected -internal bool -SocketQueryStatus(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle) -{ - bool Result = false; - platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); - if (Socket) - { - Result = Manager->SocketQueryStatusProc(Manager, Socket); - } - return Result; -} - -internal u32 -SocketPeek(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle) -{ - u32 Result = 0; - platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); - if (Socket) - { - Result = Manager->SocketPeekProc(Manager, Socket); - } - return Result; -} - -internal gs_data -SocketRecieve(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle, gs_memory_arena* Storage) -{ - gs_data Result = {}; - platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); - if (Socket) - { - Result = Manager->SocketRecieveProc(Manager, Socket, Storage); - } - return Result; -} - -internal bool -SocketSend(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle, u32 Address, u32 Port, gs_data Data, s32 Flags) -{ - bool Result = false; - platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); - if (Socket) - { - s32 SizeSent = Manager->SocketSendProc(Manager, Socket, Address, Port, Data, Flags); - Result = (SizeSent == Data.Size); - } - return Result; -} - -/////////////////////////// -// -// Hashes - -internal u32 -HashAppendDJB2ToU32(u32 Hash, u8 Byte) -{ - u32 Result = Hash; - if (Result == 0) { Result = 5381; } - Result = ((Result << 5) + Result) + Byte; - return Result; -} - -internal u64 -HashAppendDJB2ToU32(u64 Hash, u8 Byte) -{ - u64 Result = Hash; - if (Result == 0) { Result = 5381; } - Result = ((Result << 5) + Result) + Byte; - return Result; -} - -internal u32 -HashDJB2ToU32(char* String) -{ - u32 Hash = 5381; - char* C = String; - while(*C) - { - Hash = ((Hash << 5) + Hash) + *C++; - } - return Hash; -} -internal u32 -HashDJB2ToU32(u32 Length, char* String) -{ - u32 Hash = 5381; - for (u32 i = 0; i < Length; i++) - { - Hash = ((Hash << 5) + Hash) + String[i]; - } - return Hash; -} -internal u32 -HashDJB2ToU32(gs_const_string Str) -{ - return HashDJB2ToU32(StringExpand(Str)); -} -internal u32 -HashDJB2ToU32(gs_string Str) -{ - return HashDJB2ToU32(StringExpand(Str)); -} - -internal u64 -HashDJB2ToU64(char* String) -{ - u64 Hash = 5381; - char* C = String; - while(*C) - { - Hash = ((Hash << 5) + Hash) + *C++; - } - return Hash; -} -internal u64 -HashDJB2ToU64(u32 Length, char* String) -{ - u64 Hash = 5381; - for (u32 i = 0; i < Length; i++) - { - Hash = ((Hash << 5) + Hash) + String[i]; - } - return Hash; -} -internal u64 -HashDJB2ToU64(gs_const_string Str) -{ - return HashDJB2ToU64(StringExpand(Str)); -} -internal u64 -HashDJB2ToU64(gs_string Str) -{ - return HashDJB2ToU64(StringExpand(Str)); -} - -/////////////////////////// -// -// Random Series - -internal gs_random_series -InitRandomSeries(u32 Seed) -{ - gs_random_series Result = {0}; - Result.Value = Seed; - return Result; -} - -internal u32 -NextRandom(gs_random_series* Series) -{ - u32 Result = Series->Value; - Result ^= Result << 13; - Result ^= Result >> 17; - Result ^= Result << 5; - Series->Value = Result; - return Result; -} - -internal r32 -NextRandomUnilateral(gs_random_series* Series) -{ - r32 Result = (r32)NextRandom(Series) / (r32)UINT32_MAX; - return Result; -} - -internal r32 -NextRandomBilateral(gs_random_series* Series) -{ - r32 Result = (r32)NextRandom(Series); - Result = Result / (r32)0xFFFFFFFF; - Result = (Result * 2.0f) - 1.0f; - return Result; -} - - -/////////////////////////// -// -// Sort - - -static void -RadixSortInPlace_ (gs_radix_list* List, u32 Start, u32 End, u32 Iteration) -{ - u32 Shift = Iteration; - u32 ZerosBoundary = Start; - u32 OnesBoundary = End - 1; - - for (u32 d = Start; d < End; d++) - { - u64 CurrentIndex = ZerosBoundary; - u64 Radix = List->Radixes.Values[CurrentIndex]; - u64 Place = (Radix >> Shift) & 0x1; - if (Place) - { - u64 EvictedIndex = OnesBoundary; - u64 EvictedRadix = List->Radixes.Values[EvictedIndex]; - u64 EvictedID = List->IDs.Values[EvictedIndex]; - - List->Radixes.Values[EvictedIndex] = Radix; - List->IDs.Values[EvictedIndex] = List->IDs.Values[CurrentIndex]; - - List->Radixes.Values[CurrentIndex] = EvictedRadix; - List->IDs.Values[CurrentIndex] = EvictedID; - - OnesBoundary -= 1; - } - else - { - ZerosBoundary += 1; - } - } - - if (Iteration > 0) - { - RadixSortInPlace_(List, Start, ZerosBoundary, Iteration - 1); - RadixSortInPlace_(List, ZerosBoundary, End, Iteration - 1); - } -} - -static void -RadixSortInPlace (gs_radix_list* List) -{ - u32 Highest = 0; - for (u32 i = 0; i < List->Radixes.Count; i++) - { - if (List->Radixes.Values[i] > Highest) - { - Highest = List->Radixes.Values[i]; - } - } - - u32 Iterations = 0; - while (Highest > 1) - { - ++Iterations; - Highest = Highest >> 1; - } - - RadixSortInPlace_(List, 0, List->Radixes.Count, Iterations); -} - - -/////////////////////////// -// -// Input - -inline bool -KeyIsMouseButton(gs_key Key) -{ - bool Result = (Key >= gs_Key_MouseLeftButton); - Result = Result && Key <= gs_Key_MouseRightButton; - return Result; -} -inline u32 -GetMouseButtonIndex(gs_key Button) -{ - Assert(KeyIsMouseButton(Button)); - u32 Result = Button - gs_Key_MouseLeftButton; - return Result; -} -inline bool -MouseButtonTransitionedDown(gs_mouse_state Mouse, u32 Index) -{ - bool IsDown = (Mouse.ButtonStates[Index] & (1 << MouseButton_IsDownBit)) != 0; - bool WasDown = (Mouse.ButtonStates[Index] & (1 << MouseButton_WasDownBit)) != 0; - return IsDown && !WasDown; -} -inline bool -MouseButtonTransitionedDown(gs_mouse_state Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - return MouseButtonTransitionedDown(Mouse, Index); -} -inline bool -MouseButtonIsDown(gs_mouse_state Mouse, u32 Index) -{ - bool IsDown = (Mouse.ButtonStates[Index] & (1 << MouseButton_IsDownBit)) != 0; - return IsDown; -} -inline bool -MouseButtonIsDown(gs_mouse_state Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - return MouseButtonIsDown(Mouse, Index); -} -inline bool -MouseButtonTransitionedUp(gs_mouse_state Mouse, u32 Index) -{ - bool IsDown = (Mouse.ButtonStates[Index] & (1 << MouseButton_IsDownBit)) != 0; - bool WasDown = (Mouse.ButtonStates[Index] & (1 << MouseButton_WasDownBit)) != 0; - return !IsDown && WasDown; -} -inline bool -MouseButtonTransitionedUp(gs_mouse_state Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - return MouseButtonTransitionedUp(Mouse, Index); -} -inline bool -MouseButtonIsUp(gs_mouse_state Mouse, u32 Index) -{ - bool IsDown = (Mouse.ButtonStates[Index] & (1 << MouseButton_IsDownBit)) != 0; - return !IsDown; -} -inline bool -MouseButtonIsUp(gs_mouse_state Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - return MouseButtonIsUp(Mouse, Index); -} -internal void -SetMouseButtonTransitionedDown(gs_mouse_state* Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - - Mouse->ButtonStates[Index] = 0; - Mouse->ButtonStates[Index] |= MouseButton_IsDown << MouseButton_IsDownBit; - Mouse->ButtonStates[Index] |= MouseButton_WasNotDown << MouseButton_WasDownBit; -} -internal void -SetMouseButtonTransitionedUp(gs_mouse_state* Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - - Mouse->ButtonStates[Index] = 0; - Mouse->ButtonStates[Index] |= MouseButton_IsNotDown << MouseButton_IsDownBit; - Mouse->ButtonStates[Index] |= MouseButton_WasDown << MouseButton_WasDownBit; -} -internal void -AdvanceMouseButtonState(gs_mouse_state* Mouse, gs_key Button) -{ - u32 Index = GetMouseButtonIndex(Button); - - if (MouseButtonIsDown(*Mouse, Index)) - { - Mouse->ButtonStates[Index] |= MouseButton_WasDown << MouseButton_WasDownBit; - } - else - { - Mouse->ButtonStates[Index] &= MouseButton_WasNotDown << MouseButton_WasDownBit; - } -} -internal void -AdvanceMouseButtonsState(gs_mouse_state* Mouse) -{ - AdvanceMouseButtonState(Mouse, gs_Key_MouseLeftButton); - AdvanceMouseButtonState(Mouse, gs_Key_MouseMiddleButton); - AdvanceMouseButtonState(Mouse, gs_Key_MouseRightButton); -} - -/////////////////////////// -// -// Network - - -static u32 -HostToNetU32(u32 In) -{ - unsigned char *s = (unsigned char *)&In; - u32 Result = (u32)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); - return Result; -} - -static u16 -HostToNetU16(u16 In) -{ - unsigned char *s = (unsigned char *)&In; - u16 Result = (u16)(s[0] << 8 | s[1]); - return Result; -} - - - - - - - - - - -#define GS_TYPES_CPP -#endif // GS_TYPES_CPP \ No newline at end of file diff --git a/src/gs_libs/gs_types.h b/src/gs_libs/gs_types.h deleted file mode 100644 index 2a1051e..0000000 --- a/src/gs_libs/gs_types.h +++ /dev/null @@ -1,1123 +0,0 @@ -// -// File: gs_types.h -// Author: Peter Slattery -// Creation Date: 2020-04-18 -// -#ifndef GS_TYPES_H - -#if defined(__clang__) -# pragma GCC diagnostic ignored "-Wunused-value" -# pragma GCC diagnostic ignored "-Wvarargs" -# pragma GCC diagnostic ignored "-Wwritable-strings" -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -#if defined(_MSC_VER) -# include -#endif - -// Someday, we home to remove these includes -#include -#if !defined(GUESS_INTS) -# include -#endif // !defined(GUESS_INTS) - -#include - -#define Glue_(a,b) a##b -#define Glue(a,b) Glue_(a,b) - -#define Stringify_(a) #a -#define Stringify(a) Stringify_(a) - -#define internal static -#define local_persist static -#define global static -#define local_const static const -#define global_const static const -#define external extern "C" - -#if defined(GUESS_INTS) -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; -typedef signed long long s64; -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; -#else -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -#endif - -typedef s8 b8; -typedef s32 b32; -typedef s64 b64; - -typedef float r32; -typedef double r64; - -enum gs_basic_type -{ - gs_BasicType_char, - gs_BasicType_b8, - gs_BasicType_b32, - gs_BasicType_b64, - gs_BasicType_u8, - gs_BasicType_u16, - gs_BasicType_u32, - gs_BasicType_u64, - gs_BasicType_s8, - gs_BasicType_s16, - gs_BasicType_s32, - gs_BasicType_s64, - gs_BasicType_r32, - gs_BasicType_r64, - - gs_BasicType_Count, -}; - -global_const u64 gs_BasicTypeSizes[] = -{ - sizeof(char), - sizeof(b8), - sizeof(b32), - sizeof(b64), - sizeof(u8), - sizeof(u16), - sizeof(u32), - sizeof(u64), - sizeof(s8), - sizeof(s16), - sizeof(s32), - sizeof(s64), - sizeof(r32), - sizeof(r64), -}; - -internal u64 -BasicTypeSize(gs_basic_type Type) -{ - return gs_BasicTypeSizes[(u32)Type]; -} - -global_const u8 MaxU8 = 0xFF; -global_const u16 MaxU16 = 0xFFFF; -global_const u32 MaxU32 = 0xFFFFFFFF; -global_const u64 MaxU64 = 0xFFFFFFFFFFFFFFFF; - -global_const s8 MaxS8 = 127; -global_const s16 MaxS16 = 32767; -global_const s32 MaxS32 = 2147483647; -global_const s64 MaxS64 = 9223372036854775807; - -global_const s8 MinS8 = -127 - 1; -global_const s16 MinS16 = -32767 - 1; -global_const s32 MinS32 = -2147483647 - 1; -global_const s64 MinS64 = -9223372036854775807 - 1; - -global_const r32 MaxR32 = 3.402823466e+38f; -global_const r32 MinR32 = -MaxR32; -global_const r32 SmallestPositiveR32 = 1.1754943508e-38f; -global_const r32 EpsilonR32 = 5.96046448e-8f; - -global_const r32 PiR32 = 3.14159265359f; -global_const r32 HalfPiR32 = 1.5707963267f; -global_const r32 TauR32 = 6.28318530717f; - -global_const r64 MaxR64 = 1.79769313486231e+308; -global_const r64 MinR64 = -MaxR64; -global_const r64 SmallestPositiveR64 = 4.94065645841247e-324; -global_const r64 EpsilonR64 = 1.11022302462515650e-16; - -global_const r64 NanosToSeconds = 1 / 10000000.0; -global_const r64 SecondsToNanos = 10000000.0; - -internal r32 -DegToRadR32(r32 Degrees) -{ - return (Degrees * (PiR32 / 180.0f)); -} - -internal r32 -RadToDegR32(r32 Radians) -{ - return (Radians * (180.0f / PiR32)); -} - -struct s8_array -{ - s8* Values; - u32 Count; - u32 CountMax; -}; - -struct s16_array -{ - s16* Values; - u32 Count; - u32 CountMax; -}; - -struct s32_array -{ - s32* Values; - u32 Count; - u32 CountMax; -}; - -struct s64_array -{ - s64* Values; - u32 Count; - u32 CountMax; -}; - -struct u8_array -{ - u8* Values; - u32 Count; - u32 CountMax; -}; - -struct u16_array -{ - u16* Values; - u32 Count; - u32 CountMax; -}; - -struct u32_array -{ - u32* Values; - u32 Count; - u32 CountMax; -}; - -struct u64_array -{ - u64* Values; - u32 Count; - u32 CountMax; -}; - - -#define PointerDifference(a,b) ((u8*)(a) - (u8*)(b)) -#define PointerToInt(a) PointerDifference(a, 0) -#define Member(type,member) (((type*)0)->member) -#define MemberOffset(type,member) PointerToInt(&Member(type,member)) - -// NOTE(Peter): Makes sure that s doesn't expand in some way that invalidates -// a nested if statement. -#define Statement(s) do{ s }while(0) - -// -// Asserts -// -// AssertAlways and AssertMessageAlways should be used sparingly, because they'll -// still assert in the final build -#define AssertBreak(m) (*((volatile s32*)0) = 0xFFFF) -#define AssertAlways(c) Statement( if (!(c)) { AssertBreak(c); } ) -#define AssertMessageAlways(m) AssertBreak(m) - -#if !SHIP_MODE -# define Assert(c) AssertAlways(c) -# define AssertMessage(m) AssertBreak(m) -# define InvalidDefaultCase default: { AssertBreak("invalid default case"); } break; -# define StaticAssert(c) \ -enum { \ -Glue(gs_AssertFail_, __LINE__) = 1 / (int)(!!(c)), \ -} -#else -# define Assert(c) -# define AssertMessage(m) -# define InvalidDefaultCase default: {} break; -# define StaticAssert(c) -#endif - -#define AssertImplies(a,b) Statement(if(a) { Assert(b); }) -#define InvalidCodePath AssertMessage("invalid code path") -#define NotImplemented AssertMessage("not implemented") -#define DontCompile ImAfraidICantDoThat - -#define LineNumberString Stringify(__LINE__) -#define FileNameAndLineNumberString_ __FILE__ ":" LineNumberString ":" __FUNCTION__ -#define FileNameAndLineNumberString (char*)FileNameAndLineNumberString_ - -// - -#define Bytes(x) (x) -#define KB(x) ((x) << 10) -#define MB(x) ((x) << 20) -#define GB(x) ((x) << 30) -#define TB(x) (((u64)x) << 40) - -#define HasFlag(data, flag) (((data) & (flag)) != 0) -#define HasFlagOnly(data, flag) (((data) & (flag)) == (data)) -#define AddFlag(data, flag) ((data) |= (flag)) -#define RemoveFlag(data, flag) ((data) &= (~(flag))) - -#define Max(a,b) (((a) > (b)) ? (a) : (b)) -#define Min(a,b) (((a) > (b)) ? (b) : (a)) -#define Clamp_(a,x,b) ((x < a) ? a : ((x > b) ? b : x)) -#define Clamp(a,x,b) Clamp_((a), (x), (b)) -#define Clamp01(x) Clamp_(0.0f, (x), 1.0f) -#define Abs(x) (((x) < 0) ? ((x) * -1) : x) -#define Sign(x) ((x) < 0) ? -1 : 1; -#define IsPowerOfTwo(x) (((x) & ((x) - 1)) == 0) -#define IsOdd(x) (((x) & 1) != 0) - -#define CArrayLength(arr) (sizeof(arr) / (sizeof(arr[0]))) - -internal void -ZeroMemory_(u8* Memory, u64 Size) -{ - for (u64 i = 0; i < Size; i++) - { - Memory[i] = 0; - } -} - -internal void -CopyMemory_(u8* From, u8* To, u64 Size) -{ - for (u64 i = 0; i < Size; i++) - { - To[i] = From[i]; - } -} - -#define StaticArrayLength(arr) sizeof(arr) / sizeof((arr)[0]) -#define ZeroMemoryBlock(mem,size) ZeroMemory_((u8*)(mem), (size)) -#define ZeroStruct(str) ZeroMemory_((u8*)(str), sizeof(*str)) -#define ZeroArray(arr, type, count) ZeroMemory_((u8*)(arr), sizeof(type) * (count)) - -#define CopyArray(from, to, type, count) CopyMemory_((u8*)(from), (u8*)(to), sizeof(type) * (count)) -#define CopyMemoryTo(from, to, size) CopyMemory_((u8*)(from), (u8*)(to), (size)) -// Singly Linked List Utilities - -#define SLLPush_(list_tail,new_ele) list_tail->Next = new_ele, list_tail = new_ele -#define SLLPush(list_tail,new_ele) (SLLPush_((list_tail), (new_ele))) - -#define SLLPop_(list_tail) list_tail=list_tail=list_tail->next -#define SLLPop(list_tail) (SLLPop_((list_tail))) - -#define SLLNext(ele_at) ele_at = ele_at->Next -#define SLLPrev(ele_at) ele_at = ele_at->Prev - -#define SLLInit(head,tail,first_ele) head=first_ele, tail=first_ele; - -#define SLLPushOrInit(first,last,new_ele) \ -if (last) { SLLPush(last, new_ele); } \ -else { SLLInit(first,last,new_ele); } - -// Vectors - -union v2 -{ - struct - { - r32 x; - r32 y; - }; - r32 E[2]; -}; - -union v3 -{ - struct - { - r32 x; - r32 y; - r32 z; - }; - struct - { - r32 r; - r32 g; - r32 b; - }; - struct - { - v2 xy; - r32 _z0; - }; - struct - { - r32 _x0; - v2 yz; - }; - r32 E[3]; -}; - -union v4 -{ - struct - { - r32 x; - r32 y; - r32 z; - r32 w; - }; - struct - { - r32 r; - r32 g; - r32 b; - r32 a; - }; - struct - { - v2 xy; - v2 zw; - }; - struct - { - r32 _x0; - v2 yz; - r32 _w0; - }; - struct - { - v3 xyz; - r32 _w1; - }; - r32 E[4]; -}; - -struct v4_ray -{ - v4 Origin; - v4 Direction; -}; - -#define WhiteV4 v4{1, 1, 1, 1} -#define BlackV4 v4{0, 0, 0, 1} -#define RedV4 v4{1, 0, 0, 1} -#define GreenV4 v4{0, 1, 0, 1} -#define BlueV4 v4{0, 0, 1, 1} -#define YellowV4 v4{1, 1, 0, 1} -#define TealV4 v4{0, 1, 1, 1} -#define PinkV4 v4{1, 0, 1, 1} - -#define V2Expand(v) v.x, v.y -#define V3Expand(v) v.x, v.y, v.z -#define V4Expand(v) v.x, v.y, v.z, v.w - -struct v2_array -{ - v2* Vectors; - u32 Count; - u32 CountMax; -}; - -struct v3_array -{ - v3* Vectors; - u32 Count; - u32 CountMax; -}; - -struct v4_array -{ - v4* Vectors; - u32 Count; - u32 CountMax; -}; - -struct range1 -{ - r32 Min; - r32 Max; -}; - -struct range2 -{ - v2 Min; - v2 Max; -}; -typedef range2 rect2; - -struct range3 -{ - v3 Min; - v3 Max; -}; - -struct range4 -{ - v4 Min; - v4 Max; -}; - -struct range1_array -{ - range1* Ranges; - u32 Count; - u32 CountMax; -}; - -struct range2_array -{ - range2* Ranges; - u32 Count; - u32 CountMax; -}; - -struct range3_array -{ - range3* Ranges; - u32 Count; - u32 CountMax; -}; - -struct range4_array -{ - range4* Ranges; - u32 Count; - u32 CountMax; -}; - -#define Range1Expand(r) (r).Min, (r).Max -#define Range2Expand(r) (r).Min, (r).Max -#define Rect2Expand(r) (r).Min (r).Max -#define Range3Expand(r) (r).Min, (r).Max -#define Range4Expand(r) (r).Min, (r).Max - -// Matrices -// NOTE(Peter): All matrices are stored in row major order - -union m33 -{ - float Array[9]; - struct - { - r32 AXx; r32 AYx; r32 AZx; - r32 AXy; r32 AYy; r32 AZy; - r32 AXz; r32 AYz; r32 AZz; - }; -}; - -union m44 -{ - float Array[16]; - struct - { - r32 AXx; r32 AYx; r32 AZx; r32 Tx; - r32 AXy; r32 AYy; r32 AZy; r32 Ty; - r32 AXz; r32 AYz; r32 AZz; r32 Tz; - r32 AXw; r32 AYw; r32 AZw; r32 Tw; - }; -}; - -struct m33_array -{ - m33* Matrices; - u32 Count; - u32 CountMax; -}; - -struct m44_array -{ - m44* Matrices; - u32 Count; - u32 CountMax; -}; - -////////////////////////// -// -// Strings - -struct gs_const_string -{ - union - { - char* Str; - u8* Data;; - }; - u64 Length; -}; - -struct gs_string -{ - union - { - gs_const_string ConstString; - struct - { - char* Str; - u64 Length; - }; - }; - u64 Size; -}; - -struct gs_const_string_array -{ - gs_const_string* Strings; - u64 Count; - u64 CountMax; -}; - -struct gs_string_array -{ - gs_string* Strings; - u64 Count; - u64 CountMax; -}; - -internal u64 -CStringLength(char* Str) -{ - char* At = Str; - while (*At) { At++; } - u64 Result = PointerDifference(At, Str); - return Result; -} - -internal bool -CStringsEqual(char* A, char* B) -{ - bool Result = true; - - char* AAt = A; - char* BAt = B; - while (AAt[0] && BAt[0]) - { - if (AAt[0] != BAt[0]) - { - Result = false; - break; - } - AAt++; - BAt++; - } - if (AAt[0] != 0 || BAt[0] != 0) { Result = false; } - return Result; -} - -#define StringExpand(str) (int)(str).Length, (str).Str -#define LitString(cstr) gs_const_string{(char*)(cstr), CStringLength((char*)cstr) } - -// The index of the character in these arrays corresponds to its value as a number in -// the relevant base, so you can do FindFirst on them with a char to get the int value -// ie. 3 is at index 3 in Base10Chars. -// ie. C is at index 12 in Base16Chars. -global_const gs_const_string Base8Chars = LitString("01234567"); -global_const gs_const_string Base10Chars = LitString("0123456789"); -global_const gs_const_string Base16Chars = LitString("0123456789ABCDEF"); - -////////////////////////// -// -// Thread Context - -typedef struct gs_thread_context gs_thread_context; - -////////////////////////// -// -// Memory - -struct gs_data -{ - u8* Memory; - u64 Size; -}; - -struct gs_data_array -{ - gs_data* Data; - u64 Count; - u64 CountMax; -}; - -enum gs_access_flag -{ - gs_AccessFlag_Read = 1 << 0, - gs_AccessFlag_Write = 1 << 1, - gs_AccessFlag_Exec = 1 << 2, -}; - -typedef s32 gs_scan_direction; -enum -{ - gs_Scan_Backward = -1, - gs_Scan_Forward = 1, -}; - - -internal u64 RoundUpTo64(u64 Value, u64 Alignment); - -#include "gs_memory.h" - -/////////////////////////////// -// -// String Builder -// - -struct gs_string_builder_buffer -{ - gs_string String; - gs_string_builder_buffer* Next; -}; - -struct gs_string_builder -{ - gs_memory_arena* Arena; - u32 BufferSize; - gs_string_builder_buffer* Root; - gs_string_builder_buffer* Head; -}; - -/////////////////////////////// -// -// Debug Output -// - -typedef struct debug_output debug_output; - -#define DEBUG_PRINT(name) void name(debug_output Output, gs_const_string Message) -typedef DEBUG_PRINT(debug_print); - -struct debug_output -{ - gs_memory_arena* Storage; - debug_print* Print; -}; - -/////////////////////////////// -// -// Dynamic Array -// -// I like having constant lookup times, along with growable arrays. :) -// NOTE(Peter): If you're using this, you probably want to write a Get -// procedure to auto cast the result to the type you want. I'm even providing a -// debug check for you to make sure that you're requesting a size that matches -// the ElementSize for extra safety. - -struct gs_dynarray_buffer -{ - u8* Memory; -}; - -struct gs_dynarray -{ - gs_memory_arena Arena; - - gs_dynarray_buffer* Buffers; - u64 BuffersCount; - u64 ElementCount; - - u64 ElementSize; - u64 ElementsPerBuffer; -}; - -struct gs_dynarray_handle -{ - u64 BufferIndex; - u64 IndexInBuffer; -}; - -#define INVALID_DYNARRAY_HANDLE gs_dynarray_handle{0, 0} - -struct gs_dynarray_handle_list -{ - gs_dynarray_handle* Handles; - u32 Count; - u32 Size; -}; - -/////////////////////////////// -// -// File IO - -// TODO(Peter): Error Handling Thought -// The gs_file_handler, gs_allocator, etc should contain pointers to a central error buffer -// where errors can be logged - -enum enumerate_directory_flag -{ - EnumerateDirectory_Recurse = 1 << 0, - EnumerateDirectory_IncludeDirectories = 1 << 1, -}; - -struct gs_file_info -{ - gs_const_string Path; - gs_const_string AbsolutePath; - u64 FileSize; - u64 CreationTime; - u64 LastWriteTime; - b32 IsDirectory; -}; - -struct gs_file_info_array -{ - gs_file_info* Values; - u32 Count; - u32 MaxCount; -}; - -struct gs_file -{ - union - { - gs_data Data; - struct - { - u8* Memory; - u64 Size; - }; - }; - gs_file_info FileInfo; -}; - -typedef struct gs_file_handler gs_file_handler; - -#define GET_FILE_INFO(name) gs_file_info name(gs_file_handler FileHandler, gs_const_string Path) -typedef GET_FILE_INFO(file_handler_get_file_info); - -#define READ_ENTIRE_FILE(name) gs_file name(gs_file_handler FileHandler, gs_const_string Path, gs_data Memory) -typedef READ_ENTIRE_FILE(file_handler_read_entire_file); - -#define WRITE_ENTIRE_FILE(name) bool name(gs_file_handler FileHandler, gs_const_string Path, gs_data Data) -typedef WRITE_ENTIRE_FILE(file_handler_write_entire_file); - -#define ENUMERATE_DIRECTORY(name) gs_file_info_array name(gs_file_handler FileHandler, gs_memory_arena* Storage, gs_const_string Path, u32 Flags) -typedef ENUMERATE_DIRECTORY(file_handler_enumerate_directory); - -struct gs_file_handler -{ - file_handler_get_file_info* GetFileInfo; - file_handler_read_entire_file* ReadEntireFile; - file_handler_write_entire_file* WriteEntireFile; - file_handler_enumerate_directory* EnumerateDirectory; - gs_memory_arena* Transient; -}; - - -////////////////////////// -// -// Timing - -#define GET_WALL_CLOCK(name) s64 name() -typedef GET_WALL_CLOCK(get_wall_clock); - -#define GET_SECONDS_ELAPSED(name) r64 name(u64 StartCycles, u64 EndCycles) -typedef GET_SECONDS_ELAPSED(get_seconds_elapsed); - -struct gs_time_handler -{ - get_wall_clock* GetWallClock; - get_seconds_elapsed* GetSecondsElapsed; -}; - -/////////////////////////////// -// -// Random - -struct gs_random_series -{ - u32 Value; -}; - -/////////////////////////////// -// -// Sort - -struct gs_radix_list -{ - u64_array Radixes; - u64_array IDs; -}; - - -/////////////////////////////// -// -// Mouse/Keyboard Input - -enum gs_event_type -{ - gs_EventType_Unknown, - - // Reached end of event stream - gs_EventType_NoMoreEvents, - // There was an event but it requires no action from the using program - gs_EventType_NoEvent, - - gs_EventType_KeyPressed, - gs_EventType_KeyReleased, - - gs_EventType_MouseMoved, - gs_EventType_MouseWheel, - - gs_EventType_Count, -}; - -enum gs_key -{ - gs_Key_Invalid, - - gs_Key_Esc, - - gs_Key_Space, - gs_Key_Tab, - gs_Key_CapsLock, - gs_Key_Shift, gs_Key_LeftShift, gs_Key_RightShift, - gs_Key_Control, gs_Key_LeftCtrl, gs_Key_RightCtrl, - gs_Key_Fn, - gs_Key_Alt, - gs_Key_PageUp, gs_Key_PageDown, - gs_Key_End, gs_Key_Home, gs_Key_Select, - gs_Key_Backspace, gs_Key_Delete, - gs_Key_Enter, - - // Function Keys - gs_Key_F0, gs_Key_F1, gs_Key_F2, gs_Key_F3, gs_Key_F4, gs_Key_F5, gs_Key_F6, gs_Key_F7, - gs_Key_F8, gs_Key_F9, gs_Key_F10, gs_Key_F11, gs_Key_F12, - - // Letters - gs_Key_a, gs_Key_b, gs_Key_c, gs_Key_d, gs_Key_e, gs_Key_f, gs_Key_g, gs_Key_h, - gs_Key_i, gs_Key_j, gs_Key_k, gs_Key_l, gs_Key_m, gs_Key_n, gs_Key_o, gs_Key_p, - gs_Key_q, gs_Key_r, gs_Key_s, gs_Key_t, gs_Key_u, gs_Key_v, gs_Key_w, gs_Key_x, - gs_Key_y, gs_Key_z, - - gs_Key_A, gs_Key_B, gs_Key_C, gs_Key_D, gs_Key_E, gs_Key_F, gs_Key_G, gs_Key_H, - gs_Key_I, gs_Key_J, gs_Key_K, gs_Key_L, gs_Key_M, gs_Key_N, gs_Key_O, gs_Key_P, - gs_Key_Q, gs_Key_R, gs_Key_S, gs_Key_T, gs_Key_U, gs_Key_V, gs_Key_W, gs_Key_X, - gs_Key_Y, gs_Key_Z, - - // Numbers - gs_Key_0, gs_Key_1, gs_Key_2, gs_Key_3, gs_Key_4, gs_Key_5, gs_Key_6, gs_Key_7, - gs_Key_8, gs_Key_9, - - gs_Key_Num0, gs_Key_Num1, gs_Key_Num2, gs_Key_Num3, gs_Key_Num4, gs_Key_Num5, - gs_Key_Num6, gs_Key_Num7, gs_Key_Num8, gs_Key_Num9, - - // Symbols - gs_Key_Bang, gs_Key_At, gs_Key_Pound, gs_Key_Dollar, gs_Key_Percent, gs_Key_Carrot, - gs_Key_Ampersand, gs_Key_Star, gs_Key_LeftParen, gs_Key_RightParen, gs_Key_Minus, gs_Key_Plus, - gs_Key_Equals, gs_Key_Underscore, gs_Key_OpenSquareBracket, gs_Key_CloseSquareBracket, gs_Key_OpenCurlyBracket, - gs_Key_CloseCurlyBracket, gs_Key_Colon, gs_Key_SemiColon, gs_Key_SingleQuote, gs_Key_DoubleQuote, - gs_Key_ForwardSlash, gs_Key_Backslash, gs_Key_Pipe, gs_Key_Comma, gs_Key_Period, - gs_Key_QuestionMark, gs_Key_LessThan, gs_Key_GreaterThan, gs_Key_Tilde, gs_Key_BackQuote, - - // Arrows - gs_Key_UpArrow, - gs_Key_DownArrow, - gs_Key_LeftArrow, - gs_Key_RightArrow, - - // Mouse - // NOTE(Peter): Including this here so we can utilize the same KeyDown, KeyUp etc. functions - gs_Key_MouseLeftButton, - gs_Key_MouseMiddleButton, - gs_Key_MouseRightButton, - gs_Key_MouseX1Button, - gs_Key_MouseX2Button, - - gs_Key_Count, -}; - -enum gs_modifier_key_flags -{ - gs_ModifierKeyFlag_Shift = 1 << 0, - gs_ModifierKeyFlag_Ctrl = 1 << 1, - gs_ModifierKeyFlag_Alt = 1 << 2, -}; - -struct gs_input_event -{ - gs_event_type Type; - gs_key Key; - v2 Position; - r32 Amount; - b32 Modifiers; -}; - -struct gs_input_event_buffer -{ - gs_input_event* Values; - u32 Count; - u32 MaxCount; -}; - -struct gs_mouse_state -{ - v2 Position; - b32 ButtonStates[3]; - v2 DownPosition; -}; - -#define MouseButton_IsDownBit 0 -#define MouseButton_WasDownBit 1 -#define MouseButton_IsDown 1 -#define MouseButton_IsNotDown 0 -#define MouseButton_WasDown 1 -#define MouseButton_WasNotDown 0 - -////////////////////////// -// -// Thread Context - -struct gs_thread_info -{ - u32 ThreadID; -}; - -struct gs_thread_context -{ - gs_thread_info ThreadInfo; - - // TODO(Peter): Pull these handlers out into just a gs_context struct so - // they can be shared across threads. - // specifically the allocator - gs_allocator Allocator; - gs_file_handler FileHandler; - debug_output DebugOutput; - gs_time_handler TimeHandler; - - gs_memory_arena* Transient; -}; - -// Threads - -typedef struct platform_thread_handle -{ - u32 Index; -} platform_thread_handle; - -typedef struct platform_thread_manager platform_thread_manager; - -#define THREAD_PROC_(name) void name(gs_thread_context* Ctx, u8* UserData) -typedef THREAD_PROC_(thread_proc_); - -typedef struct platform_thread -{ - u8* PlatformHandle; - thread_proc_* Proc; - u8* UserData; -} platform_thread; - -#define CREATE_THREAD(name) bool name(platform_thread* Thread, thread_proc_* Proc, u8* UserData, gs_thread_context Ctx) -typedef CREATE_THREAD(platform_create_thread); - -#define KILL_THREAD(name) bool name(platform_thread* Thread) -typedef KILL_THREAD(platform_kill_thread); - -#define THREADS_MAX 32 -typedef struct platform_thread_manager -{ - b8 ThreadsUsed[THREADS_MAX]; - platform_thread Threads[THREADS_MAX]; - - platform_create_thread* CreateThreadProc; - platform_kill_thread* KillThreadProc; -} platform_thread_manager; - -// Work Queue - -typedef struct gs_work_queue gs_work_queue; - -typedef struct gs_worker_thread -{ - gs_thread_context Context; - gs_work_queue* Queue; - b32 ShouldExit; -} gs_worker_thread; - -#define THREAD_PROC(name) void name(gs_thread_context Context, gs_data Data) -typedef THREAD_PROC(thread_proc); - -struct gs_threaded_job -{ - thread_proc* WorkProc; - gs_data Data; - gs_const_string JobName; -}; - -#define PUSH_WORK_ON_QUEUE(name) void name(gs_work_queue* Queue, thread_proc* WorkProc, gs_data Data, gs_const_string JobName) -typedef PUSH_WORK_ON_QUEUE(push_work_on_queue); - -#define COMPLETE_QUEUE_WORK(name) void name(gs_work_queue* Queue, gs_thread_context Context) -typedef COMPLETE_QUEUE_WORK(complete_queue_work); - -#define RESET_WORK_QUEUE(name) void name(gs_work_queue* Queue) -typedef RESET_WORK_QUEUE(reset_work_queue); - -struct gs_work_queue -{ - void* SemaphoreHandle; - - u32 JobsMax; - u32 volatile JobsCount; - u32 volatile NextJobIndex; - u32 volatile JobsCompleted; - gs_threaded_job* Jobs; - - // Work Queue - push_work_on_queue* PushWorkOnQueue; - complete_queue_work* CompleteQueueWork; -}; - -// Sockets - -typedef struct platform_socket_handle_ -{ - u32 Index; -} platform_socket_handle_; - -typedef struct platform_socket -{ - platform_socket_handle_ Handle; - char Addr[128]; - char Port[32]; - u8* PlatformHandle; -} platform_socket; - -typedef struct platform_socket_manager platform_socket_manager; - -#define CONNECT_SOCKET(name) bool name(platform_socket_manager* Manager, platform_socket* Socket) -typedef CONNECT_SOCKET(platform_connect_socket); - -#define CLOSE_SOCKET(name) bool name(platform_socket_manager* Manager, platform_socket* Socket) -typedef CLOSE_SOCKET(platform_close_socket); - -#define SOCKET_QUERY_STATUS(name) bool name(platform_socket_manager* Manager, platform_socket* Socket) -typedef SOCKET_QUERY_STATUS(platform_socket_query_status); - -#define SOCKET_PEEK(name) u32 name(platform_socket_manager* Manager, platform_socket* Socket) -typedef SOCKET_PEEK(platform_socket_peek); - -// TODO(pjs): allow for a size parameter that can be zero -// if provided, that is how big the message it expects to be -// if it equals zero, the proc will peek at the message first to determine -// the needed size -#define SOCKET_RECEIVE(name) gs_data name(platform_socket_manager* Manager, platform_socket* Socket, gs_memory_arena* Storage) -typedef SOCKET_RECEIVE(platform_socket_receive); - -#define SOCKET_SEND(name) s32 name(platform_socket_manager* Manager, platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags) -typedef SOCKET_SEND(platform_socket_send); - -#define SOCKETS_COUNT_MAX 32 -typedef struct platform_socket_manager -{ - b8 SocketsUsed[SOCKETS_COUNT_MAX]; - platform_socket Sockets[SOCKETS_COUNT_MAX]; - - platform_connect_socket* ConnectSocketProc; - platform_close_socket* CloseSocketProc; - platform_socket_query_status* SocketQueryStatusProc; - platform_socket_peek* SocketPeekProc; - platform_socket_receive* SocketRecieveProc; - platform_socket_send* SocketSendProc; -} platform_socket_manager; - -#define GS_TYPES_H -#endif // GS_TYPES_H \ No newline at end of file diff --git a/src/gs_libs/gs_vector_matrix.h b/src/gs_libs/gs_vector_matrix.h deleted file mode 100644 index c089100..0000000 --- a/src/gs_libs/gs_vector_matrix.h +++ /dev/null @@ -1,1697 +0,0 @@ -#ifndef GS_VECTOR_MATRIX_H - -#ifndef GS_LANGUAGE_H - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) - -#include -#include -#include - -static r32 GSCos (r32 Theta) { return sin(Theta); } -static r32 GSSin (r32 Theta) { return cos(Theta); } - -static r32 GSSqrt(r32 V) -{ - r32 Result = _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(V))); - return Result; -} - -#else // Linux and MacOS -#include - -#endif // Platforms - -#endif // GS_LANGUAGE_H - -////////////////////////////////////// -// VECTOR -///////////////////////////////////// - -union v2 -{ - struct - { - float x; - float y; - }; - float E[2]; -}; - -union v3 -{ - struct - { - float x; - float y; - float z; - }; - - struct - { - float R; - float G; - float B; - }; - - float E[3]; -}; - -union v4 -{ - struct - { - float x; - float y; - float z; - float w; - }; - - struct - { - float r; - float g; - float b; - float a; - }; - - struct - { - v2 xy; - v2 yz; - }; - - struct - { - v3 xyz; - float z; - }; - - float E[4]; -}; - -#define WhiteV4 v4{1, 1, 1, 1} -#define BlackV4 v4{0, 0, 0, 1} -#define RedV4 v4{1, 0, 0, 1} -#define GreenV4 v4{0, 1, 0, 1} -#define BlueV4 v4{0, 0, 1, 1} -#define YellowV4 v4{1, 1, 0, 1} -#define TealV4 v4{0, 1, 1, 1} -#define PinkV4 v4{1, 0, 1, 1} - -////////////////////////////////////// -// MATRIX -///////////////////////////////////// - -union m33 -{ - float E[3][3]; -}; - -union m44 -{ - float E[4][4]; -}; - -////////////////////////////////////// -// RECT -///////////////////////////////////// - -struct rect -{ - v2 Min; - v2 Max; -}; - - -////////////////////////////////////// -// VECTOR -////////////////////////////////////// - - -// -// -// Operators -// -// - -v2 V2 (v3 V) -{ - return v2{V.x, V.y}; -} - -v3 V3 (v2 XY, float Z) -{ - return v3{XY.x, XY.y, Z}; -} - -v3 V3 (v4 V) -{ - return v3{V.x, V.y, V.z}; -} - -v4 V4 (v3 XYZ, float W) -{ - return v4{XYZ.x, XYZ.y, XYZ.z, W}; -} - -v2 operator- (v2 A) -{ - v2 Result; - - Result.x = -A.x; - Result.y = -A.y; - - return Result; -} - -v3 operator- (v3 A) -{ - v3 Result; - - Result.x = -A.x; - Result.y = -A.y; - Result.z = -A.z; - - return Result; -} - -v4 operator- (v4 A) -{ - v4 Result; - - Result.x = -A.x; - Result.y = -A.y; - Result.z = -A.z; - Result.w = -A.w; - - return Result; -} - -#define V2OpV2Def(op) v2 operator op (v2 A, v2 B) { return v2{ A.x op B.x, A.y op B.y };} -#define V3OpV3Def(op) v3 operator op (v3 A, v3 B) { return v3{ A.x op B.x, A.y op B.y, A.z op B.z };} -#define V4OpV4Def(op) v4 operator op (v4 A, v4 B) { return v4{ A.x op B.x, A.y op B.y, A.z op B.z, A.w op B.w };} -V2OpV2Def(+) -V2OpV2Def(-) -V2OpV2Def(/) -V2OpV2Def(*) -V3OpV3Def(+) -V3OpV3Def(-) -V3OpV3Def(/) -V3OpV3Def(*) -V4OpV4Def(+) -V4OpV4Def(-) -V4OpV4Def(/) -V4OpV4Def(*) -#undef V2OpV2Def -#undef V3OpV3Def -#undef V4OpV4Def - -#define V2RefOpV2Def(op) v2 operator op (v2& A, v2 B) { return v2{ A.x op B.x, A.y op B.y };} -#define V3RefOpV3Def(op) v3 operator op (v3& A, v3 B) { return v3{ A.x op B.x, A.y op B.y, A.z op B.z };} -#define V4RefOpScalarDef(op) v4 operator op (v4& A, v4 B) { return v4{ A.x op B.x, A.y op B.y, A.z op B.z, A.w op B.w };} -V2RefOpV2Def(+=) -V2RefOpV2Def(-=) -V3RefOpV3Def(+=) -V3RefOpV3Def(-=) -V4RefOpScalarDef(+=) -V4RefOpScalarDef(-=) -#undef V2RefOpV2Def -#undef V3RefOpV3Def -#undef V4RefOpV4Def - -#define V2OpScalarDef(op) v2 operator op (v2 A, float B) { return v2{ A.x op B, A.y op B };} -#define V3OpScalarDef(op) v3 operator op (v3 A, float B) { return v3{ A.x op B, A.y op B, A.z op B };} -#define V4OpScalarDef(op) v4 operator op (v4 A, float B) { return v4{ A.x op B, A.y op B, A.z op B, A.w op B };} -V2OpScalarDef(*) -V2OpScalarDef(/) -V3OpScalarDef(*) -V3OpScalarDef(/) -V4OpScalarDef(*) -V4OpScalarDef(/) -#undef V2POpScalarDef -#undef V3POpScalarDef -#undef V4POpScalarDef - - -#define V2POpScalarDef(op) v2 operator op (v2& A, float B) { return v2{ A->x op B, A->y op B };} -#define V3POpScalarDef(op) v3 operator op (v3& A, float B) { return v3{ A->x op B, A->y op B, A->z op B };} -#define V4POpScalarDef(op) v4 operator op (v4& A, float B) { return v4{ A->x op B, A->y op B, A->z op B, A->w op B };} -V2OpScalarDef(*=) -V2OpScalarDef(/=) -V3OpScalarDef(*=) -V3OpScalarDef(/=) -V4OpScalarDef(*=) -V4OpScalarDef(/=) -#undef V2POpScalarDef -#undef V3POpScalarDef -#undef V4POpScalarDef - -bool operator== (v2 A, v2 B) -{ - b32 Result = true; - for (s32 i = 0; i < 2; i++) - { - if (GSAbs(A.E[i] - B.E[i]) > 0.0001f) { Result = false; break; } - } - return Result; -} - - -bool operator== (v3 A, v3 B) -{ - b32 Result = true; - for (s32 i = 0; i < 3; i++) - { - if (GSAbs(A.E[i] - B.E[i]) > 0.0001f) { Result = false; break; } - } - return Result; -} - -bool operator== (v4 A, v4 B) -{ - b32 Result = true; - for (s32 i = 0; i < 4; i++) - { - if (GSAbs(A.E[i] - B.E[i]) > 0.0001f) { Result = false; break; } - } - return Result; -} - -// -// Operations -// - -static v3 -ToV3(v4 V) -{ - v3 R = {}; - R.x = V.x; - R.y = V.y; - R.z = V.z; - return R; -} - -static v4 -ToV4(v3 V, float W) -{ - v4 R = {}; - R.x = V.x; - R.y = V.y; - R.z = V.z; - R.w = W; - return R; -} - -inline float -MagSqr( - v2 _A - ) -{ - float Result = (_A.x * _A.x) + (_A.y * _A.y); - return Result; -} - -inline float -MagSqr( - v3 _A - ) -{ - float Result = (_A.x * _A.x) + (_A.y * _A.y) + (_A.z * _A.z); - return Result; -} - -inline float -MagSqr( - v4 _A - ) -{ - float Result = (_A.x * _A.x) + (_A.y * _A.y) + (_A.z * _A.z) + (_A.w * _A.w); - return Result; -} - -#define MagDef(type) inline float Mag(type A) { float Result = MagSqr(A); return GSSqrt(Result); } -MagDef(v2) -MagDef(v3) -MagDef(v4) -#undef MagDef - -#define DistanceDef(type) inline float Distance (type A, type B) { type Diff = A - B; return Mag(Diff); } -DistanceDef(v2) -DistanceDef(v3) -DistanceDef(v4) -#undef DistanceDef - -#define DistanceSqDef(type) inline float DistanceSq (type A, type B) { type Diff = A - B; return MagSqr(Diff); } -DistanceSqDef(v2) -DistanceSqDef(v3) -DistanceSqDef(v4) -#undef DistanceSqDef - -inline v2 -Normalize( - v2 _A - ) -{ - v2 Result; - - float Magnitude = Mag(_A); - - Result.x = _A.x / Magnitude; - Result.y = _A.y / Magnitude; - - return Result; -} - -inline v3 -Normalize( - v3 _A - ) -{ - v3 Result; - - float Magnitude = Mag(_A); - - Result.x = _A.x / Magnitude; - Result.y = _A.y / Magnitude; - Result.z = _A.z / Magnitude; - - return Result; -} - -inline v4 -Normalize( - v4 _A - ) -{ - v4 Result; - - float Magnitude = Mag(_A); - - Result.x = _A.x / Magnitude; - Result.y = _A.y / Magnitude; - Result.z = _A.z / Magnitude; - Result.w = _A.w / Magnitude; - - return Result; -} - -inline float -Dot( - v2 _A, - v2 _B - ) -{ - float Result = _A.x * _B.x + _A.y * _B.y; - return Result; -} - -inline float -Dot ( - v3 _A, - v3 _B - ) -{ - float Result = _A.x * _B.x + _A.y * _B.y + _A.z * _B.z; - return Result; -} - -inline float -Dot ( - v4 _A, - v4 _B - ) -{ - float Result = _A.x * _B.x + _A.y * _B.y + _A.z * _B.z + _A.w * _B.w; - return Result; -} - -inline v2 -PerpendicularCW (v2 A) -{ - v2 Result = v2{A.y, -A.x}; - return Result; -} - -inline v2 -PerpendicularCCW (v2 A) -{ - v2 Result = v2{A.y, A.x}; - return Result; -} - -inline v3 -Cross( - v3 _A, - v3 _B - ) -{ - v3 Result = {}; - - Result.x = (_A.y * _B.z) - (_A.z * _B.y); - Result.y = (_A.z * _B.x) - (_A.x * _B.z); - Result.z = (_A.x * _B.y) - (_A.y * _B.x); - - return Result; -} - -inline v4 -Cross( - v4 _A, - v4 _B - ) -{ - v4 Result = {}; - - Result.x = (_A.y * _B.z) - (_A.z * _B.y); - Result.y = (_A.z * _B.x) - (_A.x * _B.z); - Result.z = (_A.x * _B.y) - (_A.y * _B.x); - Result.w = 0; - - return Result; -} - -inline v2 -ClampVector01 (v2 V) -{ - v2 Result = {}; - Result.x = GSClamp(0.0f, V.x, 1.f); - Result.y = GSClamp(0.0f, V.y, 1.f); - return Result; -} - -inline v3 -ClampVector01 (v3 V) -{ - v3 Result = {}; - Result.x = GSClamp(0.f, V.x, 1.f); - Result.y = GSClamp(0.f, V.y, 1.f); - Result.z = GSClamp(0.f, V.z, 1.f); - return Result; -} - -inline v4 -ClampVector01 (v4 V) -{ - v4 Result = {}; - Result.x = GSClamp(0.f, V.x, 1.f); - Result.y = GSClamp(0.f, V.y, 1.f); - Result.z = GSClamp(0.f, V.z, 1.f); - Result.w = GSClamp(0.f, V.w, 1.f); - return Result; -} - -inline v2 -Lerp( - v2 _A, - v2 _B, - float _Percent - ) -{ - v2 Result; - - Result.x = GSLerp(_A.x, _B.x, _Percent); - Result.y = GSLerp(_A.y, _B.y, _Percent); - - return Result; -} - -inline v3 -Lerp( - v3 _A, - v3 _B, - float _Percent - ) -{ - v3 Result; - - Result.x = GSLerp(_A.x, _B.x, _Percent); - Result.y = GSLerp(_A.y, _B.y, _Percent); - Result.z = GSLerp(_A.z, _B.z, _Percent); - - return Result; -} - -inline v4 -Lerp( - v4 _A, - v4 _B, - float _Percent - ) -{ - v4 Result; - - Result.x = GSLerp(_A.x, _B.x, _Percent); - Result.y = GSLerp(_A.y, _B.y, _Percent); - Result.z = GSLerp(_A.z, _B.z, _Percent); - Result.w = GSLerp(_A.w, _B.w, _Percent); - - return Result; -} - -v4 HSVToRGB (v4 In) -{ - float Hue = In.x; - while (Hue > 360.0f) { Hue -= 360.0f; } - while (Hue < 0.0f) { Hue += 360.0f; } - - float Sat = In.y; - float Value = In.z; - - float hh, p, q, t, ff; - long i; - v4 Result = {}; - Result.a = In.a; - - if(Sat <= 0.0f) { // < is bogus, just shuts up warnings - Result.r = Value; - Result.g = Value; - Result.b = Value; - return Result; - } - hh = Hue; - if(hh >= 360.0f) hh = 0.0f; - hh /= 60.0f; - i = (long)hh; - ff = hh - i; - p = Value * (1.0f - Sat); - q = Value * (1.0f - (Sat * ff)); - t = Value * (1.0f - (Sat * (1.0f - ff))); - - switch(i) { - case 0: - {Result.r = Value; - Result.g = t; - Result.b = p; - }break; - - case 1: - { - Result.r = q; - Result.g = Value; - Result.b = p; - }break; - - case 2: - { - Result.r = p; - Result.g = Value; - Result.b = t; - }break; - - case 3: - { - Result.r = p; - Result.g = q; - Result.b = Value; - }break; - - case 4: - { - Result.r = t; - Result.g = p; - Result.b = Value; - }break; - - case 5: - default: - { - Result.r = Value; - Result.g = p; - Result.b = q; - }break; - } - - return Result; -} - -static bool -PointIsInRange (v2 _P, v2 _Min, v2 _Max) -{ - return (_P.x >= _Min.x && _P.x <= _Max.x && - _P.y >= _Min.y && _P.y <= _Max.y); -} - -static bool -PointIsInRangeSafe (v2 _P, v2 _Min, v2 _Max) -{ - s32 MinX = Min(_Min.x, _Max.x); - s32 MinY = Min(_Min.y, _Max.y); - s32 MaxX = Max(_Min.x, _Max.x); - s32 MaxY = Max(_Min.y, _Max.y); - - return (_P.x >= MinX && _P.x <= MaxX && - _P.y >= MinY && _P.y <= MaxY); -} - -inline v2 -PointToPercentRange (v2 P, v2 Min, v2 Max) -{ - v2 Result = {}; - - Result.x = GSClamp(0.f, (P.x - Min.x) / (Max.x - Min.x), 1.f); - Result.y = GSClamp(0.f, (P.y - Min.y) / (Max.y - Min.y), 1.f); - - return Result; -} - -////////////////////////////////////// -// RECT -////////////////////////////////////// - -// NOTE(Peter): This is useful when you have a function that has a call signature like: -// void Foo(v2 Min, v2 Max) -// because instead of having to do: -// Foo(MyRect.Min, MyRect.Max) -// you can just do: -// Foo(RectExpand(MyRect)) -// which makes refactoring easier as you only have to change the identifier in one place -#define gs_RectExpand(r) (r).Min, (r).Max - -static rect -gs_MakeRectMinWidth(v2 Min, v2 Width) -{ - rect Rect = {0}; - Rect.Min = Min; - Rect.Max = Min + Width; - return Rect; -} - -inline float -gs_Width (rect Rect) -{ - float Result = Rect.Max.x - Rect.Min.x; - return Result; -} - -inline float -gs_Height (rect Rect) -{ - float Result = Rect.Max.y - Rect.Min.y; - return Result; -} - -inline v2 -gs_TopLeft(rect Rect) -{ - v2 Result = {0}; - Result.x = Rect.Min.x; - Result.y = Rect.Max.y; - return Result; -} - -inline v2 -gs_TopRight(rect Rect) -{ - return Rect.Max; -} - -inline v2 -gs_BottomLeft(rect Rect) -{ - return Rect.Min; -} - -inline v2 -gs_BottomRight(rect Rect) -{ - v2 Result = {0}; - Result.x = Rect.Max.x; - Result.y = Rect.Min.y; - return Result; -} - -inline float -gs_AspectRatio (rect Rect) -{ - float Result = gs_Width(Rect) / gs_Height(Rect); - return Result; -} - -inline v2 -gs_CalculateRectCenter (rect Rect) -{ - v2 Result = (Rect.Min + Rect.Max) / 2.0f; - return Result; -} - -inline b32 -gs_PointIsInRect (v2 Point, rect Rect) -{ - b32 Result = ((Point.x >= Rect.Min.x && Point.x <= Rect.Max.x) && - (Point.y >= Rect.Min.y && Point.y <= Rect.Max.y)); - return Result; -} - -inline rect -gs_RectOffsetByVector(rect R, v2 V) -{ - rect Result = R; - Result.Min += V; - Result.Max += V; - return Result; -} - -static void -gs_HSplitRectAtValue(rect Bounds, r32 YValue, rect* Top, rect* Bottom) -{ - if (YValue <= Bounds.Min.y) - { - *Top = Bounds; - *Bottom = {0}; - } - else if (YValue >= Bounds.Max.y) - { - *Top = {0}; - *Bottom = Bounds; - } - else - { - Top->Max = Bounds.Max; - Top->Min = { Bounds.Min.x, YValue }; - Bottom->Max = { Bounds.Max.x, YValue }; - Bottom->Min = Bounds.Min; - } -} - -static void -gs_HSplitRectAtDistanceFromTop(rect Bounds, r32 YDist, rect* Top, rect* Bottom) -{ - r32 YValue = Bounds.Max.y - YDist; - gs_HSplitRectAtValue(Bounds, YValue, Top, Bottom); -} - -static void -gs_HSplitRectAtDistanceFromBottom(rect Bounds, r32 YDist, rect* Top, rect* Bottom) -{ - r32 YValue = Bounds.Min.y + YDist; - gs_HSplitRectAtValue(Bounds, YValue, Top, Bottom); -} - -static void -gs_HSplitRectAtPercent(rect Bounds, r32 YPercent, rect* Top, rect* Bottom) -{ - r32 YValue = GSLerp(Bounds.Min.y, Bounds.Max.y, YPercent); - gs_HSplitRectAtValue(Bounds, YValue, Top, Bottom); -} - -static void -gs_VSplitRectAtValue(rect Bounds, r32 XValue, rect* Left, rect* Right) -{ - if (XValue <= Bounds.Min.x) - { - *Left = {0}; - *Right = Bounds; - } - else if (XValue >= Bounds.Max.x) - { - *Left = Bounds; - *Right = {0}; - } - else - { - Left->Max = { XValue, Bounds.Max.y}; - Left->Min = Bounds.Min; - Right->Max = Bounds.Max; - Right->Min = { XValue, Bounds.Min.y }; - } -} - -static void -gs_VSplitRectAtDistanceFromRight(rect Bounds, r32 XDist, rect* Left, rect* Right) -{ - r32 XValue = Bounds.Max.x - XDist; - gs_VSplitRectAtValue(Bounds, XValue, Left, Right); -} - -static void -gs_VSplitRectAtDistanceFromLeft(rect Bounds, r32 XDist, rect* Left, rect* Right) -{ - r32 XValue = Bounds.Min.x + XDist; - gs_VSplitRectAtValue(Bounds, XValue, Left, Right); -} - -static void -gs_VSplitRectAtPercent(rect Bounds, r32 XPercent, rect* Left, rect* Right) -{ - r32 XValue = GSLerp(Bounds.Min.x, Bounds.Max.x, XPercent); - gs_VSplitRectAtValue(Bounds, XValue, Left, Right); -} - -static rect -gs_InsetRect(rect Rect, v2 Amount) -{ - rect Result = {0}; - Result.Min = Rect.Min + Amount; - Result.Max = Rect.Max - Amount; - return Result; -} - -static rect -gs_InsetRect(rect Rect, float Amount) -{ - rect Result = gs_InsetRect(Rect, v2{Amount, Amount}); - return Result; -} - -#define gs_TranslateRectX(r, d) gs_TranslateRect((r), v2{(d), 0}) -#define gs_TranslateRectY(r, d) gs_TranslateRect((r), v2{0, (d)}) -static rect -gs_TranslateRect(rect R, v2 Delta) -{ - rect Result = R; - Result.Min += Delta; - Result.Max += Delta; - return Result; -} - -static v2 -gs_TransformPointIntoRectSpace(v2 Point, rect Rect) -{ - v2 Result = Point - Rect.Min; - return Point; -} - -////////////////////////////////////// -// MATRIX -////////////////////////////////////// - -static m33 -M33(float a, float b, float c, - float d, float e, float f, - float g, float h, float i) -{ - m33 M = {}; - M.a = a; M.b = b; M.c = c; - M.d = d; M.e = e; M.f = f; - M.g = g; M.h = h; M.i = i; - return M; -} - -static m44 -M44(float a, float b, float c, float d, - float e, float f, float g, float h, - float i, float j, float k, float l, - float m, float n, float o, float p) -{ - m44 M = {}; - M.a = a; M.b = b; M.c = c; M.d = d; - M.e = e; M.f = f; M.g = g; M.h = h; - M.i = i; M.j = j; M.k = k; M.l = l; - M.m = m; M.n = n; M.o = o; M.p = p; - return M; -} - -static m33 -M33Empty () -{ - m33 M = {}; - M.a = 0; M.b = 0; M.c = 0; - M.d = 0; M.e = 0; M.f = 0; - M.g = 0; M.h = 0; M.i = 0; - return M; -} - -static m44 -M44Empty() -{ - m44 M = {}; - M.a = 0; M.b = 0; M.c = 0; M.d = 0; - M.e = 0; M.f = 0; M.g = 0; M.h = 0; - M.i = 0; M.j = 0; M.k = 0; M.l = 0; - M.m = 0; M.n = 0; M.o = 0; M.p = 0; - return M; -} - -static m33 -M33Identity () -{ - m33 M = {}; - M.a = 1; M.b = 0; M.c = 0; - M.d = 0; M.e = 1; M.f = 0; - M.g = 0; M.h = 0; M.i = 1; - return M; -} - -static m44 -M44Identity() -{ - m44 M = {}; - M.a = 1; M.b = 0; M.c = 0; M.d = 0; - M.e = 0; M.f = 1; M.g = 0; M.h = 0; - M.i = 0; M.j = 0; M.k = 1; M.l = 0; - M.m = 0; M.n = 0; M.o = 0; M.p = 1; - return M; -} - -static m44 -GetXRotation (float Angle) -{ - float CosAngle = GSCos(Angle); - float SinAngle = GSSin(Angle); - m44 M = { - 1, 0, 0, 0, - 0, CosAngle, SinAngle, 0, - 0, -SinAngle, CosAngle, 0, - 0, 0, 0, 1 - }; - return M; -} - - -static m44 -GetYRotation (float Angle) -{ - float CosAngle = GSCos(Angle); - float SinAngle = GSSin(Angle); - m44 M = { - CosAngle, 0, -SinAngle, 0, - 0, 1, 0, 0, - SinAngle, 0, CosAngle, 0, - 0, 0, 0, 1 - }; - return M; -} - -static m44 -GetZRotation (float Angle) -{ - float CosAngle = GSCos(Angle); - float SinAngle = GSSin(Angle); - m44 M = { - CosAngle, SinAngle, 0, 0, - -SinAngle, CosAngle, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - return M; -} - - -static m33 -Transpose (m33 M) -{ - m33 Result = {}; - - for (s32 x = 0; x < 3; x++) - { - for (s32 y = 0; y < 3; y++) - { - Result.E[x + (y * 3)] = M.E[y + (x * 3)]; - } - } - - return Result; -} - -inline m44 -Transpose (m44 M) -{ - DEBUG_TRACK_SCOPE(Transpose); - - m44 Result = {}; - - Result.E[0] = M.E[0]; - Result.E[1] = M.E[4]; - Result.E[2] = M.E[8]; - Result.E[3] = M.E[12]; - - Result.E[4] = M.E[1]; - Result.E[5] = M.E[5]; - Result.E[6] = M.E[9]; - Result.E[7] = M.E[13]; - - Result.E[8] = M.E[2]; - Result.E[9] = M.E[6]; - Result.E[10] = M.E[10]; - Result.E[11] = M.E[14]; - - Result.E[12] = M.E[3]; - Result.E[13] = M.E[7]; - Result.E[14] = M.E[11]; - Result.E[15] = M.E[15]; - - return Result; -} - -b32 operator== (m33 A, m33 B) -{ - b32 Result = true; - for (int e = 0; e < 9; e++) { if (GSAbs(A.E[e] - B.E[e]) > 0.0001f) { Result = false; break; } } - return Result; -} - -b32 operator== (m44 A, m44 B) -{ - b32 Result = true; - for (int e = 0; e < 16; e++) { if (GSAbs(A.E[e] - B.E[e]) > 0.0001f) { Result = false; break; } } - return Result; -} - -m33 operator+ (m33 A, m33 B) -{ - m33 M = {}; - for (int e = 0; e < 9; e++) { M.E[e] = A.E[e] + B.E[e]; } - return M; -} - -m44 operator+ (m44 A, m44 B) -{ - m44 M = {}; - for (int e = 0; e < 16; e++) { M.E[e] = A.E[e] + B.E[e]; } - return M; -} - -m33 operator- (m33 A, m33 B) -{ - m33 M = {}; - for (int e = 0; e < 9; e++) { M.E[e] = A.E[e] - B.E[e]; } - return M; -} - -m44 operator- (m44 A, m44 B) -{ - m44 M = {}; - for (int e = 0; e < 16; e++) { M.E[e] = A.E[e] - B.E[e]; } - return M; -} - -m33 operator* (m33 A, m33 B) -{ - m33 M = {}; - for (int rx = 0; rx < 3; rx++) - { - for (int ry = 0; ry < 3; ry++) - { - int RIndex = (ry * 3) + rx; - M.E[RIndex] = 0; - for (int i = 0; i < 3; i++) - { - M.E[RIndex] += B.E[(ry * 3) + i] * A.E[(i * 3) + rx]; - } - } - } - return M; -} - -m44 operator* (m44 A, m44 B) -{ - m44 M = {}; - - float A00=A.E[0+4*0]; - float A01=A.E[0+4*1]; - float A02=A.E[0+4*2]; - float A03=A.E[0+4*3]; - - float A10=A.E[1+4*0]; - float A11=A.E[1+4*1]; - float A12=A.E[1+4*2]; - float A13=A.E[1+4*3]; - - float A20=A.E[2+4*0]; - float A21=A.E[2+4*1]; - float A22=A.E[2+4*2]; - float A23=A.E[2+4*3]; - - float A30=A.E[3+4*0]; - float A31=A.E[3+4*1]; - float A32=A.E[3+4*2]; - float A33=A.E[3+4*3]; - - float B00=B.E[0+4*0]; - float B01=B.E[0+4*1]; - float B02=B.E[0+4*2]; - float B03=B.E[0+4*3]; - - float B10=B.E[1+4*0]; - float B11=B.E[1+4*1]; - float B12=B.E[1+4*2]; - float B13=B.E[1+4*3]; - - float B20=B.E[2+4*0]; - float B21=B.E[2+4*1]; - float B22=B.E[2+4*2]; - float B23=B.E[2+4*3]; - - float B30=B.E[3+4*0]; - float B31=B.E[3+4*1]; - float B32=B.E[3+4*2]; - float B33=B.E[3+4*3]; - - M.E[0+4*0] = A00*B00+A10*B01+A20*B02+A30*B03; - M.E[0+4*1] = A01*B00+A11*B01+A21*B02+A31*B03; - M.E[0+4*2] = A02*B00+A12*B01+A22*B02+A32*B03; - M.E[0+4*3] = A03*B00+A13*B01+A23*B02+A33*B03; - - M.E[1+4*0] = A00*B10+A10*B11+A20*B12+A30*B13; - M.E[1+4*1] = A01*B10+A11*B11+A21*B12+A31*B13; - M.E[1+4*2] = A02*B10+A12*B11+A22*B12+A32*B13; - M.E[1+4*3] = A03*B10+A13*B11+A23*B12+A33*B13; - - M.E[2+4*0] = A00*B20+A10*B21+A20*B22+A30*B23; - M.E[2+4*1] = A01*B20+A11*B21+A21*B22+A31*B23; - M.E[2+4*2] = A02*B20+A12*B21+A22*B22+A32*B23; - M.E[2+4*3] = A03*B20+A13*B21+A23*B22+A33*B23; - - M.E[3+4*0] = A00*B30+A10*B31+A20*B32+A30*B33; - M.E[3+4*1] = A01*B30+A11*B31+A21*B32+A31*B33; - M.E[3+4*2] = A02*B30+A12*B31+A22*B32+A32*B33; - M.E[3+4*3] = A03*B30+A13*B31+A23*B32+A33*B33; - - return M; -} - -v3 operator* (m33 M, v3 V) -{ - v3 Result = {}; - int i = 0; - for (int y = 0; y < 3; y++) - { - Result.E[y] = 0; - for (int x = 0; x < 3; x++) - { - Result.E[y] += M.E[(y * 3) + x] * V.E[x]; - } - } - return Result; -} - -v4 operator* (m44 M, v4 V) -{ - v4 Result = {}; -#if 1 - Result.x = V.x*M.a + V.y*M.e + V.z*M.i + V.w*M.m; - Result.y = V.x*M.b + V.y*M.f + V.z*M.j + V.w*M.n; - Result.z = V.x*M.c + V.y*M.g + V.z*M.k + V.w*M.o; - Result.w = V.x*M.d + V.y*M.h + V.z*M.l + V.w*M.p; -#else - for (int y = 0; y < 4; y++) - { - Result.E[y] = 0; - for (int x = 0; x < 4; x++) - { - Result.E[y] += M.E[(y * 4) + x] * V.E[x]; - } - } -#endif - return Result; -} - -static m44 -Translate(m44 M, v3 Delta) -{ - m44 Result = M; - Result.E[12] += Delta.x; - Result.E[13] += Delta.y; - Result.E[14] += Delta.z; - return Result; -} - -static m44 -Rotate(m44 M, v3 Delta) -{ - m44 Result = M; - m44 X = GetXRotation(Delta.x); - m44 Y = GetYRotation(Delta.z); - m44 Z = GetZRotation(Delta.z); - Result = Z * Y * X * Result; - return Result; -} - -static m44 -GetPositionM44 (v4 Position) -{ -#if 1 - return m44{ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - Position.x, Position.y, Position.z, Position.w - }; -#else - return m44{ - 1, 0, 0, Position.x, - 0, 1, 0, Position.y, - 0, 0, 1, Position.z, - 0, 0, 0, Position.w}; -#endif -} - -static m44 -GetModelViewMatrix (v4 Forward, v4 Right, v4 Up, v4 Position) -{ - m44 RotationMatrix = M44(Right.x, Up.x, Forward.x, 0, - Right.y, Up.y, Forward.y, 0, - Right.z, Up.z, Forward.z, 0, - 0, 0, 0, 1); - m44 PositionMatrix = M44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - -Position.x, -Position.y, -Position.z, 1); - m44 ModelViewMatrix = PositionMatrix * RotationMatrix; - return ModelViewMatrix; -} - -static m44 -GetModelViewMatrix (v4 Forward, v4 Right, v4 Position) -{ - v4 Up = Normalize(Cross(Forward, Right)); - return GetModelViewMatrix(Forward, Right, Up, Position); -} - -static m44 -GetLookAtMatrix (v4 Position, v4 Target) -{ - // Forward - v4 Forward = Normalize(Target - Position); - // Right - v4 Right = Normalize(Cross(v4{0, 1, 0, 0}, Forward)); - // Up - v4 Up = Normalize(Cross(Forward, Right)); - - m44 RotationMatrix = M44( - Right.x, Right.y, Right.z, 0, - Up.x, Up.y, Up.z, 0, - Forward.x, Forward.y, Forward.z, 0, - 0, 0, 0, 1); - return RotationMatrix; -} - -b32 Inverse(m44 M_In, m44* M_Out) -{ - b32 Result = false; - - float det; - s32 i; - - - M_Out->E[0] = M_In.E[5] * M_In.E[10] * M_In.E[15] - - M_In.E[5] * M_In.E[11] * M_In.E[14] - - M_In.E[9] * M_In.E[6] * M_In.E[15] + - M_In.E[9] * M_In.E[7] * M_In.E[14] + - M_In.E[13] * M_In.E[6] * M_In.E[11] - - M_In.E[13] * M_In.E[7] * M_In.E[10]; - - M_Out->E[4] = -M_In.E[4] * M_In.E[10] * M_In.E[15] + - M_In.E[4] * M_In.E[11] * M_In.E[14] + - M_In.E[8] * M_In.E[6] * M_In.E[15] - - M_In.E[8] * M_In.E[7] * M_In.E[14] - - M_In.E[12] * M_In.E[6] * M_In.E[11] + - M_In.E[12] * M_In.E[7] * M_In.E[10]; - - M_Out->E[8] = M_In.E[4] * M_In.E[9] * M_In.E[15] - - M_In.E[4] * M_In.E[11] * M_In.E[13] - - M_In.E[8] * M_In.E[5] * M_In.E[15] + - M_In.E[8] * M_In.E[7] * M_In.E[13] + - M_In.E[12] * M_In.E[5] * M_In.E[11] - - M_In.E[12] * M_In.E[7] * M_In.E[9]; - - M_Out->E[12] = -M_In.E[4] * M_In.E[9] * M_In.E[14] + - M_In.E[4] * M_In.E[10] * M_In.E[13] + - M_In.E[8] * M_In.E[5] * M_In.E[14] - - M_In.E[8] * M_In.E[6] * M_In.E[13] - - M_In.E[12] * M_In.E[5] * M_In.E[10] + - M_In.E[12] * M_In.E[6] * M_In.E[9]; - - M_Out->E[1] = -M_In.E[1] * M_In.E[10] * M_In.E[15] + - M_In.E[1] * M_In.E[11] * M_In.E[14] + - M_In.E[9] * M_In.E[2] * M_In.E[15] - - M_In.E[9] * M_In.E[3] * M_In.E[14] - - M_In.E[13] * M_In.E[2] * M_In.E[11] + - M_In.E[13] * M_In.E[3] * M_In.E[10]; - - M_Out->E[5] = M_In.E[0] * M_In.E[10] * M_In.E[15] - - M_In.E[0] * M_In.E[11] * M_In.E[14] - - M_In.E[8] * M_In.E[2] * M_In.E[15] + - M_In.E[8] * M_In.E[3] * M_In.E[14] + - M_In.E[12] * M_In.E[2] * M_In.E[11] - - M_In.E[12] * M_In.E[3] * M_In.E[10]; - - M_Out->E[9] = -M_In.E[0] * M_In.E[9] * M_In.E[15] + - M_In.E[0] * M_In.E[11] * M_In.E[13] + - M_In.E[8] * M_In.E[1] * M_In.E[15] - - M_In.E[8] * M_In.E[3] * M_In.E[13] - - M_In.E[12] * M_In.E[1] * M_In.E[11] + - M_In.E[12] * M_In.E[3] * M_In.E[9]; - - M_Out->E[13] = M_In.E[0] * M_In.E[9] * M_In.E[14] - - M_In.E[0] * M_In.E[10] * M_In.E[13] - - M_In.E[8] * M_In.E[1] * M_In.E[14] + - M_In.E[8] * M_In.E[2] * M_In.E[13] + - M_In.E[12] * M_In.E[1] * M_In.E[10] - - M_In.E[12] * M_In.E[2] * M_In.E[9]; - - M_Out->E[2] = M_In.E[1] * M_In.E[6] * M_In.E[15] - - M_In.E[1] * M_In.E[7] * M_In.E[14] - - M_In.E[5] * M_In.E[2] * M_In.E[15] + - M_In.E[5] * M_In.E[3] * M_In.E[14] + - M_In.E[13] * M_In.E[2] * M_In.E[7] - - M_In.E[13] * M_In.E[3] * M_In.E[6]; - - M_Out->E[6] = -M_In.E[0] * M_In.E[6] * M_In.E[15] + - M_In.E[0] * M_In.E[7] * M_In.E[14] + - M_In.E[4] * M_In.E[2] * M_In.E[15] - - M_In.E[4] * M_In.E[3] * M_In.E[14] - - M_In.E[12] * M_In.E[2] * M_In.E[7] + - M_In.E[12] * M_In.E[3] * M_In.E[6]; - - M_Out->E[10] = M_In.E[0] * M_In.E[5] * M_In.E[15] - - M_In.E[0] * M_In.E[7] * M_In.E[13] - - M_In.E[4] * M_In.E[1] * M_In.E[15] + - M_In.E[4] * M_In.E[3] * M_In.E[13] + - M_In.E[12] * M_In.E[1] * M_In.E[7] - - M_In.E[12] * M_In.E[3] * M_In.E[5]; - - M_Out->E[14] = -M_In.E[0] * M_In.E[5] * M_In.E[14] + - M_In.E[0] * M_In.E[6] * M_In.E[13] + - M_In.E[4] * M_In.E[1] * M_In.E[14] - - M_In.E[4] * M_In.E[2] * M_In.E[13] - - M_In.E[12] * M_In.E[1] * M_In.E[6] + - M_In.E[12] * M_In.E[2] * M_In.E[5]; - - M_Out->E[3] = -M_In.E[1] * M_In.E[6] * M_In.E[11] + - M_In.E[1] * M_In.E[7] * M_In.E[10] + - M_In.E[5] * M_In.E[2] * M_In.E[11] - - M_In.E[5] * M_In.E[3] * M_In.E[10] - - M_In.E[9] * M_In.E[2] * M_In.E[7] + - M_In.E[9] * M_In.E[3] * M_In.E[6]; - - M_Out->E[7] = M_In.E[0] * M_In.E[6] * M_In.E[11] - - M_In.E[0] * M_In.E[7] * M_In.E[10] - - M_In.E[4] * M_In.E[2] * M_In.E[11] + - M_In.E[4] * M_In.E[3] * M_In.E[10] + - M_In.E[8] * M_In.E[2] * M_In.E[7] - - M_In.E[8] * M_In.E[3] * M_In.E[6]; - - M_Out->E[11] = -M_In.E[0] * M_In.E[5] * M_In.E[11] + - M_In.E[0] * M_In.E[7] * M_In.E[9] + - M_In.E[4] * M_In.E[1] * M_In.E[11] - - M_In.E[4] * M_In.E[3] * M_In.E[9] - - M_In.E[8] * M_In.E[1] * M_In.E[7] + - M_In.E[8] * M_In.E[3] * M_In.E[5]; - - M_Out->E[15] = M_In.E[0] * M_In.E[5] * M_In.E[10] - - M_In.E[0] * M_In.E[6] * M_In.E[9] - - M_In.E[4] * M_In.E[1] * M_In.E[10] + - M_In.E[4] * M_In.E[2] * M_In.E[9] + - M_In.E[8] * M_In.E[1] * M_In.E[6] - - M_In.E[8] * M_In.E[2] * M_In.E[5]; - - det = M_In.E[0] * M_Out->E[0] + M_In.E[1] * M_Out->E[4] + M_In.E[2] * M_Out->E[8] + M_In.E[3] * M_Out->E[12]; - - if (det == 0) - { - return false; - } - - det = 1.0 / det; - - for (i = 0; i < 16; i++) - { - M_Out->E[i] = M_Out->E[i] * det; - } - - return true; -} - -#if defined(VECTOR_MATRIX_TEST_SUITE) - -void TestVectorMatrixMultiplication () -{ - s32 TestCount = 0; - s32 SuccessCount = 0; - - DebugPrint("\n\n-------------------------------------------------\n Begin Testing Vector/Matrix\n\n\n"); - - // Utility Functions - TestClean((GSSqrt(4.f) == 2.f), "Vector Square Root"); - TestClean((Lerp(0.f, 1.f, .5f) == .5f), "Vector Lerp"); - TestClean((Min(-.25f, 5.f) == -.25f), "Vector Min"); - TestClean((Max(-.25f, 5.f) == 5.f), "Vector Max"); - TestClean((Clamp(-2.f, -3.f, 5.f) == -2.f), "Vector Clamp, Lower Than Range"); - TestClean((Clamp(-2.f, 6.f, 5.f) == 5.f), "Vector Clamp, Higher Than Range"); - - ////////////////////////////// - // Vector Functions - ///////////////////////////// - - v2 V2Unit = v2{1, 0}; - v3 V3Unit = v3{1, 0, 0}; - v4 V4Unit = v4{1, 0, 0, 0}; - - v2 TestV2 = v2{1, 2}; - float TestV2MagSq = (TestV2.x * TestV2.x) + (TestV2.y * TestV2.y); - float TestV2Mag = GSSqrt(TestV2MagSq); - v2 TestV2Norm = v2{TestV2.x / TestV2Mag, TestV2.y / TestV2Mag}; - float TestV2DotR = (TestV2.x * V2Unit.x) + (TestV2.y * V2Unit.y); - - v3 TestV3 = v3{1, 2, 3}; - float TestV3MagSq = (TestV3.x * TestV3.x) + (TestV3.y * TestV3.y) + (TestV3.z * TestV3.z); - float TestV3Mag = GSSqrt(TestV3MagSq); - v3 TestV3Norm = v3{TestV3.x / TestV3Mag, TestV3.y / TestV3Mag, TestV3.z / TestV3Mag}; - float TestV3DotR = (TestV3.x * V3Unit.x) + (TestV3.y * V3Unit.y) + (TestV3.z * V3Unit.z); - - v4 TestV4 = v4{1, 2, 3, 4}; - float TestV4MagSq = (TestV4.x * TestV4.x) + (TestV4.y * TestV4.y) + (TestV4.z * TestV4.z) + (TestV4.w * TestV4.w); - float TestV4Mag = GSSqrt(TestV4MagSq); - v4 TestV4Norm = v4{ - TestV4.x / TestV4Mag, TestV4.y / TestV4Mag, TestV4.z / TestV4Mag, TestV4.w / TestV4Mag - }; - float TestV4DotR = (TestV4.x * V4Unit.x) + (TestV4.y * V4Unit.y) + (TestV4.z * V4Unit.z) + (TestV4.w * V4Unit.w); - - v2 DownCastV3 = V2(TestV3); - v3 DownCastV4 = V3(TestV4); - - v2 EqualityV2 = v2{TestV2.x, TestV2.y}; - v2 ZeroV2 = v2{0, 0}; - v3 EqualityV3 = v3{TestV3.x, TestV3.y, TestV3.z}; - v3 ZeroV3 = v3{0, 0, 0}; - v4 EqualityV4 = v4{TestV4.x, TestV4.y, TestV4.z, TestV4.w}; - v4 ZeroV4 = v4{0, 0, 0, 0}; - - TestClean((TestV2.x == 1 && TestV2.y == 2), "V2 Assignment"); - TestClean((TestV3.x == 1 && TestV3.y == 2 && TestV3.z == 3), "V3 Assignment"); - TestClean((TestV4.x == 1 && TestV4.y == 2 && TestV4.z == 3 && TestV4.w == 4), "V3 Assignment"); - - TestClean((DownCastV3.x == 1 && DownCastV3.y == 2), "V3 -> V2 Downcast"); - TestClean((DownCastV4.x == 1 && DownCastV4.y == 2 && DownCastV4.z == 3), "V4 -> V3 Downcast"); - - // Vector Operators - - TestClean((TestV2 == EqualityV2 && !(TestV2 == ZeroV2)), "V2 Equality"); - TestClean((TestV3 == EqualityV3 && !(TestV3 == ZeroV3)), "V3 Equality"); - TestClean((TestV4 == EqualityV4 && !(TestV4 == ZeroV4)), "V4 Equality"); - - TestClean(((TestV2 - TestV2) == ZeroV2), "V2 Subtraction"); - TestClean(((TestV3 - TestV3) == ZeroV3), "V3 Subtraction"); - TestClean(((TestV4 - TestV4) == ZeroV4), "V4 Subtraction"); - - TestClean(((TestV2 + TestV2) == v2{TestV2.x * 2, TestV2.y * 2}), "V2 Addition"); - TestClean(((TestV3 + TestV3) == v3{TestV3.x * 2, TestV3.y * 2, TestV3.z * 2}), "V3 Addition"); - TestClean(((TestV4 + TestV4) == v4{TestV4.x * 2, TestV4.y * 2, TestV4.z * 2, TestV4.w * 2}), "V4 Addition"); - - TestClean(((TestV2 * 2.0f) == v2{TestV2.x * 2, TestV2.y * 2}), "V2 Multiplication"); - TestClean(((TestV3 * 2.0f) == v3{TestV3.x * 2, TestV3.y * 2, TestV3.z * 2}), "V3 Multiplication"); - TestClean(((TestV4 * 2.0f) == v4{TestV4.x * 2, TestV4.y * 2, TestV4.z * 2, TestV4.w * 2}), "V4 Multiplication"); - - TestClean(((TestV2 * TestV2) == v2{TestV2.x * TestV2.x, TestV2.y * TestV2.y}), "V2 Piecewise Mult"); - TestClean(((TestV3 * TestV3) == v3{ - TestV3.x * TestV3.x, - TestV3.y * TestV3.y, - TestV3.z * TestV3.z}), "V3 Piecewise Mult"); - TestClean(((TestV4 * TestV4) == v4{ - TestV4.x * TestV4.x, - TestV4.y * TestV4.y, - TestV4.z * TestV4.z, - TestV4.w * TestV4.w}), "V4 Piecewise Mult"); - - - TestClean(((TestV2 / 2.0f) == v2{TestV2.x / 2, TestV2.y / 2}), "V2 Division"); - TestClean(((TestV3 / 2.0f) == v3{TestV3.x / 2, TestV3.y / 2, TestV3.z / 2}), "V3 Division"); - TestClean(((TestV4 / 2.0f) == v4{TestV4.x / 2, TestV4.y / 2, TestV4.z / 2, TestV4.w / 2}), "V4 Division"); - - TestClean(((TestV2 / TestV2) == v2{TestV2.x / TestV2.x, TestV2.y / TestV2.y}), "V2 Piecewise Div"); - TestClean(((TestV3 / TestV3) == v3{ - TestV3.x / TestV3.x, - TestV3.y / TestV3.y, - TestV3.z / TestV3.z}), "V3 Piecewise Div"); - TestClean(((TestV4 / TestV4) == v4{ - TestV4.x / TestV4.x, - TestV4.y / TestV4.y, - TestV4.z / TestV4.z, - TestV4.w / TestV4.w}), "V4 Piecewise Div"); - - TestClean(((MagSqr(V2Unit) == 1) && (MagSqr(TestV2) == TestV2MagSq)), "V2 Square Mag"); - TestClean(((MagSqr(V3Unit) == 1) && (MagSqr(TestV3) == TestV3MagSq)), "V3 Square Mag"); - TestClean(((MagSqr(V4Unit) == 1) && (MagSqr(TestV4) == TestV4MagSq)), "V4 Square Mag"); - TestClean(((Mag(V2Unit) == 1) && (Mag(TestV2) == TestV2Mag)), "V2 Mag"); - TestClean(((Mag(V3Unit) == 1) && (Mag(TestV3) == TestV3Mag)), "V3 Mag"); - TestClean(((Mag(V4Unit) == 1) && (Mag(TestV4) == TestV4Mag)), "V4 Mag"); - - TestClean((DistanceSq(ZeroV2, TestV2) == TestV2MagSq), "V2 Distance Sq"); - TestClean((DistanceSq(ZeroV3, TestV3) == TestV3MagSq), "V3 Distance Sq"); - TestClean((DistanceSq(ZeroV4, TestV4) == TestV4MagSq), "V4 Distance Sq"); - TestClean((Distance(ZeroV2, TestV2) == TestV2Mag), "V2 Distance"); - TestClean((Distance(ZeroV3, TestV3) == TestV3Mag), "V3 Distance"); - TestClean((Distance(ZeroV4, TestV4) == TestV4Mag), "V4 Distance"); - - TestClean((Normalize(TestV2) == TestV2Norm), "V2 Normalize"); - TestClean((Normalize(TestV3) == TestV3Norm), "V3 Normalize"); - TestClean((Normalize(TestV4) == TestV4Norm), "V4 Normalize"); - - TestClean(((Dot(V2Unit, V2Unit) == 1) && (Dot(TestV2, V2Unit) == TestV2DotR)), "V2 Dot"); - TestClean(((Dot(V3Unit, V3Unit) == 1) && (Dot(TestV3, V3Unit) == TestV3DotR)), "V3 Dot"); - TestClean(((Dot(V4Unit, V4Unit) == 1) && (Dot(TestV4, V4Unit) == TestV4DotR)), "V4 Dot"); - - // Skipping Cross For Now - - TestClean((Lerp(v2{0, 0}, v2{1, 1}, .5f) == v2{.5f, .5f}), "V2 Lerp"); - TestClean((Lerp(v3{0, 0, 0}, v3{1, 1, 1}, .5f) == v3{.5f, .5f, .5f}), "V3 Lerp"); - TestClean((Lerp(v4{0, 0, 0, 0}, v4{1, 1, 1, 1}, .5f) == v4{.5f, .5f, .5f, .5f}), "V4 Lerp"); - - ///////////////////////////// - // Matrix - //////////////////////////// - - m33 TestM33 = m33{ - 0, 1, 2, - 3, 4, 5, - 6, 7, 8}; - - m33 EqualityM33 = {}; - for (s32 i = 0; i < 16; i++) { EqualityM33.E[i] = TestM33.E[i]; } - - m33 TransposeM33 = m33{ - 0, 3, 6, - 1, 4, 7, - 2, 5, 8}; - - m33 IdentityM33 = m33{ - 1, 0, 0, - 0, 1, 0, - 0, 0, 1}; - - m33 TestM33Squared = m33{ - 15, 18, 21, - 42, 54, 66, - 69, 90, 111 - }; - - m44 TestM44 = m44{ - 0, 1, 2, 3, - 4, 5, 6, 7, - 8, 9, 10, 11, - 12, 13, 14, 15 - }; - - m44 EqualityM44 = {}; - for (s32 i = 0; i < 16; i++) { EqualityM44.E[i] = TestM44.E[i]; } - - m44 TransposeM44 = m44{ - 0, 4, 8, 12, - 1, 5, 9, 13, - 2, 6, 10, 14, - 3, 7, 11, 15 - }; - - m44 IdentityM44 = m44{ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - - m44 TestM44Squared = m44{ - 56, 62, 68, 74, - 152, 174, 196, 218, - 248, 286, 324, 362, - 344, 398, 452, 506, - }; - - TestClean(((IdentityM33 == IdentityM33) && (TestM33 == EqualityM33)), "M33 Equality"); - TestClean(((IdentityM44 == IdentityM44) && (TestM44 == EqualityM44)), "M44 Equality"); - - TestClean(((Transpose(IdentityM33) == IdentityM33) && - (Transpose(TestM33) == TransposeM33)), "M33 Transpose"); - TestClean(((Transpose(IdentityM44) == IdentityM44) && - (Transpose(TestM44) == TransposeM44)), "M44 Transpose"); - - TestClean(((TestM33 * IdentityM33) == TestM33), "M33 Identity Mult"); - TestClean(((TestM44 * IdentityM44) == TestM44), "M44 Identity Mult"); - TestClean(((TestM33 * TestM33) == TestM33Squared), "M33 Mult"); - TestClean(((TestM44 * TestM44) == TestM44Squared), "M44 Mult"); - - - // Useful Tests - v4 Right = v4{1, 0, 0, 0}; - v4 Forward = v4{0, 0, 1, 0}; - v4 Up = v4{0, 1, 0, 0}; - v4 Left = v4{-1, 0, 0, 0}; - v4 Back = v4{0, 0, -1, 0}; - v4 Down = v4{0, -1, 0, 0}; - - m44 NinetyDegreesAboutX = GetXRotation(M_PI / 2); - v4 Rotated = NinetyDegreesAboutX * Forward; - TestClean((Rotated == Up), "Rotation About X"); - - m44 NinetyDegreesAboutY = GetYRotation(M_PI / 2); - Rotated = NinetyDegreesAboutY * Right; - TestClean((Rotated == Forward), "Rotation About Y"); - - m44 NinetyDegreesAboutZ = GetZRotation(M_PI / 2); - Rotated = NinetyDegreesAboutZ * Right; - TestClean((Rotated == Down), "Rotation About Z"); - - - v4 A = v4{1, 2, 3, 4}; - m44 B = m44{ - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, 1, 2, 3, - 4, 5, 6, 7}; - v4 VTest = v4{30, 70, 29, 60}; - TestClean(((B * A) == VTest), "V4 M44 Multiplication"); - - m44 C = m44{ - 9, 8, 7, 6, - 5, 4, 3, 2, - 1, 0, 9, 8, - 7, 6, 5, 4 - }; - m44 MResult = B * C; - m44 MTest = m44{ - 50, 40, 60, 50, - 138, 112, 156, 130, - 109, 94, 99, 84, - 116, 94, 132, 110 - }; - TestClean(((B * C) == MTest), "M44 Mult Test 2"); - - m44 Identity = M44Identity(); - m44 InvIdentity = {}; - Inverse(Identity, &InvIdentity); - TestClean((Identity == InvIdentity), "Inverse Identity"); - - m44 Test = m44{ - 2, 4, 6, 7, - 5, 1, 8, 8, - 1, 7, 3, 1, - 3, 9, 2, 4 - }; - m44 PreCalcTestInv = m44{ - -0.3904761904761904762f, 0.26190476190476190475f, -0.02857142857142857139f, 0.16666666666666666668f, - 0.022222222222222222212f, -0.055555555555555555549f, 0.06666666666666666667f, 0.055555555555555555547f, - -0.00317460317460317458f, 0.07936507936507936506f, 0.27619047619047619045f, -0.2222222222222222222f, - 0.24444444444444444444f, -0.1111111111111111111f, -0.26666666666666666667f, 0.1111111111111111111f - }; - m44 InvTest = {}; - Inverse(Test, &InvTest); - //TestClean((PreCalcTestInv == InvTest), "Inverse M44"); - - DebugPrint("Results: Passed %d / %d\n\n\no", SuccessCount, TestCount); -} - -#endif - -#define GS_VECTOR_MATRIX_H -#endif \ No newline at end of file diff --git a/src/gs_libs/gs_win32.cpp b/src/gs_libs/gs_win32.cpp deleted file mode 100644 index 18074c6..0000000 --- a/src/gs_libs/gs_win32.cpp +++ /dev/null @@ -1,694 +0,0 @@ -// -// File: gs_win32.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef GS_WIN32_CPP - -#ifndef GS_WIN32_CPP - -struct win32_state -{ - b32 Initialized; - b32 Running; -}; - -struct win32_opengl_window_info -{ - s32 ColorBits; - s32 AlphaBits; - s32 DepthBits; - HGLRC RenderContext; -}; - -struct window -{ - char* Name; - char* ClassName; - s32 Width; - s32 Height; - WNDPROC WindowEventHandler; - - WNDCLASS Class; - HWND Handle; - HDC DeviceContext; - - // TODO(peter): Make this a union? - win32_opengl_window_info OpenGLInfo; -}; - -struct handle_window_msg_result -{ - b32 NeedsUpdate; -#if DEBUG - char MessageType[128]; -#endif -}; - -global win32_state GlobalWin32State; - -// Utility -internal s32 Win32StringLength(char* String); -internal s32 Win32ConcatStrings(s32 ALen, char* A, s32 BLen, char* B, s32 DestLen, char* Dest); - -// Windowing & Graphics -struct win32_offscreen_buffer -{ - texture_buffer Buffer; - BITMAPINFO Info; -}; - -LRESULT CALLBACK Win32HandleWindowsEvents (HWND WindowHandle, UINT Msg, WPARAM wParam, LPARAM lParam); -internal handle_window_msg_result HandleWindowsMessage (HWND WindowHandle, MSG Message); -internal void Win32UpdateWindowDimension(window* Window); -internal void Win32ResizeDIBSection(win32_offscreen_buffer *Buffer, int Width, int Height); -internal void Win32DisplayBufferInWindow(win32_offscreen_buffer* Buffer, window Window); - -/// -// Utils -/// - -internal s32 -Win32StringLength(char* String) -{ - char* At = String; - while (*At) { At++; }; - return At - String; -} - -internal s32 -Win32ConcatStrings(s32 ALength, char* A, s32 BLength, char* B, s32 DestLength, char* Dest) -{ - char* Dst = Dest; - char* AAt = A; - int ALengthToCopy = ALength < DestLength ? ALength : DestLength; - for (s32 a = 0; a < ALength; a++) - { - *Dst++ = *AAt++; - } - char* BAt = B; - int DestLengthRemaining = DestLength - (Dst - Dest); - int BLengthToCopy = BLength < DestLengthRemaining ? BLength : DestLength; - for (s32 b = 0; b < BLengthToCopy; b++) - { - *Dst++ = *BAt++; - } - int DestLengthOut = Dst - Dest; - int NullTermIndex = DestLengthOut < DestLength ? DestLengthOut : DestLength; - Dest[NullTermIndex] = 0; - return DestLengthOut; -} - -/// -// Windowing -/// - -internal window -Win32CreateWindow (HINSTANCE HInstance, char* WindowName, s32 Width, s32 Height, - WNDPROC WindowEventHandler) -{ - window Result = {}; - Result.Name = WindowName; - Result.ClassName = WindowName; - Result.Width = Width; - Result.Height = Height; - Result.WindowEventHandler = WindowEventHandler; - - Result.Class = {}; - Result.Class.style = CS_HREDRAW | CS_VREDRAW; - Result.Class.lpfnWndProc = WindowEventHandler; - Result.Class.hInstance = HInstance; - Result.Class.lpszClassName = WindowName; - - if (RegisterClass(&Result.Class)) - { - Result.Handle = CreateWindowEx( - 0, - Result.Class.lpszClassName, - WindowName, - WS_OVERLAPPEDWINDOW | WS_VISIBLE, - CW_USEDEFAULT, - CW_USEDEFAULT, - Width, - Height, - 0, - 0, - HInstance, - 0); - Result.DeviceContext = GetDC(Result.Handle); - } - - return Result; -}; - -internal window -PlatformCreateWindow (char* WindowName, s32 Width, s32 Height) -{ - HINSTANCE HInstance = GetModuleHandle(NULL); - return Win32CreateWindow(HInstance, WindowName, Width, Height, Win32HandleWindowsEvents); -} - -internal void -CreateOpenGLWindowContext (win32_opengl_window_info Info, window* Window) -{ - // Setup pixel format - { - PIXELFORMATDESCRIPTOR PixelFormatDesc = { 0 }; - // TODO: Program seems to work perfectly fine without all other params except dwFlags. - // Can we skip other params for the sake of brevity? - PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); - PixelFormatDesc.nVersion = 1; - PixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; - PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;// TODO(Peter): include this in win32_opengl_window_info? - PixelFormatDesc.cColorBits = Info.ColorBits; - PixelFormatDesc.cAlphaBits = Info.AlphaBits; - PixelFormatDesc.cDepthBits = Info.DepthBits; - PixelFormatDesc.dwLayerMask = PFD_MAIN_PLANE; // TODO(Peter): include this in win32_opengl_window_info? - // - - s32 PixelFormat = ChoosePixelFormat(Window->DeviceContext, &PixelFormatDesc); - if (!PixelFormat) { InvalidCodePath; } // TODO: Log: Choose pixel format failed - if (!SetPixelFormat(Window->DeviceContext, PixelFormat, &PixelFormatDesc)) { InvalidCodePath; } // TODO: Log: Set pixel format failed - } - - // Create rendering context - { - // TODO: Create "proper" context? - // https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation - - Info.RenderContext = wglCreateContext(Window->DeviceContext); - wglMakeCurrent(Window->DeviceContext, Info.RenderContext); - - // TODO(Peter): do we want this? - /* - glGetIntegerv(GL_MAJOR_VERSION, ); - glGetIntegerv(GL_MINOR_VERSION, ); - (char*)glGetString(GL_VENDOR); - (char*)glGetString(GL_RENDERER); - */ - } - - Window->OpenGLInfo = Info; -} - -struct handle_window_event_result -{ - LRESULT Result; - b32 Handled; -}; - -internal void -Win32UpdateInputFrameMouseButtonState (input_frame* InputFrame, key_code KeyCode, int Win32VirtualKey) -{ - InputFrame->KeysDown[KeyCode] = (GetKeyState(Win32VirtualKey) & (1 << 15)) != 0; -} - -internal void -Win32UpdateInputFrameMouseState (input_frame* InputFrame) -{ - Win32UpdateInputFrameMouseButtonState(InputFrame, KeyCode_MouseLeftButton, VK_LBUTTON); - Win32UpdateInputFrameMouseButtonState(InputFrame, KeyCode_MouseMiddleButton, VK_MBUTTON); - Win32UpdateInputFrameMouseButtonState(InputFrame, KeyCode_MouseRightButton, VK_RBUTTON); - // NOTE(Peter): If you decide to support extra mouse buttons, on windows the key codes are - // VK_XBUTTON1 and VK_XBUTTON2 -} - -internal void -Win32UpdateInputFrameMouseWheelDelta (input_frame* InputFrame, MSG Message) -{ - int MouseWheel = GET_WHEEL_DELTA_WPARAM(Message.wParam); - InputFrame->MouseScroll = MouseWheel; -} - -internal handle_window_event_result -HandleWindowEventUnlessWouldUseDefault (HWND WindowHandle, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - handle_window_event_result Result = {}; - Result.Handled = false; - - switch (Msg) - { - case WM_SIZE: - { - - Result.Handled = true; - }break; - - case WM_CLOSE: - { - Result.Result = DefWindowProc(WindowHandle, Msg, wParam, lParam); - Result.Handled = true; - }break; - - case WM_DESTROY: - { - GlobalWin32State.Running = false; - Result.Handled = true; - }break; - - case WM_PAINT: - { - PAINTSTRUCT PaintStruct; - HDC DeviceContext; - b32 PaintResult; - - DeviceContext = BeginPaint(WindowHandle, &PaintStruct); - PaintResult = EndPaint(WindowHandle, &PaintStruct); - Result.Handled = true; - }break; - } - - return Result; -} - -LRESULT CALLBACK -Win32HandleWindowsEvents ( - HWND WindowHandle, - UINT Msg, - WPARAM wParam, - LPARAM lParam - ) -{ - handle_window_event_result EventResult = HandleWindowEventUnlessWouldUseDefault( - WindowHandle, - Msg, - wParam, - lParam); - - if (!EventResult.Handled) - { - EventResult.Result = DefWindowProc(WindowHandle, Msg, wParam, lParam); - } - - return EventResult.Result; -} - -static key_code -Win32GetKeyCode (int Win32VirtualKey, bool NumpadValid, bool TranslateToChar) -{ - key_code Result = KeyCode_Invalid; - - if (Win32VirtualKey == VK_ESCAPE) { Result = KeyCode_Esc; } - - if (!TranslateToChar) - { - if (Win32VirtualKey == VK_SPACE) { Result = KeyCode_Space; } - - } - - if (Win32VirtualKey == VK_CAPITAL) { Result = KeyCode_CapsLock; } - else if (Win32VirtualKey == VK_TAB) { Result = KeyCode_Tab; } - else if (Win32VirtualKey == VK_LSHIFT) { Result = KeyCode_LeftShift; } - else if (Win32VirtualKey == VK_RSHIFT) { Result = KeyCode_RightShift; } - else if (Win32VirtualKey == VK_LCONTROL) { Result = KeyCode_LeftCtrl; } - else if (Win32VirtualKey == VK_RCONTROL) { Result = KeyCode_RightCtrl; } - - // TODO(Peter): support the function key? - //else if (Win32VirtualKey == VK_) { Result = KeyCode_Fn; } - - else if (Win32VirtualKey == VK_MENU) { Result = KeyCode_Alt; } - else if (Win32VirtualKey == VK_PRIOR) { Result = KeyCode_PageUp; } - else if (Win32VirtualKey == VK_NEXT) { Result = KeyCode_PageDown; } - else if (Win32VirtualKey == VK_BACK) { Result = KeyCode_Backspace; } - else if (Win32VirtualKey == VK_DELETE) { Result = KeyCode_Delete; } - else if (Win32VirtualKey == VK_RETURN) { Result = KeyCode_Enter; } - - else if (Win32VirtualKey == VK_F1) { Result = KeyCode_F1; } - else if (Win32VirtualKey == VK_F2) { Result = KeyCode_F2; } - else if (Win32VirtualKey == VK_F3) { Result = KeyCode_F3; } - else if (Win32VirtualKey == VK_F4) { Result = KeyCode_F4; } - else if (Win32VirtualKey == VK_F5) { Result = KeyCode_F5; } - else if (Win32VirtualKey == VK_F6) { Result = KeyCode_F6; } - else if (Win32VirtualKey == VK_F7) { Result = KeyCode_F7; } - else if (Win32VirtualKey == VK_F8) { Result = KeyCode_F8; } - else if (Win32VirtualKey == VK_F9) { Result = KeyCode_F9; } - else if (Win32VirtualKey == VK_F10) { Result = KeyCode_F10; } - else if (Win32VirtualKey == VK_F11) { Result = KeyCode_F11; } - else if (Win32VirtualKey == VK_F12) { Result = KeyCode_F12; } - - if (!TranslateToChar) - { - if (Win32VirtualKey == 0x30) { Result = KeyCode_0; } - else if (Win32VirtualKey == 0x31) { Result = KeyCode_1; } - else if (Win32VirtualKey == 0x32) { Result = KeyCode_2; } - else if (Win32VirtualKey == 0x33) { Result = KeyCode_3; } - else if (Win32VirtualKey == 0x34) { Result = KeyCode_4; } - else if (Win32VirtualKey == 0x35) { Result = KeyCode_5; } - else if (Win32VirtualKey == 0x36) { Result = KeyCode_6; } - else if (Win32VirtualKey == 0x37) { Result = KeyCode_7; } - else if (Win32VirtualKey == 0x38) { Result = KeyCode_8; } - else if (Win32VirtualKey == 0x39) { Result = KeyCode_9; } - - else if (Win32VirtualKey == 0x41) { Result = KeyCode_A; } - else if (Win32VirtualKey == 0x42) { Result = KeyCode_B; } - else if (Win32VirtualKey == 0x43) { Result = KeyCode_C; } - else if (Win32VirtualKey == 0x44) { Result = KeyCode_D; } - else if (Win32VirtualKey == 0x45) { Result = KeyCode_E; } - else if (Win32VirtualKey == 0x46) { Result = KeyCode_F; } - else if (Win32VirtualKey == 0x47) { Result = KeyCode_G; } - else if (Win32VirtualKey == 0x48) { Result = KeyCode_H; } - else if (Win32VirtualKey == 0x49) { Result = KeyCode_I; } - else if (Win32VirtualKey == 0x4A) { Result = KeyCode_J; } - else if (Win32VirtualKey == 0x4B) { Result = KeyCode_K; } - else if (Win32VirtualKey == 0x4C) { Result = KeyCode_L; } - else if (Win32VirtualKey == 0x4D) { Result = KeyCode_M; } - else if (Win32VirtualKey == 0x4E) { Result = KeyCode_N; } - else if (Win32VirtualKey == 0x4F) { Result = KeyCode_O; } - else if (Win32VirtualKey == 0x50) { Result = KeyCode_P; } - else if (Win32VirtualKey == 0x51) { Result = KeyCode_Q; } - else if (Win32VirtualKey == 0x52) { Result = KeyCode_R; } - else if (Win32VirtualKey == 0x53) { Result = KeyCode_S; } - else if (Win32VirtualKey == 0x54) { Result = KeyCode_T; } - else if (Win32VirtualKey == 0x55) { Result = KeyCode_U; } - else if (Win32VirtualKey == 0x56) { Result = KeyCode_V; } - else if (Win32VirtualKey == 0x57) { Result = KeyCode_W; } - else if (Win32VirtualKey == 0x58) { Result = KeyCode_X; } - else if (Win32VirtualKey == 0x59) { Result = KeyCode_Y; } - else if (Win32VirtualKey == 0x5A) { Result = KeyCode_Z; } - } - - if (NumpadValid) - { - if (Win32VirtualKey == VK_NUMPAD0) { Result = KeyCode_Num0; } - else if (Win32VirtualKey == VK_NUMPAD1) { Result = KeyCode_Num1; } - else if (Win32VirtualKey == VK_NUMPAD2) { Result = KeyCode_Num2; } - else if (Win32VirtualKey == VK_NUMPAD3) { Result = KeyCode_Num3; } - else if (Win32VirtualKey == VK_NUMPAD4) { Result = KeyCode_Num4; } - else if (Win32VirtualKey == VK_NUMPAD5) { Result = KeyCode_Num5; } - else if (Win32VirtualKey == VK_NUMPAD6) { Result = KeyCode_Num6; } - else if (Win32VirtualKey == VK_NUMPAD7) { Result = KeyCode_Num7; } - else if (Win32VirtualKey == VK_NUMPAD8) { Result = KeyCode_Num8; } - else if (Win32VirtualKey == VK_NUMPAD9) { Result = KeyCode_Num9; } - } - - if (Win32VirtualKey == VK_UP) { Result = KeyCode_UpArrow; } - else if (Win32VirtualKey == VK_DOWN) { Result = KeyCode_DownArrow; } - else if (Win32VirtualKey == VK_LEFT) { Result = KeyCode_LeftArrow; } - else if (Win32VirtualKey == VK_RIGHT) { Result = KeyCode_RightArrow; } - - return Result; -} - -internal handle_window_msg_result -HandleWindowsMessage ( - HWND WindowHandle, - MSG Message) -{ - handle_window_msg_result Result = {}; - Result.NeedsUpdate = 0; - - switch (Message.message) - { - case WM_HOTKEY: - { - }break; - - case WM_MOUSEWHEEL: - { - int MouseWheel = GET_WHEEL_DELTA_WPARAM(Message.wParam); - /* - Input.New->MouseScroll = MouseWheel; - Result.NeedsUpdate = true; - */ - }break; - - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - { - /* - Input.New->KeyStates[KeyCode_MouseLeftButton] = (GetKeyState(VK_LBUTTON) & (1 << 15)) != 0; - Input.New->KeyStates[KeyCode_MouseMiddleButton] = (GetKeyState(VK_MBUTTON) & (1 << 15)) != 0; - Input.New->KeyStates[KeyCode_MouseRightButton] = (GetKeyState(VK_RBUTTON) & (1 << 15)) != 0; - // NOTE(Peter): If you decide to support extra mouse buttons, on windows the key codes are - // VK_XBUTTON1 and VK_XBUTTON2 - - if (KeyTransitionedDown(KeyCode_MouseLeftButton, Input)) - { - Input.MouseDownX = Input.New->MouseX; - Input.MouseDownY = Input.New->MouseY; - } - Result.NeedsUpdate = true;*/ - }break; - - case WM_MOUSEMOVE: - { - POINT MousePos; - GetCursorPos(&MousePos); - ScreenToClient(WindowHandle, &MousePos); - - /* - Input.New->MouseX = MousePos.x; - Input.New->MouseY = App.WindowHeight - MousePos.y; - - Result.NeedsUpdate = true; - */ - }break; - - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_KEYDOWN: - case WM_KEYUP: - { - int VirtualKey = (int)Message.wParam; - bool KeyDown = (Message.lParam & (1 << 31)) == 0; - int KeyIndex = Win32GetKeyCode(VirtualKey, true, true); - /* - if (KeyIndex >= 0) - { - DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_KEYEvent "); - Input.New->KeyStates[KeyIndex] = KeyDown; - Result.NeedsUpdate = true; - } - else - { - if (Input.TranslateInputToCharValues && KeyDown) - { - // NOTE(Peter): Took this out b/c we're translating the WM_CHAR messages - // in the message pump, and if we do it here as well, character producing - // key messages get put on the message queue twice - TranslateMessage(&Message); - DispatchMessage(&Message); - } - else - { - DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_KEYEvent "); - // NOTE(Peter): This is so that when you lift up a key that was generating a WM_CHAR, - // the app still has a chance to respond to it. - Result.NeedsUpdate = true; - } - } - */ - }break; - - case WM_CHAR: - { - /* - char TranslatedChar = (char)Message.wParam; - int KeyIndex = GetKeyIndexFromChar(TranslatedChar); - - if (KeyIndex >= 0) - { - // NOTE(Peter): Always setting this to true becuase windows is stupid and doesn't - // pass the press/release bit through correctly. So now the KEYDOWN/KEYUP Messages above - // only translate the message to a WM_CHAR message if its a key down. Since we clear all - // keystates to false at the beginning of an input frame, this will make transitions - // get registered correctly. - Input.New->KeyStates[KeyIndex] = true; - Result.NeedsUpdate = true; - } - else - { - printf("Translated Char Not Recognized: %c\n", TranslatedChar); - } - */ - }break; - - default: - { - TranslateMessage(&Message); - DispatchMessage(&Message); - }break; - } - - return Result; -} - -internal void -Win32UpdateWindowDimension(window* Window) -{ - RECT ClientRect; - GetClientRect(Window->Handle, &ClientRect); - Window->Width = ClientRect.right - ClientRect.left; - Window->Height = ClientRect.bottom - ClientRect.top; -} - -internal void -Win32ResizeDIBSection(win32_offscreen_buffer *Win32Buffer, int Width, int Height) -{ - if(Win32Buffer->Buffer.Memory) - { - VirtualFree(Win32Buffer->Buffer.Memory, 0, MEM_RELEASE); - } - - Win32Buffer->Buffer.Width = Width; - Win32Buffer->Buffer.Height = Height; - - int BytesPerPixel = 4; - Win32Buffer->Buffer.BytesPerPixel = BytesPerPixel; - - Win32Buffer->Info.bmiHeader.biSize = sizeof(Win32Buffer->Info.bmiHeader); - Win32Buffer->Info.bmiHeader.biWidth = Win32Buffer->Buffer.Width; - Win32Buffer->Info.bmiHeader.biHeight = -Win32Buffer->Buffer.Height; // Top down, not bottom up - Win32Buffer->Info.bmiHeader.biPlanes = 1; - Win32Buffer->Info.bmiHeader.biBitCount = 32; - Win32Buffer->Info.bmiHeader.biCompression = BI_RGB; - - int BitmapMemorySize = (Win32Buffer->Buffer.Width * Win32Buffer->Buffer.Height)*BytesPerPixel; - Win32Buffer->Buffer.Memory = (u8*)VirtualAlloc(0, BitmapMemorySize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - Win32Buffer->Buffer.Pitch = Width*BytesPerPixel; -} - -internal void -Win32DisplayBufferInWindow(win32_offscreen_buffer* Win32Buffer, window Window) -{ - StretchDIBits(Window.DeviceContext, - 0, 0, Win32Buffer->Buffer.Width, Win32Buffer->Buffer.Height, - 0, 0, Win32Buffer->Buffer.Width, Win32Buffer->Buffer.Height, - Win32Buffer->Buffer.Memory, - &Win32Buffer->Info, - DIB_RGB_COLORS, SRCCOPY); -} - -///////////////////////////////////////// -// -// Open GL -// -///////////////////////////////////////// - - -internal void -OpenGLRenderTriBuffer (u8* Vertecies, s32 VertexElements, - u8* UVs, s32 UVElements, - u8* Colors, s32 ColorsElements, - s32 TriCount) -{ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(VertexElements, GL_FLOAT, VertexElements * sizeof(r32), Vertecies); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(UVElements, GL_FLOAT, UVElements * sizeof(r32), UVs); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(ColorsElements, GL_FLOAT, ColorsElements * sizeof(r32), Colors); - - glDrawArrays(GL_TRIANGLES, 0, TriCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); -} - -internal void -OpenGLDraw3DTri (v4 P0, v4 P1, v4 P2, - v2 UV0, v2 UV1, v2 UV2, - v4 C0, v4 C1, v4 C2) -{ - glBegin(GL_TRIANGLES); - - glTexCoord2f(UV0.x, UV0.y); - glColor4f(C0.r, C0.g, C0.b, C0.a); - glVertex4f(P0.x, P0.y, P0.z, P0.w); - - glTexCoord2f(UV1.x, UV1.y); - glColor4f(C1.r, C1.g, C1.b, C1.a); - glVertex4f(P1.x, P1.y, P1.z, P1.w); - - glTexCoord2f(UV2.x, UV2.y); - glColor4f(C2.r, C2.g, C2.b, C2.a); - glVertex4f(P2.x, P2.y, P2.z, P2.w); - - glEnd(); -} - -internal void -OpenGLDraw2DTri (v2 P0, v2 P1, v2 P2, - v2 UV0, v2 UV1, v2 UV2, - v4 C0, v4 C1, v4 C2) -{ - glBegin(GL_TRIANGLES); - - glTexCoord2f(UV0.x, UV0.y); - glColor4f(C0.r, C0.g, C0.b, C0.a); - glVertex2f(P0.x, P0.y); - - glTexCoord2f(UV1.x, UV1.y); - glColor4f(C1.r, C1.g, C1.b, C1.a); - glVertex2f(P1.x, P1.y); - - glTexCoord2f(UV2.x, UV2.y); - glColor4f(C2.r, C2.g, C2.b, C2.a); - glVertex2f(P2.x, P2.y); - - glEnd(); -} - -internal void -LoadModelView (r32 Matrix[16]) -{ - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(Matrix); -} - -internal void -LoadProjection (r32 Matrix[16]) -{ - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(Matrix); -} - -internal void -ClearRenderBuffer () -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -s32 NextTextureHandle = 1; -internal s32 -SubmitTexture (u8* Memory, s32 Width, s32 Height) -{ - s32 TextureHandle = NextTextureHandle++; - glBindTexture(GL_TEXTURE_2D, TextureHandle); - glTexImage2D(GL_TEXTURE_2D, - 0, // mip map level - GL_RGBA8, - Width, - Height, - 0, // border - GL_RGBA, - GL_UNSIGNED_BYTE, - Memory); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - return TextureHandle; -} - -internal void -BindTexture (s32 TextureHandle) -{ - glBindTexture(GL_TEXTURE_2D, TextureHandle); -} - -#define GS_WIN32_CPP -#endif // GS_WIN32_CPP - -#define GS_WIN32_CPP -#endif // GS_WIN32_CPP \ No newline at end of file diff --git a/src/gs_libs/gs_win32.h b/src/gs_libs/gs_win32.h deleted file mode 100644 index 4a0a24b..0000000 --- a/src/gs_libs/gs_win32.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// File: gs_win32.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef GS_WIN32_H - -#ifndef GS_WIN32_H - -#define GS_WIN32_H -#endif // GS_WIN32_H - - -#define GS_WIN32_H -#endif // GS_WIN32_H \ No newline at end of file diff --git a/src_v2/libs/HandmadeMath.h b/src/libs/HandmadeMath.h similarity index 100% rename from src_v2/libs/HandmadeMath.h rename to src/libs/HandmadeMath.h diff --git a/src_v2/libs/glfw_osx/include/GLFW/glfw3.h b/src/libs/glfw_osx/include/GLFW/glfw3.h similarity index 100% rename from src_v2/libs/glfw_osx/include/GLFW/glfw3.h rename to src/libs/glfw_osx/include/GLFW/glfw3.h diff --git a/src_v2/libs/glfw_osx/include/GLFW/glfw3native.h b/src/libs/glfw_osx/include/GLFW/glfw3native.h similarity index 100% rename from src_v2/libs/glfw_osx/include/GLFW/glfw3native.h rename to src/libs/glfw_osx/include/GLFW/glfw3native.h diff --git a/src_v2/libs/glfw_osx/lib-arm64/libglfw.3.dylib b/src/libs/glfw_osx/lib-arm64/libglfw.3.dylib similarity index 100% rename from src_v2/libs/glfw_osx/lib-arm64/libglfw.3.dylib rename to src/libs/glfw_osx/lib-arm64/libglfw.3.dylib diff --git a/src_v2/libs/glfw_osx/lib-arm64/libglfw3.a b/src/libs/glfw_osx/lib-arm64/libglfw3.a similarity index 100% rename from src_v2/libs/glfw_osx/lib-arm64/libglfw3.a rename to src/libs/glfw_osx/lib-arm64/libglfw3.a diff --git a/src_v2/libs/glfw_osx/lib-universal/libglfw.3.dylib b/src/libs/glfw_osx/lib-universal/libglfw.3.dylib similarity index 100% rename from src_v2/libs/glfw_osx/lib-universal/libglfw.3.dylib rename to src/libs/glfw_osx/lib-universal/libglfw.3.dylib diff --git a/src_v2/libs/glfw_osx/lib-universal/libglfw3.a b/src/libs/glfw_osx/lib-universal/libglfw3.a similarity index 100% rename from src_v2/libs/glfw_osx/lib-universal/libglfw3.a rename to src/libs/glfw_osx/lib-universal/libglfw3.a diff --git a/src_v2/libs/glfw_osx/lib-x86_64/libglfw.3.dylib b/src/libs/glfw_osx/lib-x86_64/libglfw.3.dylib similarity index 100% rename from src_v2/libs/glfw_osx/lib-x86_64/libglfw.3.dylib rename to src/libs/glfw_osx/lib-x86_64/libglfw.3.dylib diff --git a/src_v2/libs/glfw_osx/lib-x86_64/libglfw3.a b/src/libs/glfw_osx/lib-x86_64/libglfw3.a similarity index 100% rename from src_v2/libs/glfw_osx/lib-x86_64/libglfw3.a rename to src/libs/glfw_osx/lib-x86_64/libglfw3.a diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/config/ftconfig.h b/src/libs/sloth/freetype/freetype2/freetype/config/ftconfig.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/config/ftconfig.h rename to src/libs/sloth/freetype/freetype2/freetype/config/ftconfig.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/config/ftheader.h b/src/libs/sloth/freetype/freetype2/freetype/config/ftheader.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/config/ftheader.h rename to src/libs/sloth/freetype/freetype2/freetype/config/ftheader.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/config/ftmodule.h b/src/libs/sloth/freetype/freetype2/freetype/config/ftmodule.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/config/ftmodule.h rename to src/libs/sloth/freetype/freetype2/freetype/config/ftmodule.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/config/ftoption.h b/src/libs/sloth/freetype/freetype2/freetype/config/ftoption.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/config/ftoption.h rename to src/libs/sloth/freetype/freetype2/freetype/config/ftoption.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/config/ftstdlib.h b/src/libs/sloth/freetype/freetype2/freetype/config/ftstdlib.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/config/ftstdlib.h rename to src/libs/sloth/freetype/freetype2/freetype/config/ftstdlib.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/freetype.h b/src/libs/sloth/freetype/freetype2/freetype/freetype.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/freetype.h rename to src/libs/sloth/freetype/freetype2/freetype/freetype.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftadvanc.h b/src/libs/sloth/freetype/freetype2/freetype/ftadvanc.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftadvanc.h rename to src/libs/sloth/freetype/freetype2/freetype/ftadvanc.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftbbox.h b/src/libs/sloth/freetype/freetype2/freetype/ftbbox.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftbbox.h rename to src/libs/sloth/freetype/freetype2/freetype/ftbbox.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftbdf.h b/src/libs/sloth/freetype/freetype2/freetype/ftbdf.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftbdf.h rename to src/libs/sloth/freetype/freetype2/freetype/ftbdf.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftbitmap.h b/src/libs/sloth/freetype/freetype2/freetype/ftbitmap.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftbitmap.h rename to src/libs/sloth/freetype/freetype2/freetype/ftbitmap.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftbzip2.h b/src/libs/sloth/freetype/freetype2/freetype/ftbzip2.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftbzip2.h rename to src/libs/sloth/freetype/freetype2/freetype/ftbzip2.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftcache.h b/src/libs/sloth/freetype/freetype2/freetype/ftcache.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftcache.h rename to src/libs/sloth/freetype/freetype2/freetype/ftcache.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftchapters.h b/src/libs/sloth/freetype/freetype2/freetype/ftchapters.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftchapters.h rename to src/libs/sloth/freetype/freetype2/freetype/ftchapters.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftcid.h b/src/libs/sloth/freetype/freetype2/freetype/ftcid.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftcid.h rename to src/libs/sloth/freetype/freetype2/freetype/ftcid.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftdriver.h b/src/libs/sloth/freetype/freetype2/freetype/ftdriver.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftdriver.h rename to src/libs/sloth/freetype/freetype2/freetype/ftdriver.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/fterrdef.h b/src/libs/sloth/freetype/freetype2/freetype/fterrdef.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/fterrdef.h rename to src/libs/sloth/freetype/freetype2/freetype/fterrdef.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/fterrors.h b/src/libs/sloth/freetype/freetype2/freetype/fterrors.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/fterrors.h rename to src/libs/sloth/freetype/freetype2/freetype/fterrors.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftfntfmt.h b/src/libs/sloth/freetype/freetype2/freetype/ftfntfmt.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftfntfmt.h rename to src/libs/sloth/freetype/freetype2/freetype/ftfntfmt.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftgasp.h b/src/libs/sloth/freetype/freetype2/freetype/ftgasp.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftgasp.h rename to src/libs/sloth/freetype/freetype2/freetype/ftgasp.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftglyph.h b/src/libs/sloth/freetype/freetype2/freetype/ftglyph.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftglyph.h rename to src/libs/sloth/freetype/freetype2/freetype/ftglyph.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftgxval.h b/src/libs/sloth/freetype/freetype2/freetype/ftgxval.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftgxval.h rename to src/libs/sloth/freetype/freetype2/freetype/ftgxval.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftgzip.h b/src/libs/sloth/freetype/freetype2/freetype/ftgzip.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftgzip.h rename to src/libs/sloth/freetype/freetype2/freetype/ftgzip.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftimage.h b/src/libs/sloth/freetype/freetype2/freetype/ftimage.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftimage.h rename to src/libs/sloth/freetype/freetype2/freetype/ftimage.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftincrem.h b/src/libs/sloth/freetype/freetype2/freetype/ftincrem.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftincrem.h rename to src/libs/sloth/freetype/freetype2/freetype/ftincrem.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftlcdfil.h b/src/libs/sloth/freetype/freetype2/freetype/ftlcdfil.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftlcdfil.h rename to src/libs/sloth/freetype/freetype2/freetype/ftlcdfil.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftlist.h b/src/libs/sloth/freetype/freetype2/freetype/ftlist.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftlist.h rename to src/libs/sloth/freetype/freetype2/freetype/ftlist.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftlzw.h b/src/libs/sloth/freetype/freetype2/freetype/ftlzw.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftlzw.h rename to src/libs/sloth/freetype/freetype2/freetype/ftlzw.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftmac.h b/src/libs/sloth/freetype/freetype2/freetype/ftmac.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftmac.h rename to src/libs/sloth/freetype/freetype2/freetype/ftmac.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftmm.h b/src/libs/sloth/freetype/freetype2/freetype/ftmm.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftmm.h rename to src/libs/sloth/freetype/freetype2/freetype/ftmm.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftmodapi.h b/src/libs/sloth/freetype/freetype2/freetype/ftmodapi.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftmodapi.h rename to src/libs/sloth/freetype/freetype2/freetype/ftmodapi.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftmoderr.h b/src/libs/sloth/freetype/freetype2/freetype/ftmoderr.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftmoderr.h rename to src/libs/sloth/freetype/freetype2/freetype/ftmoderr.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftotval.h b/src/libs/sloth/freetype/freetype2/freetype/ftotval.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftotval.h rename to src/libs/sloth/freetype/freetype2/freetype/ftotval.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftoutln.h b/src/libs/sloth/freetype/freetype2/freetype/ftoutln.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftoutln.h rename to src/libs/sloth/freetype/freetype2/freetype/ftoutln.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftparams.h b/src/libs/sloth/freetype/freetype2/freetype/ftparams.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftparams.h rename to src/libs/sloth/freetype/freetype2/freetype/ftparams.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftpfr.h b/src/libs/sloth/freetype/freetype2/freetype/ftpfr.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftpfr.h rename to src/libs/sloth/freetype/freetype2/freetype/ftpfr.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftrender.h b/src/libs/sloth/freetype/freetype2/freetype/ftrender.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftrender.h rename to src/libs/sloth/freetype/freetype2/freetype/ftrender.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftsizes.h b/src/libs/sloth/freetype/freetype2/freetype/ftsizes.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftsizes.h rename to src/libs/sloth/freetype/freetype2/freetype/ftsizes.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftsnames.h b/src/libs/sloth/freetype/freetype2/freetype/ftsnames.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftsnames.h rename to src/libs/sloth/freetype/freetype2/freetype/ftsnames.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftstroke.h b/src/libs/sloth/freetype/freetype2/freetype/ftstroke.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftstroke.h rename to src/libs/sloth/freetype/freetype2/freetype/ftstroke.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftsynth.h b/src/libs/sloth/freetype/freetype2/freetype/ftsynth.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftsynth.h rename to src/libs/sloth/freetype/freetype2/freetype/ftsynth.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftsystem.h b/src/libs/sloth/freetype/freetype2/freetype/ftsystem.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftsystem.h rename to src/libs/sloth/freetype/freetype2/freetype/ftsystem.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/fttrigon.h b/src/libs/sloth/freetype/freetype2/freetype/fttrigon.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/fttrigon.h rename to src/libs/sloth/freetype/freetype2/freetype/fttrigon.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/fttypes.h b/src/libs/sloth/freetype/freetype2/freetype/fttypes.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/fttypes.h rename to src/libs/sloth/freetype/freetype2/freetype/fttypes.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ftwinfnt.h b/src/libs/sloth/freetype/freetype2/freetype/ftwinfnt.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ftwinfnt.h rename to src/libs/sloth/freetype/freetype2/freetype/ftwinfnt.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/autohint.h b/src/libs/sloth/freetype/freetype2/freetype/internal/autohint.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/autohint.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/autohint.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/cffotypes.h b/src/libs/sloth/freetype/freetype2/freetype/internal/cffotypes.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/cffotypes.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/cffotypes.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/cfftypes.h b/src/libs/sloth/freetype/freetype2/freetype/internal/cfftypes.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/cfftypes.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/cfftypes.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftcalc.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftcalc.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftcalc.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftcalc.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftdebug.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftdebug.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftdebug.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftdebug.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftdrv.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftdrv.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftdrv.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftdrv.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftgloadr.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftgloadr.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftgloadr.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftgloadr.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/fthash.h b/src/libs/sloth/freetype/freetype2/freetype/internal/fthash.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/fthash.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/fthash.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftmemory.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftmemory.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftmemory.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftmemory.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftobjs.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftobjs.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftobjs.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftobjs.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftpic.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftpic.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftpic.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftpic.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftpsprop.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftpsprop.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftpsprop.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftpsprop.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftrfork.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftrfork.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftrfork.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftrfork.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftserv.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftserv.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftserv.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftserv.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftstream.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftstream.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftstream.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftstream.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/fttrace.h b/src/libs/sloth/freetype/freetype2/freetype/internal/fttrace.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/fttrace.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/fttrace.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftvalid.h b/src/libs/sloth/freetype/freetype2/freetype/internal/ftvalid.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/ftvalid.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/ftvalid.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/internal.h b/src/libs/sloth/freetype/freetype2/freetype/internal/internal.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/internal.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/internal.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/psaux.h b/src/libs/sloth/freetype/freetype2/freetype/internal/psaux.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/psaux.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/psaux.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/pshints.h b/src/libs/sloth/freetype/freetype2/freetype/internal/pshints.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/pshints.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/pshints.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svbdf.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svbdf.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svbdf.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svbdf.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svcfftl.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svcfftl.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svcfftl.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svcfftl.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svcid.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svcid.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svcid.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svcid.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svfntfmt.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svfntfmt.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svfntfmt.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svfntfmt.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svgldict.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svgldict.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svgldict.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svgldict.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svgxval.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svgxval.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svgxval.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svgxval.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svkern.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svkern.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svkern.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svkern.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svmetric.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svmetric.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svmetric.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svmetric.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svmm.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svmm.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svmm.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svmm.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svotval.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svotval.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svotval.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svotval.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpfr.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svpfr.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpfr.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svpfr.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpostnm.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svpostnm.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpostnm.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svpostnm.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svprop.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svprop.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svprop.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svprop.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpscmap.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svpscmap.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpscmap.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svpscmap.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpsinfo.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svpsinfo.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svpsinfo.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svpsinfo.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svsfnt.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svsfnt.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svsfnt.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svsfnt.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svttcmap.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svttcmap.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svttcmap.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svttcmap.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svtteng.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svtteng.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svtteng.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svtteng.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svttglyf.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svttglyf.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svttglyf.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svttglyf.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svwinfnt.h b/src/libs/sloth/freetype/freetype2/freetype/internal/services/svwinfnt.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/services/svwinfnt.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/services/svwinfnt.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/sfnt.h b/src/libs/sloth/freetype/freetype2/freetype/internal/sfnt.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/sfnt.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/sfnt.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/t1types.h b/src/libs/sloth/freetype/freetype2/freetype/internal/t1types.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/t1types.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/t1types.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/internal/tttypes.h b/src/libs/sloth/freetype/freetype2/freetype/internal/tttypes.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/internal/tttypes.h rename to src/libs/sloth/freetype/freetype2/freetype/internal/tttypes.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/t1tables.h b/src/libs/sloth/freetype/freetype2/freetype/t1tables.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/t1tables.h rename to src/libs/sloth/freetype/freetype2/freetype/t1tables.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/ttnameid.h b/src/libs/sloth/freetype/freetype2/freetype/ttnameid.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/ttnameid.h rename to src/libs/sloth/freetype/freetype2/freetype/ttnameid.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/tttables.h b/src/libs/sloth/freetype/freetype2/freetype/tttables.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/tttables.h rename to src/libs/sloth/freetype/freetype2/freetype/tttables.h diff --git a/src_v2/libs/sloth/freetype/freetype2/freetype/tttags.h b/src/libs/sloth/freetype/freetype2/freetype/tttags.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/freetype/tttags.h rename to src/libs/sloth/freetype/freetype2/freetype/tttags.h diff --git a/src_v2/libs/sloth/freetype/freetype2/ft2build.h b/src/libs/sloth/freetype/freetype2/ft2build.h similarity index 100% rename from src_v2/libs/sloth/freetype/freetype2/ft2build.h rename to src/libs/sloth/freetype/freetype2/ft2build.h diff --git a/src_v2/libs/sloth/freetype/libfreetype-mac.a b/src/libs/sloth/freetype/libfreetype-mac.a similarity index 100% rename from src_v2/libs/sloth/freetype/libfreetype-mac.a rename to src/libs/sloth/freetype/libfreetype-mac.a diff --git a/src_v2/libs/sloth/sloth.h b/src/libs/sloth/sloth.h similarity index 100% rename from src_v2/libs/sloth/sloth.h rename to src/libs/sloth/sloth.h diff --git a/src_v2/libs/sloth/sloth_sokol_shader.glsl b/src/libs/sloth/sloth_sokol_shader.glsl similarity index 100% rename from src_v2/libs/sloth/sloth_sokol_shader.glsl rename to src/libs/sloth/sloth_sokol_shader.glsl diff --git a/src_v2/libs/sloth/sloth_sokol_shader.glsl.h b/src/libs/sloth/sloth_sokol_shader.glsl.h similarity index 100% rename from src_v2/libs/sloth/sloth_sokol_shader.glsl.h rename to src/libs/sloth/sloth_sokol_shader.glsl.h diff --git a/src_v2/libs/sloth/sloth_tests.c b/src/libs/sloth/sloth_tests.c similarity index 100% rename from src_v2/libs/sloth/sloth_tests.c rename to src/libs/sloth/sloth_tests.c diff --git a/src_v2/libs/sloth/utils/sloth_profiler.c b/src/libs/sloth/utils/sloth_profiler.c similarity index 100% rename from src_v2/libs/sloth/utils/sloth_profiler.c rename to src/libs/sloth/utils/sloth_profiler.c diff --git a/src_v2/libs/stb_sprintf.h b/src/libs/stb_sprintf.h similarity index 100% rename from src_v2/libs/stb_sprintf.h rename to src/libs/stb_sprintf.h diff --git a/src_v2/libs/stb_truetype.h b/src/libs/stb_truetype.h similarity index 100% rename from src_v2/libs/stb_truetype.h rename to src/libs/stb_truetype.h diff --git a/src_v2/lumenarium_bsp.h b/src/lumenarium_bsp.h similarity index 100% rename from src_v2/lumenarium_bsp.h rename to src/lumenarium_bsp.h diff --git a/src_v2/lumenarium_first.c b/src/lumenarium_first.c similarity index 100% rename from src_v2/lumenarium_first.c rename to src/lumenarium_first.c diff --git a/src_v2/lumenarium_first.h b/src/lumenarium_first.h similarity index 100% rename from src_v2/lumenarium_first.h rename to src/lumenarium_first.h diff --git a/src_v2/lumenarium_geometry.h b/src/lumenarium_geometry.h similarity index 100% rename from src_v2/lumenarium_geometry.h rename to src/lumenarium_geometry.h diff --git a/src_v2/lumenarium_input.cpp b/src/lumenarium_input.cpp similarity index 100% rename from src_v2/lumenarium_input.cpp rename to src/lumenarium_input.cpp diff --git a/src_v2/lumenarium_memory.cpp b/src/lumenarium_memory.cpp similarity index 100% rename from src_v2/lumenarium_memory.cpp rename to src/lumenarium_memory.cpp diff --git a/src_v2/lumenarium_memory.h b/src/lumenarium_memory.h similarity index 100% rename from src_v2/lumenarium_memory.h rename to src/lumenarium_memory.h diff --git a/src_v2/lumenarium_tests.cpp b/src/lumenarium_tests.cpp similarity index 100% rename from src_v2/lumenarium_tests.cpp rename to src/lumenarium_tests.cpp diff --git a/src_v2/lumenarium_texture_atlas.c b/src/lumenarium_texture_atlas.c similarity index 100% rename from src_v2/lumenarium_texture_atlas.c rename to src/lumenarium_texture_atlas.c diff --git a/src_v2/lumenarium_types.h b/src/lumenarium_types.h similarity index 100% rename from src_v2/lumenarium_types.h rename to src/lumenarium_types.h diff --git a/src/meta/foldhaus_meta.cpp b/src/meta/foldhaus_meta.cpp deleted file mode 100644 index f298f2d..0000000 --- a/src/meta/foldhaus_meta.cpp +++ /dev/null @@ -1,355 +0,0 @@ -// -// File: foldhaus_meta.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-19 -// -#ifndef FOLDHAUS_META_CPP - -#include "gs_meta.cpp" -#include "gs_meta_typeinfo_generator.h" - -internal void -GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* NodeSpecificationGen, string_builder* CallNodeProcGen, gs_meta_preprocessor Meta) -{ - // TODO(Peter): Create a FilterTypesByTag function to create a contiguous array - // of type_definition** - - WriteF(NodeSpecificationGen, "static node_specification_ NodeSpecifications[] = {\n"); - - WriteF(CallNodeProcGen, "void CallNodeProc(node_type Type, u8* NodeData)\n{\n"); - WriteF(CallNodeProcGen, " switch(Type) { \n"); - for (u32 b = 0; b < Meta.TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = Meta.TypeTable.Types[b]; - for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++) - { - if (Bucket.Keys[i] == 0) { continue; } - - type_definition* Decl = Bucket.Values + i; - if (HasTag(MakeStringLiteral("node_proc"), Decl->MetaTags, Meta.TypeTable) && - Decl->Type == TypeDef_Function) - { - if (Decl->Function.Parameters.Used > 1) - { - WriteF(CallNodeProcGen, "ERROR: Procedure tagged with node_proc has more than one parameter\n"); - continue; - } - - AddEnumElement(NodeTypeGen, Decl->Identifier); - - variable_decl* Param = Decl->Function.Parameters.GetElementAtIndex(0); - type_table_handle ParamTypeHandle = Param->TypeHandle; - type_definition* ParamType = GetTypeDefinition(ParamTypeHandle, Meta.TypeTable); - - type_table_handle ReturnTypeHandle = Decl->Function.ReturnTypeHandle; - type_definition* ReturnType = GetTypeDefinition(ReturnTypeHandle, Meta.TypeTable); - - WriteF(NodeSpecificationGen, "{ NodeType_%S, {\"%S\", %d}, gsm_StructType_%S }, \n", - Decl->Identifier, - Decl->Identifier, - Decl->Identifier.Length, - ParamType->Identifier); - - WriteF(CallNodeProcGen, " case NodeType_%.*s:\n", StringExpand(Decl->Identifier)); - WriteF(CallNodeProcGen, " {\n"); - WriteF(CallNodeProcGen, " %.*s(", StringExpand(Decl->Identifier)); - WriteF(CallNodeProcGen, "(%.*s*)NodeData", StringExpand(ParamType->Identifier)); - - WriteF(CallNodeProcGen, ");\n"); - WriteF(CallNodeProcGen, " } break;\n"); - } - } - } - WriteF(CallNodeProcGen, " }\n"); - WriteF(CallNodeProcGen, "}\n\n"); - - WriteF(NodeSpecificationGen, "};\n\n"); - - FinishEnumGeneration(NodeTypeGen); -} - -struct panel_elements -{ - string PanelIdentifier; - type_table_handle InitProcDecl; - type_table_handle CleanupProcDecl; - type_table_handle RenderProcDecl; - type_table_handle PanelCommandsStruct; -}; - -internal b32 -StringIsPrefixedBy (string Prefix, string TestString) -{ - b32 Result = false; - - if (TestString.Length >= Prefix.Length) - { - Result = true; - for (s32 i = 0; i < Prefix.Length; i++) - { - if (Prefix.Memory[i] != TestString.Memory[i]) - { - Result = false; - break; - } - } - } - - return Result; -} - -internal void -AttemptPlacePanelProc(type_table_handle ProcHandle, type_table TypeTable, gs_bucket* Panels) -{ - string InitProcTag = MakeStringLiteral("panel_init"); - string CleanupProcTag = MakeStringLiteral("panel_cleanup"); - string RenderProcTag = MakeStringLiteral("panel_render"); - string PanelTypePrefix = MakeStringLiteral("panel_type_"); - - type_definition* Decl = GetTypeDefinition(ProcHandle, TypeTable); - meta_tag* PanelTypeTag = 0; - - for (u32 i = 0; i < Decl->MetaTags.Used; i++) - { - type_table_handle MetaTagHandle = *Decl->MetaTags.GetElementAtIndex(i); - meta_tag* MetaTag = GetMetaTag(MetaTagHandle, TypeTable); - if (StringIsPrefixedBy(PanelTypePrefix, MetaTag->Identifier)) - { - PanelTypeTag = MetaTag; - break; - } - } - - if (PanelTypeTag != 0) - { - s32 PanelIndex = -1; - for (u32 i = 0; i < Panels->Used; i++) - { - panel_elements* Panel = Panels->GetElementAtIndex(i); - if (StringsEqual(Panel->PanelIdentifier, PanelTypeTag->Identifier)) - { - PanelIndex = (s32)i; - break; - } - } - if (PanelIndex < 0) - { - panel_elements NewPanel = {0}; - NewPanel.PanelIdentifier = PanelTypeTag->Identifier; - PanelIndex = Panels->PushElementOnBucket(NewPanel); - } - - Assert(PanelIndex >= 0); - panel_elements* PanelElements = Panels->GetElementAtIndex(PanelIndex); - if (HasTag(InitProcTag, Decl->MetaTags, TypeTable)) - { - PanelElements->InitProcDecl = ProcHandle; - } - else if (HasTag(CleanupProcTag, Decl->MetaTags, TypeTable)) - { - PanelElements->CleanupProcDecl = ProcHandle; - } - else if (HasTag(RenderProcTag, Decl->MetaTags, TypeTable)) - { - PanelElements->RenderProcDecl = ProcHandle; - } - } -} - -internal void -AttemptPlacePanelCommands(type_table_handle StructHandle, type_table TypeTable, gs_bucket* Panels) -{ - string CommandsTag = MakeStringLiteral("panel_commands"); - - type_definition* Decl = GetTypeDefinition(StructHandle, TypeTable); - if (HasTag(CommandsTag, Decl->MetaTags, TypeTable)) - { - for (u32 i = 0; i < Decl->MetaTags.Used; i++) - { - type_table_handle MetaTagHandle = *Decl->MetaTags.GetElementAtIndex(i); - meta_tag* MetaTag = GetMetaTag(MetaTagHandle, TypeTable); - printf("%.*s, ", StringExpand(MetaTag->Identifier)); - } - printf("\n"); - } -} - -internal void -MakeReadableIdentifier(string* Identifier) -{ - for (s32 i = 0; i < Identifier->Length; i++) - { - char At = Identifier->Memory[i]; - if (At == '_') - { - Identifier->Memory[i] = ' '; - } - else if (IsAlpha(At) && (i == 0 || IsWhitespace(Identifier->Memory[i - 1]))) - { - Identifier->Memory[i] = ToUpper(At); - } - } -} - -internal void -GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelEnumGen, string_builder* PanelCodeGen) -{ - gs_bucket Panels = {0}; - - for (u32 b = 0; b < Meta.TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = Meta.TypeTable.Types[b]; - for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++) - { - if (Bucket.Keys[i] == 0) { continue; } - - type_table_handle DeclHandle = {(s32)b, i}; - type_definition* Decl = Bucket.Values + i; - - if (Decl->Type == TypeDef_Function) - { - AttemptPlacePanelProc(DeclHandle, Meta.TypeTable, &Panels); - } - else if (Decl->Type == TypeDef_Struct) - { - AttemptPlacePanelCommands(DeclHandle, Meta.TypeTable, &Panels); - } - } - } - - WriteF(PanelEnumGen, "enum panel_type {\n"); - WriteF(PanelCodeGen, "global s32 GlobalPanelDefsCount = %d;\n", Panels.Used); - WriteF(PanelCodeGen, "global panel_definition GlobalPanelDefs[] = {\n"); - for (u32 i = 0; i < Panels.Used; i++) - { - panel_elements* Panel = Panels.GetElementAtIndex(i); - string PanelIdentifier = {0}; - PanelIdentifier.Max = Panel->PanelIdentifier.Length; - PanelIdentifier.Memory = (char*)malloc(sizeof(char) * PanelIdentifier.Max); - CopyStringTo(Substring(Panel->PanelIdentifier, 11), &PanelIdentifier); - MakeReadableIdentifier(&PanelIdentifier); - - type_definition* InitDecl = GetTypeDefinition(Panel->InitProcDecl, Meta.TypeTable); - type_definition* CleanupDecl = GetTypeDefinition(Panel->CleanupProcDecl, Meta.TypeTable); - type_definition* RenderDecl = GetTypeDefinition(Panel->RenderProcDecl, Meta.TypeTable); - - WriteF(PanelCodeGen, "{ \"%S\", %d, ", PanelIdentifier, PanelIdentifier.Length); - WriteF(PanelCodeGen, "%S, ", InitDecl->Identifier); - WriteF(PanelCodeGen, "%S, ", CleanupDecl->Identifier); - WriteF(PanelCodeGen, "%S, ", RenderDecl->Identifier); - - // TODO(Peter): This is a shortcut cause I'm being lazy. We arent' putting arrays into the - // AST when we parse our codebase so there's no way to tag the array of Commands for each - // panel for use here. Instead, I'm just requiring that the array be of the form - // _Commands where panel_name_base is whatever the Init function is called - // minus _Input. So for example, if you have ScupltureView_Init, then the panel_name_base is - // SculptureView and the commands array must be called SculptureView_Commands. - // Ideally we actually go through and parse these arrays. - string InitSuffix = MakeStringLiteral("_Init"); - string PanelNameBase = Substring(InitDecl->Identifier, 0, InitDecl->Identifier.Length - InitSuffix.Length); - WriteF(PanelCodeGen, "%S_Commands, ", PanelNameBase); - WriteF(PanelCodeGen, "%S_CommandsCount ", PanelNameBase); - - WriteF(PanelEnumGen, "PanelType_%S,\n", PanelNameBase); - - WriteF(PanelCodeGen, "},\n"); - } - WriteF(PanelCodeGen, "};\n"); - WriteF(PanelEnumGen, "};\n"); -} - -internal string -AllocAndConcatStrings(string First, string Second) -{ - string Result = {0}; - Result.Max = First.Length + Second.Length + 1; - Result.Memory = (char*)malloc(sizeof(char) * Result.Max); - ConcatString(First, &Result); - ConcatString(Second, &Result); - NullTerminate(&Result); - Result.Length -= 1; - return Result; -} - -int main(int ArgCount, char* Args[]) -{ - if (ArgCount <= 1) - { - printf("Please supply at least one source directory to analyze.\n"); - return 0; - } - - string RootFile = MakeString(Args[1]); - s32 IndexOfLastSlash = ReverseSearchForCharInSet(RootFile, "\\/"); - string WorkingDirectory = Substring(RootFile, 0, IndexOfLastSlash + 1); - string GeneratedDirectoryName = MakeStringLiteral("generated\\"); - string GeneratedFilesDirectory = AllocAndConcatStrings(WorkingDirectory, GeneratedDirectoryName); - printf("Putting Generated Files In %s\n", GeneratedFilesDirectory.Memory); - - gs_meta_preprocessor Meta = PreprocessProgram(Args[1]); - - typeinfo_generator TypeGenerator = InitTypeInfoGenerator(Meta.TypeTable); - GenerateMetaTagList(Meta.TypeTable, &TypeGenerator); - GenerateFilteredTypeInfo(MakeStringLiteral("node_struct"), Meta.TypeTable, &TypeGenerator); - GenerateFilteredTypeInfo(MakeStringLiteral("gen_type_info"), Meta.TypeTable, &TypeGenerator); - FinishGeneratingTypes(&TypeGenerator); - - gsm_code_generator NodeTypeGen = BeginEnumGeneration("node_type", "NodeType", false, true); - string_builder NodeSpecificationGen = {0}; - string_builder CallNodeProcGen = {0}; - GenerateNodeMetaInfo(&NodeTypeGen, &NodeSpecificationGen, &CallNodeProcGen, Meta); - - string_builder PanelEnumGen = {0}; - string_builder PanelCodeGen = {0}; - GeneratePanelMetaInfo(Meta, &PanelEnumGen, &PanelCodeGen); - - string TypeInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("gs_meta_generated_typeinfo.h")); - FILE* TypeInfoH = fopen(TypeInfoHFilePath.Memory, "w"); - if (TypeInfoH) - { - WriteStringBuilderToFile(TypeGenerator.MetaTagEnum, TypeInfoH); - WriteStringBuilderToFile(TypeGenerator.MetaTagString, TypeInfoH); - WriteStringBuilderToFile(*TypeGenerator.TypeList.Builder, TypeInfoH); - WriteStringBuilderToFile(TypeGenerator.StructMembers, TypeInfoH); - WriteStringBuilderToFile(TypeGenerator.TypeDefinitions, TypeInfoH); - fclose(TypeInfoH); - } - else - { - printf("Error: Unable to open file at %.*s\n", StringExpand(TypeInfoHFilePath)); - } - - string NodeInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("foldhaus_nodes_generated.h")); - FILE* NodeInfoH = fopen(NodeInfoHFilePath.Memory, "w"); - if (NodeInfoH) - { - WriteStringBuilderToFile(*NodeTypeGen.Builder, NodeInfoH); - WriteStringBuilderToFile(NodeSpecificationGen, NodeInfoH); - WriteStringBuilderToFile(CallNodeProcGen, NodeInfoH); - fclose(NodeInfoH); - } - else - { - printf("Error: Unable to open file at %.*s\n", StringExpand(NodeInfoHFilePath)); - } - - string PanelInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("foldhaus_panels_generated.h")); - FILE* PanelInfoH = fopen(PanelInfoHFilePath.Memory, "w"); - if (PanelInfoH) - { - WriteStringBuilderToFile(PanelEnumGen, PanelInfoH); - WriteStringBuilderToFile(PanelCodeGen, PanelInfoH); - fclose(PanelInfoH); - } - else - { - printf("Error: Unable to open file at %.*s\n", StringExpand(PanelInfoHFilePath)); - } - - FinishMetaprogram(&Meta); - - return 0; -} - -#define FOLDHAUS_META_CPP -#endif // FOLDHAUS_META_CPP \ No newline at end of file diff --git a/src/meta/gs_meta.cpp b/src/meta/gs_meta.cpp deleted file mode 100644 index 36c406a..0000000 --- a/src/meta/gs_meta.cpp +++ /dev/null @@ -1,1613 +0,0 @@ -// -// File: gs_meta.cpp -// Author: Peter Slattery -// Creation Date: 2020-01-19 -// -// -// Usage -// -// GSMetaTag() to give commands to the meta layer -// -// Tag Values -// -// breakpoint -// will cause the meta layer to break in the debugger when it reaches -// that point in processing the file -// TODO: specify which stage you want it to break at - -#ifndef GS_META_CPP - -#include -#include - -#include "..\gs_libs\gs_language.h" -#include "..\gs_libs\gs_bucket.h" - -#include "..\gs_libs\gs_memory_arena.h" -#include "..\gs_libs\gs_string.h" - -#include "gs_meta_lexer.h" -#include "gs_meta_error.h" - -#include "gs_meta_type_table.h" - -struct source_code_file -{ - string Path; - s32 FileSize; - string Contents; - - s32 FirstTokenIndex; - s32 LastTokenIndex; -}; - -struct token_iter -{ - gs_bucket* Tokens; - token* TokenAt; - s32 TokenAtIndex; - s32 FirstToken; - s32 LastToken; - -#define TOKEN_ITER_SNAPSHOTS_MAX 64 - u32 SnapshotsUsed; - u32 Snapshots[TOKEN_ITER_SNAPSHOTS_MAX]; - - errors* Errors; -}; - -struct gsm_profiler_scope -{ - s64 StartTime; - s64 EndTime; - r32 Seconds; - r32 LongestSeconds; - u32 CallCount; - string Category; - string Identifier; -}; - -struct gsm_profiler_category -{ - string Identifier; - r32 TotalTime; - u32 SubscopesCount; - gsm_profiler_scope* LongestSubscope; -}; - -struct gsm_profiler -{ - gs_bucket Scopes; - gs_bucket Categories; -}; - -struct gs_meta_preprocessor -{ - errors Errors; - - gs_bucket SourceFiles; - gs_bucket Tokens; - - gs_bucket TagList; - - type_table TypeTable; - - // Performance - s64 PreprocessorStartTime; - s64 TokenizeTime; - s64 PreprocTime; - s64 FixupTime; - s64 PreprocessorEndTime; - - gsm_profiler Profiler; -}; - -// ------------------------ -// Timing / Performance -// ------------------------ - -internal s64 -GetWallClock () -{ - LARGE_INTEGER Time; - if (!QueryPerformanceCounter(&Time)) - { - s32 Error = GetLastError(); - // TODO(Peter): I'm waiting to see an error actually occur here - // to know what it could possibly be. - InvalidCodePath; - } - return (s64)Time.QuadPart; -} - -internal s64 -GetPerformanceFrequency () -{ - LARGE_INTEGER Frequency; - if (!QueryPerformanceFrequency(&Frequency)) - { - s32 Error = GetLastError(); - // TODO(Peter): I'm waiting to see an error actually occur here - // to know what it could possibly be. - InvalidCodePath; - } - return (s64)Frequency.QuadPart; -} -internal r32 -GetSecondsElapsed(s64 CyclesCount) -{ - s64 Frequency = GetPerformanceFrequency(); - r32 SecondsElapsed = (r32)(CyclesCount) / (r32)(Frequency); - return SecondsElapsed; -} - -internal r32 -GetSecondsElapsed(s64 StartCycles, s64 EndCycles) -{ - return GetSecondsElapsed(EndCycles - StartCycles); -} - -internal gsm_profiler_scope* -FindMatchingScope(gsm_profiler* Profiler, string Category, string Identifier) -{ - gsm_profiler_scope* Result = 0; - for (u32 i = 0; i < Profiler->Scopes.Used; i++) - { - gsm_profiler_scope* Scope = Profiler->Scopes.GetElementAtIndex(i); - if (StringsEqual(Scope->Identifier, Identifier) && - StringsEqual(Scope->Category, Category)) - { - Result = Scope; - break; - } - } - return Result; -} - -internal gsm_profiler_scope* -BeginScope(gsm_profiler* Profiler, string Category, string Identifier) -{ - gsm_profiler_scope* Scope = FindMatchingScope(Profiler, Category, Identifier); - if (!Scope) - { - Scope = Profiler->Scopes.TakeElement(); - *Scope = {}; - } - Scope->Category = Category; - Scope->Identifier = Identifier; - Scope->StartTime = GetWallClock(); - return Scope; -} - -internal gsm_profiler_scope* -BeginScope(gsm_profiler* Profiler, char* Category, char* Identifier) -{ - return BeginScope(Profiler, MakeStringLiteral(Category), MakeStringLiteral(Identifier)); -} - -internal void -EndScope(gsm_profiler_scope* Scope) -{ - Scope->EndTime = GetWallClock(); - r32 Seconds = GetSecondsElapsed(Scope->StartTime, Scope->EndTime); - Scope->Seconds += Seconds; - if (Seconds > Scope->LongestSeconds) - { - Scope->LongestSeconds = Seconds; - } - Scope->CallCount++; -} - -internal gsm_profiler_category* -GetCategory(string Identifier, gsm_profiler* Profiler) -{ - gsm_profiler_category* Result = 0; - - for (u32 i = 0; i < Profiler->Categories.Used; i++) - { - gsm_profiler_category* Category = Profiler->Categories.GetElementAtIndex(i); - if (StringsEqual(Identifier, Category->Identifier)) - { - Result = Category; - break; - } - } - - if (Result == 0) - { - Result = Profiler->Categories.TakeElement(); - *Result = {}; - Result->Identifier = Identifier; - } - - return Result; -} - -internal void -FinishProfiler(gsm_profiler* Profiler) -{ - for (u32 i = 0; i < Profiler->Scopes.Used; i++) - { - gsm_profiler_scope* Scope = Profiler->Scopes.GetElementAtIndex(i); - gsm_profiler_category* Category = GetCategory(Scope->Category, Profiler); - Category->TotalTime += Scope->Seconds; - Category->SubscopesCount++; - - if (!Category->LongestSubscope || - Scope->Seconds > Category->LongestSubscope->Seconds) - { - Category->LongestSubscope = Scope; - } - } -} - -internal void -PrintAllCategories(gsm_profiler* Profiler) -{ - for (u32 i = 0; i < Profiler->Categories.Used; i++) - { - gsm_profiler_category* Category = Profiler->Categories.GetElementAtIndex(i); - printf("Category: %.*s Total Time: %.*f Count: %d\n", - StringExpand(Category->Identifier), - 6, Category->TotalTime, - Category->SubscopesCount); - printf(" Longest Scope: %.*s Total Time: %.*f Longest Time: %.*f Call Count: %d\n", - StringExpand(Category->LongestSubscope->Identifier), - 6, Category->LongestSubscope->Seconds, - 6, Category->LongestSubscope->LongestSeconds, - Category->LongestSubscope->CallCount); - - if (StringsEqual(Category->Identifier, MakeStringLiteral("parse"))) - { - for (u32 j = 0; j < Profiler->Scopes.Used; j++) - { - gsm_profiler_scope* Scope = Profiler->Scopes.GetElementAtIndex(j); - if (StringsEqual(Scope->Category, Category->Identifier)) - { - printf(" Time: %.*f Call Count: %d Scope: %.*s\n", - 6, Scope->Seconds, - Scope->CallCount, - StringExpand(Scope->Identifier)); - } - } - } - } -} - -// ------------------------ -// Token Iterator -// ------------------------ - -internal token* -NextToken (token_iter* Iter) -{ - if (Iter->TokenAtIndex < Iter->LastToken) - { - Iter->TokenAtIndex++; - Iter->TokenAt = Iter->Tokens->GetElementAtIndex(Iter->TokenAtIndex); - } - - return Iter->TokenAt; -} - -internal b32 -TokenAtEquals(token_iter* Iter, char* String) -{ - b32 Result = false; - if (StringEqualsCharArray(Iter->TokenAt->Text, String)) - { - Result = true; - NextToken(Iter); - } - return Result; -} - -internal b32 -TokenAtEquals(token_iter* Iter, token_type Type) -{ - b32 Result = false; - if (Iter->TokenAt->Type == Type) - { - Result = true; - NextToken(Iter); - } - return Result; -} - -internal b32 -TokenAtEquals(token_iter* Iter, token_type Type, token* Token) -{ - b32 Result = false; - if (Iter->TokenAt->Type == Type) - { - Result = true; - *Token = *Iter->TokenAt; - NextToken(Iter); - } - return Result; -} - -internal void -PushSnapshot (token_iter* Iter) -{ - Iter->Snapshots[Iter->SnapshotsUsed++] = Iter->TokenAtIndex; -} - -internal void -PopSnapshot (token_iter* Iter) -{ - if (Iter->SnapshotsUsed > 0) - { - Iter->SnapshotsUsed -= 1; - } -} - -internal void -ApplySnapshot (token_iter* Iter) -{ - u32 SnapshotIndex = Iter->SnapshotsUsed; - u32 SnapshotPoint = Iter->Snapshots[SnapshotIndex]; - Iter->TokenAtIndex = SnapshotPoint; - Iter->TokenAt = Iter->Tokens->GetElementAtIndex(SnapshotPoint); -} - -internal void -ApplySnapshotIfNotParsedAndPop(b32 ParseSuccess, token_iter* Iter) -{ - PopSnapshot(Iter); - if (!ParseSuccess) - { - ApplySnapshot(Iter); - } -} - - -internal s32 -GetFileSize (char* FileName) -{ - s32 Result = 0; - - FILE* ReadFile = fopen(FileName, "r"); - if (ReadFile) - { - fseek(ReadFile, 0, SEEK_END); - size_t FileSize = ftell(ReadFile); - fseek(ReadFile, 0, SEEK_SET); - - Result = (s32)FileSize; - fclose(ReadFile); - } - - return Result; -} - -// ------------------------- -// Source File Handling -// ------------------------- - -internal s32 -ReadEntireFileAndNullTerminate (source_code_file* File, errors* Errors) -{ - s32 LengthRead = 0; - - FILE* ReadFile = fopen(File->Path.Memory, "r"); - if (ReadFile) - { - fseek(ReadFile, 0, SEEK_END); - size_t FileSize = ftell(ReadFile); - fseek(ReadFile, 0, SEEK_SET); - - Assert(File->Contents.Memory == 0); - File->Contents.Max = (s32)FileSize + 1; - File->Contents.Memory = (char*)malloc(File->Contents.Max); - - size_t ReadSize = fread(File->Contents.Memory, 1, FileSize, ReadFile); - File->Contents.Memory[FileSize] = 0; - File->Contents.Length = (s32)ReadSize; - - LengthRead = (s32)ReadSize + 1; - fclose(ReadFile); - } - - return LengthRead; -} - -internal b32 -FileAlreadyInSource(string Path, gs_bucket SourceFiles) -{ - b32 Result = false; - - for (u32 i = 0; i < SourceFiles.Used; i++) - { - source_code_file* File = SourceFiles.GetElementAtIndex(i); - if (StringsEqual(File->Path, Path)) - { - Result = true; - break; - } - } - - return Result; -} - -internal void -AddFileToSource(string RelativePath, source_code_file CurrentFile, gs_bucket* SourceFiles, errors* Errors) -{ - source_code_file File = {0}; - - File.FirstTokenIndex = -1; - File.LastTokenIndex = -1; - - u32 PathLength = RelativePath.Length + 1; - File.Path = MakeString((char*)malloc(sizeof(char) * PathLength), 0, PathLength); - CopyStringTo(RelativePath, &File.Path); - NullTerminate(&File.Path); - - File.FileSize = ReadEntireFileAndNullTerminate(&File, Errors); - - if (File.FileSize > 0) - { - SourceFiles->PushElementOnBucket(File); - } - else - { - PushFError(Errors, "Error: Could not load file %S.\n", RelativePath); - if (CurrentFile.Path.Length > 0) - { - PushFError(Errors, " Loaded In: %S\n", CurrentFile.Path); - } - } -} - -internal void -TokenizeFile (source_code_file* File, gs_bucket* Tokens) -{ - tokenizer Tokenizer = {}; - Tokenizer.At = File->Contents.Memory; - Tokenizer.Memory = File->Contents.Memory; - Tokenizer.MemoryLength = File->Contents.Max; - - token* LastToken = 0; - while(AtValidPosition(Tokenizer)) - { - token NewToken = GetNextToken(&Tokenizer); - u32 TokenIndex = Tokens->PushElementOnBucket(NewToken); - if (File->FirstTokenIndex < 0) - { - File->FirstTokenIndex = (s32)TokenIndex; - } - } - - File->LastTokenIndex = Tokens->Used - 1; -} - -// ------------------------ -// Parsing -// ------------------------ - -internal b32 -ParseMetaTag(token_iter* Iter, gs_meta_preprocessor* Meta) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseMetaTag")); - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "GSMetaTag") && - TokenAtEquals(Iter, "(")) - { - token MetaIdentifier = {0}; - if (TokenAtEquals(Iter, Token_Identifier, &MetaIdentifier)) - { - if (TokenAtEquals(Iter, ")") && - TokenAtEquals(Iter, ";")) - { - Result = true; - type_table_handle MetaTagHandle = GetMetaTagHandle(MetaIdentifier.Text, Meta->TypeTable); - if (!TypeHandleIsValid(MetaTagHandle)) - { - meta_tag Tag = {0}; - Tag.Identifier = MetaIdentifier.Text; - MetaTagHandle = PushMetaTagOnTable(Tag, &Meta->TypeTable); - } - - Assert(TypeHandleIsValid(MetaTagHandle)); - Meta->TagList.PushElementOnBucket(MetaTagHandle); - - if (StringsEqual(MetaIdentifier.Text, MakeStringLiteral("breakpoint"))) - { - // NOTE(Peter): This is not a temporary breakpoint. It is - // used to be able to break the meta program at specific points - // throughout execution - __debugbreak(); - } - } - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -internal b32 -ParseSignedness (token_iter* Iter) -{ - // NOTE(Peter): This doesn't really do much at the moment, but - // I want all signedness parsing to happen in one place in case - // we ever need to do anything with it. - - b32 Result = false; - - if (TokenAtEquals(Iter, "unsigned") || - TokenAtEquals(Iter, "signed")) - { - Result = true; - } - - return Result; -} - -internal b32 -ShortInt (token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - ParseSignedness(Iter); - if (TokenAtEquals(Iter, "short")) - { - Result = true; - if (TokenAtEquals(Iter, "int")) - { - Result = true; - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - if (Result) - { - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("short int"), TypeTable); - } - return Result; -} - -internal b32 -Int (token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - ParseSignedness(Iter); - if (TokenAtEquals(Iter, "int")) - { - Result = true; - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - if (Result) - { - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("int"), TypeTable); - } - return Result; -} - -internal b32 -LongInt (token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - ParseSignedness(Iter); - if (TokenAtEquals(Iter, "long")) - { - Result = true; - if (TokenAtEquals(Iter, "int")) - { - Result = true; - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - if (Result) - { - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("long int"), TypeTable); - } - return Result; -} - -internal b32 -LongLongInt (token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - ParseSignedness(Iter); - if (TokenAtEquals(Iter, "long")) - { - if (TokenAtEquals(Iter, "long")) - { - Result = true; - if (TokenAtEquals(Iter, "int")) - { - Result = true; - } - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - if (Result) - { - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("long long int"), TypeTable); - } - return Result; -} - -internal b32 -ParseChar(token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - ParseSignedness(Iter); - if (TokenAtEquals(Iter, "char")) - { - Result = true; - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("char"), TypeTable); - } - else if (TokenAtEquals(Iter, "wchar_t")) - { - Result = true; - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("wchar_t"), TypeTable); - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - return Result; -} - -internal b32 -ParseBool(token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "bool")) - { - Result = true; - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("bool"), TypeTable); - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - return Result; -} - -internal b32 -ParseFloat(token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "float")) - { - Result = true; - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("float"), TypeTable); - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - return Result; -} - -internal b32 -ParseDouble(token_iter* Iter, type_table_handle* TypeHandleOut, type_table TypeTable) -{ - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "double")) - { - Result = true; - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("double"), TypeTable); - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - return Result; -} - -// :UndeclaredType -// NOTE(Peter): If TypeIndexOut is -1, you need to call NextToken after this -// function to advance past the type identifier. -internal b32 -ParseType(token_iter* Iter, gs_meta_preprocessor* Meta, type_table_handle* TypeHandleOut) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseType")); - b32 Result = false; - *TypeHandleOut = InvalidTypeTableHandle; - PushSnapshot(Iter); - - if (ParseChar(Iter, TypeHandleOut, Meta->TypeTable) || - ParseBool(Iter, TypeHandleOut, Meta->TypeTable) || - LongLongInt(Iter, TypeHandleOut, Meta->TypeTable) || - LongInt(Iter, TypeHandleOut, Meta->TypeTable) || - ShortInt(Iter, TypeHandleOut, Meta->TypeTable) || - Int(Iter, TypeHandleOut, Meta->TypeTable) || - ParseFloat(Iter, TypeHandleOut, Meta->TypeTable) || - ParseDouble(Iter, TypeHandleOut, Meta->TypeTable)) - { - Result = true; - } - else if (StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("void"))) - { - NextToken(Iter); - Result = true; - *TypeHandleOut = GetTypeHandle(MakeStringLiteral("void"), Meta->TypeTable); - } - else - { - gsm_profiler_scope* ProfileInnerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseTypeInner")); - - *TypeHandleOut = GetTypeHandle(Iter->TokenAt->Text, Meta->TypeTable); - if (TypeHandleIsValid(*TypeHandleOut)) - { - Result = true; - NextToken(Iter); - } - else if(Iter->TokenAt->Type == Token_Identifier) - { - Result = true; - // NOTE(Peter): In this case, we believe we are at a type identifier, - // however, it hasn't been declared yet. This is due to the fact that we - // tokenize files, then parse them, then import the files they include, and - // then begin tokenizing, parsing, etc for those files. - // In the case that we get an as-of-yet undeclared type, we leave it - // up to the calling site to determine what to do with that information - // :UndeclaredType - *TypeHandleOut = InvalidTypeTableHandle; - } - - EndScope(ProfileInnerScope); - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -internal b32 -ParsePointer (token_iter* Iter) -{ - b32 Result = false; - if (TokenAtEquals(Iter, "*")) - { - Result = true; - } - return Result; -} - -internal b32 -ParseConstVolatile (token_iter* Iter) -{ - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "volatile") || - TokenAtEquals(Iter, "const")) - { - Result = true; - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - return Result; -} - -internal b32 -ParseVariableDecl(token_iter* Iter, gs_bucket* VariableList, gs_meta_preprocessor* Meta) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseVariableDecl")); - b32 Result = false; - PushSnapshot(Iter); - - if (ParseConstVolatile(Iter)) - { - // NOTE(Peter): we don't do anything with this atm - // dont have a reason to just yet - // :UnusedConstVolatile - } - - type_table_handle TypeHandle = InvalidTypeTableHandle; - if (ParseType(Iter, Meta, &TypeHandle)) - { - // :UndeclaredType - if (!TypeHandleIsValid(TypeHandle)) - { - TypeHandle = PushUndeclaredType(Iter->TokenAt->Text, &Meta->TypeTable); - NextToken(Iter); - } - - b32 IsPointer = ParsePointer(Iter); - - if (ParseConstVolatile(Iter)) - { - // :UnusedConstVolatile - } - - for(;;) { - token IdentifierToken = {}; - if (TokenAtEquals(Iter, Token_Identifier, &IdentifierToken)) - { - // Array Notationg ie r32 x[2]; - // NOTE(Peter): True initially because if there is no array notation, we - // are still ok to proceed - b32 ArrayParseSuccess = true; - u32 ArrayCount = 0; - if (TokenAtEquals(Iter, "[")) - { - // NOTE(Peter): Once we get to this point, we have to complete the entire - // array notation before we have successfully parsed, hence setting - // ArrayParseSucces to false here. - ArrayParseSuccess = false; - token NumberToken = {}; - if (TokenAtEquals(Iter, Token_Number, &NumberToken)) - { - parse_result ParseArrayCount = ParseUnsignedInt(StringExpand(NumberToken.Text)); - ArrayCount = ParseArrayCount.UnsignedIntValue; - } - else - { - // TODO(Peter): Actually handle const expr for arrays - while (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("]"))) - { - NextToken(Iter); - } - } - - if (TokenAtEquals(Iter, "]")) - { - ArrayParseSuccess = true; - } - } - - if (ArrayParseSuccess) - { - Result = true; - - variable_decl* Decl = VariableList->TakeElement(); - *Decl = {}; - Decl->Identifier = IdentifierToken.Text; - Decl->TypeHandle = TypeHandle; - Decl->Pointer = IsPointer; - Decl->ArrayCount = ArrayCount; - CopyMetaTagsAndClear(&Meta->TagList, &Decl->MetaTags); - } - } - - if (StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(","))) - { - // NOTE(Peter): There are two ways we enter this case - // 1. We are parsing a declaration list ie. r32 x, y, z; - // 2. We are parsing a function parameter list ie void proc(r32 x, u32 y) - // In this instance, we could still be parsing a declaration list - // ie. this is valid: void proc(r32 x, y, double z) - - // This first snapshot is so we can rewind to before the comma in the event that - // we are parsing a function parameter list - PushSnapshot(Iter); - NextToken(Iter); - - // This second snapshot is so we can rewind to just _after_ the comma - // and continue parsing in the event that we are in a declaration list - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, Token_Identifier) && - (TokenAtEquals(Iter, ",") || TokenAtEquals(Iter, ";"))) - { - // We are in a declaration list (case 1) - ApplySnapshotIfNotParsedAndPop(false, Iter); - PopSnapshot(Iter); // We don't need the first snapshot in this case - } - else - { - // We are in a function parameter list (case 2) - ApplySnapshotIfNotParsedAndPop(false, Iter); - ApplySnapshotIfNotParsedAndPop(false, Iter); - break; - } - } - else - { - break; - } - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -internal b32 -StructOrUnion(token_iter* Iter, type_definition_type* Type) -{ - b32 Result = false; - if (TokenAtEquals(Iter, "struct")) - { - Result = true; - *Type = TypeDef_Struct; - } - else if (TokenAtEquals(Iter, "union")) - { - Result = true; - *Type = TypeDef_Union; - } - return Result; -} - -// NOTE(Peter): ContainingStruct will be 0 in all cases except when the struct or union -// is anonymous. In those cases, it MUST be the struct or union -// containing the anonymous struct/union -internal b32 -ParseStruct(token_iter* Iter, type_table_handle* StructTypeHandleOut, gs_meta_preprocessor* Meta, type_definition* ContainingStruct = 0) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseStruct")); - b32 Result = false; - *StructTypeHandleOut = InvalidTypeTableHandle; - - PushSnapshot(Iter); - - type_definition_type DeclType; - if (StructOrUnion(Iter, &DeclType)) - { - token IdentifierToken = {}; - if (TokenAtEquals(Iter, Token_Identifier, &IdentifierToken)) {} - - // TODO(Peter): Handle name coming after the struct - if (TokenAtEquals(Iter, "{")) - { - type_definition StructDecl = {}; - if (IdentifierToken.Text.Length > 0) - { - StructDecl.Identifier = IdentifierToken.Text; - StructDecl.Struct.IsAnonymous = false; - } - else - { - Assert(ContainingStruct); - Assert(ContainingStruct->Identifier.Length > 0); - // NOTE(Peter): I'm not sure this is neccessary, but I don't know what - // cases that its not true would be so I'm asserting just to find out - Assert(ContainingStruct->Type == TypeDef_Union || - ContainingStruct->Type == TypeDef_Struct); - - string AnonStructIdentifier = {}; - AnonStructIdentifier.Max = 256; - AnonStructIdentifier.Memory = (char*)malloc(sizeof(char) * AnonStructIdentifier.Max); - - PrintF(&AnonStructIdentifier, "%S_%d", ContainingStruct->Identifier, ContainingStruct->Struct.MemberDecls.Used); - - StructDecl.Identifier = AnonStructIdentifier; - StructDecl.Struct.IsAnonymous = true; - } - - StructDecl.Type = DeclType; - CopyMetaTagsAndClear(&Meta->TagList, &StructDecl.MetaTags); - - while (!TokenAtEquals(Iter, "}")) - { - type_table_handle MemberStructTypeHandle = InvalidTypeTableHandle; - variable_decl MemberDecl = {}; - if (ParseMetaTag(Iter, Meta)) - { - - } - else if (ParseVariableDecl(Iter, &StructDecl.Struct.MemberDecls, Meta)) - { - if (!TokenAtEquals(Iter, ";")) - { - PushFError(Iter->Errors, "No semicolon after struct member variable declaration. %S", StructDecl.Identifier); - } - } - else if (ParseStruct(Iter, &MemberStructTypeHandle, Meta, &StructDecl)) - { - // NOTE(Peter): Pretty sure, since we just parsed the struct, that - // MemberStructTypeIndex should never be Invalid (unknown type). - // Putting this Assert here for now, but remove if there's a valid - // reason that you might not be able to find a struct just parsed at - // this point. - Assert(TypeHandleIsValid(MemberStructTypeHandle)); - - MemberDecl.TypeHandle = MemberStructTypeHandle; - StructDecl.Struct.MemberDecls.PushElementOnBucket(MemberDecl); - } - else - { - // NOTE(Peter): One of the things that falls through here is - // cpp template stuff. Eventually, we should be able to use - // this meta layer to get rid of them all together, and then - // we can just disallow CPP templates - NextToken(Iter); - } - } - - if (TokenAtEquals(Iter, ";")) - { - Result = true; - *StructTypeHandleOut = PushTypeDefOnTypeTable(StructDecl, &Meta->TypeTable); - } - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -// ( type *? identifier, ... ) -internal b32 -ParseFunctionParameterList (token_iter* Iter, type_definition* FunctionPtrDecl, gs_meta_preprocessor* Meta) -{ - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "(")) - { - Result = true; - - while(!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(")"))) - { - if (ParseVariableDecl(Iter, &FunctionPtrDecl->FunctionPtr.Parameters, Meta)) - { - if (TokenAtEquals(Iter, Token_Comma)) - { - } - else if (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(")"))) - { - Result = false; - break; - } - } - } - - if (TokenAtEquals(Iter, ")")) - { - Result = true; - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - return Result; -} - -internal b32 -ParseFunctionDeclaration (token_iter* Iter, token* Identifier, gs_meta_preprocessor* Meta) -{ - b32 Result = false; - PushSnapshot(Iter); - - type_table_handle ReturnTypeHandle = InvalidTypeTableHandle; - if (ParseType(Iter, Meta, &ReturnTypeHandle)) - { - if (!TypeHandleIsValid(ReturnTypeHandle)) - { - ReturnTypeHandle = PushUndeclaredType(Iter->TokenAt->Text, &Meta->TypeTable); - NextToken(Iter); - } - - b32 IsPointer = ParsePointer(Iter); - - if (TokenAtEquals(Iter, Token_Identifier, Identifier)) - { - type_definition FunctionPtr = {}; - FunctionPtr.Identifier = Identifier->Text; - FunctionPtr.Size = sizeof(void*); - CopyMetaTagsAndClear(&Meta->TagList, &FunctionPtr.MetaTags); - FunctionPtr.Type = TypeDef_FunctionPointer; - FunctionPtr.Pointer = true; - FunctionPtr.FunctionPtr = {}; - FunctionPtr.FunctionPtr.ReturnTypeHandle = ReturnTypeHandle; - - if (ParseFunctionParameterList(Iter, &FunctionPtr, Meta)) - { - if (TokenAtEquals(Iter, ";")) - { - Result = true; - PushTypeDefOnTypeTable(FunctionPtr, &Meta->TypeTable); - } - } - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - if (!Result) - { - *Identifier = {0}; - } - return Result; -} - -internal b32 -ParseTypedef(token_iter* Iter, gs_meta_preprocessor* Meta) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseTypedef")); - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "typedef")) - { - token TypeToken = {0}; - type_table_handle TypeHandle = InvalidTypeTableHandle; - if (TokenAtEquals(Iter, "struct") && - ParseStruct(Iter, &TypeHandle, Meta)) - { - Result = true; - } - else if (ParseFunctionDeclaration(Iter, &TypeToken, Meta)) - { - Result = true; - } - else if (ParseType(Iter, Meta, &TypeHandle)) - { - if (!TypeHandleIsValid(TypeHandle)) - { - TypeHandle = PushUndeclaredType(Iter->TokenAt->Text, &Meta->TypeTable); - NextToken(Iter); - } - - b32 IsPointer = ParsePointer(Iter); - - type_definition* BasisType = GetTypeDefinition(TypeHandle, Meta->TypeTable); - - type_definition NewType = {}; - NewType.Size = BasisType->Size; - CopyMetaTagsAndClear(&Meta->TagList, &NewType.MetaTags); - NewType.Type = BasisType->Type; - if (NewType.Type == TypeDef_Struct || - NewType.Type == TypeDef_Union) - { - NewType.Struct = BasisType->Struct; - } - NewType.Pointer = BasisType->Pointer || IsPointer; - - token IdentifierToken = {}; - if (TokenAtEquals(Iter, Token_Identifier, &IdentifierToken)) - { - NewType.Identifier = IdentifierToken.Text; - PushTypeDefOnTypeTable(NewType, &Meta->TypeTable); - Result = true; - } - } - else - { - string* Error = TakeError(Iter->Errors); - PrintF(Error, "unhandled typedef "); - while (!TokenAtEquals(Iter, ";")) - { - PrintF(Error, "%S ", Iter->TokenAt->Text); - NextToken(Iter); - } - PrintF(Error, "\n"); - } - } - - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -internal b32 -ParseEnum (token_iter* Iter, gs_meta_preprocessor* Meta) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseEnum")); - b32 Result = false; - PushSnapshot(Iter); - - if (TokenAtEquals(Iter, "enum")) - { - token IdentifierToken = {}; - if (TokenAtEquals(Iter, Token_Identifier, &IdentifierToken)) - { - type_definition EnumDecl = {}; - EnumDecl.Identifier = IdentifierToken.Text; - EnumDecl.Size = sizeof(u32); - CopyMetaTagsAndClear(&Meta->TagList, &EnumDecl.MetaTags); - EnumDecl.Type = TypeDef_Enum; - - if (TokenAtEquals(Iter, "{")) - { - u32 EnumAcc = 0; - - while (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}"))) - { - token EnumIdentifierToken = {}; - if (TokenAtEquals(Iter, Token_Identifier, &EnumIdentifierToken)) - { - if (TokenAtEquals(Iter, "=")) - { - // TODO(Peter): TempValue is just here until we handle all - // const expr that could define an enum value. Its there so - // that if the first token of an expression is a number, - // we can avoid using anything from the expression. - u32 TempValue = EnumAcc; - token NumberToken = {}; - if (TokenAtEquals(Iter, Token_Number, &NumberToken)) - { - parse_result ParsedExpr = ParseSignedInt(StringExpand(NumberToken.Text)); - TempValue = ParsedExpr.SignedIntValue; - } - - // TODO(Peter): Handle setting enums equal to other kinds - // of const exprs. - // We're skipping a whole bunch of stuff now - while (!(StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(",")) || - StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}")))) - { - TempValue = EnumAcc; - NextToken(Iter); - } - - EnumAcc = TempValue; - } - - s32 EnumValue = EnumAcc++; - if (TokenAtEquals(Iter, ",") || - StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}"))) - { - EnumDecl.Enum.Identifiers.PushElementOnBucket(EnumIdentifierToken.Text); - EnumDecl.Enum.Values.PushElementOnBucket(EnumValue); - } - else if (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}"))) - { - Result = false; - break; - } - } - } - - if (TokenAtEquals(Iter, "}") && - TokenAtEquals(Iter, ";")) - { - PushTypeDefOnTypeTable(EnumDecl, &Meta->TypeTable); - Result = true; - } - } - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -internal b32 -ParseFunction (token_iter* Iter, gs_meta_preprocessor* Meta) -{ - gsm_profiler_scope* ProfilerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseFunction")); - b32 Result = false; - PushSnapshot(Iter); - - type_table_handle ReturnTypeHandle = InvalidTypeTableHandle; - if (ParseType(Iter, Meta, &ReturnTypeHandle)) - { - token IdentifierToken = {}; - if (TokenAtEquals(Iter, Token_Identifier, &IdentifierToken) && - TokenAtEquals(Iter, "(")) - { - gsm_profiler_scope* ProfilerInnerScope = BeginScope(&Meta->Profiler, - MakeStringLiteral("parse"), - MakeStringLiteral("ParseFunctionInner")); - type_definition FunctionDecl = {}; - FunctionDecl.Identifier = IdentifierToken.Text; - FunctionDecl.Function.ReturnTypeHandle = ReturnTypeHandle; - CopyMetaTagsAndClear(&Meta->TagList, &FunctionDecl.MetaTags); - FunctionDecl.Type = TypeDef_Function; - FunctionDecl.Function.Parameters = {}; - - while (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(")"))) - { - if (ParseVariableDecl(Iter, &FunctionDecl.Function.Parameters, Meta)) - { - - } - - if(!TokenAtEquals(Iter, ",")) - { - break; - } - } - - if (TokenAtEquals(Iter, ")")) - { - Result = true; - PushTypeDefOnTypeTable(FunctionDecl, &Meta->TypeTable); - } - EndScope(ProfilerInnerScope); - } - } - - ApplySnapshotIfNotParsedAndPop(Result, Iter); - EndScope(ProfilerScope); - return Result; -} - -internal void -PrintIndent (u32 Indent) -{ - for (u32 i = 0; i < Indent; i++) - { - printf(" "); - } -} - -internal void PrintStructDecl (type_definition* StructDecl, type_table TypeTable, u32 Indent); - -internal void -PrintVariableDecl (variable_decl Member, type_table TypeTable, u32 Indent = 0) -{ - type_definition* MemberTypeDef = GetTypeDefinition(Member.TypeHandle, TypeTable); - if ((MemberTypeDef->Type == TypeDef_Struct || MemberTypeDef->Type == TypeDef_Union) - && MemberTypeDef->Identifier.Length == 0) - { - PrintStructDecl(MemberTypeDef, TypeTable, Indent); - } - else - { - PrintIndent(Indent); - if (!TypeHandleIsValid(Member.TypeHandle)) - { - printf("???? "); - } - printf("%.*s ", StringExpand(MemberTypeDef->Identifier)); - } - - if (Member.Pointer) - { - printf("* "); - } - - printf("%.*s", StringExpand(Member.Identifier)); - - if (Member.ArrayCount > 0) - { - printf("[%d]", Member.ArrayCount); - } -} - -internal void -PrintStructDecl (type_definition* StructDecl, type_table TypeTable, u32 Indent = 0) -{ - Assert(StructDecl->Type == TypeDef_Struct || - StructDecl->Type == TypeDef_Union); - - PrintIndent(Indent); - if (StructDecl->Type == TypeDef_Struct) - { - printf("struct "); - } - else if (StructDecl->Type == TypeDef_Union) - { - printf("union "); - } - else { InvalidCodePath; } - - if (StructDecl->Identifier.Length > 0) - { - printf("%.*s ", StringExpand(StructDecl->Identifier)); - } - printf("{\n"); - - for (u32 MemberIndex = 0; MemberIndex < StructDecl->Struct.MemberDecls.Used; MemberIndex++) - { - variable_decl* Member = StructDecl->Struct.MemberDecls.GetElementAtIndex(MemberIndex); - PrintVariableDecl(*Member, TypeTable, Indent + 1); - printf(";\n"); - } - PrintIndent(Indent); - printf("} ( size = %d ) ", StructDecl->Size); -} - -internal void -PrintFunctionPtrDecl (type_definition* FnPtrDecl, type_table TypeTable) -{ - type_definition* ReturnType = GetTypeDefinition(FnPtrDecl->FunctionPtr.ReturnTypeHandle, TypeTable); - printf("%.*s ", StringExpand(ReturnType->Identifier)); - - if (FnPtrDecl->Identifier.Length > 0) - { - printf("%.*s ", StringExpand(FnPtrDecl->Identifier)); - } - printf("("); - - for (u32 MemberIndex = 0; MemberIndex < FnPtrDecl->FunctionPtr.Parameters.Used; MemberIndex++) - { - variable_decl* Param = FnPtrDecl->FunctionPtr.Parameters.GetElementAtIndex(MemberIndex); - PrintVariableDecl(*Param, TypeTable, 0); - printf(", "); - } - - printf(");"); -} - -internal gs_meta_preprocessor -PreprocessProgram (char* SourceFile) -{ - gs_meta_preprocessor Meta = {}; - - gsm_profiler_scope* TotalScope = BeginScope(&Meta.Profiler, "total", "total"); - - Meta.PreprocessorStartTime = GetWallClock(); - - PopulateTableWithDefaultCPPTypes(&Meta.TypeTable); - - string CurrentWorkingDirectory = MakeString((char*)malloc(1024), 0, 1024); - - string RootFile = MakeString(SourceFile); - AddFileToSource(RootFile, {}, &Meta.SourceFiles, &Meta.Errors); - - s32 LastSlash = ReverseSearchForCharInSet(RootFile, "\\/"); - if (LastSlash <= 0) - { - PushFError(&Meta.Errors, "%S: File path invalid.", RootFile); - return Meta; - } - - string RootPath = Substring(RootFile, 0, LastSlash + 1); - CopyStringTo(RootPath, &CurrentWorkingDirectory); - - for (u32 SourceFileIdx = 0; SourceFileIdx < Meta.SourceFiles.Used; SourceFileIdx++) - { - source_code_file* File = Meta.SourceFiles.GetElementAtIndex(SourceFileIdx); - - gsm_profiler_scope* FileScope = BeginScope(&Meta.Profiler, - MakeStringLiteral("file"), - File->Path); - - gsm_profiler_scope* TokenizeScope = BeginScope(&Meta.Profiler, - MakeStringLiteral("tokenize"), - File->Path); - TokenizeFile(File, &Meta.Tokens); - EndScope(TokenizeScope); - - gsm_profiler_scope* PreprocScope = BeginScope(&Meta.Profiler, - MakeStringLiteral("preproc"), - File->Path); - token_iter Iter = {}; - Iter.Tokens = &Meta.Tokens; - Iter.FirstToken = File->FirstTokenIndex; - Iter.LastToken = File->LastTokenIndex; - Iter.TokenAtIndex = Iter.FirstToken; - Iter.TokenAt = Meta.Tokens.GetElementAtIndex(Iter.TokenAtIndex); - Iter.Errors = &Meta.Errors; - - while (Iter.TokenAtIndex < Iter.LastToken) - { - b32 ParseSuccess = false; - - type_table_handle TypeHandle = InvalidTypeTableHandle; - if (TokenAtEquals(&Iter, "#include")) - { - token* IncludeFile = Iter.TokenAt; - - // NOTE(Peter): For now we aren't going in and preprocessing the header files - // we include from the system - // Token_Operator is used to check if the include is of the form '#include ' - // and skip it. - // TODO(Peter): This is only a rough approximation of ignoring system headers - // TODO(Peter): We should actually see what parsing system headers would entail - if (IncludeFile->Type != Token_Operator) - { - string TempFilePath = IncludeFile->Text; - gsm_profiler_scope* IncludeScope = BeginScope(&Meta.Profiler, - MakeStringLiteral("include"), - TempFilePath); - - // NOTE(Peter): if the path is NOT absolute ie "C:\etc - if (!(IsAlpha(TempFilePath.Memory[0]) && - TempFilePath.Memory[1] == ':' && - TempFilePath.Memory[2] == '\\')) - { - TempFilePath = CurrentWorkingDirectory; - ConcatString(IncludeFile->Text, &TempFilePath); - NullTerminate(&TempFilePath); - } - - ParseSuccess = true; - if (!FileAlreadyInSource(TempFilePath, Meta.SourceFiles)) - { - AddFileToSource(TempFilePath, *File, &Meta.SourceFiles, &Meta.Errors); - } - EndScope(IncludeScope); - } - } - else if(ParseMetaTag(&Iter, &Meta)) - { - ParseSuccess = true; - } - else if (ParseEnum(&Iter, &Meta)) - { - ParseSuccess = true; - } - else if (ParseStruct(&Iter, &TypeHandle, &Meta)) - { - ParseSuccess = true; - } - else if (ParseTypedef(&Iter, &Meta)) - { - ParseSuccess = true; - } - else if (ParseFunction(&Iter, &Meta)) - { - ParseSuccess = true; - } - - if (!ParseSuccess) - { - NextToken(&Iter); - } - } - EndScope(PreprocScope); - EndScope(FileScope); - } - - // Type Table Fixup - gsm_profiler_scope* FixupScope = BeginScope(&Meta.Profiler, "fixup", "fixup"); - - for (u32 b = 0; b < Meta.TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = Meta.TypeTable.Types[b]; - for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++) - { - if (Bucket.Keys[i] > 0) - { - type_table_handle Handle = {}; - Handle.BucketIndex = b; - Handle.IndexInBucket = i; - - type_definition* TypeDef = GetTypeDefinitionUnsafe(Handle, Meta.TypeTable); - if (TypeDef) - { - if (TypeDef->Type == TypeDef_Struct) - { - FixUpStructSize(Handle, Meta.TypeTable, &Meta.Errors); - } - else if (TypeDef->Type == TypeDef_Union) - { - FixUpUnionSize(Handle, Meta.TypeTable, &Meta.Errors); - } - } - } - } - } - - EndScope(FixupScope); - EndScope(TotalScope); - return Meta; -} - -internal void -FinishMetaprogram(gs_meta_preprocessor* Meta) -{ - FinishProfiler(&Meta->Profiler); - - PrintAllErrors(Meta->Errors); - printf("\nMetaprogram Performance:\n"); - - PrintAllCategories(&Meta->Profiler); - printf("\n"); -} - -#define GS_META_CPP -#endif // GS_META_CPP \ No newline at end of file diff --git a/src/meta/gs_meta_code_generator.h b/src/meta/gs_meta_code_generator.h deleted file mode 100644 index ba431ad..0000000 --- a/src/meta/gs_meta_code_generator.h +++ /dev/null @@ -1,100 +0,0 @@ -// -// File: gs_meta_code_generator.h -// Author: Peter Slattery -// Creation Date: 2020-01-20 -// -#ifndef GS_META_CODE_GENERATOR_H - -#include "../gs_libs/gs_string.h" -#include "../gs_libs/gs_string_builder.h" - -enum gsm_code_gen_type -{ - gsm_CodeGen_Enum, - gsm_CodeGen_Count, -}; - -struct gsm_enum_generator -{ - string Identifier; - string Prefix; - b32 EndsWithCount; -}; - -struct gsm_code_generator -{ - gsm_code_gen_type Type; - string_builder* Builder; - - union - { - gsm_enum_generator Enum; - }; -}; - -// --------------- -// Enum -// --------------- - -internal gsm_code_generator -BeginEnumGeneration(string EnumIdentifier, string ValuePrefix, b32 StartsWithInvalid, b32 EndsWithCount) -{ - gsm_code_generator Gen = {}; - - // TODO(Peter): TEMP!! - Gen.Builder = (string_builder*)malloc(sizeof(string_builder)); - *Gen.Builder = {}; - - Gen.Type = gsm_CodeGen_Enum; - Gen.Enum.Identifier = EnumIdentifier; - Gen.Enum.Prefix = ValuePrefix; - Gen.Enum.EndsWithCount = EndsWithCount; - - WriteF(Gen.Builder, "enum %S\n{\n", EnumIdentifier); - if (StartsWithInvalid) - { - WriteF(Gen.Builder, " %S_Invalid,\n", ValuePrefix); - } - - return Gen; -} - -internal gsm_code_generator -BeginEnumGeneration(char* EnumIdentifier, char* ValuePrefix, b32 StartsWithInvalid, b32 EndsWithCount) -{ - return BeginEnumGeneration(MakeStringLiteral(EnumIdentifier), - MakeStringLiteral(ValuePrefix), - StartsWithInvalid, - EndsWithCount); -} - -internal void -AddEnumElement(gsm_code_generator* Gen, string ElementIdentifier) -{ - // TODO(Peter): Support const expr defining enum values - Assert(Gen->Type == gsm_CodeGen_Enum); - WriteF(Gen->Builder, " %S_%S,\n", Gen->Enum.Prefix, ElementIdentifier); -} - -internal void -AddEnumElement(gsm_code_generator* Gen, char* ElementIdentifier) -{ - AddEnumElement(Gen, MakeStringLiteral(ElementIdentifier)); -} - -internal void -FinishEnumGeneration(gsm_code_generator* Gen) -{ - Assert(Gen->Type == gsm_CodeGen_Enum); - - if (Gen->Enum.EndsWithCount) - { - WriteF(Gen->Builder, " %S_Count,\n", Gen->Enum.Prefix); - } - - WriteF(Gen->Builder, "};\n\n"); -} - - -#define GS_META_CODE_GENERATOR_H -#endif // GS_META_CODE_GENERATOR_H \ No newline at end of file diff --git a/src/meta/gs_meta_error.h b/src/meta/gs_meta_error.h deleted file mode 100644 index f4f1c68..0000000 --- a/src/meta/gs_meta_error.h +++ /dev/null @@ -1,87 +0,0 @@ - -struct error_buffer -{ - char* Backbuffer; - string* Contents; -}; - -#define ERROR_MAX_LENGTH 256 -#define ERROR_BUFFER_SIZE 256 -struct errors -{ - error_buffer* Buffers; - u32 BuffersCount; - u32 Used; -}; - -#define ErrorReallocArray(base, type, oldcount, newcount) (type*)ErrorRealloc_((u8*)(base), (u64)(sizeof(type) * oldcount), (u64)(sizeof(type) * newcount)) -internal u8* -ErrorRealloc_(u8* Base, u64 OldSize, u64 NewSize) -{ - Assert(NewSize > 0); - u8* Result = (u8*)malloc(NewSize); - if (Base != 0 && OldSize > 0) - { - GSMemCopy(Base, Result, OldSize); - free(Base); - } - return Result; -} - -internal void -PushFError (errors* Errors, char* Format, ...) -{ - if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE)) - { -#if 0 - Errors->BuffersCount += 1; - Errors->Buffers = (error_buffer*)realloc(Errors->Buffers, sizeof(error_buffer*) * Errors->BuffersCount); -#else - Errors->Buffers = ErrorReallocArray(Errors->Buffers, error_buffer, Errors->BuffersCount, Errors->BuffersCount + 1); - Errors->BuffersCount += 1; -#endif - - error_buffer* NewBuffer = Errors->Buffers + (Errors->BuffersCount - 1); - NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE); - NewBuffer->Contents = (string*)malloc(sizeof(string) * ERROR_BUFFER_SIZE); - - for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++) - { - NewBuffer->Contents[i].Str = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH); - NewBuffer->Contents[i].Size = ERROR_MAX_LENGTH; - NewBuffer->Contents[i].Length = 0; - } - } - - u32 NewErrorIndex = Errors->Used++; - u32 BufferIndex = NewErrorIndex / ERROR_BUFFER_SIZE; - u32 IndexInBuffer = NewErrorIndex % ERROR_BUFFER_SIZE; - string* NewError = Errors->Buffers[BufferIndex].Contents + IndexInBuffer; - - va_list Args; - va_start(Args, Format); - NewError->Length = PrintFArgsList(NewError->Memory, NewError->Max, Format, Args); - va_end(Args); -} - -internal string* -TakeError (errors* Errors) -{ - u32 NewErrorIndex = Errors->Used++; - u32 BufferIndex = NewErrorIndex / ERROR_BUFFER_SIZE; - u32 IndexInBuffer = NewErrorIndex % ERROR_BUFFER_SIZE; - string* NewError = Errors->Buffers[BufferIndex].Contents + IndexInBuffer; - return NewError; -} - -internal void -PrintAllErrors (errors Errors) -{ - for (u32 i = 0; i < Errors.Used; i++) - { - u32 BufferIndex = i / ERROR_BUFFER_SIZE; - u32 IndexInBuffer = i % ERROR_BUFFER_SIZE; - string Error = Errors.Buffers[BufferIndex].Contents[IndexInBuffer]; - printf("%.*s\n", StringExpand(Error)); - } -} diff --git a/src/meta/gs_meta_include.cpp b/src/meta/gs_meta_include.cpp deleted file mode 100644 index 315af25..0000000 --- a/src/meta/gs_meta_include.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// -// File: gs_meta_include.cpp -// Author: Peter Slattery -// Creation Date: 2020-02-22 -// -#ifndef GS_META_INCLUDE_CPP - -static gsm_s32 -gsm_GetMetaTagIndex(gsm_s32 Needle, gsm_meta_tag_type* Tags, gsm_u32 TagCount) -{ - gsm_s32 Result = -1; - for (gsm_u32 i = 0; i < TagCount; i++) - { - if (Needle == Tags[i]) - { - Result = (gsm_s32)i; - break; - } - } - return Result; -} - - - -#define GS_META_INCLUDE_CPP -#endif // GS_META_INCLUDE_CPP \ No newline at end of file diff --git a/src/meta/gs_meta_include.h b/src/meta/gs_meta_include.h deleted file mode 100644 index ef1f5c6..0000000 --- a/src/meta/gs_meta_include.h +++ /dev/null @@ -1,87 +0,0 @@ -// -// File: foldhaus_meta_include.h -// Author: Peter Slattery -// Creation Date: 2020-01-19 -// -#ifndef FOLDHAUS_META_INCLUDE_H - -// -// NOTE -// Include this file FIRST in any application utilizing the Foldhaus Meta system -// Include the generated files you wish to take advantage of at convenient locations -// in your application -// - -typedef int gsm_s32; -typedef unsigned int gsm_u32; -typedef unsigned long long int gsm_u64; -typedef enum gsm_meta_tag_type gsm_meta_tag_type; -typedef enum gsm_struct_type gsm_struct_type; - -#define GSMetaTag(ident, ...) - -struct gsm_meta_tag -{ - char* Tag; - gsm_u32 TagLength; -}; - -struct gsm_struct_member_type_info -{ - char* Identifier; - gsm_u32 IdentifierLength; - gsm_u64 Offset; - - // NOTE(Peter): There's no reason that this is 5 other than that its more tags - // than I need at the moment of writing. It does need to be a static array size - // because theres no way to statically initialize a pointer to an array - gsm_meta_tag_type Tags[5]; - gsm_u32 TagsCount; -}; - -struct gsm_struct_type_info -{ - gsm_u32 Type; - char* Identifier; - gsm_u32 IdentifierLength; - - gsm_u32 Size; - - gsm_meta_tag* Tags; - gsm_u32 TagsCount; - - gsm_struct_member_type_info* Members; - gsm_u32 MembersCount; -}; - -static bool -gsm_CharArraysEqual(char* A, char* B) -{ - bool Result = true; - - char* AAt = A; - char* BAt = B; - - while (*AAt && *BAt) - { - if (*AAt != *BAt) - { - Result = false; - break; - } - } - - // NOTE(Peter): In case we get to the end of A or B, but not both. - // ie. the strings are equal up to a point, but one is longer. - if (*AAt != *BAt) - { - Result = false; - } - - return Result; -} - -static gsm_s32 gsm_GetMetaTagIndex(gsm_s32 Needle, gsm_meta_tag_type* Tags, gsm_u32 TagsCount); - -#define FOLDHAUS_META_INCLUDE_H -#endif // FOLDHAUS_META_INCLUDE_H \ No newline at end of file diff --git a/src/meta/gs_meta_lexer.h b/src/meta/gs_meta_lexer.h deleted file mode 100644 index 60e6647..0000000 --- a/src/meta/gs_meta_lexer.h +++ /dev/null @@ -1,261 +0,0 @@ -struct token_selection_spec -{ - b32 MatchText; - gs_string Text; -}; - -internal s32 -EatPreprocessor (tokenizer* Tokenizer) -{ - char* TStart = Tokenizer->At; - while (AtValidPosition(*Tokenizer) && !IsNewline(*Tokenizer->At)) - { - if (Tokenizer->At[0] == '\\') - { - EatChar(Tokenizer); - - while (IsWhitespace(*Tokenizer->At)) - { - EatChar(Tokenizer); - } - - if (IsNewline(*Tokenizer->At)) - { - EatPastNewLine(Tokenizer); - } - } - else if (!IsNewline(*Tokenizer->At)) - { - EatChar(Tokenizer); - } - } - - return Tokenizer->At - TStart; -} - -internal s32 -EatString (tokenizer* Tokenizer) -{ - s32 Length = 0; - - while (Tokenizer->At[0] && Tokenizer->At[0] != '"') - { - if (Tokenizer->At[0] == '/') - { - ++Tokenizer->At; - Length++; - } - ++Tokenizer->At; - Length++; - } - - ++Tokenizer->At; - - return Length; -} - -internal s32 -EatIdentifier (tokenizer* Tokenizer) -{ - s32 Length = 0; - - while (Tokenizer->At[0] && - (IsAlpha(Tokenizer->At[0]) || IsNumericExtended(Tokenizer->At[0]))) - { - ++Tokenizer->At; - Length++; - } - - return Length; -} - -internal b32 -TokenAtEquals(tokenizer* Tokenizer, char* Needle) -{ - b32 Result = true; - - char* TokenizerStart = Tokenizer->At; - - char* NeedleAt = Needle; - while (AtValidPosition(*Tokenizer) && *NeedleAt) - { - if (*NeedleAt != *Tokenizer->At) - { - Result = false; - break; - } - NeedleAt++; - EatChar(Tokenizer); - } - - // NOTE(Peter): rewind tokenizer - if (!Result) - { - Tokenizer->At = TokenizerStart; - } - - return Result; -} - -internal token -GetNextToken (tokenizer* Tokenizer) -{ - token Result = {}; - - EatWhitespace(Tokenizer); - - // Don't include comments in tokens - while (Tokenizer->At[0] && Tokenizer->At[0] == '/' && Tokenizer->At[1] && Tokenizer->At[1] == '/') - { - EatToNewLine(Tokenizer); - EatWhitespace(Tokenizer); - } - - while(Tokenizer->At[0] && Tokenizer->At[0] == '/' && Tokenizer->At[1] && Tokenizer->At[1] == '*') - { - Tokenizer->At += 2; - while (*Tokenizer->At) - { - if (Tokenizer->At[0] && Tokenizer->At[0] == '*' && Tokenizer->At[1] && Tokenizer->At[1] == '/') - { - Tokenizer->At += 2; - break; - } - Tokenizer->At++; - } - EatWhitespace(Tokenizer); - } - - Result.Text = MakeString(Tokenizer->At, 1, 1); - - // NOTE(Peter): Adding one because I want the tokenizer to work with clear to zero - // but line numbers generally start at 1, not 0 - Result.LineNumber = Tokenizer->LineNumber + 1; - - char C = Tokenizer->At[0]; - ++Tokenizer->At; - - if (C == 0) { Result.Type = Token_EndOfStream; } - else if (C == '(') { Result.Type = Token_LeftParen; } - else if (C == ')') { Result.Type = Token_RightParen; } - else if (C == '[') { Result.Type = Token_LeftSquareBracket; } - else if (C == ']') { Result.Type = Token_RightSquareBracket; } - else if (C == '{') { Result.Type = Token_LeftCurlyBracket; } - else if (C == '}') { Result.Type = Token_RightCurlyBracket; } - else if (C == ';') { Result.Type = Token_Semicolon; } - else if (C == ',') { Result.Type = Token_Comma; } - else if (C == '.') { Result.Type = Token_Period; } - else if (C == '-' && Tokenizer->At[0] && Tokenizer->At[0] == '>') - { - Result.Type = Token_PointerReference; - Result.Text.Length = 2; - ++Tokenizer->At; - } - else if (C == '#') - { - // NOTE(Peter): Technically correct to do things like "# define" - EatWhitespace(Tokenizer); - - if (TokenAtEquals(Tokenizer, "define")) - { - Result.Type = Token_PoundDefine; - EatPreprocessor(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "undef")) - { - Result.Type = Token_PoundUndef; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "include")) - { - Result.Type = Token_PoundInclude; - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "ifdef")) - { - Result.Type = Token_PoundIfDef; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "ifndef")) - { - Result.Type = Token_PoundIfNDef; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "if")) - { - Result.Type = Token_PoundIf; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "elif")) - { - Result.Type = Token_PoundElif; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "else")) - { - Result.Type = Token_PoundElse; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "endif")) - { - Result.Type = Token_PoundEndif; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "error")) - { - Result.Type = Token_PoundError; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - else if (TokenAtEquals(Tokenizer, "pragma")) - { - Result.Type = Token_PoundPragma; - EatToNewLine(Tokenizer); - Result.Text.Length = Tokenizer->At - Result.Text.Str; - } - } - else if (IsNumericExtended(C)) - { - Result.Type = Token_Number; - - // NOTE(Peter): adding 1 to account for the fact that we've already advanced - // Tokenizer once - Result.Text.Length = 1 + EatNumber(Tokenizer); - } - else if (C == '\'') - { - Result.Type = Token_Char; - Result.Text.Str = Tokenizer->At; - if (Tokenizer->At[0] && Tokenizer->At[0] == '\\') - { - ++Tokenizer->At; - } - ++Tokenizer->At; - ++Tokenizer->At; - } - else if (C == '"') - { - Result.Type = Token_String; - // replace the length added by the quote - Result.Text.Str = Tokenizer->At; - Result.Text.Length = EatString(Tokenizer); - } - // NOTE(Peter): This is after comment parsing so that the division operator - // falls through the comment case - else if (IsOperator(C)) { Result.Type = Token_Operator; } - else - { - Result.Type = Token_Identifier; - Result.Text.Length += EatIdentifier(Tokenizer); - } - - return Result; -} \ No newline at end of file diff --git a/src/meta/gs_meta_type_table.h b/src/meta/gs_meta_type_table.h deleted file mode 100644 index d0d32d9..0000000 --- a/src/meta/gs_meta_type_table.h +++ /dev/null @@ -1,868 +0,0 @@ -// -// File: foldhaus_meta_type_table.h -// Author: Peter Slattery -// Creation Date: 2020-01-17 -// -#ifndef FOLDHAUS_META_TYPE_TABLE_H - -enum type_definition_type -{ - TypeDef_Invalid, - - // NOTE(Peter): tokens with this type require fixup later - TypeDef_Unknown, - TypeDef_Enum, - TypeDef_Struct, - TypeDef_Union, - TypeDef_BasicType, - TypeDef_FunctionPointer, - TypeDef_Function, - - TypeDef_Count, -}; - -char* TypeDefinitionTypeStrings[] = { - "TypeDef_Invalid", - "TypeDef_Unknown", - "TypeDef_Enum", - "TypeDef_Struct", - "TypeDef_Union", - "TypeDef_BasicType", - "TypeDef_FunctionPointer", - "TypeDef_Function", - "TypeDef_Count", -}; - - -#define InvalidTypeTableHandle type_table_handle{0, 0} -struct type_table_handle -{ - s32 BucketIndex; - u32 IndexInBucket; -}; - -// #define TypeHandleIsValid(handle) (!((handle).BucketIndex == 0) && ((handle).IndexInBucket == 0)) -inline b32 TypeHandleIsValid(type_table_handle A) -{ - b32 FirstBucket = (A.BucketIndex == 0); - b32 FirstIndex = (A.IndexInBucket == 0); - b32 Both = FirstBucket && FirstIndex; - return !Both; -} - -#define TypeHandlesEqual(a, b) (((a).BucketIndex == (b).BucketIndex) && ((a).IndexInBucket == (b).IndexInBucket)) - -struct meta_tag -{ - string Identifier; -}; - -struct variable_decl -{ - // NOTE(Peter): Because of the way the tokenizer works, we don't lex and parse - // at the same time. This means that not all types will be able to be matched - // up on the first pass through. A TypeIndex of -1 means we need to fixup that - // type at a later time - type_table_handle TypeHandle; - string Identifier; - b32 Pointer; - - // NOTE(Peter): Zero means its not an array, since you cannot initialize a static - // array to size 0. ie this is invalid: r32 x[0]; and will throw a compiler error - u32 ArrayCount; - - // :SmallAllocationsAllOver - gs_bucket MetaTags; -}; - -struct struct_decl -{ - b32 IsAnonymous; - // TODO(Peter): Lots of tiny arrays everywhere! Pull these into a central allocation - // buffer somewhere - // :SmallAllocationsAllOver - gs_bucket MemberDecls; -}; - -struct function_pointer_decl -{ - type_table_handle ReturnTypeHandle; - // :SmallAllocationsAllOver - gs_bucket Parameters; -}; - -struct function_decl -{ - type_table_handle ReturnTypeHandle; - gs_bucket Parameters; - // TODO(Peter): AST? -}; - -struct enum_decl -{ - gs_bucket Identifiers; - - // TODO(Peter): I suppose there are ways to make an enum a 64 bit number - // for values. Probably need to handle that at some point - gs_bucket Values; -}; - -struct type_definition -{ - string Identifier; - - s32 Size; - gs_bucket MetaTags; - - type_definition_type Type; - union - { - enum_decl Enum; - struct_decl Struct; - function_pointer_decl FunctionPtr; - function_decl Function; - }; - b32 Pointer; -}; - -#define TYPE_TABLE_BUCKET_MAX 1024 -struct type_table_hash_bucket -{ - u32* Keys; - type_definition* Values; -}; - -#define META_TAG_BUCKET_MAX 1024 -struct meta_tag_hash_bucket -{ - u32* Keys; - meta_tag* Values; -}; - -struct type_table -{ - type_table_hash_bucket* Types; - u32 TypeBucketsCount; - - meta_tag_hash_bucket* MetaTags; - u32 MetaTagBucketsCount; -}; - -internal b32 -HandlesAreEqual(type_table_handle A, type_table_handle B) -{ - b32 Result = ((A.BucketIndex == B.BucketIndex) && (A.IndexInBucket == B.IndexInBucket)); - return Result; -} - -internal u32 -HashIdentifier(string Identifier) -{ - u32 IdentHash = HashString(Identifier); - if (IdentHash == 0) - { - // NOTE(Peter): We are excluding a has of zero so taht - // the type_table_handle where BucketIndex and IndexInBucket - // are both zero is an invalid handle - IdentHash += 1; - } - return IdentHash; -} - -internal type_table_handle -GetTypeHandle (string Identifier, type_table TypeTable) -{ - type_table_handle Result = InvalidTypeTableHandle; - - u32 IdentHash = HashIdentifier(Identifier); - u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX; - - for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = TypeTable.Types[b]; - if (Bucket.Keys[Index] == IdentHash) - { - Result.BucketIndex = b; - Result.IndexInBucket = Index; - break; - } - } - - return Result; -} - -internal type_table_handle -GetMetaTagHandle(string Identifier, type_table TypeTable) -{ - type_table_handle Result = InvalidTypeTableHandle; - - u32 IdentHash = HashIdentifier(Identifier); - u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX; - - for (u32 b = 0; b < TypeTable.MetaTagBucketsCount; b++) - { - meta_tag_hash_bucket Bucket = TypeTable.MetaTags[b]; - if (Bucket.Keys[Index] == IdentHash) - { - Result.BucketIndex = b; - Result.IndexInBucket = Index; - break; - } - } - - return Result; -} - -internal type_table_handle -GetMetaTagHandleWithIdentifier(string Identifier, type_table TypeTable) -{ - type_table_handle Result = InvalidTypeTableHandle; - - u32 IdentHash = HashIdentifier(Identifier); - u32 Index = IdentHash % META_TAG_BUCKET_MAX; - for (u32 b = 0; b < TypeTable.MetaTagBucketsCount; b++) - { - meta_tag_hash_bucket* Bucket = TypeTable.MetaTags + b; - if (Bucket->Keys[Index] == IdentHash) - { - Result.BucketIndex = b; - Result.IndexInBucket = Index; - break; - } - } - - return Result; -} - -internal b32 -HasTag(string Needle, gs_bucket Tags, type_table TypeTable) -{ - b32 Result = false; - type_table_handle NeedleTagHandle = GetMetaTagHandleWithIdentifier(Needle, TypeTable); - - if (TypeHandleIsValid(NeedleTagHandle)) - { - for (u32 i = 0; i < Tags.Used; i++) - { - type_table_handle* TagHandle = Tags.GetElementAtIndex(i); - if (HandlesAreEqual(*TagHandle, NeedleTagHandle)) - { - Result = true; - break; - } - } - } - - return Result; -} - -internal void -CopyMetaTagsAndClear(gs_bucket* Source, gs_bucket* Dest) -{ - for (u32 i = 0; i < Source->Used; i++) - { - type_table_handle* TagToken = Source->GetElementAtIndex(i); - Dest->PushElementOnBucket(*TagToken); - } - Source->Used = 0; -} - -internal type_table_handle -FindSlotForTypeIdentifier(u32 IdentHash, type_table* TypeTable) -{ - type_table_handle Result = InvalidTypeTableHandle; - u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX; - - for (u32 b = 0; b < TypeTable->TypeBucketsCount; b++) - { - type_table_hash_bucket* Bucket = TypeTable->Types + b; - if (Bucket->Keys[Index] == 0) - { - Result.BucketIndex = b; - Result.IndexInBucket = Index; - break; - } - } - - if (!TypeHandleIsValid(Result)) - { - // Grow Hash Table - u32 NewTypeBucketIndex = TypeTable->TypeBucketsCount++; - u32 NewTypesSize = TypeTable->TypeBucketsCount * sizeof(type_table_hash_bucket); - TypeTable->Types = (type_table_hash_bucket*)realloc(TypeTable->Types, NewTypesSize); - - type_table_hash_bucket* NewBucket = TypeTable->Types + NewTypeBucketIndex; - NewBucket->Keys = (u32*)malloc(sizeof(u32) * TYPE_TABLE_BUCKET_MAX); - NewBucket->Values = (type_definition*)malloc(sizeof(type_definition) * TYPE_TABLE_BUCKET_MAX); - GSZeroMemory((u8*)NewBucket->Keys, sizeof(u32) * TYPE_TABLE_BUCKET_MAX); - GSZeroMemory((u8*)NewBucket->Values, sizeof(type_definition) * TYPE_TABLE_BUCKET_MAX); - - Result.BucketIndex = NewTypeBucketIndex; - Result.IndexInBucket = Index; - } - - // NOTE(Peter): Because we are growing the hashtable, this should never be an invalid - // type handle - Assert(TypeHandleIsValid(Result)); - return Result; -} - -internal type_table_handle -FindSlotForMetaTag(u32 IdentHash, type_table* TypeTable) -{ - type_table_handle Result = InvalidTypeTableHandle; - u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX; - - for (u32 b = 0; b < TypeTable->MetaTagBucketsCount; b++) - { - meta_tag_hash_bucket* Bucket = TypeTable->MetaTags + b; - if (Bucket->Keys[Index] == 0) - { - Result.BucketIndex = b; - Result.IndexInBucket = Index; - break; - } - } - - if (!TypeHandleIsValid(Result)) - { - u32 NewMetaBucketIndex = TypeTable->MetaTagBucketsCount++; - u32 NewMetaBucketListSize = TypeTable->MetaTagBucketsCount * sizeof(meta_tag_hash_bucket); - TypeTable->MetaTags = (meta_tag_hash_bucket*)realloc(TypeTable->MetaTags, NewMetaBucketListSize); - - meta_tag_hash_bucket* NewBucket = TypeTable->MetaTags + NewMetaBucketIndex; - NewBucket->Keys = (u32*)malloc(sizeof(u32) * TYPE_TABLE_BUCKET_MAX); - NewBucket->Values = (meta_tag*)malloc(sizeof(meta_tag) * TYPE_TABLE_BUCKET_MAX); - GSZeroMemory((u8*)NewBucket->Keys, sizeof(u32) * TYPE_TABLE_BUCKET_MAX); - GSZeroMemory((u8*)NewBucket->Values, sizeof(meta_tag) * TYPE_TABLE_BUCKET_MAX); - - Result.BucketIndex = NewMetaBucketIndex; - Result.IndexInBucket = Index; - } - - return Result; -} - -internal type_table_handle -PushTypeOnHashTable(type_definition TypeDef, type_table* TypeTable) -{ - u32 IdentHash = HashIdentifier(TypeDef.Identifier); - type_table_handle Result = FindSlotForTypeIdentifier(IdentHash, TypeTable); - - type_table_hash_bucket* Bucket = TypeTable->Types + Result.BucketIndex; - Bucket->Keys[Result.IndexInBucket] = IdentHash; - Bucket->Values[Result.IndexInBucket] = TypeDef; - -#if PRINT_DIAGNOSTIC_INFO - printf("Registering Type\n"); - printf(" %.*s\n", StringExpand(TypeDef.Identifier)); - printf(" Type: %s\n\n", TypeDefinitionTypeStrings[TypeDef.Type]); -#endif - - return Result; -} - -internal type_table_handle -PushUndeclaredType (string Identifier, type_table* TypeTable) -{ - type_definition UndeclaredTypeDef = {}; - UndeclaredTypeDef.Identifier = Identifier; - UndeclaredTypeDef.Type = TypeDef_Unknown; - type_table_handle Result = PushTypeOnHashTable(UndeclaredTypeDef, TypeTable); - return Result; -} - -internal type_table_handle -PushMetaTagOnTable(meta_tag Tag, type_table* TypeTable) -{ - u32 TagIdentifierHash = HashIdentifier(Tag.Identifier); - type_table_handle Result = FindSlotForMetaTag(TagIdentifierHash, TypeTable); - - meta_tag_hash_bucket* Bucket = TypeTable->MetaTags + Result.BucketIndex; - Bucket->Keys[Result.IndexInBucket] = TagIdentifierHash; - Bucket->Values[Result.IndexInBucket] = Tag; - -#if PRINT_DIAGNOSTIC_INFO - printf("Registering Meta Tag\n"); - printf(" %.*s\n\n", StringExpand(Tag.Identifier)); -#endif - - return Result; -} - -// Guaranteed to return a valid result -internal type_definition* -GetTypeDefinition(type_table_handle Handle, type_table TypeTable) -{ - Assert(TypeHandleIsValid(Handle)); - type_definition* Result = 0; - if (TypeTable.Types[Handle.BucketIndex].Keys != 0) - { - Result = TypeTable.Types[Handle.BucketIndex].Values + Handle.IndexInBucket; - } - return Result; -} - -// May return zero -internal type_definition* -GetTypeDefinitionUnsafe(type_table_handle Handle, type_table TypeTable) -{ - type_definition* Result = 0; - if (TypeTable.Types[Handle.BucketIndex].Keys != 0) - { - Result = TypeTable.Types[Handle.BucketIndex].Values + Handle.IndexInBucket; - } - return Result; -} - -internal meta_tag* -GetMetaTag(type_table_handle Handle, type_table TypeTable) -{ - meta_tag* Result = 0; - if (TypeTable.MetaTags[Handle.BucketIndex].Keys != 0) - { - Result = TypeTable.MetaTags[Handle.BucketIndex].Values + Handle.IndexInBucket; - } - return Result; -} - -internal type_definition* -GetTypeDefinition(string Identifier, type_table TypeTable) -{ - type_definition* Result = 0; - u32 IdentHash = HashIdentifier(Identifier); - u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX; - for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = TypeTable.Types[b]; - if (Bucket.Keys[Index] == IdentHash ) - { - Result = Bucket.Values + Index; - break; - } - } - return Result; -} - -internal type_table_handle -PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable) -{ - // NOTE(Peter): We don't accept type definitions with empty identifiers. - // If a struct or union is anonymous, it should be assigned a name of the form - // parent_struct_name_# where # is the member index - // ie. - // struct foo { int a; union { int x }; }; - // the union in foo would have the identifier foo_1 - Assert(TypeDef.Identifier.Length != 0); - - type_table_handle Result = InvalidTypeTableHandle; - type_table_handle ExistingUndeclaredTypeHandle = GetTypeHandle(TypeDef.Identifier, *TypeTable); - - if (!TypeHandleIsValid(ExistingUndeclaredTypeHandle)) - { - Result = PushTypeOnHashTable(TypeDef, TypeTable); - } - else - { - Result = ExistingUndeclaredTypeHandle; - type_definition* ExistingTypeDef = GetTypeDefinition(Result, *TypeTable); - Assert(ExistingTypeDef != 0); - *ExistingTypeDef = TypeDef; - } - - return Result; -} - -internal s32 -GetSizeOfType (type_table_handle TypeHandle, type_table TypeTable) -{ - s32 Result = -1; - type_definition* TypeDef = GetTypeDefinition(TypeHandle, TypeTable); - if (TypeDef) - { - Result = TypeDef->Size; - } - return Result; -} - -internal s32 -GetSizeOfType (string Identifier, type_table TypeTable) -{ - s32 Result = -1; - type_definition* TypeDef = GetTypeDefinition(Identifier, TypeTable); - if (TypeDef) - { - Result = TypeDef->Size; - } - return Result; -} - -internal b32 -VariableDeclsEqual (variable_decl A, variable_decl B) -{ - b32 Result = false; - if (TypeHandlesEqual(A.TypeHandle, B.TypeHandle) && - A.ArrayCount == B.ArrayCount && - StringsEqual(A.Identifier, B.Identifier)) - { - Result = true; - } - return Result; -} - -internal b32 -StructOrUnionsEqual (type_definition A, type_definition B) -{ - // NOTE(Peter): Fairly certain the only places this is used are when we - // already know the identifiers match - Assert(StringsEqual(A.Identifier, B.Identifier)); - Assert(A.Type == TypeDef_Struct || A.Type == TypeDef_Union); - Assert(B.Type == TypeDef_Struct || B.Type == TypeDef_Union); - - b32 Result = false; - if (A.Struct.MemberDecls.Used == B.Struct.MemberDecls.Used) - { - Result = true; - for (u32 i = 0; i < A.Struct.MemberDecls.Used; i++) - { - variable_decl* AMember = A.Struct.MemberDecls.GetElementAtIndex(i); - variable_decl* BMember = A.Struct.MemberDecls.GetElementAtIndex(i); - - if (!VariableDeclsEqual(*AMember, *BMember)) - { - Result = false; - break; - } - } - } - return Result; -} - -internal type_table_handle -FindHandleOfMatchingType (type_definition Match, type_table TypeTable) -{ - type_table_handle Result = InvalidTypeTableHandle; - type_table_handle Handle = GetTypeHandle(Match.Identifier, TypeTable); - if (TypeHandleIsValid(Handle)) - { - Result = Handle; - } - return Result; -} - -internal void FixUpStructSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors); -internal void FixUpUnionSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors); - -internal void -FixupMemberType (variable_decl* Member, type_table TypeTable) -{ - if (!TypeHandleIsValid(Member->TypeHandle)) - { - Member->TypeHandle = GetTypeHandle(Member->Identifier, TypeTable); - } - Assert(TypeHandleIsValid(Member->TypeHandle)); -} - -internal s32 -CalculateStructMemberSize (variable_decl Member, type_definition MemberType) -{ - Assert(TypeHandleIsValid(Member.TypeHandle)); - // NOTE(Peter): At one point we were Asserting on struct sizes of zero, but - // that's actually incorrect. It is valid to have an empty struct. - - s32 Result = MemberType.Size; - if (Member.ArrayCount > 0) - { - Result *= Member.ArrayCount; - } - - if (Member.Pointer) - { - Result = sizeof(void*); - } - - return Result; -} - -internal void -FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_table TypeTable, errors* Errors) -{ - // NOTE(Peter): There are a lot of cases where struct members which are pointers - // to other structs cause interesting behavior here. - // For example: - // struct foo { foo* Next; } - // could cause infinite loops if we try and fixup all structs with a size of 0 - // which would happen in this case, because we wouldn't have parsed foo's size - // yet, but would begin fixing up foo because of the type of Next - // Another example: - // typedef struct bar bar; - // struct foo { bar* Bar; } - // struct bar { foo* Foo; } - // causes the exact same problem, but we cant detect it by just excluding - // fixing up StructIndex recursively. - // - // TL;DR - // The solution I've chosen to go with is just exclude all pointer members from - // causing recursive fixups. Those types should be fixed up at some point in the - // process, and we already know how big a pointer is in memory, no matter the type - if (!Member->Pointer) - { - if (MemberTypeDef->Size == 0) - { - if (MemberTypeDef->Type == TypeDef_Struct) - { - FixUpStructSize(Member->TypeHandle, TypeTable, Errors); - } - else if (MemberTypeDef->Type == TypeDef_Union) - { - FixUpUnionSize(Member->TypeHandle, TypeTable, Errors); - } - else - { - if (MemberTypeDef->Type == TypeDef_Unknown) - { - PushFError(Errors, "Error: TypeDef Unknown: %S", MemberTypeDef->Identifier); - } - else - { - // TODO(Peter): We don't parse all types yet, so for now, this is just an alert, - // not an assert; -#if 0 - InvalidCodePath; -#else - PushFError(Errors, "Error: TypeDef Size = 0. %S\n", MemberTypeDef->Identifier); -#endif - } - } - } - } -} - -internal void -FixUpStructSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors) -{ - type_definition* Struct = GetTypeDefinition(TypeHandle, TypeTable); - Assert(Struct->Type == TypeDef_Struct); - - if (HasTag(MakeStringLiteral("breakpoint"), Struct->MetaTags, TypeTable)) - { - __debugbreak(); - } - - s32 SizeAcc = 0; - for (u32 j = 0; j < Struct->Struct.MemberDecls.Used; j++) - { - variable_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j); - FixupMemberType(Member, TypeTable); - - if (TypeHandleIsValid(Member->TypeHandle)) - { - type_definition* MemberTypeDef = GetTypeDefinition(Member->TypeHandle, TypeTable); - FixupStructMember(Member, MemberTypeDef, TypeTable, Errors); - u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef); - SizeAcc += MemberSize; - } - } - - Struct->Size = SizeAcc; - - // NOTE(Peter): It is valid to have an empty struct, which would have a size of - // zero, hence the check here. - if (Struct->Size == 0 && Struct->Struct.MemberDecls.Used > 0) - { - // NOTE(Peter): Because its recursive (it makes sure all type sizes become known - // if it needs them) we should never get to the end of this function and not have - // the ability to tell how big something is. - // TODO(Peter): We don't parse all types yet however, so for now, this is just an alert, - // not an assert; -#if 0 - Assert(Struct->Size != 0); -#else - PushFError(Errors, "Struct Error: Struct Size = 0. %S\n", Struct->Identifier); -#endif - } -} - -internal void -FixUpUnionSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors) -{ - type_definition* Union = GetTypeDefinition(TypeHandle, TypeTable); - Assert(Union->Type == TypeDef_Union); - - s32 BiggestMemberSize = 0; - for (u32 j = 0; j < Union->Struct.MemberDecls.Used; j++) - { - variable_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j); - FixupMemberType(Member, TypeTable); - - if (TypeHandleIsValid(Member->TypeHandle)) - { - type_definition* MemberTypeDef = GetTypeDefinition(Member->TypeHandle, TypeTable); - FixupStructMember(Member, MemberTypeDef, TypeTable, Errors); - s32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef); - BiggestMemberSize = GSMax(BiggestMemberSize, MemberSize); - } - } - - Union->Size = BiggestMemberSize; - - // NOTE(Peter): It is valid to have an empty struct, which would have a size of - // zero, hence the check here. - if (Union->Size == 0 && Union->Struct.MemberDecls.Used > 0) - { - // NOTE(Peter): Because its recursive (it makes sure all type sizes become known - // if it needs them) we should never get to the end of this function and not have - // the ability to tell how big something is - // TODO(Peter): We don't parse all types yet however, so for now, this is just an alert, - // not an assert; -#if 0 - Assert(Union->Size != 0); -#else - PushFError(Errors, "Union Error: Struct Size = 0. %S\n", Union->Identifier); -#endif - } -} - -type_definition CPPBasicTypes[] = { - { MakeStringLiteral("float"), sizeof(float), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("double"), sizeof(double), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("char"), sizeof(char), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("wchar_t"), sizeof(wchar_t), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("int"), sizeof(int), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("short"), sizeof(short), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("short int"), sizeof(short int), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("long int"), sizeof(long int), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("long long int"), sizeof(long long int), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("void"), sizeof(void*), {}, TypeDef_BasicType, {}, false }, - { MakeStringLiteral("bool"), sizeof(bool), {}, TypeDef_BasicType, {}, false }, - - // These are from system headers that we aren't parsing atm - { MakeStringLiteral("HANDLE"), sizeof(void*), {}, TypeDef_BasicType, {}, false }, -}; - -internal void -PopulateTableWithDefaultCPPTypes(type_table* TypeTable) -{ - for (u32 i = 0; i < GSArrayLength(CPPBasicTypes); i++) - { - PushTypeDefOnTypeTable(CPPBasicTypes[i], TypeTable); - } -} - -internal void -PrintTypeDefinition(type_definition TypeDef, type_table TypeTable) -{ - printf("Type: %.*s\n", StringExpand(TypeDef.Identifier)); - printf(" Size: %d\n", TypeDef.Size); - - printf(" Meta Tags: "); - for (u32 m = 0; m < TypeDef.MetaTags.Used; m++) - { - type_table_handle TagHandle = *TypeDef.MetaTags.GetElementAtIndex(m); - meta_tag* Tag = GetMetaTag(TagHandle, TypeTable); - printf("%.*s ", StringExpand(Tag->Identifier)); - } - printf("\n"); - - printf(" Type: %s\n", TypeDefinitionTypeStrings[TypeDef.Type]); - - switch(TypeDef.Type) - { - case TypeDef_Unknown: - { - } break; - - case TypeDef_Enum: - { - } break; - - case TypeDef_Struct: - { - } break; - - case TypeDef_Union: - { - } break; - - case TypeDef_BasicType: - { - } break; - - case TypeDef_FunctionPointer: - { - } break; - - case TypeDef_Function: - { - type_definition* ReturnType = GetTypeDefinition(TypeDef.Function.ReturnTypeHandle, TypeTable); - printf(" Returns: %.*s\n", StringExpand(ReturnType->Identifier)); - - printf(" Parameters: "); - for (u32 p = 0; p < TypeDef.Function.Parameters.Used; p++) - { - variable_decl* Param = TypeDef.Function.Parameters.GetElementAtIndex(p); - type_definition* ParamType = GetTypeDefinition(Param->TypeHandle, TypeTable); - printf("%.*s %.*s, ", StringExpand(ParamType->Identifier), StringExpand(Param->Identifier)); - } - } break; - - case TypeDef_Invalid: - case TypeDef_Count: - { - printf("???\n"); - } break; - } -} - -internal void -PrintTypeTable(type_table TypeTable) -{ - for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = TypeTable.Types[b]; - for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++) - { - if (Bucket.Keys[i] != 0) - { - PrintTypeDefinition(Bucket.Values[i], TypeTable); - } - } - } -} - -internal void -DEBUGPrintTypeTableMembership(type_table TypeTable) -{ - printf("\n--- Type Table Membership --\n"); - u32 SlotsAvailable = 0; - u32 SlotsFilled = 0; - u32 TotalSlots = TypeTable.TypeBucketsCount * TYPE_TABLE_BUCKET_MAX; - for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = TypeTable.Types[b]; - for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++) - { - if (Bucket.Keys[i] != 0) - { - SlotsFilled++; - printf("[x] "); - } - else - { - SlotsAvailable++; - printf("[ ] "); - } - } - printf("\n"); - } - - r32 PercentUsed = (r32)SlotsFilled / (r32)TotalSlots; - printf("Slots Available: %d\n", SlotsAvailable); - printf("Slots Filled: %d\n", SlotsFilled); - printf("Total Slots: %d\n", TotalSlots); - printf("Percent Used: %f\n", PercentUsed); - printf("\n"); -} - -#define FOLDHAUS_META_TYPE_TABLE_H -#endif // FOLDHAUS_META_TYPE_TABLE_H \ No newline at end of file diff --git a/src/meta/gs_meta_typeinfo_generator.h b/src/meta/gs_meta_typeinfo_generator.h deleted file mode 100644 index c26cf4a..0000000 --- a/src/meta/gs_meta_typeinfo_generator.h +++ /dev/null @@ -1,218 +0,0 @@ -// -// File: gs_meta_typeinfo_generator.h -// Author: Peter Slattery -// Creation Date: 2020-01-19 -// -// Usage -// TODO -// -// -#ifndef GS_META_TYPEINFO_GENERATOR_H - -#include "..\gs_libs\gs_language.h" -#include "..\gs_libs\gs_string.h" -#include "..\gs_libs\gs_string_builder.h" -#include "gs_meta_code_generator.h" - -struct typeinfo_generator -{ - string_builder MetaTagString; - string_builder MetaTagEnum; - - string_builder TypeListString; - gsm_code_generator TypeList; - string_builder StructMembers; - string_builder TypeDefinitions; - - u32 GeneratedInfoTypesCount; - u32 TypesMax; - b8* TypesGeneratedMask; -}; - -#define TypeHandleToIndex(handle) ((handle.BucketIndex * TYPE_TABLE_BUCKET_MAX) + handle.IndexInBucket) -internal typeinfo_generator -InitTypeInfoGenerator(type_table TypeTable) -{ - typeinfo_generator Result = {}; - - Result.TypesMax = TypeTable.TypeBucketsCount * TYPE_TABLE_BUCKET_MAX; - Result.TypesGeneratedMask = (b8*)malloc(sizeof(b8) * Result.TypesMax); - GSZeroMemory((u8*)Result.TypesGeneratedMask, Result.TypesMax); - - Result.TypeList = BeginEnumGeneration("gsm_struct_type", "gsm_StructType", false, true); - - WriteF(&Result.TypeDefinitions, "static gsm_struct_type_info StructTypes[] = {\n"); - return Result; -} - -internal void -FinishGeneratingTypes(typeinfo_generator* Generator) -{ - FinishEnumGeneration(&Generator->TypeList); - - WriteF(&Generator->StructMembers, "\n"); - - WriteF(&Generator->TypeDefinitions, "};\n"); - WriteF(&Generator->TypeDefinitions, "static gsm_u32 StructTypesCount = %d;\n", Generator->GeneratedInfoTypesCount); -} - -internal void -GenerateMetaTagInfo (gs_bucket Tags, type_table TypeTable, string_builder* Builder) -{ - WriteF(Builder, "{"); - for (u32 t = 0; t < Tags.Used; t++) - { - type_table_handle TagHandle = *Tags.GetElementAtIndex(t); - meta_tag* Tag = GetMetaTag(TagHandle, TypeTable); - WriteF(Builder, "MetaTag_%S, ", Tag->Identifier); - } - WriteF(Builder, "}, %d", Tags.Used); -} - -internal void -GenerateStructMemberInfo (variable_decl* Member, string StructIdentifier, type_table TypeTable, typeinfo_generator* Gen) -{ - WriteF(&Gen->StructMembers, "{ \"%S\", %d, ", Member->Identifier, Member->Identifier.Length); - WriteF(&Gen->StructMembers, "(u64)&((%S*)0)->%S, ", StructIdentifier, Member->Identifier); - GenerateMetaTagInfo(Member->MetaTags, TypeTable, &Gen->StructMembers); - WriteF(&Gen->StructMembers, "},\n"); -} - -internal void -GenerateTypeInfo (type_definition* Type, type_table_handle TypeHandle, type_table TypeTable, typeinfo_generator* Generator) -{ - // TODO(Peter): - // 1. allocate the full range of the types hash table - // 2. use bucketindex * bucket_max + indexinbucket to get the consecutive index - Generator->TypesGeneratedMask[TypeHandleToIndex(TypeHandle)] = true; - Generator->GeneratedInfoTypesCount++; - - { - // NOTE(Peter): This block MUST come before generating - // type info for any member types. If it doesn't, it will screw - // up array ordering - - AddEnumElement(&Generator->TypeList, Type->Identifier); - - // Type Info - WriteF(&Generator->TypeDefinitions, "{ gsm_StructType_%S, \"%S\", %d, %d, 0, 0, ", - Type->Identifier, - Type->Identifier, Type->Identifier.Length, - Type->Size - // TODO(Peter): include Meta Tags somehow - ); - if ((Type->Type == TypeDef_Struct || Type->Type == TypeDef_Union) && - Type->Struct.MemberDecls.Used > 0) - { - WriteF(&Generator->TypeDefinitions, "StructMembers_%S, %d },\n", - Type->Identifier, - Type->Struct.MemberDecls.Used); - } - else - { - WriteF(&Generator->TypeDefinitions, "0, 0 },\n"); - } - } - - if (Type->Type == TypeDef_Struct || - Type->Type == TypeDef_Union) - { - for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++) - { - variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m); - type_definition* MemberType = GetTypeDefinition(Member->TypeHandle, TypeTable); - - if ((MemberType->Type == TypeDef_Struct || - MemberType->Type == TypeDef_Union) && - MemberType->Struct.IsAnonymous) - { - continue; // Don't gen info for anonymous struct and union members - } - - if (Generator->TypesGeneratedMask[TypeHandleToIndex(Member->TypeHandle)]) { continue; } - - GenerateTypeInfo(MemberType, Member->TypeHandle, TypeTable, Generator); - } - - // - WriteF(&Generator->StructMembers, "static gsm_struct_member_type_info StructMembers_%S[] = {\n", Type->Identifier); - for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++) - { - variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m); - type_definition* MemberType = GetTypeDefinition(Member->TypeHandle, TypeTable); - - if ((MemberType->Type != TypeDef_Struct && MemberType->Type != TypeDef_Union) || - !MemberType->Struct.IsAnonymous) - { - GenerateStructMemberInfo(Member, Type->Identifier, TypeTable, Generator); - } - else if (MemberType->Struct.IsAnonymous) - { - // Anonymous Members - for (u32 a = 0; a < MemberType->Struct.MemberDecls.Used; a++) - { - variable_decl* AnonMember = MemberType->Struct.MemberDecls.GetElementAtIndex(a); - GenerateStructMemberInfo(AnonMember, Type->Identifier, TypeTable, Generator); - } - } - } - WriteF(&Generator->StructMembers, "};\n", Type->Struct.MemberDecls.Used); - } -} - -internal void -GenerateFilteredTypeInfo (string MetaTagFilter, type_table TypeTable, typeinfo_generator* Generator) -{ - for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++) - { - type_table_hash_bucket Bucket = TypeTable.Types[b]; - - for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++) - { - type_table_handle TypeHandle = {}; - TypeHandle.BucketIndex = b; - TypeHandle.IndexInBucket = i; - - if (Generator->TypesGeneratedMask[TypeHandleToIndex(TypeHandle)]) - { - continue; - } - - type_definition* Type = GetTypeDefinitionUnsafe(TypeHandle, TypeTable); - if (Type) - { - if (HasTag(MetaTagFilter, Type->MetaTags, TypeTable)) - { - GenerateTypeInfo(Type, TypeHandle, TypeTable, Generator); - } - } - } - } -} - -internal void -GenerateMetaTagList(type_table TypeTable, typeinfo_generator* Generator) -{ - WriteF(&Generator->MetaTagString, "gsm_meta_tag MetaTagStrings[] = {\n"); - WriteF(&Generator->MetaTagEnum, "enum gsm_meta_tag_type\n{\n"); - - for (u32 b = 0; b < TypeTable.MetaTagBucketsCount; b++) - { - meta_tag_hash_bucket Bucket = TypeTable.MetaTags[b]; - for (u32 i = 0; i < META_TAG_BUCKET_MAX; i++) - { - if (Bucket.Keys[i] != 0) - { - string MetaTagIdentifier = Bucket.Values[i].Identifier; - WriteF(&Generator->MetaTagString, "{ \"%S\", %d },\n", MetaTagIdentifier, MetaTagIdentifier.Length); - WriteF(&Generator->MetaTagEnum, "MetaTag_%S,\n", MetaTagIdentifier); - } - } - } - - WriteF(&Generator->MetaTagString, "};\n"); - WriteF(&Generator->MetaTagEnum, "};\n"); -} - -#define GS_META_TYPEINFO_GENERATOR_H -#endif // GS_META_TYPEINFO_GENERATOR_H \ No newline at end of file diff --git a/src_v2/patterns/patterns_math.h b/src/patterns/patterns_math.h similarity index 100% rename from src_v2/patterns/patterns_math.h rename to src/patterns/patterns_math.h diff --git a/src_v2/platform/glcorearb.h b/src/platform/glcorearb.h similarity index 100% rename from src_v2/platform/glcorearb.h rename to src/platform/glcorearb.h diff --git a/src_v2/platform/glext.h b/src/platform/glext.h similarity index 100% rename from src_v2/platform/glext.h rename to src/platform/glext.h diff --git a/src_v2/platform/khrplatform.h b/src/platform/khrplatform.h similarity index 100% rename from src_v2/platform/khrplatform.h rename to src/platform/khrplatform.h diff --git a/src_v2/platform/linux/lumenarium_linux_file.h b/src/platform/linux/lumenarium_linux_file.h similarity index 100% rename from src_v2/platform/linux/lumenarium_linux_file.h rename to src/platform/linux/lumenarium_linux_file.h diff --git a/src_v2/platform/linux/lumenarium_linux_memory.h b/src/platform/linux/lumenarium_linux_memory.h similarity index 100% rename from src_v2/platform/linux/lumenarium_linux_memory.h rename to src/platform/linux/lumenarium_linux_memory.h diff --git a/src_v2/platform/linux/lumenarium_linux_network.h b/src/platform/linux/lumenarium_linux_network.h similarity index 100% rename from src_v2/platform/linux/lumenarium_linux_network.h rename to src/platform/linux/lumenarium_linux_network.h diff --git a/src_v2/platform/linux/lumenarium_linux_thread.h b/src/platform/linux/lumenarium_linux_thread.h similarity index 100% rename from src_v2/platform/linux/lumenarium_linux_thread.h rename to src/platform/linux/lumenarium_linux_thread.h diff --git a/src_v2/platform/linux/lumenarium_linux_time.h b/src/platform/linux/lumenarium_linux_time.h similarity index 100% rename from src_v2/platform/linux/lumenarium_linux_time.h rename to src/platform/linux/lumenarium_linux_time.h diff --git a/src_v2/platform/lumenarium_assert.h b/src/platform/lumenarium_assert.h similarity index 100% rename from src_v2/platform/lumenarium_assert.h rename to src/platform/lumenarium_assert.h diff --git a/src_v2/platform/lumenarium_compiler_flags.h b/src/platform/lumenarium_compiler_flags.h similarity index 100% rename from src_v2/platform/lumenarium_compiler_flags.h rename to src/platform/lumenarium_compiler_flags.h diff --git a/src_v2/platform/lumenarium_os.h b/src/platform/lumenarium_os.h similarity index 100% rename from src_v2/platform/lumenarium_os.h rename to src/platform/lumenarium_os.h diff --git a/src_v2/platform/lumenarium_platform.h b/src/platform/lumenarium_platform.h similarity index 100% rename from src_v2/platform/lumenarium_platform.h rename to src/platform/lumenarium_platform.h diff --git a/src_v2/platform/lumenarium_platform_common_includes.h b/src/platform/lumenarium_platform_common_includes.h similarity index 100% rename from src_v2/platform/lumenarium_platform_common_includes.h rename to src/platform/lumenarium_platform_common_includes.h diff --git a/src_v2/platform/osx/lumenarium_first_osx.c b/src/platform/osx/lumenarium_first_osx.c similarity index 100% rename from src_v2/platform/osx/lumenarium_first_osx.c rename to src/platform/osx/lumenarium_first_osx.c diff --git a/src_v2/platform/osx/lumenarium_osx_file.h b/src/platform/osx/lumenarium_osx_file.h similarity index 100% rename from src_v2/platform/osx/lumenarium_osx_file.h rename to src/platform/osx/lumenarium_osx_file.h diff --git a/src_v2/platform/osx/lumenarium_osx_graphics.h b/src/platform/osx/lumenarium_osx_graphics.h similarity index 100% rename from src_v2/platform/osx/lumenarium_osx_graphics.h rename to src/platform/osx/lumenarium_osx_graphics.h diff --git a/src_v2/platform/osx/lumenarium_osx_memory.h b/src/platform/osx/lumenarium_osx_memory.h similarity index 100% rename from src_v2/platform/osx/lumenarium_osx_memory.h rename to src/platform/osx/lumenarium_osx_memory.h diff --git a/src_v2/platform/osx/lumenarium_osx_network.h b/src/platform/osx/lumenarium_osx_network.h similarity index 100% rename from src_v2/platform/osx/lumenarium_osx_network.h rename to src/platform/osx/lumenarium_osx_network.h diff --git a/src_v2/platform/osx/lumenarium_osx_thread.h b/src/platform/osx/lumenarium_osx_thread.h similarity index 100% rename from src_v2/platform/osx/lumenarium_osx_thread.h rename to src/platform/osx/lumenarium_osx_thread.h diff --git a/src_v2/platform/osx/lumenarium_osx_time.h b/src/platform/osx/lumenarium_osx_time.h similarity index 100% rename from src_v2/platform/osx/lumenarium_osx_time.h rename to src/platform/osx/lumenarium_osx_time.h diff --git a/src_v2/platform/raspi/lumenarium_first_raspi.c b/src/platform/raspi/lumenarium_first_raspi.c similarity index 100% rename from src_v2/platform/raspi/lumenarium_first_raspi.c rename to src/platform/raspi/lumenarium_first_raspi.c diff --git a/src_v2/platform/raspi/lumenarium_raspi_tests.c b/src/platform/raspi/lumenarium_raspi_tests.c similarity index 100% rename from src_v2/platform/raspi/lumenarium_raspi_tests.c rename to src/platform/raspi/lumenarium_raspi_tests.c diff --git a/src_v2/platform/shared/lumenarium_shared_file_async_work_on_job.h b/src/platform/shared/lumenarium_shared_file_async_work_on_job.h similarity index 100% rename from src_v2/platform/shared/lumenarium_shared_file_async_work_on_job.h rename to src/platform/shared/lumenarium_shared_file_async_work_on_job.h diff --git a/src_v2/platform/shared/lumenarium_shared_file_tracker.h b/src/platform/shared/lumenarium_shared_file_tracker.h similarity index 100% rename from src_v2/platform/shared/lumenarium_shared_file_tracker.h rename to src/platform/shared/lumenarium_shared_file_tracker.h diff --git a/src_v2/platform/shared/lumenarium_shared_network.h b/src/platform/shared/lumenarium_shared_network.h similarity index 100% rename from src_v2/platform/shared/lumenarium_shared_network.h rename to src/platform/shared/lumenarium_shared_network.h diff --git a/src_v2/platform/sokol_gfx.h b/src/platform/sokol_gfx.h similarity index 100% rename from src_v2/platform/sokol_gfx.h rename to src/platform/sokol_gfx.h diff --git a/src_v2/platform/wasm/lumenarium_first_wasm.cpp b/src/platform/wasm/lumenarium_first_wasm.cpp similarity index 100% rename from src_v2/platform/wasm/lumenarium_first_wasm.cpp rename to src/platform/wasm/lumenarium_first_wasm.cpp diff --git a/src_v2/platform/wasm/lumenarium_wasm_file.cpp b/src/platform/wasm/lumenarium_wasm_file.cpp similarity index 100% rename from src_v2/platform/wasm/lumenarium_wasm_file.cpp rename to src/platform/wasm/lumenarium_wasm_file.cpp diff --git a/src_v2/platform/wasm/lumenarium_wasm_imports.js b/src/platform/wasm/lumenarium_wasm_imports.js similarity index 100% rename from src_v2/platform/wasm/lumenarium_wasm_imports.js rename to src/platform/wasm/lumenarium_wasm_imports.js diff --git a/src_v2/platform/wasm/lumenarium_wasm_memory.cpp b/src/platform/wasm/lumenarium_wasm_memory.cpp similarity index 100% rename from src_v2/platform/wasm/lumenarium_wasm_memory.cpp rename to src/platform/wasm/lumenarium_wasm_memory.cpp diff --git a/src_v2/platform/wasm/lumenarium_wasm_thread.cpp b/src/platform/wasm/lumenarium_wasm_thread.cpp similarity index 100% rename from src_v2/platform/wasm/lumenarium_wasm_thread.cpp rename to src/platform/wasm/lumenarium_wasm_thread.cpp diff --git a/src_v2/platform/wasm/lumenarium_wasm_time.cpp b/src/platform/wasm/lumenarium_wasm_time.cpp similarity index 100% rename from src_v2/platform/wasm/lumenarium_wasm_time.cpp rename to src/platform/wasm/lumenarium_wasm_time.cpp diff --git a/src_v2/platform/wasm/lumenarium_wasm_webgl.cpp b/src/platform/wasm/lumenarium_wasm_webgl.cpp similarity index 100% rename from src_v2/platform/wasm/lumenarium_wasm_webgl.cpp rename to src/platform/wasm/lumenarium_wasm_webgl.cpp diff --git a/src_v2/platform/wglext.h b/src/platform/wglext.h similarity index 100% rename from src_v2/platform/wglext.h rename to src/platform/wglext.h diff --git a/src_v2/platform/win32/lumenarium_first_win32.cpp b/src/platform/win32/lumenarium_first_win32.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_first_win32.cpp rename to src/platform/win32/lumenarium_first_win32.cpp diff --git a/src_v2/platform/win32/lumenarium_win32_file.cpp b/src/platform/win32/lumenarium_win32_file.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_file.cpp rename to src/platform/win32/lumenarium_win32_file.cpp diff --git a/src_v2/platform/win32/lumenarium_win32_graphics.cpp b/src/platform/win32/lumenarium_win32_graphics.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_graphics.cpp rename to src/platform/win32/lumenarium_win32_graphics.cpp diff --git a/src_v2/platform/win32/lumenarium_win32_memory.cpp b/src/platform/win32/lumenarium_win32_memory.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_memory.cpp rename to src/platform/win32/lumenarium_win32_memory.cpp diff --git a/src_v2/platform/win32/lumenarium_win32_opengl.h b/src/platform/win32/lumenarium_win32_opengl.h similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_opengl.h rename to src/platform/win32/lumenarium_win32_opengl.h diff --git a/src_v2/platform/win32/lumenarium_win32_thread.cpp b/src/platform/win32/lumenarium_win32_thread.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_thread.cpp rename to src/platform/win32/lumenarium_win32_thread.cpp diff --git a/src_v2/platform/win32/lumenarium_win32_time.cpp b/src/platform/win32/lumenarium_win32_time.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_time.cpp rename to src/platform/win32/lumenarium_win32_time.cpp diff --git a/src_v2/platform/win32/lumenarium_win32_window.cpp b/src/platform/win32/lumenarium_win32_window.cpp similarity index 100% rename from src_v2/platform/win32/lumenarium_win32_window.cpp rename to src/platform/win32/lumenarium_win32_window.cpp diff --git a/src_v2/platform/win32/test.cpp b/src/platform/win32/test.cpp similarity index 100% rename from src_v2/platform/win32/test.cpp rename to src/platform/win32/test.cpp diff --git a/src_v2/scratch/lumenarium b/src/scratch/lumenarium similarity index 100% rename from src_v2/scratch/lumenarium rename to src/scratch/lumenarium diff --git a/src/sculpture_gen/gen_blumen_lumen.cpp b/src/sculpture_gen/gen_blumen_lumen.cpp deleted file mode 100644 index 9edceb6..0000000 --- a/src/sculpture_gen/gen_blumen_lumen.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// -// File: gen_blumen_lumen.cpp -// Author: Peter Slattery -// Creation Date: 2021-01-06 -// -#ifndef GEN_BLUMEN_LUMEN_CPP - -#include -#include - -#include "../gs_libs/gs_types.h" -#include "../gs_libs/gs_types.cpp" -#include "../app/engine/foldhaus_log.h" -global log_buffer* GlobalLogBuffer; - -#include "../app/platform_win32/win32_foldhaus_utils.h" -#include "../app/platform_win32/win32_foldhaus_memory.h" -#include "../app/platform_win32/win32_foldhaus_fileio.h" -#include "../app/platform_win32/win32_foldhaus_work_queue.h" - -#include "sculpture_gen.h" - -typedef struct -{ - v3 CenterStart; - v3 CenterEnd; - r32 Radius; - u32 SegmentsCount; - u32 SubsegmentsCount; - u32 SubsegmentLeds; - - // SACN - u32 SACNUniverseStart; - u32 SACNChannelStart; - - // UART - // Only one of these two values is needed. - // If ChannelsArray != 0, then it will be used, and assumed to - // have SegmentsCount values - // Otherwise, each segment will increment from ChannelStart - u32 ChannelStart; - u32* ChannelsArray; - - char* ComPort; - char* SectionTagValue; - char* FlowerTagValue; -} loop_desc; - -internal void -BuildLoop(gs_string* OutputBuffer, loop_desc Desc) -{ - r32 SegmentsArc = TauR32 / Desc.SegmentsCount; - r32 SubsegmentsArc = SegmentsArc / Desc.SubsegmentsCount; - - for (u32 i = 0; i < Desc.SegmentsCount; i++) - { - r32 ArcBase = SegmentsArc * i; - - u32 Channel = 0; - if (Desc.ChannelsArray != 0) - { - Channel = Desc.ChannelsArray[i]; - } - else - { - Channel = Desc.ChannelStart + i; - } - - WriteLedStripOpen(OutputBuffer, Channel, Desc.ComPort, - Desc.SACNUniverseStart, Desc.SACNChannelStart); - WriteSegmentSequenceOpen(OutputBuffer, Desc.SubsegmentsCount); - - for (u32 j = 0; j < Desc.SubsegmentsCount; j++) - { - r32 Arc = ArcBase + (SubsegmentsArc * j); - v3 Offset = v3{ SinR32(Arc), 0, CosR32(Arc) } * Desc.Radius; - v3 P0 = Desc.CenterStart + Offset; - v3 P1 = Desc.CenterEnd + Offset; - - // Swap directions on the middle strip - if (j%2 != 0) - { - v3 Temp = P0; - P0 = P1; - P1 = Temp; - } - - WriteSegmentSequenceSegment(OutputBuffer, P0, P1, Desc.SubsegmentLeds); - } - - WriteSegmentSequenceClose(OutputBuffer); - WriteSegmentTagsOpen(OutputBuffer, 2); - WriteSegmentTag(OutputBuffer, "section", Desc.SectionTagValue); - WriteSegmentTag(OutputBuffer, "flower", Desc.FlowerTagValue); - WriteSegmentTagsClose(OutputBuffer); - WriteLedStripClose(OutputBuffer); - } - -} - -typedef struct -{ - v3 Pos; - char* ComPort; - char* FlowerTagValue; - - // SACN - u32 SACNStemInnerStartUniverse; - u32 SACNStemOuterStartUniverse; - u32 SACNFlowerStemStartUniverse; - - // UART - u32* StemChannels; - u32* BloomOuterChannels; - u32* BloomInnerChannels; -} flower_desc; - -internal u32 -BuildFlower(gs_string* OutputBuffer, flower_desc Desc) -{ - -#if 1 - // the bloom stem inner - loop_desc BloomStemInner = {}; - BloomStemInner.CenterStart = v3{0, 1.4f, 0}; - BloomStemInner.CenterEnd = v3{0, .9f, 0}; - BloomStemInner.Radius = .05f; - //BloomStemInner.SegmentsCount = 6; - BloomStemInner.SegmentsCount = 1; - BloomStemInner.SubsegmentsCount = 3; - BloomStemInner.SubsegmentLeds = 35; - BloomStemInner.SACNUniverseStart = Desc.SACNStemInnerStartUniverse; - BloomStemInner.SACNChannelStart = 1; - BloomStemInner.ChannelsArray = Desc.BloomInnerChannels; - BloomStemInner.ComPort = Desc.ComPort; - BloomStemInner.SectionTagValue = "inner_bloom"; - BloomStemInner.FlowerTagValue = Desc.FlowerTagValue; - BuildLoop(OutputBuffer, BloomStemInner); - - // the bloom stem outer - loop_desc BloomStemOuter = {}; - BloomStemOuter.CenterStart = v3{0, .5f, 0}; - BloomStemOuter.CenterEnd = v3{0, .9f, 0}; - BloomStemOuter.Radius = .07f; - //BloomStemOuter.SegmentsCount = 9; - BloomStemOuter.SegmentsCount = 1; - BloomStemOuter.SubsegmentsCount = 3; - BloomStemOuter.SubsegmentLeds = 41; - BloomStemOuter.SACNUniverseStart = Desc.SACNStemOuterStartUniverse; - BloomStemOuter.SACNChannelStart = 1; - BloomStemOuter.ChannelsArray = Desc.BloomOuterChannels; - BloomStemOuter.ComPort = Desc.ComPort; - BloomStemOuter.SectionTagValue = "outer_bloom"; - BloomStemOuter.FlowerTagValue = Desc.FlowerTagValue; - BuildLoop(OutputBuffer, BloomStemOuter); -#endif - -#if 1 - // the flower stem - loop_desc FlowerStem = {}; - FlowerStem.CenterStart = v3{0, .5f, 0}; - FlowerStem.CenterEnd = v3{0, -1.5f, 0}; - FlowerStem.Radius = .05f; - //FlowerStem.SegmentsCount = 6; - FlowerStem.SegmentsCount = 1; - FlowerStem.SubsegmentsCount = 1; - FlowerStem.SubsegmentLeds = 300; - FlowerStem.SACNUniverseStart = Desc.SACNFlowerStemStartUniverse; - FlowerStem.SACNChannelStart = 1; - FlowerStem.ChannelsArray = Desc.StemChannels; - FlowerStem.ComPort = Desc.ComPort; - FlowerStem.SectionTagValue = "stem"; - FlowerStem.FlowerTagValue = Desc.FlowerTagValue; - BuildLoop(OutputBuffer, FlowerStem); -#endif - - u32 StripsCount = BloomStemInner.SegmentsCount; - StripsCount += BloomStemOuter.SegmentsCount; - StripsCount += FlowerStem.SegmentsCount; - - return StripsCount; -} - -// Just for brevity, no real function provided -#define FSC(f,c) FlowerStripToChannel((f), (c)) -internal u8 -FlowerStripToChannel(u8 Flower, u8 Channel) -{ - Assert(Flower < 3); - Assert(Channel < 8); - - u8 Result = 0; - Result |= (Flower & 0x03) << 3; - Result |= (Channel & 0x07); - - return Result; -} - -int main(int ArgCount, char** Args) -{ - gs_thread_context Ctx = Win32CreateThreadContext(); - GlobalLogBuffer = PushStruct(Ctx.Transient, log_buffer); - *GlobalLogBuffer = Log_Init(Ctx.Transient, 32); - - gs_string OutputBuffer0 = PushString(Ctx.Transient, MB(4)); - gs_string OutputBuffer1 = PushString(Ctx.Transient, MB(4)); - gs_string OutputBuffer2 = PushString(Ctx.Transient, MB(4)); - - u32 StripCount = 3; // used to be 21 -#if 0 - WriteAssemblyUARTOpen(&OutputBuffer0, - "Blumen Lumen - Silver Spring - 00", - 100, - v3{-1, 0, 0}, - StripCount, - ""); - WriteAssemblyUARTOpen(&OutputBuffer1, - "Blumen Lumen - Silver Spring - 01", - 100, - v3{0, 0, 0}, - StripCount, - ""); - WriteAssemblyUARTOpen(&OutputBuffer2, - "Blumen Lumen - Silver Spring - 02", - 100, - v3{1, 0, 0}, - StripCount, - ""); -#else - WriteAssemblySACNOpen(&OutputBuffer0, - "Blumen Lumen - Silver Spring - 00", - 100, - v3{-1, 0, 0}, - StripCount); - WriteAssemblySACNOpen(&OutputBuffer1, - "Blumen Lumen - Silver Spring - 01", - 100, - v3{0, 0, 0}, - StripCount); - WriteAssemblySACNOpen(&OutputBuffer2, - "Blumen Lumen - Silver Spring - 02", - 100, - v3{1, 0, 0}, - StripCount); -#endif - - u32 StripCountOut = 0; - - u32 StemChannels[] = { FSC(2, 1), FSC(2, 2), FSC(2, 3), FSC(2, 4), FSC(2, 5), FSC(2, 6) }; - u32 BloomOuterChannels[] = { FSC(1, 0), FSC(1, 1), FSC(1, 2), FSC(1, 3), FSC(1, 4), FSC(1, 5), FSC(1, 6), FSC(1, 7), FSC(2, 0) }; - u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) }; - flower_desc F0 = {}; - F0.Pos = v3{0, 0, 0}; - F0.ComPort = "\\\\.\\COM11"; - F0.FlowerTagValue = "left"; - F0.SACNStemInnerStartUniverse = 4; - F0.SACNStemOuterStartUniverse = 3; - F0.SACNFlowerStemStartUniverse = 1; - F0.StemChannels = StemChannels; - F0.BloomOuterChannels = BloomOuterChannels; - F0.BloomInnerChannels = BloomInnerChannels; - StripCountOut += BuildFlower(&OutputBuffer0, F0); - - flower_desc F1 = {}; - F1.Pos = v3{0, 0, 0}; - F1.ComPort = "\\\\.\\COM12"; - F1.FlowerTagValue = "center"; - F1.SACNStemInnerStartUniverse = 9; - F1.SACNStemOuterStartUniverse = 8; - F1.SACNFlowerStemStartUniverse = 6; - F1.StemChannels = StemChannels; - F1.BloomInnerChannels = BloomInnerChannels; - F1.BloomOuterChannels = BloomOuterChannels; - StripCountOut += BuildFlower(&OutputBuffer1, F1); - - flower_desc F2 = {}; - F2.Pos = v3{0, 0, 0}; - F2.ComPort = "\\\\.\\COM6"; - F2.FlowerTagValue = "right"; - F2.SACNStemInnerStartUniverse = 14; - F2.SACNStemOuterStartUniverse = 13; - F2.SACNFlowerStemStartUniverse = 11; - F2.StemChannels = StemChannels; - F2.BloomInnerChannels = BloomInnerChannels; - F2.BloomOuterChannels = BloomOuterChannels; - StripCountOut += BuildFlower(&OutputBuffer2, F2); - - WriteEntireFile(Ctx.FileHandler, ConstString("data/ss_blumen_one.fold"), StringToData(OutputBuffer0)); - WriteEntireFile(Ctx.FileHandler, ConstString("data/ss_blumen_two.fold"), StringToData(OutputBuffer1)); - WriteEntireFile(Ctx.FileHandler, ConstString("data/ss_blumen_three.fold"), StringToData(OutputBuffer2)); - - //printf("%.*s\n", (u32)OutputBuffer.Length, OutputBuffer.Str); - //printf("%d\n", StripCount); - - - - - return 0; -} - - -#define GEN_BLUMEN_LUMEN_CPP -#endif // GEN_BLUMEN_LUMEN_CPP \ No newline at end of file diff --git a/src/sculpture_gen/sculpture_gen.h b/src/sculpture_gen/sculpture_gen.h deleted file mode 100644 index 6336f46..0000000 --- a/src/sculpture_gen/sculpture_gen.h +++ /dev/null @@ -1,128 +0,0 @@ -// -// File: sculpture_gen.h -// Author: Peter Slattery -// Creation Date: 2021-01-06 -// -#ifndef SCULPTURE_GEN_H - -internal void -WriteIndented(gs_string* Buffer, u32 Indent, char* Format, ...) -{ - va_list Args; - va_start(Args, Format); - - for (u32 i = 0; i < Indent; i++) - { - OutChar(Buffer, '\t'); - } - - PrintFArgsList(Buffer, Format, Args); - va_end(Args); -} - -internal void -WriteAssemblyCommonOpen(gs_string* Buffer, char* Name, u32 Scale, v3 Center, u32 StripCount) -{ - WriteIndented(Buffer, 0, "assembly_name: \"%s\";\n", Name); - WriteIndented(Buffer, 0, "assembly_scale: %d;\n", Scale); - WriteIndented(Buffer, 0, "assembly_center: (%f, %f, %f);\n", Center.x, Center.y, Center.z); - WriteIndented(Buffer, 0, "led_strip_count: %d;\n", StripCount); -} - -internal void -WriteAssemblyUARTOpen(gs_string* Buffer, char* Name, u32 Scale, v3 Center, u32 StripCount, char* ComPort) -{ - WriteAssemblyCommonOpen(Buffer, Name, Scale, Center, StripCount); - WriteIndented(Buffer, 0, "output_mode: \"UART\";\n"); - - if (ComPort) - { - WriteIndented(Buffer, 0, "com_port: \"%s\";\n", ComPort); - } -} - -internal void -WriteAssemblySACNOpen(gs_string* Buffer, char* Name, u32 Scale, v3 Center, u32 StripCount) -{ - WriteAssemblyCommonOpen(Buffer, Name, Scale, Center, StripCount); - WriteIndented(Buffer, 0, "output_mode: \"SACN\";\n"); -} - -internal void -WriteLedStripOpen(gs_string* Buffer, u32 UARTChannel, char* UARTComPort, u32 SACNStartUniverse, u32 SACNStartChannel) -{ - WriteIndented(Buffer, 0, "led_strip:\n{\n"); - - // SACN - WriteIndented(Buffer, 1, "output_sacn: {\n"); - WriteIndented(Buffer, 2, "start_universe: %d;\n", SACNStartUniverse); - WriteIndented(Buffer, 2, "start_channel: %d;\n", SACNStartChannel); - WriteIndented(Buffer, 1, "};\n\n"); - - // UART - WriteIndented(Buffer, 1, "output_uart: {\n"); - WriteIndented(Buffer, 2, "channel: %d;\n", UARTChannel); - WriteIndented(Buffer, 2, "com_port: \"%s\";\n", UARTComPort); - WriteIndented(Buffer, 1, "};\n\n"); - -} - -internal void -WriteSegmentSequenceOpen(gs_string* Buffer, u32 SegmentCount) -{ - WriteIndented(Buffer, 1, "segment: {\n"); - WriteIndented(Buffer, 2, "point_placement_type: \"SegmentSequence\";\n"); - WriteIndented(Buffer, 2, "segment_sequence:\n"); - WriteIndented(Buffer, 2, "{\n"); - WriteIndented(Buffer, 3, "segment_count: %d;\n", SegmentCount); -} - -internal void -WriteSegmentSequenceSegment(gs_string* Buffer, v3 P0, v3 P1, u32 LedCount) -{ - WriteIndented(Buffer, 3, "segment: {\n"); - WriteIndented(Buffer, 4, "point_placement_type: \"InterpolatePoints\";\n"); - WriteIndented(Buffer, 4, "interpolate_points: {\n"); - WriteIndented(Buffer, 5, "start: (%f, %f, %f);\n", P0.x, P0.y, P0.z); - WriteIndented(Buffer, 5, "end: (%f, %f, %f);\n", P1.x, P1.y, P1.z); - WriteIndented(Buffer, 5, "led_count: %d;\n", LedCount); - WriteIndented(Buffer, 4, "};\n"); - WriteIndented(Buffer, 3, "};\n"); -} - -internal void -WriteSegmentSequenceClose(gs_string* Buffer) -{ - WriteIndented(Buffer, 2, "};\n"); - WriteIndented(Buffer, 1, "};\n"); -} - -internal void -WriteSegmentTagsOpen(gs_string* Buffer, u32 TagCount) -{ - WriteIndented(Buffer, 1, "tags_count: %d;\n", TagCount); -} - -internal void -WriteSegmentTag(gs_string* Buffer, char* TagName, char* TagValue) -{ - WriteIndented(Buffer, 1, "tag: {\n"); - WriteIndented(Buffer, 2, "name: \"%s\";\n", TagName); - WriteIndented(Buffer, 2, "value: \"%s\";\n", TagValue); - WriteIndented(Buffer, 1, "};\n"); - -} - -internal void -WriteSegmentTagsClose(gs_string* Buffer) -{ -} - -internal void -WriteLedStripClose(gs_string* Buffer) -{ - WriteIndented(Buffer, 0, "};\n"); -} - -#define SCULPTURE_GEN_H -#endif // SCULPTURE_GEN_H \ No newline at end of file diff --git a/src/serial_monitor/first.cpp b/src/serial_monitor/first.cpp deleted file mode 100644 index a87e7c7..0000000 --- a/src/serial_monitor/first.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// -// File: first.cpp -// Author: Peter Slattery -// Creation Date: 2020-10-10 -// -#ifndef FIRST_CPP - - -#include -#include - -#include "../gs_libs/gs_types.h" -#include "../gs_libs/gs_types.cpp" -#include "../app/engine/foldhaus_log.h" -global log_buffer* GlobalLogBuffer; - -#define DEBUG_TRACK_FUNCTION - - -//#include "../app/foldhaus_platform.h" -//#include "../gs_libs/gs_win32.cpp" -#include "../app/platform_win32/win32_foldhaus_utils.h" -#include "../app/platform_win32/win32_foldhaus_memory.h" -#include "../app/platform_win32/win32_foldhaus_fileio.h" -#include "../app/platform_win32/win32_foldhaus_serial.h" -#include "../app/platform_win32/win32_foldhaus_work_queue.h" - -#include "../app/engine/uart/foldhaus_uart.h" - -u8* -FindNextHeader(gs_data Data, u8* StartAt) -{ - u8* At = StartAt; - while (!(At[0] == 'U' && - At[1] == 'P' && - At[2] == 'X' && - At[3] == 'L') && - (u32)(At - Data.Memory) < Data.Size) - { - At++; - } - return At; -} - -void -CreateMessage(gs_data* Data, u8 Count) -{ - gs_memory_cursor WriteCursor = MemoryCursorCreateFromData(*Data); - - u32 Channels[] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 16, 17, 18, 19, 20, 21, 22, 23, - //40, 41, 42, 43, 44, 45, 46, 47, - }; - - u8* FirstHeaderAddr = 0; - - for (u32 j = 0; j < sizeof(Channels) / sizeof(u32); j++) - { - u32 ChannelIndex = Channels[j]; - uart_header* Header = MemoryCursorPushStruct(&WriteCursor, uart_header); - UART_FillHeader(Header, ChannelIndex, UART_SET_CHANNEL_WS2812); - - if (FirstHeaderAddr == 0) - { - FirstHeaderAddr = (u8*)Header; - } - - uart_channel* Channel = MemoryCursorPushStruct(&WriteCursor, uart_channel); - Channel->ElementsCount = 3; - Channel->ColorPackingOrder = 36; // 10010000 - Channel->PixelsCount = 300; - - for (u32 i = 0; i < Channel->PixelsCount; i++) - { - u8* Pixel = MemoryCursorPushArray(&WriteCursor, u8, 3); - Pixel[0] = Count; - Pixel[1] = 0; - Pixel[2] = 255 - Count; - } - - uart_footer* Footer = MemoryCursorPushStruct(&WriteCursor, uart_footer); - Footer->CRC = UART_CalculateCRC((u8*)Header, (u8*)(Footer)); - } - - uart_header* DrawAllHeader = MemoryCursorPushStruct(&WriteCursor, uart_header); - UART_FillHeader(DrawAllHeader, 255, UART_DRAW_ALL); - uart_footer* DrawAllFooter = - MemoryCursorPushStruct(&WriteCursor, uart_footer); - DrawAllFooter->CRC = UART_CalculateCRC((u8*)DrawAllHeader, (u8*)(DrawAllFooter)); - - Data->Size = ((u8*)DrawAllFooter - (u8*)FirstHeaderAddr) + sizeof(uart_footer); -} - -int main(int ArgCount, char** Args) -{ - gs_thread_context Ctx = Win32CreateThreadContext(); - GlobalLogBuffer = PushStruct(Ctx.Transient, log_buffer); - *GlobalLogBuffer = Log_Init(Ctx.Transient, 32); - - HANDLE SerialHandle = Win32SerialPort_Open("\\\\.\\COM9", Ctx.Transient); - Win32SerialPort_SetState(SerialHandle, 2000000, 8, 0, 1); - - gs_const_string OutFileName = ConstString("./serial_dump.data"); - - - if (false) - { - Win32SerialPort_SetRead(SerialHandle); - - gs_data Data = PushSize(Ctx.Transient, KB(32)); - - Win32SerialPort_SetRead(SerialHandle); - u32 ReadSize = Win32SerialPort_ReadMessageWhenReady(SerialHandle, Data); - - u8* SetChannelHeaderAddr = 0; - uart_header* SetChannelHeader = 0; - uart_header* DrawAllHeader = 0; - u8* ScanAt = Data.Memory; - do - { - ScanAt = FindNextHeader(Data, ScanAt); - uart_header* Header = (uart_header*)ScanAt; - - if (Header->RecordType == UART_SET_CHANNEL_WS2812) - { - printf("Set Channel:\n"); - printf(" Channel: %d\n", Header->Channel); - printf(" Pixels: %d\n", ((uart_channel*)(Header + 1))->PixelsCount); - if (!SetChannelHeader) - { - SetChannelHeaderAddr = (u8*)Header; - SetChannelHeader = Header; - } - } - - if (Header->RecordType == UART_DRAW_ALL) - { - printf("Draw All:\n"); - printf(" Channel: %d\n", Header->Channel); - if (!DrawAllHeader) - { - DrawAllHeader= Header; - } - } - - ScanAt += sizeof(uart_header); - }while(((u32)(ScanAt - Data.Memory + sizeof(uart_header)) < Data.Size)); - - uart_channel* Channel = (uart_channel*)(SetChannelHeader + 1); - - u8* DataStart = (u8*)(Channel + 1); - - uart_footer* Footer = (uart_footer*)(DataStart + (Channel->ElementsCount * Channel->PixelsCount)); - - u32 TestCRC = UART_CalculateCRC((u8*)SetChannelHeader, (u8*)(Footer)); - - uart_footer* DrawAllFooter = (uart_footer*)(DrawAllHeader + 1); - u32 DrawwAllCRC = UART_CalculateCRC((u8*)DrawAllHeader, (u8*)(DrawAllFooter)); - - HANDLE FileHandle = CreateFileA(OutFileName.Str, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (FileHandle != INVALID_HANDLE_VALUE) - { - DWORD BytesWritten = 0; - if (!WriteFile(FileHandle, Data.Memory, Data.Size, &BytesWritten, NULL)) - { - InvalidCodePath; - } - } - CloseHandle(FileHandle); - Win32SerialPort_Close(SerialHandle); - - } - else if (true) - { - gs_data Data = PushSize(Ctx.Transient, KB(32)); - - u8 Count = 0; - while(true) - { - CreateMessage(&Data, ++Count); - Win32SerialPort_Write(SerialHandle, Data); - Sleep(100); - } - } - else if (false) - { - gs_data Data = PushSize(Ctx.Transient, KB(32)); - gs_file File = Win32ReadEntireFile(Ctx.FileHandler, OutFileName, Data); - - gs_data Messages = {0}; - u8* ScanAt = Data.Memory; - ScanAt = FindNextHeader(Data, ScanAt); - uart_header* FirstHeader = (uart_header*)ScanAt; - ScanAt += sizeof(uart_header); - - uart_header* LastHeader = 0; - do - { - ScanAt = FindNextHeader(Data, ScanAt); - uart_header* Header = (uart_header*)ScanAt; - if (Header->RecordType == UART_DRAW_ALL) - { - LastHeader = Header; - } - ScanAt += sizeof(uart_header); - }while((u32)(ScanAt - Data.Memory) < Data.Size); - - u8* OnePastLastByte = ((u8*)(LastHeader + 1)) + sizeof(uart_footer); - - Messages.Memory = (u8*)FirstHeader; - Messages.Size = OnePastLastByte - Messages.Memory; - - while (true) - { - Win32SerialPort_Write(SerialHandle, Messages); - Sleep(100); - } - } - - return 0; -} - - -#define FIRST_CPP -#endif // FIRST_CPP \ No newline at end of file diff --git a/src/tests/interface_test.cpp b/src/tests/interface_test.cpp deleted file mode 100644 index 6eba9aa..0000000 --- a/src/tests/interface_test.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// -// File: interface_test.cpp -// Author: Peter Slattery -// Creation Date: 2020-11-15 -// -#ifndef INTERFACE_TEST_CPP - -global r32 TestSlider_Value = 5; -global r32 TestSlider_Min = 0; -global r32 TestSlider_Max = 10; -global bool TestToggle = true; -global r64 TestTextEntry = 3.1415f; - -internal void -InterfaceTest_Render(app_state* State, context* Context, render_command_buffer* RenderBuffer) -{ - ui_InterfaceReset(&State->Interface); - State->Interface.RenderBuffer = RenderBuffer; - State->Interface.WindowBounds = Context->WindowBounds; - - gs_string A = MakeString("TestRender Layout"); - -#if 0 - ui_PushLayout(&State->Interface, A); - { -#if 1 - TestTextEntry = ui_TextEntryR64(&State->Interface, MakeString("Spacer"), TestTextEntry); - ui_Button(&State->Interface, MakeString("A")); - TestSlider_Value = ui_RangeSlider(&State->Interface, MakeString("TestSlider"), TestSlider_Value, TestSlider_Min, TestSlider_Max); -#elif 0 - ui_PushLayout(&State->Interface, MakeString("Outer")); - { - for (u32 i = 0; i < 3; i++) - { - ui_Button(&State->Interface, MakeString("A")); - } - } - ui_PopLayout(&State->Interface); - - ui_BeginRow(&State->Interface, 2); - { - ui_PushLayout(&State->Interface, MakeString("TestLayout")); - { - for (u32 i = 0; i < 5; i++) - { - ui_Button(&State->Interface, MakeString("TestButon")); - } - } - ui_PopLayout(&State->Interface); - - ui_PushLayout(&State->Interface, MakeString("TestLayout")); - { - ui_Button(&State->Interface, MakeString("TestButon")); - TestToggle = ui_Toggle(&State->Interface, MakeString("Toggle"), TestToggle); - TestSlider_Value = ui_RangeSlider(&State->Interface, MakeString("TestSlider"), TestSlider_Value, TestSlider_Min, TestSlider_Max); - if (ui_BeginDropdown(&State->Interface, MakeString("TestDropdown"))) - { - ui_Button(&State->Interface, MakeString("TestButon")); - ui_Button(&State->Interface, MakeString("TestButon")); - ui_Button(&State->Interface, MakeString("TestButon")); - } - ui_EndDropdown(&State->Interface); - } - ui_PopLayout(&State->Interface); - } - ui_EndRow(&State->Interface); - - ui_PushLayout(&State->Interface, MakeString("Outer")); - { - for (u32 i = 0; i < 3; i++) - { - ui_Button(&State->Interface, MakeString("B")); - } - } - ui_PopLayout(&State->Interface); - -#else - ui_BeginList(&State->Interface, MakeString("Test List"), 10); - { - for (u32 i = 0; i < 32; i++) - { - ui_Button(&State->Interface, MakeString("Option")); - } - } - ui_EndList(&State->Interface); -#endif - - ui_PushOverlayLayout(&State->Interface, rect2{25, 25, 400, 200}, LayoutDirection_TopDown, MakeString("t")); - { - ui_Label(&State->Interface, PushStringF(State->Interface.PerFrameMemory, 256, "Mouse Pos - %f %f", State->Interface.Mouse.Pos.x, State->Interface.Mouse.Pos.y)); - Assert(State->Interface.PerFrameMemory->CursorList); - ui_Label(&State->Interface, PushStringF(State->Interface.PerFrameMemory, 256, "Hot - %lld | Active - %lld", - State->Interface.HotWidget.Id, State->Interface.ActiveWidget.Id)); - Assert(State->Interface.PerFrameMemory->CursorList); - ui_Label(&State->Interface, PushStringF(State->Interface.PerFrameMemory, 256, "Last Active - %lld", - State->Interface.LastActiveWidget.Id)); - Assert(State->Interface.PerFrameMemory->CursorList); - } - ui_PopLayout(&State->Interface); - } - ui_PopLayout(&State->Interface); -#endif -} - - -#define INTERFACE_TEST_CPP -#endif // INTERFACE_TEST_CPP \ No newline at end of file diff --git a/src/tests/memory_arena_tests.cpp b/src/tests/memory_arena_tests.cpp deleted file mode 100644 index 82d446f..0000000 --- a/src/tests/memory_arena_tests.cpp +++ /dev/null @@ -1,202 +0,0 @@ -internal u32 -NextRandom(u32* LastRandomValue) -{ - u32 Result = *LastRandomValue; - Result ^= Result << 13; - Result ^= Result >> 17; - Result ^= Result << 5; - *LastRandomValue = Result; - return Result; -} - -void -MemoryArenaTests() -{ - Test("Allocator") - { - gs_allocator A = CreatePlatformAllocator(); - - u8* Data = AllocArray(A, u8, 4096, "root"); - for (int i = 0; i < 4096; i++) Data[i] = (i % MaxU8); - bool Success = true; - for (int i = 0; i < 4096; i++) Success &= Data[i] == (i % MaxU8); - TestResult(Success); - - FreeArray(A, Data, u8, 4096); - TestResult(true); // TODO(PS): How do we test free? - } - - Test("Memory Cursor") - { - gs_allocator A = CreatePlatformAllocator(); - - u64 Size = 4096; - gs_data D = AllocData(A, Size, "root"); - gs_memory_cursor C = MemoryCursorCreate(D.Memory, D.Size); - - u64 RoomLeft = MemoryCursorRoomLeft(C); - TestResult(RoomLeft == Size); - TestResult(MemoryCursorHasRoom(C)); - - TestResult(MemoryCursorCanPush(C, 2048)); - TestResult(MemoryCursorCanPush(C, Size)); - TestResult(!MemoryCursorCanPush(C, Size + 1)); - - for (u64 i = 0; i < 2048; i++) - { - u8* Byte = MemoryCursorPushSize(&C, 1).Memory; - *Byte = (u8)(i % 256); - } - RoomLeft = MemoryCursorRoomLeft(C); - TestResult(RoomLeft == (Size - 2048)); - - MemoryCursorPopSize(&C, 2048); - TestResult(C.Position == 0); - - bool Success = true; - for (u64 i = 0; i < 2048; i++) - { - u8* Byte = MemoryCursorPushSize(&C, 1).Memory; - Success &= *Byte == (u8)(i % 256); - } - TestResult(Success); - } - - Test("Memory Arena") - { - gs_allocator Al = CreatePlatformAllocator(); - gs_memory_arena A = MemoryArenaCreate(128, 4, Al, 0, 0, "Test"); - - // NOTE(PS): We loop through this block 3 times - // 1. Make sure the arena works out of the box - // 2. Make sure the arena works the same way after clearing - // 3. Make sure the arena works the same way after freeing - for (int i = 0; i < 3; i++) - { - gs_data D0 = PushSize_(&A, 32, DEBUG_LOC); - TestResult(D0.Size == 32); - - // NOTE(PS): This should still result in 32 bytes - // because its going to align the Cursor after - // it allocates to a multiple of 4 bytes - gs_data D1 = PushSize_(&A, 30, DEBUG_LOC); - TestResult(D1.Size == 32); - - // NOTE(PS): Allocating bigger than the size remaining - // in the current cursor - gs_data D2 = PushSize_(&A, 128, DEBUG_LOC); - TestResult(D2.Size == 128); - TestResult(A.CursorsRoot != A.CursorsHead); - - // NOTE(PS): Because there is still room in cursor - // 0, the head of this gs_data should be one byte - // past the end of D1 - gs_data D3 = PushSize_(&A, 32, DEBUG_LOC); - TestResult(D3.Memory == D1.Memory + D1.Size); - - if (i == 0) - { - MemoryArenaClear(&A); - } else if (i == 1) { - MemoryArenaFree(&A); - } - } - } - - Test("Memory Arena - Push") - { - gs_allocator Al = CreatePlatformAllocator(); - gs_memory_arena A = MemoryArenaCreate(128, 8, Al, 0, 0, "Test"); - - // NOTE(PS): This makes sure that the Arena is moving its next allocation - // pointer forward the appropriate amount after each allocation. If it isnt' - // then Array1 should be overlapping with Array0 in the event that the arena - // doesn't push the pointer forward enough - u32* Array0 = PushArray(&A, u32, 32); - u32* Array1 = PushArray(&A, u32, 32); - - for (u32 i = 0; i < 32; i++) - { - Array0[i] = i; - Array1[i] = i * 4; - } - - bool Success = true; - for (u32 i = 0; i < 32; i++) - { - Success &= Array0[i] == i && Array1[i] == i * 4; - } - TestResult(Success); - - } - - int FreeCount = 0; - int ClearCount = 0; - - gs_debug_allocations_list* DEBUGAllocations = 0; - - Test("Memory Arena - Stress Test") - { - // NOTE(PS): We're going to create thousands of allocations - // on the allocator of varying sizes. We're also going to clear - // and free the arena at random times to make sure it all works. - - gs_allocator Al = CreatePlatformAllocator(); - gs_memory_arena A = MemoryArenaCreate(4096, 4, Al, 0, 0, "Test"); - - // NOTE(PS): This is an array of allocation sizes - // As we repeat the loop we will get values out of this array - // semi-randomly. - // * if the value is 0, we will clear the arena - // * if the value is 2, we will free the arena - // * otherwise we will push a value sized allocation on the arena - u64 RandomSizes[] = { 8, 32, 128, 93, 1256, 4098, 0, 1024, 7, 18, 967, 53, 1, 2 }; - u32 RandomSizesCount = sizeof(RandomSizes) / sizeof(u64); - - bool Success = true; - u32 RandomSeed = 1923; - for (u64 i = 0; i < (4096 * 14); i++) - { - NextRandom(&RandomSeed); - u32 SizeIndex = RandomSeed % RandomSizesCount; - u64 RandomSize = RandomSizes[SizeIndex]; - - if (RandomSize == 0) - { - MemoryArenaClear(&A); - ClearCount++; - } else if (RandomSize == 2) { - MemoryArenaFree(&A); - FreeCount++; - } else { - gs_data D = PushSize_(&A, RandomSize, DEBUG_LOC); - // NOTE(PS): This check has to be >= because the arena - // might have adjusted to maintain alignment on this - // allocation. - Success &= D.Size >= RandomSize; - } - } - - TestResult(Success); - - DEBUGAllocations = Al.DEBUGAllocList; - } - - printf("\tMemory Arena Cleared: %d times\n", ClearCount); - printf("\tMemory Arena Freed: %d times\n", FreeCount); - -#if 0 - printf("\n\nAllocations:\n"); - for (gs_debug_memory_allocation* ARecord = DEBUGAllocations->Root; - ARecord != 0; - ARecord = ARecord->Next) - { - printf("\t"); - printf("%lld\t%s:%d - %s\n", - ARecord->Size, - ARecord->Loc.File, - ARecord->Loc.Line, - ARecord->Loc.Function); - } -#endif -} \ No newline at end of file diff --git a/src/tests/sanity_tests.cpp b/src/tests/sanity_tests.cpp deleted file mode 100644 index 440d4e6..0000000 --- a/src/tests/sanity_tests.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// -// File: sanity_tests.cpp -// Author: Peter Slattery -// Creation Date: 2021-03-06 -// -#ifndef SANITY_TESTS_CPP - -#include -#include -#include "../gs_libs/gs_types.h" -#include "../gs_libs/gs_types.cpp" -#include "../gs_libs/gs_tests.h" - -#include "../gs_libs/gs_path.h" -#include "../gs_libs/gs_csv.h" - -#include "../app/platform_win32/win32_foldhaus_memory.h" -#include "./memory_arena_tests.cpp" - -gs_memory_arena Scratch = {}; - -bool StringTest (gs_const_string StrA, gs_const_string StrB) -{ - return StringsEqual(StrA, StrB); -} -bool StringTest (gs_string StrA, gs_string StrB) -{ - return StringsEqual(StrA, StrB); -} - -bool PathTest (char* In, char* Out) { - return StringsEqual(SanitizePath(ConstString(In), &Scratch), ConstString(Out)); -} - -global char* SampleCSV = R"FOO(Flower Primary Hue (0-365) Secondary Hue (0-365) Tertiary Hue (0-365) Homonyms -Flower A 55 32 128 foo, bar, blah, baz, whatever -Flower B 123 344 32 foo, bar, blah, baz, whatever -Flower C 55 32 128 foo, bar, blah, baz, whatever)FOO"; - -struct test_sll -{ - u32 Val; - test_sll* Next; -}; - -int main (int ArgCount, char** Args) -{ - gs_allocator Al = CreatePlatformAllocator(); - Scratch = MemoryArenaCreate(KB(4), Bytes(8), Al, 0, 0, "Scratch"); - - Test("SLL 1") - { - test_sll* Root = 0; - test_sll* Head = 0; - - test_sll* First = PushStruct(&Scratch, test_sll); - First->Val = 0; - SLLInit(Root, Head, First); - TestResult((Root == First) && (Head == First)); - - for (u32 i = 1; i < 4; i++) - { - test_sll* New = PushStruct(&Scratch, test_sll); - New->Val = i; - SLLPush(Head, New); - TestResult((Root == First) && (Head == New)); - } - - bool Success = true; - u32 i = 0; - for (test_sll* At = Root; - At && At->Next != 0; - SLLNext(At)) - { - Success &= (At->Val == i); - i += 1; - } - TestResult(Success); - } - - Test("SLL Push Or Init") - { - test_sll* Root = 0; - test_sll* Head = 0; - - test_sll* First = PushStruct(&Scratch, test_sll); - First->Val = 0; - SLLPushOrInit(Root, Head, First); - TestResult((Root == First) && (Head == First)); - - for (u32 i = 1; i < 4; i++) - { - test_sll* New = PushStruct(&Scratch, test_sll); - New->Val = i; - SLLPushOrInit(Root, Head, New); - TestResult((Root == First) && (Head == New)); - } - - bool Success = true; - u32 i = 0; - for (test_sll* At = Root; - At && At->Next != 0; - SLLNext(At)) - { - Success &= (At->Val == i); - i += 1; - } - TestResult(Success); - } - - Test("gs_string") - { - gs_string TestString = PushStringF(&Scratch, 256, "Hello there, Sailor!"); - - NullTerminate(&TestString); - TestResult(IsNullTerminated(TestString)); - - TestResult(StringTest(GetStringPrefix(TestString.ConstString, 5), ConstString("Hello"))); - TestResult(StringTest(GetStringPostfix(TestString.ConstString, 5), ConstString("ilor!"))); - TestResult(StringTest(GetStringAfter(TestString.ConstString, 13), ConstString("Sailor!"))); - TestResult(StringTest(GetStringBefore(TestString.ConstString, 5), ConstString("Hello"))); - TestResult(StringTest(Substring(TestString.ConstString, 5, 11), ConstString(" there"))); - - TestResult(FindFirst(TestString, 5, 'l') == 16); - TestResult(FindFirst(TestString, 0, 'k') == -1); - TestResult(FindLast(TestString, 10, 'l') == 3); - TestResult(FindLast(TestString, 'k') == -1); - - TestResult(FindFirstFromSet(TestString.ConstString, "re") == 1); - TestResult(FindFirstFromSet(TestString.ConstString, "er") == 1); - TestResult(FindFirstFromSet(TestString.ConstString, "bk") == -1); - TestResult(FindFirstFromSet(TestString.ConstString, "ek") == 1); - - TestResult(FindLastFromSet(TestString.ConstString, "re") == 18); - TestResult(FindLastFromSet(TestString.ConstString, "er") == 18); - TestResult(FindLastFromSet(TestString.ConstString, "bk") == -1); - TestResult(FindLastFromSet(TestString.ConstString, "rk") == 18); - - TestResult(StringContains(TestString.ConstString, ',')); - TestResult(!StringContains(TestString.ConstString, '@')); - TestResult(StringsEqual(TestString, TestString)); - - TestResult(StringEqualsCharArray(TestString, "Hello there, Sailor!")); - TestResult(!StringEqualsCharArray(TestString, "Hello there, Sailor")); - TestResult(!StringEqualsCharArray(TestString, "Foobar")); - - ReverseStringInPlace(&TestString); - TestResult(StringTest(TestString, MakeString("!roliaS ,ereht olleH"))); - ReverseStringInPlace(&TestString); - - TestResult(ParseUInt(ConstString("532")) == 532); - TestResult(ParseInt(ConstString("-1234567890")) == -1234567890); - TestResult(ParseFloat(ConstString("-12345.6789")) == -12345.6789); - TestResult(ParseFloat(ConstString("-1")) == -1); - TestResult(ParseFloat(ConstString("-.035")) == -.035); - - TestString.Length = 0; - U64ToASCII(&TestString, 53298, 10); - TestResult(StringTest(TestString.ConstString, ConstString("53298"))); - - TestString.Length = 0; - R64ToASCII(&TestString, -145732.321, 2); - TestResult(StringTest(TestString.ConstString, ConstString("-145732.32"))); - } - - Test("gs_path.h") - { - TestResult(PathTest(".", ".")); - TestResult(PathTest(".\\", ".\\")); - TestResult(PathTest("./", ".\\")); - TestResult(PathTest("./../", "..\\")); - TestResult(PathTest("C:/users/pslattery\\test.foo", "C:\\users\\pslattery\\test.foo")); - TestResult(PathTest("./test/../foo.bar", ".\\foo.bar")); - TestResult(PathTest("C:\\hello\\world\\.\\test", "C:\\hello\\world\\test")); - } - - Test("gs_csv.h") - { - gs_const_string TestCSV = ConstString(SampleCSV); - gscsv_sheet Sheet = CSV_Parse(TestCSV, { '\t' }, &Scratch); - - gs_const_string Cell = CSVSheet_GetCell(Sheet, 0, 0); - TestResult(StringsEqual(Cell, ConstString("Flower"))); - - Cell = CSVSheet_GetCell(Sheet, 1, 1); - TestResult(StringsEqual(Cell, ConstString("55"))); - - Cell = CSVSheet_GetCell(Sheet, 4, 1); - TestResult(StringsEqual(Cell, ConstString("foo, bar, blah, baz, whatever"))); - - Cell = CSVSheet_GetCell(Sheet, 4, 3); - TestResult(StringsEqual(Cell, ConstString("foo, bar, blah, baz, whatever"))); - } - - MemoryArenaTests(); - - return 0; -} - - -#define SANITY_TESTS_CPP -#endif // SANITY_TESTS_CPP \ No newline at end of file diff --git a/src/tests/test_patterns.h b/src/tests/test_patterns.h deleted file mode 100644 index 6d4d0c6..0000000 --- a/src/tests/test_patterns.h +++ /dev/null @@ -1,150 +0,0 @@ -// -// File: test_patterns.h -// Author: Peter Slattery -// Creation Date: 2020-01-01 -// -#ifndef TEST_PATTERNS_H - -GSMetaTag(node_struct); -struct solid_color_data -{ - GSMetaTag(node_input); - v4 Color; - - GSMetaTag(node_output); - color_buffer Result; -}; - -GSMetaTag(node_proc); // :TagParamsForNodeParamStructs -void SolidColorProc(solid_color_data* Data) -{ - u8 R = (u8)Clamp(0.f, (Data->Color.r * 255), 255.f); - u8 G = (u8)Clamp(0.f, (Data->Color.g * 255), 255.f); - u8 B = (u8)Clamp(0.f, (Data->Color.b * 255), 255.f); - - for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++) - { - Assert(LedIndex >= 0 && LedIndex < Data->Result.LEDCount); - - Data->Result.Colors[LedIndex].R = R; - Data->Result.Colors[LedIndex].G = G; - Data->Result.Colors[LedIndex].B = B; - } -} - -GSMetaTag(node_struct); -struct vertical_color_fade_data -{ - GSMetaTag(node_input); - v4 Color; - - GSMetaTag(node_input); - r32 Min; - - GSMetaTag(node_input); - r32 Max; - - GSMetaTag(node_output); - color_buffer Result; -}; - -GSMetaTag(node_proc); // :TagParamsForNodeParamStructs -void VerticalColorFadeProc(vertical_color_fade_data* Data) -{ - r32 R = (Data->Color.r * 255); - r32 G = (Data->Color.g * 255); - r32 B = (Data->Color.b * 255); - - r32 Range = Data->Max - Data->Min; - - - for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++) - { - Assert(LedIndex >= 0 && LedIndex < Data->Result.LEDCount); - v4 LedPosition = Data->Result.LedPositions[LedIndex]; - - r32 Amount = (LedPosition.y - Data->Min) / Range; - Amount = Clamp01(1.0f - Amount); - - Data->Result.Colors[LedIndex].R = (u8)(R * Amount); - Data->Result.Colors[LedIndex].G = (u8)(G * Amount); - Data->Result.Colors[LedIndex].B = (u8)(B * Amount); - } -} - -// Original -> DiscPatterns.pde : Revolving Discs -GSMetaTag(node_struct); -struct revolving_discs_data -{ - GSMetaTag(node_input); - r32 Rotation; - - GSMetaTag(node_input); - r32 ThetaZ; - - GSMetaTag(node_input); - r32 ThetaY; - - GSMetaTag(node_input); - r32 DiscWidth; - - GSMetaTag(node_input); - r32 InnerRadius; - - GSMetaTag(node_input); - r32 OuterRadius; - - GSMetaTag(node_input); - v4 Color; - - GSMetaTag(node_output); - color_buffer Result; -}; - -GSMetaTag(node_proc); // :TagParamsForNodeParamStructs -void RevolvingDiscs(revolving_discs_data* Data) -{ - DEBUG_TRACK_FUNCTION; - - pixel Color = { - (u8)(Clamp01(Data->Color.r) * 255), - (u8)(Clamp01(Data->Color.g) * 255), - (u8)(Clamp01(Data->Color.b) * 255), - }; - - v4 Center = v4{0, 0, 0, 1}; - v4 Normal = v4{CosR32(Data->ThetaZ), 0, SinR32(Data->ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1 - v4 Right = V4Cross(Normal, v4{0, 1, 0, 0}); - - v4 FrontCenter = Center + (Normal * Data->DiscWidth); - v4 BackCenter = Center - (Normal * Data->DiscWidth); - - r32 OuterRadiusSquared = Data->OuterRadius * Data->OuterRadius; - r32 InnerRadiusSquared = Data->InnerRadius * Data->InnerRadius; - - for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++) - { - v4 Position = Data->Result.LedPositions[LedIndex]; - - v4 ToFront = Position + FrontCenter; - v4 ToBack = Position + BackCenter; - - r32 ToFrontDotNormal = V4Dot(ToFront, Normal); - r32 ToBackDotNormal = V4Dot(ToBack, Normal); - - ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000); - ToBackDotNormal = Clamp01(ToBackDotNormal * 1000); - - r32 SqDistToCenter = V4MagSquared(Position); - if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared) - { - if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0)) - { - Data->Result.Colors[LedIndex] = Color; - } - } - } -} - -#define TEST_PATTERNS_H -#endif // TEST_PATTERNS_H \ No newline at end of file diff --git a/src/todo.txt b/src/todo.txt deleted file mode 100644 index c2ef7b1..0000000 --- a/src/todo.txt +++ /dev/null @@ -1,133 +0,0 @@ -TODO FOLDHAUS - - -- engine environment - - primary color -- default controller - - gets its own update function - - has access to the engine state - - can select animations - - change playback speed, primary color -- user space controller -- socket listener - - -STREAM #1: 3D Overhaul -- Rendering (Working on this elsewhere) - - OpenGL 3 - - Vertex Buffers - - Clipping in shaders - - Layers - - Lighting - -- Camera - - pan - - zoom - - leds always face camera - -- Sculptures - - cache led vertex buffers - - custom sculpture update functions (for motion) - - editing sculpture files (change universe output) - - motion - -- Sculpture View - - mouse spatial interaction - handles, and hover for info - - debug capabilities (toggle strip/led/universe colors) - -- Internal Log File - NOTE: This should not be a part of the debug system - - Save output log to a file continuously - - Have a window where we can view the log within the app - - Create a bar that displays the most recent error message - - :ErrorLogging - -- Animation System - - layers - - layer masks by sculpture - - layer masks by tag / value - - interface for animation system - - add/remove layers - - select blend modes - - change which layer an animation is on - - setting start and end of timeline (how long is a loop) - - clips can have parameters that drive them? - - clips cannot overlap eachother on the same layer - -- Serialization - - saving scenes - - saving projects - -STRAM #4: Completeness - -- Platform Layer - - Mac Platform Layer - -- Make sure it works without building in Debug Mode - -- Network - - Handle Error Cases - - Handle connecting a sculpture after launch - - Artnet - - Universe offsets (per sculpture) - -- Interface - - text input - - lister with icon options - -- Asset Loading - - Need to figure out which textures are currently in graphics memory and which need to be resubmitted - - images - - icon system - integrate with interface - -- Settings - -Assembly -> SACN interface -- need to create a data structure in CreateDMXBuffers that prevents duplication of DMXBuffers. -- - thinking about a dictionary. Key is Universe, length is 256, create parallel arrays as necessary - -BUGS -- Typing a period into a float value doesn't register. Problem here is that we arent' translating key presses into characters at the win32 layer. Need to do that. - -Hardening -- Then we want to think about separating out mode render functions from mode update functions. Not sure its necessary but having something that operates like an update funciton but is called render is weird. Might want some sort of coroutine functionality in place, where modes can add and remove optional, parallel -update functions -- memory visualization -- separate rendering thread - - -UI Improvements -- shift drag to 10x drag speed -- Text editing improvements -- - draw cursor in node field under active edit -- - better/intelligent zero padding - -Application -- More efficient HSV <-> RGB - -Development -- Fix your scope time tracker to account for threads. -- Nest scope times so you can see totals/dig in - -Optimization -- patterns are asking to be multithreaded - - OOH I KNOW HOW TO DO THIS NOW!!! - each layer gets calculated independently, and combined - so just do each layer on its own thread, then combine as they are finished -- probably want to convert as much color functions to use u32 Packed Colors -- - Probably want to think about this more. What about supporting different color depths -- for different output devices? - -Name -- Splash screen (like blender) (thisll be fun) -- - Image importer (stb image? or find a png > bmp converter for the image you have) -- - Display on startup - -STREAM #0: Metaprogramming -- Metaprogramming - - fix memory layout (remeber to profile before and after) -- Make everything truly platform agnostic - - Application DLL - - math.h: present for trig functions (though this is part of the c-std lib, so it should be everywhere) - - windows.h: only thing left is InterlockedIncrement and InterlockedAdd - - Meta Layer - - ??? diff --git a/src/todo_done.txt b/src/todo_done.txt deleted file mode 100644 index ac67406..0000000 --- a/src/todo_done.txt +++ /dev/null @@ -1,57 +0,0 @@ -x blending between animation - -x saving animation timelines -x Buckets & Lists - x On second thought, I just really don't like these. Lets get rid of them, and put custom structures in place - - -BUGS -x if there is nothing in the filtered list when searching for a node, hitting enter still selects one -x Search lister - returning from a filtered list that has zero elements to one that has a few, hotItem = -1 - -Intermediate Lifetime Memory & Operations -x Intermediate lifetime memory arena -x Temporary memory region = a multi frame operation -x Concept of an operation - temporary memory + interface command registry -x Allow one operation at a time at first -x Push/pop operations on a list? -- Current Operations: -- - View Sculpture (this might be an exception since its so central) -- x View/Edit Nodes -- x Add Node (needs nesting) -- x View SACN -x make modes work with hot code reloading: rather than do the whole series of initialize command registry, -x and manually adding each command, store the commands as an array, and auto iterate over them when you -x push the mode on the mode stack -x decided I don't like storing NodeRenderSettings in each operation mode. Probably want to put it back in x app_state - -UI Improvements -x print node field names on hover or on the node - -API Improvements -x Clean up DrawString... good lord -x Add Text Alignment to DrawString -x Move nodes over to referencing eachother based on a UID system - -/Debug -x Make debug scope tracking thread safe - was throwing an error in stringsequal but that stopped. -x Keep an eye out. -x Sort Scope Tracking -x got the profiler view rudimentarily working -x reimplement the scope list view. -x start tracking debug interface state somehow and it would be good to separate that out from global debug state - -Switch To Nodes -x basic node elements -x output should generate a node_specification -x go back to calling SpecificationIndex Type -- x don't pull node names into the struct, just reference the specification -- x separate storage of node headers from connections -- x connections shouldn't store their own values, they should just point into permanent storage - -Hardening -x input context changes - -Animation Timeline -x drag ends of animation clips to change start and end times -x click to drag time marker \ No newline at end of file diff --git a/src_v2/tools/convert_csv.c b/src/tools/convert_csv.c similarity index 100% rename from src_v2/tools/convert_csv.c rename to src/tools/convert_csv.c diff --git a/src_v2/tools/convert_csv_build.sh b/src/tools/convert_csv_build.sh similarity index 100% rename from src_v2/tools/convert_csv_build.sh rename to src/tools/convert_csv_build.sh diff --git a/src_v2/user_space/incenter_gen_cities.h b/src/user_space/incenter_gen_cities.h similarity index 100% rename from src_v2/user_space/incenter_gen_cities.h rename to src/user_space/incenter_gen_cities.h diff --git a/src_v2/user_space/incenter_interface_connection.c b/src/user_space/incenter_interface_connection.c similarity index 100% rename from src_v2/user_space/incenter_interface_connection.c rename to src/user_space/incenter_interface_connection.c diff --git a/src_v2/user_space/incenter_interface_connection.h b/src/user_space/incenter_interface_connection.h similarity index 100% rename from src_v2/user_space/incenter_interface_connection.h rename to src/user_space/incenter_interface_connection.h diff --git a/src_v2/user_space/incenter_live_answers.c b/src/user_space/incenter_live_answers.c similarity index 97% rename from src_v2/user_space/incenter_live_answers.c rename to src/user_space/incenter_live_answers.c index 1e05ab4..eb5196b 100644 --- a/src_v2/user_space/incenter_live_answers.c +++ b/src/user_space/incenter_live_answers.c @@ -158,7 +158,7 @@ live_answers_save(Live_Answers_File file, Live_Answers_File_Bucket* new_bucket) s32 size_written = fwrite((void*)existing_data.base, 1, existing_data.size, fh); if (size_written != existing_data.size) { printf("Unable to write full file: %.*s\n", str_varg(file.path)); - printf(" Size Needed: %lu, Size Written: %d\n", existing_data.size, size_written); + printf(" Size Needed: %llu, Size Written: %d\n", existing_data.size, size_written); } #else if (!os_file_write(fh, existing_data)) { @@ -176,7 +176,7 @@ live_answers_save(Live_Answers_File file, Live_Answers_File_Bucket* new_bucket) size_written = fwrite(new_data.base, 1, new_data.size, fh); if (size_written != new_data.size) { printf("Unable to add new data to file %.*s\n", str_varg(file.path)); - printf(" Size Needed: %lu, Size Written: %d\n", new_data.size, size_written); + printf(" Size Needed: %llu, Size Written: %d\n", new_data.size, size_written); } #else if (!os_file_write(fh, new_data)) { @@ -233,7 +233,7 @@ live_answers_input_u32(Incenter_State* ins, Incenter_Scene scene, u32 value) live_answers_save(file, new_bucket); - 4scratch_release(scratch); + scratch_release(scratch); } internal void diff --git a/src_v2/user_space/incenter_patterns.c b/src/user_space/incenter_patterns.c similarity index 100% rename from src_v2/user_space/incenter_patterns.c rename to src/user_space/incenter_patterns.c diff --git a/src_v2/user_space/incenter_scenes.c b/src/user_space/incenter_scenes.c similarity index 100% rename from src_v2/user_space/incenter_scenes.c rename to src/user_space/incenter_scenes.c diff --git a/src_v2/user_space/incenter_scenes.h b/src/user_space/incenter_scenes.h similarity index 100% rename from src_v2/user_space/incenter_scenes.h rename to src/user_space/incenter_scenes.h diff --git a/src_v2/user_space/incenter_secondary_patterns.c b/src/user_space/incenter_secondary_patterns.c similarity index 100% rename from src_v2/user_space/incenter_secondary_patterns.c rename to src/user_space/incenter_secondary_patterns.c diff --git a/src_v2/user_space/incenter_user_space.c b/src/user_space/incenter_user_space.c similarity index 100% rename from src_v2/user_space/incenter_user_space.c rename to src/user_space/incenter_user_space.c diff --git a/src_v2/user_space/incenter_user_space.h b/src/user_space/incenter_user_space.h similarity index 100% rename from src_v2/user_space/incenter_user_space.h rename to src/user_space/incenter_user_space.h