Cleaning up, converting over to using new gs files.

This commit is contained in:
Peter Slattery 2020-07-18 12:00:14 -07:00
parent 295a5aaaa0
commit 50c2ef9290
55 changed files with 9546 additions and 3555 deletions

View File

@ -16,7 +16,7 @@ pushd %BuildPath%
del *.pdb > NUL 2> NUL del *.pdb > NUL 2> NUL
REM Run the Preprocessor REM Run the Preprocessor
%MetaProgramPath%\foldhaus_meta.exe %SourceCodePath%\foldhaus_app.cpp REM %MetaProgramPath%\foldhaus_meta.exe %SourceCodePath%\foldhaus_app.cpp
echo WAITING FOR PDB TO WRITE > lock.tmp echo WAITING FOR PDB TO WRITE > lock.tmp

View File

@ -31,7 +31,7 @@ enum blend_mode
struct anim_layer struct anim_layer
{ {
string Name; gs_string Name;
blend_mode BlendMode; blend_mode BlendMode;
}; };
@ -39,7 +39,7 @@ struct anim_layer
#define ANIMATION_SYSTEM_BLOCKS_MAX 128 #define ANIMATION_SYSTEM_BLOCKS_MAX 128
struct animation_system struct animation_system
{ {
memory_arena* Storage; gs_memory_arena* Storage;
gs_list<animation_block> Blocks; gs_list<animation_block> Blocks;
anim_layer* Layers; anim_layer* Layers;
@ -75,7 +75,7 @@ FrameIsInRange(s32 Frame, frame_range Range)
internal u32 internal u32
GetFrameCount(frame_range Range) GetFrameCount(frame_range Range)
{ {
u32 Result = (u32)GSMax(0, Range.Max - Range.Min); u32 Result = (u32)Max(0, Range.Max - Range.Min);
return Result; return Result;
} }
@ -133,7 +133,7 @@ RemoveAnimationBlock(gs_list_handle AnimationBlockHandle, animation_system* Anim
// Layers // Layers
internal u32 internal u32
AddLayer (string Name, animation_system* AnimationSystem, blend_mode BlendMode = BlendMode_Overwrite) AddLayer (gs_string Name, animation_system* AnimationSystem, blend_mode BlendMode = BlendMode_Overwrite)
{ {
// NOTE(Peter): If this assert fires its time to make the layer buffer system // NOTE(Peter): If this assert fires its time to make the layer buffer system
// resizable. // resizable.
@ -144,7 +144,7 @@ AddLayer (string Name, animation_system* AnimationSystem, blend_mode BlendMode =
anim_layer* NewLayer = AnimationSystem->Layers + Result; anim_layer* NewLayer = AnimationSystem->Layers + Result;
*NewLayer = {0}; *NewLayer = {0};
NewLayer->Name = MakeString(PushArray(AnimationSystem->Storage, char, Name.Length), Name.Length); NewLayer->Name = MakeString(PushArray(AnimationSystem->Storage, char, Name.Length), Name.Length);
CopyStringTo(Name, &NewLayer->Name); PrintF(&NewLayer->Name, "%S", Name);
NewLayer->BlendMode = BlendMode; NewLayer->BlendMode = BlendMode;
return Result; return Result;
} }

View File

@ -28,7 +28,7 @@ enum assembly_field
AssemblyField_Count, AssemblyField_Count,
}; };
global_variable char* AssemblyFieldIdentifiers[] = { global char* AssemblyFieldIdentifiers[] = {
"assembly_name", // AssemblyField_AssemblyName "assembly_name", // AssemblyField_AssemblyName
"assembly_scale", // AssemblyField_AssemblyScale "assembly_scale", // AssemblyField_AssemblyScale
"led_strip_count", // AssemblyField_LedStripCount "led_strip_count", // AssemblyField_LedStripCount
@ -52,20 +52,32 @@ global_variable char* AssemblyFieldIdentifiers[] = {
"value", // AssemblyField_Value "value", // AssemblyField_Value
}; };
struct assembly_error_list
{
gs_string String;
assembly_error_list* Next;
};
struct assembly_tokenizer struct assembly_tokenizer
{ {
string Text; gs_string Text;
char* At; char* At;
gs_const_string FileName;
u32 LineNumber; u32 LineNumber;
bool ParsingIsValid; bool ParsingIsValid;
gs_memory_arena* ErrorArena;
assembly_error_list* ErrorsRoot;
assembly_error_list* ErrorsTail;
}; };
internal bool internal bool
AtValidPosition(assembly_tokenizer* T) AtValidPosition(assembly_tokenizer* T)
{ {
bool Result = ((T->At - T->Text.Memory) < T->Text.Length); u64 Offset = T->At - T->Text.Str;
bool Result = (Offset < T->Text.Length);
return Result; return Result;
} }
@ -88,6 +100,16 @@ EatWhitespace(assembly_tokenizer* T)
} }
} }
internal void
EatToNewLine(assembly_tokenizer* T)
{
while(AtValidPosition(T) && !IsNewline(T->At[0]))
{
AdvanceChar(T);
}
EatWhitespace(T);
}
internal bool internal bool
AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value) AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
{ {
@ -118,6 +140,22 @@ AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
return Result; return Result;
} }
internal void
TokenizerPushError(assembly_tokenizer* T, char* ErrorString)
{
// NOTE(Peter): We can make this more expressive if we need to
assembly_error_list* Error = PushStruct(T->ErrorArena, assembly_error_list);
Error->String = PushString(T->ErrorArena, 512);
PrintF(&Error->String, "%S(%d): %s", T->FileName, T->LineNumber, ErrorString);
SLLPushOrInit(T->ErrorsRoot, T->ErrorsTail, Error);
T->ParsingIsValid = false;
// NOTE(Peter): I'm not sure this is the best idea, but at least this way,
// if there's multiple errors, you'll get a number of them, rather than
// a bunch of erroneous errors happening on the same line
EatToNewLine(T);
}
internal bool internal bool
ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T) ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
{ {
@ -130,12 +168,12 @@ ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Field identifier is missing a colon");
} }
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Field Identifier Invalid");
} }
return Result; return Result;
} }
@ -150,15 +188,15 @@ ReadFieldEnd(assembly_tokenizer* T)
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Missing a semicolon");
} }
return Result; return Result;
} }
internal string internal gs_string
ReadString(assembly_tokenizer* T) ReadString(assembly_tokenizer* T)
{ {
string Result = {}; gs_string Result = {};
if (AdvanceIfTokenEquals(T, "\"")) if (AdvanceIfTokenEquals(T, "\""))
{ {
char* StringStart = T->At; char* StringStart = T->At;
@ -166,32 +204,36 @@ ReadString(assembly_tokenizer* T)
{ {
T->At++; T->At++;
} }
Result.Memory = StringStart; Result.Str = StringStart;
Result.Max = T->At - StringStart; Result.Size = T->At - StringStart;
Result.Length = Result.Max; Result.Length = Result.Size;
if (AdvanceIfTokenEquals(T, "\"")) if (AdvanceIfTokenEquals(T, "\""))
{ {
// Success // Success
} }
else else
{ {
// TODO(Peter): Error TokenizerPushError(T, "String not closed with a \"");
} }
} }
else
{
TokenizerPushError(T, "Expecting a string, but none was found");
}
return Result; return Result;
} }
internal string internal gs_string
GetNumberString(assembly_tokenizer* T) GetNumberString(assembly_tokenizer* T)
{ {
string Result = {}; gs_string Result = {};
Result.Memory = T->At; Result.Str = T->At;
while(AtValidPosition(T) && IsNumericExtended(T->At[0])) while(AtValidPosition(T) && IsNumericExtended(T->At[0]))
{ {
AdvanceChar(T); AdvanceChar(T);
} }
Result.Length = T->At - Result.Memory; Result.Length = T->At - Result.Str;
Result.Max = Result.Length; Result.Size = Result.Length;
return Result; return Result;
} }
@ -199,9 +241,8 @@ internal r32
ReadFloat(assembly_tokenizer* T) ReadFloat(assembly_tokenizer* T)
{ {
r32 Result = 0; r32 Result = 0;
string NumberString = GetNumberString(T); gs_string NumberString = GetNumberString(T);
parse_result ParsedFloat = ParseFloat(StringExpand(NumberString)); Result = (r32)ParseFloat(NumberString.ConstString);
Result = ParsedFloat.FloatValue;
return Result; return Result;
} }
@ -209,28 +250,23 @@ internal s32
ReadInt(assembly_tokenizer* T) ReadInt(assembly_tokenizer* T)
{ {
s32 Result = 0; s32 Result = 0;
string NumberString = GetNumberString(T); gs_string NumberString = GetNumberString(T);
parse_result ParsedInt = ParseSignedInt(StringExpand(NumberString)); Result = (r32)ParseInt(NumberString.ConstString);
Result = ParsedInt.SignedIntValue;
return Result; return Result;
} }
internal string internal gs_string
ReadStringField(assembly_field Field, assembly_tokenizer* T, memory_arena* Arena) ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Arena)
{ {
string Result = {}; gs_string Result = {};
if (ReadFieldIdentifier(Field, T)) if (ReadFieldIdentifier(Field, T))
{ {
string ExistingString = ReadString(T); gs_string ExistingString = ReadString(T);
if (ReadFieldEnd(T)) if (ReadFieldEnd(T))
{ {
// Success // Success
Result = PushString(Arena, ExistingString.Length); Result = PushString(Arena, ExistingString.Length);
CopyStringTo(ExistingString, &Result); PrintF(&Result, "%S", ExistingString);
}
else
{
T->ParsingIsValid = false;
} }
} }
return Result; return Result;
@ -290,22 +326,22 @@ ReadV3Field(assembly_field Field, assembly_tokenizer* T)
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Vector 3 doesn't end with a ')'");
} }
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Vector 3: unable to read a field");
} }
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Vector 3: unable to read a field");
} }
} }
else else
{ {
T->ParsingIsValid = false; TokenizerPushError(T, "Vector 3: unable to read a field");
} }
} }
return Result; return Result;
@ -333,14 +369,18 @@ ReadStructClosing(assembly_tokenizer* T)
} }
internal bool internal bool
ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient) ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileText, gs_memory_arena* Transient)
{ {
Assembly->LedCountTotal = 0; Assembly->LedCountTotal = 0;
r32 Value = ParseFloat(ConstString("-2.355"));
assembly_tokenizer Tokenizer = {}; assembly_tokenizer Tokenizer = {};
Tokenizer.Text = FileText; Tokenizer.Text = FileText;
Tokenizer.At = Tokenizer.Text.Memory; Tokenizer.At = Tokenizer.Text.Str;
Tokenizer.ParsingIsValid = true; Tokenizer.ParsingIsValid = true;
Tokenizer.ErrorArena = Transient;
Tokenizer.FileName = FileName;
Assembly->Name = ReadStringField(AssemblyField_AssemblyName, &Tokenizer, &Assembly->Arena); Assembly->Name = ReadStringField(AssemblyField_AssemblyName, &Tokenizer, &Assembly->Arena);
Assembly->Scale = ReadFloatField(AssemblyField_AssemblyScale, &Tokenizer); Assembly->Scale = ReadFloatField(AssemblyField_AssemblyScale, &Tokenizer);
@ -358,7 +398,7 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
StripAt->StartChannel = ReadIntField(AssemblyField_StartChannel, &Tokenizer); StripAt->StartChannel = ReadIntField(AssemblyField_StartChannel, &Tokenizer);
// TODO(Peter): Need to store this // TODO(Peter): Need to store this
string PointPlacementType = ReadStringField(AssemblyField_PointPlacementType, &Tokenizer, &Assembly->Arena); gs_string PointPlacementType = ReadStringField(AssemblyField_PointPlacementType, &Tokenizer, &Assembly->Arena);
// TODO(Peter): Switch on value of PointPlacementType // TODO(Peter): Switch on value of PointPlacementType
if (ReadStructOpening(AssemblyField_InterpolatePoints, &Tokenizer)) if (ReadStructOpening(AssemblyField_InterpolatePoints, &Tokenizer))
{ {
@ -367,6 +407,10 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
if (!ReadStructClosing(&Tokenizer)) if (!ReadStructClosing(&Tokenizer))
{ {
Tokenizer.ParsingIsValid = false; Tokenizer.ParsingIsValid = false;
// TODO(Peter): @ErrorHandling
// Have this function prepend the filename and line number.
// Create an error display popup window, or an error log window that takes over a panel automatically
// TokenizerPushError(&Tokenizer, "Unable to read
} }
} }
@ -380,31 +424,31 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
v2_tag* TagAt = StripAt->Tags + Tag; v2_tag* TagAt = StripAt->Tags + Tag;
if (ReadStructOpening(AssemblyField_Tag, &Tokenizer)) if (ReadStructOpening(AssemblyField_Tag, &Tokenizer))
{ {
// TODO(Peter): Need to store the string somewhere we can look it up for display in the interface // 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 // right now they are stored in temp memory and won't persist
string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient); gs_string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient);
string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient); gs_string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient);
TagAt->NameHash = HashString(TagName); TagAt->NameHash = HashDJB2ToU32(StringExpand(TagName));
TagAt->ValueHash = HashString(TagValue); TagAt->ValueHash = HashDJB2ToU32(StringExpand(TagValue));
if (!ReadStructClosing(&Tokenizer)) if (!ReadStructClosing(&Tokenizer))
{ {
Tokenizer.ParsingIsValid = false; TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
} }
} }
else else
{ {
Tokenizer.ParsingIsValid = false; TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
} }
} }
if (!ReadStructClosing(&Tokenizer)) if (!ReadStructClosing(&Tokenizer))
{ {
Tokenizer.ParsingIsValid = false; TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
} }
} }
else else
{ {
Tokenizer.ParsingIsValid = false; TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
} }
} }

View File

@ -100,10 +100,10 @@ NODE_PROC(SinWave, sin_wave_data)
Data->Accumulator -= Data->Period; Data->Accumulator -= Data->Period;
} }
r32 ActualMin = GSMin(Data->Min, Data->Max); r32 ActualMin = Min(Data->Min, Data->Max);
r32 ActualMax = GSMax(Data->Min, Data->Max); r32 ActualMax = Max(Data->Min, Data->Max);
r32 SinResult = GSSin((Data->Accumulator / Data->Period) * PI * 2); r32 SinResult = SinR32((Data->Accumulator / Data->Period) * PiR32 * 2);
Data->Result = GSRemap(SinResult, -1.f, 1.f, ActualMin, ActualMax); Data->Result = RemapR32(SinResult, -1.f, 1.f, ActualMin, ActualMax);
} }
else else
{ {

View File

@ -15,7 +15,7 @@ struct visual_port
{ {
gs_list_handle SparseNodeHandle; gs_list_handle SparseNodeHandle;
u32 PortIndex; u32 PortIndex;
rect PortBounds; rect2 PortBounds;
}; };
struct visual_connection struct visual_connection
@ -57,7 +57,7 @@ struct node_graph_state
{ {
v2 ViewOffset; v2 ViewOffset;
memory_arena LayoutMemory; gs_memory_arena LayoutMemory;
node_layout Layout; node_layout Layout;
b32 LayoutIsDirty; b32 LayoutIsDirty;
@ -128,7 +128,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndConnectNodesOperation)
for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; p++) for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; p++)
{ {
visual_port VisualPort = GraphState->Layout.VisualPorts[p]; visual_port VisualPort = GraphState->Layout.VisualPorts[p];
rect ViewAdjustedBounds = gs_RectOffsetByVector(VisualPort.PortBounds, GraphState->ViewOffset); rect2 ViewAdjustedBounds = gs_RectOffsetByVector(VisualPort.PortBounds, GraphState->ViewOffset);
if (gs_PointIsInRect(Mouse.Pos, ViewAdjustedBounds)) if (gs_PointIsInRect(Mouse.Pos, ViewAdjustedBounds))
{ {
visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort; visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort;
@ -196,7 +196,7 @@ NodeGraph_Cleanup(panel* Panel, app_state* State)
} }
internal void internal void
DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer* RenderBuffer) DrawGrid (v2 Offset, v2 GridSquareDim, rect2 PanelBounds, render_command_buffer* RenderBuffer)
{ {
r32 LineValue = .16f; r32 LineValue = .16f;
v4 LineColor = v4{LineValue, LineValue, LineValue, 1.f}; v4 LineColor = v4{LineValue, LineValue, LineValue, 1.f};
@ -232,9 +232,9 @@ DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer*
} }
internal void internal void
DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position, r32 LineHeight, string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse) 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)
{ {
rect PortBounds = rect{v2{0, 0}, v2{6, 6}}; rect2 PortBounds = rect2{v2{0, 0}, v2{6, 6}};
v2 LinePosition = Position; v2 LinePosition = Position;
for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++) for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
@ -244,7 +244,7 @@ DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position,
{ {
// TODO(Peter): Can we make this rely on the same data that we use to // TODO(Peter): Can we make this rely on the same data that we use to
// render the actual connection points? // render the actual connection points?
string MemberName = MakeString(Member.Identifier, Member.IdentifierLength); gs_string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign); DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign);
LinePosition.y -= LineHeight; LinePosition.y -= LineHeight;
} }
@ -252,7 +252,7 @@ DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position,
} }
internal void 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, memory_arena* Scratch) 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]; gsm_struct_type_info NodeDataTypeInfo = StructTypes[NodeSpecification.DataType];
@ -264,13 +264,13 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
if (MemberIsInput(Member)) { InputMembers++; } if (MemberIsInput(Member)) { InputMembers++; }
if (MemberIsOutput(Member)) { OutputMembers++; } if (MemberIsOutput(Member)) { OutputMembers++; }
} }
u32 LineCount = 1 + GSMax(InputMembers, OutputMembers); u32 LineCount = 1 + Max(InputMembers, OutputMembers);
v2 NodeDim = v2{ v2 NodeDim = v2{
NodeWidth, NodeWidth,
(LineHeight * LineCount) + Interface.Margin.y, (LineHeight * LineCount) + Interface.Margin.y,
}; };
rect NodeBounds = rect{ rect2 NodeBounds = rect2{
v2{ Position.x, Position.y - NodeDim.y }, v2{ Position.x, Position.y - NodeDim.y },
v2{ Position.x + NodeDim.x, Position.y }, v2{ Position.x + NodeDim.x, Position.y },
}; };
@ -282,7 +282,7 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f}); PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f});
string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256); gs_string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256);
PrintF(&NodePrintName, "%S [%d]", NodeSpecification.Identifier, NodeHandle.Index); PrintF(&NodePrintName, "%S [%d]", NodeSpecification.Identifier, NodeHandle.Index);
DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4); DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4);
LinePosition.y -= LineHeight; LinePosition.y -= LineHeight;
@ -293,7 +293,7 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++) for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
{ {
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i]; gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i];
string MemberName = MakeString(Member.Identifier, Member.IdentifierLength); gs_string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
// TODO(Peter): Can we make this rely on the same data that we use to // TODO(Peter): Can we make this rely on the same data that we use to
// render the actual connection points? // render the actual connection points?
@ -329,7 +329,7 @@ GetVisualPortIndexForNode(gs_list_handle SparseNodeHandle, u32 PortIndex, node_l
} }
internal node_layout internal node_layout
ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, r32 LineHeight, memory_arena* Storage, app_state* State) ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, r32 LineHeight, gs_memory_arena* Storage, app_state* State)
{ {
node_layout Result = {}; node_layout Result = {};
@ -373,7 +373,7 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
{ {
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p]; gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p];
rect PortBounds = {0}; rect2 PortBounds = {0};
v2 PortDim = v2{8, 8}; v2 PortDim = v2{8, 8};
PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2}; PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2};
if (MemberIsInput(Member)) if (MemberIsInput(Member))
@ -420,16 +420,16 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_node_graph); GSMetaTag(panel_type_node_graph);
internal void internal void
NodeGraph_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) NodeGraph_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
node_graph_state* GraphState = (node_graph_state*)Panel.PanelStateMemory; node_graph_state* GraphState = (node_graph_state*)Panel.PanelStateMemory;
b32 MouseHandled = false; b32 MouseHandled = false;
rect NodeSelectionWindowBounds = rect{ rect2 NodeSelectionWindowBounds = rect2{
PanelBounds.Min, PanelBounds.Min,
v2{PanelBounds.Min.x + 300, PanelBounds.Max.y}, v2{PanelBounds.Min.x + 300, PanelBounds.Max.y},
}; };
rect GraphBounds = rect{ rect2 GraphBounds = rect2{
v2{NodeSelectionWindowBounds.Max.x, PanelBounds.Min.y}, v2{NodeSelectionWindowBounds.Max.x, PanelBounds.Min.y},
PanelBounds.Max, PanelBounds.Max,
}; };
@ -513,18 +513,18 @@ NodeGraph_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
List.TextColor = WhiteV4; List.TextColor = WhiteV4;
List.ListBounds = NodeSelectionWindowBounds; List.ListBounds = NodeSelectionWindowBounds;
List.ListElementDimensions = v2{ List.ListElementDimensions = v2{
gs_Width(NodeSelectionWindowBounds), Rect2Width(NodeSelectionWindowBounds),
ui_GetTextLineHeight(State->Interface) ui_GetTextLineHeight(State->Interface)
}; };
List.ElementLabelIndent = v2{10, 4}; List.ElementLabelIndent = v2{10, 4};
string TitleString = MakeStringLiteral("Available Nodes"); gs_string Titlegs_string = MakeStringLiteral("Available Nodes");
DrawListElement(TitleString, &List, Context.Mouse, RenderBuffer, State->Interface.Style); DrawListElement(Titlegs_string, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
for (u32 i = 0; i < NodeType_Count; i++) for (u32 i = 0; i < NodeType_Count; i++)
{ {
node_specification_ Spec = NodeSpecifications[i]; node_specification_ Spec = NodeSpecifications[i];
rect ElementBounds = DrawListElement(Spec.Identifier, &List, Context.Mouse, RenderBuffer, State->Interface.Style); rect2 ElementBounds = DrawListElement(Spec.Identifier, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
if (MouseButtonTransitionedDown(Context.Mouse.LeftButtonState) if (MouseButtonTransitionedDown(Context.Mouse.LeftButtonState)
&& gs_PointIsInRect(Context.Mouse.DownPos, ElementBounds)) && gs_PointIsInRect(Context.Mouse.DownPos, ElementBounds))

View File

@ -6,7 +6,7 @@
#ifndef FOLDHAUS_SEARCH_LISTER_CPP #ifndef FOLDHAUS_SEARCH_LISTER_CPP
internal b32 internal b32
NamePassesFilter (string Target, string Filter) NamePassesFilter (gs_string Target, gs_string Filter)
{ {
return (Filter.Length == 0 || StringContainsStringCaseInsensitive(Target, Filter)); return (Filter.Length == 0 || StringContainsStringCaseInsensitive(Target, Filter));
} }
@ -21,14 +21,14 @@ FilterSearchLister (search_lister* SearchLister)
for (s32 i = 0; i < SearchLister->SourceListCount; i++) for (s32 i = 0; i < SearchLister->SourceListCount; i++)
{ {
string* NameString = SearchLister->SourceList + i; gs_string* Namegs_string = SearchLister->SourceList + i;
if (NamePassesFilter(*NameString, SearchLister->Filter)) if (NamePassesFilter(*Namegs_string, SearchLister->Filter))
{ {
SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i; SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i;
} }
} }
SearchLister->HotItem = GSClamp(0, SearchLister->HotItem, SearchLister->FilteredListCount - 1); SearchLister->HotItem = Clamp(0, SearchLister->HotItem, SearchLister->FilteredListCount - 1);
if (SearchLister->FilteredListCount == 0) if (SearchLister->FilteredListCount == 0)
{ {
@ -39,14 +39,14 @@ FilterSearchLister (search_lister* SearchLister)
internal s32 internal s32
GetNextFilteredItem (search_lister SearchLister) GetNextFilteredItem (search_lister SearchLister)
{ {
s32 Result = GSMin(SearchLister.HotItem + 1, SearchLister.FilteredListCount - 1); s32 Result = Min(SearchLister.HotItem + 1, SearchLister.FilteredListCount - 1);
return Result; return Result;
} }
internal s32 internal s32
GetPrevFilteredItem (search_lister SearchLister) GetPrevFilteredItem (search_lister SearchLister)
{ {
s32 Result = GSMax(SearchLister.HotItem - 1, 0); s32 Result = Max(SearchLister.HotItem - 1, 0);
return Result; return Result;
} }

View File

@ -8,11 +8,11 @@
struct search_lister struct search_lister
{ {
// TODO(Peter): Giving up trying to just use the source list for now. At the moment // TODO(Peter): Giving up trying to just use the source list for now. At the moment
// we are copying the strings you want to filter from and storing them here. Come back // 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 // once its working and make the memory efficient version (ie store the existing memory
// location, the element stride and the offset to the char*) // location, the element stride and the offset to the char*)
s32 SourceListCount; s32 SourceListCount;
string* SourceList; gs_string* SourceList;
// NOTE(Peter): stores the source indecies of each filtered item // NOTE(Peter): stores the source indecies of each filtered item
// For example: // For example:
@ -23,7 +23,7 @@ struct search_lister
s32* FilteredIndexLUT; s32* FilteredIndexLUT;
s32 HotItem; s32 HotItem;
string Filter; gs_string Filter;
}; };

View File

@ -17,15 +17,14 @@ PipeSearchStringToDestination (text_entry* Input)
{ {
switch (Input->Destination.Type) switch (Input->Destination.Type)
{ {
case TextTranslateTo_String: case TextTranslateTo_gs_string:
{ {
CopyStringTo(Input->Buffer, Input->Destination.StringDest); PrintF(Input->Destination.StringDest, "%S", Input->Buffer);
}break; }break;
case TextTranslateTo_R32: case TextTranslateTo_R32:
{ {
parse_result FloatParseResult = ParseFloat(StringExpand(Input->Buffer)); *Input->Destination.FloatDest = (r32)ParseFloat(Input->Buffer.ConstString);
*Input->Destination.FloatDest = FloatParseResult.FloatValue;
}break; }break;
InvalidDefaultCase; InvalidDefaultCase;
@ -37,19 +36,22 @@ RemoveCharacterAtCursor (text_entry* TextEntry)
{ {
if (TextEntry->CursorPosition > 0) if (TextEntry->CursorPosition > 0)
{ {
RemoveCharAt(&TextEntry->Buffer, for (u32 i = TextEntry->CursorPosition - 1; i < TextEntry->Buffer.Length; i++)
TextEntry->CursorPosition - 1); {
Assert(i + 1 < TextEntry->Buffer.Size);
TextEntry->Buffer.Str[i] = TextEntry->Buffer.Str[i + 1];
}
TextEntry->CursorPosition--; TextEntry->CursorPosition--;
} }
} }
internal void internal void
SetTextInputDestinationToString (text_entry* TextInput, string* DestinationString) SetTextInputDestinationToString (text_entry* TextInput, gs_string* DestinationString)
{ {
ResetTextInput(TextInput); ResetTextInput(TextInput);
TextInput->Destination.Type = TextTranslateTo_String; TextInput->Destination.Type = TextTranslateTo_gs_string;
TextInput->Destination.StringDest = DestinationString; TextInput->Destination.StringDest = DestinationString;
CopyStringTo(*DestinationString, &TextInput->Buffer); PrintF(&TextInput->Buffer, "%S", *DestinationString);
} }
internal void internal void
@ -69,14 +71,13 @@ SetTextInputDestinationToFloat (text_entry* TextInput, r32* DestinationFloat)
internal void internal void
MoveCursorRight (text_entry* TextEntry) MoveCursorRight (text_entry* TextEntry)
{ {
TextEntry->CursorPosition = GSMin(TextEntry->Buffer.Length, TextEntry->CursorPosition = Min(TextEntry->Buffer.Length, TextEntry->CursorPosition + 1);
TextEntry->CursorPosition + 1);
} }
internal void internal void
MoveCursorLeft (text_entry* TextEntry) MoveCursorLeft (text_entry* TextEntry)
{ {
TextEntry->CursorPosition = GSMax(0, TextEntry->CursorPosition - 1); TextEntry->CursorPosition = Max(0, TextEntry->CursorPosition - 1);
} }
FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar) FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar)
@ -88,12 +89,21 @@ FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar)
Char += ('a' - 'A'); Char += ('a' - 'A');
} }
InsertChar(&State->ActiveTextEntry.Buffer, Char, State->ActiveTextEntry.CursorPosition); // 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++; State->ActiveTextEntry.CursorPosition++;
PipeSearchStringToDestination(&State->ActiveTextEntry); PipeSearchStringToDestination(&State->ActiveTextEntry);
} }
FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntryString) FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntrygs_string)
{ {
RemoveCharacterAtCursor(&State->ActiveTextEntry); RemoveCharacterAtCursor(&State->ActiveTextEntry);
} }
@ -109,11 +119,11 @@ FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorLeft)
} }
internal void internal void
InitializeTextInputCommands (input_command_registry* Commands, memory_arena* PermanentStorage) InitializeTextInputCommands (input_command_registry* Commands, gs_memory_arena* PermanentStorage)
{ {
if (Commands->Size > 0) if (Commands->Size > 0)
{ {
RegisterKeyPressCommand(Commands, KeyCode_Backspace, Command_Began | Command_Held, KeyCode_Invalid, RemoveCharacterFromEntryString); 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_LeftArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorLeft);
RegisterKeyPressCommand(Commands, KeyCode_RightArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorRight); RegisterKeyPressCommand(Commands, KeyCode_RightArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorRight);
@ -126,7 +136,7 @@ InitializeTextInputCommands (input_command_registry* Commands, memory_arena* Per
} }
#define DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY \ #define DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY \
{ KeyCode_Backspace, KeyCode_Invalid, Command_Began | Command_Held, RemoveCharacterFromEntryString }, \ { KeyCode_Backspace, KeyCode_Invalid, Command_Began | Command_Held, RemoveCharacterFromEntrygs_string }, \
{ KeyCode_LeftArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorLeft }, \ { KeyCode_LeftArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorLeft }, \
{ KeyCode_RightArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorRight }, \ { KeyCode_RightArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorRight }, \
{ KeyCode_a, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \ { KeyCode_a, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \

View File

@ -7,7 +7,7 @@
enum text_translation_type enum text_translation_type
{ {
TextTranslateTo_String, TextTranslateTo_gs_string,
TextTranslateTo_R32, TextTranslateTo_R32,
TextTranslateTo_S32, TextTranslateTo_S32,
TextTranslateTo_U32, TextTranslateTo_U32,
@ -17,7 +17,7 @@ struct text_entry_destination
{ {
text_translation_type Type; text_translation_type Type;
union { union {
string* StringDest; gs_string* StringDest;
r32* FloatDest; r32* FloatDest;
s32* SignedIntDest; s32* SignedIntDest;
u32* UnsignedIntDest; u32* UnsignedIntDest;
@ -26,7 +26,7 @@ struct text_entry_destination
struct text_entry struct text_entry
{ {
string Buffer; gs_string Buffer;
s32 CursorPosition; s32 CursorPosition;
text_entry_destination Destination; text_entry_destination Destination;

View File

@ -18,7 +18,7 @@ struct node_lister_operation_state
}; };
internal void internal void
RenderNodeLister(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) 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; node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory;
@ -90,7 +90,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
node_lister_operation_state); node_lister_operation_state);
{ {
OpState->SearchLister.SourceListCount = NodeSpecificationsCount; OpState->SearchLister.SourceListCount = NodeSpecificationsCount;
OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, string, OpState->SearchLister.SourceListCount); OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, gs_string, OpState->SearchLister.SourceListCount);
{ {
for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++) for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++)
{ {
@ -107,7 +107,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
} }
OpState->ListPosition = Mouse.Pos; OpState->ListPosition = Mouse.Pos;
SetTextInputDestinationToString(&State->ActiveTextEntry, &OpState->SearchLister.Filter); SetTextInputDestinationTogs_string(&State->ActiveTextEntry, &OpState->SearchLister.Filter);
} }
//////////////////////////////////////// ////////////////////////////////////////
@ -133,7 +133,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(CloseColorPickerCommand)
} }
internal void internal void
RenderColorPicker(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) 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; color_picker_operation_state* OpState = (color_picker_operation_state*)Operation.OpStateMemory;
@ -202,7 +202,7 @@ struct drag_node_port_operation_state
}; };
internal void internal void
RenderDraggingNodePort(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) 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; drag_node_port_operation_state* OpState = (drag_node_port_operation_state*)Operation.OpStateMemory;
UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList, UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList,
@ -242,7 +242,7 @@ BeginDraggingNodePort(app_state* State, node_interaction Interaction)
/////////////////////////////////////// ///////////////////////////////////////
internal void internal void
RenderDragNodeField(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) RenderDragNodeField(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
{ {
// TODO(Peter): // TODO(Peter):
//UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State); //UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State);
@ -266,7 +266,7 @@ struct drag_node_operation_state
}; };
internal void internal void
RenderDraggingNode(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) 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); drag_node_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_operation_state);
UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList, UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList,
@ -368,7 +368,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction)
} }
internal void internal void
RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse) 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; node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory;
@ -383,7 +383,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
{ {
node_header* Node = NodeIter.At; node_header* Node = NodeIter.At;
rect NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings); rect2 NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings);
b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds); b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds);
if (Node == SelectedNode) if (Node == SelectedNode)
@ -394,8 +394,8 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f}); 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 // TODO(Peter): This is just for debug purposes. We can remove and go back to just having
// Node->Name in DrawString // Node->Name in Drawgs_string
string NodeName = GetNodeName(*Node); gs_string NodeName = GetNodeName(*Node);
PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle); PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle);
DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font, DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font,
v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)}, v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)},
@ -408,7 +408,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
// Inputs // Inputs
if (ConnectionIsInput(Node, Connection)) if (ConnectionIsInput(Node, Connection))
{ {
rect PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings); rect2 PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings);
DrawPort(RenderBuffer, PortBounds, PortColor); DrawPort(RenderBuffer, PortBounds, PortColor);
// //
@ -427,7 +427,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right); v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right);
} }
rect ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings); rect2 ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings);
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font); 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, // NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship,
@ -436,7 +436,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
// most downstream node and working back up to find dependencies. // most downstream node and working back up to find dependencies.
if (ConnectionHasUpstreamConnection(Node, Connection)) if (ConnectionHasUpstreamConnection(Node, Connection))
{ {
rect ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings); rect2 ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings);
v2 InputCenter = CalculateRectCenter(PortBounds); v2 InputCenter = CalculateRectCenter(PortBounds);
v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds); v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds);
PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4); PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4);
@ -446,7 +446,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
// Outputs // Outputs
if (ConnectionIsOutput(Node, Connection)) if (ConnectionIsOutput(Node, Connection))
{ {
rect PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings); rect2 PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings);
DrawPort(RenderBuffer, PortBounds, PortColor); DrawPort(RenderBuffer, PortBounds, PortColor);
if (DrawFields) if (DrawFields)
@ -458,13 +458,13 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4); v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4);
} }
rect ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings); rect2 ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings);
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font); DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
} }
for (s32 Button = 0; Button < 3; Button++) for (s32 Button = 0; Button < 3; Button++)
{ {
rect ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings); rect2 ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings);
PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]); PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]);
} }
} }

