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;
@ -30,7 +30,7 @@ RenderNodeLister(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
FilterSearchLister(&OpState->SearchLister); FilterSearchLister(&OpState->SearchLister);
// Display Search Lister // Display Search Lister
search_lister_result NodeListerResult = EvaluateSearchLister (&State->Interface_, TopLeft, Dimension, search_lister_result NodeListerResult = EvaluateSearchLister (&State->Interface_, TopLeft, Dimension,
MakeStringLiteral("Nodes List"), MakeStringLiteral("Nodes List"),
OpState->SearchLister.SourceList, OpState->SearchLister.SourceList,
OpState->SearchLister.FilteredIndexLUT, OpState->SearchLister.FilteredIndexLUT,
@ -85,12 +85,12 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
AddNodeOperation->Render = RenderNodeLister; AddNodeOperation->Render = RenderNodeLister;
node_lister_operation_state* OpState = CreateOperationState(AddNodeOperation, node_lister_operation_state* OpState = CreateOperationState(AddNodeOperation,
&State->Modes, &State->Modes,
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,12 +133,12 @@ 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;
b32 ShouldClose = EvaluateColorPicker(RenderBuffer, OpState->ValueAddr, b32 ShouldClose = EvaluateColorPicker(RenderBuffer, OpState->ValueAddr,
v2{200, 200}, State->Interface, Mouse); v2{200, 200}, State->Interface, Mouse);
if (ShouldClose) if (ShouldClose)
@ -157,8 +157,8 @@ OpenColorPicker(app_state* State, node_connection* Connection)
operation_mode* ColorPickerMode = ActivateOperationModeWithCommands(&State->Modes, ColorPickerCommands); operation_mode* ColorPickerMode = ActivateOperationModeWithCommands(&State->Modes, ColorPickerCommands);
ColorPickerMode->Render = RenderColorPicker; ColorPickerMode->Render = RenderColorPicker;
color_picker_operation_state* OpState = CreateOperationState(ColorPickerMode, color_picker_operation_state* OpState = CreateOperationState(ColorPickerMode,
&State->Modes, &State->Modes,
color_picker_operation_state); color_picker_operation_state);
OpState->ValueAddr = Connection->V4ValuePtr; OpState->ValueAddr = Connection->V4ValuePtr;
} }
@ -184,7 +184,7 @@ input_command NodeFieldTextEditCommands [] = {
internal void internal void
BeginNodeFieldTextEdit(app_state* State, node_connection* Connection) BeginNodeFieldTextEdit(app_state* State, node_connection* Connection)
{ {
operation_mode* NodeFieldTextEditMode = ActivateOperationModeWithCommands(&State->Modes, operation_mode* NodeFieldTextEditMode = ActivateOperationModeWithCommands(&State->Modes,
NodeFieldTextEditCommands); NodeFieldTextEditCommands);
SetTextInputDestinationToFloat(&State->ActiveTextEntry, Connection->R32ValuePtr); SetTextInputDestinationToFloat(&State->ActiveTextEntry, Connection->R32ValuePtr);
@ -202,10 +202,10 @@ 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,
State->NodeRenderSettings, RenderBuffer); State->NodeRenderSettings, RenderBuffer);
} }
@ -225,12 +225,12 @@ internal void
BeginDraggingNodePort(app_state* State, node_interaction Interaction) BeginDraggingNodePort(app_state* State, node_interaction Interaction)
{ {
operation_mode* DragNodePortMode = ActivateOperationModeWithCommands( operation_mode* DragNodePortMode = ActivateOperationModeWithCommands(
&State->Modes, &State->Modes,
DragNodePortInputCommands); DragNodePortInputCommands);
DragNodePortMode->Render = RenderDraggingNodePort; DragNodePortMode->Render = RenderDraggingNodePort;
drag_node_port_operation_state* OpState = CreateOperationState(DragNodePortMode, drag_node_port_operation_state* OpState = CreateOperationState(DragNodePortMode,
&State->Modes, &State->Modes,
drag_node_port_operation_state); drag_node_port_operation_state);
OpState->Interaction = Interaction; OpState->Interaction = Interaction;
} }
@ -242,16 +242,16 @@ 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);
} }
internal void internal void
BeginInteractWithNodeField(app_state* State, node_interaction Interaction) BeginInteractWithNodeField(app_state* State, node_interaction Interaction)
{ {
// TODO(Peter): // TODO(Peter):
} }
//////////////////////////////////////// ////////////////////////////////////////
@ -266,10 +266,10 @@ 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,
State->NodeRenderSettings); State->NodeRenderSettings);
} }
@ -286,12 +286,12 @@ internal void
BeginDraggingNode(app_state* State, node_interaction Interaction) BeginDraggingNode(app_state* State, node_interaction Interaction)
{ {
operation_mode* DragNodeMode = ActivateOperationModeWithCommands( operation_mode* DragNodeMode = ActivateOperationModeWithCommands(
&State->Modes, &State->Modes,
DragNodeInputCommands); DragNodeInputCommands);
DragNodeMode->Render = RenderDraggingNode; DragNodeMode->Render = RenderDraggingNode;
drag_node_operation_state* OpState = CreateOperationState(DragNodeMode, drag_node_operation_state* OpState = CreateOperationState(DragNodeMode,
&State->Modes, &State->Modes,
drag_node_operation_state); drag_node_operation_state);
OpState->Interaction = Interaction; OpState->Interaction = Interaction;
} }
@ -314,8 +314,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction)
node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings); node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings);
if (Node) if (Node)
{ {
node_interaction NewInteraction = GetNodeInteractionType(Node, node_interaction NewInteraction = GetNodeInteractionType(Node,
Mouse.Pos, Mouse.Pos,
State->NodeRenderSettings); State->NodeRenderSettings);
if (IsDraggingNodePort(NewInteraction)) if (IsDraggingNodePort(NewInteraction))
{ {
@ -324,7 +324,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction)
else if(IsDraggingNodeValue(NewInteraction)) else if(IsDraggingNodeValue(NewInteraction))
{ {
// TODO(Peter): This probably wants to live in a mouse held action // TODO(Peter): This probably wants to live in a mouse held action
// the first frame we realize we're held over a field, just transition to // the first frame we realize we're held over a field, just transition to
// drag node field // drag node field
//BeginInteractWithNodeField(State, NewInteraction, State->NodeRenderSettings); //BeginInteractWithNodeField(State, NewInteraction, State->NodeRenderSettings);
} }
@ -347,8 +347,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction)
node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.Pos, State->NodeRenderSettings); node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.Pos, State->NodeRenderSettings);
if (Node) if (Node)
{ {
node_interaction NewInteraction = GetNodeInteractionType(Node, node_interaction NewInteraction = GetNodeInteractionType(Node,
Mouse.Pos, Mouse.Pos,
State->NodeRenderSettings); State->NodeRenderSettings);
if(IsDraggingNodeValue(NewInteraction)) if(IsDraggingNodeValue(NewInteraction))
{ {
@ -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,12 +408,12 @@ 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);
// //
// TODO(Peter): I don't like excluding OutputNode, feels too much like a special case // TODO(Peter): I don't like excluding OutputNode, feels too much like a special case
// but I don't want to get in to the meta programming right now. // but I don't want to get in to the meta programming right now.
// We should just generate a spec and struct member types for NodeType_OutputNode // We should just generate a spec and struct member types for NodeType_OutputNode
// //
// :ExcludingOutputNodeSpecialCase // :ExcludingOutputNodeSpecialCase
@ -422,21 +422,21 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
{ {
node_specification Spec = NodeSpecifications[Node->Type]; node_specification Spec = NodeSpecifications[Node->Type];
node_struct_member Member = Spec.MemberList[Connection]; node_struct_member Member = Spec.MemberList[Connection];
DrawString(RenderBuffer, MakeString(Member.Name), DrawString(RenderBuffer, MakeString(Member.Name),
State->NodeRenderSettings.Font, State->NodeRenderSettings.Font,
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,
// whereas output ports might have many connections, they really only know about the most recent one // whereas output ports might have many connections, they really only know about the most recent one
// Not sure if this is a problem. We mostly do everything backwards here, starting at the // Not sure if this is a problem. We mostly do everything backwards here, starting at the
// most downstream node and working back up to find dependencies. // 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,25 +446,25 @@ 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)
{ {
node_specification Spec = NodeSpecifications[Node->Type]; node_specification Spec = NodeSpecifications[Node->Type];
node_struct_member Member = Spec.MemberList[Connection]; node_struct_member Member = Spec.MemberList[Connection];
DrawString(RenderBuffer, MakeString(Member.Name), DrawString(RenderBuffer, MakeString(Member.Name),
State->NodeRenderSettings.Font, State->NodeRenderSettings.Font,
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]);
} }
} }
@ -501,8 +501,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView)
operation_mode* NodeViewMode = ActivateOperationModeWithCommands(&State->Modes, NodeViewCommands); operation_mode* NodeViewMode = ActivateOperationModeWithCommands(&State->Modes, NodeViewCommands);
NodeViewMode->Render = RenderNodeView; NodeViewMode->Render = RenderNodeView;
node_view_operation_state* OpState = CreateOperationState(NodeViewMode, node_view_operation_state* OpState = CreateOperationState(NodeViewMode,
&State->Modes, &State->Modes,
node_view_operation_state); node_view_operation_state);
OpState->SelectedNodeHandle = 0; OpState->SelectedNodeHandle = 0;

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

@ -8,7 +8,7 @@
#define FOLDHAUS_INPUT_COMMAND_PROC(name) void name(app_state* State, input_entry Event, mouse_state Mouse) #define FOLDHAUS_INPUT_COMMAND_PROC(name) void name(app_state* State, input_entry Event, mouse_state Mouse)
typedef FOLDHAUS_INPUT_COMMAND_PROC(input_command_proc); typedef FOLDHAUS_INPUT_COMMAND_PROC(input_command_proc);
// NOTE(Peter): Helper function so I don't have to remember the parameters to this define // NOTE(Peter): Helper function so I don't have to remember the parameters to this define
#define ExecFoldhausCommand(cmd) cmd(State, Event, Mouse) #define ExecFoldhausCommand(cmd) cmd(State, Event, Mouse)
enum input_command_flags enum input_command_flags
@ -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;
@ -115,8 +115,8 @@ internal void
RemoveCommandFromQueue(input_command_queue* Queue, s32 Index) RemoveCommandFromQueue(input_command_queue* Queue, s32 Index)
{ {
s32 CommandIndex = Index; s32 CommandIndex = Index;
if (CommandIndex < Queue->Used) if (CommandIndex < Queue->Used)
{ {
Queue->Used -= 1; Queue->Used -= 1;
for (; CommandIndex < Queue->Used; CommandIndex++) for (; CommandIndex < Queue->Used; CommandIndex++)
@ -132,9 +132,9 @@ RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_
s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event); s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event);
// NOTE(Peter): If we made it through the queue without finding an event, there wasn't one // NOTE(Peter): If we made it through the queue without finding an event, there wasn't one
// to remove. This happens when we've changed command registries as a result of an input command, // to remove. This happens when we've changed command registries as a result of an input command,
// and the command exists in the new registry. // and the command exists in the new registry.
// For example: // For example:
// clicking a mouse button triggers a command to switch registries // clicking a mouse button triggers a command to switch registries
// the new registry tracks mouse drag (persist until release) // the new registry tracks mouse drag (persist until release)
// when the mouse is released, the event fires, but there is no mouse down event to remove // when the mouse is released, the event fires, but there is no mouse down event to remove

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];
@ -168,12 +168,12 @@ StartDebugFrame(debug_frame* Frame, debug_services* Services)
} }
internal void internal void
InitDebugServices (debug_services* Services, InitDebugServices (debug_services* Services,
s64 PerformanceCountFrequency, s64 PerformanceCountFrequency,
debug_alloc* Alloc, debug_alloc* Alloc,
debug_realloc* Realloc, debug_realloc* Realloc,
debug_timing_proc* GetWallClock, debug_timing_proc* GetWallClock,
debug_get_thread_id* GetThreadId, debug_get_thread_id* GetThreadId,
s32 ThreadCount) s32 ThreadCount)
{ {
Services->Alloc = Alloc; Services->Alloc = Alloc;
@ -233,7 +233,7 @@ GetIndexForNameHash(debug_frame* Frame, u32 NameHash)
} }
// NOTE(Peter): Its not technically wrong to return a -1 here, just means we didn't find it. // NOTE(Peter): Its not technically wrong to return a -1 here, just means we didn't find it.
// At the time of writing however, this function is only being called in contexts where we // At the time of writing however, this function is only being called in contexts where we
// know there should be an entry in the Name table, so a -1 actually indicates a problem. // know there should be an entry in the Name table, so a -1 actually indicates a problem.
Assert(Result >= 0); Assert(Result >= 0);
return Result; return Result;
@ -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;
@ -402,7 +402,7 @@ internal r32 DEBUGGetSecondsElapsed (s64 Start, s64 End, r32 PerformanceCountFre
#define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices) #define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices)
#define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices) #define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices)
#else #else
#define DEBUG_TRACK_FUNCTION #define DEBUG_TRACK_FUNCTION
#define DEBUG_TRACK_SCOPE(name) #define DEBUG_TRACK_SCOPE(name)
#endif #endif
struct scope_tracker struct scope_tracker

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

@ -45,7 +45,7 @@ SortNodeNeighbors(u32 ContiguousNodeIndex, gs_list_handle NodeHandle, adjacency_
u32 ContiguousNeighborNodeIndex = SparseToContiguousNodeMap[Neighbor->NodeHandle.Index]; u32 ContiguousNeighborNodeIndex = SparseToContiguousNodeMap[Neighbor->NodeHandle.Index];
if (!NodesVisited[ContiguousNeighborNodeIndex]) if (!NodesVisited[ContiguousNeighborNodeIndex])
{ {
SortedNodesCount = SortNodeNeighbors(ContiguousNeighborNodeIndex, Neighbor->NodeHandle, NeighborsLists, NodesVisited, SortedNodeHandles, SortedNodesCount, SparseToContiguousNodeMap); SortedNodesCount = SortNodeNeighbors(ContiguousNeighborNodeIndex, Neighbor->NodeHandle, NeighborsLists, NodesVisited, SortedNodeHandles, SortedNodesCount, SparseToContiguousNodeMap);
} }
Neighbor = Neighbor->Next; Neighbor = Neighbor->Next;
} }
@ -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);
@ -81,7 +81,7 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
s32* SparseToContiguousNodeMap = CreateSparseToContiguousMap(*Workspace, &Workspace->Storage); s32* SparseToContiguousNodeMap = CreateSparseToContiguousMap(*Workspace, &Workspace->Storage);
// NOTE(Peter): We need to sort this later on so I'm just storing list lengths in this format // NOTE(Peter): We need to sort this later on so I'm just storing list lengths in this format
// to begin with. // to begin with.
// NeighborsListLengths[n].Radix = the number of neighbors for the node // NeighborsListLengths[n].Radix = the number of neighbors for the node
// NeighborsListLengths[n].ID = the sparse array index of the node // NeighborsListLengths[n].ID = the sparse array index of the node
gs_radix_entry* NeighborsListLengths = PushArray(Scratch, gs_radix_entry, NodeCount); gs_radix_entry* NeighborsListLengths = PushArray(Scratch, gs_radix_entry, NodeCount);
@ -119,24 +119,24 @@ 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);
GSZeroArray(NodesVisited, b8, NodeCount); GSZeroArray(NodesVisited, 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,13 +172,13 @@ 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;
Connection.DownstreamNodeHandle = DownstreamNodeHandle; Connection.DownstreamNodeHandle = DownstreamNodeHandle;
Connection.UpstreamPortIndex = UpstreamPortIndex; Connection.UpstreamPortIndex = UpstreamPortIndex;
Connection.DownstreamPortIndex = DownstreamPortIndex; Connection.DownstreamPortIndex = DownstreamPortIndex;
Workspace->Connections.PushElementOnBucket(Connection); Workspace->Connections.PushElementOnBucket(Connection);
UpdateSortedNodes(Workspace, Scratch); UpdateSortedNodes(Workspace, Scratch);

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

@ -64,7 +64,7 @@ Render2DQuadBatch (u8* CommandData, s32 QuadCount)
v2 P1 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 1)]; v2 P1 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 1)];
v2 P2 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 2)]; v2 P2 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 2)];
v2 UV0 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 0)]; v2 UV0 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 0)];
v2 UV1 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 1)]; v2 UV1 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 1)];
v2 UV2 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 2)]; v2 UV2 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 2)];
v4 C0 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 0)]; v4 C0 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 0)];
v4 C1 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 1)]; v4 C1 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 1)];
@ -107,11 +107,11 @@ RenderCommandBuffer (render_command_buffer CommandBuffer)
render_command_set_render_mode* Command = (render_command_set_render_mode*)(CommandHeader + 1); render_command_set_render_mode* Command = (render_command_set_render_mode*)(CommandHeader + 1);
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;
internal m44
GetCameraMatrix(camera Camera)
{
m44 ModelView = GetCameraModelViewMatrix(Camera);
m44 Projection = GetCameraPerspectiveProjectionMatrix(Camera);
m44 Result = Projection * ModelView;
return Result;
}
internal v2
ProjectWorldPointToScreen(v4 WorldSpacePoint, camera Camera, rect2 WindowBounds)
{
v2 WindowExtents = v2{Rect2Width(WindowBounds), Rect2Height(WindowBounds)};
v4 ProjectedPosition = GetCameraMatrix(Camera) * WorldSpacePoint;
ProjectedPosition.xyz /= ProjectedPosition.w;
v2 ScreenPosition = V2MultiplyPairwise(ProjectedPosition.xy, (WindowExtents / 2)) + (WindowExtents / 2);
r32 A = ((Right + Left) / (Right - Left)); return ScreenPosition;
r32 B = ((Top + Bottom) / (Top - Bottom)); }
r32 C = -((Camera.Far + Camera.Near) / (Camera.Far - Camera.Near));
r32 D = -((2 * Camera.Far * Camera.Near) / (Camera.Far - Camera.Near)); internal v4_ray
ProjectScreenPointToWorldRay(v2 ScreenPoint, camera Camera, rect2 WindowBounds)
{
v4_ray Result = {0};
r32 E = ((2 * Camera.Near) / (Right - Left)); r32 TanFOVOverTwo = TanR32(DegToRadR32(Camera.FieldOfView / 2.0f));
r32 F = ((2 * Camera.Near) / (Top - Bottom)); r32 Aspect = RectAspectRatio(WindowBounds);
m44 PerspectiveProjectionMatrix = r32 NormalizedX = ScreenPoint.x / Rect2Width(WindowBounds);
{ r32 NormalizedY = ScreenPoint.y / Rect2Height(WindowBounds);
E, 0, A, 0,
0, F, B, 0,
0, 0, C, D,
0, 0, -1, 0
};
return PerspectiveProjectionMatrix; 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>
@ -7,7 +8,7 @@
#include <math.h> #include <math.h>
#elif defined(__APPLE__) && defined(__MAC__) #elif defined(__APPLE__) && defined(__MAC__)
// TODO(Peter): // TODO(Peter):
#else // Std lib #else // Std lib
#include <stdlib.h> #include <stdlib.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)
@ -268,15 +271,15 @@ GSLerpDef(r32)
GSLerpDef(r64) GSLerpDef(r64)
#undef GSLerpDef #undef GSLerpDef
static r32 GSSqrt(r32 V) static r32 GSSqrt(r32 V)
{ {
r32 Result = _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(V))); r32 Result = _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(V)));
return Result; return Result;
} }
#if 0 #if 0
// TODO(Peter): Need a way to split the input into two f32's to supply to _mm_sqrt_sd // TODO(Peter): Need a way to split the input into two f32's to supply to _mm_sqrt_sd
static r64 GSSqrt(r64 V) static r64 GSSqrt(r64 V)
{ {
r64 Result = _mm_cvtsd_f64(_mm_sqrt_sd(_mm_set_sd(V))); r64 Result = _mm_cvtsd_f64(_mm_sqrt_sd(_mm_set_sd(V)));
return Result; return Result;
} }
@ -366,9 +369,9 @@ RoundToNearestPowerOfTwo (u8 V)
{ {
u8 Result = 0; u8 Result = 0;
if (IsPowerOfTwo(V)) if (IsPowerOfTwo(V))
{ {
Result = V; Result = V;
} }
else else
{ {
@ -387,9 +390,9 @@ RoundToNearestPowerOfTwo (u16 V)
{ {
u16 Result = 0; u16 Result = 0;
if (IsPowerOfTwo(V)) if (IsPowerOfTwo(V))
{ {
Result = V; Result = V;
} }
else else
{ {
@ -409,9 +412,9 @@ RoundToNearestPowerOfTwo (u32 V)
{ {
u32 Result = 0; u32 Result = 0;
if (IsPowerOfTwo(V)) if (IsPowerOfTwo(V))
{ {
Result = V; Result = V;
} }
else else
{ {
@ -432,9 +435,9 @@ RoundToNearestPowerOfTwo (u64 V)
{ {
u64 Result = 0; u64 Result = 0;
if (IsPowerOfTwo(V)) if (IsPowerOfTwo(V))
{ {
Result = V; Result = V;
} }
else else
{ {

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

@ -37,7 +37,7 @@ GrowStringBuilder(string_builder* StringBuilder)
{ {
StringBuilder->Buffers = NewBuffer; StringBuilder->Buffers = NewBuffer;
StringBuilder->Head = NewBuffer; StringBuilder->Head = NewBuffer;
} }
else else
{ {
StringBuilder->Head->Next = NewBuffer; StringBuilder->Head->Next = NewBuffer;
@ -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

@ -27,7 +27,7 @@ struct window
char* ClassName; char* ClassName;
s32 Width; s32 Width;
s32 Height; s32 Height;
WNDPROC WindowEventHandler; WNDPROC WindowEventHandler;
WNDCLASS Class; WNDCLASS Class;
HWND Handle; HWND Handle;
@ -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,15 +66,14 @@ 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
/// ///
internal s32 internal s32
Win32StringLength(char* String) Win32StringLength(char* String)
{ {
char* At = String; char* At = String;
@ -82,7 +81,7 @@ Win32StringLength(char* String)
return At - String; return At - String;
} }
internal s32 internal s32
Win32ConcatStrings(s32 ALength, char* A, s32 BLength, char* B, s32 DestLength, char* Dest) Win32ConcatStrings(s32 ALength, char* A, s32 BLength, char* B, s32 DestLength, char* Dest)
{ {
char* Dst = Dest; char* Dst = Dest;
@ -110,7 +109,7 @@ Win32ConcatStrings(s32 ALength, char* A, s32 BLength, char* B, s32 DestLength, c
/// ///
internal window internal window
Win32CreateWindow (HINSTANCE HInstance, char* WindowName, s32 Width, s32 Height, Win32CreateWindow (HINSTANCE HInstance, char* WindowName, s32 Width, s32 Height,
WNDPROC WindowEventHandler) WNDPROC WindowEventHandler)
{ {
window Result = {}; window Result = {};
@ -131,14 +130,14 @@ Win32CreateWindow (HINSTANCE HInstance, char* WindowName, s32 Width, s32 Height,
Result.Handle = CreateWindowEx( Result.Handle = CreateWindowEx(
0, 0,
Result.Class.lpszClassName, Result.Class.lpszClassName,
WindowName, WindowName,
WS_OVERLAPPEDWINDOW | WS_VISIBLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
Width, Width,
Height, Height,
0, 0,
0, 0,
HInstance, HInstance,
0); 0);
Result.DeviceContext = GetDC(Result.Handle); Result.DeviceContext = GetDC(Result.Handle);
@ -276,9 +275,9 @@ Win32HandleWindowsEvents (
) )
{ {
handle_window_event_result EventResult = HandleWindowEventUnlessWouldUseDefault( handle_window_event_result EventResult = HandleWindowEventUnlessWouldUseDefault(
WindowHandle, WindowHandle,
Msg, Msg,
wParam, wParam,
lParam); lParam);
if (!EventResult.Handled) if (!EventResult.Handled)
@ -298,92 +297,92 @@ Win32GetKeyCode (int Win32VirtualKey, bool NumpadValid, bool TranslateToChar)
if (!TranslateToChar) if (!TranslateToChar)
{ {
if (Win32VirtualKey == VK_SPACE) { Result = KeyCode_Space; } if (Win32VirtualKey == VK_SPACE) { Result = KeyCode_Space; }
} }
if (Win32VirtualKey == VK_CAPITAL) { Result = KeyCode_CapsLock; } if (Win32VirtualKey == VK_CAPITAL) { Result = KeyCode_CapsLock; }
else if (Win32VirtualKey == VK_TAB) { Result = KeyCode_Tab; } else if (Win32VirtualKey == VK_TAB) { Result = KeyCode_Tab; }
else if (Win32VirtualKey == VK_LSHIFT) { Result = KeyCode_LeftShift; } else if (Win32VirtualKey == VK_LSHIFT) { Result = KeyCode_LeftShift; }
else if (Win32VirtualKey == VK_RSHIFT) { Result = KeyCode_RightShift; } else if (Win32VirtualKey == VK_RSHIFT) { Result = KeyCode_RightShift; }
else if (Win32VirtualKey == VK_LCONTROL) { Result = KeyCode_LeftCtrl; } else if (Win32VirtualKey == VK_LCONTROL) { Result = KeyCode_LeftCtrl; }
else if (Win32VirtualKey == VK_RCONTROL) { Result = KeyCode_RightCtrl; } else if (Win32VirtualKey == VK_RCONTROL) { Result = KeyCode_RightCtrl; }
// TODO(Peter): support the function key? // TODO(Peter): support the function key?
//else if (Win32VirtualKey == VK_) { Result = KeyCode_Fn; } //else if (Win32VirtualKey == VK_) { Result = KeyCode_Fn; }
else if (Win32VirtualKey == VK_MENU) { Result = KeyCode_Alt; } else if (Win32VirtualKey == VK_MENU) { Result = KeyCode_Alt; }
else if (Win32VirtualKey == VK_PRIOR) { Result = KeyCode_PageUp; } else if (Win32VirtualKey == VK_PRIOR) { Result = KeyCode_PageUp; }
else if (Win32VirtualKey == VK_NEXT) { Result = KeyCode_PageDown; } else if (Win32VirtualKey == VK_NEXT) { Result = KeyCode_PageDown; }
else if (Win32VirtualKey == VK_BACK) { Result = KeyCode_Backspace; } else if (Win32VirtualKey == VK_BACK) { Result = KeyCode_Backspace; }
else if (Win32VirtualKey == VK_DELETE) { Result = KeyCode_Delete; } else if (Win32VirtualKey == VK_DELETE) { Result = KeyCode_Delete; }
else if (Win32VirtualKey == VK_RETURN) { Result = KeyCode_Enter; } else if (Win32VirtualKey == VK_RETURN) { Result = KeyCode_Enter; }
else if (Win32VirtualKey == VK_F1) { Result = KeyCode_F1; } else if (Win32VirtualKey == VK_F1) { Result = KeyCode_F1; }
else if (Win32VirtualKey == VK_F2) { Result = KeyCode_F2; } else if (Win32VirtualKey == VK_F2) { Result = KeyCode_F2; }
else if (Win32VirtualKey == VK_F3) { Result = KeyCode_F3; } else if (Win32VirtualKey == VK_F3) { Result = KeyCode_F3; }
else if (Win32VirtualKey == VK_F4) { Result = KeyCode_F4; } else if (Win32VirtualKey == VK_F4) { Result = KeyCode_F4; }
else if (Win32VirtualKey == VK_F5) { Result = KeyCode_F5; } else if (Win32VirtualKey == VK_F5) { Result = KeyCode_F5; }
else if (Win32VirtualKey == VK_F6) { Result = KeyCode_F6; } else if (Win32VirtualKey == VK_F6) { Result = KeyCode_F6; }
else if (Win32VirtualKey == VK_F7) { Result = KeyCode_F7; } else if (Win32VirtualKey == VK_F7) { Result = KeyCode_F7; }
else if (Win32VirtualKey == VK_F8) { Result = KeyCode_F8; } else if (Win32VirtualKey == VK_F8) { Result = KeyCode_F8; }
else if (Win32VirtualKey == VK_F9) { Result = KeyCode_F9; } else if (Win32VirtualKey == VK_F9) { Result = KeyCode_F9; }
else if (Win32VirtualKey == VK_F10) { Result = KeyCode_F10; } else if (Win32VirtualKey == VK_F10) { Result = KeyCode_F10; }
else if (Win32VirtualKey == VK_F11) { Result = KeyCode_F11; } else if (Win32VirtualKey == VK_F11) { Result = KeyCode_F11; }
else if (Win32VirtualKey == VK_F12) { Result = KeyCode_F12; } else if (Win32VirtualKey == VK_F12) { Result = KeyCode_F12; }
if (!TranslateToChar) if (!TranslateToChar)
{ {
if (Win32VirtualKey == 0x30) { Result = KeyCode_0; } if (Win32VirtualKey == 0x30) { Result = KeyCode_0; }
else if (Win32VirtualKey == 0x31) { Result = KeyCode_1; } else if (Win32VirtualKey == 0x31) { Result = KeyCode_1; }
else if (Win32VirtualKey == 0x32) { Result = KeyCode_2; } else if (Win32VirtualKey == 0x32) { Result = KeyCode_2; }
else if (Win32VirtualKey == 0x33) { Result = KeyCode_3; } else if (Win32VirtualKey == 0x33) { Result = KeyCode_3; }
else if (Win32VirtualKey == 0x34) { Result = KeyCode_4; } else if (Win32VirtualKey == 0x34) { Result = KeyCode_4; }
else if (Win32VirtualKey == 0x35) { Result = KeyCode_5; } else if (Win32VirtualKey == 0x35) { Result = KeyCode_5; }
else if (Win32VirtualKey == 0x36) { Result = KeyCode_6; } else if (Win32VirtualKey == 0x36) { Result = KeyCode_6; }
else if (Win32VirtualKey == 0x37) { Result = KeyCode_7; } else if (Win32VirtualKey == 0x37) { Result = KeyCode_7; }
else if (Win32VirtualKey == 0x38) { Result = KeyCode_8; } else if (Win32VirtualKey == 0x38) { Result = KeyCode_8; }
else if (Win32VirtualKey == 0x39) { Result = KeyCode_9; } else if (Win32VirtualKey == 0x39) { Result = KeyCode_9; }
else if (Win32VirtualKey == 0x41) { Result = KeyCode_A; } else if (Win32VirtualKey == 0x41) { Result = KeyCode_A; }
else if (Win32VirtualKey == 0x42) { Result = KeyCode_B; } else if (Win32VirtualKey == 0x42) { Result = KeyCode_B; }
else if (Win32VirtualKey == 0x43) { Result = KeyCode_C; } else if (Win32VirtualKey == 0x43) { Result = KeyCode_C; }
else if (Win32VirtualKey == 0x44) { Result = KeyCode_D; } else if (Win32VirtualKey == 0x44) { Result = KeyCode_D; }
else if (Win32VirtualKey == 0x45) { Result = KeyCode_E; } else if (Win32VirtualKey == 0x45) { Result = KeyCode_E; }
else if (Win32VirtualKey == 0x46) { Result = KeyCode_F; } else if (Win32VirtualKey == 0x46) { Result = KeyCode_F; }
else if (Win32VirtualKey == 0x47) { Result = KeyCode_G; } else if (Win32VirtualKey == 0x47) { Result = KeyCode_G; }
else if (Win32VirtualKey == 0x48) { Result = KeyCode_H; } else if (Win32VirtualKey == 0x48) { Result = KeyCode_H; }
else if (Win32VirtualKey == 0x49) { Result = KeyCode_I; } else if (Win32VirtualKey == 0x49) { Result = KeyCode_I; }
else if (Win32VirtualKey == 0x4A) { Result = KeyCode_J; } else if (Win32VirtualKey == 0x4A) { Result = KeyCode_J; }
else if (Win32VirtualKey == 0x4B) { Result = KeyCode_K; } else if (Win32VirtualKey == 0x4B) { Result = KeyCode_K; }
else if (Win32VirtualKey == 0x4C) { Result = KeyCode_L; } else if (Win32VirtualKey == 0x4C) { Result = KeyCode_L; }
else if (Win32VirtualKey == 0x4D) { Result = KeyCode_M; } else if (Win32VirtualKey == 0x4D) { Result = KeyCode_M; }
else if (Win32VirtualKey == 0x4E) { Result = KeyCode_N; } else if (Win32VirtualKey == 0x4E) { Result = KeyCode_N; }
else if (Win32VirtualKey == 0x4F) { Result = KeyCode_O; } else if (Win32VirtualKey == 0x4F) { Result = KeyCode_O; }
else if (Win32VirtualKey == 0x50) { Result = KeyCode_P; } else if (Win32VirtualKey == 0x50) { Result = KeyCode_P; }
else if (Win32VirtualKey == 0x51) { Result = KeyCode_Q; } else if (Win32VirtualKey == 0x51) { Result = KeyCode_Q; }
else if (Win32VirtualKey == 0x52) { Result = KeyCode_R; } else if (Win32VirtualKey == 0x52) { Result = KeyCode_R; }
else if (Win32VirtualKey == 0x53) { Result = KeyCode_S; } else if (Win32VirtualKey == 0x53) { Result = KeyCode_S; }
else if (Win32VirtualKey == 0x54) { Result = KeyCode_T; } else if (Win32VirtualKey == 0x54) { Result = KeyCode_T; }
else if (Win32VirtualKey == 0x55) { Result = KeyCode_U; } else if (Win32VirtualKey == 0x55) { Result = KeyCode_U; }
else if (Win32VirtualKey == 0x56) { Result = KeyCode_V; } else if (Win32VirtualKey == 0x56) { Result = KeyCode_V; }
else if (Win32VirtualKey == 0x57) { Result = KeyCode_W; } else if (Win32VirtualKey == 0x57) { Result = KeyCode_W; }
else if (Win32VirtualKey == 0x58) { Result = KeyCode_X; } else if (Win32VirtualKey == 0x58) { Result = KeyCode_X; }
else if (Win32VirtualKey == 0x59) { Result = KeyCode_Y; } else if (Win32VirtualKey == 0x59) { Result = KeyCode_Y; }
else if (Win32VirtualKey == 0x5A) { Result = KeyCode_Z; } else if (Win32VirtualKey == 0x5A) { Result = KeyCode_Z; }
} }
if (NumpadValid) if (NumpadValid)
{ {
if (Win32VirtualKey == VK_NUMPAD0) { Result = KeyCode_Num0; } if (Win32VirtualKey == VK_NUMPAD0) { Result = KeyCode_Num0; }
else if (Win32VirtualKey == VK_NUMPAD1) { Result = KeyCode_Num1; } else if (Win32VirtualKey == VK_NUMPAD1) { Result = KeyCode_Num1; }
else if (Win32VirtualKey == VK_NUMPAD2) { Result = KeyCode_Num2; } else if (Win32VirtualKey == VK_NUMPAD2) { Result = KeyCode_Num2; }
else if (Win32VirtualKey == VK_NUMPAD3) { Result = KeyCode_Num3; } else if (Win32VirtualKey == VK_NUMPAD3) { Result = KeyCode_Num3; }
else if (Win32VirtualKey == VK_NUMPAD4) { Result = KeyCode_Num4; } else if (Win32VirtualKey == VK_NUMPAD4) { Result = KeyCode_Num4; }
else if (Win32VirtualKey == VK_NUMPAD5) { Result = KeyCode_Num5; } else if (Win32VirtualKey == VK_NUMPAD5) { Result = KeyCode_Num5; }
else if (Win32VirtualKey == VK_NUMPAD6) { Result = KeyCode_Num6; } else if (Win32VirtualKey == VK_NUMPAD6) { Result = KeyCode_Num6; }
else if (Win32VirtualKey == VK_NUMPAD7) { Result = KeyCode_Num7; } else if (Win32VirtualKey == VK_NUMPAD7) { Result = KeyCode_Num7; }
else if (Win32VirtualKey == VK_NUMPAD8) { Result = KeyCode_Num8; } else if (Win32VirtualKey == VK_NUMPAD8) { Result = KeyCode_Num8; }
else if (Win32VirtualKey == VK_NUMPAD9) { Result = KeyCode_Num9; } else if (Win32VirtualKey == VK_NUMPAD9) { Result = KeyCode_Num9; }
} }
@ -501,14 +500,14 @@ HandleWindowsMessage (
// NOTE(Peter): Always setting this to true becuase windows is stupid and doesn't // NOTE(Peter): Always setting this to true becuase windows is stupid and doesn't
// pass the press/release bit through correctly. So now the KEYDOWN/KEYUP Messages above // pass the press/release bit through correctly. So now the KEYDOWN/KEYUP Messages above
// only translate the message to a WM_CHAR message if its a key down. Since we clear all // only translate the message to a WM_CHAR message if its a key down. Since we clear all
// keystates to false at the beginning of an input frame, this will make transitions // keystates to false at the beginning of an input frame, this will make transitions
// get registered correctly. // get registered correctly.
Input.New->KeyStates[KeyIndex] = true; Input.New->KeyStates[KeyIndex] = true;
Result.NeedsUpdate = true; Result.NeedsUpdate = true;
} }
else else
{ {
printf("Translated Char Not Recognized: %c\n", TranslatedChar); printf("Translated Char Not Recognized: %c\n", TranslatedChar);
} }
*/ */
}break; }break;
@ -570,14 +569,14 @@ Win32DisplayBufferInWindow(win32_offscreen_buffer* Win32Buffer, window Window)
} }
///////////////////////////////////////// /////////////////////////////////////////
// //
// Open GL // Open GL
// //
///////////////////////////////////////// /////////////////////////////////////////
internal void internal void
OpenGLRenderTriBuffer (u8* Vertecies, s32 VertexElements, OpenGLRenderTriBuffer (u8* Vertecies, s32 VertexElements,
u8* UVs, s32 UVElements, u8* UVs, s32 UVElements,
u8* Colors, s32 ColorsElements, u8* Colors, s32 ColorsElements,
s32 TriCount) s32 TriCount)
@ -599,7 +598,7 @@ OpenGLRenderTriBuffer (u8* Vertecies, s32 VertexElements,
} }
internal void internal void
OpenGLDraw3DTri (v4 P0, v4 P1, v4 P2, OpenGLDraw3DTri (v4 P0, v4 P1, v4 P2,
v2 UV0, v2 UV1, v2 UV2, v2 UV0, v2 UV1, v2 UV2,
v4 C0, v4 C1, v4 C2) v4 C0, v4 C1, v4 C2)
{ {
@ -621,7 +620,7 @@ OpenGLDraw3DTri (v4 P0, v4 P1, v4 P2,
} }
internal void internal void
OpenGLDraw2DTri (v2 P0, v2 P1, v2 P2, OpenGLDraw2DTri (v2 P0, v2 P1, v2 P2,
v2 UV0, v2 UV1, v2 UV2, v2 UV0, v2 UV1, v2 UV2,
v4 C0, v4 C1, v4 C2) v4 C0, v4 C1, v4 C2)
{ {
@ -668,14 +667,14 @@ SubmitTexture (u8* Memory, s32 Width, s32 Height)
{ {
s32 TextureHandle = NextTextureHandle++; s32 TextureHandle = NextTextureHandle++;
glBindTexture(GL_TEXTURE_2D, TextureHandle); glBindTexture(GL_TEXTURE_2D, TextureHandle);
glTexImage2D(GL_TEXTURE_2D, glTexImage2D(GL_TEXTURE_2D,
0, // mip map level 0, // mip map level
GL_RGBA8, GL_RGBA8,
Width, Width,
Height, Height,
0, // border 0, // border
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
Memory); Memory);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View File

@ -12,7 +12,7 @@ internal void
GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* NodeSpecificationGen, string_builder* CallNodeProcGen, gs_meta_preprocessor Meta) GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* NodeSpecificationGen, string_builder* CallNodeProcGen, gs_meta_preprocessor Meta)
{ {
// TODO(Peter): Create a FilterTypesByTag function to create a contiguous array // TODO(Peter): Create a FilterTypesByTag function to create a contiguous array
// of type_definition** // of type_definition**
WriteF(NodeSpecificationGen, "static node_specification_ NodeSpecifications[] = {\n"); WriteF(NodeSpecificationGen, "static node_specification_ NodeSpecifications[] = {\n");
@ -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;
}; };
internal void #define ErrorReallocArray(base, type, oldcount, newcount) (type*)ErrorRealloc_((u8*)(base), (u64)(sizeof(type) * oldcount), (u64)(sizeof(type) * newcount))
internal u8*
ErrorRealloc_(u8* Base, u64 OldSize, u64 NewSize)
{
Assert(NewSize > 0);
u8* Result = (u8*)malloc(NewSize);
if (Base != 0 && OldSize > 0)
{
GSMemCopy(Base, Result, OldSize);
free(Base);
}
return Result;
}
internal void
PushFError (errors* Errors, char* Format, ...) 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
@ -59,7 +59,7 @@ EatIdentifier (tokenizer* Tokenizer)
{ {
s32 Length = 0; s32 Length = 0;
while (Tokenizer->At[0] && while (Tokenizer->At[0] &&
(IsAlpha(Tokenizer->At[0]) || IsNumericExtended(Tokenizer->At[0]))) (IsAlpha(Tokenizer->At[0]) || IsNumericExtended(Tokenizer->At[0])))
{ {
++Tokenizer->At; ++Tokenizer->At;
@ -135,7 +135,7 @@ GetNextToken (tokenizer* Tokenizer)
char C = Tokenizer->At[0]; char C = Tokenizer->At[0];
++Tokenizer->At; ++Tokenizer->At;
if (C == 0) { Result.Type = Token_EndOfStream; } if (C == 0) { Result.Type = Token_EndOfStream; }
else if (C == '(') { Result.Type = Token_LeftParen; } else if (C == '(') { Result.Type = Token_LeftParen; }
else if (C == ')') { Result.Type = Token_RightParen; } else if (C == ')') { Result.Type = Token_RightParen; }
else if (C == '[') { Result.Type = Token_LeftSquareBracket; } else if (C == '[') { Result.Type = Token_LeftSquareBracket; }
@ -145,9 +145,9 @@ GetNextToken (tokenizer* Tokenizer)
else if (C == ';') { Result.Type = Token_Semicolon; } else if (C == ';') { Result.Type = Token_Semicolon; }
else if (C == ',') { Result.Type = Token_Comma; } else if (C == ',') { Result.Type = Token_Comma; }
else if (C == '.') { Result.Type = Token_Period; } else if (C == '.') { Result.Type = Token_Period; }
else if (C == '-' && Tokenizer->At[0] && Tokenizer->At[0] == '>') else if (C == '-' && Tokenizer->At[0] && Tokenizer->At[0] == '>')
{ {
Result.Type = Token_PointerReference; Result.Type = Token_PointerReference;
Result.Text.Length = 2; Result.Text.Length = 2;
++Tokenizer->At; ++Tokenizer->At;
} }
@ -157,72 +157,72 @@ GetNextToken (tokenizer* Tokenizer)
EatWhitespace(Tokenizer); EatWhitespace(Tokenizer);
if (TokenAtEquals(Tokenizer, "define")) if (TokenAtEquals(Tokenizer, "define"))
{ {
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

View File

@ -10,7 +10,7 @@ enum type_definition_type
TypeDef_Invalid, TypeDef_Invalid,
// NOTE(Peter): tokens with this type require fixup later // NOTE(Peter): tokens with this type require fixup later
TypeDef_Unknown, TypeDef_Unknown,
TypeDef_Enum, TypeDef_Enum,
TypeDef_Struct, TypeDef_Struct,
TypeDef_Union, TypeDef_Union,
@ -59,7 +59,7 @@ struct meta_tag
struct variable_decl struct variable_decl
{ {
// NOTE(Peter): Because of the way the tokenizer works, we don't lex and parse // NOTE(Peter): Because of the way the tokenizer works, we don't lex and parse
// at the same time. This means that not all types will be able to be matched // at the same time. This means that not all types will be able to be matched
// up on the first pass through. A TypeIndex of -1 means we need to fixup that // up on the first pass through. A TypeIndex of -1 means we need to fixup that
// type at a later time // type at a later time
@ -161,7 +161,7 @@ HashIdentifier(string Identifier)
u32 IdentHash = HashString(Identifier); u32 IdentHash = HashString(Identifier);
if (IdentHash == 0) if (IdentHash == 0)
{ {
// NOTE(Peter): We are excluding a has of zero so taht // NOTE(Peter): We are excluding a has of zero so taht
// the type_table_handle where BucketIndex and IndexInBucket // the type_table_handle where BucketIndex and IndexInBucket
// are both zero is an invalid handle // are both zero is an invalid handle
IdentHash += 1; IdentHash += 1;
@ -301,7 +301,7 @@ FindSlotForTypeIdentifier(u32 IdentHash, type_table* TypeTable)
Result.IndexInBucket = Index; Result.IndexInBucket = Index;
} }
// NOTE(Peter): Because we are growing the hashtable, this should never be an invalid // NOTE(Peter): Because we are growing the hashtable, this should never be an invalid
// type handle // type handle
Assert(TypeHandleIsValid(Result)); Assert(TypeHandleIsValid(Result));
return Result; return Result;
@ -391,7 +391,7 @@ PushMetaTagOnTable(meta_tag Tag, type_table* TypeTable)
} }
// Guaranteed to return a valid result // Guaranteed to return a valid result
internal type_definition* internal type_definition*
GetTypeDefinition(type_table_handle Handle, type_table TypeTable) GetTypeDefinition(type_table_handle Handle, type_table TypeTable)
{ {
Assert(TypeHandleIsValid(Handle)); Assert(TypeHandleIsValid(Handle));
@ -404,7 +404,7 @@ GetTypeDefinition(type_table_handle Handle, type_table TypeTable)
} }
// May return zero // May return zero
internal type_definition* internal type_definition*
GetTypeDefinitionUnsafe(type_table_handle Handle, type_table TypeTable) GetTypeDefinitionUnsafe(type_table_handle Handle, type_table TypeTable)
{ {
type_definition* Result = 0; type_definition* Result = 0;
@ -426,7 +426,7 @@ GetMetaTag(type_table_handle Handle, type_table TypeTable)
return Result; return Result;
} }
internal type_definition* internal type_definition*
GetTypeDefinition(string Identifier, type_table TypeTable) GetTypeDefinition(string Identifier, type_table TypeTable)
{ {
type_definition* Result = 0; type_definition* Result = 0;
@ -588,21 +588,21 @@ internal void
FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_table TypeTable, errors* Errors) FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_table TypeTable, errors* Errors)
{ {
// NOTE(Peter): There are a lot of cases where struct members which are pointers // NOTE(Peter): There are a lot of cases where struct members which are pointers
// to other structs cause interesting behavior here. // to other structs cause interesting behavior here.
// For example: // For example:
// struct foo { foo* Next; } // struct foo { foo* Next; }
// could cause infinite loops if we try and fixup all structs with a size of 0 // could cause infinite loops if we try and fixup all structs with a size of 0
// which would happen in this case, because we wouldn't have parsed foo's size // which would happen in this case, because we wouldn't have parsed foo's size
// yet, but would begin fixing up foo because of the type of Next // yet, but would begin fixing up foo because of the type of Next
// Another example: // Another example:
// typedef struct bar bar; // typedef struct bar bar;
// struct foo { bar* Bar; } // struct foo { bar* Bar; }
// struct bar { foo* Foo; } // struct bar { foo* Foo; }
// causes the exact same problem, but we cant detect it by just excluding // causes the exact same problem, but we cant detect it by just excluding
// fixing up StructIndex recursively. // fixing up StructIndex recursively.
// //
// TL;DR // TL;DR
// The solution I've chosen to go with is just exclude all pointer members from // The solution I've chosen to go with is just exclude all pointer members from
// causing recursive fixups. Those types should be fixed up at some point in the // causing recursive fixups. Those types should be fixed up at some point in the
// process, and we already know how big a pointer is in memory, no matter the type // process, and we already know how big a pointer is in memory, no matter the type
if (!Member->Pointer) if (!Member->Pointer)
@ -617,7 +617,7 @@ FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_t
{ {
FixUpUnionSize(Member->TypeHandle, TypeTable, Errors); FixUpUnionSize(Member->TypeHandle, TypeTable, Errors);
} }
else else
{ {
if (MemberTypeDef->Type == TypeDef_Unknown) if (MemberTypeDef->Type == TypeDef_Unknown)
{ {
@ -672,7 +672,7 @@ FixUpStructSize (type_table_handle TypeHandle, type_table TypeTable, errors* Err
{ {
// NOTE(Peter): Because its recursive (it makes sure all type sizes become known // NOTE(Peter): Because its recursive (it makes sure all type sizes become known
// if it needs them) we should never get to the end of this function and not have // if it needs them) we should never get to the end of this function and not have
// the ability to tell how big something is. // the ability to tell how big something is.
// TODO(Peter): We don't parse all types yet however, so for now, this is just an alert, // TODO(Peter): We don't parse all types yet however, so for now, this is just an alert,
// not an assert; // not an assert;
#if 0 #if 0