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
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

View File

@ -31,7 +31,7 @@ enum blend_mode
struct anim_layer
{
string Name;
gs_string Name;
blend_mode BlendMode;
};
@ -39,7 +39,7 @@ struct anim_layer
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
struct animation_system
{
memory_arena* Storage;
gs_memory_arena* Storage;
gs_list<animation_block> Blocks;
anim_layer* Layers;
@ -75,7 +75,7 @@ FrameIsInRange(s32 Frame, frame_range Range)
internal u32
GetFrameCount(frame_range Range)
{
u32 Result = (u32)GSMax(0, Range.Max - Range.Min);
u32 Result = (u32)Max(0, Range.Max - Range.Min);
return Result;
}
@ -133,7 +133,7 @@ RemoveAnimationBlock(gs_list_handle AnimationBlockHandle, animation_system* Anim
// Layers
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
// resizable.
@ -144,7 +144,7 @@ AddLayer (string Name, animation_system* AnimationSystem, blend_mode BlendMode =
anim_layer* NewLayer = AnimationSystem->Layers + Result;
*NewLayer = {0};
NewLayer->Name = MakeString(PushArray(AnimationSystem->Storage, char, Name.Length), Name.Length);
CopyStringTo(Name, &NewLayer->Name);
PrintF(&NewLayer->Name, "%S", Name);
NewLayer->BlendMode = BlendMode;
return Result;
}

View File

@ -28,7 +28,7 @@ enum assembly_field
AssemblyField_Count,
};
global_variable char* AssemblyFieldIdentifiers[] = {
global char* AssemblyFieldIdentifiers[] = {
"assembly_name", // AssemblyField_AssemblyName
"assembly_scale", // AssemblyField_AssemblyScale
"led_strip_count", // AssemblyField_LedStripCount
@ -52,20 +52,32 @@ global_variable char* AssemblyFieldIdentifiers[] = {
"value", // AssemblyField_Value
};
struct assembly_error_list
{
gs_string String;
assembly_error_list* Next;
};
struct assembly_tokenizer
{
string Text;
gs_string Text;
char* At;
gs_const_string FileName;
u32 LineNumber;
bool ParsingIsValid;
gs_memory_arena* ErrorArena;
assembly_error_list* ErrorsRoot;
assembly_error_list* ErrorsTail;
};
internal bool
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;
}
@ -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
AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
{
@ -118,6 +140,22 @@ AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
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
ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
{
@ -130,12 +168,12 @@ ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Field identifier is missing a colon");
}
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Field Identifier Invalid");
}
return Result;
}
@ -150,15 +188,15 @@ ReadFieldEnd(assembly_tokenizer* T)
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Missing a semicolon");
}
return Result;
}
internal string
internal gs_string
ReadString(assembly_tokenizer* T)
{
string Result = {};
gs_string Result = {};
if (AdvanceIfTokenEquals(T, "\""))
{
char* StringStart = T->At;
@ -166,32 +204,36 @@ ReadString(assembly_tokenizer* T)
{
T->At++;
}
Result.Memory = StringStart;
Result.Max = T->At - StringStart;
Result.Length = Result.Max;
Result.Str = StringStart;
Result.Size = T->At - StringStart;
Result.Length = Result.Size;
if (AdvanceIfTokenEquals(T, "\""))
{
// Success
}
else
{
// TODO(Peter): Error
TokenizerPushError(T, "String not closed with a \"");
}
}
else
{
TokenizerPushError(T, "Expecting a string, but none was found");
}
return Result;
}
internal string
internal gs_string
GetNumberString(assembly_tokenizer* T)
{
string Result = {};
Result.Memory = T->At;
gs_string Result = {};
Result.Str = T->At;
while(AtValidPosition(T) && IsNumericExtended(T->At[0]))
{
AdvanceChar(T);
}
Result.Length = T->At - Result.Memory;
Result.Max = Result.Length;
Result.Length = T->At - Result.Str;
Result.Size = Result.Length;
return Result;
}
@ -199,9 +241,8 @@ internal r32
ReadFloat(assembly_tokenizer* T)
{
r32 Result = 0;
string NumberString = GetNumberString(T);
parse_result ParsedFloat = ParseFloat(StringExpand(NumberString));
Result = ParsedFloat.FloatValue;
gs_string NumberString = GetNumberString(T);
Result = (r32)ParseFloat(NumberString.ConstString);
return Result;
}
@ -209,28 +250,23 @@ internal s32
ReadInt(assembly_tokenizer* T)
{
s32 Result = 0;
string NumberString = GetNumberString(T);
parse_result ParsedInt = ParseSignedInt(StringExpand(NumberString));
Result = ParsedInt.SignedIntValue;
gs_string NumberString = GetNumberString(T);
Result = (r32)ParseInt(NumberString.ConstString);
return Result;
}
internal string
ReadStringField(assembly_field Field, assembly_tokenizer* T, memory_arena* Arena)
internal gs_string
ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Arena)
{
string Result = {};
gs_string Result = {};
if (ReadFieldIdentifier(Field, T))
{
string ExistingString = ReadString(T);
gs_string ExistingString = ReadString(T);
if (ReadFieldEnd(T))
{
// Success
Result = PushString(Arena, ExistingString.Length);
CopyStringTo(ExistingString, &Result);
}
else
{
T->ParsingIsValid = false;
PrintF(&Result, "%S", ExistingString);
}
}
return Result;
@ -290,22 +326,22 @@ ReadV3Field(assembly_field Field, assembly_tokenizer* T)
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Vector 3 doesn't end with a ')'");
}
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Vector 3: unable to read a field");
}
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Vector 3: unable to read a field");
}
}
else
{
T->ParsingIsValid = false;
TokenizerPushError(T, "Vector 3: unable to read a field");
}
}
return Result;
@ -333,14 +369,18 @@ ReadStructClosing(assembly_tokenizer* T)
}
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;
r32 Value = ParseFloat(ConstString("-2.355"));
assembly_tokenizer Tokenizer = {};
Tokenizer.Text = FileText;
Tokenizer.At = Tokenizer.Text.Memory;
Tokenizer.At = Tokenizer.Text.Str;
Tokenizer.ParsingIsValid = true;
Tokenizer.ErrorArena = Transient;
Tokenizer.FileName = FileName;
Assembly->Name = ReadStringField(AssemblyField_AssemblyName, &Tokenizer, &Assembly->Arena);
Assembly->Scale = ReadFloatField(AssemblyField_AssemblyScale, &Tokenizer);
@ -358,7 +398,7 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
StripAt->StartChannel = ReadIntField(AssemblyField_StartChannel, &Tokenizer);
// 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
if (ReadStructOpening(AssemblyField_InterpolatePoints, &Tokenizer))
{
@ -367,6 +407,10 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
if (!ReadStructClosing(&Tokenizer))
{
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;
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
string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient);
string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient);
TagAt->NameHash = HashString(TagName);
TagAt->ValueHash = HashString(TagValue);
gs_string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient);
gs_string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient);
TagAt->NameHash = HashDJB2ToU32(StringExpand(TagName));
TagAt->ValueHash = HashDJB2ToU32(StringExpand(TagValue));
if (!ReadStructClosing(&Tokenizer))
{
Tokenizer.ParsingIsValid = false;
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
}
}
else
{
Tokenizer.ParsingIsValid = false;
TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
}
}
if (!ReadStructClosing(&Tokenizer))
{
Tokenizer.ParsingIsValid = false;
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
}
}
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;
}
r32 ActualMin = GSMin(Data->Min, Data->Max);
r32 ActualMax = GSMax(Data->Min, Data->Max);
r32 SinResult = GSSin((Data->Accumulator / Data->Period) * PI * 2);
Data->Result = GSRemap(SinResult, -1.f, 1.f, ActualMin, ActualMax);
r32 ActualMin = Min(Data->Min, Data->Max);
r32 ActualMax = Max(Data->Min, Data->Max);
r32 SinResult = SinR32((Data->Accumulator / Data->Period) * PiR32 * 2);
Data->Result = RemapR32(SinResult, -1.f, 1.f, ActualMin, ActualMax);
}
else
{

View File

@ -15,7 +15,7 @@ struct visual_port
{
gs_list_handle SparseNodeHandle;
u32 PortIndex;
rect PortBounds;
rect2 PortBounds;
};
struct visual_connection
@ -57,7 +57,7 @@ struct node_graph_state
{
v2 ViewOffset;
memory_arena LayoutMemory;
gs_memory_arena LayoutMemory;
node_layout Layout;
b32 LayoutIsDirty;
@ -128,7 +128,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndConnectNodesOperation)
for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; 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))
{
visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort;
@ -196,7 +196,7 @@ NodeGraph_Cleanup(panel* Panel, app_state* State)
}
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;
v4 LineColor = v4{LineValue, LineValue, LineValue, 1.f};
@ -232,9 +232,9 @@ DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer*
}
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;
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
// 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);
LinePosition.y -= LineHeight;
}
@ -252,7 +252,7 @@ DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position,
}
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];
@ -264,13 +264,13 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
if (MemberIsInput(Member)) { InputMembers++; }
if (MemberIsOutput(Member)) { OutputMembers++; }
}
u32 LineCount = 1 + GSMax(InputMembers, OutputMembers);
u32 LineCount = 1 + Max(InputMembers, OutputMembers);
v2 NodeDim = v2{
NodeWidth,
(LineHeight * LineCount) + Interface.Margin.y,
};
rect NodeBounds = rect{
rect2 NodeBounds = rect2{
v2{ Position.x, Position.y - NodeDim.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});
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);
DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4);
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++)
{
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
// render the actual connection points?
@ -329,7 +329,7 @@ GetVisualPortIndexForNode(gs_list_handle SparseNodeHandle, u32 PortIndex, node_l
}
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 = {};
@ -373,7 +373,7 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
{
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p];
rect PortBounds = {0};
rect2 PortBounds = {0};
v2 PortDim = v2{8, 8};
PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2};
if (MemberIsInput(Member))
@ -420,16 +420,16 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
GSMetaTag(panel_render);
GSMetaTag(panel_type_node_graph);
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;
b32 MouseHandled = false;
rect NodeSelectionWindowBounds = rect{
rect2 NodeSelectionWindowBounds = rect2{
PanelBounds.Min,
v2{PanelBounds.Min.x + 300, PanelBounds.Max.y},
};
rect GraphBounds = rect{
rect2 GraphBounds = rect2{
v2{NodeSelectionWindowBounds.Max.x, PanelBounds.Min.y},
PanelBounds.Max,
};
@ -513,18 +513,18 @@ NodeGraph_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
List.TextColor = WhiteV4;
List.ListBounds = NodeSelectionWindowBounds;
List.ListElementDimensions = v2{
gs_Width(NodeSelectionWindowBounds),
Rect2Width(NodeSelectionWindowBounds),
ui_GetTextLineHeight(State->Interface)
};
List.ElementLabelIndent = v2{10, 4};
string TitleString = MakeStringLiteral("Available Nodes");
DrawListElement(TitleString, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
gs_string Titlegs_string = MakeStringLiteral("Available Nodes");
DrawListElement(Titlegs_string, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
for (u32 i = 0; i < NodeType_Count; i++)
{
node_specification_ Spec = NodeSpecifications[i];
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)
&& gs_PointIsInRect(Context.Mouse.DownPos, ElementBounds))

View File

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

View File

@ -8,11 +8,11 @@
struct search_lister
{
// 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
// location, the element stride and the offset to the char*)
s32 SourceListCount;
string* SourceList;
gs_string* SourceList;
// NOTE(Peter): stores the source indecies of each filtered item
// For example:
@ -23,7 +23,7 @@ struct search_lister
s32* FilteredIndexLUT;
s32 HotItem;
string Filter;
gs_string Filter;
};

View File

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

View File

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

View File

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

View File

@ -8,27 +8,6 @@
#include "foldhaus_platform.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
{
@ -72,11 +51,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
app_state* State = (app_state*)Context.MemoryBase;
*State = {};
State->Permanent = {};
State->Permanent.PlatformMemory = Context.PlatformMemory;
State->Transient = {};
State->Transient.FindAddressRule = FindAddress_InLastBufferOnly;
State->Transient.PlatformMemory = Context.PlatformMemory;
State->Permanent = CreateMemoryArena(Context.ThreadContext.Allocator);
State->Transient = CreateMemoryArena(Context.ThreadContext.Allocator);
State->Assemblies.CountMax = 8;
State->Assemblies.Values = PushArray(&State->Permanent, assembly, State->Assemblies.CountMax);
@ -90,13 +66,11 @@ INITIALIZE_APPLICATION(InitializeApplication)
CommandQueueSize);
State->CommandQueue = InitializeCommandQueue(CommandQueueMemory, CommandQueueSize);
State->ActiveTextEntry.Buffer = MakeString(PushArray(&State->Permanent, char, 256), 0, 256);
// TODO(Peter): put in InitializeInterface?
r32 FontSize = 14;
{
platform_memory_result FontFile = ReadEntireFile(Context, MakeStringLiteral("data/Anonymous Pro.ttf"));
if (!FontFile.Error)
gs_file FontFile = ReadEntireFile(Context.ThreadContext.FileHandler, ConstString("data/Anonymous Pro.ttf"));
if (FileNoError(FontFile))
{
bitmap_font* Font = PushStruct(&State->Permanent, bitmap_font);
@ -105,7 +79,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
Font->BitmapBytesPerPixel = 4;
Font->BitmapMemory = PushArray(&State->Permanent, u8, Font->BitmapWidth * Font->BitmapHeight * 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);
Font->PixelHeight = FontInfo.PixelHeight;
@ -169,17 +143,18 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->SACN = InitializeSACN(Context);
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
State->Camera.FieldOfView = DegreesToRadians(45.0f);
State->Camera.AspectRatio = gs_AspectRatio(State->WindowBounds);
State->Camera.Near = 1.0f;
State->Camera.Far = 100.0f;
State->Camera.Position = v3{0, 0, -250};
State->Camera.LookAt = v3{0, 0, 0};
State->Camera.FieldOfView = 45.0f;
State->Camera.AspectRatio = RectAspectRatio(State->WindowBounds);
State->Camera.Near = .1f;
State->Camera.Far = 800.0f;
State->Camera.Position = v3{0, 0, 400};
State->Camera.LookAt = v3{0, 0, 0
};
State->LedSystem = LedSystemInitialize(Context.PlatformMemory, 128);
State->LedSystem = LedSystemInitialize(Context.ThreadContext.Allocator, 128);
#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);
#endif
@ -189,11 +164,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
ReloadStaticData(Context, GlobalDebugServices);
// Setup Operation Modes
State->Modes.ActiveModesCount = 0;
State->Modes.Arena = {};
State->Modes.Arena.PlatformMemory = Context.PlatformMemory;
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext);
{ // Animation PLAYGROUND
State->AnimationSystem = {};
@ -203,9 +174,9 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
State->AnimationSystem.LayersMax = 32;
State->AnimationSystem.Layers = PushArray(&State->Permanent, anim_layer, State->AnimationSystem.LayersMax);
AddLayer(MakeStringLiteral("Base Layer"), &State->AnimationSystem, BlendMode_Overwrite);
AddLayer(MakeStringLiteral("Color Layer"), &State->AnimationSystem, BlendMode_Multiply);
AddLayer(MakeStringLiteral("Sparkles"), &State->AnimationSystem, BlendMode_Add);
AddLayer(MakeString("Base Layer"), &State->AnimationSystem, BlendMode_Overwrite);
AddLayer(MakeString("Color Layer"), &State->AnimationSystem, BlendMode_Multiply);
AddLayer(MakeString("Sparkles"), &State->AnimationSystem, BlendMode_Add);
} // End Animation Playground
@ -215,7 +186,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
}
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;
@ -274,7 +245,7 @@ HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_
}
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;
@ -322,6 +293,10 @@ CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize,
return Result;
}
#define HANDMADE_MATH_IMPLEMENTATION
#include "handmade_math.h"
UPDATE_AND_RENDER(UpdateAndRender)
{
DEBUG_TRACK_FUNCTION;
@ -334,6 +309,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
ClearArena(&State->Transient);
Context->Mouse.CursorType = CursorType_Arrow;
PushRenderClearScreen(RenderBuffer);
State->Camera.AspectRatio = RectAspectRatio(Context->WindowBounds);
HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse);
if (State->AnimationSystem.TimelineShouldAdvance) {
@ -355,7 +333,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
u32 CurrentBlocksMax = State->AnimationSystem.LayersCount;
b8* CurrentBlocksFilled = PushArray(&State->Transient, b8, CurrentBlocksMax);
GSZeroArray(CurrentBlocksFilled, b8, CurrentBlocksMax);
ZeroArray(CurrentBlocksFilled, b8, CurrentBlocksMax);
animation_block* CurrentBlocks = PushArray(&State->Transient, animation_block, CurrentBlocksMax);
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 B = (u32)AssemblyLedBuffer->Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B;
AssemblyLedBuffer->Colors[LED].R = (u8)GSMin(R, (u32)255);
AssemblyLedBuffer->Colors[LED].G = (u8)GSMin(G, (u32)255);
AssemblyLedBuffer->Colors[LED].B = (u8)GSMin(B, (u32)255);
AssemblyLedBuffer->Colors[LED].R = (u8)Min(R, (u32)255);
AssemblyLedBuffer->Colors[LED].G = (u8)Min(G, (u32)255);
AssemblyLedBuffer->Colors[LED].B = (u8)Min(B, (u32)255);
}
}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);
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);
// Checking for overflows