View File

@ -8,27 +8,6 @@
#include "foldhaus_platform.h" #include "foldhaus_platform.h"
#include "foldhaus_app.h" #include "foldhaus_app.h"
internal v4
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
{
DEBUG_TRACK_SCOPE(MouseToWorldRay);
r32 X = ((2.0f * MouseX) / gs_Width(WindowBounds)) - 1;
r32 Y = ((2.0f * MouseY) / gs_Height(WindowBounds)) - 1;
v4 ScreenPos = v4{X, Y, -1, 1};
m44 InverseProjection = {};
Inverse(GetCameraPerspectiveProjectionMatrix(*Camera), &InverseProjection);
m44 InverseModelView = {};
Inverse(GetCameraModelViewMatrix(*Camera), &InverseModelView);
InverseModelView = Transpose(InverseModelView);
v4 ClipSpacePos = InverseProjection * ScreenPos;
v4 WorldPosition = InverseModelView * ClipSpacePos;
return WorldPosition;
}
struct send_sacn_job_data struct send_sacn_job_data
{ {
@ -72,11 +51,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
app_state* State = (app_state*)Context.MemoryBase; app_state* State = (app_state*)Context.MemoryBase;
*State = {}; *State = {};
State->Permanent = {}; State->Permanent = CreateMemoryArena(Context.ThreadContext.Allocator);
State->Permanent.PlatformMemory = Context.PlatformMemory; State->Transient = CreateMemoryArena(Context.ThreadContext.Allocator);
State->Transient = {};
State->Transient.FindAddressRule = FindAddress_InLastBufferOnly;
State->Transient.PlatformMemory = Context.PlatformMemory;
State->Assemblies.CountMax = 8; State->Assemblies.CountMax = 8;
State->Assemblies.Values = PushArray(&State->Permanent, assembly, State->Assemblies.CountMax); State->Assemblies.Values = PushArray(&State->Permanent, assembly, State->Assemblies.CountMax);
@ -90,13 +66,11 @@ INITIALIZE_APPLICATION(InitializeApplication)
CommandQueueSize); CommandQueueSize);
State->CommandQueue = InitializeCommandQueue(CommandQueueMemory, CommandQueueSize); State->CommandQueue = InitializeCommandQueue(CommandQueueMemory, CommandQueueSize);
State->ActiveTextEntry.Buffer = MakeString(PushArray(&State->Permanent, char, 256), 0, 256);
// TODO(Peter): put in InitializeInterface? // TODO(Peter): put in InitializeInterface?
r32 FontSize = 14; r32 FontSize = 14;
{ {
platform_memory_result FontFile = ReadEntireFile(Context, MakeStringLiteral("data/Anonymous Pro.ttf")); gs_file FontFile = ReadEntireFile(Context.ThreadContext.FileHandler, ConstString("data/Anonymous Pro.ttf"));
if (!FontFile.Error) if (FileNoError(FontFile))
{ {
bitmap_font* Font = PushStruct(&State->Permanent, bitmap_font); bitmap_font* Font = PushStruct(&State->Permanent, bitmap_font);
@ -105,7 +79,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
Font->BitmapBytesPerPixel = 4; Font->BitmapBytesPerPixel = 4;
Font->BitmapMemory = PushArray(&State->Permanent, u8, Font->BitmapWidth * Font->BitmapHeight * Font->BitmapBytesPerPixel); Font->BitmapMemory = PushArray(&State->Permanent, u8, Font->BitmapWidth * Font->BitmapHeight * Font->BitmapBytesPerPixel);
Font->BitmapStride = Font->BitmapWidth * Font->BitmapBytesPerPixel; Font->BitmapStride = Font->BitmapWidth * Font->BitmapBytesPerPixel;
GSMemSet(Font->BitmapMemory, 0, Font->BitmapStride * Font->BitmapHeight); ZeroMemoryBlock(Font->BitmapMemory, Font->BitmapStride * Font->BitmapHeight);
platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize, FontWeight_Normal, false, false, false); platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize, FontWeight_Normal, false, false, false);
Font->PixelHeight = FontInfo.PixelHeight; Font->PixelHeight = FontInfo.PixelHeight;
@ -169,17 +143,18 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->SACN = InitializeSACN(Context); State->SACN = InitializeSACN(Context);
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE; State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
State->Camera.FieldOfView = DegreesToRadians(45.0f); State->Camera.FieldOfView = 45.0f;
State->Camera.AspectRatio = gs_AspectRatio(State->WindowBounds); State->Camera.AspectRatio = RectAspectRatio(State->WindowBounds);
State->Camera.Near = 1.0f; State->Camera.Near = .1f;
State->Camera.Far = 100.0f; State->Camera.Far = 800.0f;
State->Camera.Position = v3{0, 0, -250}; State->Camera.Position = v3{0, 0, 400};
State->Camera.LookAt = v3{0, 0, 0}; State->Camera.LookAt = v3{0, 0, 0
};
State->LedSystem = LedSystemInitialize(Context.PlatformMemory, 128); State->LedSystem = LedSystemInitialize(Context.ThreadContext.Allocator, 128);
#if 1 #if 1
string SculpturePath = MakeStringLiteral("data/radialumia_v2.fold"); gs_const_string SculpturePath = ConstString("data/radialumia_v2.fold");
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, SculpturePath, State->GlobalLog); LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, SculpturePath, State->GlobalLog);
#endif #endif
@ -189,11 +164,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
ReloadStaticData(Context, GlobalDebugServices); ReloadStaticData(Context, GlobalDebugServices);
// Setup Operation Modes State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext);
State->Modes.ActiveModesCount = 0;
State->Modes.Arena = {};
State->Modes.Arena.PlatformMemory = Context.PlatformMemory;
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
{ // Animation PLAYGROUND { // Animation PLAYGROUND
State->AnimationSystem = {}; State->AnimationSystem = {};
@ -203,9 +174,9 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem); State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
State->AnimationSystem.LayersMax = 32; State->AnimationSystem.LayersMax = 32;
State->AnimationSystem.Layers = PushArray(&State->Permanent, anim_layer, State->AnimationSystem.LayersMax); State->AnimationSystem.Layers = PushArray(&State->Permanent, anim_layer, State->AnimationSystem.LayersMax);
AddLayer(MakeStringLiteral("Base Layer"), &State->AnimationSystem, BlendMode_Overwrite); AddLayer(MakeString("Base Layer"), &State->AnimationSystem, BlendMode_Overwrite);
AddLayer(MakeStringLiteral("Color Layer"), &State->AnimationSystem, BlendMode_Multiply); AddLayer(MakeString("Color Layer"), &State->AnimationSystem, BlendMode_Multiply);
AddLayer(MakeStringLiteral("Sparkles"), &State->AnimationSystem, BlendMode_Add); AddLayer(MakeString("Sparkles"), &State->AnimationSystem, BlendMode_Add);
} // End Animation Playground } // End Animation Playground
@ -215,7 +186,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
} }
internal void internal void
HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_state Mouse) HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse_state Mouse)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
@ -274,7 +245,7 @@ HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_
} }
internal dmx_buffer_list* internal dmx_buffer_list*
CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize, memory_arena* Arena) CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize, gs_memory_arena* Arena)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
@ -322,6 +293,10 @@ CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize,
return Result; return Result;
} }
#define HANDMADE_MATH_IMPLEMENTATION
#include "handmade_math.h"
UPDATE_AND_RENDER(UpdateAndRender) UPDATE_AND_RENDER(UpdateAndRender)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
@ -334,6 +309,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
ClearArena(&State->Transient); ClearArena(&State->Transient);
Context->Mouse.CursorType = CursorType_Arrow; Context->Mouse.CursorType = CursorType_Arrow;
PushRenderClearScreen(RenderBuffer);
State->Camera.AspectRatio = RectAspectRatio(Context->WindowBounds);
HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse); HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse);
if (State->AnimationSystem.TimelineShouldAdvance) { if (State->AnimationSystem.TimelineShouldAdvance) {
@ -355,7 +333,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
u32 CurrentBlocksMax = State->AnimationSystem.LayersCount; u32 CurrentBlocksMax = State->AnimationSystem.LayersCount;
b8* CurrentBlocksFilled = PushArray(&State->Transient, b8, CurrentBlocksMax); b8* CurrentBlocksFilled = PushArray(&State->Transient, b8, CurrentBlocksMax);
GSZeroArray(CurrentBlocksFilled, b8, CurrentBlocksMax); ZeroArray(CurrentBlocksFilled, b8, CurrentBlocksMax);
animation_block* CurrentBlocks = PushArray(&State->Transient, animation_block, CurrentBlocksMax); animation_block* CurrentBlocks = PushArray(&State->Transient, animation_block, CurrentBlocksMax);
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++) for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
@ -432,9 +410,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
u32 G = (u32)AssemblyLedBuffer->Colors[LED].G + (u32)LayerLEDBuffers[Layer].Colors[LED].G; u32 G = (u32)AssemblyLedBuffer->Colors[LED].G + (u32)LayerLEDBuffers[Layer].Colors[LED].G;
u32 B = (u32)AssemblyLedBuffer->Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B; u32 B = (u32)AssemblyLedBuffer->Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B;
AssemblyLedBuffer->Colors[LED].R = (u8)GSMin(R, (u32)255); AssemblyLedBuffer->Colors[LED].R = (u8)Min(R, (u32)255);
AssemblyLedBuffer->Colors[LED].G = (u8)GSMin(G, (u32)255); AssemblyLedBuffer->Colors[LED].G = (u8)Min(G, (u32)255);
AssemblyLedBuffer->Colors[LED].B = (u8)GSMin(B, (u32)255); AssemblyLedBuffer->Colors[LED].B = (u8)Min(B, (u32)255);
} }
}break; }break;
@ -502,7 +480,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
PushRenderOrthographic(RenderBuffer, 0, 0, gs_Width(State->WindowBounds), gs_Height(State->WindowBounds)); PushRenderOrthographic(RenderBuffer, State->WindowBounds);
PushRenderClearScreen(RenderBuffer); PushRenderClearScreen(RenderBuffer);
State->WindowBounds = Context->WindowBounds; State->WindowBounds = Context->WindowBounds;
@ -521,7 +499,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
} }
} }
Context->GeneralWorkQueue->DoQueueWorkUntilDone(Context->GeneralWorkQueue, 0); Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext);
Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue); Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue);
// Checking for overflows // Checking for overflows

View File

@ -20,13 +20,8 @@
#include "foldhaus_assembly.h" #include "foldhaus_assembly.h"
#include "assembly_parser.cpp" #include "assembly_parser.cpp"
#include "foldhaus_node.h"
typedef struct app_state app_state; typedef struct app_state app_state;
#include "test_patterns.h"
// TODO(Peter): something we can do later is to remove all reliance on app_state and context // 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 // 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. // perform operations on, like panel_draw_requests = { bounds, panel* } etc.
@ -37,10 +32,6 @@ typedef struct app_state app_state;
#include "animation/foldhaus_animation.h" #include "animation/foldhaus_animation.h"
#include "foldhaus_text_entry.h"
#include "foldhaus_search_lister.h"
enum network_protocol enum network_protocol
{ {
NetworkProtocol_SACN, NetworkProtocol_SACN,
@ -51,10 +42,11 @@ enum network_protocol
struct app_state struct app_state
{ {
rect WindowBounds; r32 CameraTheta; // TODO(Peter): @TEMPORARY
rect2 WindowBounds;
memory_arena Permanent; gs_memory_arena Permanent;
memory_arena Transient; gs_memory_arena Transient;
s32 NetworkProtocolHeaderSize; s32 NetworkProtocolHeaderSize;
network_protocol NetworkProtocol; network_protocol NetworkProtocol;
@ -69,7 +61,6 @@ struct app_state
operation_mode_system Modes; operation_mode_system Modes;
input_command_queue CommandQueue; input_command_queue CommandQueue;
text_entry ActiveTextEntry;
ui_interface Interface; ui_interface Interface;
@ -80,7 +71,7 @@ struct app_state
panel_system PanelSystem; panel_system PanelSystem;
panel* HotPanel; panel* HotPanel;
pattern_node_workspace NodeWorkspace; //pattern_node_workspace NodeWorkspace;
event_log* GlobalLog; event_log* GlobalLog;
}; };
@ -94,8 +85,8 @@ TestPatternOne(led_buffer* Assembly, r32 Time)
for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++) for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
{ {
v4 LedPosition = Assembly->Positions[LedIndex]; v4 LedPosition = Assembly->Positions[LedIndex];
float PercentX = GSRemap(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f); float PercentX = RemapClampedR32(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f);
float PercentY = GSRemap(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f); float PercentY = RemapClampedR32(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f);
Assembly->Colors[LedIndex].R = (u8)(PercentX * 255); Assembly->Colors[LedIndex].R = (u8)(PercentX * 255);
Assembly->Colors[LedIndex].G = (u8)(PercentY * 255); Assembly->Colors[LedIndex].G = (u8)(PercentY * 255);
} }
@ -104,16 +95,16 @@ TestPatternOne(led_buffer* Assembly, r32 Time)
internal void internal void
TestPatternTwo(led_buffer* Assembly, r32 Time) TestPatternTwo(led_buffer* Assembly, r32 Time)
{ {
r32 PeriodicTime = (Time / PI) * 2; r32 PeriodicTime = (Time / PiR32) * 2;
r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f; r32 ZeroOneSin = (SinR32(PeriodicTime) * .5f) + .5f;
r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f; r32 ZeroOneCos = (CosR32(PeriodicTime) * .5f) + .5f;
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) }; pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
v4 Center = v4{0, 0, 0, 1}; v4 Center = v4{0, 0, 0, 1};
r32 ThetaZ = Time / 2; r32 ThetaZ = Time / 2;
v4 Normal = v4{GSCos(ThetaZ), 0, GSSin(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1 v4 Normal = v4{CosR32(ThetaZ), 0, SinR32(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
v4 Right = Cross(Normal, v4{0, 1, 0, 0}); v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
v4 FrontCenter = Center + (Normal * 25); v4 FrontCenter = Center + (Normal * 25);
v4 BackCenter = Center - (Normal * 25); v4 BackCenter = Center - (Normal * 25);
@ -128,13 +119,13 @@ TestPatternTwo(led_buffer* Assembly, r32 Time)
v4 ToFront = Position + FrontCenter; v4 ToFront = Position + FrontCenter;
v4 ToBack = Position + BackCenter; v4 ToBack = Position + BackCenter;
r32 ToFrontDotNormal = Dot(ToFront, Normal); r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
r32 ToBackDotNormal = Dot(ToBack, Normal); r32 ToBackDotNormal = V4Dot(ToBack, Normal);
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000); ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000); ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
r32 SqDistToCenter = MagSqr(Position); r32 SqDistToCenter = V4MagSquared(Position);
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared) if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
{ {
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0)) if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
@ -157,10 +148,10 @@ internal void
TestPatternThree(led_buffer* Assembly, r32 Time) TestPatternThree(led_buffer* Assembly, r32 Time)
{ {
v4 GreenCenter = v4{0, 0, 150, 1}; v4 GreenCenter = v4{0, 0, 150, 1};
r32 GreenRadius = GSAbs(GSSin(Time)) * 200; r32 GreenRadius = Abs(SinR32(Time)) * 200;
v4 TealCenter = v4{0, 0, 150, 1}; v4 TealCenter = v4{0, 0, 150, 1};
r32 TealRadius = GSAbs(GSSin(Time + 1.5)) * 200; r32 TealRadius = Abs(SinR32(Time + 1.5)) * 200;
r32 FadeDist = 35; r32 FadeDist = 35;
@ -172,12 +163,12 @@ TestPatternThree(led_buffer* Assembly, r32 Time)
u8 Green = 0; u8 Green = 0;
u8 Blue = 0; u8 Blue = 0;
r32 GreenDist = GSAbs(Mag(LedPosition - GreenCenter) - GreenRadius); r32 GreenDist = Abs(V4Mag(LedPosition - GreenCenter) - GreenRadius);
r32 GreenBrightness = GSClamp(0.f, FadeDist - GSAbs(GreenDist), FadeDist); r32 GreenBrightness = Clamp(0.f, FadeDist - Abs(GreenDist), FadeDist);
Green = (u8)(GreenBrightness * 255); Green = (u8)(GreenBrightness * 255);
r32 TealDist = GSAbs(Mag(LedPosition - TealCenter) - TealRadius); r32 TealDist = Abs(V4Mag(LedPosition - TealCenter) - TealRadius);
r32 TealBrightness = GSClamp(0.f, FadeDist - GSAbs(TealDist), FadeDist); r32 TealBrightness = Clamp(0.f, FadeDist - Abs(TealDist), FadeDist);
Red = (u8)(TealBrightness * 255); Red = (u8)(TealBrightness * 255);
Blue = (u8)(TealBrightness * 255); Blue = (u8)(TealBrightness * 255);
@ -191,17 +182,6 @@ TestPatternThree(led_buffer* Assembly, r32 Time)
#include "foldhaus_assembly.cpp" #include "foldhaus_assembly.cpp"
#include "foldhaus_text_entry.cpp"
#include "foldhaus_search_lister.cpp"
#include "foldhaus_default_nodes.h"
#include "./generated/gs_meta_generated_typeinfo.h"
#include "generated/foldhaus_nodes_generated.h"
#include "foldhaus_node.cpp"
FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode) FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode)
{ {
DeactivateCurrentOperationMode(&State->Modes); DeactivateCurrentOperationMode(&State->Modes);
@ -213,7 +193,7 @@ typedef PANEL_INIT_PROC(panel_init_proc);
#define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State) #define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State)
typedef PANEL_CLEANUP_PROC(panel_cleanup_proc); typedef PANEL_CLEANUP_PROC(panel_cleanup_proc);
#define PANEL_RENDER_PROC(name) void name(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) #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); typedef PANEL_RENDER_PROC(panel_render_proc);
// NOTE(Peter): This is used by the meta system to generate panel type info // NOTE(Peter): This is used by the meta system to generate panel type info
@ -233,7 +213,6 @@ struct panel_definition
#include "panels/foldhaus_panel_dmx_view.h" #include "panels/foldhaus_panel_dmx_view.h"
#include "panels/foldhaus_panel_animation_timeline.h" #include "panels/foldhaus_panel_animation_timeline.h"
#include "panels/foldhaus_panel_hierarchy.h" #include "panels/foldhaus_panel_hierarchy.h"
#include "panels/foldhaus_panel_node_graph.h"
#include "panels/foldhaus_panel_file_view.h" #include "panels/foldhaus_panel_file_view.h"
#include "generated/foldhaus_panels_generated.h" #include "generated/foldhaus_panels_generated.h"

View File

@ -6,13 +6,13 @@
#ifndef FOLDHAUS_ASSEMBLY_CPP #ifndef FOLDHAUS_ASSEMBLY_CPP
internal led_system internal led_system
LedSystemInitialize(platform_memory_handler PlatformMemory, u32 BuffersMax) LedSystemInitialize(gs_allocator PlatformMemory, u32 BuffersMax)
{ {
led_system Result = {}; led_system Result = {};
Result.PlatformMemory = PlatformMemory; Result.PlatformMemory = PlatformMemory;
// TODO(Peter): Since we have access to PlatformMemory, just realloc Buffers when we fill it up // TODO(Peter): Since we have access to PlatformMemory, just realloc Buffers when we fill it up
Result.BuffersCountMax = BuffersMax; Result.BuffersCountMax = BuffersMax;
Result.Buffers = PlatformAllocArray(PlatformMemory, led_buffer, Result.BuffersCountMax); Result.Buffers = AllocatorAllocArray(PlatformMemory, led_buffer, Result.BuffersCountMax);
return Result; return Result;
} }
@ -43,8 +43,8 @@ LedSystemTakeFreeBuffer(led_system* System, u32 LedCount)
led_buffer* Buffer = &System->Buffers[Result]; led_buffer* Buffer = &System->Buffers[Result];
Buffer->LedCount = LedCount; Buffer->LedCount = LedCount;
Buffer->Colors = PlatformAllocArray(System->PlatformMemory, pixel, Buffer->LedCount); Buffer->Colors = AllocatorAllocArray(System->PlatformMemory, pixel, Buffer->LedCount);
Buffer->Positions = PlatformAllocArray(System->PlatformMemory, v4, Buffer->LedCount); Buffer->Positions = AllocatorAllocArray(System->PlatformMemory, v4, Buffer->LedCount);
System->LedsCountTotal += LedCount; System->LedsCountTotal += LedCount;
@ -56,8 +56,8 @@ LedSystemFreeBuffer(led_system* System, u32 BufferIndex)
{ {
Assert(BufferIndex < System->BuffersCountMax); Assert(BufferIndex < System->BuffersCountMax);
led_buffer* Buffer = &System->Buffers[BufferIndex]; led_buffer* Buffer = &System->Buffers[BufferIndex];
PlatformFreeArray(System->PlatformMemory, Buffer->Colors, pixel, Buffer->LedCount); AllocatorFreeArray(System->PlatformMemory, Buffer->Colors, pixel, Buffer->LedCount);
PlatformFreeArray(System->PlatformMemory, Buffer->Positions, v4, Buffer->LedCount); AllocatorFreeArray(System->PlatformMemory, Buffer->Positions, v4, Buffer->LedCount);
System->LedsCountTotal -= Buffer->LedCount; System->LedsCountTotal -= Buffer->LedCount;
*Buffer = {}; *Buffer = {};
} }
@ -77,7 +77,7 @@ LedBufferSetLed(led_buffer* Buffer, u32 Led, v4 Position)
} }
internal void internal void
ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 RootPosition, led_system* LedSystem) ConstructAssemblyFromDefinition (assembly* Assembly, gs_const_string AssemblyName, v4 RootPosition, led_system* LedSystem)
{ {
Assembly->LedBufferIndex = LedSystemTakeFreeBuffer(LedSystem, Assembly->LedCountTotal); Assembly->LedBufferIndex = LedSystemTakeFreeBuffer(LedSystem, Assembly->LedCountTotal);
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex); led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex);
@ -90,8 +90,8 @@ ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 Roo
v2_strip* StripAt = &Assembly->Strips[StripIdx]; v2_strip* StripAt = &Assembly->Strips[StripIdx];
StripAt->LedLUT = PushArray(&Assembly->Arena, u32, StripAt->LedCount); StripAt->LedLUT = PushArray(&Assembly->Arena, u32, StripAt->LedCount);
v4 WS_StripStart = RootPosition + V4(StripAt->StartPosition * Assembly->Scale, 1); v4 WS_StripStart = RootPosition + ToV4Point(StripAt->StartPosition * Assembly->Scale);
v4 WS_StripEnd = RootPosition + V4(StripAt->EndPosition * Assembly->Scale, 1); v4 WS_StripEnd = RootPosition + ToV4Point(StripAt->EndPosition * Assembly->Scale);
v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)StripAt->LedCount; v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)StripAt->LedCount;
for (u32 Step = 0; Step < StripAt->LedCount; Step++) for (u32 Step = 0; Step < StripAt->LedCount; Step++)
@ -111,25 +111,25 @@ static v4 TempAssemblyOffsets[] = { v4{0, 0, 0, 0}, v4{250, 0, 75, 0}, v4{-250,
s32 TempAssemblyOffsetsCount = 3; s32 TempAssemblyOffsetsCount = 3;
internal void internal void
LoadAssembly (assembly_array* Assemblies, led_system* LedSystem, memory_arena* Scratch, context Context, string Path, event_log* GlobalLog) LoadAssembly (assembly_array* Assemblies, led_system* LedSystem, gs_memory_arena* Scratch, context Context, gs_const_string Path, event_log* GlobalLog)
{ {
platform_memory_result AssemblyFile = ReadEntireFile(Context, Path); gs_file AssemblyFile = ReadEntireFile(Context.ThreadContext.FileHandler, Path);
if (AssemblyFile.Error == PlatformMemory_NoError && AssemblyFile.Data.Size > 0) if (FileNoError(AssemblyFile))
{ {
string AssemblyFileText = MakeString((char*)AssemblyFile.Data.Base); gs_string AssemblyFileText = MakeString((char*)AssemblyFile.Memory);
Assert(Assemblies->Count < Assemblies->CountMax); Assert(Assemblies->Count < Assemblies->CountMax);
assembly* NewAssembly = &Assemblies->Values[Assemblies->Count++]; assembly* NewAssembly = &Assemblies->Values[Assemblies->Count++];
s32 IndexOfLastSlash = FastLastIndexOfCharInCharArray(Path.Memory, Path.Length, '\\'); s32 IndexOfLastSlash = FindLast(Path, '\\');
string FileName = Substring(Path, IndexOfLastSlash + 1); gs_const_string FileName = Substring(Path, IndexOfLastSlash + 1, Path.Length);
NewAssembly->Arena.PlatformMemory = Context.PlatformMemory; NewAssembly->Arena = CreateMemoryArena(Context.ThreadContext.Allocator);
if (ParseAssemblyFile(NewAssembly, AssemblyFileText, Scratch)) if (ParseAssemblyFile(NewAssembly, FileName, AssemblyFileText, Scratch))
{ {
v4 Offset = v4{0,0,0,0}; //TempAssemblyOffsets[Assemblies->Count % TempAssemblyOffsetsCount]; v4 Offset = v4{0,0,0,0}; //TempAssemblyOffsets[Assemblies->Count % TempAssemblyOffsetsCount];
ConstructAssemblyFromDefinition(NewAssembly, FileName, Offset, LedSystem); ConstructAssemblyFromDefinition(NewAssembly, FileName, Offset, LedSystem);
PlatformFree(Context.PlatformMemory, AssemblyFile.Data.Base, AssemblyFile.Data.Size); AllocatorFree(Context.ThreadContext.Allocator, AssemblyFile.Memory, AssemblyFile.Size);
} }
else else
{ {

View File

@ -25,7 +25,7 @@ struct led_buffer
struct led_system struct led_system
{ {
platform_memory_handler PlatformMemory; gs_allocator PlatformMemory;
u32 BuffersCountMax; u32 BuffersCountMax;
u32 BuffersCount; u32 BuffersCount;
@ -62,10 +62,10 @@ struct v2_strip
struct assembly struct assembly
{ {
memory_arena Arena; gs_memory_arena Arena;
string Name; gs_string Name;
string FilePath; gs_string FilePath;
r32 Scale; r32 Scale;
s32 LedCountTotal; s32 LedCountTotal;

View File

@ -55,7 +55,7 @@ struct input_command_queue
internal void internal void
InitializeInputCommandRegistry (input_command_registry* CommandRegistry, InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
s32 Size, s32 Size,
memory_arena* Storage) gs_memory_arena* Storage)
{ {
CommandRegistry->Commands = PushArray(Storage, input_command, Size); CommandRegistry->Commands = PushArray(Storage, input_command, Size);
CommandRegistry->Size = Size; CommandRegistry->Size = Size;

View File

@ -30,7 +30,7 @@ struct collated_scope_record
struct scope_name struct scope_name
{ {
u32 Hash; u32 Hash;
string Name; gs_string Name;
char Buffer[SCOPE_NAME_BUFFER_LENGTH]; char Buffer[SCOPE_NAME_BUFFER_LENGTH];
}; };
@ -82,7 +82,7 @@ typedef u8* debug_realloc(u8* Memory, s32 OldSize, s32 NewSize);
struct debug_histogram_entry struct debug_histogram_entry
{ {
char ScopeName_[SCOPE_NAME_LENGTH]; char ScopeName_[SCOPE_NAME_LENGTH];
string ScopeName; gs_string ScopeName;
u32 PerFrame_Cycles[HISTOGRAM_DEPTH]; u32 PerFrame_Cycles[HISTOGRAM_DEPTH];
u32 PerFrame_CallCount[HISTOGRAM_DEPTH]; u32 PerFrame_CallCount[HISTOGRAM_DEPTH];
@ -359,9 +359,9 @@ BeginTrackingScopeAndGetNameHash (debug_services* Services, char* ScopeName)
if (Entry->Hash == 0) // If its new if (Entry->Hash == 0) // If its new
{ {
Entry->Hash = NameHash; Entry->Hash = NameHash;
// TODO(Peter): need to initialize all entry name strings to point at the buffer // 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 // This will break eventually. when it does, do this ^^^^ when on startup
CopyCharArrayToString(ScopeName, &Entry->Name); PrintF(&Entry->Name, "%s", ScopeName);
} }
return NameHash; return NameHash;

View File

@ -41,7 +41,7 @@ OPERATION_STATE_DEF(drag_panel_border_operation_state)
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying, // NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
// it stores the value calculated when the operation mode is kicked off. // it stores the value calculated when the operation mode is kicked off.
rect InitialPanelBounds; rect2 InitialPanelBounds;
panel_split_direction PanelEdgeDirection; panel_split_direction PanelEdgeDirection;
panel_edit_mode PanelEditMode; panel_edit_mode PanelEditMode;
}; };
@ -49,7 +49,7 @@ OPERATION_STATE_DEF(drag_panel_border_operation_state)
OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder) OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
{ {
drag_panel_border_operation_state* OpState = (drag_panel_border_operation_state*)Operation.OpStateMemory; drag_panel_border_operation_state* OpState = (drag_panel_border_operation_state*)Operation.OpStateMemory;
rect PanelBounds = OpState->InitialPanelBounds; rect2 PanelBounds = OpState->InitialPanelBounds;
if (OpState->PanelEditMode == PanelEdit_Modify) if (OpState->PanelEditMode == PanelEdit_Modify)
{ {
@ -72,10 +72,10 @@ OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
} }
else if (OpState->PanelEditMode == PanelEdit_Destroy) else if (OpState->PanelEditMode == PanelEdit_Destroy)
{ {
rect PanelToDeleteBounds = {}; rect2 PanelToDeleteBounds = {};
if (OpState->PanelEdgeDirection == PanelSplit_Horizontal) if (OpState->PanelEdgeDirection == PanelSplit_Horizontal)
{ {
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, OpState->Panel->SplitPercent); r32 SplitY = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
if (Mouse.Pos.y > SplitY) if (Mouse.Pos.y > SplitY)
{ {
PanelToDeleteBounds = GetTopPanelBounds(OpState->Panel, PanelBounds); PanelToDeleteBounds = GetTopPanelBounds(OpState->Panel, PanelBounds);
@ -87,7 +87,7 @@ OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
} }
else if (OpState->PanelEdgeDirection == PanelSplit_Vertical) else if (OpState->PanelEdgeDirection == PanelSplit_Vertical)
{ {
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, OpState->Panel->SplitPercent); r32 SplitX = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
if (Mouse.Pos.x > SplitX) if (Mouse.Pos.x > SplitX)
{ {
PanelToDeleteBounds = GetRightPanelBounds(OpState->Panel, PanelBounds); PanelToDeleteBounds = GetRightPanelBounds(OpState->Panel, PanelBounds);
@ -106,7 +106,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
{ {
drag_panel_border_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_panel_border_operation_state); drag_panel_border_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_panel_border_operation_state);
panel* Panel = OpState->Panel; panel* Panel = OpState->Panel;
rect PanelBounds = OpState->InitialPanelBounds; rect2 PanelBounds = OpState->InitialPanelBounds;
if (OpState->PanelEditMode == PanelEdit_Modify) if (OpState->PanelEditMode == PanelEdit_Modify)
{ {
@ -123,7 +123,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
} }
else else
{ {
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / gs_Height(PanelBounds); Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Rect2Height(PanelBounds);
} }
} }
else if (Panel->SplitDirection == PanelSplit_Vertical) else if (Panel->SplitDirection == PanelSplit_Vertical)
@ -139,7 +139,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
} }
else else
{ {
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / gs_Width(PanelBounds); Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Rect2Width(PanelBounds);
} }
} }
} }
@ -147,7 +147,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
{ {
if (OpState->PanelEdgeDirection == PanelSplit_Horizontal) if (OpState->PanelEdgeDirection == PanelSplit_Horizontal)
{ {
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, OpState->Panel->SplitPercent); r32 SplitY = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
if (Mouse.Pos.y > SplitY) if (Mouse.Pos.y > SplitY)
{ {
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, &State->PanelSystem); ConsolidatePanelsKeepOne(Panel, Panel->Bottom, &State->PanelSystem);
@ -159,7 +159,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
} }
else if (OpState->PanelEdgeDirection == PanelSplit_Vertical) else if (OpState->PanelEdgeDirection == PanelSplit_Vertical)
{ {
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, OpState->Panel->SplitPercent); r32 SplitX = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
if (Mouse.Pos.x > SplitX) if (Mouse.Pos.x > SplitX)
{ {
ConsolidatePanelsKeepOne(Panel, Panel->Left, &State->PanelSystem); ConsolidatePanelsKeepOne(Panel, Panel->Left, &State->PanelSystem);
@ -180,7 +180,7 @@ input_command DragPanelBorderCommands[] = {
}; };
internal void internal void
BeginDragPanelBorder(panel* Panel, panel_edit_mode PanelEditMode, rect PanelBounds, panel_split_direction PanelEdgeDirection, mouse_state Mouse, app_state* State) 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); operation_mode* DragPanelBorder = ActivateOperationModeWithCommands(&State->Modes, DragPanelBorderCommands, UpdateAndRenderDragPanelBorder);
drag_panel_border_operation_state* OpState = CreateOperationState(DragPanelBorder, &State->Modes, drag_panel_border_operation_state); drag_panel_border_operation_state* OpState = CreateOperationState(DragPanelBorder, &State->Modes, drag_panel_border_operation_state);
@ -202,17 +202,17 @@ OPERATION_STATE_DEF(split_panel_operation_state)
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying, // NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
// it stores the value calculated when the operation mode is kicked off. // it stores the value calculated when the operation mode is kicked off.
rect InitialPanelBounds; rect2 InitialPanelBounds;
}; };
OPERATION_RENDER_PROC(UpdateAndRenderSplitPanel) OPERATION_RENDER_PROC(UpdateAndRenderSplitPanel)
{ {
split_panel_operation_state* OpState = (split_panel_operation_state*)Operation.OpStateMemory; split_panel_operation_state* OpState = (split_panel_operation_state*)Operation.OpStateMemory;
rect PanelBounds = OpState->InitialPanelBounds; rect2 PanelBounds = OpState->InitialPanelBounds;
v4 EdgePreviewColor = v4{.3f, .3f, .3f, 1.f}; v4 EdgePreviewColor = v4{.3f, .3f, .3f, 1.f};
r32 MouseDeltaX = GSAbs(Mouse.Pos.x - Mouse.DownPos.x); r32 MouseDeltaX = Abs(Mouse.Pos.x - Mouse.DownPos.x);
r32 MouseDeltaY = GSAbs(Mouse.Pos.y - Mouse.DownPos.y); r32 MouseDeltaY = Abs(Mouse.Pos.y - Mouse.DownPos.y);
v2 EdgePreviewMin = {}; v2 EdgePreviewMin = {};
v2 EdgePreviewMax = {}; v2 EdgePreviewMax = {};
@ -234,19 +234,19 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation)
{ {
split_panel_operation_state* OpState = GetCurrentOperationState(State->Modes, split_panel_operation_state); split_panel_operation_state* OpState = GetCurrentOperationState(State->Modes, split_panel_operation_state);
panel* Panel = OpState->Panel; panel* Panel = OpState->Panel;
rect PanelBounds = OpState->InitialPanelBounds; rect2 PanelBounds = OpState->InitialPanelBounds;
r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x); r32 XDistance = Abs(Mouse.Pos.x - Mouse.DownPos.x);
r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y); r32 YDistance = Abs(Mouse.Pos.y - Mouse.DownPos.y);
if (XDistance > YDistance) if (XDistance > YDistance)
{ {
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / gs_Width(PanelBounds); r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds);
SplitPanelVertically(Panel, XPercent, &State->PanelSystem); SplitPanelVertically(Panel, XPercent, &State->PanelSystem);
} }
else else
{ {
r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / gs_Height(PanelBounds); r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Rect2Height(PanelBounds);
SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem); SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem);
} }
@ -264,7 +264,7 @@ input_command SplitPanelCommands[] = {
}; };
internal void internal void
BeginSplitPanelOperation(panel* Panel, rect PanelBounds, mouse_state Mouse, app_state* State) BeginSplitPanelOperation(panel* Panel, rect2 PanelBounds, mouse_state Mouse, app_state* State)
{ {
operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel); operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel);
split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state); split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state);
@ -278,20 +278,22 @@ BeginSplitPanelOperation(panel* Panel, rect PanelBounds, mouse_state Mouse, app_
#define PANEL_EDGE_CLICK_MAX_DISTANCE 6 #define PANEL_EDGE_CLICK_MAX_DISTANCE 6
internal b32 internal b32
HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, rect PanelBounds, mouse_state Mouse, app_state* State) HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, rect2 PanelBounds, mouse_state Mouse, app_state* State)
{ {
b32 HandledMouseInput = false; b32 HandledMouseInput = false;
rect2 PanelSplitButtonBounds = rect2{ PanelBounds.Min, PanelBounds.Min + v2{25, 25} };
if (Panel->SplitDirection == PanelSplit_NoSplit if (Panel->SplitDirection == PanelSplit_NoSplit
&& PointIsInRange(Mouse.DownPos, PanelBounds.Min, PanelBounds.Min + v2{25, 25})) && PointIsInRect(PanelSplitButtonBounds, Mouse.DownPos))
{ {
BeginSplitPanelOperation(Panel, PanelBounds, Mouse, State); BeginSplitPanelOperation(Panel, PanelBounds, Mouse, State);
HandledMouseInput = true; HandledMouseInput = true;
} }
else if (Panel->SplitDirection == PanelSplit_Horizontal) else if (Panel->SplitDirection == PanelSplit_Horizontal)
{ {
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent); r32 SplitY = LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY); r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.y - SplitY);
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE) if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
{ {
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Horizontal, Mouse, State); BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Horizontal, Mouse, State);
@ -299,13 +301,13 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
} }
else else
{ {
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds); rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds); rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
if (gs_PointIsInRect(Mouse.DownPos, BottomPanelBounds)) if (PointIsInRect(BottomPanelBounds, Mouse.DownPos))
{ {
HandleMouseDownPanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelEditMode, BottomPanelBounds, Mouse, State); HandleMouseDownPanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelEditMode, BottomPanelBounds, Mouse, State);
} }
if (gs_PointIsInRect(Mouse.DownPos, TopPanelBounds)) if (PointIsInRect(TopPanelBounds, Mouse.DownPos))
{ {
HandleMouseDownPanelInteractionOrRecurse(&Panel->Top->Panel, PanelEditMode, TopPanelBounds, Mouse, State); HandleMouseDownPanelInteractionOrRecurse(&Panel->Top->Panel, PanelEditMode, TopPanelBounds, Mouse, State);
} }
@ -313,8 +315,8 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
} }
else if (Panel->SplitDirection == PanelSplit_Vertical) else if (Panel->SplitDirection == PanelSplit_Vertical)
{ {
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent); r32 SplitX = LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX); r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.x - SplitX);
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE) if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
{ {
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Vertical, Mouse, State); BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Vertical, Mouse, State);
@ -322,13 +324,13 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
} }
else else
{ {
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds); rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds); rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
if (gs_PointIsInRect(Mouse.DownPos, LeftPanelBounds)) if (PointIsInRect(LeftPanelBounds, Mouse.DownPos))
{ {
HandleMouseDownPanelInteractionOrRecurse(&Panel->Left->Panel, PanelEditMode, LeftPanelBounds, Mouse, State); HandleMouseDownPanelInteractionOrRecurse(&Panel->Left->Panel, PanelEditMode, LeftPanelBounds, Mouse, State);
} }
if (gs_PointIsInRect(Mouse.DownPos, RightPanelBounds)) if (PointIsInRect(RightPanelBounds, Mouse.DownPos))
{ {
HandleMouseDownPanelInteractionOrRecurse(&Panel->Right->Panel, PanelEditMode, RightPanelBounds, Mouse, State); HandleMouseDownPanelInteractionOrRecurse(&Panel->Right->Panel, PanelEditMode, RightPanelBounds, Mouse, State);
} }
@ -339,7 +341,7 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
} }
internal b32 internal b32
HandleMousePanelInteraction(panel_system* PanelSystem, rect WindowBounds, mouse_state Mouse, app_state* State) HandleMousePanelInteraction(panel_system* PanelSystem, rect2 WindowBounds, mouse_state Mouse, app_state* State)
{ {
b32 HandledMouseInput = false; b32 HandledMouseInput = false;
@ -359,10 +361,10 @@ HandleMousePanelInteraction(panel_system* PanelSystem, rect WindowBounds, mouse_
internal void internal void
DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mouse, render_command_buffer* RenderBuffer) DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mouse, render_command_buffer* RenderBuffer)
{ {
r32 MouseLeftEdgeDistance = GSAbs(Mouse->Pos.x - PanelMin.x); r32 MouseLeftEdgeDistance = Abs(Mouse->Pos.x - PanelMin.x);
r32 MouseRightEdgeDistance = GSAbs(Mouse->Pos.x - PanelMax.x); r32 MouseRightEdgeDistance = Abs(Mouse->Pos.x - PanelMax.x);
r32 MouseTopEdgeDistance = GSAbs(Mouse->Pos.y - PanelMax.y); r32 MouseTopEdgeDistance = Abs(Mouse->Pos.y - PanelMax.y);
r32 MouseBottomEdgeDistance = GSAbs(Mouse->Pos.y - PanelMin.y); r32 MouseBottomEdgeDistance = Abs(Mouse->Pos.y - PanelMin.y);
PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color); PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color);
v4 HighlightColor = v4{.3f, .3f, .3f, 1.f}; v4 HighlightColor = v4{.3f, .3f, .3f, 1.f};
@ -398,41 +400,46 @@ DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mo
} }
internal void internal void
DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBounds, mouse_state Mouse, app_state* State) DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterBounds, mouse_state Mouse, app_state* State)
{ {
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, v2{FooterBounds.Max.x, FooterBounds.Min.y + 25}, v4{.5f, .5f, .5f, 1.f}); 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); PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4);
rect PanelSelectBtnBounds = gs_MakeRectMinWidth(FooterBounds.Min + v2{30, 1}, v2{100, 23}); rect2 PanelSelectBtnBounds = MakeRect2MinDim(FooterBounds.Min + v2{30, 1}, v2{100, 23});
if (Panel->PanelSelectionMenuOpen) if (Panel->PanelSelectionMenuOpen)
{ {
rect ButtonBounds = gs_MakeRectMinWidth(v2{ PanelSelectBtnBounds.Min.x, FooterBounds.Max.y }, v2{ 100, 25 }); rect2 ButtonBounds = MakeRect2MinDim(v2{ PanelSelectBtnBounds.Min.x, FooterBounds.Max.y }, v2{ 100, 25 });
rect2 MenuBounds = rect2
{
ButtonBounds.Min,
v2{
ButtonBounds.Min.x + Rect2Width(ButtonBounds), ButtonBounds.Min.y + (Rect2Height(ButtonBounds) * GlobalPanelDefsCount)
},
};
v2 MenuMin = ButtonBounds.Min;
v2 MenuMax = v2{ButtonBounds.Min.x + gs_Width(ButtonBounds), ButtonBounds.Min.y + (gs_Height(ButtonBounds) * GlobalPanelDefsCount)};
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax)) && !PointIsInRect(MenuBounds, Mouse.DownPos))
{ {
Panel->PanelSelectionMenuOpen = false; Panel->PanelSelectionMenuOpen = false;
} }
for (s32 i = 0; i < GlobalPanelDefsCount; i++) for (s32 i = 0; i < GlobalPanelDefsCount; i++)
{ {
panel_definition Def = GlobalPanelDefs[i]; panel_definition Def = GlobalPanelDefs[i];
string DefName = MakeString(Def.PanelName, Def.PanelNameLength); gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
if (ui_Button(&State->Interface, DefName, ButtonBounds)) if (ui_Button(&State->Interface, DefName, ButtonBounds))
{ {
SetPanelDefinition(Panel, i, State); SetPanelDefinition(Panel, i, State);
Panel->PanelSelectionMenuOpen = false; Panel->PanelSelectionMenuOpen = false;
} }
ButtonBounds = gs_TranslateRectY(ButtonBounds, gs_Height(ButtonBounds)); ButtonBounds = Rect2TranslateY(ButtonBounds, Rect2Height(ButtonBounds));
} }
} }
if (ui_Button(&State->Interface, MakeStringLiteral("Select"), PanelSelectBtnBounds)) if (ui_Button(&State->Interface, MakeString("Select"), PanelSelectBtnBounds))
{ {
Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen; Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen;
} }
@ -440,15 +447,15 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBo
} }
internal void internal void
RenderPanel(panel* Panel, rect PanelBounds, rect WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse) RenderPanel(panel* Panel, rect2 PanelBounds, rect2 WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
{ {
Assert(Panel->PanelDefinitionIndex >= 0); Assert(Panel->PanelDefinitionIndex >= 0);
rect FooterBounds = rect{ rect2 FooterBounds = rect2{
PanelBounds.Min, PanelBounds.Min,
v2{PanelBounds.Max.x, PanelBounds.Min.y + 25}, v2{PanelBounds.Max.x, PanelBounds.Min.y + 25},
}; };
rect PanelViewBounds = rect{ rect2 PanelViewBounds = rect2{
v2{PanelBounds.Min.x, FooterBounds.Max.y}, v2{PanelBounds.Min.x, FooterBounds.Max.y},
PanelBounds.Max, PanelBounds.Max,
}; };
@ -456,7 +463,7 @@ RenderPanel(panel* Panel, rect PanelBounds, rect WindowBounds, render_command_bu
panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex]; panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex];
Definition.Render(*Panel, PanelViewBounds, RenderBuffer, State, Context); Definition.Render(*Panel, PanelViewBounds, RenderBuffer, State, Context);
PushRenderOrthographic(RenderBuffer, WindowBounds.Min.x, WindowBounds.Min.y, WindowBounds.Max.x, WindowBounds.Max.y); PushRenderOrthographic(RenderBuffer, WindowBounds);
DrawPanelFooter(Panel, RenderBuffer, FooterBounds, Mouse, State); DrawPanelFooter(Panel, RenderBuffer, FooterBounds, Mouse, State);
} }
@ -467,12 +474,12 @@ DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mou
{ {
panel_with_layout PanelWithLayout = PanelLayout.Panels[i]; panel_with_layout PanelWithLayout = PanelLayout.Panels[i];
panel* Panel = PanelWithLayout.Panel; panel* Panel = PanelWithLayout.Panel;
rect PanelBounds = PanelWithLayout.Bounds; rect2 PanelBounds = PanelWithLayout.Bounds;
RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse); RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse);
v4 BorderColor = v4{0, 0, 0, 1}; v4 BorderColor = v4{0, 0, 0, 1};
PushRenderOrthographic(RenderBuffer, State->WindowBounds.Min.x, State->WindowBounds.Min.y, State->WindowBounds.Max.x, State->WindowBounds.Max.y); PushRenderOrthographic(RenderBuffer, State->WindowBounds);
DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, Mouse, RenderBuffer); DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, Mouse, RenderBuffer);
} }
} }

View File

@ -13,7 +13,7 @@ enum log_entry_type
struct log_entry struct log_entry
{ {
string Message; gs_string Message;
log_entry_type Type; log_entry_type Type;
}; };
@ -25,11 +25,11 @@ struct event_log
u32 NextEntry; u32 NextEntry;
}; };
#define LogMessage(_Log, _Message) PushLogEntry(_Log, MakeStringLiteral(_Message), LogEntry_Message) #define LogMessage(_Log, _Message) PushLogEntry(_Log, MakeString(_Message), LogEntry_Message)
#define LogError(_Log, _Message) PushLogEntry(_Log, MakeStringLiteral(_Message), LogEntry_Error) #define LogError(_Log, _Message) PushLogEntry(_Log, MakeString(_Message), LogEntry_Error)
internal void internal void
PushLogEntry(event_log* Log, string Message, log_entry_type Type) PushLogEntry(event_log* Log, gs_string Message, log_entry_type Type)
{ {
u32 NewLogIndex = Log->NextEntry++; u32 NewLogIndex = Log->NextEntry++;
if (Log->NextEntry >= LOG_ENTRIES_MAX) if (Log->NextEntry >= LOG_ENTRIES_MAX)

View File

@ -55,7 +55,7 @@ SortNodeNeighbors(u32 ContiguousNodeIndex, gs_list_handle NodeHandle, adjacency_
} }
internal s32* internal s32*
CreateSparseToContiguousMap (pattern_node_workspace Workspace, memory_arena* Scratch) CreateSparseToContiguousMap (pattern_node_workspace Workspace, gs_memory_arena* Scratch)
{ {
s32* Result = PushArray(Scratch, s32, Workspace.Nodes.OnePastLastUsed); s32* Result = PushArray(Scratch, s32, Workspace.Nodes.OnePastLastUsed);
s32 ContiguousIndex = 0; s32 ContiguousIndex = 0;
@ -71,7 +71,7 @@ CreateSparseToContiguousMap (pattern_node_workspace Workspace, memory_arena* Scr
} }
internal void internal void
UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch) UpdateSortedNodes(pattern_node_workspace* Workspace, gs_memory_arena* Scratch)
{ {
ClearNodeWorkspaceStorage(Workspace); ClearNodeWorkspaceStorage(Workspace);
@ -119,22 +119,22 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
RadixSortInPlace(NeighborsListLengths, Workspace->Nodes.Used); RadixSortInPlace(NeighborsListLengths, Workspace->Nodes.Used);
char* OutputCharArray = PushArray(Scratch, char, 1024); char* OutputCharArray = PushArray(Scratch, char, 1024);
string OutputString = MakeString(OutputCharArray, 0, 1024); gs_string Outputgs_string = MakeString(OutputCharArray, 0, 1024);
PrintF(&OutputString, "Neighbors Lists: \n"); PrintF(&Outputgs_string, "Neighbors Lists: \n");
for (u32 d = 0; d < Workspace->Nodes.Used; d++) for (u32 d = 0; d < Workspace->Nodes.Used; d++)
{ {
PrintF(&OutputString, " %d: Node [ %d ] : neighbors { ", d, NeighborsListLengths[d].ID); PrintF(&Outputgs_string, " %d: Node [ %d ] : neighbors { ", d, NeighborsListLengths[d].ID);
adjacency_list* Neighbors = NeighborsLists[d]; adjacency_list* Neighbors = NeighborsLists[d];
while (Neighbors) while (Neighbors)
{ {
PrintF(&OutputString, "%d, ", Neighbors->NodeHandle.Index); PrintF(&Outputgs_string, "%d, ", Neighbors->NodeHandle.Index);
Neighbors = Neighbors->Next; Neighbors = Neighbors->Next;
} }
PrintF(&OutputString, " }\n"); PrintF(&Outputgs_string, " }\n");
} }
NullTerminate(&OutputString); NullTerminate(&Outputgs_string);
// This is a contiguous array. // This is a contiguous array.
b8* NodesVisited = PushArray(Scratch, b8, NodeCount); b8* NodesVisited = PushArray(Scratch, b8, NodeCount);
@ -163,7 +163,7 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
} }
internal void internal void
PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspace, memory_arena* Scratch) PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspace, gs_memory_arena* Scratch)
{ {
pattern_node* NewNode = Workspace->Nodes.TakeElement(); pattern_node* NewNode = Workspace->Nodes.TakeElement();
NewNode->SpecificationIndex = NodeSpecificationIndex; NewNode->SpecificationIndex = NodeSpecificationIndex;
@ -172,7 +172,7 @@ PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspac
} }
internal void internal void
PushNodeConnectionOnWorkspace(gs_list_handle UpstreamNodeHandle, u32 UpstreamPortIndex, gs_list_handle DownstreamNodeHandle, u32 DownstreamPortIndex, pattern_node_workspace* Workspace, memory_arena* Scratch) 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 = {}; pattern_node_connection Connection = {};
Connection.UpstreamNodeHandle = UpstreamNodeHandle; Connection.UpstreamNodeHandle = UpstreamNodeHandle;

View File

@ -59,7 +59,7 @@ struct node_specification
struct node_specification_ struct node_specification_
{ {
node_type Type; node_type Type;
string Identifier; gs_string Identifier;
gsm_struct_type DataType; gsm_struct_type DataType;
}; };
@ -92,7 +92,7 @@ struct pattern_node_workspace
// This is storage for all the structures which follow. // This is storage for all the structures which follow.
// It is cleared when new nodes are added so that the // It is cleared when new nodes are added so that the
// acceleration structures can be recalculated // acceleration structures can be recalculated
memory_arena Storage; gs_memory_arena Storage;
s32* SparseToSortedNodeMap; s32* SparseToSortedNodeMap;
gs_list_handle* SortedNodeHandles; gs_list_handle* SortedNodeHandles;
}; };

View File

@ -16,6 +16,7 @@ struct operation_mode
{ {
input_command_registry Commands; input_command_registry Commands;
operation_render_proc* Render; operation_render_proc* Render;
gs_memory_cursor Memory;
u8* OpStateMemory; u8* OpStateMemory;
}; };
@ -24,28 +25,66 @@ struct operation_mode_system
{ {
s32 ActiveModesCount; s32 ActiveModesCount;
operation_mode ActiveModes[OPERATION_MODES_MAX]; operation_mode ActiveModes[OPERATION_MODES_MAX];
arena_snapshot ModeMemorySnapshots[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 // 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 // temporary memory which then gets freed when the mode is deactivated
memory_arena Arena; 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 = 16; // TODO(Peter): Static number of modes that can be active simultaneously
Result.ModeMemoryPagesFreeList.Data = PushArray(Storage, gs_data, Result.ModeMemoryPagesFreeList.CountMax);
for (u32 Page = 0; Page < Result.ModeMemoryPagesFreeList.CountMax; Page++)
{
// TODO(Peter): 4k pages = page size on windows
Result.ModeMemoryPagesFreeList.Data[Page] = PushSizeToData(Storage, KB(4));
}
Result.ModeMemoryPagesFreeList.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* internal operation_mode*
ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc) ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc)
{ {
operation_mode* Result = 0;
Assert(System->ActiveModesCount < OPERATION_MODES_MAX); Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
operation_mode* Result = 0;
s32 ModeIndex = System->ActiveModesCount++; s32 ModeIndex = System->ActiveModesCount++;
System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena); //System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena);
operation_mode NewMode = {};
System->ActiveModes[ModeIndex] = NewMode;
Result = &System->ActiveModes[ModeIndex]; Result = &System->ActiveModes[ModeIndex];
Result->Memory = CreateMemoryCursor(OperationModeTakeMemoryPage(System));
Result->Render = RenderProc; Result->Render = RenderProc;
return Result; return Result;
} }
@ -57,13 +96,18 @@ ActivateOperationModeWithCommands_(operation_mode_system* System, input_command*
{ {
operation_mode* NewMode = ActivateOperationMode(System, RenderProc); operation_mode* NewMode = ActivateOperationMode(System, RenderProc);
#if 0
InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena); InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena);
for (s32 i = 0; i < CommandsCount; i++) for (s32 i = 0; i < CommandsCount; i++)
{ {
input_command Command = Commands[i]; input_command Command = Commands[i];
RegisterKeyPressCommand(&NewMode->Commands, Command.Key, Command.Flags, Command.Mdfr, Command.Proc); 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; return NewMode;
} }
@ -72,7 +116,8 @@ DeactivateCurrentOperationMode (operation_mode_system* System)
{ {
Assert(System->ActiveModesCount > 0); Assert(System->ActiveModesCount > 0);
s32 ModeIndex = --System->ActiveModesCount; s32 ModeIndex = --System->ActiveModesCount;
ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]); OperationModeFreeMemoryPage(System, System->ActiveModes[ModeIndex].Memory.Data);
//ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]);
} }
#define CreateOperationState(mode, modeSystem, stateType) \ #define CreateOperationState(mode, modeSystem, stateType) \
@ -85,8 +130,12 @@ DeactivateCurrentOperationMode (operation_mode_system* System)
internal u8* internal u8*
CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize) CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize)
{ {
Mode->OpStateMemory = PushSize(&System->Arena, StateSize); // NOTE(Peter): This isn't a problem if this fires, it just means our page size is too small,
return Mode->OpStateMemory; // and its time to make the pages dynamically sized
Assert(Mode->Memory.Data.Size >= StateSize);
u8* Result = PushSizeOnCursor(&Mode->Memory, StateSize).Memory;
Mode->OpStateMemory = Result;
return Result;
} }

View File