View File

@ -20,13 +20,8 @@
#include "foldhaus_assembly.h"
#include "assembly_parser.cpp"
#include "foldhaus_node.h"
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
// 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.
@ -37,10 +32,6 @@ typedef struct app_state app_state;
#include "animation/foldhaus_animation.h"
#include "foldhaus_text_entry.h"
#include "foldhaus_search_lister.h"
enum network_protocol
{
NetworkProtocol_SACN,
@ -51,10 +42,11 @@ enum network_protocol
struct app_state
{
rect WindowBounds;
r32 CameraTheta; // TODO(Peter): @TEMPORARY
rect2 WindowBounds;
memory_arena Permanent;
memory_arena Transient;
gs_memory_arena Permanent;
gs_memory_arena Transient;
s32 NetworkProtocolHeaderSize;
network_protocol NetworkProtocol;
@ -69,7 +61,6 @@ struct app_state
operation_mode_system Modes;
input_command_queue CommandQueue;
text_entry ActiveTextEntry;
ui_interface Interface;
@ -80,7 +71,7 @@ struct app_state
panel_system PanelSystem;
panel* HotPanel;
pattern_node_workspace NodeWorkspace;
//pattern_node_workspace NodeWorkspace;
event_log* GlobalLog;
};
@ -94,8 +85,8 @@ TestPatternOne(led_buffer* Assembly, r32 Time)
for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
{
v4 LedPosition = Assembly->Positions[LedIndex];
float PercentX = GSRemap(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f);
float PercentY = GSRemap(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f);
float PercentX = RemapClampedR32(LedPosition.x, -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].G = (u8)(PercentY * 255);
}
@ -104,16 +95,16 @@ TestPatternOne(led_buffer* Assembly, r32 Time)
internal void
TestPatternTwo(led_buffer* Assembly, r32 Time)
{
r32 PeriodicTime = (Time / PI) * 2;
r32 PeriodicTime = (Time / PiR32) * 2;
r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f;
r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
r32 ZeroOneSin = (SinR32(PeriodicTime) * .5f) + .5f;
r32 ZeroOneCos = (CosR32(PeriodicTime) * .5f) + .5f;
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
v4 Center = v4{0, 0, 0, 1};
r32 ThetaZ = Time / 2;
v4 Normal = v4{GSCos(ThetaZ), 0, GSSin(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
v4 Right = Cross(Normal, v4{0, 1, 0, 0});
v4 Normal = v4{CosR32(ThetaZ), 0, SinR32(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
v4 FrontCenter = Center + (Normal * 25);
v4 BackCenter = Center - (Normal * 25);
@ -128,13 +119,13 @@ TestPatternTwo(led_buffer* Assembly, r32 Time)
v4 ToFront = Position + FrontCenter;
v4 ToBack = Position + BackCenter;
r32 ToFrontDotNormal = Dot(ToFront, Normal);
r32 ToBackDotNormal = Dot(ToBack, Normal);
r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
r32 ToBackDotNormal = V4Dot(ToBack, Normal);
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000);
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000);
ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
r32 SqDistToCenter = MagSqr(Position);
r32 SqDistToCenter = V4MagSquared(Position);
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
{
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
@ -157,10 +148,10 @@ internal void
TestPatternThree(led_buffer* Assembly, r32 Time)
{
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};
r32 TealRadius = GSAbs(GSSin(Time + 1.5)) * 200;
r32 TealRadius = Abs(SinR32(Time + 1.5)) * 200;
r32 FadeDist = 35;
@ -172,12 +163,12 @@ TestPatternThree(led_buffer* Assembly, r32 Time)
u8 Green = 0;
u8 Blue = 0;
r32 GreenDist = GSAbs(Mag(LedPosition - GreenCenter) - GreenRadius);
r32 GreenBrightness = GSClamp(0.f, FadeDist - GSAbs(GreenDist), FadeDist);
r32 GreenDist = Abs(V4Mag(LedPosition - GreenCenter) - GreenRadius);
r32 GreenBrightness = Clamp(0.f, FadeDist - Abs(GreenDist), FadeDist);
Green = (u8)(GreenBrightness * 255);
r32 TealDist = GSAbs(Mag(LedPosition - TealCenter) - TealRadius);
r32 TealBrightness = GSClamp(0.f, FadeDist - GSAbs(TealDist), FadeDist);
r32 TealDist = Abs(V4Mag(LedPosition - TealCenter) - TealRadius);
r32 TealBrightness = Clamp(0.f, FadeDist - Abs(TealDist), FadeDist);
Red = (u8)(TealBrightness * 255);
Blue = (u8)(TealBrightness * 255);
@ -191,17 +182,6 @@ TestPatternThree(led_buffer* Assembly, r32 Time)
#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)
{
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)
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);
// 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_animation_timeline.h"
#include "panels/foldhaus_panel_hierarchy.h"
#include "panels/foldhaus_panel_node_graph.h"
#include "panels/foldhaus_panel_file_view.h"
#include "generated/foldhaus_panels_generated.h"

View File

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

View File

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

View File

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

View File

@ -30,7 +30,7 @@ struct collated_scope_record
struct scope_name
{
u32 Hash;
string Name;
gs_string Name;
char Buffer[SCOPE_NAME_BUFFER_LENGTH];
};
@ -82,7 +82,7 @@ typedef u8* debug_realloc(u8* Memory, s32 OldSize, s32 NewSize);
struct debug_histogram_entry
{
char ScopeName_[SCOPE_NAME_LENGTH];
string ScopeName;
gs_string ScopeName;
u32 PerFrame_Cycles[HISTOGRAM_DEPTH];
u32 PerFrame_CallCount[HISTOGRAM_DEPTH];
@ -359,9 +359,9 @@ BeginTrackingScopeAndGetNameHash (debug_services* Services, char* ScopeName)
if (Entry->Hash == 0) // If its new
{
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
CopyCharArrayToString(ScopeName, &Entry->Name);
PrintF(&Entry->Name, "%s", ScopeName);
}
return NameHash;

View File

@ -41,7 +41,7 @@ OPERATION_STATE_DEF(drag_panel_border_operation_state)
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
// it stores the value calculated when the operation mode is kicked off.
rect InitialPanelBounds;
rect2 InitialPanelBounds;
panel_split_direction PanelEdgeDirection;
panel_edit_mode PanelEditMode;
};
@ -49,7 +49,7 @@ OPERATION_STATE_DEF(drag_panel_border_operation_state)
OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
{
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)
{
@ -72,10 +72,10 @@ OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
}
else if (OpState->PanelEditMode == PanelEdit_Destroy)
{
rect PanelToDeleteBounds = {};
rect2 PanelToDeleteBounds = {};
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)
{
PanelToDeleteBounds = GetTopPanelBounds(OpState->Panel, PanelBounds);
@ -87,7 +87,7 @@ OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
}
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)
{
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);
panel* Panel = OpState->Panel;
rect PanelBounds = OpState->InitialPanelBounds;
rect2 PanelBounds = OpState->InitialPanelBounds;
if (OpState->PanelEditMode == PanelEdit_Modify)
{
@ -123,7 +123,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
}
else
{
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / gs_Height(PanelBounds);
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Rect2Height(PanelBounds);
}
}
else if (Panel->SplitDirection == PanelSplit_Vertical)
@ -139,7 +139,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
}
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)
{
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)
{
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, &State->PanelSystem);
@ -159,7 +159,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
}
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)
{
ConsolidatePanelsKeepOne(Panel, Panel->Left, &State->PanelSystem);
@ -180,7 +180,7 @@ input_command DragPanelBorderCommands[] = {
};
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);
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,
// it stores the value calculated when the operation mode is kicked off.
rect InitialPanelBounds;
rect2 InitialPanelBounds;
};
OPERATION_RENDER_PROC(UpdateAndRenderSplitPanel)
{
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};
r32 MouseDeltaX = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
r32 MouseDeltaY = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
r32 MouseDeltaX = Abs(Mouse.Pos.x - Mouse.DownPos.x);
r32 MouseDeltaY = Abs(Mouse.Pos.y - Mouse.DownPos.y);
v2 EdgePreviewMin = {};
v2 EdgePreviewMax = {};
@ -234,19 +234,19 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation)
{
split_panel_operation_state* OpState = GetCurrentOperationState(State->Modes, split_panel_operation_state);
panel* Panel = OpState->Panel;
rect PanelBounds = OpState->InitialPanelBounds;
rect2 PanelBounds = OpState->InitialPanelBounds;
r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
r32 XDistance = Abs(Mouse.Pos.x - Mouse.DownPos.x);
r32 YDistance = Abs(Mouse.Pos.y - Mouse.DownPos.y);
if (XDistance > YDistance)
{
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / gs_Width(PanelBounds);
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds);
SplitPanelVertically(Panel, XPercent, &State->PanelSystem);
}
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);
}
@ -264,7 +264,7 @@ input_command SplitPanelCommands[] = {
};
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);
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
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;
rect2 PanelSplitButtonBounds = rect2{ PanelBounds.Min, PanelBounds.Min + v2{25, 25} };
if (Panel->SplitDirection == PanelSplit_NoSplit
&& PointIsInRange(Mouse.DownPos, PanelBounds.Min, PanelBounds.Min + v2{25, 25}))
&& PointIsInRect(PanelSplitButtonBounds, Mouse.DownPos))
{
BeginSplitPanelOperation(Panel, PanelBounds, Mouse, State);
HandledMouseInput = true;
}
else if (Panel->SplitDirection == PanelSplit_Horizontal)
{
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent);
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY);
r32 SplitY = LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.y - SplitY);
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
{
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Horizontal, Mouse, State);
@ -299,13 +301,13 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
}
else
{
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
if (gs_PointIsInRect(Mouse.DownPos, BottomPanelBounds))
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
if (PointIsInRect(BottomPanelBounds, Mouse.DownPos))
{
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);
}
@ -313,8 +315,8 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
}
else if (Panel->SplitDirection == PanelSplit_Vertical)
{
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent);
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX);
r32 SplitX = LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.x - SplitX);
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
{
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Vertical, Mouse, State);
@ -322,13 +324,13 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
}
else
{
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
if (gs_PointIsInRect(Mouse.DownPos, LeftPanelBounds))
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
if (PointIsInRect(LeftPanelBounds, Mouse.DownPos))
{
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);
}
@ -339,7 +341,7 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
}
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;
@ -359,10 +361,10 @@ HandleMousePanelInteraction(panel_system* PanelSystem, rect WindowBounds, mouse_
internal void
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 MouseRightEdgeDistance = GSAbs(Mouse->Pos.x - PanelMax.x);
r32 MouseTopEdgeDistance = GSAbs(Mouse->Pos.y - PanelMax.y);
r32 MouseBottomEdgeDistance = GSAbs(Mouse->Pos.y - PanelMin.y);
r32 MouseLeftEdgeDistance = Abs(Mouse->Pos.x - PanelMin.x);
r32 MouseRightEdgeDistance = Abs(Mouse->Pos.x - PanelMax.x);
r32 MouseTopEdgeDistance = Abs(Mouse->Pos.y - PanelMax.y);
r32 MouseBottomEdgeDistance = Abs(Mouse->Pos.y - PanelMin.y);
PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color);
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
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, 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)
{
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)
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
&& !PointIsInRect(MenuBounds, Mouse.DownPos))
{
Panel->PanelSelectionMenuOpen = false;
}
for (s32 i = 0; i < GlobalPanelDefsCount; 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))
{
SetPanelDefinition(Panel, i, State);
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;
}
@ -440,15 +447,15 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBo
}
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);
rect FooterBounds = rect{
rect2 FooterBounds = rect2{
PanelBounds.Min,
v2{PanelBounds.Max.x, PanelBounds.Min.y + 25},
};
rect PanelViewBounds = rect{
rect2 PanelViewBounds = rect2{
v2{PanelBounds.Min.x, FooterBounds.Max.y},
PanelBounds.Max,
};
@ -456,7 +463,7 @@ RenderPanel(panel* Panel, rect PanelBounds, rect WindowBounds, render_command_bu
panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex];
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);
}
@ -467,12 +474,12 @@ DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mou
{
panel_with_layout PanelWithLayout = PanelLayout.Panels[i];
panel* Panel = PanelWithLayout.Panel;
rect PanelBounds = PanelWithLayout.Bounds;
rect2 PanelBounds = PanelWithLayout.Bounds;
RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse);
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);
}
}