@ -72,7 +72,7 @@ struct panel_system
struct panel_with_layout struct panel_with_layout
{ {
panel* Panel; panel* Panel;
rect Bounds; rect2 Bounds;
}; };
struct panel_layout struct panel_layout
@ -205,56 +205,56 @@ ConsolidatePanelsKeepOne(panel* Parent, panel_entry* PanelEntryToKeep, panel_sys
// //
///////////////////////////////// /////////////////////////////////
internal rect internal rect2
GetTopPanelBounds(panel* Panel, rect PanelBounds) GetTopPanelBounds(panel* Panel, rect2 PanelBounds)
{ {
rect Result = {}; rect2 Result = {};
Result.Min = v2{ Result.Min = v2{
PanelBounds.Min.x, PanelBounds.Min.x,
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent) LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y)
}; };
Result.Max = PanelBounds.Max; Result.Max = PanelBounds.Max;
return Result; return Result;
} }
internal rect internal rect2
GetBottomPanelBounds(panel* Panel, rect PanelBounds) GetBottomPanelBounds(panel* Panel, rect2 PanelBounds)
{ {
rect Result = {}; rect2 Result = {};
Result.Min = PanelBounds.Min; Result.Min = PanelBounds.Min;
Result.Max = v2{ Result.Max = v2{
PanelBounds.Max.x, PanelBounds.Max.x,
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent) LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y)
}; };
return Result; return Result;
} }
internal rect internal rect2
GetRightPanelBounds(panel* Panel, rect PanelBounds) GetRightPanelBounds(panel* Panel, rect2 PanelBounds)
{ {
rect Result = {}; rect2 Result = {};
Result.Min = v2{ Result.Min = v2{
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent), LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x),
PanelBounds.Min.y PanelBounds.Min.y
}; };
Result.Max = PanelBounds.Max; Result.Max = PanelBounds.Max;
return Result; return Result;
} }
internal rect internal rect2
GetLeftPanelBounds(panel* Panel, rect PanelBounds) GetLeftPanelBounds(panel* Panel, rect2 PanelBounds)
{ {
rect Result = {}; rect2 Result = {};
Result.Min = PanelBounds.Min; Result.Min = PanelBounds.Min;
Result.Max = v2{ Result.Max = v2{
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent), LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x),
PanelBounds.Max.y PanelBounds.Max.y
}; };
return Result; return Result;
} }
internal void internal void
LayoutPanel(panel* Panel, rect PanelBounds, panel_layout* Layout) LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout)
{ {
if (Panel->SplitDirection == PanelSplit_NoSplit) if (Panel->SplitDirection == PanelSplit_NoSplit)
{ {
@ -264,22 +264,22 @@ LayoutPanel(panel* Panel, rect PanelBounds, panel_layout* Layout)
} }
else if (Panel->SplitDirection == PanelSplit_Horizontal) else if (Panel->SplitDirection == PanelSplit_Horizontal)
{ {
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds); rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds); rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout); LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout);
LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout); LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout);
} }
else if (Panel->SplitDirection == PanelSplit_Vertical) else if (Panel->SplitDirection == PanelSplit_Vertical)
{ {
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds); rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds); rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout); LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout);
LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout); LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout);
} }
} }
internal panel_layout internal panel_layout
GetPanelLayout(panel_system* System, rect WindowBounds, memory_arena* Storage) GetPanelLayout(panel_system* System, rect2 WindowBounds, gs_memory_arena* Storage)
{ {
panel_layout Result = {}; panel_layout Result = {};
Result.PanelsMax = System->PanelsUsed; Result.PanelsMax = System->PanelsUsed;
@ -293,11 +293,11 @@ GetPanelLayout(panel_system* System, rect WindowBounds, memory_arena* Storage)
struct panel_and_bounds struct panel_and_bounds
{ {
panel* Panel; panel* Panel;
rect Bounds; rect2 Bounds;
}; };
internal panel_and_bounds internal panel_and_bounds
GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds) GetPanelContainingPoint(v2 Point, panel* Panel, rect2 PanelBounds)
{ {
panel_and_bounds Result = {0}; panel_and_bounds Result = {0};
@ -308,28 +308,28 @@ GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
} }
else if (Panel->SplitDirection == PanelSplit_Horizontal) else if (Panel->SplitDirection == PanelSplit_Horizontal)
{ {
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds); rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds); rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
if (PointIsInRange(Point, TopPanelBounds.Min, TopPanelBounds.Max)) if (PointIsInRect(TopPanelBounds, Point))
{ {
Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds); Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds);
} }
else if (PointIsInRange(Point, BottomPanelBounds.Min, BottomPanelBounds.Max)) else if (PointIsInRect(BottomPanelBounds, Point))
{ {
Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds); Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds);
} }
} }
else if (Panel->SplitDirection == PanelSplit_Vertical) else if (Panel->SplitDirection == PanelSplit_Vertical)
{ {
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds); rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds); rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
if (PointIsInRange(Point, LeftPanelBounds.Min, LeftPanelBounds.Max)) if (PointIsInRect(LeftPanelBounds, Point))
{ {
Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds); Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds);
} }
else if (PointIsInRange(Point, RightPanelBounds.Min, RightPanelBounds.Max)) else if (PointIsInRect(RightPanelBounds, Point))
{ {
Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds); Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds);
} }
@ -339,7 +339,7 @@ GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
} }
internal panel_and_bounds internal panel_and_bounds
GetPanelContainingPoint(v2 Point, panel_system* PanelSystem, rect WindowBounds) GetPanelContainingPoint(v2 Point, panel_system* PanelSystem, rect2 WindowBounds)
{ {
panel_and_bounds Result = {0}; panel_and_bounds Result = {0};
if (PanelSystem->PanelsUsed > 0) if (PanelSystem->PanelsUsed > 0)

View File

@ -7,22 +7,30 @@
#include <windows.h> #include <windows.h>
#define GS_LANGUAGE_NO_PROFILER_DEFINES #include <math.h> // TODO Remove
#include "..\gs_libs\gs_language.h"
#include "..\gs_libs\gs_radix_sort.h" #include "..\gs_libs\gs_types.h"
#include "..\gs_libs\gs_types.cpp"
//#define GS_LANGUAGE_NO_PROFILER_DEFINES
//#include "..\gs_libs\gs_language.h"
//#include "..\gs_libs\gs_radix_sort.h"
#include "..\gs_libs\gs_list.h" #include "..\gs_libs\gs_list.h"
#include "..\gs_libs\gs_bucket.h" #include "..\gs_libs\gs_bucket.h"
#define GS_MEMORY_TRACK_ALLOCATIONS //#define GS_MEMORY_TRACK_ALLOCATIONS
#include "..\gs_libs\gs_memory_arena.h" //#include "..\gs_libs\gs_memory_arena.h"
#include "..\gs_libs\gs_string.h" #include "..\gs_libs\gs_string.h"
#include "foldhaus_debug.h"
global_variable debug_services* GlobalDebugServices;
#include "..\gs_libs\gs_vector_matrix.h"
#include "foldhaus_debug.h"
global debug_services* GlobalDebugServices;
//#include "..\gs_libs\gs_vector_matrix.h"
#include "..\gs_libs\gs_input.h" #include "..\gs_libs\gs_input.h"
#include "foldhaus_renderer.h" #include "foldhaus_renderer.h"
@ -75,15 +83,6 @@ struct platform_memory_result
platform_memory_error Error; platform_memory_error Error;
}; };
struct texture_buffer
{
u8* Memory;
s32 Width;
s32 Height;
s32 Pitch;
s32 BytesPerPixel;
};
struct system_path struct system_path
{ {
char* Path; char* Path;
@ -91,20 +90,13 @@ struct system_path
s32 IndexOfLastSlash; s32 IndexOfLastSlash;
}; };
#define PLATFORM_READ_ENTIRE_FILE(name) platform_memory_result name(string Path) struct texture_buffer
typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file);
#define PLATFORM_WRITE_ENTIRE_FILE(name) b32 name(string Path, u8* Contents, s32 Size)
typedef PLATFORM_WRITE_ENTIRE_FILE(platform_write_entire_file);
#define PLATFORM_GET_FILE_PATH(name) b32 name(string* PathBuffer, const char* FilterStrings)
typedef PLATFORM_GET_FILE_PATH(platform_get_file_path);
struct platform_file_handler
{ {
platform_read_entire_file* ReadEntireFile; u8* Memory;
platform_write_entire_file* WriteEntireFile; s32 Width;
platform_get_file_path* GetFilePath; s32 Height;
s32 Pitch;
s32 BytesPerPixel;
}; };
#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height) #define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height)
@ -169,50 +161,11 @@ typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint);
#define PLATFORM_THREAD_COUNT 4 #define PLATFORM_THREAD_COUNT 4
#define THREADED_WORK_PROC(name) void name(s32 ThreadID, void* Data)
typedef THREADED_WORK_PROC(threaded_work_proc);
typedef struct work_queue work_queue;
#define PUSH_WORK_ON_QUEUE(name) void name(work_queue* Queue, threaded_work_proc* WorkProc, void* Data, char* JobName)
typedef PUSH_WORK_ON_QUEUE(push_work_on_queue);
#define DO_QUEUE_WORK_UNTIL_DONE(name) void name(work_queue* Queue, s32 ThreadID)
typedef DO_QUEUE_WORK_UNTIL_DONE(do_queue_work_until_done);
#define RESET_WORK_QUEUE(name) void name(work_queue* Queue)
typedef RESET_WORK_QUEUE(reset_work_queue);
struct worker_thread_job
{
void* Data;
threaded_work_proc* WorkProc;
#ifdef DEBUG
char* JobName;
#endif
};
struct work_queue
{
void* SemaphoreHandle;
u32 JobsMax;
u32 volatile JobsCount;
u32 volatile NextJobIndex;
u32 volatile JobsCompleted;
worker_thread_job* Jobs;
// Work Queue
push_work_on_queue* PushWorkOnQueue;
do_queue_work_until_done* DoQueueWorkUntilDone;
reset_work_queue* ResetWorkQueue;
};
RESET_WORK_QUEUE(ResetWorkQueue) RESET_WORK_QUEUE(ResetWorkQueue)
{ {
for (u32 i = 0; i < Queue->JobsMax; i++) for (u32 i = 0; i < Queue->JobsMax; i++)
{ {
Queue->Jobs[i].Data = 0; Queue->Jobs[i].Data = {0};
Queue->Jobs[i].WorkProc = 0; Queue->Jobs[i].WorkProc = 0;
} }
@ -232,11 +185,13 @@ GetSecondsElapsed (s64 Start, s64 End, s64 PerformanceCountFrequency)
struct context struct context
{ {
gs_thread_context ThreadContext;
u8* MemoryBase; u8* MemoryBase;
u32 MemorySize; u32 MemorySize;
b32 WindowIsVisible; b32 WindowIsVisible;
rect WindowBounds; rect2 WindowBounds;
r32 DeltaTime; r32 DeltaTime;
mouse_state Mouse; mouse_state Mouse;
@ -247,59 +202,18 @@ struct context
cleanup_application* CleanupApplication; cleanup_application* CleanupApplication;
// Platform Services // Platform Services
work_queue* GeneralWorkQueue; gs_work_queue* GeneralWorkQueue;
platform_memory_handler PlatformMemory;
platform_file_handler FileHandler;
platform_write_entire_file* PlatformWriteEntireFile;
platform_get_file_path* PlatformGetFilePath;
platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle; platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle;
platform_get_font_info* PlatformGetFontInfo; platform_get_font_info* PlatformGetFontInfo;
platform_draw_font_codepoint* PlatformDrawFontCodepoint; platform_draw_font_codepoint* PlatformDrawFontCodepoint;
platform_get_socket_handle* PlatformGetSocketHandle; platform_get_socket_handle* PlatformGetSocketHandle;
platform_set_socket_option* PlatformSetSocketOption; platform_set_socket_option* PlatformSetSocketOption;
platform_send_to* PlatformSendTo; platform_send_to* PlatformSendTo;
platform_close_socket* PlatformCloseSocket; platform_close_socket* PlatformCloseSocket;
}; };
// File Handler
internal platform_memory_result
ReadEntireFile(platform_file_handler FileHandler, string Path)
{
platform_memory_result Result = FileHandler.ReadEntireFile(Path);
return Result;
}
internal platform_memory_result
ReadEntireFile(context Context, string Path)
{
return ReadEntireFile(Context.FileHandler, Path);
}
internal b32
WriteEntireFile(platform_file_handler FileHandler, string Path, u8* Contents, u32 Size)
{
b32 Result = FileHandler.WriteEntireFile(Path, Contents, Size);
return Result;
}
internal b32
WriteEntireFile(context Context, string Path, u8* Contents, u32 Size)
{
return WriteEntireFile(Context.FileHandler, Path, Contents, Size);
}
internal b32
GetFilePath(platform_file_handler FileHandler, string* PathBuffer, char* FilterStrings)
{
b32 Result = FileHandler.GetFilePath(PathBuffer, (const char*)FilterStrings);
return Result;
}
internal b32
GetFilePath(context Context, string* PathBuffer, char* FilterStrings)
{
return GetFilePath(Context.FileHandler, PathBuffer, FilterStrings);
}
#define FOLDHAUS_PLATFORM_H #define FOLDHAUS_PLATFORM_H
#endif // FOLDHAUS_PLATFORM_H #endif // FOLDHAUS_PLATFORM_H

View File

@ -110,8 +110,8 @@ RenderCommandBuffer (render_command_buffer CommandBuffer)
glViewport(Command->ViewOffsetX, Command->ViewOffsetY, glViewport(Command->ViewOffsetX, Command->ViewOffsetY,
Command->ViewWidth, Command->ViewHeight); Command->ViewWidth, Command->ViewHeight);
LoadModelView(Command->ModelView.E); LoadModelView(Command->ModelView.Array);
LoadProjection(Command->Projection.E); LoadProjection(Command->Projection.Array);
if (Command->UseDepthBuffer) if (Command->UseDepthBuffer)
{ {

View File

@ -19,65 +19,71 @@ struct camera
inline m44 inline m44
GetCameraModelViewMatrix (camera Camera) GetCameraModelViewMatrix (camera Camera)
{ {
#if 0 m44 RotationMatrix = M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt));
// Forward m44 PositionMatrix = M44Translation(ToV4Point(-Camera.Position));
v4 CamForward = V4(Normalize(Camera.Position - Camera.LookAt), 0); m44 ModelViewMatrix = RotationMatrix * PositionMatrix;
// Right
v4 CamRight = Normalize(Cross(v4{0, 1, 0, 0}, CamForward));
// Up
v4 CamUp = Normalize(Cross(CamForward, CamRight));
r32 X = Camera.Position.x;
r32 Y = Camera.Position.y;
r32 Z = Camera.Position.z;
m44 RotationMatrix = M44(
CamRight.x, CamUp.x, CamForward.x, 0,
CamRight.y, CamUp.y, CamForward.y, 0,
CamRight.z, CamUp.z, CamForward.z, 0,
0, 0, 0, 1);
m44 PositionMatrix = M44(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
-X, -Y, -Z, 1
);
#else
m44 RotationMatrix = GetLookAtMatrix(V4(Camera.Position, 1), V4(Camera.LookAt, 1));
m44 PositionMatrix = GetPositionM44(V4(Camera.Position, 1));
#endif
m44 ModelViewMatrix = PositionMatrix * RotationMatrix;
return ModelViewMatrix; return ModelViewMatrix;
} }
inline m44 inline m44
GetCameraPerspectiveProjectionMatrix(camera Camera) GetCameraPerspectiveProjectionMatrix(camera Camera)
{ {
r32 Top = Camera.Near * GSTan((Camera.FieldOfView / 2.0f)); m44 Result = M44ProjectionPerspective(Camera.FieldOfView, Camera.AspectRatio, Camera.Near, Camera.Far);
r32 Bottom = -Top; return Result;
r32 Right = Top * Camera.AspectRatio; }
r32 Left = -Right;
r32 A = ((Right + Left) / (Right - Left)); internal m44
r32 B = ((Top + Bottom) / (Top - Bottom)); GetCameraMatrix(camera Camera)
r32 C = -((Camera.Far + Camera.Near) / (Camera.Far - Camera.Near)); {
r32 D = -((2 * Camera.Far * Camera.Near) / (Camera.Far - Camera.Near)); m44 ModelView = GetCameraModelViewMatrix(Camera);
m44 Projection = GetCameraPerspectiveProjectionMatrix(Camera);
m44 Result = Projection * ModelView;
return Result;
}
r32 E = ((2 * Camera.Near) / (Right - Left)); internal v2
r32 F = ((2 * Camera.Near) / (Top - Bottom)); 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);
m44 PerspectiveProjectionMatrix = return ScreenPosition;
{ }
E, 0, A, 0,
0, F, B, 0,
0, 0, C, D,
0, 0, -1, 0
};
return PerspectiveProjectionMatrix; 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 // Render Commands
@ -200,7 +206,7 @@ struct render_command_set_render_mode
typedef u8* renderer_realloc(u8* Base, s32 CurrentSize, s32 NewSize); typedef u8* renderer_realloc(u8* Base, s32 CurrentSize, s32 NewSize);
#define COMMAND_BUFFER_MIN_GROW_SIZE Megabytes(2) #define COMMAND_BUFFER_MIN_GROW_SIZE MB(2)
struct render_command_buffer struct render_command_buffer
{ {
@ -257,7 +263,7 @@ ResizeBufferIfNecessary(render_command_buffer* Buffer, s32 DataSize)
// NewSize = Buffer->CommandMemorySize + (2 * DataSize); // NewSize = Buffer->CommandMemorySize + (2 * DataSize);
s32 SpaceAvailable = Buffer->CommandMemorySize - Buffer->CommandMemoryUsed; s32 SpaceAvailable = Buffer->CommandMemorySize - Buffer->CommandMemoryUsed;
s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point
s32 AdditionSize = GSMax(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE); s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
s32 NewSize = Buffer->CommandMemorySize + AdditionSize; s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory, Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory,
Buffer->CommandMemorySize, Buffer->CommandMemorySize,
@ -285,7 +291,7 @@ PushQuad3DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* C
internal s32 internal s32
PushQuad2DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* Constructor, s32 QuadCount, s32 DataSize, u8* MemStart) PushQuad2DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* Constructor, s32 QuadCount, s32 DataSize, u8* MemStart)
{ {
GSZeroMemory(MemStart, DataSize); ZeroMemoryBlock(MemStart, DataSize);
Constructor->Max = QuadCount; Constructor->Max = QuadCount;
Constructor->Count = 0; Constructor->Count = 0;
@ -316,6 +322,15 @@ struct quad_batch_constructor_reserved_range
s32 OnePastLast; 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;
Result.Start = Result.OnePastLast - TrisNeeded;
return Result;
}
internal quad_batch_constructor_reserved_range internal quad_batch_constructor_reserved_range
ThreadSafeReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded) ThreadSafeReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded)
{ {
@ -331,6 +346,8 @@ SetTri3DInBatch (render_quad_batch_constructor* Constructor, s32 TriIndex,
v2 UV0, v2 UV1, v2 UV2, v2 UV0, v2 UV1, v2 UV2,
v4 C0, v4 C1, v4 C2) 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 // Vertecies
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 0)] = P0; 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, 1)] = P1;
@ -355,6 +372,7 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
v4 C0, v4 C1, v4 C2) v4 C0, v4 C1, v4 C2)
{ {
DEBUG_TRACK_FUNCTION; 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); s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor);
SetTri3DInBatch(Constructor, Tri, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2); SetTri3DInBatch(Constructor, Tri, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
}; };
@ -362,7 +380,7 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
internal void internal void
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color) 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); Assert(Constructor->Count + 2 <= Constructor->Max);
PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color, Color, Color); 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); PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color, Color, Color);
} }
@ -373,7 +391,7 @@ PushQuad3DOnBatch (render_quad_batch_constructor* Constructor,
v2 UV0, v2 UV1, v2 UV2, v2 UV3, v2 UV0, v2 UV1, v2 UV2, v2 UV3,
v4 C0, v4 C1, v4 C2, v4 C3) v4 C0, v4 C1, v4 C2, v4 C3)
{ {
Assert(Constructor->Count < Constructor->Max); Assert(Constructor->Count <= Constructor->Max);
PushTri3DOnBatch(Constructor, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2); PushTri3DOnBatch(Constructor, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
PushTri3DOnBatch(Constructor, P0, P2, P3, UV0, UV2, UV3, C0, C2, C3); PushTri3DOnBatch(Constructor, P0, P2, P3, UV0, UV2, UV3, C0, C2, C3);
} }
@ -472,7 +490,7 @@ internal void
PushLine2DOnBatch (render_quad_batch_constructor* Constructor, v2 P0, v2 P1, r32 Thickness, v4 Color) PushLine2DOnBatch (render_quad_batch_constructor* Constructor, v2 P0, v2 P1, r32 Thickness, v4 Color)
{ {
r32 HalfThickness = Thickness / 2.0f; r32 HalfThickness = Thickness / 2.0f;
v2 Perpendicular = Normalize(PerpendicularCCW(P1 - P0)) * HalfThickness; v2 Perpendicular = V2Normalize(V2PerpendicularCCW(P1 - P0)) * HalfThickness;
PushQuad2DOnBatch(Constructor, P0 - Perpendicular, P1 - Perpendicular, P1 + Perpendicular, P0 + Perpendicular, PushQuad2DOnBatch(Constructor, P0 - Perpendicular, P1 - Perpendicular, P1 + Perpendicular, P0 + Perpendicular,
v2{0, 0}, v2{1, 1}, Color); v2{0, 0}, v2{1, 1}, Color);
@ -501,8 +519,8 @@ PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
{ {
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode); render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
Command->ModelView = GetCameraModelViewMatrix(Camera); Command->ModelView = M44Transpose(GetCameraModelViewMatrix(Camera));
Command->Projection = GetCameraPerspectiveProjectionMatrix(Camera); Command->Projection = M44Transpose(GetCameraPerspectiveProjectionMatrix(Camera));
Command->ViewOffsetX = (r32)OffsetX; Command->ViewOffsetX = (r32)OffsetX;
Command->ViewOffsetY = (r32)OffsetY; Command->ViewOffsetY = (r32)OffsetY;
@ -514,25 +532,18 @@ PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
return Command; 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 internal void
PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight) 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); render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
Command->ModelView = m44{ Command->ModelView = M44Identity();
1, 0, 0, 0, Command->Projection = M44ProjectionOrtho((r32)ViewWidth, (r32)ViewHeight, 0, 100, ViewWidth, 0, ViewHeight, 0);
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
r32 a = 2.0f / ViewWidth;
r32 b = 2.0f / ViewHeight;
Command->Projection = m44{
a, 0, 0, 0,
0, b, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1
};
Command->ViewOffsetX = (r32)OffsetX; Command->ViewOffsetX = (r32)OffsetX;
Command->ViewOffsetY = (r32)OffsetY; Command->ViewOffsetY = (r32)OffsetY;
@ -542,6 +553,12 @@ PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
Command->UseDepthBuffer = false;; 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 internal void
PushRenderClearScreen (render_command_buffer* Buffer) PushRenderClearScreen (render_command_buffer* Buffer)
{ {
@ -571,6 +588,13 @@ PushRenderQuad2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 Color)
PushQuad2DOnBatch(&Batch, Min, Max, Color); PushQuad2DOnBatch(&Batch, Min, 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 internal void
PushRenderLine2D (render_command_buffer* Buffer, v2 P0, v2 P1, r32 Thickness, v4 Color) PushRenderLine2D (render_command_buffer* Buffer, v2 P0, v2 P1, r32 Thickness, v4 Color)
{ {

View File

@ -10,42 +10,42 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <gs_string.h>
#include "gs/gs_language.h" #include "gs/gs_language.h"
#include "gs/gs_string.h" #include "gs/gs_string.h"
#include "../meta/gs_meta_lexer.h" #include "../meta/gs_meta_lexer.h"
#include "gs/gs_vector.h" #include "gs/gs_vector.h"
#define STRING_BUFFER_SIZE 512 #define gs_string_BUFFER_SIZE 512
struct string_buffer struct gs_string_buffer
{ {
char* Memory; char* Memory;
s32 Size; s32 Size;
string_buffer* Next; gs_string_buffer* Next;
}; };
struct string_writer struct gs_string_writer
{ {
char* Cursor; char* Cursor;
s32 UsedInString; s32 UsedIngs_string;
string_buffer* Buffer; gs_string_buffer* Buffer;
}; };
internal string_buffer* internal gs_string_buffer*
GrowStringBuffer (string_buffer* Buffer) Growgs_stringBuffer (gs_string_buffer* Buffer)
{ {
string_buffer* Result; gs_string_buffer* Result;
if (Buffer->Next) if (Buffer->Next)
{ {
Result = GrowStringBuffer(Buffer->Next); Result = Growgs_stringBuffer(Buffer->Next);
} }
else else
{ {
Result = (string_buffer*)malloc(sizeof(string_buffer)); Result = (gs_string_buffer*)malloc(sizeof(gs_string_buffer));
Result->Memory = (char*)malloc(sizeof(char) * STRING_BUFFER_SIZE); Result->Memory = (char*)malloc(sizeof(char) * gs_string_BUFFER_SIZE);
memset(Result->Memory, 0, STRING_BUFFER_SIZE); memset(Result->Memory, 0, gs_string_BUFFER_SIZE);
Result->Size = STRING_BUFFER_SIZE; Result->Size = gs_string_BUFFER_SIZE;
Result->Next = 0; Result->Next = 0;
Buffer->Next = Result; Buffer->Next = Result;
@ -54,28 +54,28 @@ GrowStringBuffer (string_buffer* Buffer)
} }
internal void internal void
WriteString(string_writer* Writer, char* String, s32 Length) Writegs_string(gs_string_writer* Writer, char* gs_string, s32 Length)
{ {
char* Src = String; char* Src = gs_string;
char* Dst = Writer->Cursor; char* Dst = Writer->Cursor;
s32 LengthWritten = 0; s32 LengthWritten = 0;
while (*Src && Writer->UsedInString < Writer->Buffer->Size &&LengthWritten < Length) while (*Src && Writer->UsedIngs_string < Writer->Buffer->Size &&LengthWritten < Length)
{ {
LengthWritten++; LengthWritten++;
*Dst++ = *Src++; *Dst++ = *Src++;
Writer->UsedInString++; Writer->UsedIngs_string++;
} }
Writer->Cursor = Dst; Writer->Cursor = Dst;
if (*Src && Writer->UsedInString == Writer->Buffer->Size) if (*Src && Writer->UsedIngs_string == Writer->Buffer->Size)
{ {
*(Dst - 1) = 0; // Null terminate the buffer *(Dst - 1) = 0; // Null terminate the buffer
Writer->Buffer = GrowStringBuffer(Writer->Buffer); Writer->Buffer = Growgs_stringBuffer(Writer->Buffer);
Writer->Cursor = Writer->Buffer->Memory; Writer->Cursor = Writer->Buffer->Memory;
Writer->UsedInString = 0; Writer->UsedIngs_string = 0;
WriteString(Writer, (Src - 1), (Length - LengthWritten) + 1); Writegs_string(Writer, (Src - 1), (Length - LengthWritten) + 1);
} }
} }
@ -141,15 +141,15 @@ int main(int ArgCount, char* Args[])
control_box_pairs* StartPair = NextControlBoxPair; control_box_pairs* StartPair = NextControlBoxPair;
s32 PairsCount = 0; s32 PairsCount = 0;
if (StringsEqual(Tokenizer.At, "EOF")) if (gs_stringsEqual(Tokenizer.At, "EOF"))
{ {
break; break;
} }
EatToCharacterInclusive(&Tokenizer, '{'); EatToCharacterInclusive(&Tokenizer, '{');
EatWhitespace(&Tokenizer); EatWhitespace(&Tokenizer);
Assert(StringsEqual(Tokenizer.At, "neighbors: [")); Assert(gs_stringsEqual(Tokenizer.At, "neighbors: ["));
Tokenizer.At += StringLength("neighbors: ["); Tokenizer.At += gs_stringLength("neighbors: [");
// Parse Neighbors // Parse Neighbors
while(*Tokenizer.At && *Tokenizer.At != ']') while(*Tokenizer.At && *Tokenizer.At != ']')
@ -177,8 +177,8 @@ int main(int ArgCount, char* Args[])
EatWhitespace(&Tokenizer); EatWhitespace(&Tokenizer);
//Parse IP //Parse IP
Assert(StringsEqual(Tokenizer.At, "ip: ")); Assert(gs_stringsEqual(Tokenizer.At, "ip: "));
Tokenizer.At += StringLength("ip: "); Tokenizer.At += gs_stringLength("ip: ");
NextControlBox->Address = (char*)malloc(sizeof(char) * 13); NextControlBox->Address = (char*)malloc(sizeof(char) * 13);
memcpy(NextControlBox->Address, Tokenizer.At, 13); memcpy(NextControlBox->Address, Tokenizer.At, 13);
Tokenizer.At += 13; Tokenizer.At += 13;
@ -186,27 +186,27 @@ int main(int ArgCount, char* Args[])
// Parse X // Parse X
EatWhitespace(&Tokenizer); EatWhitespace(&Tokenizer);
Assert(StringsEqual(Tokenizer.At, "x: ")); Assert(gs_stringsEqual(Tokenizer.At, "x: "));
Tokenizer.At += StringLength("x: "); Tokenizer.At += gs_stringLength("x: ");
NextControlBox->X = ParseFloat(Tokenizer.At); NextControlBox->X = ParseFloat(Tokenizer.At);
EatToCharacterInclusive(&Tokenizer, ';'); EatToCharacterInclusive(&Tokenizer, ';');
// Parse Y // Parse Y
EatWhitespace(&Tokenizer); EatWhitespace(&Tokenizer);
Assert(StringsEqual(Tokenizer.At, "y: ")); Assert(gs_stringsEqual(Tokenizer.At, "y: "));
Tokenizer.At += StringLength("y: "); Tokenizer.At += gs_stringLength("y: ");
NextControlBox->Y = ParseFloat(Tokenizer.At); NextControlBox->Y = ParseFloat(Tokenizer.At);
EatToCharacterInclusive(&Tokenizer, ';'); EatToCharacterInclusive(&Tokenizer, ';');
// Parse Z // Parse Z
EatWhitespace(&Tokenizer); EatWhitespace(&Tokenizer);
Assert(StringsEqual(Tokenizer.At, "z: ")); Assert(gs_stringsEqual(Tokenizer.At, "z: "));
Tokenizer.At += StringLength("z: "); Tokenizer.At += gs_stringLength("z: ");
NextControlBox->Z = ParseFloat(Tokenizer.At); NextControlBox->Z = ParseFloat(Tokenizer.At);
EatToCharacterInclusive(&Tokenizer, ';'); EatToCharacterInclusive(&Tokenizer, ';');
// Parse ID // Parse ID
EatWhitespace(&Tokenizer); EatWhitespace(&Tokenizer);
Assert(StringsEqual(Tokenizer.At, "id: ")); Assert(gs_stringsEqual(Tokenizer.At, "id: "));
Tokenizer.At += StringLength("id: "); Tokenizer.At += gs_stringLength("id: ");
NextControlBox->ID = ParseSignedInt(Tokenizer.At); NextControlBox->ID = ParseSignedInt(Tokenizer.At);
EatToCharacterInclusive(&Tokenizer, ';'); EatToCharacterInclusive(&Tokenizer, ';');
@ -278,36 +278,36 @@ int main(int ArgCount, char* Args[])
} }
string_buffer OutputFileBuffer = {}; gs_string_buffer OutputFileBuffer = {};
OutputFileBuffer.Memory = (char*)malloc(sizeof(char) * STRING_BUFFER_SIZE); OutputFileBuffer.Memory = (char*)malloc(sizeof(char) * gs_string_BUFFER_SIZE);
OutputFileBuffer.Size = STRING_BUFFER_SIZE; OutputFileBuffer.Size = gs_string_BUFFER_SIZE;
OutputFileBuffer.Next = 0; OutputFileBuffer.Next = 0;
string_writer RefWriter = {}; gs_string_writer RefWriter = {};
RefWriter.Cursor = OutputFileBuffer.Memory; RefWriter.Cursor = OutputFileBuffer.Memory;
RefWriter.UsedInString = 0; RefWriter.UsedIngs_string = 0;
RefWriter.Buffer = &OutputFileBuffer; RefWriter.Buffer = &OutputFileBuffer;
string_writer* Writer = &RefWriter; gs_string_writer* Writer = &RefWriter;
char StringBuffer[512]; char gs_stringBuffer[512];
s32 Len = 0; s32 Len = 0;
Len = sprintf_s(StringBuffer, 512, "control_box_count %d\n", ControlBoxesUsed); Len = sprintf_s(gs_stringBuffer, 512, "control_box_count %d\n", ControlBoxesUsed);
WriteString(Writer, StringBuffer, Len); Writegs_string(Writer, gs_stringBuffer, Len);
Len = sprintf_s(StringBuffer, 512, "led_strip_count %d\n\n", ControlBoxPairsUsed); Len = sprintf_s(gs_stringBuffer, 512, "led_strip_count %d\n\n", ControlBoxPairsUsed);
WriteString(Writer, StringBuffer, Len); Writegs_string(Writer, gs_stringBuffer, Len);
for (s32 c = 0; c < ControlBoxesUsed; c++) for (s32 c = 0; c < ControlBoxesUsed; c++)
{ {
control_box* Box = ControlBoxes + c; control_box* Box = ControlBoxes + c;
Len = sprintf_s(StringBuffer, 512, Len = sprintf_s(gs_stringBuffer, 512,
"control_box { %d, \"%s\", (%f, %f, %f) }\n", "control_box { %d, \"%s\", (%f, %f, %f) }\n",
Box->ID, Box->Address, Box->ID, Box->Address,
Box->X, Box->Y, Box->Z); Box->X, Box->Y, Box->Z);
WriteString(Writer, StringBuffer, Len); Writegs_string(Writer, gs_stringBuffer, Len);
} }
WriteString(Writer, "\n", 1); Writegs_string(Writer, "\n", 1);
#define UNIVERSES_PER_BOX 25 #define UNIVERSES_PER_BOX 25
s32 UniversesPerBox[64]; s32 UniversesPerBox[64];
@ -316,7 +316,7 @@ int main(int ArgCount, char* Args[])
UniversesPerBox[u] = UNIVERSES_PER_BOX * u; UniversesPerBox[u] = UNIVERSES_PER_BOX * u;
} }
char LEDStripFormatString[] = "led_strip { %d, %d, %d, INTERPOLATE_POINTS, (%f, %f, %f), (%f, %f, %f), 144 } \n"; 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++) for (s32 s = 0; s < ControlBoxPairsUsed; s++)
{ {
control_box_pairs* Pair = ControlBoxPairs + s; control_box_pairs* Pair = ControlBoxPairs + s;
@ -332,15 +332,15 @@ int main(int ArgCount, char* Args[])
r32 EndY = ControlBoxes[Pair->End].Y; r32 EndY = ControlBoxes[Pair->End].Y;
r32 EndZ = ControlBoxes[Pair->End].Z; r32 EndZ = ControlBoxes[Pair->End].Z;
Len = sprintf_s(StringBuffer, 512, Len = sprintf_s(gs_stringBuffer, 512,
LEDStripFormatString, LEDStripFormatgs_string,
Pair->Start, Universe, 0, Pair->Start, Universe, 0,
StartX, StartY, StartZ, StartX, StartY, StartZ,
EndX, EndY, EndZ); EndX, EndY, EndZ);
WriteString(Writer, StringBuffer, Len); Writegs_string(Writer, gs_stringBuffer, Len);
} }
WriteString(Writer, "\n", 1); Writegs_string(Writer, "\n", 1);
for (s32 sp = 0; sp < ExtraStripsUsed; sp++) for (s32 sp = 0; sp < ExtraStripsUsed; sp++)
{ {
@ -349,20 +349,20 @@ int main(int ArgCount, char* Args[])
s32 Universe = UniversesPerBox[Strip->BoxID]; s32 Universe = UniversesPerBox[Strip->BoxID];
UniversesPerBox[Strip->BoxID]++; UniversesPerBox[Strip->BoxID]++;
Len = sprintf_s(StringBuffer, 512, Len = sprintf_s(gs_stringBuffer, 512,
LEDStripFormatString, LEDStripFormatgs_string,
Strip->BoxID, Universe, 0, Strip->BoxID, Universe, 0,
Strip->Start.x, Strip->Start.y, Strip->Start.z, Strip->Start.x, Strip->Start.y, Strip->Start.z,
Strip->End.x, Strip->End.y, Strip->End.z); Strip->End.x, Strip->End.y, Strip->End.z);
WriteString(Writer, StringBuffer, Len); Writegs_string(Writer, gs_stringBuffer, Len);
} }
WriteString(Writer, "END_OF_ASSEMBLY_FILE", StringLength("END_OF_ASSEMBLY_FILE")); Writegs_string(Writer, "END_OF_ASSEMBLY_FILE", gs_stringLength("END_OF_ASSEMBLY_FILE"));
*Writer->Cursor = 0; *Writer->Cursor = 0;
FILE* OutputFile = fopen("F:/data/radialumia.fold", "w"); FILE* OutputFile = fopen("F:/data/radialumia.fold", "w");
string_buffer* BufferCursor = &OutputFileBuffer; gs_string_buffer* BufferCursor = &OutputFileBuffer;
while(BufferCursor) while(BufferCursor)
{ {
fprintf(OutputFile, BufferCursor->Memory); fprintf(OutputFile, BufferCursor->Memory);

View File

@ -1,19 +1,18 @@
enum panel_type { enum panel_type {
PanelType_FileView, PanelType_FileView,
PanelType_SculptureView, PanelType_SculptureView,
PanelType_AnimationTimeline, PanelType_AnimationTimeline,
PanelType_DMXView, PanelType_DMXView,
PanelType_HierarchyView, PanelType_HierarchyView,
PanelType_NodeGraph, PanelType_NodeGraph,
PanelType_ProfilerView, PanelType_ProfilerView,
}; };
global_variable s32 GlobalPanelDefsCount = 7; global s32 GlobalPanelDefsCount = 6;
global_variable panel_definition GlobalPanelDefs[] = { global panel_definition GlobalPanelDefs[] = {
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount }, { "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 }, { "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 }, { "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 }, { "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 }, { "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
{ "Node Graph", 10, NodeGraph_Init, NodeGraph_Cleanup, NodeGraph_Render, NodeGraph_Commands, NodeGraph_CommandsCount }, { "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
}; };

View File

@ -1,40 +1,41 @@
enum gsm_meta_tag_type enum gsm_meta_tag_type
{ {
MetaTag_panel_type_file_view, MetaTag_panel_type_file_view,
MetaTag_panel_type_node_graph, MetaTag_panel_type_node_graph,
MetaTag_node_output, MetaTag_node_output,
MetaTag_node_struct, MetaTag_node_struct,
MetaTag_panel_cleanup, MetaTag_panel_cleanup,
MetaTag_node_input, MetaTag_node_input,
MetaTag_panel_init, MetaTag_panel_init,
MetaTag_panel_type_animation_timeline, MetaTag_panel_type_animation_timeline,
MetaTag_panel_commands, MetaTag_panel_commands,
MetaTag_panel_type_sculpture_view, MetaTag_panel_type_sculpture_view,
MetaTag_node_proc, MetaTag_node_proc,
MetaTag_panel_type_hierarchy, MetaTag_panel_type_hierarchy,
MetaTag_panel_type_profiler, MetaTag_panel_type_profiler,
MetaTag_panel_render, MetaTag_panel_render,
MetaTag_panel_type_dmx_view, MetaTag_panel_type_dmx_view,
}; };
gsm_meta_tag MetaTagStrings[] = { gsm_meta_tag MetaTaggs_strings[] = {
{ "panel_type_file_view", 20 }, { "panel_type_file_view", 20 },
{ "panel_type_node_graph", 21 }, { "panel_type_node_graph", 21 },
{ "node_output", 11 }, { "node_output", 11 },
{ "node_struct", 11 }, { "node_struct", 11 },
{ "panel_cleanup", 13 }, { "panel_cleanup", 13 },
{ "node_input", 10 }, { "node_input", 10 },
{ "panel_init", 10 }, { "panel_init", 10 },
{ "panel_type_animation_timeline", 29 }, { "panel_type_animation_timeline", 29 },
{ "panel_commands", 14 }, { "panel_commands", 14 },
{ "panel_type_sculpture_view", 25 }, { "panel_type_sculpture_view", 25 },
{ "node_proc", 9 }, { "node_proc", 9 },
{ "panel_type_hierarchy", 20 }, { "panel_type_hierarchy", 20 },
{ "panel_type_profiler", 19 }, { "panel_type_profiler", 19 },
{ "panel_render", 12 }, { "panel_render", 12 },
{ "panel_type_dmx_view", 19 }, { "panel_type_dmx_view", 19 },
}; };
enum gsm_struct_type enum gsm_struct_type
{ {
gsm_StructType_r32,
gsm_StructType_solid_color_data, gsm_StructType_solid_color_data,
gsm_StructType_v4, gsm_StructType_v4,
gsm_StructType_float, gsm_StructType_float,
@ -42,85 +43,68 @@ enum gsm_struct_type
gsm_StructType_pixel, gsm_StructType_pixel,
gsm_StructType_u8, gsm_StructType_u8,
gsm_StructType_s32, gsm_StructType_s32,
gsm_StructType_sin_wave_data,
gsm_StructType_r32,
gsm_StructType_revolving_discs_data, gsm_StructType_revolving_discs_data,
gsm_StructType_vertical_color_fade_data, gsm_StructType_vertical_color_fade_data,
gsm_StructType_multiply_patterns_data,
gsm_StructType_Count, gsm_StructType_Count,
}; };
static gsm_struct_member_type_info StructMembers_v4[] = { static gsm_struct_member_type_info StructMembers_v4[] = {
{ "x", 1, (u64)&((v4*)0)->x, {}, 0}, { "x", 1, (u64)&((v4*)0)->x, {}, 0},
{ "y", 1, (u64)&((v4*)0)->y, {}, 0}, { "y", 1, (u64)&((v4*)0)->y, {}, 0},
{ "z", 1, (u64)&((v4*)0)->z, {}, 0}, { "z", 1, (u64)&((v4*)0)->z, {}, 0},
{ "w", 1, (u64)&((v4*)0)->w, {}, 0}, { "w", 1, (u64)&((v4*)0)->w, {}, 0},
{ "r", 1, (u64)&((v4*)0)->r, {}, 0}, { "r", 1, (u64)&((v4*)0)->r, {}, 0},
{ "g", 1, (u64)&((v4*)0)->g, {}, 0}, { "g", 1, (u64)&((v4*)0)->g, {}, 0},
{ "b", 1, (u64)&((v4*)0)->b, {}, 0}, { "b", 1, (u64)&((v4*)0)->b, {}, 0},
{ "a", 1, (u64)&((v4*)0)->a, {}, 0}, { "a", 1, (u64)&((v4*)0)->a, {}, 0},
{ "xy", 2, (u64)&((v4*)0)->xy, {}, 0}, { "xy", 2, (u64)&((v4*)0)->xy, {}, 0},
{ "yz", 2, (u64)&((v4*)0)->yz, {}, 0}, { "yz", 2, (u64)&((v4*)0)->yz, {}, 0},
{ "xyz", 3, (u64)&((v4*)0)->xyz, {}, 0}, { "xyz", 3, (u64)&((v4*)0)->xyz, {}, 0},
{ "z", 1, (u64)&((v4*)0)->z, {}, 0}, { "z", 1, (u64)&((v4*)0)->z, {}, 0},
{ "E", 1, (u64)&((v4*)0)->E, {}, 0}, { "E", 1, (u64)&((v4*)0)->E, {}, 0},
}; };
static gsm_struct_member_type_info StructMembers_pixel[] = { static gsm_struct_member_type_info StructMembers_pixel[] = {
{ "R", 1, (u64)&((pixel*)0)->R, {}, 0}, { "R", 1, (u64)&((pixel*)0)->R, {}, 0},
{ "G", 1, (u64)&((pixel*)0)->G, {}, 0}, { "G", 1, (u64)&((pixel*)0)->G, {}, 0},
{ "B", 1, (u64)&((pixel*)0)->B, {}, 0}, { "B", 1, (u64)&((pixel*)0)->B, {}, 0},
{ "Channels", 8, (u64)&((pixel*)0)->Channels, {}, 0}, { "Channels", 8, (u64)&((pixel*)0)->Channels, {}, 0},
}; };
static gsm_struct_member_type_info StructMembers_color_buffer[] = { static gsm_struct_member_type_info StructMembers_color_buffer[] = {
{ "LedPositions", 12, (u64)&((color_buffer*)0)->LedPositions, {}, 0}, { "LedPositions", 12, (u64)&((color_buffer*)0)->LedPositions, {}, 0},
{ "Colors", 6, (u64)&((color_buffer*)0)->Colors, {}, 0}, { "Colors", 6, (u64)&((color_buffer*)0)->Colors, {}, 0},
{ "LEDCount", 8, (u64)&((color_buffer*)0)->LEDCount, {}, 0}, { "LEDCount", 8, (u64)&((color_buffer*)0)->LEDCount, {}, 0},
}; };
static gsm_struct_member_type_info StructMembers_solid_color_data[] = { static gsm_struct_member_type_info StructMembers_solid_color_data[] = {
{ "Color", 5, (u64)&((solid_color_data*)0)->Color, {MetaTag_node_input, }, 1}, { "Color", 5, (u64)&((solid_color_data*)0)->Color, {MetaTag_node_input, }, 1},
{ "Result", 6, (u64)&((solid_color_data*)0)->Result, {MetaTag_node_output, }, 1}, { "Result", 6, (u64)&((solid_color_data*)0)->Result, {MetaTag_node_output, }, 1},
};
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
{ "Period", 6, (u64)&((sin_wave_data*)0)->Period, {MetaTag_node_input, }, 1},
{ "Min", 3, (u64)&((sin_wave_data*)0)->Min, {MetaTag_node_input, }, 1},
{ "Max", 3, (u64)&((sin_wave_data*)0)->Max, {MetaTag_node_input, }, 1},
{ "Result", 6, (u64)&((sin_wave_data*)0)->Result, {MetaTag_node_input, }, 1},
{ "Accumulator", 11, (u64)&((sin_wave_data*)0)->Accumulator, {}, 0},
}; };
static gsm_struct_member_type_info StructMembers_revolving_discs_data[] = { static gsm_struct_member_type_info StructMembers_revolving_discs_data[] = {
{ "Rotation", 8, (u64)&((revolving_discs_data*)0)->Rotation, {MetaTag_node_input, }, 1}, { "Rotation", 8, (u64)&((revolving_discs_data*)0)->Rotation, {MetaTag_node_input, }, 1},
{ "ThetaZ", 6, (u64)&((revolving_discs_data*)0)->ThetaZ, {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}, { "ThetaY", 6, (u64)&((revolving_discs_data*)0)->ThetaY, {MetaTag_node_input, }, 1},
{ "DiscWidth", 9, (u64)&((revolving_discs_data*)0)->DiscWidth, {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}, { "InnerRadius", 11, (u64)&((revolving_discs_data*)0)->InnerRadius, {MetaTag_node_input, }, 1},
{ "OuterRadius", 11, (u64)&((revolving_discs_data*)0)->OuterRadius, {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}, { "Color", 5, (u64)&((revolving_discs_data*)0)->Color, {MetaTag_node_input, }, 1},
{ "Result", 6, (u64)&((revolving_discs_data*)0)->Result, {MetaTag_node_output, }, 1}, { "Result", 6, (u64)&((revolving_discs_data*)0)->Result, {MetaTag_node_output, }, 1},
}; };
static gsm_struct_member_type_info StructMembers_vertical_color_fade_data[] = { static gsm_struct_member_type_info StructMembers_vertical_color_fade_data[] = {
{ "Color", 5, (u64)&((vertical_color_fade_data*)0)->Color, {MetaTag_node_input, }, 1}, { "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}, { "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}, { "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}, { "Result", 6, (u64)&((vertical_color_fade_data*)0)->Result, {MetaTag_node_output, }, 1},
};
static gsm_struct_member_type_info StructMembers_multiply_patterns_data[] = {
{ "A", 1, (u64)&((multiply_patterns_data*)0)->A, {MetaTag_node_input, }, 1},
{ "B", 1, (u64)&((multiply_patterns_data*)0)->B, {MetaTag_node_input, }, 1},
{ "Result", 6, (u64)&((multiply_patterns_data*)0)->Result, {MetaTag_node_output, }, 1},
}; };
static gsm_struct_type_info StructTypes[] = { static gsm_struct_type_info StructTypes[] = {
{ gsm_StructType_solid_color_data, "solid_color_data", 16, 36, 0, 0, StructMembers_solid_color_data, 2 }, { gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 },
{ gsm_StructType_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 5 }, { gsm_StructType_solid_color_data, "solid_color_data", 16, 32, 0, 0, StructMembers_solid_color_data, 2 },
{ gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 }, { gsm_StructType_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 5 },
{ gsm_StructType_color_buffer, "color_buffer", 12, 20, 0, 0, StructMembers_color_buffer, 3 }, { gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 },
{ gsm_StructType_pixel, "pixel", 5, 3, 0, 0, StructMembers_pixel, 2 }, { gsm_StructType_color_buffer, "color_buffer", 12, 16, 0, 0, StructMembers_color_buffer, 3 },
{ gsm_StructType_u8, "u8", 2, 1, 0, 0, 0, 0 }, { gsm_StructType_pixel, "pixel", 5, 0, 0, 0, StructMembers_pixel, 2 },
{ gsm_StructType_s32, "s32", 3, 4, 0, 0, 0, 0 }, { gsm_StructType_u8, "u8", 2, 0, 0, 0, 0, 0 },
{ gsm_StructType_sin_wave_data, "sin_wave_data", 13, 20, 0, 0, StructMembers_sin_wave_data, 5 }, { gsm_StructType_s32, "s32", 3, 0, 0, 0, 0, 0 },
{ gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 }, { gsm_StructType_revolving_discs_data, "revolving_discs_data", 20, 56, 0, 0, StructMembers_revolving_discs_data, 8 },
{ gsm_StructType_revolving_discs_data, "revolving_discs_data", 20, 60, 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 },
{ gsm_StructType_vertical_color_fade_data, "vertical_color_fade_data", 24, 44, 0, 0, StructMembers_vertical_color_fade_data, 4 },
{ gsm_StructType_multiply_patterns_data, "multiply_patterns_data", 22, 60, 0, 0, StructMembers_multiply_patterns_data, 3 },
}; };
static gsm_u32 StructTypesCount = 12; static gsm_u32 StructTypesCount = 12;

View File

@ -67,7 +67,7 @@ gsosx_CreateWindow(NSApplication* App, int Width, int Height, id Title)
[App setMainMenu: MenuBar]; [App setMainMenu: MenuBar];
NSMenu* AppMenu = [NSMenu alloc]; NSMenu* AppMenu = [NSMenu alloc];
id QuitTitle = [@"Quit " stringByAppendingString: Title]; id QuitTitle = [@"Quit " gs_stringByAppendinggs_string: Title];
id QuitMenuItem = [[NSMenuItem alloc] initWithTitle: QuitTitle action: @selector(terminate:) keyEquivalent: @"q"]; id QuitMenuItem = [[NSMenuItem alloc] initWithTitle: QuitTitle action: @selector(terminate:) keyEquivalent: @"q"];
[AppMenu addItem: QuitMenuItem]; [AppMenu addItem: QuitMenuItem];
[AppMenuItem setSubmenu: AppMenu]; [AppMenuItem setSubmenu: AppMenu];

3239
src/app/handmade_math.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
// //
#ifndef INTERFACE_H #ifndef INTERFACE_H
enum string_alignment enum gs_string_alignment
{ {
Align_Left, Align_Left,
Align_Center, Align_Center,
@ -60,10 +60,10 @@ DrawCharacterRightAligned (render_quad_batch_constructor* BatchConstructor, char
} }
internal v2 internal v2
DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* String, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color) DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* gs_string, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
{ {
v2 RegisterPosition = InitialRegisterPosition; v2 RegisterPosition = InitialRegisterPosition;
char* C = String; char* C = gs_string;
for (s32 i = 0; i < Length; i++) for (s32 i = 0; i < Length; i++)
{ {
v2 PositionAfterCharacter = DrawCharacterLeftAligned(BatchConstructor, *C, *Font, RegisterPosition, Color); v2 PositionAfterCharacter = DrawCharacterLeftAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
@ -74,10 +74,10 @@ DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Leng
} }
internal v2 internal v2
DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* String, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color) DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* gs_string, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
{ {
v2 RegisterPosition = InitialRegisterPosition; v2 RegisterPosition = InitialRegisterPosition;
char* C = String + Length - 1; char* C = gs_string + Length - 1;
for (s32 i = Length - 1; i >= 0; i--) for (s32 i = Length - 1; i >= 0; i--)
{ {
v2 PositionAfterCharacter = DrawCharacterRightAligned(BatchConstructor, *C, *Font, RegisterPosition, Color); v2 PositionAfterCharacter = DrawCharacterRightAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
@ -88,7 +88,7 @@ DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Len
} }
internal v2 internal v2
DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Font, v2 Position, v4 Color, string_alignment Alignment = Align_Left) DrawString(render_command_buffer* RenderBuffer, gs_string String, bitmap_font* Font, v2 Position, v4 Color, gs_string_alignment Alignment = Align_Left)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
v2 LowerRight = Position; v2 LowerRight = Position;
@ -129,7 +129,7 @@ DrawCursor (render_quad_batch_constructor* BatchConstructor, v2 Position, v4 Col
} }
internal v2 internal v2
DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 CursorPosition, bitmap_font* Font, v2 Position, v4 Color, v4 CursorColor, string_alignment Alignment = Align_Left) Drawgs_stringWithCursor (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; DEBUG_TRACK_FUNCTION;
v2 LowerRight = Position; v2 LowerRight = Position;
@ -153,21 +153,21 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
{ {
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
String.Length - CursorPosition, String.Length - CursorPosition,
String.Memory + CursorPosition, String.Str + CursorPosition,
RegisterPosition, Font, Color); RegisterPosition, Font, Color);
} }
} }
else if (Alignment == Align_Right) else if (Alignment == Align_Right)
{ {
RegisterPosition = DrawStringRightAligned(&BatchConstructor, RegisterPosition = DrawStringRightAligned(&BatchConstructor,
CursorPosition, String.Memory, CursorPosition, String.Str,
RegisterPosition, Font, Color); RegisterPosition, Font, Color);
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font); DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
if (String.Length - CursorPosition > 0) if (String.Length - CursorPosition > 0)
{ {
RegisterPosition = DrawStringRightAligned(&BatchConstructor, RegisterPosition = DrawStringRightAligned(&BatchConstructor,
String.Length - CursorPosition, String.Length - CursorPosition,
String.Memory + CursorPosition, String.Str + CursorPosition,
RegisterPosition, Font, Color); RegisterPosition, Font, Color);
} }
} }
@ -201,7 +201,7 @@ struct interface_config
struct ui_layout struct ui_layout
{ {
rect Bounds; rect2 Bounds;
v2 Margin; v2 Margin;
r32 RowHeight; r32 RowHeight;
r32 RowYAt; r32 RowYAt;
@ -220,7 +220,7 @@ struct ui_interface
}; };
static ui_layout static ui_layout
ui_CreateLayout(ui_interface Interface, rect Bounds) ui_CreateLayout(ui_interface Interface, rect2 Bounds)
{ {
ui_layout Result = {0}; ui_layout Result = {0};
Result.Bounds = Bounds; Result.Bounds = Bounds;
@ -263,7 +263,7 @@ ui_EndRow(ui_layout* Layout)
} }
static b32 static b32
ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds) ui_TryReserveElementBounds(ui_layout* Layout, rect2* Bounds)
{ {
b32 Result = true; b32 Result = true;
if (!Layout->DrawHorizontal) if (!Layout->DrawHorizontal)
@ -289,7 +289,7 @@ ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
} }
else else
{ {
r32 ElementWidth = gs_Width(Layout->Bounds) / Layout->ColumnsMax; r32 ElementWidth = Rect2Width(Layout->Bounds) / Layout->ColumnsMax;
Bounds->Min = { Bounds->Min = {
Layout->Bounds.Min.x + (ElementWidth * Layout->ColumnsCount) + Layout->Margin.x, Layout->Bounds.Min.x + (ElementWidth * Layout->ColumnsCount) + Layout->Margin.x,
Layout->RowYAt Layout->RowYAt
@ -309,18 +309,18 @@ ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
return Result; return Result;
} }
static rect static rect2
ui_ReserveTextLineBounds(ui_interface Interface, string Text, ui_layout* Layout) ui_ReserveTextLineBounds(ui_interface Interface, gs_string Text, ui_layout* Layout)
{ {
rect Bounds = {0}; rect2 Bounds = {0};
return Bounds; return Bounds;
} }
static rect static rect2
ui_ReserveElementBounds(ui_layout* Layout) ui_ReserveElementBounds(ui_layout* Layout)
{ {
rect Bounds = {0}; rect2 Bounds = {0};
if (!ui_TryReserveElementBounds(Layout, &Bounds)) if (!ui_TryReserveElementBounds(Layout, &Bounds))
{ {
InvalidCodePath; InvalidCodePath;
@ -328,10 +328,10 @@ ui_ReserveElementBounds(ui_layout* Layout)
return Bounds; return Bounds;
} }
static rect static rect2
ui_LayoutRemaining(ui_layout Layout) ui_LayoutRemaining(ui_layout Layout)
{ {
rect Result = Layout.Bounds; rect2 Result = Layout.Bounds;
Result.Max.y = Layout.RowYAt; Result.Max.y = Layout.RowYAt;
if (Layout.DrawHorizontal) if (Layout.DrawHorizontal)
{ {
@ -352,19 +352,19 @@ ui_GetTextLineHeight(ui_interface Interface)
} }
static void static void
ui_FillRect(ui_interface* Interface, rect Bounds, v4 Color) ui_FillRect(ui_interface* Interface, rect2 Bounds, v4 Color)
{ {
PushRenderQuad2D(Interface->RenderBuffer, gs_RectExpand(Bounds), Color); PushRenderQuad2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Color);
} }
static void static void
ui_OutlineRect(ui_interface* Interface, rect Bounds, r32 Thickness, v4 Color) ui_OutlineRect(ui_interface* Interface, rect2 Bounds, r32 Thickness, v4 Color)
{ {
PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color); PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color);
} }
internal void internal void
ui_DrawString(ui_interface* Interface, string String, rect Bounds, v4 Color, string_alignment Alignment = Align_Left) ui_DrawString(ui_interface* Interface, gs_string String, rect2 Bounds, v4 Color, gs_string_alignment Alignment = Align_Left)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(Interface->RenderBuffer, render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(Interface->RenderBuffer,
@ -392,9 +392,9 @@ ui_DrawString(ui_interface* Interface, string String, rect Bounds, v4 Color, str
} }
static void static void
ui_LayoutDrawString(ui_interface* Interface, ui_layout* Layout, string String, v4 Color, string_alignment Alignment = Align_Left) ui_LayoutDrawString(ui_interface* Interface, ui_layout* Layout, gs_string String, v4 Color, gs_string_alignment Alignment = Align_Left)
{ {
rect Bounds = {0}; rect2 Bounds = {0};
if (!ui_TryReserveElementBounds(Layout, &Bounds)) if (!ui_TryReserveElementBounds(Layout, &Bounds))
{ {
// TODO(NAME): Not invalid, just haven't implemented yet. // TODO(NAME): Not invalid, just haven't implemented yet.
@ -405,18 +405,18 @@ ui_LayoutDrawString(ui_interface* Interface, ui_layout* Layout, string String, v
} }
static void static void
ui_TextBox(ui_interface* Interface, rect Bounds, string Text, v4 BGColor, v4 TextColor) ui_TextBox(ui_interface* Interface, rect2 Bounds, gs_string Text, v4 BGColor, v4 TextColor)
{ {
ui_FillRect(Interface, Bounds, BGColor); ui_FillRect(Interface, Bounds, BGColor);
ui_DrawString(Interface, Text, Bounds, TextColor); ui_DrawString(Interface, Text, Bounds, TextColor);
} }
static b32 static b32
ui_Button(ui_interface* Interface, string Text, rect Bounds, v4 InactiveColor, v4 HoverColor, v4 ClickedColor) ui_Button(ui_interface* Interface, gs_string Text, rect2 Bounds, v4 InactiveColor, v4 HoverColor, v4 ClickedColor)
{ {
b32 Pressed = false; b32 Pressed = false;
v4 ButtonBG = InactiveColor; v4 ButtonBG = InactiveColor;
if (gs_PointIsInRect(Interface->Mouse.Pos, Bounds)) if (PointIsInRect(Bounds, Interface->Mouse.Pos))
{ {
ButtonBG = HoverColor; ButtonBG = HoverColor;
if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState)) if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState))
@ -430,7 +430,7 @@ ui_Button(ui_interface* Interface, string Text, rect Bounds, v4 InactiveColor, v
} }
static b32 static b32
ui_Button(ui_interface* Interface, string Text, rect Bounds) ui_Button(ui_interface* Interface, gs_string Text, rect2 Bounds)
{ {
v4 BGColor = Interface->Style.ButtonColor_Inactive; v4 BGColor = Interface->Style.ButtonColor_Inactive;
v4 HoverColor = Interface->Style.ButtonColor_Active; v4 HoverColor = Interface->Style.ButtonColor_Active;
@ -463,16 +463,16 @@ ui_GetListItemColors(ui_interface* Interface, u32 ListItemIndex)
} }
static b32 static b32
ui_ListButton(ui_interface* Interface, string Text, rect Bounds, u32 ListItemIndex) ui_ListButton(ui_interface* Interface, gs_string Text, rect2 Bounds, u32 ListItemIndex)
{ {
list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex); list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex);
return ui_Button(Interface, Text, Bounds, Colors.Hover, Colors.Selected, Colors.BGColor); return ui_Button(Interface, Text, Bounds, Colors.Hover, Colors.Selected, Colors.BGColor);
} }
static b32 static b32
ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text, v4 BGColor, v4 HoverColor, v4 SelectColor) ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, gs_string Text, v4 BGColor, v4 HoverColor, v4 SelectColor)
{ {
rect ButtonBounds = {0}; rect2 ButtonBounds = {0};
if (!ui_TryReserveElementBounds(Layout, &ButtonBounds)) if (!ui_TryReserveElementBounds(Layout, &ButtonBounds))
{ {
ButtonBounds = ui_ReserveTextLineBounds(*Interface, Text, Layout); ButtonBounds = ui_ReserveTextLineBounds(*Interface, Text, Layout);
@ -481,7 +481,7 @@ ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text, v4 BGCo
} }
static b32 static b32
ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text) ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, gs_string Text)
{ {
v4 BGColor = Interface->Style.ButtonColor_Inactive; v4 BGColor = Interface->Style.ButtonColor_Inactive;
v4 HoverColor = Interface->Style.ButtonColor_Active; v4 HoverColor = Interface->Style.ButtonColor_Active;
@ -490,16 +490,16 @@ ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text)
} }
static b32 static b32
ui_LayoutListButton(ui_interface* Interface, ui_layout* Layout, string Text, u32 ListItemIndex) ui_LayoutListButton(ui_interface* Interface, ui_layout* Layout, gs_string Text, u32 ListItemIndex)
{ {
list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex); list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex);
return ui_LayoutButton(Interface, Layout, Text, Colors.Hover, Colors.Selected, Colors.BGColor); return ui_LayoutButton(Interface, Layout, Text, Colors.Hover, Colors.Selected, Colors.BGColor);
} }
static b32 static b32
ui_LayoutListEntry(ui_interface* Interface, ui_layout* Layout, string Text, u32 Index) ui_LayoutListEntry(ui_interface* Interface, ui_layout* Layout, gs_string Text, u32 Index)
{ {
rect Bounds = {0}; rect2 Bounds = {0};
if (!ui_TryReserveElementBounds(Layout, &Bounds)) if (!ui_TryReserveElementBounds(Layout, &Bounds))
{ {
// TODO(Peter): this isn't really invalid, but I don't have a concrete use case // TODO(Peter): this isn't really invalid, but I don't have a concrete use case
@ -527,7 +527,7 @@ enum selection_state
struct interface_list struct interface_list
{ {
rect ListBounds; rect2 ListBounds;
v2 ListElementDimensions; v2 ListElementDimensions;
v2 ElementLabelIndent; v2 ElementLabelIndent;
@ -540,10 +540,10 @@ struct interface_list
s32 ListElementsCount; s32 ListElementsCount;
}; };
internal rect internal rect2
DrawListElementBackground(interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer) DrawListElementBackground(interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer)
{ {
rect LineBounds = {}; rect2 LineBounds = {};
LineBounds.Min = v2{ LineBounds.Min = v2{
List->ListBounds.Min.x, List->ListBounds.Min.x,
List->ListBounds.Max.y - (List->ListElementDimensions.y * (List->ListElementsCount + 1)) List->ListBounds.Max.y - (List->ListElementDimensions.y * (List->ListElementsCount + 1))
@ -551,7 +551,7 @@ DrawListElementBackground(interface_list* List, mouse_state Mouse, render_comman
LineBounds.Max = LineBounds.Min + List->ListElementDimensions; LineBounds.Max = LineBounds.Min + List->ListElementDimensions;
v4 Color = List->LineBGColors[List->ListElementsCount % List->LineBGColorsCount]; v4 Color = List->LineBGColors[List->ListElementsCount % List->LineBGColorsCount];
if (PointIsInRange(Mouse.Pos, LineBounds.Min, LineBounds.Max)) if (PointIsInRect(LineBounds, Mouse.Pos))
{ {
Color = List->LineBGHoverColor; Color = List->LineBGHoverColor;
} }
@ -560,10 +560,10 @@ DrawListElementBackground(interface_list* List, mouse_state Mouse, render_comman
return LineBounds; return LineBounds;
} }
internal rect internal rect2
DrawListElement(string Label, interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer, interface_config Interface) DrawListElement(gs_string Label, interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer, interface_config Interface)
{ {
rect Bounds = DrawListElementBackground(List, Mouse, RenderBuffer); rect2 Bounds = DrawListElementBackground(List, Mouse, RenderBuffer);
v2 LabelPosition = Bounds.Min + List->ElementLabelIndent; v2 LabelPosition = Bounds.Min + List->ElementLabelIndent;
DrawString(RenderBuffer, Label, Interface.Font, LabelPosition, List->TextColor); DrawString(RenderBuffer, Label, Interface.Font, LabelPosition, List->TextColor);
@ -578,27 +578,34 @@ EvaluateColorChannelSlider (render_command_buffer* RenderBuffer, v4 ChannelMask,
{ {
r32 Result = Current; r32 Result = Current;
// TODO(Peter): Can this come from outside the function? Would rather pass rect around than min/max
rect2 Rect = rect2{ Min, Max };
render_quad_batch_constructor Batch = PushRenderQuad2DBatch(RenderBuffer, 2); render_quad_batch_constructor Batch = PushRenderQuad2DBatch(RenderBuffer, 2);
v4 LeftColor = ChannelMask * 0; v4 LeftColor = ChannelMask * 0;
LeftColor.a = 1.f; LeftColor.a = 1.f;
v4 RightColor = ChannelMask; v4 RightColor = ChannelMask;
PushQuad2DOnBatch(&Batch, PushQuad2DOnBatch(&Batch,
Min, v2{Max.x, Min.y}, Max, v2{Min.x, Max.y}, RectBottomLeft(Rect), RectBottomRight(Rect),
RectTopRight(Rect), RectTopLeft(Rect),
v2{0, 0}, v2{1, 0}, v2{1, 1}, v2{0, 1}, v2{0, 0}, v2{1, 0}, v2{1, 1}, v2{0, 1},
LeftColor, RightColor, RightColor, LeftColor); LeftColor, RightColor, RightColor, LeftColor);
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)) if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
{ {
if (PointIsInRange(Mouse.DownPos, Min, Max)) if (PointIsInRect(Rect, Mouse.DownPos))
{ {
Result = ((r32)Mouse.Pos.x - Min.x) / (Max.x - Min.x); Result = ((r32)Mouse.Pos.x - Min.x) / (Max.x - Min.x);
Result = GSClamp01(Result); Result = Clamp01(Result);
} }
} }
r32 DragBarWidth = 8; r32 DragBarWidth = 8;
v2 DragBarMin = v2{GSLerp(Min.x, Max.x, Result) - (DragBarWidth / 2), Min.y - 2}; v2 DragBarMin = v2{
LerpR32(Result, Min.x, Max.x) - (DragBarWidth / 2),
Min.y - 2
};
v2 DragBarMax = DragBarMin + v2{DragBarWidth, (Max.y - Min.y) + 4}; v2 DragBarMax = DragBarMin + v2{DragBarWidth, (Max.y - Min.y) + 4};
PushQuad2DOnBatch(&Batch, DragBarMin, DragBarMax, v4{.3f, .3f, .3f, 1.f}); PushQuad2DOnBatch(&Batch, DragBarMin, DragBarMax, v4{.3f, .3f, .3f, 1.f});
@ -612,16 +619,18 @@ EvaluateColorPicker (render_command_buffer* RenderBuffer, v4* Value, v2 PanelMin
b32 ShouldClose = false; b32 ShouldClose = false;
v2 PanelMax = v2{400, 500}; v2 PanelMax = v2{400, 500};
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) && !PointIsInRange(Mouse.Pos, PanelMin, PanelMax)) // TODO(Peter): Can this get passed from outside? rather pass rect2 than min/max pairs
rect2 PanelRect = rect2{PanelMin, PanelMax};
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) && !PointIsInRect(PanelRect, Mouse.Pos))
{ {
ShouldClose = true; ShouldClose = true;
} }
else else
{ {
PushRenderQuad2D(RenderBuffer, PanelMin, PanelMax, v4{.5f, .5f, .5f, 1.f}); PushRenderQuad2D(RenderBuffer, PanelRect.Min, PanelRect.Max, v4{.5f, .5f, .5f, 1.f});
v2 TitleMin = v2{PanelMin.x + 5, PanelMax.y - (Config.Font->PixelHeight + 5)}; v2 TitleMin = v2{PanelRect.Min.x + 5, PanelRect.Max.y - (Config.Font->PixelHeight + 5)};
DrawString(RenderBuffer, MakeStringLiteral("Color Picker"), Config.Font, DrawString(RenderBuffer, MakeString("Color Picker"), Config.Font,
TitleMin, WhiteV4); TitleMin, WhiteV4);
v2 SliderDim = v2{(PanelMax.x - PanelMin.x) - 20, 32}; v2 SliderDim = v2{(PanelMax.x - PanelMin.x) - 20, 32};
@ -650,13 +659,13 @@ struct search_lister_result
b32 ShouldRemainOpen; b32 ShouldRemainOpen;
}; };
typedef string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, string SearchString, s32 Offset); typedef gs_string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, gs_string Searchgs_string, s32 Offset);
internal search_lister_result internal search_lister_result
EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string Title, EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, gs_string Title,
string* ItemList, s32* ListLUT, s32 ListLength, gs_string* ItemList, s32* ListLUT, s32 ListLength,
s32 HotItem, s32 HotItem,
string* SearchString, s32 SearchStringCursorPosition) gs_string* Searchgs_string, s32 Searchgs_stringCursorPosition)
{ {
search_lister_result Result = {}; search_lister_result Result = {};
Result.ShouldRemainOpen = true; Result.ShouldRemainOpen = true;
@ -666,24 +675,24 @@ EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string
InvalidCodePath; InvalidCodePath;
#if 0 #if 0
// Title Bar // Title Bar
rect TitleBarBounds = rect{v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}}; rect2 TitleBarBounds = rect2{v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}};
ui_FillRect(Interface, TitleBarBounds, v4{.3f, .3f, .3f, 1.f}); ui_FillRect(Interface, TitleBarBounds, v4{.3f, .3f, .3f, 1.f});
ui_DrawString(Interface, Title, TitleBarBounds, Interface->Style.TextColor); ui_Drawgs_string(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
MakeStringBuffer(DebugString, 256); MakeStringBuffer(Debuggs_string, 256);
PrintF(&DebugString, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength); PrintF(&Debuggs_string, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
rect DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight}); rect2 DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
ui_DrawString(Interface, DebugString, DebugBounds, Interface->Style.TextColor); ui_Drawgs_string(Interface, Debuggs_string, DebugBounds, Interface->Style.TextColor);
// Search Bar // Search Bar
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f}); PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
DrawStringWithCursor(RenderBuffer, *SearchString, SearchStringCursorPosition, Font, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4); Drawgs_stringWithCursor(RenderBuffer, *Searchgs_string, Searchgs_stringCursorPosition, Font, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4);
TopLeft.y -= 30; TopLeft.y -= 30;
for (s32 i = 0; i < ListLength; i++) for (s32 i = 0; i < ListLength; i++)
{ {
s32 FilteredIndex = ListLUT[i]; s32 FilteredIndex = ListLUT[i];
string ListItemString = ItemList[FilteredIndex]; gs_string ListItemgs_string = ItemList[FilteredIndex];
v2 Min = v2{TopLeft.x, TopLeft.y - 30}; v2 Min = v2{TopLeft.x, TopLeft.y - 30};
v2 Max = Min + Dimension - v2{0, Config.Margin.y}; v2 Max = Min + Dimension - v2{0, Config.Margin.y};
@ -694,7 +703,7 @@ EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string
ButtonColor = Config.ButtonColor_Active; ButtonColor = Config.ButtonColor_Active;
} }
if (ui_Button(Interface, ListItemString, rect{Min, Max})) if (ui_Button(Interface, ListItemgs_string, rect2{Min, Max}))
{ {
Result.SelectedItem = i; Result.SelectedItem = i;
} }

View File

@ -6,7 +6,7 @@
#ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H #ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
// Colors // Colors
global_variable v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f}; global v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f};
// //
struct animation_timeline_state struct animation_timeline_state
@ -15,7 +15,7 @@ struct animation_timeline_state
}; };
inline u32 inline u32
GetFrameFromPointInAnimationPanel(v2 Point, rect PanelBounds, frame_range VisibleRange) GetFrameFromPointInAnimationPanel(v2 Point, rect2 PanelBounds, frame_range VisibleRange)
{ {
r32 HorizontalPercentOfBounds = (Point.x - PanelBounds.Min.x) / (PanelBounds.Max.x - PanelBounds.Min.x); r32 HorizontalPercentOfBounds = (Point.x - PanelBounds.Min.x) / (PanelBounds.Max.x - PanelBounds.Min.x);
u32 VisibleFramesCount = GetFrameCount(VisibleRange); u32 VisibleFramesCount = GetFrameCount(VisibleRange);
@ -24,10 +24,10 @@ GetFrameFromPointInAnimationPanel(v2 Point, rect PanelBounds, frame_range Visibl
} }
inline s32 inline s32
GetXPositionFromFrameInAnimationPanel (u32 Frame, rect PanelBounds, frame_range VisibleRange) GetXPositionFromFrameInAnimationPanel (u32 Frame, rect2 PanelBounds, frame_range VisibleRange)
{ {
r32 PercentOfTimeline = (r32)(Frame - VisibleRange.Min) / (r32)GetFrameCount(VisibleRange); r32 PercentOfTimeline = (r32)(Frame - VisibleRange.Min) / (r32)GetFrameCount(VisibleRange);
s32 XPositionAtFrame = (PercentOfTimeline * gs_Width(PanelBounds)) + PanelBounds.Min.x; s32 XPositionAtFrame = (PercentOfTimeline * Rect2Width(PanelBounds)) + PanelBounds.Min.x;
return XPositionAtFrame; return XPositionAtFrame;
} }
@ -67,7 +67,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
OPERATION_STATE_DEF(drag_time_marker_operation_state) OPERATION_STATE_DEF(drag_time_marker_operation_state)
{ {
rect TimelineBounds; rect2 TimelineBounds;
s32 StartFrame; s32 StartFrame;
s32 EndFrame; s32 EndFrame;
}; };
@ -90,7 +90,7 @@ input_command DragTimeMarkerCommands [] = {
}; };
internal void internal void
StartDragTimeMarker(rect TimelineBounds, frame_range VisibleFrames, app_state* State) StartDragTimeMarker(rect2 TimelineBounds, frame_range VisibleFrames, app_state* State)
{ {
operation_mode* DragTimeMarkerMode = ActivateOperationModeWithCommands(&State->Modes, DragTimeMarkerCommands, UpdateDragTimeMarker); operation_mode* DragTimeMarkerMode = ActivateOperationModeWithCommands(&State->Modes, DragTimeMarkerCommands, UpdateDragTimeMarker);
@ -112,7 +112,7 @@ StartDragTimeMarker(rect TimelineBounds, frame_range VisibleFrames, app_state* S
OPERATION_STATE_DEF(drag_animation_clip_state) OPERATION_STATE_DEF(drag_animation_clip_state)
{ {
rect TimelineBounds; rect2 TimelineBounds;
frame_range VisibleRange; frame_range VisibleRange;
frame_range ClipRange; frame_range ClipRange;
}; };
@ -122,7 +122,7 @@ AttemptToSnapPosition(u32 SnappingFrame, u32 SnapToFrame)
{ {
u32 Result = SnappingFrame; u32 Result = SnappingFrame;
s32 SnapDistance = 5; s32 SnapDistance = 5;
if (GSAbs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance) if (Abs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance)
{ {
Result = SnapToFrame; Result = SnapToFrame;
} }
@ -134,13 +134,13 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
drag_animation_clip_state* OpState = (drag_animation_clip_state*)Operation.OpStateMemory; drag_animation_clip_state* OpState = (drag_animation_clip_state*)Operation.OpStateMemory;
r32 ClipInitialStartFrameXPercent = FrameToPercentRange(OpState->ClipRange.Min, OpState->VisibleRange); r32 ClipInitialStartFrameXPercent = FrameToPercentRange(OpState->ClipRange.Min, OpState->VisibleRange);
u32 ClipInitialStartFrameXPosition = GSLerp(OpState->TimelineBounds.Min.x, u32 ClipInitialStartFrameXPosition = LerpR32(ClipInitialStartFrameXPercent,
OpState->TimelineBounds.Max.x, OpState->TimelineBounds.Min.x,
ClipInitialStartFrameXPercent); OpState->TimelineBounds.Max.x);
r32 ClipInitialEndFrameXPercent = FrameToPercentRange(OpState->ClipRange.Max, OpState->VisibleRange); r32 ClipInitialEndFrameXPercent = FrameToPercentRange(OpState->ClipRange.Max, OpState->VisibleRange);
u32 ClipInitialEndFrameXPosition = GSLerp(OpState->TimelineBounds.Min.x, u32 ClipInitialEndFrameXPosition = LerpR32(ClipInitialEndFrameXPercent,
OpState->TimelineBounds.Max.x, OpState->TimelineBounds.Min.x,
ClipInitialEndFrameXPercent); OpState->TimelineBounds.Max.x);
u32 FrameAtMouseDownX = GetFrameFromPointInAnimationPanel(Mouse.DownPos, OpState->TimelineBounds, OpState->VisibleRange); u32 FrameAtMouseDownX = GetFrameFromPointInAnimationPanel(Mouse.DownPos, OpState->TimelineBounds, OpState->VisibleRange);
@ -154,7 +154,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
return; return;
} }
if (GSAbs(Mouse.DownPos.x - ClipInitialStartFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE) if (Abs(Mouse.DownPos.x - ClipInitialStartFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
{ {
s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset; s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
if (FrameOffset < 0) if (FrameOffset < 0)
@ -176,7 +176,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
} }
AnimationBlock->Range.Min = NewStartFrame; AnimationBlock->Range.Min = NewStartFrame;
} }
else if (GSAbs(Mouse.DownPos.x - ClipInitialEndFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE) else if (Abs(Mouse.DownPos.x - ClipInitialEndFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
{ {
r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset; r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset;
if (FrameOffset > 0) if (FrameOffset > 0)
@ -228,8 +228,8 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
s32 PlayableStartFrame = State->AnimationSystem.PlayableRange.Min; s32 PlayableStartFrame = State->AnimationSystem.PlayableRange.Min;
s32 PlayableEndFrame = State->AnimationSystem.PlayableRange.Max; s32 PlayableEndFrame = State->AnimationSystem.PlayableRange.Max;
AnimationBlock->Range.Min = (u32)GSClamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame); AnimationBlock->Range.Min = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame);
AnimationBlock->Range.Max = (u32)GSClamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame); AnimationBlock->Range.Max = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame);
} }
input_command DragAnimationClipCommands [] = { input_command DragAnimationClipCommands [] = {
@ -237,7 +237,7 @@ input_command DragAnimationClipCommands [] = {
}; };
internal void internal void
SelectAndBeginDragAnimationBlock(gs_list_handle BlockHandle, frame_range VisibleRange, rect TimelineBounds, app_state* State) SelectAndBeginDragAnimationBlock(gs_list_handle BlockHandle, frame_range VisibleRange, rect2 TimelineBounds, app_state* State)
{ {
SelectAnimationBlock(BlockHandle, State); SelectAnimationBlock(BlockHandle, State);
@ -289,20 +289,20 @@ AnimationTimeline_Cleanup(panel* Panel, app_state* State)
} }
internal void internal void
DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBuffer, frame_range VisibleFrames, rect BarBounds, mouse_state Mouse, app_state* State) DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBuffer, frame_range VisibleFrames, rect2 BarBounds, mouse_state Mouse, app_state* State)
{ {
string TempString = PushString(&State->Transient, 256); gs_string TempString = PushString(&State->Transient, 256);
s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min; s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min;
r32 BarHeight = gs_Height(BarBounds); r32 BarHeight = Rect2Height(BarBounds);
r32 BarWidth = gs_Width(BarBounds); r32 BarWidth = Rect2Width(BarBounds);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(BarBounds), v4{.16f, .16f, .16f, 1.f}); PushRenderQuad2D(RenderBuffer, BarBounds.Min, BarBounds.Max, v4{.16f, .16f, .16f, 1.f});
// Mouse clicked inside frame nubmer bar -> change current frame on timeline // Mouse clicked inside frame nubmer bar -> change current frame on timeline
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) && if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
PointIsInRange(Mouse.DownPos, gs_RectExpand(BarBounds))) PointIsInRect(BarBounds, Mouse.DownPos))
{ {
StartDragTimeMarker(BarBounds, VisibleFrames, State); StartDragTimeMarker(BarBounds, VisibleFrames, State);
} }
@ -315,7 +315,7 @@ DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBu
u32 Frame = PercentToFrameInRange(Percent, VisibleFrames); u32 Frame = PercentToFrameInRange(Percent, VisibleFrames);
PrintF(&TempString, "%d", Frame); PrintF(&TempString, "%d", Frame);
r32 FramePercent = FrameToPercentRange(Frame, VisibleFrames); r32 FramePercent = FrameToPercentRange(Frame, VisibleFrames);
r32 FrameX = GSLerp(BarBounds.Min.x, BarBounds.Max.x, FramePercent); r32 FrameX = LerpR32(FramePercent, BarBounds.Min.x, BarBounds.Max.x);
v2 FrameTextPos = v2{FrameX, BarBounds.Min.y + 2}; v2 FrameTextPos = v2{FrameX, BarBounds.Min.y + 2};
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, FrameTextPos, WhiteV4); DrawString(RenderBuffer, TempString, State->Interface.Style.Font, FrameTextPos, WhiteV4);
} }
@ -324,29 +324,28 @@ DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBu
if (FrameIsInRange(AnimationSystem->CurrentFrame, VisibleFrames)) if (FrameIsInRange(AnimationSystem->CurrentFrame, VisibleFrames))
{ {
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, VisibleFrames); r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, VisibleFrames);
r32 SliderX = GSLerp(BarBounds.Min.x, BarBounds.Max.x, FrameAtPercentVisibleRange); r32 SliderX = LerpR32(FrameAtPercentVisibleRange, BarBounds.Min.x, BarBounds.Max.x);
PrintF(&TempString, "%d", AnimationSystem->CurrentFrame);
u32 FrameNumberCharCount = GetU32NumberOfCharactersNeeded(AnimationSystem->CurrentFrame);
// space for each character + a margin on either side // space for each character + a margin on either side
r32 SliderWidth = (8 * FrameNumberCharCount) + 8; r32 SliderWidth = (8 * TempString.Length) + 8;
r32 SliderHalfWidth = SliderWidth / 2.f; r32 SliderHalfWidth = SliderWidth / 2.f;
v2 HeadMin = v2{SliderX - SliderHalfWidth, BarBounds.Min.y}; v2 HeadMin = v2{SliderX - SliderHalfWidth, BarBounds.Min.y};
v2 HeadMax = v2{SliderX + SliderHalfWidth, BarBounds.Max.y}; v2 HeadMax = v2{SliderX + SliderHalfWidth, BarBounds.Max.y};
PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor); PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor);
PrintF(&TempString, "%d", AnimationSystem->CurrentFrame);
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, HeadMin + v2{6, 4}, WhiteV4); DrawString(RenderBuffer, TempString, State->Interface.Style.Font, HeadMin + v2{6, 4}, WhiteV4);
} }
} }
internal frame_range internal frame_range
DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_state* TimelineState, render_command_buffer* RenderBuffer, rect BarBounds, mouse_state Mouse) DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_state* TimelineState, render_command_buffer* RenderBuffer, rect2 BarBounds, mouse_state Mouse)
{ {
frame_range Result = {0}; frame_range Result = {0};
r32 BarHeight = gs_Height(BarBounds); r32 BarHeight = Rect2Height(BarBounds);
r32 BarWidth = gs_Width(BarBounds); r32 BarWidth = Rect2Width(BarBounds);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(BarBounds), v4{.16f, .16f, .16f, 1.f}); PushRenderQuad2D(RenderBuffer, BarBounds.Min, BarBounds.Max, v4{.16f, .16f, .16f, 1.f});
r32 PlayableFrames = (r32)GetFrameCount(AnimationSystem->PlayableRange); r32 PlayableFrames = (r32)GetFrameCount(AnimationSystem->PlayableRange);
v2 SliderBarDim = v2{25, BarHeight}; v2 SliderBarDim = v2{25, BarHeight};
@ -354,22 +353,24 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
// Convert Frames To Pixels // Convert Frames To Pixels
r32 VisibleMinPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Min, AnimationSystem->PlayableRange); r32 VisibleMinPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Min, AnimationSystem->PlayableRange);
r32 VisibleMaxPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Max, AnimationSystem->PlayableRange); r32 VisibleMaxPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Max, AnimationSystem->PlayableRange);
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * gs_Width(BarBounds)), BarBounds.Min.y}; v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * Rect2Width(BarBounds)), BarBounds.Min.y};
v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (VisibleMaxPercentPlayable * gs_Width(BarBounds)) - 25, BarBounds.Min.y}; v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (VisibleMaxPercentPlayable * Rect2Width(BarBounds)) - 25, BarBounds.Min.y};
rect2 SliderBarRange = rect2{ RangeMinSliderMin, RangeMinSliderMin + SliderBarDim };
if (MouseButtonHeldDown(Mouse.LeftButtonState) || if (MouseButtonHeldDown(Mouse.LeftButtonState) ||
MouseButtonTransitionedUp(Mouse.LeftButtonState)) MouseButtonTransitionedUp(Mouse.LeftButtonState))
{ {
v2 MouseDragOffset = Mouse.Pos - Mouse.DownPos; v2 MouseDragOffset = Mouse.Pos - Mouse.DownPos;
if (PointIsInRange(Mouse.DownPos, RangeMinSliderMin, RangeMinSliderMin + SliderBarDim)) if (PointIsInRect(SliderBarRange, Mouse.DownPos))
{ {
r32 NewSliderX = RangeMinSliderMin.x + MouseDragOffset.x; r32 NewSliderX = RangeMinSliderMin.x + MouseDragOffset.x;
RangeMinSliderMin.x = GSClamp(BarBounds.Min.x, NewSliderX, RangeMaxSliderMin.x - SliderBarDim.x); RangeMinSliderMin.x = Clamp(BarBounds.Min.x, NewSliderX, RangeMaxSliderMin.x - SliderBarDim.x);
} }
if (PointIsInRange(Mouse.DownPos, RangeMaxSliderMin, RangeMaxSliderMin + SliderBarDim)) if (PointIsInRect(SliderBarRange, Mouse.DownPos))
{ {
r32 NewSliderX = RangeMaxSliderMin.x + MouseDragOffset.x; r32 NewSliderX = RangeMaxSliderMin.x + MouseDragOffset.x;
RangeMaxSliderMin.x = GSClamp(RangeMinSliderMin.x + SliderBarDim.x, NewSliderX, BarBounds.Max.x - SliderBarDim.x); RangeMaxSliderMin.x = Clamp(RangeMinSliderMin.x + SliderBarDim.x, NewSliderX, BarBounds.Max.x - SliderBarDim.x);
} }
} }
@ -396,19 +397,19 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
#define LAYER_HEIGHT 52 #define LAYER_HEIGHT 52
internal void internal void
DrawLayerMenu(animation_system* AnimationSystem, rect PanelDim, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse) DrawLayerMenu(animation_system* AnimationSystem, rect2 PanelDim, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
{ {
v2 LayerDim = { gs_Width(PanelDim), LAYER_HEIGHT }; v2 LayerDim = { Rect2Width(PanelDim), LAYER_HEIGHT };
v2 LayerListMin = PanelDim.Min + v2{0, 24}; v2 LayerListMin = PanelDim.Min + v2{0, 24};
for (u32 LayerIndex = 0; LayerIndex < AnimationSystem->LayersCount; LayerIndex++) for (u32 LayerIndex = 0; LayerIndex < AnimationSystem->LayersCount; LayerIndex++)
{ {
anim_layer* Layer = AnimationSystem->Layers + LayerIndex; anim_layer* Layer = AnimationSystem->Layers + LayerIndex;
rect LayerBounds = {0}; rect2 LayerBounds = {0};
LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * LayerIndex) }; LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * LayerIndex) };
LayerBounds.Max = LayerBounds.Min + LayerDim; LayerBounds.Max = LayerBounds.Min + LayerDim;
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) && if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
gs_PointIsInRect(Mouse.Pos, LayerBounds)) PointIsInRect(LayerBounds, Mouse.Pos))
{ {
State->SelectedAnimationLayer = LayerIndex; State->SelectedAnimationLayer = LayerIndex;
} }
@ -416,18 +417,18 @@ DrawLayerMenu(animation_system* AnimationSystem, rect PanelDim, render_command_b
v2 LayerTextPos = { LayerBounds.Min.x + 6, LayerBounds.Max.y - 16}; v2 LayerTextPos = { LayerBounds.Min.x + 6, LayerBounds.Max.y - 16};
if (State->SelectedAnimationLayer == LayerIndex) if (State->SelectedAnimationLayer == LayerIndex)
{ {
PushRenderBoundingBox2D(RenderBuffer, gs_RectExpand(LayerBounds), 1, WhiteV4); PushRenderBoundingBox2D(RenderBuffer, LayerBounds.Min, LayerBounds.Max, 1, WhiteV4);
} }
DrawString(RenderBuffer, Layer->Name, State->Interface.Style.Font, LayerTextPos, WhiteV4); DrawString(RenderBuffer, Layer->Name, State->Interface.Style.Font, LayerTextPos, WhiteV4);
} }
} }
internal rect internal rect2
DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect TimelineBounds, render_command_buffer* RenderBuffer) DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect2 TimelineBounds, render_command_buffer* RenderBuffer)
{ {
rect BlockBounds = {}; rect2 BlockBounds = {};
r32 TimelineWidth = gs_Width(TimelineBounds); r32 TimelineWidth = Rect2Width(TimelineBounds);
u32 ClampedBlockStartFrame = ClampFrameToRange(AnimationBlock.Range.Min, VisibleFrames); u32 ClampedBlockStartFrame = ClampFrameToRange(AnimationBlock.Range.Min, VisibleFrames);
r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, VisibleFrames); r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, VisibleFrames);
@ -448,18 +449,18 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
} }
internal gs_list_handle internal gs_list_handle
DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect PanelBounds, gs_list_handle SelectedBlockHandle, ui_interface* Interface, app_state* State) DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect2 PanelBounds, gs_list_handle SelectedBlockHandle, ui_interface* Interface, app_state* State)
{ {
string TempString = PushString(&State->Transient, 256); gs_string Tempgs_string = PushString(&State->Transient, 256);
gs_list_handle Result = SelectedBlockHandle; gs_list_handle Result = SelectedBlockHandle;
rect LayerMenuBounds, TimelineBounds; rect2 LayerMenuBounds, TimelineBounds;
gs_VSplitRectAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds); RectVSplitAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
// In Top To Bottom Order // In Top To Bottom Order
rect TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds; rect2 TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
gs_HSplitRectAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds); RectHSplitAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
gs_HSplitRectAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds); RectHSplitAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
// TODO(Peter): Clean Up // TODO(Peter): Clean Up
DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse); DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse);
@ -500,8 +501,8 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
BlockColor = PinkV4; BlockColor = PinkV4;
} }
// TODO(Peter): Clean Up // TODO(Peter): Clean Up
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer); rect2 BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
if (gs_PointIsInRect(Interface->Mouse.Pos, BlockBounds)) if (PointIsInRect(BlockBounds, Interface->Mouse.Pos))
{ {
DragBlockHandle = CurrentBlockHandle; DragBlockHandle = CurrentBlockHandle;
} }
@ -519,8 +520,8 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
if (FrameIsInRange(AnimationSystem->CurrentFrame, AdjustedViewRange)) if (FrameIsInRange(AnimationSystem->CurrentFrame, AdjustedViewRange))
{ {
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange); r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
r32 SliderX = GSLerp(TimelineBounds.Min.x, TimelineBounds.Max.x, FrameAtPercentVisibleRange); r32 SliderX = LerpR32(FrameAtPercentVisibleRange, TimelineBounds.Min.x, TimelineBounds.Max.x);
rect SliderBounds = { rect2 SliderBounds = {
v2{ SliderX, TimelineBounds.Min.y }, v2{ SliderX, TimelineBounds.Min.y },
v2{ SliderX + 1, TimelineBounds.Max.y } v2{ SliderX + 1, TimelineBounds.Max.y }
}; };
@ -531,7 +532,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
ui_OutlineRect(Interface, TimelineFrameBarBounds, 1.f, RedV4); ui_OutlineRect(Interface, TimelineFrameBarBounds, 1.f, RedV4);
ui_OutlineRect(Interface, TimelineBlockDisplayBounds, 1.f, RedV4); ui_OutlineRect(Interface, TimelineBlockDisplayBounds, 1.f, RedV4);
if (MouseDownAndNotHandled && gs_PointIsInRect(Interface->Mouse.Pos, TimelineBounds)) if (MouseDownAndNotHandled && PointIsInRect(TimelineBounds, Interface->Mouse.Pos))
{ {
DeselectCurrentAnimationBlock(State); DeselectCurrentAnimationBlock(State);
} }
@ -554,13 +555,13 @@ animation_clip GlobalAnimationClips[] = {
}; };
internal void internal void
DrawAnimationClipsList(rect PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayer, animation_system* AnimationSystem) DrawAnimationClipsList(rect2 PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayer, animation_system* AnimationSystem)
{ {
ui_layout Layout = ui_CreateLayout(*Interface, PanelBounds); ui_layout Layout = ui_CreateLayout(*Interface, PanelBounds);
for (s32 i = 0; i < GlobalAnimationClipsCount; i++) for (s32 i = 0; i < GlobalAnimationClipsCount; i++)
{ {
animation_clip Clip = GlobalAnimationClips[i]; animation_clip Clip = GlobalAnimationClips[i];
string ClipName = MakeString(Clip.Name, Clip.NameLength); gs_string ClipName = MakeString(Clip.Name, Clip.NameLength);
if (ui_LayoutListEntry(Interface, &Layout, ClipName, i)) if (ui_LayoutListEntry(Interface, &Layout, ClipName, i))
{ {
AddAnimationBlockAtCurrentTime(i + 1, SelectedAnimationLayer, AnimationSystem); AddAnimationBlockAtCurrentTime(i + 1, SelectedAnimationLayer, AnimationSystem);
@ -572,7 +573,7 @@ DrawAnimationClipsList(rect PanelBounds, ui_interface* Interface, u32 SelectedAn
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_animation_timeline); GSMetaTag(panel_type_animation_timeline);
internal void internal void
AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) AnimationTimeline_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
animation_timeline_state* TimelineState = (animation_timeline_state*)Panel.PanelStateMemory; animation_timeline_state* TimelineState = (animation_timeline_state*)Panel.PanelStateMemory;
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle; gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
@ -580,24 +581,24 @@ AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* R
ui_interface* Interface = &State->Interface; ui_interface* Interface = &State->Interface;
animation_system* AnimationSystem = &State->AnimationSystem; animation_system* AnimationSystem = &State->AnimationSystem;
rect TitleBarBounds, PanelContentsBounds; rect2 TitleBarBounds, PanelContentsBounds;
gs_HSplitRectAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds); RectHSplitAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds);
rect AnimationListBounds, TimelineBounds; rect2 AnimationListBounds, TimelineBounds;
gs_VSplitRectAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds); RectVSplitAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds);
ui_FillRect(Interface, TitleBarBounds, Interface->Style.PanelBGColors[0]); ui_FillRect(Interface, TitleBarBounds, Interface->Style.PanelBGColors[0]);
ui_layout TitleBarLayout = ui_CreateLayout(*Interface, TitleBarBounds); ui_layout TitleBarLayout = ui_CreateLayout(*Interface, TitleBarBounds);
ui_StartRow(&TitleBarLayout, 3); ui_StartRow(&TitleBarLayout, 3);
{ {
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Pause"))) if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Pause")))
{ {
State->AnimationSystem.TimelineShouldAdvance = true; State->AnimationSystem.TimelineShouldAdvance = true;
} }
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Play"))) if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Play")))
{ {
State->AnimationSystem.TimelineShouldAdvance = false; State->AnimationSystem.TimelineShouldAdvance = false;
} }
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Stop"))) if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Stop")))
{ {
State->AnimationSystem.TimelineShouldAdvance = false; State->AnimationSystem.TimelineShouldAdvance = false;
State->AnimationSystem.CurrentFrame = 0; State->AnimationSystem.CurrentFrame = 0;
@ -605,7 +606,7 @@ AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* R
} }
ui_EndRow(&TitleBarLayout); ui_EndRow(&TitleBarLayout);
if (gs_Height(TimelineBounds) > 0) if (Rect2Height(TimelineBounds) > 0)
{ {
SelectedBlockHandle = DrawAnimationTimeline(AnimationSystem, TimelineState, TimelineBounds, SelectedBlockHandle, Interface, State); SelectedBlockHandle = DrawAnimationTimeline(AnimationSystem, TimelineState, TimelineBounds, SelectedBlockHandle, Interface, State);
DrawAnimationClipsList(AnimationListBounds, Interface, State->SelectedAnimationLayer, &State->AnimationSystem); DrawAnimationClipsList(AnimationListBounds, Interface, State->SelectedAnimationLayer, &State->AnimationSystem);

View File

@ -74,7 +74,7 @@ DrawSACNUniversePixels (render_command_buffer* RenderBuffer, sacn_universe* ToDr
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_dmx_view); GSMetaTag(panel_type_dmx_view);
internal void internal void
DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) DMXView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
#if 0 #if 0
// :NoLongerFunctionalSACNCodeButThatsOk // :NoLongerFunctionalSACNCodeButThatsOk
@ -82,7 +82,7 @@ DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffe
universe_view_operation_state* OpState = (universe_view_operation_state*)Operation.OpStateMemory; universe_view_operation_state* OpState = (universe_view_operation_state*)Operation.OpStateMemory;
string TitleBarString = InitializeEmptyString(PushArray(State->Transient, char, 64), 64); gs_string TitleBargs_string = InitializeEmptygs_string(PushArray(State->Transient, char, 64), 64);
v2 DisplayArea_Dimension = v2{600, 600}; v2 DisplayArea_Dimension = v2{600, 600};
@ -120,8 +120,8 @@ DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffe
if (OpState->Zoom > .5f) if (OpState->Zoom > .5f)
{ {
v2 TitleDisplayStart = UniverseDisplayTopLeft + v2{0, 12}; v2 TitleDisplayStart = UniverseDisplayTopLeft + v2{0, 12};
PrintF(&TitleBarString, "Universe %d", Universe->Universe); PrintF(&TitleBargs_string, "Universe %d", Universe->Universe);
DrawString(RenderBuffer, TitleBarString, State->Interface.Font, DrawString(RenderBuffer, TitleBargs_string, State->Interface.Font,
TitleDisplayStart, WhiteV4); TitleDisplayStart, WhiteV4);
} }

View File

@ -7,7 +7,7 @@
struct file_view_state struct file_view_state
{ {
string WorkingDirectory; gs_string WorkingDirectory;
}; };
input_command* FileView_Commands = 0; input_command* FileView_Commands = 0;
@ -36,18 +36,18 @@ FileView_Cleanup(panel* Panel, app_state* State)
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_file_view); GSMetaTag(panel_type_file_view);
internal void internal void
FileView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) FileView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
rect HeaderBounds = {0}; rect2 HeaderBounds = {0};
HeaderBounds.Min = {PanelBounds.Min.x, PanelBounds.Max.y - 32}; HeaderBounds.Min = {PanelBounds.Min.x, PanelBounds.Max.y - 32};
HeaderBounds.Max = PanelBounds.Max; HeaderBounds.Max = PanelBounds.Max;
rect ListBounds = {0}; rect2 ListBounds = {0};
ListBounds.Min = PanelBounds.Min; ListBounds.Min = PanelBounds.Min;
ListBounds.Max = gs_BottomRight(HeaderBounds); ListBounds.Max = RectBottomRight(HeaderBounds);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(HeaderBounds), PinkV4); PushRenderQuad2D(RenderBuffer, HeaderBounds.Min, HeaderBounds.Max, PinkV4);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(ListBounds), RedV4); PushRenderQuad2D(RenderBuffer, ListBounds.Min, ListBounds.Max, RedV4);
} }