View File

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

View File

@ -55,7 +55,7 @@ SortNodeNeighbors(u32 ContiguousNodeIndex, gs_list_handle NodeHandle, adjacency_
}
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 ContiguousIndex = 0;
@ -71,7 +71,7 @@ CreateSparseToContiguousMap (pattern_node_workspace Workspace, memory_arena* Scr
}
internal void
UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
UpdateSortedNodes(pattern_node_workspace* Workspace, gs_memory_arena* Scratch)
{
ClearNodeWorkspaceStorage(Workspace);
@ -119,22 +119,22 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
RadixSortInPlace(NeighborsListLengths, Workspace->Nodes.Used);
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++)
{
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];
while (Neighbors)
{
PrintF(&OutputString, "%d, ", Neighbors->NodeHandle.Index);
PrintF(&Outputgs_string, "%d, ", Neighbors->NodeHandle.Index);
Neighbors = Neighbors->Next;
}
PrintF(&OutputString, " }\n");
PrintF(&Outputgs_string, " }\n");
}
NullTerminate(&OutputString);
NullTerminate(&Outputgs_string);
// This is a contiguous array.
b8* NodesVisited = PushArray(Scratch, b8, NodeCount);
@ -163,7 +163,7 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
}
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();
NewNode->SpecificationIndex = NodeSpecificationIndex;
@ -172,7 +172,7 @@ PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspac
}
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 = {};
Connection.UpstreamNodeHandle = UpstreamNodeHandle;

View File

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

View File