View File

@ -27,13 +27,13 @@ HierarchyView_Cleanup(panel* Panel, app_state* State)
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_hierarchy); GSMetaTag(panel_type_hierarchy);
internal void internal void
HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) HierarchyView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
ui_layout Layout = ui_CreateLayout(State->Interface, PanelBounds); ui_layout Layout = ui_CreateLayout(State->Interface, PanelBounds);
string TempString = PushString(&State->Transient, 256); gs_string Tempgs_string = PushString(&State->Transient, 256);
u32 LineCount = (u32)(gs_Height(PanelBounds) / Layout.RowHeight) + 1; u32 LineCount = (u32)(Rect2Height(PanelBounds) / Layout.RowHeight) + 1;
u32 AssembliesToDraw = GSMin(LineCount, State->Assemblies.Count); u32 AssembliesToDraw = Min(LineCount, State->Assemblies.Count);
rect* LineBounds = PushArray(&State->Transient, rect, LineCount); rect2* LineBounds = PushArray(&State->Transient, rect2, LineCount);
// Fill in alternating color rows for the backgrounds // Fill in alternating color rows for the backgrounds
for (u32 Line = 0; Line < LineCount; Line++) for (u32 Line = 0; Line < LineCount; Line++)
@ -46,13 +46,13 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
for (u32 AssemblyIndex = 0; AssemblyIndex < AssembliesToDraw; AssemblyIndex++) for (u32 AssemblyIndex = 0; AssemblyIndex < AssembliesToDraw; AssemblyIndex++)
{ {
assembly Assembly = State->Assemblies.Values[AssemblyIndex]; assembly Assembly = State->Assemblies.Values[AssemblyIndex];
PrintF(&TempString, "%S", Assembly.Name); PrintF(&Tempgs_string, "%S", Assembly.Name);
ui_layout ItemLayout = ui_CreateLayout(State->Interface, LineBounds[AssemblyIndex]); ui_layout ItemLayout = ui_CreateLayout(State->Interface, LineBounds[AssemblyIndex]);
ui_StartRow(&ItemLayout, 2); ui_StartRow(&ItemLayout, 2);
{ {
ui_LayoutDrawString(&State->Interface, &ItemLayout, TempString, State->Interface.Style.TextColor); ui_LayoutDrawString(&State->Interface, &ItemLayout, Tempgs_string, State->Interface.Style.TextColor);
if (ui_LayoutListButton(&State->Interface, &ItemLayout, MakeStringLiteral("X"), AssemblyIndex)) if (ui_LayoutListButton(&State->Interface, &ItemLayout, MakeString("X"), AssemblyIndex))
{ {
UnloadAssembly(AssemblyIndex, State, Context); UnloadAssembly(AssemblyIndex, State, Context);
} }
@ -63,15 +63,22 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
if (AssembliesToDraw < LineCount) if (AssembliesToDraw < LineCount)
{ {
// NOTE(Peter): Add assembly button // NOTE(Peter): Add assembly button
PrintF(&TempString, "+ Add Assembly"); PrintF(&Tempgs_string, "+ Add Assembly");
if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw)) if (ui_ListButton(&State->Interface, Tempgs_string, LineBounds[AssembliesToDraw], AssembliesToDraw))
{ {
string FilePath = PushString(&State->Transient, 256); gs_string FilePath = PushString(&State->Transient, 256);
// TODO(Peter): Took out file opening temporarily while I get things back up and running.
// Ideally we can just write our own file lister using the new filehandler so that
// execution doesn't suspend while we try and open a file
InvalidCodePath;
#if 0
b32 Success = GetFilePath(Context, &FilePath, "Foldhaus Files\0*.fold\0\0"); b32 Success = GetFilePath(Context, &FilePath, "Foldhaus Files\0*.fold\0\0");
if (Success) if (Success)
{ {
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, FilePath, State->GlobalLog); LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, FilePath.ConstString, State->GlobalLog);
} }
#endif
} }
} }
} }

View File

@ -25,7 +25,7 @@ ProfilerView_Cleanup(panel* Panel, app_state* State)
} }
internal void internal void
RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, memory_arena* Memory) RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, gs_memory_arena* Memory)
{ {
v4 ThreadColors[] = { v4 ThreadColors[] = {
v4{.73f, .33f, .83f, 1}, v4{.73f, .33f, .83f, 1},
@ -35,8 +35,8 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
v4{.74f, .40f, .25f, 1}, v4{.74f, .40f, .25f, 1},
}; };
rect Bounds = ui_LayoutRemaining(Layout); rect2 Bounds = ui_LayoutRemaining(Layout);
r32 Width = gs_Width(Bounds); r32 Width = Rect2Width(Bounds);
r32 DepthHeight = 64; r32 DepthHeight = 64;
s64 FrameStartCycles = VisibleFrame->FrameStartCycles; s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
@ -48,7 +48,8 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
scope_record* HotRecord = 0; scope_record* HotRecord = 0;
scope_name* HotRecordName = 0; scope_name* HotRecordName = 0;
MakeStringBuffer(String, 256); char Backbuffer[256];
gs_string String = MakeString(Backbuffer, 0, 256);
for (s32 i = 0; i < ThreadScopeCalls->Count; i++) for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
{ {
scope_record* Record = ThreadScopeCalls->Calls + i; scope_record* Record = ThreadScopeCalls->Calls + i;
@ -59,14 +60,14 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
r32 PixelStart = Bounds.Min.x + (Width * PercentStart); r32 PixelStart = Bounds.Min.x + (Width * PercentStart);
r32 PixelEnd = Bounds.Min.x + (Width * PercentEnd); r32 PixelEnd = Bounds.Min.x + (Width * PercentEnd);
r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight); r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight);
rect ScopeBounds = { rect2 ScopeBounds = {
v2{ PixelStart, MinY }, v2{ PixelStart, MinY },
v2{ PixelEnd, MinY + (DepthHeight - 4) } v2{ PixelEnd, MinY + (DepthHeight - 4) }
}; };
if (gs_Width(ScopeBounds) >= 1) if (Rect2Width(ScopeBounds) >= 1)
{ {
v4 Color = ThreadColors[0]; v4 Color = ThreadColors[0];
if (gs_PointIsInRect(Interface->Mouse.Pos, ScopeBounds)) if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
{ {
Color = GreenV4; Color = GreenV4;
HotRecord = Record; HotRecord = Record;
@ -81,23 +82,26 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
if (HotRecord != 0) if (HotRecord != 0)
{ {
PrintF(&String, "%S : %d - %d", HotRecordName->Name, HotRecord->StartCycles, HotRecord->EndCycles); PrintF(&String, "%S : %d - %d", HotRecordName->Name, HotRecord->StartCycles, HotRecord->EndCycles);
ui_TextBox(Interface, gs_MakeRectMinWidth(Interface->Mouse.Pos, v2{256, 32}), String, BlackV4, WhiteV4);
rect2 TextBounds = MakeRect2MinDim(Interface->Mouse.Pos, v2{256, 32});
ui_TextBox(Interface, TextBounds, String, BlackV4, WhiteV4);
} }
} }
internal void internal void
RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, memory_arena* Memory) RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, gs_memory_arena* Memory)
{ {
MakeStringBuffer(String, 256); char Backbuffer[256];
gs_string String = MakeString(Backbuffer, 0, 256);
r32 ColumnWidths[] = {256, 128, 128, 128, 128}; r32 ColumnWidths[] = {256, 128, 128, 128, 128};
ui_StartRow(&Layout, 5, &ColumnWidths[0]); ui_StartRow(&Layout, 5, &ColumnWidths[0]);
{ {
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Procedure"), Interface->Style.TextColor); ui_LayoutDrawString(Interface, &Layout, MakeString("Procedure"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("% Frame"), Interface->Style.TextColor); ui_LayoutDrawString(Interface, &Layout, MakeString("% Frame"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Seconds"), Interface->Style.TextColor); ui_LayoutDrawString(Interface, &Layout, MakeString("Seconds"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Cycles"), Interface->Style.TextColor); ui_LayoutDrawString(Interface, &Layout, MakeString("Cycles"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Calls"), Interface->Style.TextColor); ui_LayoutDrawString(Interface, &Layout, MakeString("Calls"), Interface->Style.TextColor);
} }
ui_EndRow(&Layout); ui_EndRow(&Layout);
@ -133,40 +137,43 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debu
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_profiler); GSMetaTag(panel_type_profiler);
internal void internal void
ProfilerView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) ProfilerView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
memory_arena* Memory = &State->Transient; gs_memory_arena* Memory = &State->Transient;
string String = InitializeEmptyString(PushArray(Memory, char, 256), 256); gs_string String = PushString(Memory, 256);
v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 }; v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 };
r32 FrameListHeight = 64; r32 FrameListHeight = 64;
rect FrameListBounds, ProcListBounds; rect2 FrameListBounds, ProcListBounds;
gs_HSplitRectAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds); RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
rect FrameListInner = gs_InsetRect(FrameListBounds, 4); rect2 FrameListInner = RectInset(FrameListBounds, 4);
r32 SingleFrameStep = gs_Width(FrameListInner) / DEBUG_FRAME_COUNT; r32 SingleFrameStep = Rect2Width(FrameListInner) / DEBUG_FRAME_COUNT;
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2); r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4); ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4);
if (gs_PointIsInRect(Context.Mouse.Pos, FrameListBounds) && MouseButtonHeldDown(Context.Mouse.LeftButtonState)) if (MouseButtonHeldDown(Context.Mouse.LeftButtonState))
{ {
v2 LocalMouse = gs_TransformPointIntoRectSpace(Context.Mouse.Pos, FrameListBounds); if (PointIsInRect(FrameListBounds, Context.Mouse.Pos))
s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
{ {
GlobalDebugServices->RecordFrames = false; v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos);
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex; s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
{
GlobalDebugServices->RecordFrames = false;
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
}
} }
} }
rect FrameBounds = gs_MakeRectMinWidth(FrameListInner.Min, v2{SingleFrameWidth, gs_Height(FrameListInner)}); rect2 FrameBounds = MakeRect2MinDim(FrameListInner.Min, v2{SingleFrameWidth, Rect2Height(FrameListInner)});
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++) for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
{ {
rect PositionedFrameBounds = gs_TranslateRectX(FrameBounds, F * SingleFrameStep); rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep);
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F); s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; } if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
v4 Color = FrameColors[GSClamp(0, FramesAgo, 3)]; v4 Color = FrameColors[Clamp(0, FramesAgo, 3)];
ui_FillRect(&State->Interface, PositionedFrameBounds, Color); ui_FillRect(&State->Interface, PositionedFrameBounds, Color);
} }