@ -16,6 +16,7 @@ struct operation_mode
{
input_command_registry Commands;
operation_render_proc* Render;
gs_memory_cursor Memory;
u8* OpStateMemory;
};
@ -24,28 +25,66 @@ struct operation_mode_system
{
s32 ActiveModesCount;
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
// 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*
ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc)
{
operation_mode* Result = 0;
Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
operation_mode* Result = 0;
s32 ModeIndex = System->ActiveModesCount++;
System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena);
operation_mode NewMode = {};
System->ActiveModes[ModeIndex] = NewMode;
//System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena);
Result = &System->ActiveModes[ModeIndex];
Result->Memory = CreateMemoryCursor(OperationModeTakeMemoryPage(System));
Result->Render = RenderProc;
return Result;
}
@ -57,13 +96,18 @@ ActivateOperationModeWithCommands_(operation_mode_system* System, input_command*
{
operation_mode* NewMode = ActivateOperationMode(System, RenderProc);
#if 0
InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena);
for (s32 i = 0; i < CommandsCount; i++)
{
input_command Command = Commands[i];
RegisterKeyPressCommand(&NewMode->Commands, Command.Key, Command.Flags, Command.Mdfr, Command.Proc);
}
#else
NewMode->Commands.Commands = Commands;
NewMode->Commands.Size = CommandsCount;
NewMode->Commands.Used = CommandsCount;
#endif
return NewMode;
}
@ -72,7 +116,8 @@ DeactivateCurrentOperationMode (operation_mode_system* System)
{
Assert(System->ActiveModesCount > 0);
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) \
@ -85,8 +130,12 @@ DeactivateCurrentOperationMode (operation_mode_system* System)
internal u8*
CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize)
{
Mode->OpStateMemory = PushSize(&System->Arena, StateSize);
return Mode->OpStateMemory;
// NOTE(Peter): This isn't a problem if this fires, it just means our page size is too small,
// and its time to make the pages dynamically sized
Assert(Mode->Memory.Data.Size >= StateSize);
u8* Result = PushSizeOnCursor(&Mode->Memory, StateSize).Memory;
Mode->OpStateMemory = Result;
return Result;
}

View File

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

View File