View File

@ -18,11 +18,11 @@ OPERATION_RENDER_PROC(Update3DViewMouseRotate)
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos; v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale); m44 XRotation = M44RotationX(-TotalDeltaPos.y * State->PixelsToWorldScale);
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale); m44 YRotation = M44RotationY(TotalDeltaPos.x * State->PixelsToWorldScale);
m44 Combined = XRotation * YRotation; m44 Combined = XRotation * YRotation;
State->Camera.Position = V3(Combined * OpState->CameraStartPos); State->Camera.Position = (Combined * OpState->CameraStartPos).xyz;
} }
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate) FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
@ -40,17 +40,17 @@ FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode, mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
&State->Modes, &State->Modes,
mouse_rotate_view_operation_state); mouse_rotate_view_operation_state);
OpState->CameraStartPos = V4(State->Camera.Position, 1); OpState->CameraStartPos = ToV4Point(State->Camera.Position);
} }
// ---------------- // ----------------
GSMetaTag(panel_commands); GSMetaTag(panel_commands);
GSMetaTag(panel_type_sculpture_view); GSMetaTag(panel_type_sculpture_view);
global_variable input_command SculptureView_Commands[] = { global input_command SculptureView_Commands[] = {
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate }, { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
}; };
global_variable s32 SculptureView_CommandsCount = 1; global s32 SculptureView_CommandsCount = 1;
GSMetaTag(panel_init); GSMetaTag(panel_init);
GSMetaTag(panel_type_sculpture_view); GSMetaTag(panel_type_sculpture_view);
@ -76,23 +76,26 @@ struct draw_leds_job_data
s32 StartIndex; s32 StartIndex;
s32 OnePastLastIndex; s32 OnePastLastIndex;
render_quad_batch_constructor* Batch; render_quad_batch_constructor* Batch;
m44 ModelViewMatrix; quad_batch_constructor_reserved_range BatchReservedRange;
r32 LEDHalfWidth; r32 LEDHalfWidth;
}; };
internal void internal void
DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData) DrawLEDsInBufferRangeJob (gs_thread_context Context, gs_data JobData)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
draw_leds_job_data* Data = (draw_leds_job_data*)JobData; draw_leds_job_data* Data = (draw_leds_job_data*)JobData.Memory;
s32 LEDCount = Data->OnePastLastIndex - Data->StartIndex; s32 LEDCount = Data->OnePastLastIndex - Data->StartIndex;
#if 0
// TODO(Peter): Why are we doing this here? Shouldn't we be able to tell what the range // TODO(Peter): Why are we doing this here? Shouldn't we be able to tell what the range
// needs to be at the time of creation? That way its all on one thread and we're not // needs to be at the time of creation? That way its all on one thread and we're not
// worried about locking up. // worried about locking up.
quad_batch_constructor_reserved_range BatchReservedRange = ThreadSafeReserveRangeInQuadConstructor(Data->Batch, LEDCount * 2); quad_batch_constructor_reserved_range BatchReservedRange = ThreadSafeReserveRangeInQuadConstructor(Data->Batch, LEDCount * 2);
#endif
s32 TrisUsed = 0; s32 TrisUsed = 0;
r32 HalfWidth = Data->LEDHalfWidth; r32 HalfWidth = Data->LEDHalfWidth;
@ -113,77 +116,101 @@ DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData)
v4 Color = v4{PixelColor.R / 255.f, PixelColor.G / 255.f, PixelColor.B / 255.f, 1.0f}; v4 Color = v4{PixelColor.R / 255.f, PixelColor.G / 255.f, PixelColor.B / 255.f, 1.0f};
v4 Position = Data->LedBuffer.Positions[LedIndex]; v4 Position = Data->LedBuffer.Positions[LedIndex];
m44 FaceCameraMatrix = GetLookAtMatrix(Position, Data->CameraPosition); m44 FaceCameraMatrix = M44LookAt(Position, Data->CameraPosition);
v4 PositionOffset = V4(Position.xyz, 0); // Ensure PositionOffset is a vector, not a point v4 PositionOffset = ToV4Vec(Position.xyz);
v4 P0 = (FaceCameraMatrix * P0_In) + PositionOffset; v4 P0 = (FaceCameraMatrix * P0_In) + PositionOffset;
v4 P1 = (FaceCameraMatrix * P1_In) + PositionOffset; v4 P1 = (FaceCameraMatrix * P1_In) + PositionOffset;
v4 P2 = (FaceCameraMatrix * P2_In) + PositionOffset; v4 P2 = (FaceCameraMatrix * P2_In) + PositionOffset;
v4 P3 = (FaceCameraMatrix * P3_In) + PositionOffset; v4 P3 = (FaceCameraMatrix * P3_In) + PositionOffset;
SetTri3DInBatch(Data->Batch, BatchReservedRange.Start + TrisUsed++, SetTri3DInBatch(Data->Batch, Data->BatchReservedRange.Start + TrisUsed++,
P0, P1, P2, UV0, UV1, UV2, Color, Color, Color); P0, P1, P2, UV0, UV1, UV2, Color, Color, Color);
SetTri3DInBatch(Data->Batch, BatchReservedRange.Start + TrisUsed++, SetTri3DInBatch(Data->Batch, Data->BatchReservedRange.Start + TrisUsed++,
P0, P2, P3, UV0, UV2, UV3, Color, Color, Color); P0, P2, P3, UV0, UV2, UV3, Color, Color, Color);
} }
} }
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);
}
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_sculpture_view); GSMetaTag(panel_type_sculpture_view);
internal void internal void
SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) SculptureView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
DEBUG_TRACK_SCOPE(RenderSculpture); DEBUG_TRACK_SCOPE(RenderSculpture);
r32 PanelWidth = PanelBounds.Max.x - PanelBounds.Min.x; // TODO(Peter): @MajorFix
r32 PanelHeight = PanelBounds.Max.y - PanelBounds.Min.y; // NOTE(Peter): Just returning from this function to make sure that this isn't a problem as I go and try to fix
State->Camera.AspectRatio = PanelWidth / PanelHeight; // the other panels
return;
m44 ModelViewMatrix = GetCameraModelViewMatrix(State->Camera);
m44 ProjectionMatrix = GetCameraPerspectiveProjectionMatrix(State->Camera);
r32 LEDHalfWidth = .5f; State->Camera.AspectRatio = RectAspectRatio(PanelBounds);
PushRenderPerspective(RenderBuffer, PanelBounds.Min.x, PanelBounds.Min.y, PanelWidth, PanelHeight, State->Camera); PushRenderPerspective(RenderBuffer, PanelBounds, State->Camera);
m44 FaceCameraMatrix = GetLookAtMatrix(v4{0, 0, 0, 1}, V4(State->Camera.Position, 1));
u32 MaxLEDsPerJob = 2048; u32 MaxLEDsPerJob = 2048;
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal); render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal);
u32 FocusPixel = 256; u32 FocusPixel = 256;
for (u32 i = 0; i < State->Assemblies.Count; i++) for (u32 BufferIndex = 0; BufferIndex < State->LedSystem.BuffersCount; BufferIndex++)
{ {
assembly Assembly = State->Assemblies.Values[i]; led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, BufferIndex);
led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, Assembly.LedBufferIndex); u32 JobsNeeded = U32DivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
u32 JobsNeeded = IntegerDivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
// TODO(Peter): TEMPORARY - identify this pixel
LedBuffer->Colors[FocusPixel] = pixel{ 255, 0, 255 };
#if 1
u32 NextLEDIndex = 0;
for (u32 Job = 0; Job < JobsNeeded; Job++) for (u32 Job = 0; Job < JobsNeeded; Job++)
{ {
draw_leds_job_data* JobData = PushStruct(&State->Transient, draw_leds_job_data); gs_data Data = PushSizeToData(&State->Transient, sizeof(draw_leds_job_data));
draw_leds_job_data* JobData = (draw_leds_job_data*)Data.Memory;
JobData->LedBuffer = *LedBuffer; JobData->LedBuffer = *LedBuffer;
JobData->StartIndex = Job * MaxLEDsPerJob; JobData->StartIndex = NextLEDIndex;
JobData->OnePastLastIndex = GSMin(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount); JobData->OnePastLastIndex = Min(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount);
s32 JobLedCount = JobData->OnePastLastIndex - JobData->StartIndex;
JobData->Batch = &RenderLEDsBatch; JobData->Batch = &RenderLEDsBatch;
JobData->ModelViewMatrix = ModelViewMatrix; JobData->BatchReservedRange = ReserveRangeInQuadConstructor(JobData->Batch, JobLedCount * 2);
JobData->LEDHalfWidth = LEDHalfWidth; JobData->LEDHalfWidth = .5f;
JobData->CameraPosition = V4(State->Camera.Position, 1); JobData->CameraPosition = ToV4Point(State->Camera.Position);
Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, DrawLEDsInBufferRangeJob, JobData, "Sculpture Draw LEDS"); Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, (thread_proc*)DrawLEDsInBufferRangeJob, Data, ConstString("Sculpture Draw LEDS"));
NextLEDIndex = JobData->OnePastLastIndex;
} }
#else
gs_data Data = PushSizeToData(&State->Transient, sizeof(draw_leds_job_data));
draw_leds_job_data* JobData = (draw_leds_job_data*)Data.Memory;
JobData->LedBuffer = *LedBuffer;
JobData->StartIndex = 0;
JobData->OnePastLastIndex = LedBuffer->LedCount;
s32 JobLedCount = JobData->OnePastLastIndex - JobData->StartIndex;
JobData->Batch = &RenderLEDsBatch;
JobData->BatchReservedRange = ReserveRangeInQuadConstructor(JobData->Batch, JobLedCount * 2);
JobData->LEDHalfWidth = .5f;
JobData->CameraPosition = ToV4Point(State->Camera.Position);
Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, (thread_proc*)DrawLEDsInBufferRangeJob, Data, ConstString("Sculpture Draw LEDS"));
#endif
u32 f = 0;
} }
// TODO(Peter): I don't like the fact that setting an orthographic view inside a panel render function // 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 // needs to relyon the window bounds rather than the panel bounds. Ideally the panel only needs to know where
// itself is, and nothing else. // itself is, and nothing else.
PushRenderOrthographic(RenderBuffer, PushRenderOrthographic(RenderBuffer, State->WindowBounds);
State->WindowBounds.Min.x, State->WindowBounds.Min.y,
State->WindowBounds.Max.x, State->WindowBounds.Max.y);
if (State->Assemblies.Count > 0) if (State->Assemblies.Count > 0)
{ {
@ -196,9 +223,9 @@ SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
v4 LedProjectedPosition = Matrix * LedPosition; v4 LedProjectedPosition = Matrix * LedPosition;
v2 LedOnScreenPosition = LedProjectedPosition.xy; v2 LedOnScreenPosition = LedProjectedPosition.xy;
string TempString = PushString(&State->Transient, 256); gs_string Tempgs_string = PushString(&State->Transient, 256);
PrintF(&TempString, "%f %f", LedOnScreenPosition.x, LedOnScreenPosition.y); PrintF(&Tempgs_string, "%f %f", LedOnScreenPosition.x, LedOnScreenPosition.y);
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4); DrawString(RenderBuffer, Tempgs_string, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4);
v2 BoxHalfDim = v2{ 25, 25 }; v2 BoxHalfDim = v2{ 25, 25 };
v2 BoxMin = LedOnScreenPosition - BoxHalfDim; v2 BoxMin = LedOnScreenPosition - BoxHalfDim;
@ -206,7 +233,7 @@ SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
PushRenderBoundingBox2D(RenderBuffer, BoxMin, BoxMax, 2.0f, TealV4); PushRenderBoundingBox2D(RenderBuffer, BoxMin, BoxMax, 2.0f, TealV4);
} }
Context.GeneralWorkQueue->DoQueueWorkUntilDone(Context.GeneralWorkQueue, 0); Context.GeneralWorkQueue->CompleteQueueWork(Context.GeneralWorkQueue, Context.ThreadContext);
} }
#define FOLDHAUS_PANEL_SCULPTURE_VIEW_H #define FOLDHAUS_PANEL_SCULPTURE_VIEW_H

View File