@ -7,22 +7,30 @@
#include <windows.h>
#define GS_LANGUAGE_NO_PROFILER_DEFINES
#include "..\gs_libs\gs_language.h"
#include <math.h> // TODO Remove
#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_bucket.h"
#define GS_MEMORY_TRACK_ALLOCATIONS
#include "..\gs_libs\gs_memory_arena.h"
//#define GS_MEMORY_TRACK_ALLOCATIONS
//#include "..\gs_libs\gs_memory_arena.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 "foldhaus_renderer.h"
@ -75,15 +83,6 @@ struct platform_memory_result
platform_memory_error Error;
};
struct texture_buffer
{
u8* Memory;
s32 Width;
s32 Height;
s32 Pitch;
s32 BytesPerPixel;
};
struct system_path
{
char* Path;
@ -91,20 +90,13 @@ struct system_path
s32 IndexOfLastSlash;
};
#define PLATFORM_READ_ENTIRE_FILE(name) platform_memory_result name(string Path)
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
struct texture_buffer
{
platform_read_entire_file* ReadEntireFile;
platform_write_entire_file* WriteEntireFile;
platform_get_file_path* GetFilePath;
u8* Memory;
s32 Width;
s32 Height;
s32 Pitch;
s32 BytesPerPixel;
};
#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height)
@ -169,50 +161,11 @@ typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint);
#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)
{
for (u32 i = 0; i < Queue->JobsMax; i++)
{
Queue->Jobs[i].Data = 0;
Queue->Jobs[i].Data = {0};
Queue->Jobs[i].WorkProc = 0;
}
@ -232,11 +185,13 @@ GetSecondsElapsed (s64 Start, s64 End, s64 PerformanceCountFrequency)
struct context
{
gs_thread_context ThreadContext;
u8* MemoryBase;
u32 MemorySize;
b32 WindowIsVisible;
rect WindowBounds;
rect2 WindowBounds;
r32 DeltaTime;
mouse_state Mouse;
@ -247,59 +202,18 @@ struct context
cleanup_application* CleanupApplication;
// 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_font_info* PlatformGetFontInfo;
platform_draw_font_codepoint* PlatformDrawFontCodepoint;
platform_get_socket_handle* PlatformGetSocketHandle;
platform_set_socket_option* PlatformSetSocketOption;
platform_send_to* PlatformSendTo;
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
#endif // FOLDHAUS_PLATFORM_H

View File

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

View File

@ -19,65 +19,71 @@ struct camera
inline m44
GetCameraModelViewMatrix (camera Camera)
{
#if 0
// Forward
v4 CamForward = V4(Normalize(Camera.Position - Camera.LookAt), 0);
// 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;
m44 RotationMatrix = M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt));
m44 PositionMatrix = M44Translation(ToV4Point(-Camera.Position));
m44 ModelViewMatrix = RotationMatrix * PositionMatrix;
return ModelViewMatrix;
}
inline m44
GetCameraPerspectiveProjectionMatrix(camera Camera)
{
r32 Top = Camera.Near * GSTan((Camera.FieldOfView / 2.0f));
r32 Bottom = -Top;
r32 Right = Top * Camera.AspectRatio;
r32 Left = -Right;
m44 Result = M44ProjectionPerspective(Camera.FieldOfView, Camera.AspectRatio, Camera.Near, Camera.Far);
return Result;
}
r32 A = ((Right + Left) / (Right - Left));
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 m44
GetCameraMatrix(camera Camera)
{
m44 ModelView = GetCameraModelViewMatrix(Camera);
m44 Projection = GetCameraPerspectiveProjectionMatrix(Camera);
m44 Result = Projection * ModelView;
return Result;
}
r32 E = ((2 * Camera.Near) / (Right - Left));
r32 F = ((2 * Camera.Near) / (Top - Bottom));
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);
m44 PerspectiveProjectionMatrix =
{
E, 0, A, 0,
0, F, B, 0,
0, 0, C, D,
0, 0, -1, 0
};
return ScreenPosition;
}
return PerspectiveProjectionMatrix;
internal v4_ray
ProjectScreenPointToWorldRay(v2 ScreenPoint, camera Camera, rect2 WindowBounds)
{
v4_ray Result = {0};
r32 TanFOVOverTwo = TanR32(DegToRadR32(Camera.FieldOfView / 2.0f));
r32 Aspect = RectAspectRatio(WindowBounds);
r32 NormalizedX = ScreenPoint.x / Rect2Width(WindowBounds);
r32 NormalizedY = ScreenPoint.y / Rect2Height(WindowBounds);
r32 CenteredX = (2.0f * NormalizedX) - 1.0f;
r32 CenteredY = (2.0f * NormalizedY) - 1.0f;
r32 ScaledX = CenteredX * Aspect;
r32 ScaledY = CenteredY;
r32 CameraX = ScaledX * TanFOVOverTwo;
r32 CameraY = ScaledY * TanFOVOverTwo;
r32 Near = Camera.Near;
r32 Far = Camera.Far;
v3 MousePointOnNearPlane = v3{CameraX, CameraY, -1} * Near;
v3 MousePointOnFarPlane = v3{CameraX, CameraY, -1} * Far;
v4 MouseRayDirection = ToV4Vec(V3Normalize(MousePointOnFarPlane - MousePointOnNearPlane));
m44 CameraTransform = M44Transpose(M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt)));
Result.Origin = ToV4Point(Camera.Position);
Result.Direction = CameraTransform * MouseRayDirection;
return Result;
}
// Render Commands
@ -200,7 +206,7 @@ struct render_command_set_render_mode
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
{
@ -257,7 +263,7 @@ ResizeBufferIfNecessary(render_command_buffer* Buffer, s32 DataSize)
// NewSize = Buffer->CommandMemorySize + (2 * DataSize);
s32 SpaceAvailable = Buffer->CommandMemorySize - Buffer->CommandMemoryUsed;
s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point
s32 AdditionSize = GSMax(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory,
Buffer->CommandMemorySize,
@ -285,7 +291,7 @@ PushQuad3DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* C
internal s32
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->Count = 0;
@ -316,6 +322,15 @@ struct quad_batch_constructor_reserved_range
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
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,
v4 C0, v4 C1, v4 C2)
{
//Assert(P0.w != 0 && P1.w != 0 && P2.w != 0); // Passing vectors, rather than positions. Will draw wrong
// Vertecies
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 0)] = P0;
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 1)] = P1;
@ -355,6 +372,7 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
v4 C0, v4 C1, v4 C2)
{
DEBUG_TRACK_FUNCTION;
// TODO(Peter): I think we avoid doing cross thread filling of a batch so do we need this?
s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor);
SetTri3DInBatch(Constructor, Tri, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
};
@ -362,7 +380,7 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
internal void
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color)
{
Assert(Constructor->Count + 2 < Constructor->Max);
Assert(Constructor->Count + 2 <= Constructor->Max);
PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color, Color, Color);
PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color, Color, Color);
}
@ -373,7 +391,7 @@ PushQuad3DOnBatch (render_quad_batch_constructor* Constructor,
v2 UV0, v2 UV1, v2 UV2, v2 UV3,
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, 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)
{
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,
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);
Command->ModelView = GetCameraModelViewMatrix(Camera);
Command->Projection = GetCameraPerspectiveProjectionMatrix(Camera);
Command->ModelView = M44Transpose(GetCameraModelViewMatrix(Camera));
Command->Projection = M44Transpose(GetCameraPerspectiveProjectionMatrix(Camera));
Command->ViewOffsetX = (r32)OffsetX;
Command->ViewOffsetY = (r32)OffsetY;
@ -514,25 +532,18 @@ PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
return Command;
}
internal void
PushRenderPerspective(render_command_buffer* Buffer, rect2 Viewport, camera Camera)
{
PushRenderPerspective(Buffer, Viewport.Min.x, Viewport.Min.y, Rect2Width(Viewport), Rect2Height(Viewport), Camera);
}
internal void
PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight)
{
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
Command->ModelView = m44{
1, 0, 0, 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->ModelView = M44Identity();
Command->Projection = M44ProjectionOrtho((r32)ViewWidth, (r32)ViewHeight, 0, 100, ViewWidth, 0, ViewHeight, 0);
Command->ViewOffsetX = (r32)OffsetX;
Command->ViewOffsetY = (r32)OffsetY;
@ -542,6 +553,12 @@ PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
Command->UseDepthBuffer = false;;
}
internal void
PushRenderOrthographic(render_command_buffer* Buffer, rect2 Viewport)
{
PushRenderOrthographic(Buffer, Viewport.Min.x, Viewport.Min.y, Rect2Width(Viewport), Rect2Height(Viewport));
}
internal void
PushRenderClearScreen (render_command_buffer* Buffer)
{
@ -571,6 +588,13 @@ PushRenderQuad2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 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
PushRenderLine2D (render_command_buffer* Buffer, v2 P0, v2 P1, r32 Thickness, v4 Color)
{

View File

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

View File

@ -1,19 +1,18 @@
enum panel_type {
PanelType_FileView,
PanelType_SculptureView,
PanelType_AnimationTimeline,
PanelType_DMXView,
PanelType_HierarchyView,
PanelType_NodeGraph,
PanelType_ProfilerView,
PanelType_FileView,
PanelType_SculptureView,
PanelType_AnimationTimeline,
PanelType_DMXView,
PanelType_HierarchyView,
PanelType_NodeGraph,
PanelType_ProfilerView,
};
global_variable s32 GlobalPanelDefsCount = 7;
global_variable panel_definition GlobalPanelDefs[] = {
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands, AnimationTimeline_CommandsCount },
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
{ "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 },
global s32 GlobalPanelDefsCount = 6;
global panel_definition GlobalPanelDefs[] = {
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands, AnimationTimeline_CommandsCount },
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
};

View File

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

View File

@ -67,7 +67,7 @@ gsosx_CreateWindow(NSApplication* App, int Width, int Height, id Title)
[App setMainMenu: MenuBar];
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"];
[AppMenu addItem: QuitMenuItem];
[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
enum string_alignment
enum gs_string_alignment
{
Align_Left,
Align_Center,
@ -60,10 +60,10 @@ DrawCharacterRightAligned (render_quad_batch_constructor* BatchConstructor, char
}
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;
char* C = String;
char* C = gs_string;
for (s32 i = 0; i < Length; i++)
{
v2 PositionAfterCharacter = DrawCharacterLeftAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
@ -74,10 +74,10 @@ DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Leng
}
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;
char* C = String + Length - 1;
char* C = gs_string + Length - 1;
for (s32 i = Length - 1; i >= 0; i--)
{
v2 PositionAfterCharacter = DrawCharacterRightAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
@ -88,7 +88,7 @@ DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Len
}
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;
v2 LowerRight = Position;
@ -129,7 +129,7 @@ DrawCursor (render_quad_batch_constructor* BatchConstructor, v2 Position, v4 Col
}
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;
v2 LowerRight = Position;
@ -153,21 +153,21 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
{
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
String.Length - CursorPosition,
String.Memory + CursorPosition,
String.Str + CursorPosition,
RegisterPosition, Font, Color);
}
}
else if (Alignment == Align_Right)
{
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
CursorPosition, String.Memory,
CursorPosition, String.Str,
RegisterPosition, Font, Color);
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
if (String.Length - CursorPosition > 0)
{
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
String.Length - CursorPosition,
String.Memory + CursorPosition,
String.Str + CursorPosition,
RegisterPosition, Font, Color);
}
}
@ -201,7 +201,7 @@ struct interface_config
struct ui_layout
{
rect Bounds;
rect2 Bounds;
v2 Margin;
r32 RowHeight;
r32 RowYAt;
@ -220,7 +220,7 @@ struct ui_interface
};
static ui_layout
ui_CreateLayout(ui_interface Interface, rect Bounds)
ui_CreateLayout(ui_interface Interface, rect2 Bounds)
{
ui_layout Result = {0};
Result.Bounds = Bounds;
@ -263,7 +263,7 @@ ui_EndRow(ui_layout* Layout)
}
static b32
ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
ui_TryReserveElementBounds(ui_layout* Layout, rect2* Bounds)
{
b32 Result = true;
if (!Layout->DrawHorizontal)
@ -289,7 +289,7 @@ ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
}
else
{
r32 ElementWidth = gs_Width(Layout->Bounds) / Layout->ColumnsMax;
r32 ElementWidth = Rect2Width(Layout->Bounds) / Layout->ColumnsMax;
Bounds->Min = {
Layout->Bounds.Min.x + (ElementWidth * Layout->ColumnsCount) + Layout->Margin.x,
Layout->RowYAt
@ -309,18 +309,18 @@ ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
return Result;
}
static rect
ui_ReserveTextLineBounds(ui_interface Interface, string Text, ui_layout* Layout)
static rect2
ui_ReserveTextLineBounds(ui_interface Interface, gs_string Text, ui_layout* Layout)
{
rect Bounds = {0};
rect2 Bounds = {0};
return Bounds;
}
static rect
static rect2
ui_ReserveElementBounds(ui_layout* Layout)
{
rect Bounds = {0};
rect2 Bounds = {0};
if (!ui_TryReserveElementBounds(Layout, &Bounds))
{
InvalidCodePath;
@ -328,10 +328,10 @@ ui_ReserveElementBounds(ui_layout* Layout)
return Bounds;
}
static rect
static rect2
ui_LayoutRemaining(ui_layout Layout)
{
rect Result = Layout.Bounds;
rect2 Result = Layout.Bounds;
Result.Max.y = Layout.RowYAt;
if (Layout.DrawHorizontal)
{
@ -352,19 +352,19 @@ ui_GetTextLineHeight(ui_interface Interface)
}
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
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);
}
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;
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
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))
{
// 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
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_DrawString(Interface, Text, Bounds, TextColor);
}
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;
v4 ButtonBG = InactiveColor;
if (gs_PointIsInRect(Interface->Mouse.Pos, Bounds))
if (PointIsInRect(Bounds, Interface->Mouse.Pos))
{
ButtonBG = HoverColor;
if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState))
@ -430,7 +430,7 @@ ui_Button(ui_interface* Interface, string Text, rect Bounds, v4 InactiveColor, v
}
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 HoverColor = Interface->Style.ButtonColor_Active;
@ -463,16 +463,16 @@ ui_GetListItemColors(ui_interface* Interface, u32 ListItemIndex)
}
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);
return ui_Button(Interface, Text, Bounds, Colors.Hover, Colors.Selected, Colors.BGColor);
}
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))
{
ButtonBounds = ui_ReserveTextLineBounds(*Interface, Text, Layout);
@ -481,7 +481,7 @@ ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text, v4 BGCo
}
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 HoverColor = Interface->Style.ButtonColor_Active;
@ -490,16 +490,16 @@ ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text)
}
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);
return ui_LayoutButton(Interface, Layout, Text, Colors.Hover, Colors.Selected, Colors.BGColor);
}
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))
{
// 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
{
rect ListBounds;
rect2 ListBounds;
v2 ListElementDimensions;
v2 ElementLabelIndent;
@ -540,10 +540,10 @@ struct interface_list
s32 ListElementsCount;
};
internal rect
internal rect2
DrawListElementBackground(interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer)
{
rect LineBounds = {};
rect2 LineBounds = {};
LineBounds.Min = v2{
List->ListBounds.Min.x,
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;
v4 Color = List->LineBGColors[List->ListElementsCount % List->LineBGColorsCount];
if (PointIsInRange(Mouse.Pos, LineBounds.Min, LineBounds.Max))
if (PointIsInRect(LineBounds, Mouse.Pos))
{
Color = List->LineBGHoverColor;
}
@ -560,10 +560,10 @@ DrawListElementBackground(interface_list* List, mouse_state Mouse, render_comman
return LineBounds;
}
internal rect
DrawListElement(string Label, interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer, interface_config Interface)
internal rect2
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;
DrawString(RenderBuffer, Label, Interface.Font, LabelPosition, List->TextColor);
@ -578,27 +578,34 @@ EvaluateColorChannelSlider (render_command_buffer* RenderBuffer, v4 ChannelMask,
{
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);
v4 LeftColor = ChannelMask * 0;
LeftColor.a = 1.f;
v4 RightColor = ChannelMask;
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},
LeftColor, RightColor, RightColor, LeftColor);
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 = GSClamp01(Result);
Result = Clamp01(Result);
}
}
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};
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;
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;
}
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)};
DrawString(RenderBuffer, MakeStringLiteral("Color Picker"), Config.Font,
v2 TitleMin = v2{PanelRect.Min.x + 5, PanelRect.Max.y - (Config.Font->PixelHeight + 5)};
DrawString(RenderBuffer, MakeString("Color Picker"), Config.Font,
TitleMin, WhiteV4);
v2 SliderDim = v2{(PanelMax.x - PanelMin.x) - 20, 32};
@ -650,13 +659,13 @@ struct search_lister_result
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
EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string Title,
string* ItemList, s32* ListLUT, s32 ListLength,
EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, gs_string Title,
gs_string* ItemList, s32* ListLUT, s32 ListLength,
s32 HotItem,
string* SearchString, s32 SearchStringCursorPosition)
gs_string* Searchgs_string, s32 Searchgs_stringCursorPosition)
{
search_lister_result Result = {};
Result.ShouldRemainOpen = true;
@ -666,24 +675,24 @@ EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string
InvalidCodePath;
#if 0
// 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_DrawString(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
ui_Drawgs_string(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
MakeStringBuffer(DebugString, 256);
PrintF(&DebugString, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
rect DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
ui_DrawString(Interface, DebugString, DebugBounds, Interface->Style.TextColor);
MakeStringBuffer(Debuggs_string, 256);
PrintF(&Debuggs_string, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
rect2 DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
ui_Drawgs_string(Interface, Debuggs_string, DebugBounds, Interface->Style.TextColor);
// Search Bar
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
DrawStringWithCursor(RenderBuffer, *SearchString, SearchStringCursorPosition, Font, 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;
for (s32 i = 0; i < ListLength; i++)
{
s32 FilteredIndex = ListLUT[i];
string ListItemString = ItemList[FilteredIndex];
gs_string ListItemgs_string = ItemList[FilteredIndex];
v2 Min = v2{TopLeft.x, TopLeft.y - 30};
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;
}
if (ui_Button(Interface, ListItemString, rect{Min, Max}))
if (ui_Button(Interface, ListItemgs_string, rect2{Min, Max}))
{
Result.SelectedItem = i;
}

View File

@ -6,7 +6,7 @@
#ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
// Colors
global_variable v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f};
global v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f};
//
struct animation_timeline_state
@ -15,7 +15,7 @@ struct animation_timeline_state
};
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);
u32 VisibleFramesCount = GetFrameCount(VisibleRange);
@ -24,10 +24,10 @@ GetFrameFromPointInAnimationPanel(v2 Point, rect PanelBounds, frame_range Visibl
}
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);
s32 XPositionAtFrame = (PercentOfTimeline * gs_Width(PanelBounds)) + PanelBounds.Min.x;
s32 XPositionAtFrame = (PercentOfTimeline * Rect2Width(PanelBounds)) + PanelBounds.Min.x;
return XPositionAtFrame;
}
@ -67,7 +67,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
OPERATION_STATE_DEF(drag_time_marker_operation_state)
{
rect TimelineBounds;
rect2 TimelineBounds;
s32 StartFrame;
s32 EndFrame;
};
@ -90,7 +90,7 @@ input_command DragTimeMarkerCommands [] = {
};
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);
@ -112,7 +112,7 @@ StartDragTimeMarker(rect TimelineBounds, frame_range VisibleFrames, app_state* S
OPERATION_STATE_DEF(drag_animation_clip_state)
{
rect TimelineBounds;
rect2 TimelineBounds;
frame_range VisibleRange;
frame_range ClipRange;
};
@ -122,7 +122,7 @@ AttemptToSnapPosition(u32 SnappingFrame, u32 SnapToFrame)
{
u32 Result = SnappingFrame;
s32 SnapDistance = 5;
if (GSAbs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance)
if (Abs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance)
{
Result = SnapToFrame;
}
@ -134,13 +134,13 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
drag_animation_clip_state* OpState = (drag_animation_clip_state*)Operation.OpStateMemory;
r32 ClipInitialStartFrameXPercent = FrameToPercentRange(OpState->ClipRange.Min, OpState->VisibleRange);
u32 ClipInitialStartFrameXPosition = GSLerp(OpState->TimelineBounds.Min.x,
OpState->TimelineBounds.Max.x,
ClipInitialStartFrameXPercent);
u32 ClipInitialStartFrameXPosition = LerpR32(ClipInitialStartFrameXPercent,
OpState->TimelineBounds.Min.x,
OpState->TimelineBounds.Max.x);
r32 ClipInitialEndFrameXPercent = FrameToPercentRange(OpState->ClipRange.Max, OpState->VisibleRange);
u32 ClipInitialEndFrameXPosition = GSLerp(OpState->TimelineBounds.Min.x,
OpState->TimelineBounds.Max.x,
ClipInitialEndFrameXPercent);
u32 ClipInitialEndFrameXPosition = LerpR32(ClipInitialEndFrameXPercent,
OpState->TimelineBounds.Min.x,
OpState->TimelineBounds.Max.x);
u32 FrameAtMouseDownX = GetFrameFromPointInAnimationPanel(Mouse.DownPos, OpState->TimelineBounds, OpState->VisibleRange);
@ -154,7 +154,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
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;
if (FrameOffset < 0)
@ -176,7 +176,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
}
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;
if (FrameOffset > 0)
@ -228,8 +228,8 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
s32 PlayableStartFrame = State->AnimationSystem.PlayableRange.Min;
s32 PlayableEndFrame = State->AnimationSystem.PlayableRange.Max;
AnimationBlock->Range.Min = (u32)GSClamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame);
AnimationBlock->Range.Max = (u32)GSClamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame);
AnimationBlock->Range.Min = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame);
AnimationBlock->Range.Max = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame);
}
input_command DragAnimationClipCommands [] = {
@ -237,7 +237,7 @@ input_command DragAnimationClipCommands [] = {
};
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);
@ -289,20 +289,20 @@ AnimationTimeline_Cleanup(panel* Panel, app_state* State)
}
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;
r32 BarHeight = gs_Height(BarBounds);
r32 BarWidth = gs_Width(BarBounds);
r32 BarHeight = Rect2Height(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
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
PointIsInRange(Mouse.DownPos, gs_RectExpand(BarBounds)))
PointIsInRect(BarBounds, Mouse.DownPos))
{
StartDragTimeMarker(BarBounds, VisibleFrames, State);
}
@ -315,7 +315,7 @@ DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBu
u32 Frame = PercentToFrameInRange(Percent, VisibleFrames);
PrintF(&TempString, "%d", Frame);
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};
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))
{
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
r32 SliderWidth = (8 * FrameNumberCharCount) + 8;
r32 SliderWidth = (8 * TempString.Length) + 8;
r32 SliderHalfWidth = SliderWidth / 2.f;
v2 HeadMin = v2{SliderX - SliderHalfWidth, BarBounds.Min.y};
v2 HeadMax = v2{SliderX + SliderHalfWidth, BarBounds.Max.y};
PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor);
PrintF(&TempString, "%d", AnimationSystem->CurrentFrame);
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, HeadMin + v2{6, 4}, WhiteV4);
}
}
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};
r32 BarHeight = gs_Height(BarBounds);
r32 BarWidth = gs_Width(BarBounds);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(BarBounds), v4{.16f, .16f, .16f, 1.f});
r32 BarHeight = Rect2Height(BarBounds);
r32 BarWidth = Rect2Width(BarBounds);
PushRenderQuad2D(RenderBuffer, BarBounds.Min, BarBounds.Max, v4{.16f, .16f, .16f, 1.f});
r32 PlayableFrames = (r32)GetFrameCount(AnimationSystem->PlayableRange);
v2 SliderBarDim = v2{25, BarHeight};
@ -354,22 +353,24 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
// Convert Frames To Pixels
r32 VisibleMinPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Min, AnimationSystem->PlayableRange);
r32 VisibleMaxPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Max, AnimationSystem->PlayableRange);
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * gs_Width(BarBounds)), BarBounds.Min.y};
v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (VisibleMaxPercentPlayable * gs_Width(BarBounds)) - 25, BarBounds.Min.y};
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * Rect2Width(BarBounds)), 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) ||
MouseButtonTransitionedUp(Mouse.LeftButtonState))
{
v2 MouseDragOffset = Mouse.Pos - Mouse.DownPos;
if (PointIsInRange(Mouse.DownPos, RangeMinSliderMin, RangeMinSliderMin + SliderBarDim))
if (PointIsInRect(SliderBarRange, Mouse.DownPos))
{
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;
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
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};
for (u32 LayerIndex = 0; LayerIndex < AnimationSystem->LayersCount; LayerIndex++)
{
anim_layer* Layer = AnimationSystem->Layers + LayerIndex;
rect LayerBounds = {0};
rect2 LayerBounds = {0};
LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * LayerIndex) };
LayerBounds.Max = LayerBounds.Min + LayerDim;
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
gs_PointIsInRect(Mouse.Pos, LayerBounds))
PointIsInRect(LayerBounds, Mouse.Pos))
{
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};
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);
}
}
internal rect
DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect TimelineBounds, render_command_buffer* RenderBuffer)
internal rect2
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);
r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, VisibleFrames);
@ -448,18 +449,18 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
}
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;
rect LayerMenuBounds, TimelineBounds;
gs_VSplitRectAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
rect2 LayerMenuBounds, TimelineBounds;
RectVSplitAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
// In Top To Bottom Order
rect TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
gs_HSplitRectAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
gs_HSplitRectAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
rect2 TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
RectHSplitAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
RectHSplitAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
// TODO(Peter): Clean Up
DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse);
@ -500,8 +501,8 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
BlockColor = PinkV4;
}
// TODO(Peter): Clean Up
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
if (gs_PointIsInRect(Interface->Mouse.Pos, BlockBounds))
rect2 BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
if (PointIsInRect(BlockBounds, Interface->Mouse.Pos))
{
DragBlockHandle = CurrentBlockHandle;
}
@ -519,8 +520,8 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
if (FrameIsInRange(AnimationSystem->CurrentFrame, AdjustedViewRange))
{
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
r32 SliderX = GSLerp(TimelineBounds.Min.x, TimelineBounds.Max.x, FrameAtPercentVisibleRange);
rect SliderBounds = {
r32 SliderX = LerpR32(FrameAtPercentVisibleRange, TimelineBounds.Min.x, TimelineBounds.Max.x);
rect2 SliderBounds = {
v2{ SliderX, TimelineBounds.Min.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, TimelineBlockDisplayBounds, 1.f, RedV4);
if (MouseDownAndNotHandled && gs_PointIsInRect(Interface->Mouse.Pos, TimelineBounds))
if (MouseDownAndNotHandled && PointIsInRect(TimelineBounds, Interface->Mouse.Pos))
{
DeselectCurrentAnimationBlock(State);
}
@ -554,13 +555,13 @@ animation_clip GlobalAnimationClips[] = {
};
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);
for (s32 i = 0; i < GlobalAnimationClipsCount; 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))
{
AddAnimationBlockAtCurrentTime(i + 1, SelectedAnimationLayer, AnimationSystem);
@ -572,7 +573,7 @@ DrawAnimationClipsList(rect PanelBounds, ui_interface* Interface, u32 SelectedAn
GSMetaTag(panel_render);
GSMetaTag(panel_type_animation_timeline);
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;
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;
animation_system* AnimationSystem = &State->AnimationSystem;
rect TitleBarBounds, PanelContentsBounds;
gs_HSplitRectAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds);
rect AnimationListBounds, TimelineBounds;
gs_VSplitRectAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds);
rect2 TitleBarBounds, PanelContentsBounds;
RectHSplitAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds);
rect2 AnimationListBounds, TimelineBounds;
RectVSplitAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds);
ui_FillRect(Interface, TitleBarBounds, Interface->Style.PanelBGColors[0]);
ui_layout TitleBarLayout = ui_CreateLayout(*Interface, TitleBarBounds);
ui_StartRow(&TitleBarLayout, 3);
{
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Pause")))
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Pause")))
{
State->AnimationSystem.TimelineShouldAdvance = true;
}
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Play")))
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Play")))
{
State->AnimationSystem.TimelineShouldAdvance = false;
}
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Stop")))
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Stop")))
{
State->AnimationSystem.TimelineShouldAdvance = false;
State->AnimationSystem.CurrentFrame = 0;
@ -605,7 +606,7 @@ AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* R
}
ui_EndRow(&TitleBarLayout);
if (gs_Height(TimelineBounds) > 0)
if (Rect2Height(TimelineBounds) > 0)
{
SelectedBlockHandle = DrawAnimationTimeline(AnimationSystem, TimelineState, TimelineBounds, SelectedBlockHandle, Interface, State);
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_type_dmx_view);
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
// :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;
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};
@ -120,8 +120,8 @@ DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffe
if (OpState->Zoom > .5f)
{
v2 TitleDisplayStart = UniverseDisplayTopLeft + v2{0, 12};
PrintF(&TitleBarString, "Universe %d", Universe->Universe);
DrawString(RenderBuffer, TitleBarString, State->Interface.Font,
PrintF(&TitleBargs_string, "Universe %d", Universe->Universe);
DrawString(RenderBuffer, TitleBargs_string, State->Interface.Font,
TitleDisplayStart, WhiteV4);
}

View File

@ -7,7 +7,7 @@
struct file_view_state
{
string WorkingDirectory;
gs_string WorkingDirectory;
};
input_command* FileView_Commands = 0;
@ -36,18 +36,18 @@ FileView_Cleanup(panel* Panel, app_state* State)
GSMetaTag(panel_render);
GSMetaTag(panel_type_file_view);
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.Max = PanelBounds.Max;
rect ListBounds = {0};
rect2 ListBounds = {0};
ListBounds.Min = PanelBounds.Min;
ListBounds.Max = gs_BottomRight(HeaderBounds);
ListBounds.Max = RectBottomRight(HeaderBounds);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(HeaderBounds), PinkV4);
PushRenderQuad2D(RenderBuffer, gs_RectExpand(ListBounds), RedV4);
PushRenderQuad2D(RenderBuffer, HeaderBounds.Min, HeaderBounds.Max, PinkV4);
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_type_hierarchy);
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);
string TempString = PushString(&State->Transient, 256);
u32 LineCount = (u32)(gs_Height(PanelBounds) / Layout.RowHeight) + 1;
u32 AssembliesToDraw = GSMin(LineCount, State->Assemblies.Count);
rect* LineBounds = PushArray(&State->Transient, rect, LineCount);
gs_string Tempgs_string = PushString(&State->Transient, 256);
u32 LineCount = (u32)(Rect2Height(PanelBounds) / Layout.RowHeight) + 1;
u32 AssembliesToDraw = Min(LineCount, State->Assemblies.Count);
rect2* LineBounds = PushArray(&State->Transient, rect2, LineCount);
// Fill in alternating color rows for the backgrounds
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++)
{
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_StartRow(&ItemLayout, 2);
{
ui_LayoutDrawString(&State->Interface, &ItemLayout, TempString, State->Interface.Style.TextColor);
if (ui_LayoutListButton(&State->Interface, &ItemLayout, MakeStringLiteral("X"), AssemblyIndex))
ui_LayoutDrawString(&State->Interface, &ItemLayout, Tempgs_string, State->Interface.Style.TextColor);
if (ui_LayoutListButton(&State->Interface, &ItemLayout, MakeString("X"), AssemblyIndex))
{
UnloadAssembly(AssemblyIndex, State, Context);
}
@ -63,15 +63,22 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
if (AssembliesToDraw < LineCount)
{
// NOTE(Peter): Add assembly button
PrintF(&TempString, "+ Add Assembly");
if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw))
PrintF(&Tempgs_string, "+ Add Assembly");
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");
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
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{.73f, .33f, .83f, 1},
@ -35,8 +35,8 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
v4{.74f, .40f, .25f, 1},
};
rect Bounds = ui_LayoutRemaining(Layout);
r32 Width = gs_Width(Bounds);
rect2 Bounds = ui_LayoutRemaining(Layout);
r32 Width = Rect2Width(Bounds);
r32 DepthHeight = 64;
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
@ -48,7 +48,8 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
scope_record* HotRecord = 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++)
{
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 PixelEnd = Bounds.Min.x + (Width * PercentEnd);
r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight);
rect ScopeBounds = {
rect2 ScopeBounds = {
v2{ PixelStart, MinY },
v2{ PixelEnd, MinY + (DepthHeight - 4) }
};
if (gs_Width(ScopeBounds) >= 1)
if (Rect2Width(ScopeBounds) >= 1)
{
v4 Color = ThreadColors[0];
if (gs_PointIsInRect(Interface->Mouse.Pos, ScopeBounds))
if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
{
Color = GreenV4;
HotRecord = Record;
@ -81,23 +82,26 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
if (HotRecord != 0)
{
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
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};
ui_StartRow(&Layout, 5, &ColumnWidths[0]);
{
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Procedure"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("% Frame"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Seconds"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Cycles"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Calls"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeString("Procedure"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeString("% Frame"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeString("Seconds"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeString("Cycles"), Interface->Style.TextColor);
ui_LayoutDrawString(Interface, &Layout, MakeString("Calls"), Interface->Style.TextColor);
}
ui_EndRow(&Layout);
@ -133,25 +137,27 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debu
GSMetaTag(panel_render);
GSMetaTag(panel_type_profiler);
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;
string String = InitializeEmptyString(PushArray(Memory, char, 256), 256);
gs_memory_arena* Memory = &State->Transient;
gs_string String = PushString(Memory, 256);
v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 };
r32 FrameListHeight = 64;
rect FrameListBounds, ProcListBounds;
gs_HSplitRectAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
rect FrameListInner = gs_InsetRect(FrameListBounds, 4);
rect2 FrameListBounds, ProcListBounds;
RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
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);
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))
{
v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos);
s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
{
@ -159,14 +165,15 @@ ProfilerView_Render(panel Panel, rect PanelBounds, render_command_buffer* Render
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++)
{
rect PositionedFrameBounds = gs_TranslateRectX(FrameBounds, F * SingleFrameStep);
rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep);
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
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);
}

View File

@ -18,11 +18,11 @@ OPERATION_RENDER_PROC(Update3DViewMouseRotate)
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale);
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale);
m44 XRotation = M44RotationX(-TotalDeltaPos.y * State->PixelsToWorldScale);
m44 YRotation = M44RotationY(TotalDeltaPos.x * State->PixelsToWorldScale);
m44 Combined = XRotation * YRotation;
State->Camera.Position = V3(Combined * OpState->CameraStartPos);
State->Camera.Position = (Combined * OpState->CameraStartPos).xyz;
}
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
@ -40,17 +40,17 @@ FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
&State->Modes,
mouse_rotate_view_operation_state);
OpState->CameraStartPos = V4(State->Camera.Position, 1);
OpState->CameraStartPos = ToV4Point(State->Camera.Position);
}
// ----------------
GSMetaTag(panel_commands);
GSMetaTag(panel_type_sculpture_view);
global_variable input_command SculptureView_Commands[] = {
global input_command SculptureView_Commands[] = {
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
};
global_variable s32 SculptureView_CommandsCount = 1;
global s32 SculptureView_CommandsCount = 1;
GSMetaTag(panel_init);
GSMetaTag(panel_type_sculpture_view);
@ -76,23 +76,26 @@ struct draw_leds_job_data
s32 StartIndex;
s32 OnePastLastIndex;
render_quad_batch_constructor* Batch;
m44 ModelViewMatrix;
quad_batch_constructor_reserved_range BatchReservedRange;
r32 LEDHalfWidth;
};
internal void
DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData)
DrawLEDsInBufferRangeJob (gs_thread_context Context, gs_data JobData)
{
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;
#if 0
// 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
// worried about locking up.
quad_batch_constructor_reserved_range BatchReservedRange = ThreadSafeReserveRangeInQuadConstructor(Data->Batch, LEDCount * 2);
#endif
s32 TrisUsed = 0;
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 Position = Data->LedBuffer.Positions[LedIndex];
m44 FaceCameraMatrix = GetLookAtMatrix(Position, Data->CameraPosition);
v4 PositionOffset = V4(Position.xyz, 0); // Ensure PositionOffset is a vector, not a point
m44 FaceCameraMatrix = M44LookAt(Position, Data->CameraPosition);
v4 PositionOffset = ToV4Vec(Position.xyz);
v4 P0 = (FaceCameraMatrix * P0_In) + PositionOffset;
v4 P1 = (FaceCameraMatrix * P1_In) + PositionOffset;
v4 P2 = (FaceCameraMatrix * P2_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);
SetTri3DInBatch(Data->Batch, BatchReservedRange.Start + TrisUsed++,
SetTri3DInBatch(Data->Batch, Data->BatchReservedRange.Start + TrisUsed++,
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_type_sculpture_view);
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);
r32 PanelWidth = PanelBounds.Max.x - PanelBounds.Min.x;
r32 PanelHeight = PanelBounds.Max.y - PanelBounds.Min.y;
State->Camera.AspectRatio = PanelWidth / PanelHeight;
// TODO(Peter): @MajorFix
// NOTE(Peter): Just returning from this function to make sure that this isn't a problem as I go and try to fix
// 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);
m44 FaceCameraMatrix = GetLookAtMatrix(v4{0, 0, 0, 1}, V4(State->Camera.Position, 1));
PushRenderPerspective(RenderBuffer, PanelBounds, State->Camera);
u32 MaxLEDsPerJob = 2048;
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal);
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, Assembly.LedBufferIndex);
u32 JobsNeeded = IntegerDivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
// TODO(Peter): TEMPORARY - identify this pixel
LedBuffer->Colors[FocusPixel] = pixel{ 255, 0, 255 };
led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, BufferIndex);
u32 JobsNeeded = U32DivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
#if 1
u32 NextLEDIndex = 0;
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->StartIndex = Job * MaxLEDsPerJob;
JobData->OnePastLastIndex = GSMin(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount);
JobData->StartIndex = NextLEDIndex;
JobData->OnePastLastIndex = Min(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount);
s32 JobLedCount = JobData->OnePastLastIndex - JobData->StartIndex;
JobData->Batch = &RenderLEDsBatch;
JobData->ModelViewMatrix = ModelViewMatrix;
JobData->LEDHalfWidth = LEDHalfWidth;
JobData->BatchReservedRange = ReserveRangeInQuadConstructor(JobData->Batch, JobLedCount * 2);
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
// needs to relyon the window bounds rather than the panel bounds. Ideally the panel only needs to know where
// itself is, and nothing else.
PushRenderOrthographic(RenderBuffer,
State->WindowBounds.Min.x, State->WindowBounds.Min.y,
State->WindowBounds.Max.x, State->WindowBounds.Max.y);
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
if (State->Assemblies.Count > 0)
{
@ -196,9 +223,9 @@ SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
v4 LedProjectedPosition = Matrix * LedPosition;
v2 LedOnScreenPosition = LedProjectedPosition.xy;
string TempString = PushString(&State->Transient, 256);
PrintF(&TempString, "%f %f", LedOnScreenPosition.x, LedOnScreenPosition.y);
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4);
gs_string Tempgs_string = PushString(&State->Transient, 256);
PrintF(&Tempgs_string, "%f %f", LedOnScreenPosition.x, LedOnScreenPosition.y);
DrawString(RenderBuffer, Tempgs_string, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4);
v2 BoxHalfDim = v2{ 25, 25 };
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);
}
Context.GeneralWorkQueue->DoQueueWorkUntilDone(Context.GeneralWorkQueue, 0);
Context.GeneralWorkQueue->CompleteQueueWork(Context.GeneralWorkQueue, Context.ThreadContext);
}
#define FOLDHAUS_PANEL_SCULPTURE_VIEW_H