@ -160,11 +160,11 @@ VHD_PackLength_(u8* Buffer, u32 Length, b32 IncludeLength)
} }
internal cid internal cid
StringToCID_ (const char* String) gs_stringToCID_ (const char* gs_string)
{ {
cid Result = {}; cid Result = {};
const char* Src = String; const char* Src = gs_string;
u8* Dest = &Result.Bytes[0]; u8* Dest = &Result.Bytes[0];
b32 FirstNibble = true; b32 FirstNibble = true;
@ -215,7 +215,7 @@ InitStreamHeader (u8* Buffer, s32 BufferSize,
Cursor = PackB2(Cursor, RLP_PREAMBLE_SIZE); Cursor = PackB2(Cursor, RLP_PREAMBLE_SIZE);
Cursor = PackB2(Cursor, RLP_POSTAMBLE_SIZE); Cursor = PackB2(Cursor, RLP_POSTAMBLE_SIZE);
GSMemCopy(ACN_IDENTIFIER, Cursor, ACN_IDENTIFIER_SIZE); CopyMemoryTo(ACN_IDENTIFIER, Cursor, ACN_IDENTIFIER_SIZE);
Cursor += ACN_IDENTIFIER_SIZE; Cursor += ACN_IDENTIFIER_SIZE;
// TODO(Peter): If you never use this anywhere else, go back and remove the parameters // TODO(Peter): If you never use this anywhere else, go back and remove the parameters
@ -243,7 +243,7 @@ InitStreamHeader (u8* Buffer, s32 BufferSize,
// framing source name // framing source name
// :Check // :Check
GSMemCopy(SourceName, (char*)Cursor, SOURCE_NAME_SIZE); CopyMemoryTo(SourceName, (char*)Cursor, SOURCE_NAME_SIZE);
Cursor[SOURCE_NAME_SIZE - 1] = '\0'; Cursor[SOURCE_NAME_SIZE - 1] = '\0';
Cursor += SOURCE_NAME_SIZE; Cursor += SOURCE_NAME_SIZE;
@ -298,7 +298,7 @@ InitializeSACN (context Context)
s32 Multicast_TimeToLive = 20; s32 Multicast_TimeToLive = 20;
SACN.SendSocket = Context.PlatformGetSocketHandle(Multicast_TimeToLive); SACN.SendSocket = Context.PlatformGetSocketHandle(Multicast_TimeToLive);
SACN.CID = StringToCID_ ("{67F9D986-544E-4abb-8986-D5F79382586C}"); SACN.CID = gs_stringToCID_ ("{67F9D986-544E-4abb-8986-D5F79382586C}");
return SACN; return SACN;
} }

View File

@ -18,9 +18,9 @@ struct solid_color_data
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
void SolidColorProc(solid_color_data* Data) void SolidColorProc(solid_color_data* Data)
{ {
u8 R = (u8)GSClamp(0.f, (Data->Color.r * 255), 255.f); u8 R = (u8)Clamp(0.f, (Data->Color.r * 255), 255.f);
u8 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f); u8 G = (u8)Clamp(0.f, (Data->Color.g * 255), 255.f);
u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f); u8 B = (u8)Clamp(0.f, (Data->Color.b * 255), 255.f);
for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++) for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++)
{ {
@ -64,7 +64,7 @@ void VerticalColorFadeProc(vertical_color_fade_data* Data)
v4 LedPosition = Data->Result.LedPositions[LedIndex]; v4 LedPosition = Data->Result.LedPositions[LedIndex];
r32 Amount = (LedPosition.y - Data->Min) / Range; r32 Amount = (LedPosition.y - Data->Min) / Range;
Amount = GSClamp01(1.0f - Amount); Amount = Clamp01(1.0f - Amount);
Data->Result.Colors[LedIndex].R = (u8)(R * Amount); Data->Result.Colors[LedIndex].R = (u8)(R * Amount);
Data->Result.Colors[LedIndex].G = (u8)(G * Amount); Data->Result.Colors[LedIndex].G = (u8)(G * Amount);
@ -107,14 +107,14 @@ void RevolvingDiscs(revolving_discs_data* Data)
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
pixel Color = { pixel Color = {
(u8)(GSClamp01(Data->Color.r) * 255), (u8)(Clamp01(Data->Color.r) * 255),
(u8)(GSClamp01(Data->Color.g) * 255), (u8)(Clamp01(Data->Color.g) * 255),
(u8)(GSClamp01(Data->Color.b) * 255), (u8)(Clamp01(Data->Color.b) * 255),
}; };
v4 Center = v4{0, 0, 0, 1}; v4 Center = v4{0, 0, 0, 1};
v4 Normal = v4{GSCos(Data->ThetaZ), 0, GSSin(Data->ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1 v4 Normal = v4{CosR32(Data->ThetaZ), 0, SinR32(Data->ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
v4 Right = Cross(Normal, v4{0, 1, 0, 0}); v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
v4 FrontCenter = Center + (Normal * Data->DiscWidth); v4 FrontCenter = Center + (Normal * Data->DiscWidth);
v4 BackCenter = Center - (Normal * Data->DiscWidth); v4 BackCenter = Center - (Normal * Data->DiscWidth);
@ -129,13 +129,13 @@ void RevolvingDiscs(revolving_discs_data* Data)
v4 ToFront = Position + FrontCenter; v4 ToFront = Position + FrontCenter;
v4 ToBack = Position + BackCenter; v4 ToBack = Position + BackCenter;
r32 ToFrontDotNormal = Dot(ToFront, Normal); r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
r32 ToBackDotNormal = Dot(ToBack, Normal); r32 ToBackDotNormal = V4Dot(ToBack, Normal);
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000); ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000); ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
r32 SqDistToCenter = MagSqr(Position); r32 SqDistToCenter = V4MagSquared(Position);
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared) if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
{ {
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0)) if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))

View File

@ -16,14 +16,13 @@
#include "../gs_libs/gs_win32.cpp" #include "../gs_libs/gs_win32.cpp"
#include "win32_foldhaus_memory.h" #include "win32_foldhaus_memory.h"
#include "win32_foldhaus_fileio.h"
#include "win32_foldhaus_dll.h" #include "win32_foldhaus_dll.h"
#include "win32_foldhaus_timing.h" #include "win32_foldhaus_timing.h"
#include "foldhaus_renderer.cpp" #include "foldhaus_renderer.cpp"
global_variable b32 Running = false; global b32 Running = false;
global_variable b32 WindowIsActive = false; global b32 WindowIsActive = false;
char DLLName[] = "foldhaus.dll"; char DLLName[] = "foldhaus.dll";
char WorkingDLLName[] = "foldhaus_temp.dll"; char WorkingDLLName[] = "foldhaus_temp.dll";
@ -31,6 +30,317 @@ char DLLLockFileName[] = "lock.tmp";
window MainWindow; window MainWindow;
// Utils
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)
{
Assert(IsNullTerminated(Message));
OutputDebugStringA(Message.Str);
}
#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();
PrintF(&DebugString, "%s Line %d: Win32 Error %d\n\0", File, Line, Error);
OutputDebugStringA(DebugString.Str);
}
internal HINSTANCE
GetHInstance()
{
HINSTANCE Result = GetModuleHandle(NULL);
if (Result == NULL)
{
PrintLastError();
}
return Result;
}
///////////////////////
//
// Fie I/O
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);
}
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 u32
Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list* TempList, gs_const_string Path, gs_memory_arena* Storage, b32 Flags)
{
u32 FilesCount = 0;
u32 IndexOfLastSlash = FindLastFromSet(Path, "\\/");
gs_const_string SearchPath = Substring(Path, 0, IndexOfLastSlash + 1);
WIN32_FIND_DATA FindFileData;
HANDLE SearchHandle = FindFirstFile(Path.Str, &FindFileData);
if (SearchHandle != INVALID_HANDLE_VALUE)
{
do
{
if (HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY))
{
if (HasFlag(Flags, EnumerateDirectory_Recurse))
{
gs_const_string SubDirName = ConstString(FindFileData.cFileName);
if (!StringsEqual(SubDirName, ConstString(".")) &&
!StringsEqual(SubDirName, ConstString("..")))
{
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);
}
}
if (HasFlag(Flags, EnumerateDirectory_IncludeDirectories))
{
FilesCount += 1;
}
}
else
{
temp_file_list_entry* File = PushStruct(FileHandler.Transient, temp_file_list_entry);
File->Info.FileSize = Win32HighLowToU64(FindFileData.nFileSizeLow, FindFileData.nFileSizeHigh);
File->Info.CreationTime = Win32FileTimeToU64(FindFileData.ftCreationTime);
File->Info.LastWriteTime = Win32FileTimeToU64(FindFileData.ftLastWriteTime);
File->Next = 0;
u32 FileNameLength = CharArrayLength(FindFileData.cFileName);
// 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 + 1);
PrintF(&FileName, "%S%.*s", SearchPath, FileName.Size, FindFileData.cFileName);
NullTerminate(&FileName);
File->Info.Path = FileName.ConstString;
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;
}
///////////////////////
//
// Job System
struct worker_thread_entry struct worker_thread_entry
{ {
b32 IsValid; b32 IsValid;
@ -39,11 +349,42 @@ struct worker_thread_entry
struct worker_thread_info struct worker_thread_info
{ {
s32 ID; gs_thread_context ThreadContext;
HANDLE Handle; HANDLE Handle;
work_queue* Queue; gs_work_queue* Queue;
}; };
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 = CreateAllocator(Win32Alloc, Win32Free);
if (Transient != 0)
{
Result.Transient = Transient;
}
else
{
Result.Transient = (gs_memory_arena*)AllocatorAlloc(Result.Allocator, sizeof(gs_memory_arena)).Memory;
*Result.Transient = CreateMemoryArena(Result.Allocator);
}
Result.FileHandler = CreateFileHandler(Win32GetFileInfo,
Win32ReadEntireFile,
Win32WriteEntireFile,
Win32EnumerateDirectory,
Result.Transient);
return Result;
}
PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue) PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -51,18 +392,18 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
// overflowing the buffer // overflowing the buffer
if (Queue->JobsCount >= Queue->JobsMax) if (Queue->JobsCount >= Queue->JobsMax)
{ {
string DebugString = MakeString((char*)malloc(256), 256); gs_string DebugString = MakeString((char*)malloc(256), 256);
for (u32 i = 0; i < Queue->JobsCount; i++) for (u32 i = 0; i < Queue->JobsCount; i++)
{ {
PrintF(&DebugString, "%d %s\n", i, Queue->Jobs[i].JobName); PrintF(&DebugString, "%d %s\n", i, Queue->Jobs[i].JobName);
NullTerminate(&DebugString); NullTerminate(&DebugString);
OutputDebugStringA(DebugString.Memory); OutputDebugStringA(DebugString.Str);
} }
} }
#endif #endif
Assert(Queue->JobsCount < Queue->JobsMax); Assert(Queue->JobsCount < Queue->JobsMax);
worker_thread_job* Job = Queue->Jobs + Queue->JobsCount; gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount;
Job->WorkProc = WorkProc; Job->WorkProc = WorkProc;
Job->Data = Data; Job->Data = Data;
#ifdef DEBUG #ifdef DEBUG
@ -78,7 +419,7 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
} }
internal worker_thread_entry internal worker_thread_entry
CompleteAndTakeNextJob(work_queue* Queue, worker_thread_entry Completed) CompleteAndTakeNextJob(gs_work_queue* Queue, worker_thread_entry Completed, gs_thread_context Context)
{ {
if (Completed.IsValid) if (Completed.IsValid)
{ {
@ -106,16 +447,16 @@ CompleteAndTakeNextJob(work_queue* Queue, worker_thread_entry Completed)
return Result; return Result;
} }
DO_QUEUE_WORK_UNTIL_DONE(Win32DoQueueWorkUntilDone) COMPLETE_QUEUE_WORK(Win32DoQueueWorkUntilDone)
{ {
worker_thread_entry Entry = {}; worker_thread_entry Entry = {};
Entry.IsValid = false; Entry.IsValid = false;
while (Queue->JobsCompleted < Queue->JobsCount) while (Queue->JobsCompleted < Queue->JobsCount)
{ {
Entry = CompleteAndTakeNextJob(Queue, Entry); Entry = CompleteAndTakeNextJob(Queue, Entry, Context);
if (Entry.IsValid) if (Entry.IsValid)
{ {
Queue->Jobs[Entry.Index].WorkProc(ThreadID, Queue->Jobs[Entry.Index].Data); Queue->Jobs[Entry.Index].WorkProc(Context, Queue->Jobs[Entry.Index].Data);
} }
} }
} }
@ -124,15 +465,17 @@ DWORD WINAPI
WorkerThreadProc (LPVOID InputThreadInfo) WorkerThreadProc (LPVOID InputThreadInfo)
{ {
worker_thread_info* ThreadInfo = (worker_thread_info*)InputThreadInfo; worker_thread_info* ThreadInfo = (worker_thread_info*)InputThreadInfo;
ThreadInfo->ThreadContext = Win32CreateThreadContext();
worker_thread_entry Entry = {}; worker_thread_entry Entry = {};
Entry.IsValid = false; Entry.IsValid = false;
while (true) while (true)
{ {
Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry); ClearArena(ThreadInfo->ThreadContext.Transient);
Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry, ThreadInfo->ThreadContext);
if (Entry.IsValid) if (Entry.IsValid)
{ {
ThreadInfo->Queue->Jobs[Entry.Index].WorkProc(ThreadInfo->ID, ThreadInfo->Queue->Jobs[Entry.Index].WorkProc(ThreadInfo->ThreadContext,
ThreadInfo->Queue->Jobs[Entry.Index].Data); ThreadInfo->Queue->Jobs[Entry.Index].Data);
} }
else else
@ -188,13 +531,13 @@ PLATFORM_GET_SOCKET_HANDLE(Win32GetSocketHandle)
{ {
s32 NewDictionaryMax = Win32SocketHandleMax + SOCKET_DICTIONARY_GROW_SIZE; s32 NewDictionaryMax = Win32SocketHandleMax + SOCKET_DICTIONARY_GROW_SIZE;
s32 NewDictionaryDataSize = NewDictionaryMax * sizeof(win32_socket); s32 NewDictionaryDataSize = NewDictionaryMax * sizeof(win32_socket);
u8* DictionaryMemory = Win32Alloc(NewDictionaryDataSize); u8* DictionaryMemory = (u8*)Win32Alloc(NewDictionaryDataSize, 0);
Assert(DictionaryMemory); Assert(DictionaryMemory);
win32_socket* NewValues = (win32_socket*)(DictionaryMemory); win32_socket* NewValues = (win32_socket*)(DictionaryMemory);
if (SocketValues) if (SocketValues)
{ {
GSMemCopy(SocketValues, NewValues, sizeof(win32_socket) * NewDictionaryMax); CopyMemoryTo(SocketValues, NewValues, sizeof(win32_socket) * NewDictionaryMax);
Win32Free((u8*)SocketValues, sizeof(win32_socket) * Win32SocketHandleCount); Win32Free((u8*)SocketValues, sizeof(win32_socket) * Win32SocketHandleCount);
} }
SocketValues = NewValues; SocketValues = NewValues;
@ -512,7 +855,7 @@ internal void
DebugPrint (char* Format, ...) DebugPrint (char* Format, ...)
{ {
char Buffer[256]; char Buffer[256];
string StringBuffer = MakeString(Buffer, 256); gs_string StringBuffer = MakeString(Buffer, 256);
va_list Args; va_list Args;
va_start(Args, Format); va_start(Args, Format);
PrintF(&StringBuffer, Format, Args); PrintF(&StringBuffer, Format, Args);
@ -521,7 +864,7 @@ DebugPrint (char* Format, ...)
} }
internal void internal void
SetApplicationLinks (context* Context, win32_dll_refresh DLL, work_queue* WorkQueue) SetApplicationLinks (context* Context, win32_dll_refresh DLL, gs_work_queue* WorkQueue)
{ {
if (DLL.IsValid) if (DLL.IsValid)
{ {
@ -539,27 +882,22 @@ SetApplicationLinks (context* Context, win32_dll_refresh DLL, work_queue* WorkQu
} }
} }
// TODO(Peter): :Redundant remove
internal u8* internal u8*
DEBUGAlloc(s32 ElementSize, s32 ElementCount) DEBUGAlloc(s32 ElementSize, s32 ElementCount)
{ {
return Win32Alloc(ElementSize * ElementCount); return (u8*)Win32Alloc(ElementSize * ElementCount, 0);
} }
// TODO(Peter): :Redundant remove
internal u8* internal u8*
Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize) Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
{ {
u8* NewMemory = Win32Alloc(NewSize); u8* NewMemory = (u8*)Win32Alloc(NewSize, 0);
GSMemCopy(Buf, NewMemory, OldSize); CopyMemoryTo(Buf, NewMemory, OldSize);
return NewMemory; return NewMemory;
} }
internal s32
Win32GetThreadId()
{
s32 Result = GetCurrentThreadId();
return Result;
}
// NOTE(Peter): Only meant to take one of the values specified below: // 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_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_ICON, IDC_NO, IDC_SIZE, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE,
@ -577,6 +915,36 @@ Win32LoadSystemCursor(char* CursorIdentifier)
return Result; return Result;
} }
internal void
PrintMatrix(m44 M, gs_thread_context Context)
{
gs_string PrintString = AllocatorAllocString(Context.Allocator, 256);
PrintF(&PrintString, "[\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n]\n",
M.Array[0], M.Array[1], M.Array[2], M.Array[3],
M.Array[4], M.Array[5], M.Array[6], M.Array[7],
M.Array[8], M.Array[9], M.Array[10], M.Array[11],
M.Array[12], M.Array[13], M.Array[14], M.Array[15]);
NullTerminate(&PrintString);
OutputDebugStringA(PrintString.Str);
}
v4 PerspectiveDivide(v4 A)
{
v4 Result = {0, 0, 0, 1};
Result.x = A.x / A.w;
Result.y = A.y / A.w;
Result.z = A.z / A.w;
Result.w = A.w;
return Result;
}
v4 ToScreen(v4 P, rect2 WindowBounds)
{
v4 Result = P;
Result.x = RemapR32(P.x, -1, 1, WindowBounds.Min.x, WindowBounds.Max.x);
Result.y = RemapR32(P.y, -1, 1, WindowBounds.Min.y, WindowBounds.Max.y);
return Result;
}
int WINAPI int WINAPI
WinMain ( WinMain (
HINSTANCE HInstance, HINSTANCE HInstance,
@ -585,6 +953,171 @@ WinMain (
INT NCmdShow INT NCmdShow
) )
{ {
gs_thread_context ThreadContext = Win32CreateThreadContext();
{
m44 Before = m44{
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15
};
m44 After = M44Transpose(Before);
OutputDebugStringA("Before:\n");
PrintMatrix(Before, ThreadContext);
OutputDebugStringA("\n\n");
OutputDebugStringA("After:\n");
PrintMatrix(After, ThreadContext);
OutputDebugStringA("\n\n");
}
{
v4 Before = {1, 2, 3, 4};
m44 Transform = {};
for (u32 i = 0; i < 16; i++)
{
Transform.Array[i] = i + 1;
}
v4 After = Transform * Before;
Assert(V4Mag(After - v4{30, 70, 110, 150}) < .00000001f);
}
{ // Translation
v4 Before = {0, 0, 0, 1};
m44 Translation = M44Translation(v4{5, 5, 5, 0});
v4 After = Translation * Before;
Assert((After == v4{5, 5, 5, 1}));
}
{ // X Rotation
v4 Before = {0, 5, 0, 1};
m44 Forward = M44RotationX(HalfPiR32);
m44 Backward = M44RotationX(-HalfPiR32);
v4 After = Forward * Before;
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
After = Backward * Before;
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
}
{ // Y Rotation
v4 Before = {5, 0, 0, 1};
m44 Forward = M44RotationY(HalfPiR32);
m44 Backward = M44RotationY(-HalfPiR32);
v4 After = Forward * Before;
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
After = Backward * Before;
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
}
{ // Z Rotation
v4 Before = {0, 5, 0, 1};
m44 Forward = M44RotationZ(HalfPiR32);
m44 Backward = M44RotationZ(-HalfPiR32);
v4 After = Forward * Before;
Assert(V4Mag(After - v4{-5, 0, 0, 1}) < .000001f);
After = Backward * Before;
Assert(V4Mag(After - v4{5, 0, 0, 1}) < .000001f);
}
{ // Combined X Rotation
v4 Before = {0, 5, 0, 1};
m44 Forward = M44Rotation(v3{HalfPiR32, 0, 0});
m44 Backward = M44Rotation(v3{-HalfPiR32, 0, 0});
v4 After = Forward * Before;
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
After = Backward * Before;
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
}
{ // Combined Y Rotation
v4 Before = {5, 0, 0, 1};
m44 Forward = M44Rotation(v3{0, HalfPiR32, 0});
m44 Backward = M44Rotation(v3{0, -HalfPiR32, 0});
v4 After = Forward * Before;
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
After = Backward * Before;
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
}
{ // Combined Z Rotation
v4 Before = {0, 5, 0, 1};
m44 Forward = M44Rotation(v3{0, 0, HalfPiR32});
m44 Backward = M44Rotation(v3{0, 0, -HalfPiR32});
v4 After = Forward * Before;
Assert(V4Mag(After - v4{-5, 0, 0, 1}) < .000001f);
After = Backward * Before;
Assert(V4Mag(After - v4{5, 0, 0, 1}) < .000001f);
}
{ // Translate then Rotate
v4 Before = v4{0, 0, 0, 1};
m44 Translation = M44Translation(v4{5, 0, 0, 0});
m44 Rotation = M44Rotation(v3{0, 0, HalfPiR32});
m44 Composite = Rotation * Translation;
v4 Inbetween = Translation * Before;
v4 After = Rotation * Inbetween;
Assert(V4Mag(After - v4{0, 5, 0, 1}) < .000001f);
After = Composite * Before;
Assert(V4Mag(After - v4{0, 5, 0, 1}) < .000001f);
}
{ // Two translations
v4 Before = v4{0, 0, 0, 1};
m44 TranslationA = M44Translation(v4{5, 0, 0, 0});
m44 TranslationB = M44Translation(v4{0, 5, 0, 0});
v4 After = TranslationB * TranslationA * Before;
Assert(V4Mag(After - v4{5, 5, 0, 1}) < .000001f);
}
{ // Perspective Transform
rect2 WindowBounds = rect2{
v2{0, 0},
v2{1440.0f, 768.0f},
};
m44 Matrix = M44Translation(v4{0, 0, -200, 0}) * M44Rotation(v3{0, DegToRadR32(45), 0});
m44 Projection = M44ProjectionPerspective(45, RectAspectRatio(WindowBounds), 0.1f, 500);
r32 Rad = 25;
v4 P0 = Matrix * v4{-Rad, -Rad, 0, 1};
v4 P1 = Matrix * v4{Rad, -Rad, 0, 1};
v4 P2 = Matrix * v4{Rad, Rad, 0, 1};
v4 P3 = Matrix * v4{-Rad, Rad, 0, 1};
v4 P0P = Projection * P0;
v4 P1P = Projection * P1;
v4 P2P = Projection * P2;
v4 P3P = Projection * P3;
v4 P0PD = PerspectiveDivide(P0P);
v4 P1PD = PerspectiveDivide(P1P);
v4 P2PD = PerspectiveDivide(P2P);
v4 P3PD = PerspectiveDivide(P3P);
v4 P0S = ToScreen(P0PD, WindowBounds);
P0S.w = 1;
v4 P1S = ToScreen(P1PD, WindowBounds);
P1S.w = 1;
v4 P2S = ToScreen(P2PD, WindowBounds);
P2S.w = 1;
v4 P3S = ToScreen(P3PD, WindowBounds);
P3S.w = 1;
Assert(V4Mag(P0S - v4{630.11401, 256.88202, 0.99930286, 1}) < 0.00001f);
Assert(V4Mag(P1S - v4{795.28662, 277.52859, 0.99948108, 1}) < 0.00001f);
Assert(V4Mag(P2S - v4{795.28662, 490.47144, 0.99948108, 1}) < 0.00001f);
Assert(V4Mag(P3S - v4{630.11401, 511.11798, 0.99930286, 1}) < 0.00001f);
//PushRenderQuad2D(RenderBuffer, P0S.xy, P1S.xy, P2S.xy, P3S.xy, WhiteV4);
}
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents); MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
Win32UpdateWindowDimension(&MainWindow); Win32UpdateWindowDimension(&MainWindow);
@ -612,7 +1145,7 @@ WinMain (
input_queue InputQueue; input_queue InputQueue;
{ {
s32 InputQueueMemorySize = sizeof(input_entry) * 32; s32 InputQueueMemorySize = sizeof(input_entry) * 32;
u8* InputQueueMemory = Win32Alloc(InputQueueMemorySize); u8* InputQueueMemory = (u8*)Win32Alloc(InputQueueMemorySize, 0);
InputQueue = InitializeInputQueue(InputQueueMemory, InputQueueMemorySize); InputQueue = InitializeInputQueue(InputQueueMemory, InputQueueMemorySize);
} }
@ -625,31 +1158,31 @@ WinMain (
WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * PLATFORM_THREAD_COUNT); WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * PLATFORM_THREAD_COUNT);
} }
work_queue WorkQueue = {}; HANDLE WorkQueueSemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS);
WorkQueue.SemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS);
gs_work_queue WorkQueue = {};
WorkQueue.SemaphoreHandle = &WorkQueueSemaphoreHandle;
WorkQueue.JobsMax = 512; WorkQueue.JobsMax = 512;
WorkQueue.Jobs = (worker_thread_job*)Win32Alloc(sizeof(worker_thread_job) * WorkQueue.JobsMax); WorkQueue.Jobs = (gs_threaded_job*)Win32Alloc(sizeof(gs_threaded_job) * WorkQueue.JobsMax, 0);
WorkQueue.NextJobIndex = 0; WorkQueue.NextJobIndex = 0;
WorkQueue.PushWorkOnQueue = Win32PushWorkOnQueue; WorkQueue.PushWorkOnQueue = Win32PushWorkOnQueue;
WorkQueue.DoQueueWorkUntilDone = Win32DoQueueWorkUntilDone; WorkQueue.CompleteQueueWork = Win32DoQueueWorkUntilDone;
WorkQueue.ResetWorkQueue = ResetWorkQueue; WorkQueue.ResetWorkQueue = ResetWorkQueue;
OutputDebugStringA("Hellooooo\n");
for (s32 i = 0; i < PLATFORM_THREAD_COUNT; i++) for (s32 i = 0; i < PLATFORM_THREAD_COUNT; i++)
{ {
// ID = 0 is reserved for this thread // ID = 0 is reserved for this thread
WorkerThreads[i].ID = i + 1;
WorkerThreads[i].Queue = &WorkQueue; WorkerThreads[i].Queue = &WorkQueue;
WorkerThreads[i].Handle = CreateThread(0, 0, &WorkerThreadProc, (void*)&WorkerThreads[i], 0, 0); WorkerThreads[i].Handle = CreateThread(0, 0, &WorkerThreadProc, (void*)&WorkerThreads[i], 0, 0);
} }
s32 InitialMemorySize = Megabytes(64); s32 InitialMemorySize = MB(64);
u8* InitialMemory = Win32Alloc(InitialMemorySize); u8* InitialMemory = (u8*)Win32Alloc(InitialMemorySize, 0);
context Context = {}; context Context = {};
Context.ThreadContext = ThreadContext;
Context.MemorySize = InitialMemorySize; Context.MemorySize = InitialMemorySize;
Context.MemoryBase = InitialMemory; Context.MemoryBase = InitialMemory;
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}}; Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
Context.Mouse = {0}; Context.Mouse = {0};
// Cursors // Cursors
@ -663,12 +1196,6 @@ WinMain (
// Platform functions // Platform functions
Context.GeneralWorkQueue = &WorkQueue; Context.GeneralWorkQueue = &WorkQueue;
Context.PlatformMemory.Alloc = Win32Alloc;
Context.PlatformMemory.Free = Win32Free;
Context.PlatformMemory.Realloc = Win32Realloc;
Context.FileHandler.ReadEntireFile = Win32ReadEntireFile;
Context.FileHandler.WriteEntireFile = Win32WriteEntireFile;
Context.FileHandler.GetFilePath = Win32SystemDialogueOpenFile;
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle; Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
Context.PlatformGetSocketHandle = Win32GetSocketHandle; Context.PlatformGetSocketHandle = Win32GetSocketHandle;
Context.PlatformSetSocketOption = Win32SetSocketOption; Context.PlatformSetSocketOption = Win32SetSocketOption;
@ -692,8 +1219,8 @@ WinMain (
WSADATA WSAData; WSADATA WSAData;
WSAStartup(MAKEWORD(2, 2), &WSAData); WSAStartup(MAKEWORD(2, 2), &WSAData);
s32 RenderMemorySize = Megabytes(12); s32 RenderMemorySize = MB(12);
u8* RenderMemory = Win32Alloc(RenderMemorySize); u8* RenderMemory = (u8*)Win32Alloc(RenderMemorySize, 0);
render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(RenderMemory, RenderMemorySize, Win32Realloc); render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(RenderMemory, RenderMemorySize, Win32Realloc);
Context.InitializeApplication(Context); Context.InitializeApplication(Context);
@ -733,7 +1260,7 @@ WinMain (
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse); HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse);
} }
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}}; Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
RenderBuffer.ViewWidth = MainWindow.Width; RenderBuffer.ViewWidth = MainWindow.Width;
RenderBuffer.ViewHeight = MainWindow.Height; RenderBuffer.ViewHeight = MainWindow.Height;
Context.DeltaTime = LastFrameSecondsElapsed; Context.DeltaTime = LastFrameSecondsElapsed;

View File

@ -22,15 +22,15 @@ struct win32_dll_refresh
}; };
internal int internal int
Win32DLLStringLength(char* String) Win32DLLgs_stringLength(char* gs_string)
{ {
char* At = String; char* At = gs_string;
while (*At) { At++; }; while (*At) { At++; };
return At - String; return At - gs_string;
} }
internal int internal int
Win32DLLConcatStrings(int ALength, char* A, int BLength, char* B, int DestLength, char* Dest) Win32DLLConcatgs_strings(int ALength, char* A, int BLength, char* B, int DestLength, char* Dest)
{ {
char* Dst = Dest; char* Dst = Dest;
char* AAt = A; char* AAt = A;
@ -112,14 +112,14 @@ InitializeDLLHotReloading(char* SourceDLLName,
ExePath.Path = (char*)VirtualAlloc(NULL, ExePath.PathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); ExePath.Path = (char*)VirtualAlloc(NULL, ExePath.PathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
GetApplicationPath(&ExePath); GetApplicationPath(&ExePath);
Win32DLLConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path,
Win32DLLStringLength(SourceDLLName), SourceDLLName, Win32DLLgs_stringLength(SourceDLLName), SourceDLLName,
MAX_PATH, Result.SourceDLLPath); MAX_PATH, Result.SourceDLLPath);
Win32DLLConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path,
Win32DLLStringLength(WorkingDLLFileName), WorkingDLLFileName, Win32DLLgs_stringLength(WorkingDLLFileName), WorkingDLLFileName,
MAX_PATH, Result.WorkingDLLPath); MAX_PATH, Result.WorkingDLLPath);
Win32DLLConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path,
Win32DLLStringLength(LockFileName), LockFileName, Win32DLLgs_stringLength(LockFileName), LockFileName,
MAX_PATH, Result.LockFilePath); MAX_PATH, Result.LockFilePath);
Win32Free((u8*)ExePath.Path, ExePath.PathLength); Win32Free((u8*)ExePath.Path, ExePath.PathLength);

View File

@ -8,138 +8,5 @@
// //
#ifndef WIN32_FOLDHAUS_FILEIO_H #ifndef WIN32_FOLDHAUS_FILEIO_H
PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile)
{
platform_memory_result Result = {};
Result.Error = PlatformMemory_NoError;
Assert(IsNullTerminated(Path));
HANDLE FileHandle = CreateFileA (Path.Memory, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (FileHandle != INVALID_HANDLE_VALUE)
{
DWORD FileSize = GetFileSize(FileHandle, NULL);
Result.Data.Base = (u8*)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (Result.Data.Base)
{
Result.Data.Size = FileSize;
s32 BytesRead = 0;
if (ReadFile(FileHandle, (LPVOID)Result.Data.Base, FileSize, (LPDWORD)(&BytesRead), NULL))
{
}
else
{
u32 Error = GetLastError();
VirtualFree(Result.Data.Base, 0, MEM_RELEASE);
Result.Data.Size = 0;
Result.Error = PlatformMemory_UnknownError;
}
}
else
{
Result.Error = PlatformMemory_UnknownError;
}
CloseHandle(FileHandle);
}
else
{
Result.Error = PlatformMemory_FileNotFound;
}
return Result;
}
PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile)
{
Assert(IsNullTerminated(Path));
b32 Result = false;
HANDLE FileHandle = CreateFileA (
Path.Memory,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (FileHandle != INVALID_HANDLE_VALUE)
{
DWORD BytesWritten = 0;
b32 WriteSuccess = WriteFile(FileHandle,
Contents, Size,
&BytesWritten,
NULL);
if (WriteSuccess && BytesWritten == (u32)Size)
{
CloseHandle(FileHandle);
Result = true;
}
else
{
Result = false;
}
}
else
{
Result = false;
}
return Result;
}
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;
}
PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile)
{
b32 Result = false;
PathBuffer->Memory[0] = 0;
OPENFILENAMEA OpenFileName = {};
OpenFileName.lStructSize = sizeof(OpenFileName);
OpenFileName.hwndOwner = NULL;
OpenFileName.lpstrFilter = FilterStrings;
OpenFileName.lpstrCustomFilter = NULL; // NOTE(Peter): for preserving last filter string chosen
OpenFileName.nMaxCustFilter = 0; // NOTE(Peter): ignored since we left CustomFilter null
OpenFileName.nFilterIndex = 1;
OpenFileName.lpstrFile = PathBuffer->Memory;
OpenFileName.nMaxFile = PathBuffer->Max;
OpenFileName.lpstrFileTitle = NULL;
OpenFileName.nMaxFileTitle = 0; // NOTE(Peter): Ignored since fileTitle is null
OpenFileName.lpstrInitialDir = NULL;
OpenFileName.lpstrTitle = NULL;
OpenFileName.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
OpenFileName.lpstrDefExt = NULL;
Result = GetOpenFileNameA (&OpenFileName);
PathBuffer->Length = CharArrayLength(PathBuffer->Memory);
return Result;
}
#define WIN32_FOLDHAUS_FILEIO_H #define WIN32_FOLDHAUS_FILEIO_H
#endif // WIN32_FOLDHAUS_FILEIO_H #endif // WIN32_FOLDHAUS_FILEIO_H

View File

@ -8,17 +8,21 @@
// //
#ifndef WIN32_FOLDHAUS_MEMORY_H #ifndef WIN32_FOLDHAUS_MEMORY_H
PLATFORM_ALLOC(Win32Alloc) ALLOCATOR_ALLOC(Win32Alloc)
{ {
u8* Result = (u8*)VirtualAlloc(NULL, Size, u8* Result = (u8*)VirtualAlloc(NULL, Size,
MEM_COMMIT | MEM_RESERVE, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE); PAGE_EXECUTE_READWRITE);
if (ResultSize != 0)
{
*ResultSize = Size;
}
return Result; return Result;
} }
PLATFORM_FREE(Win32Free) ALLOCATOR_FREE(Win32Free)
{ {
b32 Result = VirtualFree(Base, 0, MEM_RELEASE); b32 Result = VirtualFree(Ptr, 0, MEM_RELEASE);
if (!Result) if (!Result)
{ {
s32 Error = GetLastError(); s32 Error = GetLastError();
@ -26,18 +30,6 @@ PLATFORM_FREE(Win32Free)
// to know what it could possibly be. // to know what it could possibly be.
InvalidCodePath; InvalidCodePath;
} }
return Result;
}
PLATFORM_REALLOC(Win32Realloc)
{
u8* NewMemory = Win32Alloc(NewSize);
if (Base)
{
GSMemCopy(Base, NewMemory, OldSize);
Win32Free(Base, OldSize);
}
return NewMemory;
} }
#define WIN32_FOLDHAUS_MEMORY_H #define WIN32_FOLDHAUS_MEMORY_H

View File

@ -1,5 +1,6 @@
#ifndef GS_LANGUAGE_H #ifndef GS_LANGUAGE_H
#if 0
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__)
#include <intrin.h> #include <intrin.h>
@ -42,6 +43,8 @@ typedef long long int s64;
typedef float r32; typedef float r32;
typedef double r64; typedef double r64;
#endif
#ifndef _STDINT #ifndef _STDINT
#define INT8_MIN (-128) #define INT8_MIN (-128)

View File

@ -314,7 +314,7 @@ PlatformRealloc(platform_memory_handler Platform, gs_mem_u8* Head, gs_mem_u32 Ol
Result = PlatformAlloc(Platform, NewSize); Result = PlatformAlloc(Platform, NewSize);
if (Head != 0 && OldSize != 0) if (Head != 0 && OldSize != 0)
{ {
GSMemCopy(Head, Result, OldSize); CopyMemoryTo(Head, Result, OldSize);
PlatformFree(Platform, Head, OldSize); PlatformFree(Platform, Head, OldSize);
} }
} }
@ -336,8 +336,6 @@ FreeMemoryArena(memory_arena* Arena)
PlatformFree(Arena->PlatformMemory, (u8*)Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount); PlatformFree(Arena->PlatformMemory, (u8*)Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount);
} }
#define IsPowerOfTwo(v) ((v != 0) && ((v & (v - 1)) == 0))
inline gs_mem_u32 inline gs_mem_u32
GetAlignmentOffset (gs_mem_u64 Address, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask) GetAlignmentOffset (gs_mem_u64 Address, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,7 @@ Write(string Text, string_builder* StringBuilder)
// Copy what there is room for // Copy what there is room for
s32 SpaceAvailable = StringBuilder->Head->String.Max - StringBuilder->Head->String.Length; s32 SpaceAvailable = StringBuilder->Head->String.Max - StringBuilder->Head->String.Length;
ConcatString(TextLeft, GSMin(SpaceAvailable, TextLeft.Length), &StringBuilder->Head->String); ConcatString(TextLeft, Min(SpaceAvailable, TextLeft.Length), &StringBuilder->Head->String);
TextLeft.Memory += SpaceAvailable; TextLeft.Memory += SpaceAvailable;
TextLeft.Length -= SpaceAvailable; TextLeft.Length -= SpaceAvailable;
@ -93,7 +93,7 @@ WriteStringBuilderToFile(string_builder StringBuilder, FILE* WriteFile)
while (BufferAt) while (BufferAt)
{ {
string String = BufferAt->String; string String = BufferAt->String;
fwrite(String.Memory, 1, String.Length, WriteFile); fwrite(String.Str, 1, String.Length, WriteFile);
BufferAt = BufferAt->Next; BufferAt = BufferAt->Next;
} }
} }

3383
src/gs_libs/gs_types.cpp Normal file

File diff suppressed because it is too large Load Diff

1053
src/gs_libs/gs_types.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -105,25 +105,12 @@ union v4
union m33 union m33
{ {
struct float E[3][3];
{
float a; float b; float c;
float d; float e; float f;
float g; float h; float i;
};
float E[9];
}; };
union m44 union m44
{ {
struct float E[4][4];
{
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;
};
float E[16];
}; };
////////////////////////////////////// //////////////////////////////////////
@ -648,10 +635,10 @@ PointIsInRange (v2 _P, v2 _Min, v2 _Max)
static bool static bool
PointIsInRangeSafe (v2 _P, v2 _Min, v2 _Max) PointIsInRangeSafe (v2 _P, v2 _Min, v2 _Max)
{ {
s32 MinX = GSMin(_Min.x, _Max.x); s32 MinX = Min(_Min.x, _Max.x);
s32 MinY = GSMin(_Min.y, _Max.y); s32 MinY = Min(_Min.y, _Max.y);
s32 MaxX = GSMax(_Min.x, _Max.x); s32 MaxX = Max(_Min.x, _Max.x);
s32 MaxY = GSMax(_Min.y, _Max.y); s32 MaxY = Max(_Min.y, _Max.y);
return (_P.x >= MinX && _P.x <= MaxX && return (_P.x >= MinX && _P.x <= MaxX &&
_P.y >= MinY && _P.y <= MaxY); _P.y >= MinY && _P.y <= MaxY);
@ -1438,11 +1425,11 @@ void TestVectorMatrixMultiplication ()
// Utility Functions // Utility Functions
TestClean((GSSqrt(4.f) == 2.f), "Vector Square Root"); TestClean((GSSqrt(4.f) == 2.f), "Vector Square Root");
TestClean((GSLerp(0.f, 1.f, .5f) == .5f), "Vector Lerp"); TestClean((Lerp(0.f, 1.f, .5f) == .5f), "Vector Lerp");
TestClean((GSMin(-.25f, 5.f) == -.25f), "Vector Min"); TestClean((Min(-.25f, 5.f) == -.25f), "Vector Min");
TestClean((GSMax(-.25f, 5.f) == 5.f), "Vector Max"); TestClean((Max(-.25f, 5.f) == 5.f), "Vector Max");
TestClean((GSClamp(-2.f, -3.f, 5.f) == -2.f), "Vector Clamp, Lower Than Range"); TestClean((Clamp(-2.f, -3.f, 5.f) == -2.f), "Vector Clamp, Lower Than Range");
TestClean((GSClamp(-2.f, 6.f, 5.f) == 5.f), "Vector Clamp, Higher Than Range"); TestClean((Clamp(-2.f, 6.f, 5.f) == 5.f), "Vector Clamp, Higher Than Range");
////////////////////////////// //////////////////////////////
// Vector Functions // Vector Functions

View File

@ -45,7 +45,7 @@ struct handle_window_msg_result
#endif #endif
}; };
global_variable win32_state GlobalWin32State; global win32_state GlobalWin32State;
// Utility // Utility
internal s32 Win32StringLength(char* String); internal s32 Win32StringLength(char* String);
@ -66,9 +66,8 @@ internal void Win32DisplayBufferInWindow(win32_offscreen_buffer* Buffer
// Memory // Memory
internal PLATFORM_ALLOC(Win32Alloc); internal ALLOCATOR_ALLOC(Win32Alloc);
internal PLATFORM_FREE(Win32Free); internal ALLOCATOR_FREE(Win32Free);
internal PLATFORM_REALLOC(Win32Realloc);
/// ///
// Utils // Utils

View File

@ -218,8 +218,8 @@ GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelEnumGen, s
} }
WriteF(PanelEnumGen, "enum panel_type {\n"); WriteF(PanelEnumGen, "enum panel_type {\n");
WriteF(PanelCodeGen, "global_variable s32 GlobalPanelDefsCount = %d;\n", Panels.Used); WriteF(PanelCodeGen, "global s32 GlobalPanelDefsCount = %d;\n", Panels.Used);
WriteF(PanelCodeGen, "global_variable panel_definition GlobalPanelDefs[] = {\n"); WriteF(PanelCodeGen, "global panel_definition GlobalPanelDefs[] = {\n");
for (u32 i = 0; i < Panels.Used; i++) for (u32 i = 0; i < Panels.Used; i++)
{ {
panel_elements* Panel = Panels.GetElementAtIndex(i); panel_elements* Panel = Panels.GetElementAtIndex(i);

View File

@ -14,13 +14,32 @@ struct errors
u32 Used; 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 internal void
PushFError (errors* Errors, char* Format, ...) PushFError (errors* Errors, char* Format, ...)
{ {
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE)) if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
{ {
#if 0
Errors->BuffersCount += 1; Errors->BuffersCount += 1;
Errors->Buffers = (error_buffer*)realloc(Errors->Buffers, sizeof(error_buffer*) * Errors->BuffersCount); 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); error_buffer* NewBuffer = Errors->Buffers + (Errors->BuffersCount - 1);
NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE); NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE);
@ -28,8 +47,8 @@ PushFError (errors* Errors, char* Format, ...)
for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++) for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++)
{ {
NewBuffer->Contents[i].Memory = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH); NewBuffer->Contents[i].Str = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH);
NewBuffer->Contents[i].Max = ERROR_MAX_LENGTH; NewBuffer->Contents[i].Size = ERROR_MAX_LENGTH;
NewBuffer->Contents[i].Length = 0; NewBuffer->Contents[i].Length = 0;
} }
} }

View File

@ -1,7 +1,7 @@
struct token_selection_spec struct token_selection_spec
{ {
b32 MatchText; b32 MatchText;
string Text; gs_string Text;
}; };
internal s32 internal s32
@ -160,69 +160,69 @@ GetNextToken (tokenizer* Tokenizer)
{ {
Result.Type = Token_PoundDefine; Result.Type = Token_PoundDefine;
EatPreprocessor(Tokenizer); EatPreprocessor(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "undef")) else if (TokenAtEquals(Tokenizer, "undef"))
{ {
Result.Type = Token_PoundUndef; Result.Type = Token_PoundUndef;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "include")) else if (TokenAtEquals(Tokenizer, "include"))
{ {
Result.Type = Token_PoundInclude; Result.Type = Token_PoundInclude;
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "ifdef")) else if (TokenAtEquals(Tokenizer, "ifdef"))
{ {
Result.Type = Token_PoundIfDef; Result.Type = Token_PoundIfDef;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "ifndef")) else if (TokenAtEquals(Tokenizer, "ifndef"))
{ {
Result.Type = Token_PoundIfNDef; Result.Type = Token_PoundIfNDef;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "if")) else if (TokenAtEquals(Tokenizer, "if"))
{ {
Result.Type = Token_PoundIf; Result.Type = Token_PoundIf;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "elif")) else if (TokenAtEquals(Tokenizer, "elif"))
{ {
Result.Type = Token_PoundElif; Result.Type = Token_PoundElif;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "else")) else if (TokenAtEquals(Tokenizer, "else"))
{ {
Result.Type = Token_PoundElse; Result.Type = Token_PoundElse;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "endif")) else if (TokenAtEquals(Tokenizer, "endif"))
{ {
Result.Type = Token_PoundEndif; Result.Type = Token_PoundEndif;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "error")) else if (TokenAtEquals(Tokenizer, "error"))
{ {
Result.Type = Token_PoundError; Result.Type = Token_PoundError;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
else if (TokenAtEquals(Tokenizer, "pragma")) else if (TokenAtEquals(Tokenizer, "pragma"))
{ {
Result.Type = Token_PoundPragma; Result.Type = Token_PoundPragma;
EatToNewLine(Tokenizer); EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory; Result.Text.Length = Tokenizer->At - Result.Text.Str;
} }
} }
else if (IsNumeric(C)) else if (IsNumericExtended(C))
{ {
Result.Type = Token_Number; Result.Type = Token_Number;
@ -233,7 +233,7 @@ GetNextToken (tokenizer* Tokenizer)
else if (C == '\'') else if (C == '\'')
{ {
Result.Type = Token_Char; Result.Type = Token_Char;
Result.Text.Memory = Tokenizer->At; Result.Text.Str = Tokenizer->At;
if (Tokenizer->At[0] && Tokenizer->At[0] == '\\') if (Tokenizer->At[0] && Tokenizer->At[0] == '\\')
{ {
++Tokenizer->At; ++Tokenizer->At;
@ -245,7 +245,7 @@ GetNextToken (tokenizer* Tokenizer)
{ {
Result.Type = Token_String; Result.Type = Token_String;
// replace the length added by the quote // replace the length added by the quote
Result.Text.Memory = Tokenizer->At; Result.Text.Str = Tokenizer->At;
Result.Text.Length = EatString(Tokenizer); Result.Text.Length = EatString(Tokenizer);
} }
// NOTE(Peter): This is after comment parsing so that the division operator // NOTE(Peter): This is after comment parsing so that the division operator