View File

@ -160,11 +160,11 @@ VHD_PackLength_(u8* Buffer, u32 Length, b32 IncludeLength)
}
internal cid
StringToCID_ (const char* String)
gs_stringToCID_ (const char* gs_string)
{
cid Result = {};
const char* Src = String;
const char* Src = gs_string;
u8* Dest = &Result.Bytes[0];
b32 FirstNibble = true;
@ -215,7 +215,7 @@ InitStreamHeader (u8* Buffer, s32 BufferSize,
Cursor = PackB2(Cursor, RLP_PREAMBLE_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;
// 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
// :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;
@ -298,7 +298,7 @@ InitializeSACN (context Context)
s32 Multicast_TimeToLive = 20;
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;
}

View File

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

View File

@ -16,14 +16,13 @@
#include "../gs_libs/gs_win32.cpp"
#include "win32_foldhaus_memory.h"
#include "win32_foldhaus_fileio.h"
#include "win32_foldhaus_dll.h"
#include "win32_foldhaus_timing.h"
#include "foldhaus_renderer.cpp"
global_variable b32 Running = false;
global_variable b32 WindowIsActive = false;
global b32 Running = false;
global b32 WindowIsActive = false;
char DLLName[] = "foldhaus.dll";
char WorkingDLLName[] = "foldhaus_temp.dll";
@ -31,6 +30,317 @@ char DLLLockFileName[] = "lock.tmp";
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
{
b32 IsValid;
@ -39,11 +349,42 @@ struct worker_thread_entry
struct worker_thread_info
{
s32 ID;
gs_thread_context ThreadContext;
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)
{
#ifdef DEBUG
@ -51,18 +392,18 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
// overflowing the buffer
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++)
{
PrintF(&DebugString, "%d %s\n", i, Queue->Jobs[i].JobName);
NullTerminate(&DebugString);
OutputDebugStringA(DebugString.Memory);
OutputDebugStringA(DebugString.Str);
}
}
#endif
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->Data = Data;
#ifdef DEBUG
@ -78,7 +419,7 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
}
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)
{
@ -106,16 +447,16 @@ CompleteAndTakeNextJob(work_queue* Queue, worker_thread_entry Completed)
return Result;
}
DO_QUEUE_WORK_UNTIL_DONE(Win32DoQueueWorkUntilDone)
COMPLETE_QUEUE_WORK(Win32DoQueueWorkUntilDone)
{
worker_thread_entry Entry = {};
Entry.IsValid = false;
while (Queue->JobsCompleted < Queue->JobsCount)
{
Entry = CompleteAndTakeNextJob(Queue, Entry);
Entry = CompleteAndTakeNextJob(Queue, Entry, Context);
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)
{
worker_thread_info* ThreadInfo = (worker_thread_info*)InputThreadInfo;
ThreadInfo->ThreadContext = Win32CreateThreadContext();
worker_thread_entry Entry = {};
Entry.IsValid = false;
while (true)
{
Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry);
ClearArena(ThreadInfo->ThreadContext.Transient);
Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry, ThreadInfo->ThreadContext);
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);
}
else
@ -188,13 +531,13 @@ PLATFORM_GET_SOCKET_HANDLE(Win32GetSocketHandle)
{
s32 NewDictionaryMax = Win32SocketHandleMax + SOCKET_DICTIONARY_GROW_SIZE;
s32 NewDictionaryDataSize = NewDictionaryMax * sizeof(win32_socket);
u8* DictionaryMemory = Win32Alloc(NewDictionaryDataSize);
u8* DictionaryMemory = (u8*)Win32Alloc(NewDictionaryDataSize, 0);
Assert(DictionaryMemory);
win32_socket* NewValues = (win32_socket*)(DictionaryMemory);
if (SocketValues)
{
GSMemCopy(SocketValues, NewValues, sizeof(win32_socket) * NewDictionaryMax);
CopyMemoryTo(SocketValues, NewValues, sizeof(win32_socket) * NewDictionaryMax);
Win32Free((u8*)SocketValues, sizeof(win32_socket) * Win32SocketHandleCount);
}
SocketValues = NewValues;
@ -512,7 +855,7 @@ internal void
DebugPrint (char* Format, ...)
{
char Buffer[256];
string StringBuffer = MakeString(Buffer, 256);
gs_string StringBuffer = MakeString(Buffer, 256);
va_list Args;
va_start(Args, Format);
PrintF(&StringBuffer, Format, Args);
@ -521,7 +864,7 @@ DebugPrint (char* Format, ...)
}
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)
{
@ -539,27 +882,22 @@ SetApplicationLinks (context* Context, win32_dll_refresh DLL, work_queue* WorkQu
}
}
// TODO(Peter): :Redundant remove
internal u8*
DEBUGAlloc(s32 ElementSize, s32 ElementCount)
{
return Win32Alloc(ElementSize * ElementCount);
return (u8*)Win32Alloc(ElementSize * ElementCount, 0);
}
// TODO(Peter): :Redundant remove
internal u8*
Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
{
u8* NewMemory = Win32Alloc(NewSize);
GSMemCopy(Buf, NewMemory, OldSize);
u8* NewMemory = (u8*)Win32Alloc(NewSize, 0);
CopyMemoryTo(Buf, NewMemory, OldSize);
return NewMemory;
}
internal s32
Win32GetThreadId()
{
s32 Result = GetCurrentThreadId();
return Result;
}
// NOTE(Peter): Only meant to take one of the values specified below:
// IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM,
// IDC_ICON, IDC_NO, IDC_SIZE, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE,
@ -577,6 +915,36 @@ Win32LoadSystemCursor(char* CursorIdentifier)
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
WinMain (
HINSTANCE HInstance,
@ -585,6 +953,171 @@ WinMain (
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);
Win32UpdateWindowDimension(&MainWindow);
@ -612,7 +1145,7 @@ WinMain (
input_queue InputQueue;
{
s32 InputQueueMemorySize = sizeof(input_entry) * 32;
u8* InputQueueMemory = Win32Alloc(InputQueueMemorySize);
u8* InputQueueMemory = (u8*)Win32Alloc(InputQueueMemorySize, 0);
InputQueue = InitializeInputQueue(InputQueueMemory, InputQueueMemorySize);
}
@ -625,31 +1158,31 @@ WinMain (
WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * PLATFORM_THREAD_COUNT);
}
work_queue WorkQueue = {};
WorkQueue.SemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS);
HANDLE WorkQueueSemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS);
gs_work_queue WorkQueue = {};
WorkQueue.SemaphoreHandle = &WorkQueueSemaphoreHandle;
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.PushWorkOnQueue = Win32PushWorkOnQueue;
WorkQueue.DoQueueWorkUntilDone = Win32DoQueueWorkUntilDone;
WorkQueue.CompleteQueueWork = Win32DoQueueWorkUntilDone;
WorkQueue.ResetWorkQueue = ResetWorkQueue;
OutputDebugStringA("Hellooooo\n");
for (s32 i = 0; i < PLATFORM_THREAD_COUNT; i++)
{
// ID = 0 is reserved for this thread
WorkerThreads[i].ID = i + 1;
WorkerThreads[i].Queue = &WorkQueue;
WorkerThreads[i].Handle = CreateThread(0, 0, &WorkerThreadProc, (void*)&WorkerThreads[i], 0, 0);
}
s32 InitialMemorySize = Megabytes(64);
u8* InitialMemory = Win32Alloc(InitialMemorySize);
s32 InitialMemorySize = MB(64);
u8* InitialMemory = (u8*)Win32Alloc(InitialMemorySize, 0);
context Context = {};
Context.ThreadContext = ThreadContext;
Context.MemorySize = InitialMemorySize;
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};
// Cursors
@ -663,12 +1196,6 @@ WinMain (
// Platform functions
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.PlatformGetSocketHandle = Win32GetSocketHandle;
Context.PlatformSetSocketOption = Win32SetSocketOption;
@ -692,8 +1219,8 @@ WinMain (
WSADATA WSAData;
WSAStartup(MAKEWORD(2, 2), &WSAData);
s32 RenderMemorySize = Megabytes(12);
u8* RenderMemory = Win32Alloc(RenderMemorySize);
s32 RenderMemorySize = MB(12);
u8* RenderMemory = (u8*)Win32Alloc(RenderMemorySize, 0);
render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(RenderMemory, RenderMemorySize, Win32Realloc);
Context.InitializeApplication(Context);
@ -733,7 +1260,7 @@ WinMain (
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.ViewHeight = MainWindow.Height;
Context.DeltaTime = LastFrameSecondsElapsed;

View File

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

View File

@ -8,138 +8,5 @@
//
#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
#endif // WIN32_FOLDHAUS_FILEIO_H

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,7 @@ Write(string Text, string_builder* StringBuilder)
// Copy what there is room for
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.Length -= SpaceAvailable;
@ -93,7 +93,7 @@ WriteStringBuilderToFile(string_builder StringBuilder, FILE* WriteFile)
while (BufferAt)
{
string String = BufferAt->String;
fwrite(String.Memory, 1, String.Length, WriteFile);
fwrite(String.Str, 1, String.Length, WriteFile);
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
{
struct
{
float a; float b; float c;
float d; float e; float f;
float g; float h; float i;
};
float E[9];
float E[3][3];
};
union m44
{
struct
{
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];
float E[4][4];
};
//////////////////////////////////////
@ -648,10 +635,10 @@ PointIsInRange (v2 _P, v2 _Min, v2 _Max)
static bool
PointIsInRangeSafe (v2 _P, v2 _Min, v2 _Max)
{
s32 MinX = GSMin(_Min.x, _Max.x);
s32 MinY = GSMin(_Min.y, _Max.y);
s32 MaxX = GSMax(_Min.x, _Max.x);
s32 MaxY = GSMax(_Min.y, _Max.y);
s32 MinX = Min(_Min.x, _Max.x);
s32 MinY = Min(_Min.y, _Max.y);
s32 MaxX = Max(_Min.x, _Max.x);
s32 MaxY = Max(_Min.y, _Max.y);
return (_P.x >= MinX && _P.x <= MaxX &&
_P.y >= MinY && _P.y <= MaxY);
@ -1438,11 +1425,11 @@ void TestVectorMatrixMultiplication ()
// Utility Functions
TestClean((GSSqrt(4.f) == 2.f), "Vector Square Root");
TestClean((GSLerp(0.f, 1.f, .5f) == .5f), "Vector Lerp");
TestClean((GSMin(-.25f, 5.f) == -.25f), "Vector Min");
TestClean((GSMax(-.25f, 5.f) == 5.f), "Vector Max");
TestClean((GSClamp(-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((Lerp(0.f, 1.f, .5f) == .5f), "Vector Lerp");
TestClean((Min(-.25f, 5.f) == -.25f), "Vector Min");
TestClean((Max(-.25f, 5.f) == 5.f), "Vector Max");
TestClean((Clamp(-2.f, -3.f, 5.f) == -2.f), "Vector Clamp, Lower Than Range");
TestClean((Clamp(-2.f, 6.f, 5.f) == 5.f), "Vector Clamp, Higher Than Range");
//////////////////////////////
// Vector Functions

View File

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

View File

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

View File

@ -14,13 +14,32 @@ struct errors
u32 Used;
};
#define ErrorReallocArray(base, type, oldcount, newcount) (type*)ErrorRealloc_((u8*)(base), (u64)(sizeof(type) * oldcount), (u64)(sizeof(type) * newcount))
internal u8*
ErrorRealloc_(u8* Base, u64 OldSize, u64 NewSize)
{
Assert(NewSize > 0);
u8* Result = (u8*)malloc(NewSize);
if (Base != 0 && OldSize > 0)
{
GSMemCopy(Base, Result, OldSize);
free(Base);
}
return Result;
}
internal void
PushFError (errors* Errors, char* Format, ...)
{
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
{
#if 0
Errors->BuffersCount += 1;
Errors->Buffers = (error_buffer*)realloc(Errors->Buffers, sizeof(error_buffer*) * Errors->BuffersCount);
#else
Errors->Buffers = ErrorReallocArray(Errors->Buffers, error_buffer, Errors->BuffersCount, Errors->BuffersCount + 1);
Errors->BuffersCount += 1;
#endif
error_buffer* NewBuffer = Errors->Buffers + (Errors->BuffersCount - 1);
NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE);
@ -28,8 +47,8 @@ PushFError (errors* Errors, char* Format, ...)
for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++)
{
NewBuffer->Contents[i].Memory = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH);
NewBuffer->Contents[i].Max = ERROR_MAX_LENGTH;
NewBuffer->Contents[i].Str = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH);
NewBuffer->Contents[i].Size = ERROR_MAX_LENGTH;
NewBuffer->Contents[i].Length = 0;
}
}

View File

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