Cleaning up, converting over to using new gs files.
This commit is contained in:
parent
295a5aaaa0
commit
50c2ef9290
|
@ -16,7 +16,7 @@ pushd %BuildPath%
|
||||||
del *.pdb > NUL 2> NUL
|
del *.pdb > NUL 2> NUL
|
||||||
|
|
||||||
REM Run the Preprocessor
|
REM Run the Preprocessor
|
||||||
%MetaProgramPath%\foldhaus_meta.exe %SourceCodePath%\foldhaus_app.cpp
|
REM %MetaProgramPath%\foldhaus_meta.exe %SourceCodePath%\foldhaus_app.cpp
|
||||||
|
|
||||||
echo WAITING FOR PDB TO WRITE > lock.tmp
|
echo WAITING FOR PDB TO WRITE > lock.tmp
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ enum blend_mode
|
||||||
|
|
||||||
struct anim_layer
|
struct anim_layer
|
||||||
{
|
{
|
||||||
string Name;
|
gs_string Name;
|
||||||
blend_mode BlendMode;
|
blend_mode BlendMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ struct anim_layer
|
||||||
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
||||||
struct animation_system
|
struct animation_system
|
||||||
{
|
{
|
||||||
memory_arena* Storage;
|
gs_memory_arena* Storage;
|
||||||
|
|
||||||
gs_list<animation_block> Blocks;
|
gs_list<animation_block> Blocks;
|
||||||
anim_layer* Layers;
|
anim_layer* Layers;
|
||||||
|
@ -75,7 +75,7 @@ FrameIsInRange(s32 Frame, frame_range Range)
|
||||||
internal u32
|
internal u32
|
||||||
GetFrameCount(frame_range Range)
|
GetFrameCount(frame_range Range)
|
||||||
{
|
{
|
||||||
u32 Result = (u32)GSMax(0, Range.Max - Range.Min);
|
u32 Result = (u32)Max(0, Range.Max - Range.Min);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ RemoveAnimationBlock(gs_list_handle AnimationBlockHandle, animation_system* Anim
|
||||||
|
|
||||||
// Layers
|
// Layers
|
||||||
internal u32
|
internal u32
|
||||||
AddLayer (string Name, animation_system* AnimationSystem, blend_mode BlendMode = BlendMode_Overwrite)
|
AddLayer (gs_string Name, animation_system* AnimationSystem, blend_mode BlendMode = BlendMode_Overwrite)
|
||||||
{
|
{
|
||||||
// NOTE(Peter): If this assert fires its time to make the layer buffer system
|
// NOTE(Peter): If this assert fires its time to make the layer buffer system
|
||||||
// resizable.
|
// resizable.
|
||||||
|
@ -144,7 +144,7 @@ AddLayer (string Name, animation_system* AnimationSystem, blend_mode BlendMode =
|
||||||
anim_layer* NewLayer = AnimationSystem->Layers + Result;
|
anim_layer* NewLayer = AnimationSystem->Layers + Result;
|
||||||
*NewLayer = {0};
|
*NewLayer = {0};
|
||||||
NewLayer->Name = MakeString(PushArray(AnimationSystem->Storage, char, Name.Length), Name.Length);
|
NewLayer->Name = MakeString(PushArray(AnimationSystem->Storage, char, Name.Length), Name.Length);
|
||||||
CopyStringTo(Name, &NewLayer->Name);
|
PrintF(&NewLayer->Name, "%S", Name);
|
||||||
NewLayer->BlendMode = BlendMode;
|
NewLayer->BlendMode = BlendMode;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ enum assembly_field
|
||||||
AssemblyField_Count,
|
AssemblyField_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
global_variable char* AssemblyFieldIdentifiers[] = {
|
global char* AssemblyFieldIdentifiers[] = {
|
||||||
"assembly_name", // AssemblyField_AssemblyName
|
"assembly_name", // AssemblyField_AssemblyName
|
||||||
"assembly_scale", // AssemblyField_AssemblyScale
|
"assembly_scale", // AssemblyField_AssemblyScale
|
||||||
"led_strip_count", // AssemblyField_LedStripCount
|
"led_strip_count", // AssemblyField_LedStripCount
|
||||||
|
@ -52,20 +52,32 @@ global_variable char* AssemblyFieldIdentifiers[] = {
|
||||||
"value", // AssemblyField_Value
|
"value", // AssemblyField_Value
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct assembly_error_list
|
||||||
|
{
|
||||||
|
gs_string String;
|
||||||
|
assembly_error_list* Next;
|
||||||
|
};
|
||||||
|
|
||||||
struct assembly_tokenizer
|
struct assembly_tokenizer
|
||||||
{
|
{
|
||||||
string Text;
|
gs_string Text;
|
||||||
char* At;
|
char* At;
|
||||||
|
|
||||||
|
gs_const_string FileName;
|
||||||
u32 LineNumber;
|
u32 LineNumber;
|
||||||
|
|
||||||
bool ParsingIsValid;
|
bool ParsingIsValid;
|
||||||
|
|
||||||
|
gs_memory_arena* ErrorArena;
|
||||||
|
assembly_error_list* ErrorsRoot;
|
||||||
|
assembly_error_list* ErrorsTail;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal bool
|
internal bool
|
||||||
AtValidPosition(assembly_tokenizer* T)
|
AtValidPosition(assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
bool Result = ((T->At - T->Text.Memory) < T->Text.Length);
|
u64 Offset = T->At - T->Text.Str;
|
||||||
|
bool Result = (Offset < T->Text.Length);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +100,16 @@ EatWhitespace(assembly_tokenizer* T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
EatToNewLine(assembly_tokenizer* T)
|
||||||
|
{
|
||||||
|
while(AtValidPosition(T) && !IsNewline(T->At[0]))
|
||||||
|
{
|
||||||
|
AdvanceChar(T);
|
||||||
|
}
|
||||||
|
EatWhitespace(T);
|
||||||
|
}
|
||||||
|
|
||||||
internal bool
|
internal bool
|
||||||
AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
|
AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
|
||||||
{
|
{
|
||||||
|
@ -118,6 +140,22 @@ AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
TokenizerPushError(assembly_tokenizer* T, char* ErrorString)
|
||||||
|
{
|
||||||
|
// NOTE(Peter): We can make this more expressive if we need to
|
||||||
|
assembly_error_list* Error = PushStruct(T->ErrorArena, assembly_error_list);
|
||||||
|
Error->String = PushString(T->ErrorArena, 512);
|
||||||
|
PrintF(&Error->String, "%S(%d): %s", T->FileName, T->LineNumber, ErrorString);
|
||||||
|
SLLPushOrInit(T->ErrorsRoot, T->ErrorsTail, Error);
|
||||||
|
T->ParsingIsValid = false;
|
||||||
|
|
||||||
|
// NOTE(Peter): I'm not sure this is the best idea, but at least this way,
|
||||||
|
// if there's multiple errors, you'll get a number of them, rather than
|
||||||
|
// a bunch of erroneous errors happening on the same line
|
||||||
|
EatToNewLine(T);
|
||||||
|
}
|
||||||
|
|
||||||
internal bool
|
internal bool
|
||||||
ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
|
ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
|
@ -130,12 +168,12 @@ ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Field identifier is missing a colon");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Field Identifier Invalid");
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -150,15 +188,15 @@ ReadFieldEnd(assembly_tokenizer* T)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Missing a semicolon");
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string
|
internal gs_string
|
||||||
ReadString(assembly_tokenizer* T)
|
ReadString(assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
string Result = {};
|
gs_string Result = {};
|
||||||
if (AdvanceIfTokenEquals(T, "\""))
|
if (AdvanceIfTokenEquals(T, "\""))
|
||||||
{
|
{
|
||||||
char* StringStart = T->At;
|
char* StringStart = T->At;
|
||||||
|
@ -166,32 +204,36 @@ ReadString(assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
T->At++;
|
T->At++;
|
||||||
}
|
}
|
||||||
Result.Memory = StringStart;
|
Result.Str = StringStart;
|
||||||
Result.Max = T->At - StringStart;
|
Result.Size = T->At - StringStart;
|
||||||
Result.Length = Result.Max;
|
Result.Length = Result.Size;
|
||||||
if (AdvanceIfTokenEquals(T, "\""))
|
if (AdvanceIfTokenEquals(T, "\""))
|
||||||
{
|
{
|
||||||
// Success
|
// Success
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO(Peter): Error
|
TokenizerPushError(T, "String not closed with a \"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TokenizerPushError(T, "Expecting a string, but none was found");
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string
|
internal gs_string
|
||||||
GetNumberString(assembly_tokenizer* T)
|
GetNumberString(assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
string Result = {};
|
gs_string Result = {};
|
||||||
Result.Memory = T->At;
|
Result.Str = T->At;
|
||||||
while(AtValidPosition(T) && IsNumericExtended(T->At[0]))
|
while(AtValidPosition(T) && IsNumericExtended(T->At[0]))
|
||||||
{
|
{
|
||||||
AdvanceChar(T);
|
AdvanceChar(T);
|
||||||
}
|
}
|
||||||
Result.Length = T->At - Result.Memory;
|
Result.Length = T->At - Result.Str;
|
||||||
Result.Max = Result.Length;
|
Result.Size = Result.Length;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,9 +241,8 @@ internal r32
|
||||||
ReadFloat(assembly_tokenizer* T)
|
ReadFloat(assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
r32 Result = 0;
|
r32 Result = 0;
|
||||||
string NumberString = GetNumberString(T);
|
gs_string NumberString = GetNumberString(T);
|
||||||
parse_result ParsedFloat = ParseFloat(StringExpand(NumberString));
|
Result = (r32)ParseFloat(NumberString.ConstString);
|
||||||
Result = ParsedFloat.FloatValue;
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,28 +250,23 @@ internal s32
|
||||||
ReadInt(assembly_tokenizer* T)
|
ReadInt(assembly_tokenizer* T)
|
||||||
{
|
{
|
||||||
s32 Result = 0;
|
s32 Result = 0;
|
||||||
string NumberString = GetNumberString(T);
|
gs_string NumberString = GetNumberString(T);
|
||||||
parse_result ParsedInt = ParseSignedInt(StringExpand(NumberString));
|
Result = (r32)ParseInt(NumberString.ConstString);
|
||||||
Result = ParsedInt.SignedIntValue;
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string
|
internal gs_string
|
||||||
ReadStringField(assembly_field Field, assembly_tokenizer* T, memory_arena* Arena)
|
ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Arena)
|
||||||
{
|
{
|
||||||
string Result = {};
|
gs_string Result = {};
|
||||||
if (ReadFieldIdentifier(Field, T))
|
if (ReadFieldIdentifier(Field, T))
|
||||||
{
|
{
|
||||||
string ExistingString = ReadString(T);
|
gs_string ExistingString = ReadString(T);
|
||||||
if (ReadFieldEnd(T))
|
if (ReadFieldEnd(T))
|
||||||
{
|
{
|
||||||
// Success
|
// Success
|
||||||
Result = PushString(Arena, ExistingString.Length);
|
Result = PushString(Arena, ExistingString.Length);
|
||||||
CopyStringTo(ExistingString, &Result);
|
PrintF(&Result, "%S", ExistingString);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
T->ParsingIsValid = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -290,22 +326,22 @@ ReadV3Field(assembly_field Field, assembly_tokenizer* T)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Vector 3 doesn't end with a ')'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Vector 3: unable to read a field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Vector 3: unable to read a field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T->ParsingIsValid = false;
|
TokenizerPushError(T, "Vector 3: unable to read a field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -333,14 +369,18 @@ ReadStructClosing(assembly_tokenizer* T)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool
|
internal bool
|
||||||
ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
|
ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileText, gs_memory_arena* Transient)
|
||||||
{
|
{
|
||||||
Assembly->LedCountTotal = 0;
|
Assembly->LedCountTotal = 0;
|
||||||
|
|
||||||
|
r32 Value = ParseFloat(ConstString("-2.355"));
|
||||||
|
|
||||||
assembly_tokenizer Tokenizer = {};
|
assembly_tokenizer Tokenizer = {};
|
||||||
Tokenizer.Text = FileText;
|
Tokenizer.Text = FileText;
|
||||||
Tokenizer.At = Tokenizer.Text.Memory;
|
Tokenizer.At = Tokenizer.Text.Str;
|
||||||
Tokenizer.ParsingIsValid = true;
|
Tokenizer.ParsingIsValid = true;
|
||||||
|
Tokenizer.ErrorArena = Transient;
|
||||||
|
Tokenizer.FileName = FileName;
|
||||||
|
|
||||||
Assembly->Name = ReadStringField(AssemblyField_AssemblyName, &Tokenizer, &Assembly->Arena);
|
Assembly->Name = ReadStringField(AssemblyField_AssemblyName, &Tokenizer, &Assembly->Arena);
|
||||||
Assembly->Scale = ReadFloatField(AssemblyField_AssemblyScale, &Tokenizer);
|
Assembly->Scale = ReadFloatField(AssemblyField_AssemblyScale, &Tokenizer);
|
||||||
|
@ -358,7 +398,7 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
|
||||||
StripAt->StartChannel = ReadIntField(AssemblyField_StartChannel, &Tokenizer);
|
StripAt->StartChannel = ReadIntField(AssemblyField_StartChannel, &Tokenizer);
|
||||||
|
|
||||||
// TODO(Peter): Need to store this
|
// TODO(Peter): Need to store this
|
||||||
string PointPlacementType = ReadStringField(AssemblyField_PointPlacementType, &Tokenizer, &Assembly->Arena);
|
gs_string PointPlacementType = ReadStringField(AssemblyField_PointPlacementType, &Tokenizer, &Assembly->Arena);
|
||||||
// TODO(Peter): Switch on value of PointPlacementType
|
// TODO(Peter): Switch on value of PointPlacementType
|
||||||
if (ReadStructOpening(AssemblyField_InterpolatePoints, &Tokenizer))
|
if (ReadStructOpening(AssemblyField_InterpolatePoints, &Tokenizer))
|
||||||
{
|
{
|
||||||
|
@ -367,6 +407,10 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
|
||||||
if (!ReadStructClosing(&Tokenizer))
|
if (!ReadStructClosing(&Tokenizer))
|
||||||
{
|
{
|
||||||
Tokenizer.ParsingIsValid = false;
|
Tokenizer.ParsingIsValid = false;
|
||||||
|
// TODO(Peter): @ErrorHandling
|
||||||
|
// Have this function prepend the filename and line number.
|
||||||
|
// Create an error display popup window, or an error log window that takes over a panel automatically
|
||||||
|
// TokenizerPushError(&Tokenizer, "Unable to read
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,31 +424,31 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
|
||||||
v2_tag* TagAt = StripAt->Tags + Tag;
|
v2_tag* TagAt = StripAt->Tags + Tag;
|
||||||
if (ReadStructOpening(AssemblyField_Tag, &Tokenizer))
|
if (ReadStructOpening(AssemblyField_Tag, &Tokenizer))
|
||||||
{
|
{
|
||||||
// TODO(Peter): Need to store the string somewhere we can look it up for display in the interface
|
// TODO(Peter): Need to store the gs_string somewhere we can look it up for display in the interface
|
||||||
// right now they are stored in temp memory and won't persist
|
// right now they are stored in temp memory and won't persist
|
||||||
string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient);
|
gs_string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient);
|
||||||
string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient);
|
gs_string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient);
|
||||||
TagAt->NameHash = HashString(TagName);
|
TagAt->NameHash = HashDJB2ToU32(StringExpand(TagName));
|
||||||
TagAt->ValueHash = HashString(TagValue);
|
TagAt->ValueHash = HashDJB2ToU32(StringExpand(TagValue));
|
||||||
if (!ReadStructClosing(&Tokenizer))
|
if (!ReadStructClosing(&Tokenizer))
|
||||||
{
|
{
|
||||||
Tokenizer.ParsingIsValid = false;
|
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Tokenizer.ParsingIsValid = false;
|
TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ReadStructClosing(&Tokenizer))
|
if (!ReadStructClosing(&Tokenizer))
|
||||||
{
|
{
|
||||||
Tokenizer.ParsingIsValid = false;
|
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Tokenizer.ParsingIsValid = false;
|
TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,10 +100,10 @@ NODE_PROC(SinWave, sin_wave_data)
|
||||||
Data->Accumulator -= Data->Period;
|
Data->Accumulator -= Data->Period;
|
||||||
}
|
}
|
||||||
|
|
||||||
r32 ActualMin = GSMin(Data->Min, Data->Max);
|
r32 ActualMin = Min(Data->Min, Data->Max);
|
||||||
r32 ActualMax = GSMax(Data->Min, Data->Max);
|
r32 ActualMax = Max(Data->Min, Data->Max);
|
||||||
r32 SinResult = GSSin((Data->Accumulator / Data->Period) * PI * 2);
|
r32 SinResult = SinR32((Data->Accumulator / Data->Period) * PiR32 * 2);
|
||||||
Data->Result = GSRemap(SinResult, -1.f, 1.f, ActualMin, ActualMax);
|
Data->Result = RemapR32(SinResult, -1.f, 1.f, ActualMin, ActualMax);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
|
@ -15,7 +15,7 @@ struct visual_port
|
||||||
{
|
{
|
||||||
gs_list_handle SparseNodeHandle;
|
gs_list_handle SparseNodeHandle;
|
||||||
u32 PortIndex;
|
u32 PortIndex;
|
||||||
rect PortBounds;
|
rect2 PortBounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct visual_connection
|
struct visual_connection
|
||||||
|
@ -57,7 +57,7 @@ struct node_graph_state
|
||||||
{
|
{
|
||||||
v2 ViewOffset;
|
v2 ViewOffset;
|
||||||
|
|
||||||
memory_arena LayoutMemory;
|
gs_memory_arena LayoutMemory;
|
||||||
node_layout Layout;
|
node_layout Layout;
|
||||||
|
|
||||||
b32 LayoutIsDirty;
|
b32 LayoutIsDirty;
|
||||||
|
@ -128,7 +128,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndConnectNodesOperation)
|
||||||
for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; p++)
|
for (u32 p = 0; p < GraphState->Layout.VisualPortsCount; p++)
|
||||||
{
|
{
|
||||||
visual_port VisualPort = GraphState->Layout.VisualPorts[p];
|
visual_port VisualPort = GraphState->Layout.VisualPorts[p];
|
||||||
rect ViewAdjustedBounds = gs_RectOffsetByVector(VisualPort.PortBounds, GraphState->ViewOffset);
|
rect2 ViewAdjustedBounds = gs_RectOffsetByVector(VisualPort.PortBounds, GraphState->ViewOffset);
|
||||||
if (gs_PointIsInRect(Mouse.Pos, ViewAdjustedBounds))
|
if (gs_PointIsInRect(Mouse.Pos, ViewAdjustedBounds))
|
||||||
{
|
{
|
||||||
visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort;
|
visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort;
|
||||||
|
@ -196,7 +196,7 @@ NodeGraph_Cleanup(panel* Panel, app_state* State)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer* RenderBuffer)
|
DrawGrid (v2 Offset, v2 GridSquareDim, rect2 PanelBounds, render_command_buffer* RenderBuffer)
|
||||||
{
|
{
|
||||||
r32 LineValue = .16f;
|
r32 LineValue = .16f;
|
||||||
v4 LineColor = v4{LineValue, LineValue, LineValue, 1.f};
|
v4 LineColor = v4{LineValue, LineValue, LineValue, 1.f};
|
||||||
|
@ -232,9 +232,9 @@ DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer*
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position, r32 LineHeight, string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse)
|
DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position, r32 LineHeight, gs_string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
rect PortBounds = rect{v2{0, 0}, v2{6, 6}};
|
rect2 PortBounds = rect2{v2{0, 0}, v2{6, 6}};
|
||||||
|
|
||||||
v2 LinePosition = Position;
|
v2 LinePosition = Position;
|
||||||
for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
|
for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
|
||||||
|
@ -244,7 +244,7 @@ DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position,
|
||||||
{
|
{
|
||||||
// TODO(Peter): Can we make this rely on the same data that we use to
|
// TODO(Peter): Can we make this rely on the same data that we use to
|
||||||
// render the actual connection points?
|
// render the actual connection points?
|
||||||
string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
|
gs_string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
|
||||||
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign);
|
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign);
|
||||||
LinePosition.y -= LineHeight;
|
LinePosition.y -= LineHeight;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle NodeHandle, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse, memory_arena* Scratch)
|
DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle NodeHandle, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse, gs_memory_arena* Scratch)
|
||||||
{
|
{
|
||||||
gsm_struct_type_info NodeDataTypeInfo = StructTypes[NodeSpecification.DataType];
|
gsm_struct_type_info NodeDataTypeInfo = StructTypes[NodeSpecification.DataType];
|
||||||
|
|
||||||
|
@ -264,13 +264,13 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
|
||||||
if (MemberIsInput(Member)) { InputMembers++; }
|
if (MemberIsInput(Member)) { InputMembers++; }
|
||||||
if (MemberIsOutput(Member)) { OutputMembers++; }
|
if (MemberIsOutput(Member)) { OutputMembers++; }
|
||||||
}
|
}
|
||||||
u32 LineCount = 1 + GSMax(InputMembers, OutputMembers);
|
u32 LineCount = 1 + Max(InputMembers, OutputMembers);
|
||||||
|
|
||||||
v2 NodeDim = v2{
|
v2 NodeDim = v2{
|
||||||
NodeWidth,
|
NodeWidth,
|
||||||
(LineHeight * LineCount) + Interface.Margin.y,
|
(LineHeight * LineCount) + Interface.Margin.y,
|
||||||
};
|
};
|
||||||
rect NodeBounds = rect{
|
rect2 NodeBounds = rect2{
|
||||||
v2{ Position.x, Position.y - NodeDim.y },
|
v2{ Position.x, Position.y - NodeDim.y },
|
||||||
v2{ Position.x + NodeDim.x, Position.y },
|
v2{ Position.x + NodeDim.x, Position.y },
|
||||||
};
|
};
|
||||||
|
@ -282,7 +282,7 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f});
|
PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f});
|
||||||
|
|
||||||
string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256);
|
gs_string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256);
|
||||||
PrintF(&NodePrintName, "%S [%d]", NodeSpecification.Identifier, NodeHandle.Index);
|
PrintF(&NodePrintName, "%S [%d]", NodeSpecification.Identifier, NodeHandle.Index);
|
||||||
DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4);
|
DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4);
|
||||||
LinePosition.y -= LineHeight;
|
LinePosition.y -= LineHeight;
|
||||||
|
@ -293,7 +293,7 @@ DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle Nod
|
||||||
for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
|
for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
|
||||||
{
|
{
|
||||||
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i];
|
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i];
|
||||||
string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
|
gs_string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
|
||||||
|
|
||||||
// TODO(Peter): Can we make this rely on the same data that we use to
|
// TODO(Peter): Can we make this rely on the same data that we use to
|
||||||
// render the actual connection points?
|
// render the actual connection points?
|
||||||
|
@ -329,7 +329,7 @@ GetVisualPortIndexForNode(gs_list_handle SparseNodeHandle, u32 PortIndex, node_l
|
||||||
}
|
}
|
||||||
|
|
||||||
internal node_layout
|
internal node_layout
|
||||||
ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, r32 LineHeight, memory_arena* Storage, app_state* State)
|
ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, r32 LineHeight, gs_memory_arena* Storage, app_state* State)
|
||||||
{
|
{
|
||||||
node_layout Result = {};
|
node_layout Result = {};
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
|
||||||
{
|
{
|
||||||
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p];
|
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p];
|
||||||
|
|
||||||
rect PortBounds = {0};
|
rect2 PortBounds = {0};
|
||||||
v2 PortDim = v2{8, 8};
|
v2 PortDim = v2{8, 8};
|
||||||
PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2};
|
PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2};
|
||||||
if (MemberIsInput(Member))
|
if (MemberIsInput(Member))
|
||||||
|
@ -420,16 +420,16 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_node_graph);
|
GSMetaTag(panel_type_node_graph);
|
||||||
internal void
|
internal void
|
||||||
NodeGraph_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
NodeGraph_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
node_graph_state* GraphState = (node_graph_state*)Panel.PanelStateMemory;
|
node_graph_state* GraphState = (node_graph_state*)Panel.PanelStateMemory;
|
||||||
b32 MouseHandled = false;
|
b32 MouseHandled = false;
|
||||||
|
|
||||||
rect NodeSelectionWindowBounds = rect{
|
rect2 NodeSelectionWindowBounds = rect2{
|
||||||
PanelBounds.Min,
|
PanelBounds.Min,
|
||||||
v2{PanelBounds.Min.x + 300, PanelBounds.Max.y},
|
v2{PanelBounds.Min.x + 300, PanelBounds.Max.y},
|
||||||
};
|
};
|
||||||
rect GraphBounds = rect{
|
rect2 GraphBounds = rect2{
|
||||||
v2{NodeSelectionWindowBounds.Max.x, PanelBounds.Min.y},
|
v2{NodeSelectionWindowBounds.Max.x, PanelBounds.Min.y},
|
||||||
PanelBounds.Max,
|
PanelBounds.Max,
|
||||||
};
|
};
|
||||||
|
@ -513,18 +513,18 @@ NodeGraph_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
|
||||||
List.TextColor = WhiteV4;
|
List.TextColor = WhiteV4;
|
||||||
List.ListBounds = NodeSelectionWindowBounds;
|
List.ListBounds = NodeSelectionWindowBounds;
|
||||||
List.ListElementDimensions = v2{
|
List.ListElementDimensions = v2{
|
||||||
gs_Width(NodeSelectionWindowBounds),
|
Rect2Width(NodeSelectionWindowBounds),
|
||||||
ui_GetTextLineHeight(State->Interface)
|
ui_GetTextLineHeight(State->Interface)
|
||||||
};
|
};
|
||||||
List.ElementLabelIndent = v2{10, 4};
|
List.ElementLabelIndent = v2{10, 4};
|
||||||
|
|
||||||
string TitleString = MakeStringLiteral("Available Nodes");
|
gs_string Titlegs_string = MakeStringLiteral("Available Nodes");
|
||||||
DrawListElement(TitleString, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
|
DrawListElement(Titlegs_string, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
|
||||||
|
|
||||||
for (u32 i = 0; i < NodeType_Count; i++)
|
for (u32 i = 0; i < NodeType_Count; i++)
|
||||||
{
|
{
|
||||||
node_specification_ Spec = NodeSpecifications[i];
|
node_specification_ Spec = NodeSpecifications[i];
|
||||||
rect ElementBounds = DrawListElement(Spec.Identifier, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
|
rect2 ElementBounds = DrawListElement(Spec.Identifier, &List, Context.Mouse, RenderBuffer, State->Interface.Style);
|
||||||
|
|
||||||
if (MouseButtonTransitionedDown(Context.Mouse.LeftButtonState)
|
if (MouseButtonTransitionedDown(Context.Mouse.LeftButtonState)
|
||||||
&& gs_PointIsInRect(Context.Mouse.DownPos, ElementBounds))
|
&& gs_PointIsInRect(Context.Mouse.DownPos, ElementBounds))
|
|
@ -6,7 +6,7 @@
|
||||||
#ifndef FOLDHAUS_SEARCH_LISTER_CPP
|
#ifndef FOLDHAUS_SEARCH_LISTER_CPP
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
NamePassesFilter (string Target, string Filter)
|
NamePassesFilter (gs_string Target, gs_string Filter)
|
||||||
{
|
{
|
||||||
return (Filter.Length == 0 || StringContainsStringCaseInsensitive(Target, Filter));
|
return (Filter.Length == 0 || StringContainsStringCaseInsensitive(Target, Filter));
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@ FilterSearchLister (search_lister* SearchLister)
|
||||||
|
|
||||||
for (s32 i = 0; i < SearchLister->SourceListCount; i++)
|
for (s32 i = 0; i < SearchLister->SourceListCount; i++)
|
||||||
{
|
{
|
||||||
string* NameString = SearchLister->SourceList + i;
|
gs_string* Namegs_string = SearchLister->SourceList + i;
|
||||||
if (NamePassesFilter(*NameString, SearchLister->Filter))
|
if (NamePassesFilter(*Namegs_string, SearchLister->Filter))
|
||||||
{
|
{
|
||||||
SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i;
|
SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchLister->HotItem = GSClamp(0, SearchLister->HotItem, SearchLister->FilteredListCount - 1);
|
SearchLister->HotItem = Clamp(0, SearchLister->HotItem, SearchLister->FilteredListCount - 1);
|
||||||
|
|
||||||
if (SearchLister->FilteredListCount == 0)
|
if (SearchLister->FilteredListCount == 0)
|
||||||
{
|
{
|
||||||
|
@ -39,14 +39,14 @@ FilterSearchLister (search_lister* SearchLister)
|
||||||
internal s32
|
internal s32
|
||||||
GetNextFilteredItem (search_lister SearchLister)
|
GetNextFilteredItem (search_lister SearchLister)
|
||||||
{
|
{
|
||||||
s32 Result = GSMin(SearchLister.HotItem + 1, SearchLister.FilteredListCount - 1);
|
s32 Result = Min(SearchLister.HotItem + 1, SearchLister.FilteredListCount - 1);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
internal s32
|
||||||
GetPrevFilteredItem (search_lister SearchLister)
|
GetPrevFilteredItem (search_lister SearchLister)
|
||||||
{
|
{
|
||||||
s32 Result = GSMax(SearchLister.HotItem - 1, 0);
|
s32 Result = Max(SearchLister.HotItem - 1, 0);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
struct search_lister
|
struct search_lister
|
||||||
{
|
{
|
||||||
// TODO(Peter): Giving up trying to just use the source list for now. At the moment
|
// TODO(Peter): Giving up trying to just use the source list for now. At the moment
|
||||||
// we are copying the strings you want to filter from and storing them here. Come back
|
// we are copying the gs_strings you want to filter from and storing them here. Come back
|
||||||
// once its working and make the memory efficient version (ie store the existing memory
|
// once its working and make the memory efficient version (ie store the existing memory
|
||||||
// location, the element stride and the offset to the char*)
|
// location, the element stride and the offset to the char*)
|
||||||
s32 SourceListCount;
|
s32 SourceListCount;
|
||||||
string* SourceList;
|
gs_string* SourceList;
|
||||||
|
|
||||||
// NOTE(Peter): stores the source indecies of each filtered item
|
// NOTE(Peter): stores the source indecies of each filtered item
|
||||||
// For example:
|
// For example:
|
||||||
|
@ -23,7 +23,7 @@ struct search_lister
|
||||||
s32* FilteredIndexLUT;
|
s32* FilteredIndexLUT;
|
||||||
s32 HotItem;
|
s32 HotItem;
|
||||||
|
|
||||||
string Filter;
|
gs_string Filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,14 @@ PipeSearchStringToDestination (text_entry* Input)
|
||||||
{
|
{
|
||||||
switch (Input->Destination.Type)
|
switch (Input->Destination.Type)
|
||||||
{
|
{
|
||||||
case TextTranslateTo_String:
|
case TextTranslateTo_gs_string:
|
||||||
{
|
{
|
||||||
CopyStringTo(Input->Buffer, Input->Destination.StringDest);
|
PrintF(Input->Destination.StringDest, "%S", Input->Buffer);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case TextTranslateTo_R32:
|
case TextTranslateTo_R32:
|
||||||
{
|
{
|
||||||
parse_result FloatParseResult = ParseFloat(StringExpand(Input->Buffer));
|
*Input->Destination.FloatDest = (r32)ParseFloat(Input->Buffer.ConstString);
|
||||||
*Input->Destination.FloatDest = FloatParseResult.FloatValue;
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
InvalidDefaultCase;
|
InvalidDefaultCase;
|
||||||
|
@ -37,19 +36,22 @@ RemoveCharacterAtCursor (text_entry* TextEntry)
|
||||||
{
|
{
|
||||||
if (TextEntry->CursorPosition > 0)
|
if (TextEntry->CursorPosition > 0)
|
||||||
{
|
{
|
||||||
RemoveCharAt(&TextEntry->Buffer,
|
for (u32 i = TextEntry->CursorPosition - 1; i < TextEntry->Buffer.Length; i++)
|
||||||
TextEntry->CursorPosition - 1);
|
{
|
||||||
|
Assert(i + 1 < TextEntry->Buffer.Size);
|
||||||
|
TextEntry->Buffer.Str[i] = TextEntry->Buffer.Str[i + 1];
|
||||||
|
}
|
||||||
TextEntry->CursorPosition--;
|
TextEntry->CursorPosition--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
SetTextInputDestinationToString (text_entry* TextInput, string* DestinationString)
|
SetTextInputDestinationToString (text_entry* TextInput, gs_string* DestinationString)
|
||||||
{
|
{
|
||||||
ResetTextInput(TextInput);
|
ResetTextInput(TextInput);
|
||||||
TextInput->Destination.Type = TextTranslateTo_String;
|
TextInput->Destination.Type = TextTranslateTo_gs_string;
|
||||||
TextInput->Destination.StringDest = DestinationString;
|
TextInput->Destination.StringDest = DestinationString;
|
||||||
CopyStringTo(*DestinationString, &TextInput->Buffer);
|
PrintF(&TextInput->Buffer, "%S", *DestinationString);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -69,14 +71,13 @@ SetTextInputDestinationToFloat (text_entry* TextInput, r32* DestinationFloat)
|
||||||
internal void
|
internal void
|
||||||
MoveCursorRight (text_entry* TextEntry)
|
MoveCursorRight (text_entry* TextEntry)
|
||||||
{
|
{
|
||||||
TextEntry->CursorPosition = GSMin(TextEntry->Buffer.Length,
|
TextEntry->CursorPosition = Min(TextEntry->Buffer.Length, TextEntry->CursorPosition + 1);
|
||||||
TextEntry->CursorPosition + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
MoveCursorLeft (text_entry* TextEntry)
|
MoveCursorLeft (text_entry* TextEntry)
|
||||||
{
|
{
|
||||||
TextEntry->CursorPosition = GSMax(0, TextEntry->CursorPosition - 1);
|
TextEntry->CursorPosition = Max(0, TextEntry->CursorPosition - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar)
|
FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar)
|
||||||
|
@ -88,12 +89,21 @@ FOLDHAUS_INPUT_COMMAND_PROC(TextEntryInsertChar)
|
||||||
Char += ('a' - 'A');
|
Char += ('a' - 'A');
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertChar(&State->ActiveTextEntry.Buffer, Char, State->ActiveTextEntry.CursorPosition);
|
// Shift string forward
|
||||||
|
Assert(State->ActiveTextEntry.Buffer.Length < State->ActiveTextEntry.Buffer.Size);
|
||||||
|
for (u32 i = State->ActiveTextEntry.Buffer.Length;
|
||||||
|
i > (u32)State->ActiveTextEntry.CursorPosition;
|
||||||
|
i--)
|
||||||
|
{
|
||||||
|
State->ActiveTextEntry.Buffer.Str[i] = State->ActiveTextEntry.Buffer.Str[i - 1];
|
||||||
|
}
|
||||||
|
// Insert new Character
|
||||||
|
State->ActiveTextEntry.Buffer.Str[State->ActiveTextEntry.CursorPosition] = Char;
|
||||||
State->ActiveTextEntry.CursorPosition++;
|
State->ActiveTextEntry.CursorPosition++;
|
||||||
PipeSearchStringToDestination(&State->ActiveTextEntry);
|
PipeSearchStringToDestination(&State->ActiveTextEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntryString)
|
FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntrygs_string)
|
||||||
{
|
{
|
||||||
RemoveCharacterAtCursor(&State->ActiveTextEntry);
|
RemoveCharacterAtCursor(&State->ActiveTextEntry);
|
||||||
}
|
}
|
||||||
|
@ -109,11 +119,11 @@ FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
InitializeTextInputCommands (input_command_registry* Commands, memory_arena* PermanentStorage)
|
InitializeTextInputCommands (input_command_registry* Commands, gs_memory_arena* PermanentStorage)
|
||||||
{
|
{
|
||||||
if (Commands->Size > 0)
|
if (Commands->Size > 0)
|
||||||
{
|
{
|
||||||
RegisterKeyPressCommand(Commands, KeyCode_Backspace, Command_Began | Command_Held, KeyCode_Invalid, RemoveCharacterFromEntryString);
|
RegisterKeyPressCommand(Commands, KeyCode_Backspace, Command_Began | Command_Held, KeyCode_Invalid, RemoveCharacterFromEntrygs_string);
|
||||||
RegisterKeyPressCommand(Commands, KeyCode_LeftArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorLeft);
|
RegisterKeyPressCommand(Commands, KeyCode_LeftArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorLeft);
|
||||||
RegisterKeyPressCommand(Commands, KeyCode_RightArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorRight);
|
RegisterKeyPressCommand(Commands, KeyCode_RightArrow, Command_Began | Command_Held, KeyCode_Invalid, TextEntryMoveCursorRight);
|
||||||
|
|
||||||
|
@ -126,7 +136,7 @@ InitializeTextInputCommands (input_command_registry* Commands, memory_arena* Per
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY \
|
#define DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY \
|
||||||
{ KeyCode_Backspace, KeyCode_Invalid, Command_Began | Command_Held, RemoveCharacterFromEntryString }, \
|
{ KeyCode_Backspace, KeyCode_Invalid, Command_Began | Command_Held, RemoveCharacterFromEntrygs_string }, \
|
||||||
{ KeyCode_LeftArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorLeft }, \
|
{ KeyCode_LeftArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorLeft }, \
|
||||||
{ KeyCode_RightArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorRight }, \
|
{ KeyCode_RightArrow, KeyCode_Invalid, Command_Began | Command_Held, TextEntryMoveCursorRight }, \
|
||||||
{ KeyCode_a, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \
|
{ KeyCode_a, KeyCode_Invalid, Command_Began | Command_Held, TextEntryInsertChar }, \
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
enum text_translation_type
|
enum text_translation_type
|
||||||
{
|
{
|
||||||
TextTranslateTo_String,
|
TextTranslateTo_gs_string,
|
||||||
TextTranslateTo_R32,
|
TextTranslateTo_R32,
|
||||||
TextTranslateTo_S32,
|
TextTranslateTo_S32,
|
||||||
TextTranslateTo_U32,
|
TextTranslateTo_U32,
|
||||||
|
@ -17,7 +17,7 @@ struct text_entry_destination
|
||||||
{
|
{
|
||||||
text_translation_type Type;
|
text_translation_type Type;
|
||||||
union {
|
union {
|
||||||
string* StringDest;
|
gs_string* StringDest;
|
||||||
r32* FloatDest;
|
r32* FloatDest;
|
||||||
s32* SignedIntDest;
|
s32* SignedIntDest;
|
||||||
u32* UnsignedIntDest;
|
u32* UnsignedIntDest;
|
||||||
|
@ -26,7 +26,7 @@ struct text_entry_destination
|
||||||
|
|
||||||
struct text_entry
|
struct text_entry
|
||||||
{
|
{
|
||||||
string Buffer;
|
gs_string Buffer;
|
||||||
s32 CursorPosition;
|
s32 CursorPosition;
|
||||||
|
|
||||||
text_entry_destination Destination;
|
text_entry_destination Destination;
|
|
@ -18,7 +18,7 @@ struct node_lister_operation_state
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderNodeLister(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
RenderNodeLister(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory;
|
node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
|
||||||
node_lister_operation_state);
|
node_lister_operation_state);
|
||||||
{
|
{
|
||||||
OpState->SearchLister.SourceListCount = NodeSpecificationsCount;
|
OpState->SearchLister.SourceListCount = NodeSpecificationsCount;
|
||||||
OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, string, OpState->SearchLister.SourceListCount);
|
OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, gs_string, OpState->SearchLister.SourceListCount);
|
||||||
{
|
{
|
||||||
for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++)
|
for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +107,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
|
||||||
}
|
}
|
||||||
|
|
||||||
OpState->ListPosition = Mouse.Pos;
|
OpState->ListPosition = Mouse.Pos;
|
||||||
SetTextInputDestinationToString(&State->ActiveTextEntry, &OpState->SearchLister.Filter);
|
SetTextInputDestinationTogs_string(&State->ActiveTextEntry, &OpState->SearchLister.Filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
@ -133,7 +133,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(CloseColorPickerCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderColorPicker(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
RenderColorPicker(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
color_picker_operation_state* OpState = (color_picker_operation_state*)Operation.OpStateMemory;
|
color_picker_operation_state* OpState = (color_picker_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ struct drag_node_port_operation_state
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderDraggingNodePort(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
RenderDraggingNodePort(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
drag_node_port_operation_state* OpState = (drag_node_port_operation_state*)Operation.OpStateMemory;
|
drag_node_port_operation_state* OpState = (drag_node_port_operation_state*)Operation.OpStateMemory;
|
||||||
UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList,
|
UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList,
|
||||||
|
@ -242,7 +242,7 @@ BeginDraggingNodePort(app_state* State, node_interaction Interaction)
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderDragNodeField(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
RenderDragNodeField(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
// TODO(Peter):
|
// TODO(Peter):
|
||||||
//UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State);
|
//UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State);
|
||||||
|
@ -266,7 +266,7 @@ struct drag_node_operation_state
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderDraggingNode(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
RenderDraggingNode(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
drag_node_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_operation_state);
|
drag_node_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_operation_state);
|
||||||
UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList,
|
UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList,
|
||||||
|
@ -368,7 +368,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
RenderNodeView(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBufer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory;
|
node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
{
|
{
|
||||||
node_header* Node = NodeIter.At;
|
node_header* Node = NodeIter.At;
|
||||||
|
|
||||||
rect NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings);
|
rect2 NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings);
|
||||||
b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds);
|
b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds);
|
||||||
|
|
||||||
if (Node == SelectedNode)
|
if (Node == SelectedNode)
|
||||||
|
@ -394,8 +394,8 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f});
|
PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f});
|
||||||
|
|
||||||
// TODO(Peter): This is just for debug purposes. We can remove and go back to just having
|
// TODO(Peter): This is just for debug purposes. We can remove and go back to just having
|
||||||
// Node->Name in DrawString
|
// Node->Name in Drawgs_string
|
||||||
string NodeName = GetNodeName(*Node);
|
gs_string NodeName = GetNodeName(*Node);
|
||||||
PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle);
|
PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle);
|
||||||
DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font,
|
DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font,
|
||||||
v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)},
|
v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)},
|
||||||
|
@ -408,7 +408,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
// Inputs
|
// Inputs
|
||||||
if (ConnectionIsInput(Node, Connection))
|
if (ConnectionIsInput(Node, Connection))
|
||||||
{
|
{
|
||||||
rect PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings);
|
rect2 PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
DrawPort(RenderBuffer, PortBounds, PortColor);
|
DrawPort(RenderBuffer, PortBounds, PortColor);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -427,7 +427,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right);
|
v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
rect ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings);
|
rect2 ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
||||||
|
|
||||||
// NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship,
|
// NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship,
|
||||||
|
@ -436,7 +436,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
// most downstream node and working back up to find dependencies.
|
// most downstream node and working back up to find dependencies.
|
||||||
if (ConnectionHasUpstreamConnection(Node, Connection))
|
if (ConnectionHasUpstreamConnection(Node, Connection))
|
||||||
{
|
{
|
||||||
rect ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings);
|
rect2 ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings);
|
||||||
v2 InputCenter = CalculateRectCenter(PortBounds);
|
v2 InputCenter = CalculateRectCenter(PortBounds);
|
||||||
v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds);
|
v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds);
|
||||||
PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4);
|
PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4);
|
||||||
|
@ -446,7 +446,7 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
// Outputs
|
// Outputs
|
||||||
if (ConnectionIsOutput(Node, Connection))
|
if (ConnectionIsOutput(Node, Connection))
|
||||||
{
|
{
|
||||||
rect PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings);
|
rect2 PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
DrawPort(RenderBuffer, PortBounds, PortColor);
|
DrawPort(RenderBuffer, PortBounds, PortColor);
|
||||||
|
|
||||||
if (DrawFields)
|
if (DrawFields)
|
||||||
|
@ -458,13 +458,13 @@ RenderNodeView(panel Panel, rect PanelBounds, render_command_buffer* RenderBufer
|
||||||
v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4);
|
v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4);
|
||||||
}
|
}
|
||||||
|
|
||||||
rect ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings);
|
rect2 ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 Button = 0; Button < 3; Button++)
|
for (s32 Button = 0; Button < 3; Button++)
|
||||||
{
|
{
|
||||||
rect ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings);
|
rect2 ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings);
|
||||||
PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]);
|
PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,27 +8,6 @@
|
||||||
#include "foldhaus_platform.h"
|
#include "foldhaus_platform.h"
|
||||||
#include "foldhaus_app.h"
|
#include "foldhaus_app.h"
|
||||||
|
|
||||||
internal v4
|
|
||||||
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
|
|
||||||
{
|
|
||||||
DEBUG_TRACK_SCOPE(MouseToWorldRay);
|
|
||||||
r32 X = ((2.0f * MouseX) / gs_Width(WindowBounds)) - 1;
|
|
||||||
r32 Y = ((2.0f * MouseY) / gs_Height(WindowBounds)) - 1;
|
|
||||||
|
|
||||||
v4 ScreenPos = v4{X, Y, -1, 1};
|
|
||||||
|
|
||||||
m44 InverseProjection = {};
|
|
||||||
Inverse(GetCameraPerspectiveProjectionMatrix(*Camera), &InverseProjection);
|
|
||||||
|
|
||||||
m44 InverseModelView = {};
|
|
||||||
Inverse(GetCameraModelViewMatrix(*Camera), &InverseModelView);
|
|
||||||
InverseModelView = Transpose(InverseModelView);
|
|
||||||
|
|
||||||
v4 ClipSpacePos = InverseProjection * ScreenPos;
|
|
||||||
v4 WorldPosition = InverseModelView * ClipSpacePos;
|
|
||||||
return WorldPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct send_sacn_job_data
|
struct send_sacn_job_data
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -72,11 +51,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
app_state* State = (app_state*)Context.MemoryBase;
|
app_state* State = (app_state*)Context.MemoryBase;
|
||||||
*State = {};
|
*State = {};
|
||||||
|
|
||||||
State->Permanent = {};
|
State->Permanent = CreateMemoryArena(Context.ThreadContext.Allocator);
|
||||||
State->Permanent.PlatformMemory = Context.PlatformMemory;
|
State->Transient = CreateMemoryArena(Context.ThreadContext.Allocator);
|
||||||
State->Transient = {};
|
|
||||||
State->Transient.FindAddressRule = FindAddress_InLastBufferOnly;
|
|
||||||
State->Transient.PlatformMemory = Context.PlatformMemory;
|
|
||||||
|
|
||||||
State->Assemblies.CountMax = 8;
|
State->Assemblies.CountMax = 8;
|
||||||
State->Assemblies.Values = PushArray(&State->Permanent, assembly, State->Assemblies.CountMax);
|
State->Assemblies.Values = PushArray(&State->Permanent, assembly, State->Assemblies.CountMax);
|
||||||
|
@ -90,13 +66,11 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
CommandQueueSize);
|
CommandQueueSize);
|
||||||
State->CommandQueue = InitializeCommandQueue(CommandQueueMemory, CommandQueueSize);
|
State->CommandQueue = InitializeCommandQueue(CommandQueueMemory, CommandQueueSize);
|
||||||
|
|
||||||
State->ActiveTextEntry.Buffer = MakeString(PushArray(&State->Permanent, char, 256), 0, 256);
|
|
||||||
|
|
||||||
// TODO(Peter): put in InitializeInterface?
|
// TODO(Peter): put in InitializeInterface?
|
||||||
r32 FontSize = 14;
|
r32 FontSize = 14;
|
||||||
{
|
{
|
||||||
platform_memory_result FontFile = ReadEntireFile(Context, MakeStringLiteral("data/Anonymous Pro.ttf"));
|
gs_file FontFile = ReadEntireFile(Context.ThreadContext.FileHandler, ConstString("data/Anonymous Pro.ttf"));
|
||||||
if (!FontFile.Error)
|
if (FileNoError(FontFile))
|
||||||
{
|
{
|
||||||
bitmap_font* Font = PushStruct(&State->Permanent, bitmap_font);
|
bitmap_font* Font = PushStruct(&State->Permanent, bitmap_font);
|
||||||
|
|
||||||
|
@ -105,7 +79,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
Font->BitmapBytesPerPixel = 4;
|
Font->BitmapBytesPerPixel = 4;
|
||||||
Font->BitmapMemory = PushArray(&State->Permanent, u8, Font->BitmapWidth * Font->BitmapHeight * Font->BitmapBytesPerPixel);
|
Font->BitmapMemory = PushArray(&State->Permanent, u8, Font->BitmapWidth * Font->BitmapHeight * Font->BitmapBytesPerPixel);
|
||||||
Font->BitmapStride = Font->BitmapWidth * Font->BitmapBytesPerPixel;
|
Font->BitmapStride = Font->BitmapWidth * Font->BitmapBytesPerPixel;
|
||||||
GSMemSet(Font->BitmapMemory, 0, Font->BitmapStride * Font->BitmapHeight);
|
ZeroMemoryBlock(Font->BitmapMemory, Font->BitmapStride * Font->BitmapHeight);
|
||||||
|
|
||||||
platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize, FontWeight_Normal, false, false, false);
|
platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize, FontWeight_Normal, false, false, false);
|
||||||
Font->PixelHeight = FontInfo.PixelHeight;
|
Font->PixelHeight = FontInfo.PixelHeight;
|
||||||
|
@ -169,17 +143,18 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->SACN = InitializeSACN(Context);
|
State->SACN = InitializeSACN(Context);
|
||||||
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
||||||
|
|
||||||
State->Camera.FieldOfView = DegreesToRadians(45.0f);
|
State->Camera.FieldOfView = 45.0f;
|
||||||
State->Camera.AspectRatio = gs_AspectRatio(State->WindowBounds);
|
State->Camera.AspectRatio = RectAspectRatio(State->WindowBounds);
|
||||||
State->Camera.Near = 1.0f;
|
State->Camera.Near = .1f;
|
||||||
State->Camera.Far = 100.0f;
|
State->Camera.Far = 800.0f;
|
||||||
State->Camera.Position = v3{0, 0, -250};
|
State->Camera.Position = v3{0, 0, 400};
|
||||||
State->Camera.LookAt = v3{0, 0, 0};
|
State->Camera.LookAt = v3{0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
State->LedSystem = LedSystemInitialize(Context.PlatformMemory, 128);
|
State->LedSystem = LedSystemInitialize(Context.ThreadContext.Allocator, 128);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
string SculpturePath = MakeStringLiteral("data/radialumia_v2.fold");
|
gs_const_string SculpturePath = ConstString("data/radialumia_v2.fold");
|
||||||
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, SculpturePath, State->GlobalLog);
|
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, SculpturePath, State->GlobalLog);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -189,11 +164,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
|
|
||||||
ReloadStaticData(Context, GlobalDebugServices);
|
ReloadStaticData(Context, GlobalDebugServices);
|
||||||
|
|
||||||
// Setup Operation Modes
|
State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext);
|
||||||
State->Modes.ActiveModesCount = 0;
|
|
||||||
State->Modes.Arena = {};
|
|
||||||
State->Modes.Arena.PlatformMemory = Context.PlatformMemory;
|
|
||||||
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
|
|
||||||
|
|
||||||
{ // Animation PLAYGROUND
|
{ // Animation PLAYGROUND
|
||||||
State->AnimationSystem = {};
|
State->AnimationSystem = {};
|
||||||
|
@ -203,9 +174,9 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
||||||
State->AnimationSystem.LayersMax = 32;
|
State->AnimationSystem.LayersMax = 32;
|
||||||
State->AnimationSystem.Layers = PushArray(&State->Permanent, anim_layer, State->AnimationSystem.LayersMax);
|
State->AnimationSystem.Layers = PushArray(&State->Permanent, anim_layer, State->AnimationSystem.LayersMax);
|
||||||
AddLayer(MakeStringLiteral("Base Layer"), &State->AnimationSystem, BlendMode_Overwrite);
|
AddLayer(MakeString("Base Layer"), &State->AnimationSystem, BlendMode_Overwrite);
|
||||||
AddLayer(MakeStringLiteral("Color Layer"), &State->AnimationSystem, BlendMode_Multiply);
|
AddLayer(MakeString("Color Layer"), &State->AnimationSystem, BlendMode_Multiply);
|
||||||
AddLayer(MakeStringLiteral("Sparkles"), &State->AnimationSystem, BlendMode_Add);
|
AddLayer(MakeString("Sparkles"), &State->AnimationSystem, BlendMode_Add);
|
||||||
} // End Animation Playground
|
} // End Animation Playground
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,7 +186,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_state Mouse)
|
HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
@ -274,7 +245,7 @@ HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_
|
||||||
}
|
}
|
||||||
|
|
||||||
internal dmx_buffer_list*
|
internal dmx_buffer_list*
|
||||||
CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize, memory_arena* Arena)
|
CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize, gs_memory_arena* Arena)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
@ -322,6 +293,10 @@ CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize,
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HANDMADE_MATH_IMPLEMENTATION
|
||||||
|
#include "handmade_math.h"
|
||||||
|
|
||||||
UPDATE_AND_RENDER(UpdateAndRender)
|
UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
@ -334,6 +309,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
ClearArena(&State->Transient);
|
ClearArena(&State->Transient);
|
||||||
Context->Mouse.CursorType = CursorType_Arrow;
|
Context->Mouse.CursorType = CursorType_Arrow;
|
||||||
|
|
||||||
|
PushRenderClearScreen(RenderBuffer);
|
||||||
|
State->Camera.AspectRatio = RectAspectRatio(Context->WindowBounds);
|
||||||
|
|
||||||
HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse);
|
HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse);
|
||||||
|
|
||||||
if (State->AnimationSystem.TimelineShouldAdvance) {
|
if (State->AnimationSystem.TimelineShouldAdvance) {
|
||||||
|
@ -355,7 +333,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
|
|
||||||
u32 CurrentBlocksMax = State->AnimationSystem.LayersCount;
|
u32 CurrentBlocksMax = State->AnimationSystem.LayersCount;
|
||||||
b8* CurrentBlocksFilled = PushArray(&State->Transient, b8, CurrentBlocksMax);
|
b8* CurrentBlocksFilled = PushArray(&State->Transient, b8, CurrentBlocksMax);
|
||||||
GSZeroArray(CurrentBlocksFilled, b8, CurrentBlocksMax);
|
ZeroArray(CurrentBlocksFilled, b8, CurrentBlocksMax);
|
||||||
animation_block* CurrentBlocks = PushArray(&State->Transient, animation_block, CurrentBlocksMax);
|
animation_block* CurrentBlocks = PushArray(&State->Transient, animation_block, CurrentBlocksMax);
|
||||||
|
|
||||||
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
||||||
|
@ -432,9 +410,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
u32 G = (u32)AssemblyLedBuffer->Colors[LED].G + (u32)LayerLEDBuffers[Layer].Colors[LED].G;
|
u32 G = (u32)AssemblyLedBuffer->Colors[LED].G + (u32)LayerLEDBuffers[Layer].Colors[LED].G;
|
||||||
u32 B = (u32)AssemblyLedBuffer->Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B;
|
u32 B = (u32)AssemblyLedBuffer->Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B;
|
||||||
|
|
||||||
AssemblyLedBuffer->Colors[LED].R = (u8)GSMin(R, (u32)255);
|
AssemblyLedBuffer->Colors[LED].R = (u8)Min(R, (u32)255);
|
||||||
AssemblyLedBuffer->Colors[LED].G = (u8)GSMin(G, (u32)255);
|
AssemblyLedBuffer->Colors[LED].G = (u8)Min(G, (u32)255);
|
||||||
AssemblyLedBuffer->Colors[LED].B = (u8)GSMin(B, (u32)255);
|
AssemblyLedBuffer->Colors[LED].B = (u8)Min(B, (u32)255);
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
@ -502,7 +480,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, 0, 0, gs_Width(State->WindowBounds), gs_Height(State->WindowBounds));
|
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
||||||
PushRenderClearScreen(RenderBuffer);
|
PushRenderClearScreen(RenderBuffer);
|
||||||
|
|
||||||
State->WindowBounds = Context->WindowBounds;
|
State->WindowBounds = Context->WindowBounds;
|
||||||
|
@ -521,7 +499,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Context->GeneralWorkQueue->DoQueueWorkUntilDone(Context->GeneralWorkQueue, 0);
|
Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext);
|
||||||
Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue);
|
Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue);
|
||||||
|
|
||||||
// Checking for overflows
|
// Checking for overflows
|
||||||
|
|
|
@ -20,13 +20,8 @@
|
||||||
#include "foldhaus_assembly.h"
|
#include "foldhaus_assembly.h"
|
||||||
#include "assembly_parser.cpp"
|
#include "assembly_parser.cpp"
|
||||||
|
|
||||||
|
|
||||||
#include "foldhaus_node.h"
|
|
||||||
|
|
||||||
typedef struct app_state app_state;
|
typedef struct app_state app_state;
|
||||||
|
|
||||||
#include "test_patterns.h"
|
|
||||||
|
|
||||||
// TODO(Peter): something we can do later is to remove all reliance on app_state and context
|
// TODO(Peter): something we can do later is to remove all reliance on app_state and context
|
||||||
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
|
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
|
||||||
// perform operations on, like panel_draw_requests = { bounds, panel* } etc.
|
// perform operations on, like panel_draw_requests = { bounds, panel* } etc.
|
||||||
|
@ -37,10 +32,6 @@ typedef struct app_state app_state;
|
||||||
|
|
||||||
#include "animation/foldhaus_animation.h"
|
#include "animation/foldhaus_animation.h"
|
||||||
|
|
||||||
#include "foldhaus_text_entry.h"
|
|
||||||
|
|
||||||
#include "foldhaus_search_lister.h"
|
|
||||||
|
|
||||||
enum network_protocol
|
enum network_protocol
|
||||||
{
|
{
|
||||||
NetworkProtocol_SACN,
|
NetworkProtocol_SACN,
|
||||||
|
@ -51,10 +42,11 @@ enum network_protocol
|
||||||
|
|
||||||
struct app_state
|
struct app_state
|
||||||
{
|
{
|
||||||
rect WindowBounds;
|
r32 CameraTheta; // TODO(Peter): @TEMPORARY
|
||||||
|
rect2 WindowBounds;
|
||||||
|
|
||||||
memory_arena Permanent;
|
gs_memory_arena Permanent;
|
||||||
memory_arena Transient;
|
gs_memory_arena Transient;
|
||||||
|
|
||||||
s32 NetworkProtocolHeaderSize;
|
s32 NetworkProtocolHeaderSize;
|
||||||
network_protocol NetworkProtocol;
|
network_protocol NetworkProtocol;
|
||||||
|
@ -69,7 +61,6 @@ struct app_state
|
||||||
|
|
||||||
operation_mode_system Modes;
|
operation_mode_system Modes;
|
||||||
input_command_queue CommandQueue;
|
input_command_queue CommandQueue;
|
||||||
text_entry ActiveTextEntry;
|
|
||||||
|
|
||||||
ui_interface Interface;
|
ui_interface Interface;
|
||||||
|
|
||||||
|
@ -80,7 +71,7 @@ struct app_state
|
||||||
panel_system PanelSystem;
|
panel_system PanelSystem;
|
||||||
panel* HotPanel;
|
panel* HotPanel;
|
||||||
|
|
||||||
pattern_node_workspace NodeWorkspace;
|
//pattern_node_workspace NodeWorkspace;
|
||||||
|
|
||||||
event_log* GlobalLog;
|
event_log* GlobalLog;
|
||||||
};
|
};
|
||||||
|
@ -94,8 +85,8 @@ TestPatternOne(led_buffer* Assembly, r32 Time)
|
||||||
for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
|
for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 LedPosition = Assembly->Positions[LedIndex];
|
v4 LedPosition = Assembly->Positions[LedIndex];
|
||||||
float PercentX = GSRemap(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f);
|
float PercentX = RemapClampedR32(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f);
|
||||||
float PercentY = GSRemap(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f);
|
float PercentY = RemapClampedR32(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f);
|
||||||
Assembly->Colors[LedIndex].R = (u8)(PercentX * 255);
|
Assembly->Colors[LedIndex].R = (u8)(PercentX * 255);
|
||||||
Assembly->Colors[LedIndex].G = (u8)(PercentY * 255);
|
Assembly->Colors[LedIndex].G = (u8)(PercentY * 255);
|
||||||
}
|
}
|
||||||
|
@ -104,16 +95,16 @@ TestPatternOne(led_buffer* Assembly, r32 Time)
|
||||||
internal void
|
internal void
|
||||||
TestPatternTwo(led_buffer* Assembly, r32 Time)
|
TestPatternTwo(led_buffer* Assembly, r32 Time)
|
||||||
{
|
{
|
||||||
r32 PeriodicTime = (Time / PI) * 2;
|
r32 PeriodicTime = (Time / PiR32) * 2;
|
||||||
|
|
||||||
r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f;
|
r32 ZeroOneSin = (SinR32(PeriodicTime) * .5f) + .5f;
|
||||||
r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
|
r32 ZeroOneCos = (CosR32(PeriodicTime) * .5f) + .5f;
|
||||||
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
||||||
|
|
||||||
v4 Center = v4{0, 0, 0, 1};
|
v4 Center = v4{0, 0, 0, 1};
|
||||||
r32 ThetaZ = Time / 2;
|
r32 ThetaZ = Time / 2;
|
||||||
v4 Normal = v4{GSCos(ThetaZ), 0, GSSin(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
v4 Normal = v4{CosR32(ThetaZ), 0, SinR32(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
||||||
v4 Right = Cross(Normal, v4{0, 1, 0, 0});
|
v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
|
||||||
|
|
||||||
v4 FrontCenter = Center + (Normal * 25);
|
v4 FrontCenter = Center + (Normal * 25);
|
||||||
v4 BackCenter = Center - (Normal * 25);
|
v4 BackCenter = Center - (Normal * 25);
|
||||||
|
@ -128,13 +119,13 @@ TestPatternTwo(led_buffer* Assembly, r32 Time)
|
||||||
v4 ToFront = Position + FrontCenter;
|
v4 ToFront = Position + FrontCenter;
|
||||||
v4 ToBack = Position + BackCenter;
|
v4 ToBack = Position + BackCenter;
|
||||||
|
|
||||||
r32 ToFrontDotNormal = Dot(ToFront, Normal);
|
r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
|
||||||
r32 ToBackDotNormal = Dot(ToBack, Normal);
|
r32 ToBackDotNormal = V4Dot(ToBack, Normal);
|
||||||
|
|
||||||
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000);
|
ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
|
||||||
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000);
|
ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
|
||||||
|
|
||||||
r32 SqDistToCenter = MagSqr(Position);
|
r32 SqDistToCenter = V4MagSquared(Position);
|
||||||
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
||||||
{
|
{
|
||||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
||||||
|
@ -157,10 +148,10 @@ internal void
|
||||||
TestPatternThree(led_buffer* Assembly, r32 Time)
|
TestPatternThree(led_buffer* Assembly, r32 Time)
|
||||||
{
|
{
|
||||||
v4 GreenCenter = v4{0, 0, 150, 1};
|
v4 GreenCenter = v4{0, 0, 150, 1};
|
||||||
r32 GreenRadius = GSAbs(GSSin(Time)) * 200;
|
r32 GreenRadius = Abs(SinR32(Time)) * 200;
|
||||||
|
|
||||||
v4 TealCenter = v4{0, 0, 150, 1};
|
v4 TealCenter = v4{0, 0, 150, 1};
|
||||||
r32 TealRadius = GSAbs(GSSin(Time + 1.5)) * 200;
|
r32 TealRadius = Abs(SinR32(Time + 1.5)) * 200;
|
||||||
|
|
||||||
r32 FadeDist = 35;
|
r32 FadeDist = 35;
|
||||||
|
|
||||||
|
@ -172,12 +163,12 @@ TestPatternThree(led_buffer* Assembly, r32 Time)
|
||||||
u8 Green = 0;
|
u8 Green = 0;
|
||||||
u8 Blue = 0;
|
u8 Blue = 0;
|
||||||
|
|
||||||
r32 GreenDist = GSAbs(Mag(LedPosition - GreenCenter) - GreenRadius);
|
r32 GreenDist = Abs(V4Mag(LedPosition - GreenCenter) - GreenRadius);
|
||||||
r32 GreenBrightness = GSClamp(0.f, FadeDist - GSAbs(GreenDist), FadeDist);
|
r32 GreenBrightness = Clamp(0.f, FadeDist - Abs(GreenDist), FadeDist);
|
||||||
Green = (u8)(GreenBrightness * 255);
|
Green = (u8)(GreenBrightness * 255);
|
||||||
|
|
||||||
r32 TealDist = GSAbs(Mag(LedPosition - TealCenter) - TealRadius);
|
r32 TealDist = Abs(V4Mag(LedPosition - TealCenter) - TealRadius);
|
||||||
r32 TealBrightness = GSClamp(0.f, FadeDist - GSAbs(TealDist), FadeDist);
|
r32 TealBrightness = Clamp(0.f, FadeDist - Abs(TealDist), FadeDist);
|
||||||
Red = (u8)(TealBrightness * 255);
|
Red = (u8)(TealBrightness * 255);
|
||||||
Blue = (u8)(TealBrightness * 255);
|
Blue = (u8)(TealBrightness * 255);
|
||||||
|
|
||||||
|
@ -191,17 +182,6 @@ TestPatternThree(led_buffer* Assembly, r32 Time)
|
||||||
|
|
||||||
#include "foldhaus_assembly.cpp"
|
#include "foldhaus_assembly.cpp"
|
||||||
|
|
||||||
#include "foldhaus_text_entry.cpp"
|
|
||||||
#include "foldhaus_search_lister.cpp"
|
|
||||||
|
|
||||||
#include "foldhaus_default_nodes.h"
|
|
||||||
|
|
||||||
#include "./generated/gs_meta_generated_typeinfo.h"
|
|
||||||
#include "generated/foldhaus_nodes_generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "foldhaus_node.cpp"
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode)
|
FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode)
|
||||||
{
|
{
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
@ -213,7 +193,7 @@ typedef PANEL_INIT_PROC(panel_init_proc);
|
||||||
#define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State)
|
#define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State)
|
||||||
typedef PANEL_CLEANUP_PROC(panel_cleanup_proc);
|
typedef PANEL_CLEANUP_PROC(panel_cleanup_proc);
|
||||||
|
|
||||||
#define PANEL_RENDER_PROC(name) void name(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
#define PANEL_RENDER_PROC(name) void name(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
typedef PANEL_RENDER_PROC(panel_render_proc);
|
typedef PANEL_RENDER_PROC(panel_render_proc);
|
||||||
|
|
||||||
// NOTE(Peter): This is used by the meta system to generate panel type info
|
// NOTE(Peter): This is used by the meta system to generate panel type info
|
||||||
|
@ -233,7 +213,6 @@ struct panel_definition
|
||||||
#include "panels/foldhaus_panel_dmx_view.h"
|
#include "panels/foldhaus_panel_dmx_view.h"
|
||||||
#include "panels/foldhaus_panel_animation_timeline.h"
|
#include "panels/foldhaus_panel_animation_timeline.h"
|
||||||
#include "panels/foldhaus_panel_hierarchy.h"
|
#include "panels/foldhaus_panel_hierarchy.h"
|
||||||
#include "panels/foldhaus_panel_node_graph.h"
|
|
||||||
#include "panels/foldhaus_panel_file_view.h"
|
#include "panels/foldhaus_panel_file_view.h"
|
||||||
|
|
||||||
#include "generated/foldhaus_panels_generated.h"
|
#include "generated/foldhaus_panels_generated.h"
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
#ifndef FOLDHAUS_ASSEMBLY_CPP
|
#ifndef FOLDHAUS_ASSEMBLY_CPP
|
||||||
|
|
||||||
internal led_system
|
internal led_system
|
||||||
LedSystemInitialize(platform_memory_handler PlatformMemory, u32 BuffersMax)
|
LedSystemInitialize(gs_allocator PlatformMemory, u32 BuffersMax)
|
||||||
{
|
{
|
||||||
led_system Result = {};
|
led_system Result = {};
|
||||||
Result.PlatformMemory = PlatformMemory;
|
Result.PlatformMemory = PlatformMemory;
|
||||||
// TODO(Peter): Since we have access to PlatformMemory, just realloc Buffers when we fill it up
|
// TODO(Peter): Since we have access to PlatformMemory, just realloc Buffers when we fill it up
|
||||||
Result.BuffersCountMax = BuffersMax;
|
Result.BuffersCountMax = BuffersMax;
|
||||||
Result.Buffers = PlatformAllocArray(PlatformMemory, led_buffer, Result.BuffersCountMax);
|
Result.Buffers = AllocatorAllocArray(PlatformMemory, led_buffer, Result.BuffersCountMax);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ LedSystemTakeFreeBuffer(led_system* System, u32 LedCount)
|
||||||
|
|
||||||
led_buffer* Buffer = &System->Buffers[Result];
|
led_buffer* Buffer = &System->Buffers[Result];
|
||||||
Buffer->LedCount = LedCount;
|
Buffer->LedCount = LedCount;
|
||||||
Buffer->Colors = PlatformAllocArray(System->PlatformMemory, pixel, Buffer->LedCount);
|
Buffer->Colors = AllocatorAllocArray(System->PlatformMemory, pixel, Buffer->LedCount);
|
||||||
Buffer->Positions = PlatformAllocArray(System->PlatformMemory, v4, Buffer->LedCount);
|
Buffer->Positions = AllocatorAllocArray(System->PlatformMemory, v4, Buffer->LedCount);
|
||||||
|
|
||||||
System->LedsCountTotal += LedCount;
|
System->LedsCountTotal += LedCount;
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ LedSystemFreeBuffer(led_system* System, u32 BufferIndex)
|
||||||
{
|
{
|
||||||
Assert(BufferIndex < System->BuffersCountMax);
|
Assert(BufferIndex < System->BuffersCountMax);
|
||||||
led_buffer* Buffer = &System->Buffers[BufferIndex];
|
led_buffer* Buffer = &System->Buffers[BufferIndex];
|
||||||
PlatformFreeArray(System->PlatformMemory, Buffer->Colors, pixel, Buffer->LedCount);
|
AllocatorFreeArray(System->PlatformMemory, Buffer->Colors, pixel, Buffer->LedCount);
|
||||||
PlatformFreeArray(System->PlatformMemory, Buffer->Positions, v4, Buffer->LedCount);
|
AllocatorFreeArray(System->PlatformMemory, Buffer->Positions, v4, Buffer->LedCount);
|
||||||
System->LedsCountTotal -= Buffer->LedCount;
|
System->LedsCountTotal -= Buffer->LedCount;
|
||||||
*Buffer = {};
|
*Buffer = {};
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ LedBufferSetLed(led_buffer* Buffer, u32 Led, v4 Position)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 RootPosition, led_system* LedSystem)
|
ConstructAssemblyFromDefinition (assembly* Assembly, gs_const_string AssemblyName, v4 RootPosition, led_system* LedSystem)
|
||||||
{
|
{
|
||||||
Assembly->LedBufferIndex = LedSystemTakeFreeBuffer(LedSystem, Assembly->LedCountTotal);
|
Assembly->LedBufferIndex = LedSystemTakeFreeBuffer(LedSystem, Assembly->LedCountTotal);
|
||||||
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex);
|
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex);
|
||||||
|
@ -90,8 +90,8 @@ ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 Roo
|
||||||
v2_strip* StripAt = &Assembly->Strips[StripIdx];
|
v2_strip* StripAt = &Assembly->Strips[StripIdx];
|
||||||
StripAt->LedLUT = PushArray(&Assembly->Arena, u32, StripAt->LedCount);
|
StripAt->LedLUT = PushArray(&Assembly->Arena, u32, StripAt->LedCount);
|
||||||
|
|
||||||
v4 WS_StripStart = RootPosition + V4(StripAt->StartPosition * Assembly->Scale, 1);
|
v4 WS_StripStart = RootPosition + ToV4Point(StripAt->StartPosition * Assembly->Scale);
|
||||||
v4 WS_StripEnd = RootPosition + V4(StripAt->EndPosition * Assembly->Scale, 1);
|
v4 WS_StripEnd = RootPosition + ToV4Point(StripAt->EndPosition * Assembly->Scale);
|
||||||
|
|
||||||
v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)StripAt->LedCount;
|
v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)StripAt->LedCount;
|
||||||
for (u32 Step = 0; Step < StripAt->LedCount; Step++)
|
for (u32 Step = 0; Step < StripAt->LedCount; Step++)
|
||||||
|
@ -111,25 +111,25 @@ static v4 TempAssemblyOffsets[] = { v4{0, 0, 0, 0}, v4{250, 0, 75, 0}, v4{-250,
|
||||||
s32 TempAssemblyOffsetsCount = 3;
|
s32 TempAssemblyOffsetsCount = 3;
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
LoadAssembly (assembly_array* Assemblies, led_system* LedSystem, memory_arena* Scratch, context Context, string Path, event_log* GlobalLog)
|
LoadAssembly (assembly_array* Assemblies, led_system* LedSystem, gs_memory_arena* Scratch, context Context, gs_const_string Path, event_log* GlobalLog)
|
||||||
{
|
{
|
||||||
platform_memory_result AssemblyFile = ReadEntireFile(Context, Path);
|
gs_file AssemblyFile = ReadEntireFile(Context.ThreadContext.FileHandler, Path);
|
||||||
if (AssemblyFile.Error == PlatformMemory_NoError && AssemblyFile.Data.Size > 0)
|
if (FileNoError(AssemblyFile))
|
||||||
{
|
{
|
||||||
string AssemblyFileText = MakeString((char*)AssemblyFile.Data.Base);
|
gs_string AssemblyFileText = MakeString((char*)AssemblyFile.Memory);
|
||||||
|
|
||||||
Assert(Assemblies->Count < Assemblies->CountMax);
|
Assert(Assemblies->Count < Assemblies->CountMax);
|
||||||
assembly* NewAssembly = &Assemblies->Values[Assemblies->Count++];
|
assembly* NewAssembly = &Assemblies->Values[Assemblies->Count++];
|
||||||
|
|
||||||
s32 IndexOfLastSlash = FastLastIndexOfCharInCharArray(Path.Memory, Path.Length, '\\');
|
s32 IndexOfLastSlash = FindLast(Path, '\\');
|
||||||
string FileName = Substring(Path, IndexOfLastSlash + 1);
|
gs_const_string FileName = Substring(Path, IndexOfLastSlash + 1, Path.Length);
|
||||||
|
|
||||||
NewAssembly->Arena.PlatformMemory = Context.PlatformMemory;
|
NewAssembly->Arena = CreateMemoryArena(Context.ThreadContext.Allocator);
|
||||||
if (ParseAssemblyFile(NewAssembly, AssemblyFileText, Scratch))
|
if (ParseAssemblyFile(NewAssembly, FileName, AssemblyFileText, Scratch))
|
||||||
{
|
{
|
||||||
v4 Offset = v4{0,0,0,0}; //TempAssemblyOffsets[Assemblies->Count % TempAssemblyOffsetsCount];
|
v4 Offset = v4{0,0,0,0}; //TempAssemblyOffsets[Assemblies->Count % TempAssemblyOffsetsCount];
|
||||||
ConstructAssemblyFromDefinition(NewAssembly, FileName, Offset, LedSystem);
|
ConstructAssemblyFromDefinition(NewAssembly, FileName, Offset, LedSystem);
|
||||||
PlatformFree(Context.PlatformMemory, AssemblyFile.Data.Base, AssemblyFile.Data.Size);
|
AllocatorFree(Context.ThreadContext.Allocator, AssemblyFile.Memory, AssemblyFile.Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct led_buffer
|
||||||
|
|
||||||
struct led_system
|
struct led_system
|
||||||
{
|
{
|
||||||
platform_memory_handler PlatformMemory;
|
gs_allocator PlatformMemory;
|
||||||
|
|
||||||
u32 BuffersCountMax;
|
u32 BuffersCountMax;
|
||||||
u32 BuffersCount;
|
u32 BuffersCount;
|
||||||
|
@ -62,10 +62,10 @@ struct v2_strip
|
||||||
|
|
||||||
struct assembly
|
struct assembly
|
||||||
{
|
{
|
||||||
memory_arena Arena;
|
gs_memory_arena Arena;
|
||||||
|
|
||||||
string Name;
|
gs_string Name;
|
||||||
string FilePath;
|
gs_string FilePath;
|
||||||
|
|
||||||
r32 Scale;
|
r32 Scale;
|
||||||
s32 LedCountTotal;
|
s32 LedCountTotal;
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct input_command_queue
|
||||||
internal void
|
internal void
|
||||||
InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
|
InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
|
||||||
s32 Size,
|
s32 Size,
|
||||||
memory_arena* Storage)
|
gs_memory_arena* Storage)
|
||||||
{
|
{
|
||||||
CommandRegistry->Commands = PushArray(Storage, input_command, Size);
|
CommandRegistry->Commands = PushArray(Storage, input_command, Size);
|
||||||
CommandRegistry->Size = Size;
|
CommandRegistry->Size = Size;
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct collated_scope_record
|
||||||
struct scope_name
|
struct scope_name
|
||||||
{
|
{
|
||||||
u32 Hash;
|
u32 Hash;
|
||||||
string Name;
|
gs_string Name;
|
||||||
char Buffer[SCOPE_NAME_BUFFER_LENGTH];
|
char Buffer[SCOPE_NAME_BUFFER_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ typedef u8* debug_realloc(u8* Memory, s32 OldSize, s32 NewSize);
|
||||||
struct debug_histogram_entry
|
struct debug_histogram_entry
|
||||||
{
|
{
|
||||||
char ScopeName_[SCOPE_NAME_LENGTH];
|
char ScopeName_[SCOPE_NAME_LENGTH];
|
||||||
string ScopeName;
|
gs_string ScopeName;
|
||||||
|
|
||||||
u32 PerFrame_Cycles[HISTOGRAM_DEPTH];
|
u32 PerFrame_Cycles[HISTOGRAM_DEPTH];
|
||||||
u32 PerFrame_CallCount[HISTOGRAM_DEPTH];
|
u32 PerFrame_CallCount[HISTOGRAM_DEPTH];
|
||||||
|
@ -359,9 +359,9 @@ BeginTrackingScopeAndGetNameHash (debug_services* Services, char* ScopeName)
|
||||||
if (Entry->Hash == 0) // If its new
|
if (Entry->Hash == 0) // If its new
|
||||||
{
|
{
|
||||||
Entry->Hash = NameHash;
|
Entry->Hash = NameHash;
|
||||||
// TODO(Peter): need to initialize all entry name strings to point at the buffer
|
// TODO(Peter): need to initialize all entry name gs_strings to point at the buffer
|
||||||
// This will break eventually. when it does, do this ^^^^ when on startup
|
// This will break eventually. when it does, do this ^^^^ when on startup
|
||||||
CopyCharArrayToString(ScopeName, &Entry->Name);
|
PrintF(&Entry->Name, "%s", ScopeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NameHash;
|
return NameHash;
|
||||||
|
|
|
@ -41,7 +41,7 @@ OPERATION_STATE_DEF(drag_panel_border_operation_state)
|
||||||
|
|
||||||
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
|
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
|
||||||
// it stores the value calculated when the operation mode is kicked off.
|
// it stores the value calculated when the operation mode is kicked off.
|
||||||
rect InitialPanelBounds;
|
rect2 InitialPanelBounds;
|
||||||
panel_split_direction PanelEdgeDirection;
|
panel_split_direction PanelEdgeDirection;
|
||||||
panel_edit_mode PanelEditMode;
|
panel_edit_mode PanelEditMode;
|
||||||
};
|
};
|
||||||
|
@ -49,7 +49,7 @@ OPERATION_STATE_DEF(drag_panel_border_operation_state)
|
||||||
OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
|
OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
|
||||||
{
|
{
|
||||||
drag_panel_border_operation_state* OpState = (drag_panel_border_operation_state*)Operation.OpStateMemory;
|
drag_panel_border_operation_state* OpState = (drag_panel_border_operation_state*)Operation.OpStateMemory;
|
||||||
rect PanelBounds = OpState->InitialPanelBounds;
|
rect2 PanelBounds = OpState->InitialPanelBounds;
|
||||||
|
|
||||||
if (OpState->PanelEditMode == PanelEdit_Modify)
|
if (OpState->PanelEditMode == PanelEdit_Modify)
|
||||||
{
|
{
|
||||||
|
@ -72,10 +72,10 @@ OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
|
||||||
}
|
}
|
||||||
else if (OpState->PanelEditMode == PanelEdit_Destroy)
|
else if (OpState->PanelEditMode == PanelEdit_Destroy)
|
||||||
{
|
{
|
||||||
rect PanelToDeleteBounds = {};
|
rect2 PanelToDeleteBounds = {};
|
||||||
if (OpState->PanelEdgeDirection == PanelSplit_Horizontal)
|
if (OpState->PanelEdgeDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, OpState->Panel->SplitPercent);
|
r32 SplitY = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
|
||||||
if (Mouse.Pos.y > SplitY)
|
if (Mouse.Pos.y > SplitY)
|
||||||
{
|
{
|
||||||
PanelToDeleteBounds = GetTopPanelBounds(OpState->Panel, PanelBounds);
|
PanelToDeleteBounds = GetTopPanelBounds(OpState->Panel, PanelBounds);
|
||||||
|
@ -87,7 +87,7 @@ OPERATION_RENDER_PROC(UpdateAndRenderDragPanelBorder)
|
||||||
}
|
}
|
||||||
else if (OpState->PanelEdgeDirection == PanelSplit_Vertical)
|
else if (OpState->PanelEdgeDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, OpState->Panel->SplitPercent);
|
r32 SplitX = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
|
||||||
if (Mouse.Pos.x > SplitX)
|
if (Mouse.Pos.x > SplitX)
|
||||||
{
|
{
|
||||||
PanelToDeleteBounds = GetRightPanelBounds(OpState->Panel, PanelBounds);
|
PanelToDeleteBounds = GetRightPanelBounds(OpState->Panel, PanelBounds);
|
||||||
|
@ -106,7 +106,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
{
|
{
|
||||||
drag_panel_border_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_panel_border_operation_state);
|
drag_panel_border_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_panel_border_operation_state);
|
||||||
panel* Panel = OpState->Panel;
|
panel* Panel = OpState->Panel;
|
||||||
rect PanelBounds = OpState->InitialPanelBounds;
|
rect2 PanelBounds = OpState->InitialPanelBounds;
|
||||||
|
|
||||||
if (OpState->PanelEditMode == PanelEdit_Modify)
|
if (OpState->PanelEditMode == PanelEdit_Modify)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +123,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / gs_Height(PanelBounds);
|
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Rect2Height(PanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
|
@ -139,7 +139,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / gs_Width(PanelBounds);
|
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Rect2Width(PanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
{
|
{
|
||||||
if (OpState->PanelEdgeDirection == PanelSplit_Horizontal)
|
if (OpState->PanelEdgeDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, OpState->Panel->SplitPercent);
|
r32 SplitY = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
|
||||||
if (Mouse.Pos.y > SplitY)
|
if (Mouse.Pos.y > SplitY)
|
||||||
{
|
{
|
||||||
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, &State->PanelSystem);
|
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, &State->PanelSystem);
|
||||||
|
@ -159,7 +159,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
}
|
}
|
||||||
else if (OpState->PanelEdgeDirection == PanelSplit_Vertical)
|
else if (OpState->PanelEdgeDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, OpState->Panel->SplitPercent);
|
r32 SplitX = LerpR32(OpState->Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
|
||||||
if (Mouse.Pos.x > SplitX)
|
if (Mouse.Pos.x > SplitX)
|
||||||
{
|
{
|
||||||
ConsolidatePanelsKeepOne(Panel, Panel->Left, &State->PanelSystem);
|
ConsolidatePanelsKeepOne(Panel, Panel->Left, &State->PanelSystem);
|
||||||
|
@ -180,7 +180,7 @@ input_command DragPanelBorderCommands[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
BeginDragPanelBorder(panel* Panel, panel_edit_mode PanelEditMode, rect PanelBounds, panel_split_direction PanelEdgeDirection, mouse_state Mouse, app_state* State)
|
BeginDragPanelBorder(panel* Panel, panel_edit_mode PanelEditMode, rect2 PanelBounds, panel_split_direction PanelEdgeDirection, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
operation_mode* DragPanelBorder = ActivateOperationModeWithCommands(&State->Modes, DragPanelBorderCommands, UpdateAndRenderDragPanelBorder);
|
operation_mode* DragPanelBorder = ActivateOperationModeWithCommands(&State->Modes, DragPanelBorderCommands, UpdateAndRenderDragPanelBorder);
|
||||||
drag_panel_border_operation_state* OpState = CreateOperationState(DragPanelBorder, &State->Modes, drag_panel_border_operation_state);
|
drag_panel_border_operation_state* OpState = CreateOperationState(DragPanelBorder, &State->Modes, drag_panel_border_operation_state);
|
||||||
|
@ -202,17 +202,17 @@ OPERATION_STATE_DEF(split_panel_operation_state)
|
||||||
|
|
||||||
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
|
// NOTE(Peter): InitialPanelBounds is the bounds of the panel we are modifying,
|
||||||
// it stores the value calculated when the operation mode is kicked off.
|
// it stores the value calculated when the operation mode is kicked off.
|
||||||
rect InitialPanelBounds;
|
rect2 InitialPanelBounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(UpdateAndRenderSplitPanel)
|
OPERATION_RENDER_PROC(UpdateAndRenderSplitPanel)
|
||||||
{
|
{
|
||||||
split_panel_operation_state* OpState = (split_panel_operation_state*)Operation.OpStateMemory;
|
split_panel_operation_state* OpState = (split_panel_operation_state*)Operation.OpStateMemory;
|
||||||
rect PanelBounds = OpState->InitialPanelBounds;
|
rect2 PanelBounds = OpState->InitialPanelBounds;
|
||||||
v4 EdgePreviewColor = v4{.3f, .3f, .3f, 1.f};
|
v4 EdgePreviewColor = v4{.3f, .3f, .3f, 1.f};
|
||||||
|
|
||||||
r32 MouseDeltaX = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
|
r32 MouseDeltaX = Abs(Mouse.Pos.x - Mouse.DownPos.x);
|
||||||
r32 MouseDeltaY = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
|
r32 MouseDeltaY = Abs(Mouse.Pos.y - Mouse.DownPos.y);
|
||||||
|
|
||||||
v2 EdgePreviewMin = {};
|
v2 EdgePreviewMin = {};
|
||||||
v2 EdgePreviewMax = {};
|
v2 EdgePreviewMax = {};
|
||||||
|
@ -234,19 +234,19 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation)
|
||||||
{
|
{
|
||||||
split_panel_operation_state* OpState = GetCurrentOperationState(State->Modes, split_panel_operation_state);
|
split_panel_operation_state* OpState = GetCurrentOperationState(State->Modes, split_panel_operation_state);
|
||||||
panel* Panel = OpState->Panel;
|
panel* Panel = OpState->Panel;
|
||||||
rect PanelBounds = OpState->InitialPanelBounds;
|
rect2 PanelBounds = OpState->InitialPanelBounds;
|
||||||
|
|
||||||
r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
|
r32 XDistance = Abs(Mouse.Pos.x - Mouse.DownPos.x);
|
||||||
r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
|
r32 YDistance = Abs(Mouse.Pos.y - Mouse.DownPos.y);
|
||||||
|
|
||||||
if (XDistance > YDistance)
|
if (XDistance > YDistance)
|
||||||
{
|
{
|
||||||
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / gs_Width(PanelBounds);
|
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds);
|
||||||
SplitPanelVertically(Panel, XPercent, &State->PanelSystem);
|
SplitPanelVertically(Panel, XPercent, &State->PanelSystem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / gs_Height(PanelBounds);
|
r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Rect2Height(PanelBounds);
|
||||||
SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem);
|
SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ input_command SplitPanelCommands[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
BeginSplitPanelOperation(panel* Panel, rect PanelBounds, mouse_state Mouse, app_state* State)
|
BeginSplitPanelOperation(panel* Panel, rect2 PanelBounds, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel);
|
operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel);
|
||||||
split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state);
|
split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state);
|
||||||
|
@ -278,20 +278,22 @@ BeginSplitPanelOperation(panel* Panel, rect PanelBounds, mouse_state Mouse, app_
|
||||||
#define PANEL_EDGE_CLICK_MAX_DISTANCE 6
|
#define PANEL_EDGE_CLICK_MAX_DISTANCE 6
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, rect PanelBounds, mouse_state Mouse, app_state* State)
|
HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, rect2 PanelBounds, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
b32 HandledMouseInput = false;
|
b32 HandledMouseInput = false;
|
||||||
|
|
||||||
|
rect2 PanelSplitButtonBounds = rect2{ PanelBounds.Min, PanelBounds.Min + v2{25, 25} };
|
||||||
|
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit
|
if (Panel->SplitDirection == PanelSplit_NoSplit
|
||||||
&& PointIsInRange(Mouse.DownPos, PanelBounds.Min, PanelBounds.Min + v2{25, 25}))
|
&& PointIsInRect(PanelSplitButtonBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
BeginSplitPanelOperation(Panel, PanelBounds, Mouse, State);
|
BeginSplitPanelOperation(Panel, PanelBounds, Mouse, State);
|
||||||
HandledMouseInput = true;
|
HandledMouseInput = true;
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent);
|
r32 SplitY = LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
|
||||||
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY);
|
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.y - SplitY);
|
||||||
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
||||||
{
|
{
|
||||||
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Horizontal, Mouse, State);
|
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Horizontal, Mouse, State);
|
||||||
|
@ -299,13 +301,13 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||||
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||||
if (gs_PointIsInRect(Mouse.DownPos, BottomPanelBounds))
|
if (PointIsInRect(BottomPanelBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelEditMode, BottomPanelBounds, Mouse, State);
|
HandleMouseDownPanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelEditMode, BottomPanelBounds, Mouse, State);
|
||||||
}
|
}
|
||||||
if (gs_PointIsInRect(Mouse.DownPos, TopPanelBounds))
|
if (PointIsInRect(TopPanelBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Top->Panel, PanelEditMode, TopPanelBounds, Mouse, State);
|
HandleMouseDownPanelInteractionOrRecurse(&Panel->Top->Panel, PanelEditMode, TopPanelBounds, Mouse, State);
|
||||||
}
|
}
|
||||||
|
@ -313,8 +315,8 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent);
|
r32 SplitX = LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
|
||||||
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX);
|
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.x - SplitX);
|
||||||
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
||||||
{
|
{
|
||||||
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Vertical, Mouse, State);
|
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Vertical, Mouse, State);
|
||||||
|
@ -322,13 +324,13 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||||
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||||
if (gs_PointIsInRect(Mouse.DownPos, LeftPanelBounds))
|
if (PointIsInRect(LeftPanelBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Left->Panel, PanelEditMode, LeftPanelBounds, Mouse, State);
|
HandleMouseDownPanelInteractionOrRecurse(&Panel->Left->Panel, PanelEditMode, LeftPanelBounds, Mouse, State);
|
||||||
}
|
}
|
||||||
if (gs_PointIsInRect(Mouse.DownPos, RightPanelBounds))
|
if (PointIsInRect(RightPanelBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Right->Panel, PanelEditMode, RightPanelBounds, Mouse, State);
|
HandleMouseDownPanelInteractionOrRecurse(&Panel->Right->Panel, PanelEditMode, RightPanelBounds, Mouse, State);
|
||||||
}
|
}
|
||||||
|
@ -339,7 +341,7 @@ HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEdit
|
||||||
}
|
}
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
HandleMousePanelInteraction(panel_system* PanelSystem, rect WindowBounds, mouse_state Mouse, app_state* State)
|
HandleMousePanelInteraction(panel_system* PanelSystem, rect2 WindowBounds, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
b32 HandledMouseInput = false;
|
b32 HandledMouseInput = false;
|
||||||
|
|
||||||
|
@ -359,10 +361,10 @@ HandleMousePanelInteraction(panel_system* PanelSystem, rect WindowBounds, mouse_
|
||||||
internal void
|
internal void
|
||||||
DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mouse, render_command_buffer* RenderBuffer)
|
DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mouse, render_command_buffer* RenderBuffer)
|
||||||
{
|
{
|
||||||
r32 MouseLeftEdgeDistance = GSAbs(Mouse->Pos.x - PanelMin.x);
|
r32 MouseLeftEdgeDistance = Abs(Mouse->Pos.x - PanelMin.x);
|
||||||
r32 MouseRightEdgeDistance = GSAbs(Mouse->Pos.x - PanelMax.x);
|
r32 MouseRightEdgeDistance = Abs(Mouse->Pos.x - PanelMax.x);
|
||||||
r32 MouseTopEdgeDistance = GSAbs(Mouse->Pos.y - PanelMax.y);
|
r32 MouseTopEdgeDistance = Abs(Mouse->Pos.y - PanelMax.y);
|
||||||
r32 MouseBottomEdgeDistance = GSAbs(Mouse->Pos.y - PanelMin.y);
|
r32 MouseBottomEdgeDistance = Abs(Mouse->Pos.y - PanelMin.y);
|
||||||
|
|
||||||
PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color);
|
PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color);
|
||||||
v4 HighlightColor = v4{.3f, .3f, .3f, 1.f};
|
v4 HighlightColor = v4{.3f, .3f, .3f, 1.f};
|
||||||
|
@ -398,41 +400,46 @@ DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mo
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBounds, mouse_state Mouse, app_state* State)
|
DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterBounds, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, v2{FooterBounds.Max.x, FooterBounds.Min.y + 25}, v4{.5f, .5f, .5f, 1.f});
|
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, v2{FooterBounds.Max.x, FooterBounds.Min.y + 25}, v4{.5f, .5f, .5f, 1.f});
|
||||||
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4);
|
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4);
|
||||||
|
|
||||||
rect PanelSelectBtnBounds = gs_MakeRectMinWidth(FooterBounds.Min + v2{30, 1}, v2{100, 23});
|
rect2 PanelSelectBtnBounds = MakeRect2MinDim(FooterBounds.Min + v2{30, 1}, v2{100, 23});
|
||||||
|
|
||||||
if (Panel->PanelSelectionMenuOpen)
|
if (Panel->PanelSelectionMenuOpen)
|
||||||
{
|
{
|
||||||
rect ButtonBounds = gs_MakeRectMinWidth(v2{ PanelSelectBtnBounds.Min.x, FooterBounds.Max.y }, v2{ 100, 25 });
|
rect2 ButtonBounds = MakeRect2MinDim(v2{ PanelSelectBtnBounds.Min.x, FooterBounds.Max.y }, v2{ 100, 25 });
|
||||||
|
|
||||||
|
rect2 MenuBounds = rect2
|
||||||
|
{
|
||||||
|
ButtonBounds.Min,
|
||||||
|
v2{
|
||||||
|
ButtonBounds.Min.x + Rect2Width(ButtonBounds), ButtonBounds.Min.y + (Rect2Height(ButtonBounds) * GlobalPanelDefsCount)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
v2 MenuMin = ButtonBounds.Min;
|
|
||||||
v2 MenuMax = v2{ButtonBounds.Min.x + gs_Width(ButtonBounds), ButtonBounds.Min.y + (gs_Height(ButtonBounds) * GlobalPanelDefsCount)};
|
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||||
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
|
&& !PointIsInRect(MenuBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
Panel->PanelSelectionMenuOpen = false;
|
Panel->PanelSelectionMenuOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
for (s32 i = 0; i < GlobalPanelDefsCount; i++)
|
||||||
{
|
{
|
||||||
panel_definition Def = GlobalPanelDefs[i];
|
panel_definition Def = GlobalPanelDefs[i];
|
||||||
string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
||||||
if (ui_Button(&State->Interface, DefName, ButtonBounds))
|
if (ui_Button(&State->Interface, DefName, ButtonBounds))
|
||||||
{
|
{
|
||||||
SetPanelDefinition(Panel, i, State);
|
SetPanelDefinition(Panel, i, State);
|
||||||
Panel->PanelSelectionMenuOpen = false;
|
Panel->PanelSelectionMenuOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonBounds = gs_TranslateRectY(ButtonBounds, gs_Height(ButtonBounds));
|
ButtonBounds = Rect2TranslateY(ButtonBounds, Rect2Height(ButtonBounds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui_Button(&State->Interface, MakeStringLiteral("Select"), PanelSelectBtnBounds))
|
if (ui_Button(&State->Interface, MakeString("Select"), PanelSelectBtnBounds))
|
||||||
{
|
{
|
||||||
Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen;
|
Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen;
|
||||||
}
|
}
|
||||||
|
@ -440,15 +447,15 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBo
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderPanel(panel* Panel, rect PanelBounds, rect WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
|
RenderPanel(panel* Panel, rect2 PanelBounds, rect2 WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
Assert(Panel->PanelDefinitionIndex >= 0);
|
Assert(Panel->PanelDefinitionIndex >= 0);
|
||||||
|
|
||||||
rect FooterBounds = rect{
|
rect2 FooterBounds = rect2{
|
||||||
PanelBounds.Min,
|
PanelBounds.Min,
|
||||||
v2{PanelBounds.Max.x, PanelBounds.Min.y + 25},
|
v2{PanelBounds.Max.x, PanelBounds.Min.y + 25},
|
||||||
};
|
};
|
||||||
rect PanelViewBounds = rect{
|
rect2 PanelViewBounds = rect2{
|
||||||
v2{PanelBounds.Min.x, FooterBounds.Max.y},
|
v2{PanelBounds.Min.x, FooterBounds.Max.y},
|
||||||
PanelBounds.Max,
|
PanelBounds.Max,
|
||||||
};
|
};
|
||||||
|
@ -456,7 +463,7 @@ RenderPanel(panel* Panel, rect PanelBounds, rect WindowBounds, render_command_bu
|
||||||
panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex];
|
panel_definition Definition = GlobalPanelDefs[Panel->PanelDefinitionIndex];
|
||||||
Definition.Render(*Panel, PanelViewBounds, RenderBuffer, State, Context);
|
Definition.Render(*Panel, PanelViewBounds, RenderBuffer, State, Context);
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, WindowBounds.Min.x, WindowBounds.Min.y, WindowBounds.Max.x, WindowBounds.Max.y);
|
PushRenderOrthographic(RenderBuffer, WindowBounds);
|
||||||
DrawPanelFooter(Panel, RenderBuffer, FooterBounds, Mouse, State);
|
DrawPanelFooter(Panel, RenderBuffer, FooterBounds, Mouse, State);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,12 +474,12 @@ DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mou
|
||||||
{
|
{
|
||||||
panel_with_layout PanelWithLayout = PanelLayout.Panels[i];
|
panel_with_layout PanelWithLayout = PanelLayout.Panels[i];
|
||||||
panel* Panel = PanelWithLayout.Panel;
|
panel* Panel = PanelWithLayout.Panel;
|
||||||
rect PanelBounds = PanelWithLayout.Bounds;
|
rect2 PanelBounds = PanelWithLayout.Bounds;
|
||||||
|
|
||||||
RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse);
|
RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse);
|
||||||
v4 BorderColor = v4{0, 0, 0, 1};
|
v4 BorderColor = v4{0, 0, 0, 1};
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, State->WindowBounds.Min.x, State->WindowBounds.Min.y, State->WindowBounds.Max.x, State->WindowBounds.Max.y);
|
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
||||||
DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, Mouse, RenderBuffer);
|
DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, Mouse, RenderBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ enum log_entry_type
|
||||||
|
|
||||||
struct log_entry
|
struct log_entry
|
||||||
{
|
{
|
||||||
string Message;
|
gs_string Message;
|
||||||
log_entry_type Type;
|
log_entry_type Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,11 +25,11 @@ struct event_log
|
||||||
u32 NextEntry;
|
u32 NextEntry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LogMessage(_Log, _Message) PushLogEntry(_Log, MakeStringLiteral(_Message), LogEntry_Message)
|
#define LogMessage(_Log, _Message) PushLogEntry(_Log, MakeString(_Message), LogEntry_Message)
|
||||||
#define LogError(_Log, _Message) PushLogEntry(_Log, MakeStringLiteral(_Message), LogEntry_Error)
|
#define LogError(_Log, _Message) PushLogEntry(_Log, MakeString(_Message), LogEntry_Error)
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushLogEntry(event_log* Log, string Message, log_entry_type Type)
|
PushLogEntry(event_log* Log, gs_string Message, log_entry_type Type)
|
||||||
{
|
{
|
||||||
u32 NewLogIndex = Log->NextEntry++;
|
u32 NewLogIndex = Log->NextEntry++;
|
||||||
if (Log->NextEntry >= LOG_ENTRIES_MAX)
|
if (Log->NextEntry >= LOG_ENTRIES_MAX)
|
||||||
|
|
|
@ -55,7 +55,7 @@ SortNodeNeighbors(u32 ContiguousNodeIndex, gs_list_handle NodeHandle, adjacency_
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32*
|
internal s32*
|
||||||
CreateSparseToContiguousMap (pattern_node_workspace Workspace, memory_arena* Scratch)
|
CreateSparseToContiguousMap (pattern_node_workspace Workspace, gs_memory_arena* Scratch)
|
||||||
{
|
{
|
||||||
s32* Result = PushArray(Scratch, s32, Workspace.Nodes.OnePastLastUsed);
|
s32* Result = PushArray(Scratch, s32, Workspace.Nodes.OnePastLastUsed);
|
||||||
s32 ContiguousIndex = 0;
|
s32 ContiguousIndex = 0;
|
||||||
|
@ -71,7 +71,7 @@ CreateSparseToContiguousMap (pattern_node_workspace Workspace, memory_arena* Scr
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
|
UpdateSortedNodes(pattern_node_workspace* Workspace, gs_memory_arena* Scratch)
|
||||||
{
|
{
|
||||||
ClearNodeWorkspaceStorage(Workspace);
|
ClearNodeWorkspaceStorage(Workspace);
|
||||||
|
|
||||||
|
@ -119,22 +119,22 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
|
||||||
RadixSortInPlace(NeighborsListLengths, Workspace->Nodes.Used);
|
RadixSortInPlace(NeighborsListLengths, Workspace->Nodes.Used);
|
||||||
|
|
||||||
char* OutputCharArray = PushArray(Scratch, char, 1024);
|
char* OutputCharArray = PushArray(Scratch, char, 1024);
|
||||||
string OutputString = MakeString(OutputCharArray, 0, 1024);
|
gs_string Outputgs_string = MakeString(OutputCharArray, 0, 1024);
|
||||||
|
|
||||||
PrintF(&OutputString, "Neighbors Lists: \n");
|
PrintF(&Outputgs_string, "Neighbors Lists: \n");
|
||||||
for (u32 d = 0; d < Workspace->Nodes.Used; d++)
|
for (u32 d = 0; d < Workspace->Nodes.Used; d++)
|
||||||
{
|
{
|
||||||
PrintF(&OutputString, " %d: Node [ %d ] : neighbors { ", d, NeighborsListLengths[d].ID);
|
PrintF(&Outputgs_string, " %d: Node [ %d ] : neighbors { ", d, NeighborsListLengths[d].ID);
|
||||||
|
|
||||||
adjacency_list* Neighbors = NeighborsLists[d];
|
adjacency_list* Neighbors = NeighborsLists[d];
|
||||||
while (Neighbors)
|
while (Neighbors)
|
||||||
{
|
{
|
||||||
PrintF(&OutputString, "%d, ", Neighbors->NodeHandle.Index);
|
PrintF(&Outputgs_string, "%d, ", Neighbors->NodeHandle.Index);
|
||||||
Neighbors = Neighbors->Next;
|
Neighbors = Neighbors->Next;
|
||||||
}
|
}
|
||||||
PrintF(&OutputString, " }\n");
|
PrintF(&Outputgs_string, " }\n");
|
||||||
}
|
}
|
||||||
NullTerminate(&OutputString);
|
NullTerminate(&Outputgs_string);
|
||||||
|
|
||||||
// This is a contiguous array.
|
// This is a contiguous array.
|
||||||
b8* NodesVisited = PushArray(Scratch, b8, NodeCount);
|
b8* NodesVisited = PushArray(Scratch, b8, NodeCount);
|
||||||
|
@ -163,7 +163,7 @@ UpdateSortedNodes(pattern_node_workspace* Workspace, memory_arena* Scratch)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspace, memory_arena* Scratch)
|
PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspace, gs_memory_arena* Scratch)
|
||||||
{
|
{
|
||||||
pattern_node* NewNode = Workspace->Nodes.TakeElement();
|
pattern_node* NewNode = Workspace->Nodes.TakeElement();
|
||||||
NewNode->SpecificationIndex = NodeSpecificationIndex;
|
NewNode->SpecificationIndex = NodeSpecificationIndex;
|
||||||
|
@ -172,7 +172,7 @@ PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspac
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushNodeConnectionOnWorkspace(gs_list_handle UpstreamNodeHandle, u32 UpstreamPortIndex, gs_list_handle DownstreamNodeHandle, u32 DownstreamPortIndex, pattern_node_workspace* Workspace, memory_arena* Scratch)
|
PushNodeConnectionOnWorkspace(gs_list_handle UpstreamNodeHandle, u32 UpstreamPortIndex, gs_list_handle DownstreamNodeHandle, u32 DownstreamPortIndex, pattern_node_workspace* Workspace, gs_memory_arena* Scratch)
|
||||||
{
|
{
|
||||||
pattern_node_connection Connection = {};
|
pattern_node_connection Connection = {};
|
||||||
Connection.UpstreamNodeHandle = UpstreamNodeHandle;
|
Connection.UpstreamNodeHandle = UpstreamNodeHandle;
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct node_specification
|
||||||
struct node_specification_
|
struct node_specification_
|
||||||
{
|
{
|
||||||
node_type Type;
|
node_type Type;
|
||||||
string Identifier;
|
gs_string Identifier;
|
||||||
gsm_struct_type DataType;
|
gsm_struct_type DataType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ struct pattern_node_workspace
|
||||||
// This is storage for all the structures which follow.
|
// This is storage for all the structures which follow.
|
||||||
// It is cleared when new nodes are added so that the
|
// It is cleared when new nodes are added so that the
|
||||||
// acceleration structures can be recalculated
|
// acceleration structures can be recalculated
|
||||||
memory_arena Storage;
|
gs_memory_arena Storage;
|
||||||
s32* SparseToSortedNodeMap;
|
s32* SparseToSortedNodeMap;
|
||||||
gs_list_handle* SortedNodeHandles;
|
gs_list_handle* SortedNodeHandles;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct operation_mode
|
||||||
{
|
{
|
||||||
input_command_registry Commands;
|
input_command_registry Commands;
|
||||||
operation_render_proc* Render;
|
operation_render_proc* Render;
|
||||||
|
gs_memory_cursor Memory;
|
||||||
u8* OpStateMemory;
|
u8* OpStateMemory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,28 +25,66 @@ struct operation_mode_system
|
||||||
{
|
{
|
||||||
s32 ActiveModesCount;
|
s32 ActiveModesCount;
|
||||||
operation_mode ActiveModes[OPERATION_MODES_MAX];
|
operation_mode ActiveModes[OPERATION_MODES_MAX];
|
||||||
arena_snapshot ModeMemorySnapshots[OPERATION_MODES_MAX];
|
//arena_snapshot ModeMemorySnapshots[OPERATION_MODES_MAX];
|
||||||
|
gs_data_array ModeMemoryPagesFreeList;
|
||||||
|
|
||||||
// NOTE(Peter): This acts as mode scoped memory. When a mode gets activated, it can allocate
|
// NOTE(Peter): This acts as mode scoped memory. When a mode gets activated, it can allocate
|
||||||
// temporary memory which then gets freed when the mode is deactivated
|
// temporary memory which then gets freed when the mode is deactivated
|
||||||
memory_arena Arena;
|
gs_memory_arena Arena;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal operation_mode_system
|
||||||
|
OperationModeSystemInit(gs_memory_arena* Storage, gs_thread_context ThreadContext)
|
||||||
|
{
|
||||||
|
operation_mode_system Result = {0};
|
||||||
|
// TODO(Peter): Do we really need an arena? Can this just operate in constant memory footprint?
|
||||||
|
Result.Arena.Allocator = ThreadContext.Allocator;
|
||||||
|
|
||||||
|
Result.ModeMemoryPagesFreeList.CountMax = 16; // TODO(Peter): Static number of modes that can be active simultaneously
|
||||||
|
Result.ModeMemoryPagesFreeList.Data = PushArray(Storage, gs_data, Result.ModeMemoryPagesFreeList.CountMax);
|
||||||
|
for (u32 Page = 0; Page < Result.ModeMemoryPagesFreeList.CountMax; Page++)
|
||||||
|
{
|
||||||
|
// TODO(Peter): 4k pages = page size on windows
|
||||||
|
Result.ModeMemoryPagesFreeList.Data[Page] = PushSizeToData(Storage, KB(4));
|
||||||
|
}
|
||||||
|
Result.ModeMemoryPagesFreeList.Count = Result.ModeMemoryPagesFreeList.CountMax;
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal gs_data
|
||||||
|
OperationModeTakeMemoryPage(operation_mode_system* System)
|
||||||
|
{
|
||||||
|
Assert(System->ModeMemoryPagesFreeList.Count > 0);
|
||||||
|
gs_data Result = {0};
|
||||||
|
System->ModeMemoryPagesFreeList.Count -= 1;
|
||||||
|
u64 LastIndex = System->ModeMemoryPagesFreeList.Count;
|
||||||
|
Result = System->ModeMemoryPagesFreeList.Data[LastIndex];
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
OperationModeFreeMemoryPage(operation_mode_system* System, gs_data Data)
|
||||||
|
{
|
||||||
|
Assert(System->ModeMemoryPagesFreeList.Count < System->ModeMemoryPagesFreeList.CountMax);
|
||||||
|
u64 LastIndex = System->ModeMemoryPagesFreeList.Count;
|
||||||
|
System->ModeMemoryPagesFreeList.Count += 1;
|
||||||
|
System->ModeMemoryPagesFreeList.Data[LastIndex] = Data;
|
||||||
|
}
|
||||||
|
|
||||||
internal operation_mode*
|
internal operation_mode*
|
||||||
ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc)
|
ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc)
|
||||||
{
|
{
|
||||||
operation_mode* Result = 0;
|
|
||||||
|
|
||||||
Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
|
Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
|
||||||
|
operation_mode* Result = 0;
|
||||||
s32 ModeIndex = System->ActiveModesCount++;
|
s32 ModeIndex = System->ActiveModesCount++;
|
||||||
|
|
||||||
System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena);
|
//System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena);
|
||||||
|
|
||||||
operation_mode NewMode = {};
|
|
||||||
System->ActiveModes[ModeIndex] = NewMode;
|
|
||||||
|
|
||||||
Result = &System->ActiveModes[ModeIndex];
|
Result = &System->ActiveModes[ModeIndex];
|
||||||
|
Result->Memory = CreateMemoryCursor(OperationModeTakeMemoryPage(System));
|
||||||
Result->Render = RenderProc;
|
Result->Render = RenderProc;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,13 +96,18 @@ ActivateOperationModeWithCommands_(operation_mode_system* System, input_command*
|
||||||
{
|
{
|
||||||
operation_mode* NewMode = ActivateOperationMode(System, RenderProc);
|
operation_mode* NewMode = ActivateOperationMode(System, RenderProc);
|
||||||
|
|
||||||
|
#if 0
|
||||||
InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena);
|
InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena);
|
||||||
for (s32 i = 0; i < CommandsCount; i++)
|
for (s32 i = 0; i < CommandsCount; i++)
|
||||||
{
|
{
|
||||||
input_command Command = Commands[i];
|
input_command Command = Commands[i];
|
||||||
RegisterKeyPressCommand(&NewMode->Commands, Command.Key, Command.Flags, Command.Mdfr, Command.Proc);
|
RegisterKeyPressCommand(&NewMode->Commands, Command.Key, Command.Flags, Command.Mdfr, Command.Proc);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
NewMode->Commands.Commands = Commands;
|
||||||
|
NewMode->Commands.Size = CommandsCount;
|
||||||
|
NewMode->Commands.Used = CommandsCount;
|
||||||
|
#endif
|
||||||
return NewMode;
|
return NewMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +116,8 @@ DeactivateCurrentOperationMode (operation_mode_system* System)
|
||||||
{
|
{
|
||||||
Assert(System->ActiveModesCount > 0);
|
Assert(System->ActiveModesCount > 0);
|
||||||
s32 ModeIndex = --System->ActiveModesCount;
|
s32 ModeIndex = --System->ActiveModesCount;
|
||||||
ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]);
|
OperationModeFreeMemoryPage(System, System->ActiveModes[ModeIndex].Memory.Data);
|
||||||
|
//ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CreateOperationState(mode, modeSystem, stateType) \
|
#define CreateOperationState(mode, modeSystem, stateType) \
|
||||||
|
@ -85,8 +130,12 @@ DeactivateCurrentOperationMode (operation_mode_system* System)
|
||||||
internal u8*
|
internal u8*
|
||||||
CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize)
|
CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize)
|
||||||
{
|
{
|
||||||
Mode->OpStateMemory = PushSize(&System->Arena, StateSize);
|
// NOTE(Peter): This isn't a problem if this fires, it just means our page size is too small,
|
||||||
return Mode->OpStateMemory;
|
// and its time to make the pages dynamically sized
|
||||||
|
Assert(Mode->Memory.Data.Size >= StateSize);
|
||||||
|
u8* Result = PushSizeOnCursor(&Mode->Memory, StateSize).Memory;
|
||||||
|
Mode->OpStateMemory = Result;
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct panel_system
|
||||||
struct panel_with_layout
|
struct panel_with_layout
|
||||||
{
|
{
|
||||||
panel* Panel;
|
panel* Panel;
|
||||||
rect Bounds;
|
rect2 Bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct panel_layout
|
struct panel_layout
|
||||||
|
@ -205,56 +205,56 @@ ConsolidatePanelsKeepOne(panel* Parent, panel_entry* PanelEntryToKeep, panel_sys
|
||||||
//
|
//
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
GetTopPanelBounds(panel* Panel, rect PanelBounds)
|
GetTopPanelBounds(panel* Panel, rect2 PanelBounds)
|
||||||
{
|
{
|
||||||
rect Result = {};
|
rect2 Result = {};
|
||||||
Result.Min = v2{
|
Result.Min = v2{
|
||||||
PanelBounds.Min.x,
|
PanelBounds.Min.x,
|
||||||
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent)
|
LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y)
|
||||||
};
|
};
|
||||||
Result.Max = PanelBounds.Max;
|
Result.Max = PanelBounds.Max;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
GetBottomPanelBounds(panel* Panel, rect PanelBounds)
|
GetBottomPanelBounds(panel* Panel, rect2 PanelBounds)
|
||||||
{
|
{
|
||||||
rect Result = {};
|
rect2 Result = {};
|
||||||
Result.Min = PanelBounds.Min;
|
Result.Min = PanelBounds.Min;
|
||||||
Result.Max = v2{
|
Result.Max = v2{
|
||||||
PanelBounds.Max.x,
|
PanelBounds.Max.x,
|
||||||
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent)
|
LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y)
|
||||||
};
|
};
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
GetRightPanelBounds(panel* Panel, rect PanelBounds)
|
GetRightPanelBounds(panel* Panel, rect2 PanelBounds)
|
||||||
{
|
{
|
||||||
rect Result = {};
|
rect2 Result = {};
|
||||||
Result.Min = v2{
|
Result.Min = v2{
|
||||||
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent),
|
LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x),
|
||||||
PanelBounds.Min.y
|
PanelBounds.Min.y
|
||||||
};
|
};
|
||||||
Result.Max = PanelBounds.Max;
|
Result.Max = PanelBounds.Max;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
GetLeftPanelBounds(panel* Panel, rect PanelBounds)
|
GetLeftPanelBounds(panel* Panel, rect2 PanelBounds)
|
||||||
{
|
{
|
||||||
rect Result = {};
|
rect2 Result = {};
|
||||||
Result.Min = PanelBounds.Min;
|
Result.Min = PanelBounds.Min;
|
||||||
Result.Max = v2{
|
Result.Max = v2{
|
||||||
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent),
|
LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x),
|
||||||
PanelBounds.Max.y
|
PanelBounds.Max.y
|
||||||
};
|
};
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
LayoutPanel(panel* Panel, rect PanelBounds, panel_layout* Layout)
|
LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout)
|
||||||
{
|
{
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
||||||
{
|
{
|
||||||
|
@ -264,22 +264,22 @@ LayoutPanel(panel* Panel, rect PanelBounds, panel_layout* Layout)
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||||
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||||
LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout);
|
LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout);
|
||||||
LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout);
|
LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout);
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||||
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||||
LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout);
|
LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout);
|
||||||
LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout);
|
LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_layout
|
internal panel_layout
|
||||||
GetPanelLayout(panel_system* System, rect WindowBounds, memory_arena* Storage)
|
GetPanelLayout(panel_system* System, rect2 WindowBounds, gs_memory_arena* Storage)
|
||||||
{
|
{
|
||||||
panel_layout Result = {};
|
panel_layout Result = {};
|
||||||
Result.PanelsMax = System->PanelsUsed;
|
Result.PanelsMax = System->PanelsUsed;
|
||||||
|
@ -293,11 +293,11 @@ GetPanelLayout(panel_system* System, rect WindowBounds, memory_arena* Storage)
|
||||||
struct panel_and_bounds
|
struct panel_and_bounds
|
||||||
{
|
{
|
||||||
panel* Panel;
|
panel* Panel;
|
||||||
rect Bounds;
|
rect2 Bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal panel_and_bounds
|
internal panel_and_bounds
|
||||||
GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
|
GetPanelContainingPoint(v2 Point, panel* Panel, rect2 PanelBounds)
|
||||||
{
|
{
|
||||||
panel_and_bounds Result = {0};
|
panel_and_bounds Result = {0};
|
||||||
|
|
||||||
|
@ -308,28 +308,28 @@ GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
||||||
{
|
{
|
||||||
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
||||||
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
||||||
|
|
||||||
if (PointIsInRange(Point, TopPanelBounds.Min, TopPanelBounds.Max))
|
if (PointIsInRect(TopPanelBounds, Point))
|
||||||
{
|
{
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds);
|
Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds);
|
||||||
}
|
}
|
||||||
else if (PointIsInRange(Point, BottomPanelBounds.Min, BottomPanelBounds.Max))
|
else if (PointIsInRect(BottomPanelBounds, Point))
|
||||||
{
|
{
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds);
|
Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
{
|
{
|
||||||
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
||||||
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
||||||
|
|
||||||
if (PointIsInRange(Point, LeftPanelBounds.Min, LeftPanelBounds.Max))
|
if (PointIsInRect(LeftPanelBounds, Point))
|
||||||
{
|
{
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds);
|
Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds);
|
||||||
}
|
}
|
||||||
else if (PointIsInRange(Point, RightPanelBounds.Min, RightPanelBounds.Max))
|
else if (PointIsInRect(RightPanelBounds, Point))
|
||||||
{
|
{
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds);
|
Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds);
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_and_bounds
|
internal panel_and_bounds
|
||||||
GetPanelContainingPoint(v2 Point, panel_system* PanelSystem, rect WindowBounds)
|
GetPanelContainingPoint(v2 Point, panel_system* PanelSystem, rect2 WindowBounds)
|
||||||
{
|
{
|
||||||
panel_and_bounds Result = {0};
|
panel_and_bounds Result = {0};
|
||||||
if (PanelSystem->PanelsUsed > 0)
|
if (PanelSystem->PanelsUsed > 0)
|
||||||
|
|
|
@ -7,22 +7,30 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#define GS_LANGUAGE_NO_PROFILER_DEFINES
|
#include <math.h> // TODO Remove
|
||||||
#include "..\gs_libs\gs_language.h"
|
|
||||||
|
|
||||||
#include "..\gs_libs\gs_radix_sort.h"
|
#include "..\gs_libs\gs_types.h"
|
||||||
|
#include "..\gs_libs\gs_types.cpp"
|
||||||
|
|
||||||
|
//#define GS_LANGUAGE_NO_PROFILER_DEFINES
|
||||||
|
//#include "..\gs_libs\gs_language.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#include "..\gs_libs\gs_radix_sort.h"
|
||||||
#include "..\gs_libs\gs_list.h"
|
#include "..\gs_libs\gs_list.h"
|
||||||
#include "..\gs_libs\gs_bucket.h"
|
#include "..\gs_libs\gs_bucket.h"
|
||||||
|
|
||||||
#define GS_MEMORY_TRACK_ALLOCATIONS
|
//#define GS_MEMORY_TRACK_ALLOCATIONS
|
||||||
#include "..\gs_libs\gs_memory_arena.h"
|
//#include "..\gs_libs\gs_memory_arena.h"
|
||||||
|
|
||||||
#include "..\gs_libs\gs_string.h"
|
#include "..\gs_libs\gs_string.h"
|
||||||
|
|
||||||
#include "foldhaus_debug.h"
|
|
||||||
global_variable debug_services* GlobalDebugServices;
|
|
||||||
|
|
||||||
#include "..\gs_libs\gs_vector_matrix.h"
|
|
||||||
|
#include "foldhaus_debug.h"
|
||||||
|
global debug_services* GlobalDebugServices;
|
||||||
|
|
||||||
|
//#include "..\gs_libs\gs_vector_matrix.h"
|
||||||
#include "..\gs_libs\gs_input.h"
|
#include "..\gs_libs\gs_input.h"
|
||||||
|
|
||||||
#include "foldhaus_renderer.h"
|
#include "foldhaus_renderer.h"
|
||||||
|
@ -75,15 +83,6 @@ struct platform_memory_result
|
||||||
platform_memory_error Error;
|
platform_memory_error Error;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct texture_buffer
|
|
||||||
{
|
|
||||||
u8* Memory;
|
|
||||||
s32 Width;
|
|
||||||
s32 Height;
|
|
||||||
s32 Pitch;
|
|
||||||
s32 BytesPerPixel;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct system_path
|
struct system_path
|
||||||
{
|
{
|
||||||
char* Path;
|
char* Path;
|
||||||
|
@ -91,20 +90,13 @@ struct system_path
|
||||||
s32 IndexOfLastSlash;
|
s32 IndexOfLastSlash;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PLATFORM_READ_ENTIRE_FILE(name) platform_memory_result name(string Path)
|
struct texture_buffer
|
||||||
typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file);
|
|
||||||
|
|
||||||
#define PLATFORM_WRITE_ENTIRE_FILE(name) b32 name(string Path, u8* Contents, s32 Size)
|
|
||||||
typedef PLATFORM_WRITE_ENTIRE_FILE(platform_write_entire_file);
|
|
||||||
|
|
||||||
#define PLATFORM_GET_FILE_PATH(name) b32 name(string* PathBuffer, const char* FilterStrings)
|
|
||||||
typedef PLATFORM_GET_FILE_PATH(platform_get_file_path);
|
|
||||||
|
|
||||||
struct platform_file_handler
|
|
||||||
{
|
{
|
||||||
platform_read_entire_file* ReadEntireFile;
|
u8* Memory;
|
||||||
platform_write_entire_file* WriteEntireFile;
|
s32 Width;
|
||||||
platform_get_file_path* GetFilePath;
|
s32 Height;
|
||||||
|
s32 Pitch;
|
||||||
|
s32 BytesPerPixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height)
|
#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height)
|
||||||
|
@ -169,50 +161,11 @@ typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint);
|
||||||
|
|
||||||
#define PLATFORM_THREAD_COUNT 4
|
#define PLATFORM_THREAD_COUNT 4
|
||||||
|
|
||||||
#define THREADED_WORK_PROC(name) void name(s32 ThreadID, void* Data)
|
|
||||||
typedef THREADED_WORK_PROC(threaded_work_proc);
|
|
||||||
|
|
||||||
typedef struct work_queue work_queue;
|
|
||||||
|
|
||||||
#define PUSH_WORK_ON_QUEUE(name) void name(work_queue* Queue, threaded_work_proc* WorkProc, void* Data, char* JobName)
|
|
||||||
typedef PUSH_WORK_ON_QUEUE(push_work_on_queue);
|
|
||||||
|
|
||||||
#define DO_QUEUE_WORK_UNTIL_DONE(name) void name(work_queue* Queue, s32 ThreadID)
|
|
||||||
typedef DO_QUEUE_WORK_UNTIL_DONE(do_queue_work_until_done);
|
|
||||||
|
|
||||||
#define RESET_WORK_QUEUE(name) void name(work_queue* Queue)
|
|
||||||
typedef RESET_WORK_QUEUE(reset_work_queue);
|
|
||||||
|
|
||||||
struct worker_thread_job
|
|
||||||
{
|
|
||||||
void* Data;
|
|
||||||
threaded_work_proc* WorkProc;
|
|
||||||
#ifdef DEBUG
|
|
||||||
char* JobName;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct work_queue
|
|
||||||
{
|
|
||||||
void* SemaphoreHandle;
|
|
||||||
|
|
||||||
u32 JobsMax;
|
|
||||||
u32 volatile JobsCount;
|
|
||||||
u32 volatile NextJobIndex;
|
|
||||||
u32 volatile JobsCompleted;
|
|
||||||
worker_thread_job* Jobs;
|
|
||||||
|
|
||||||
// Work Queue
|
|
||||||
push_work_on_queue* PushWorkOnQueue;
|
|
||||||
do_queue_work_until_done* DoQueueWorkUntilDone;
|
|
||||||
reset_work_queue* ResetWorkQueue;
|
|
||||||
};
|
|
||||||
|
|
||||||
RESET_WORK_QUEUE(ResetWorkQueue)
|
RESET_WORK_QUEUE(ResetWorkQueue)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < Queue->JobsMax; i++)
|
for (u32 i = 0; i < Queue->JobsMax; i++)
|
||||||
{
|
{
|
||||||
Queue->Jobs[i].Data = 0;
|
Queue->Jobs[i].Data = {0};
|
||||||
Queue->Jobs[i].WorkProc = 0;
|
Queue->Jobs[i].WorkProc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,11 +185,13 @@ GetSecondsElapsed (s64 Start, s64 End, s64 PerformanceCountFrequency)
|
||||||
|
|
||||||
struct context
|
struct context
|
||||||
{
|
{
|
||||||
|
gs_thread_context ThreadContext;
|
||||||
|
|
||||||
u8* MemoryBase;
|
u8* MemoryBase;
|
||||||
u32 MemorySize;
|
u32 MemorySize;
|
||||||
|
|
||||||
b32 WindowIsVisible;
|
b32 WindowIsVisible;
|
||||||
rect WindowBounds;
|
rect2 WindowBounds;
|
||||||
r32 DeltaTime;
|
r32 DeltaTime;
|
||||||
mouse_state Mouse;
|
mouse_state Mouse;
|
||||||
|
|
||||||
|
@ -247,59 +202,18 @@ struct context
|
||||||
cleanup_application* CleanupApplication;
|
cleanup_application* CleanupApplication;
|
||||||
|
|
||||||
// Platform Services
|
// Platform Services
|
||||||
work_queue* GeneralWorkQueue;
|
gs_work_queue* GeneralWorkQueue;
|
||||||
|
|
||||||
platform_memory_handler PlatformMemory;
|
|
||||||
platform_file_handler FileHandler;
|
|
||||||
|
|
||||||
platform_write_entire_file* PlatformWriteEntireFile;
|
|
||||||
platform_get_file_path* PlatformGetFilePath;
|
|
||||||
platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle;
|
platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle;
|
||||||
platform_get_font_info* PlatformGetFontInfo;
|
platform_get_font_info* PlatformGetFontInfo;
|
||||||
platform_draw_font_codepoint* PlatformDrawFontCodepoint;
|
platform_draw_font_codepoint* PlatformDrawFontCodepoint;
|
||||||
|
|
||||||
platform_get_socket_handle* PlatformGetSocketHandle;
|
platform_get_socket_handle* PlatformGetSocketHandle;
|
||||||
platform_set_socket_option* PlatformSetSocketOption;
|
platform_set_socket_option* PlatformSetSocketOption;
|
||||||
platform_send_to* PlatformSendTo;
|
platform_send_to* PlatformSendTo;
|
||||||
platform_close_socket* PlatformCloseSocket;
|
platform_close_socket* PlatformCloseSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
// File Handler
|
|
||||||
internal platform_memory_result
|
|
||||||
ReadEntireFile(platform_file_handler FileHandler, string Path)
|
|
||||||
{
|
|
||||||
platform_memory_result Result = FileHandler.ReadEntireFile(Path);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
internal platform_memory_result
|
|
||||||
ReadEntireFile(context Context, string Path)
|
|
||||||
{
|
|
||||||
return ReadEntireFile(Context.FileHandler, Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
WriteEntireFile(platform_file_handler FileHandler, string Path, u8* Contents, u32 Size)
|
|
||||||
{
|
|
||||||
b32 Result = FileHandler.WriteEntireFile(Path, Contents, Size);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
internal b32
|
|
||||||
WriteEntireFile(context Context, string Path, u8* Contents, u32 Size)
|
|
||||||
{
|
|
||||||
return WriteEntireFile(Context.FileHandler, Path, Contents, Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
GetFilePath(platform_file_handler FileHandler, string* PathBuffer, char* FilterStrings)
|
|
||||||
{
|
|
||||||
b32 Result = FileHandler.GetFilePath(PathBuffer, (const char*)FilterStrings);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
internal b32
|
|
||||||
GetFilePath(context Context, string* PathBuffer, char* FilterStrings)
|
|
||||||
{
|
|
||||||
return GetFilePath(Context.FileHandler, PathBuffer, FilterStrings);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define FOLDHAUS_PLATFORM_H
|
#define FOLDHAUS_PLATFORM_H
|
||||||
#endif // FOLDHAUS_PLATFORM_H
|
#endif // FOLDHAUS_PLATFORM_H
|
|
@ -110,8 +110,8 @@ RenderCommandBuffer (render_command_buffer CommandBuffer)
|
||||||
glViewport(Command->ViewOffsetX, Command->ViewOffsetY,
|
glViewport(Command->ViewOffsetX, Command->ViewOffsetY,
|
||||||
Command->ViewWidth, Command->ViewHeight);
|
Command->ViewWidth, Command->ViewHeight);
|
||||||
|
|
||||||
LoadModelView(Command->ModelView.E);
|
LoadModelView(Command->ModelView.Array);
|
||||||
LoadProjection(Command->Projection.E);
|
LoadProjection(Command->Projection.Array);
|
||||||
|
|
||||||
if (Command->UseDepthBuffer)
|
if (Command->UseDepthBuffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,65 +19,71 @@ struct camera
|
||||||
inline m44
|
inline m44
|
||||||
GetCameraModelViewMatrix (camera Camera)
|
GetCameraModelViewMatrix (camera Camera)
|
||||||
{
|
{
|
||||||
#if 0
|
m44 RotationMatrix = M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt));
|
||||||
// Forward
|
m44 PositionMatrix = M44Translation(ToV4Point(-Camera.Position));
|
||||||
v4 CamForward = V4(Normalize(Camera.Position - Camera.LookAt), 0);
|
m44 ModelViewMatrix = RotationMatrix * PositionMatrix;
|
||||||
// Right
|
|
||||||
v4 CamRight = Normalize(Cross(v4{0, 1, 0, 0}, CamForward));
|
|
||||||
// Up
|
|
||||||
v4 CamUp = Normalize(Cross(CamForward, CamRight));
|
|
||||||
|
|
||||||
r32 X = Camera.Position.x;
|
|
||||||
r32 Y = Camera.Position.y;
|
|
||||||
r32 Z = Camera.Position.z;
|
|
||||||
|
|
||||||
m44 RotationMatrix = M44(
|
|
||||||
CamRight.x, CamUp.x, CamForward.x, 0,
|
|
||||||
CamRight.y, CamUp.y, CamForward.y, 0,
|
|
||||||
CamRight.z, CamUp.z, CamForward.z, 0,
|
|
||||||
0, 0, 0, 1);
|
|
||||||
|
|
||||||
m44 PositionMatrix = M44(
|
|
||||||
1, 0, 0, 0,
|
|
||||||
0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
-X, -Y, -Z, 1
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
m44 RotationMatrix = GetLookAtMatrix(V4(Camera.Position, 1), V4(Camera.LookAt, 1));
|
|
||||||
m44 PositionMatrix = GetPositionM44(V4(Camera.Position, 1));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m44 ModelViewMatrix = PositionMatrix * RotationMatrix;
|
|
||||||
|
|
||||||
return ModelViewMatrix;
|
return ModelViewMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline m44
|
inline m44
|
||||||
GetCameraPerspectiveProjectionMatrix(camera Camera)
|
GetCameraPerspectiveProjectionMatrix(camera Camera)
|
||||||
{
|
{
|
||||||
r32 Top = Camera.Near * GSTan((Camera.FieldOfView / 2.0f));
|
m44 Result = M44ProjectionPerspective(Camera.FieldOfView, Camera.AspectRatio, Camera.Near, Camera.Far);
|
||||||
r32 Bottom = -Top;
|
return Result;
|
||||||
r32 Right = Top * Camera.AspectRatio;
|
}
|
||||||
r32 Left = -Right;
|
|
||||||
|
|
||||||
r32 A = ((Right + Left) / (Right - Left));
|
internal m44
|
||||||
r32 B = ((Top + Bottom) / (Top - Bottom));
|
GetCameraMatrix(camera Camera)
|
||||||
r32 C = -((Camera.Far + Camera.Near) / (Camera.Far - Camera.Near));
|
|
||||||
r32 D = -((2 * Camera.Far * Camera.Near) / (Camera.Far - Camera.Near));
|
|
||||||
|
|
||||||
r32 E = ((2 * Camera.Near) / (Right - Left));
|
|
||||||
r32 F = ((2 * Camera.Near) / (Top - Bottom));
|
|
||||||
|
|
||||||
m44 PerspectiveProjectionMatrix =
|
|
||||||
{
|
{
|
||||||
E, 0, A, 0,
|
m44 ModelView = GetCameraModelViewMatrix(Camera);
|
||||||
0, F, B, 0,
|
m44 Projection = GetCameraPerspectiveProjectionMatrix(Camera);
|
||||||
0, 0, C, D,
|
m44 Result = Projection * ModelView;
|
||||||
0, 0, -1, 0
|
return Result;
|
||||||
};
|
}
|
||||||
|
|
||||||
return PerspectiveProjectionMatrix;
|
internal v2
|
||||||
|
ProjectWorldPointToScreen(v4 WorldSpacePoint, camera Camera, rect2 WindowBounds)
|
||||||
|
{
|
||||||
|
v2 WindowExtents = v2{Rect2Width(WindowBounds), Rect2Height(WindowBounds)};
|
||||||
|
v4 ProjectedPosition = GetCameraMatrix(Camera) * WorldSpacePoint;
|
||||||
|
ProjectedPosition.xyz /= ProjectedPosition.w;
|
||||||
|
v2 ScreenPosition = V2MultiplyPairwise(ProjectedPosition.xy, (WindowExtents / 2)) + (WindowExtents / 2);
|
||||||
|
|
||||||
|
return ScreenPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v4_ray
|
||||||
|
ProjectScreenPointToWorldRay(v2 ScreenPoint, camera Camera, rect2 WindowBounds)
|
||||||
|
{
|
||||||
|
v4_ray Result = {0};
|
||||||
|
|
||||||
|
r32 TanFOVOverTwo = TanR32(DegToRadR32(Camera.FieldOfView / 2.0f));
|
||||||
|
r32 Aspect = RectAspectRatio(WindowBounds);
|
||||||
|
|
||||||
|
r32 NormalizedX = ScreenPoint.x / Rect2Width(WindowBounds);
|
||||||
|
r32 NormalizedY = ScreenPoint.y / Rect2Height(WindowBounds);
|
||||||
|
|
||||||
|
r32 CenteredX = (2.0f * NormalizedX) - 1.0f;
|
||||||
|
r32 CenteredY = (2.0f * NormalizedY) - 1.0f;
|
||||||
|
|
||||||
|
r32 ScaledX = CenteredX * Aspect;
|
||||||
|
r32 ScaledY = CenteredY;
|
||||||
|
|
||||||
|
r32 CameraX = ScaledX * TanFOVOverTwo;
|
||||||
|
r32 CameraY = ScaledY * TanFOVOverTwo;
|
||||||
|
|
||||||
|
r32 Near = Camera.Near;
|
||||||
|
r32 Far = Camera.Far;
|
||||||
|
v3 MousePointOnNearPlane = v3{CameraX, CameraY, -1} * Near;
|
||||||
|
v3 MousePointOnFarPlane = v3{CameraX, CameraY, -1} * Far;
|
||||||
|
|
||||||
|
v4 MouseRayDirection = ToV4Vec(V3Normalize(MousePointOnFarPlane - MousePointOnNearPlane));
|
||||||
|
m44 CameraTransform = M44Transpose(M44LookAt(ToV4Point(Camera.Position), ToV4Point(Camera.LookAt)));
|
||||||
|
|
||||||
|
Result.Origin = ToV4Point(Camera.Position);
|
||||||
|
Result.Direction = CameraTransform * MouseRayDirection;
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render Commands
|
// Render Commands
|
||||||
|
@ -200,7 +206,7 @@ struct render_command_set_render_mode
|
||||||
|
|
||||||
typedef u8* renderer_realloc(u8* Base, s32 CurrentSize, s32 NewSize);
|
typedef u8* renderer_realloc(u8* Base, s32 CurrentSize, s32 NewSize);
|
||||||
|
|
||||||
#define COMMAND_BUFFER_MIN_GROW_SIZE Megabytes(2)
|
#define COMMAND_BUFFER_MIN_GROW_SIZE MB(2)
|
||||||
|
|
||||||
struct render_command_buffer
|
struct render_command_buffer
|
||||||
{
|
{
|
||||||
|
@ -257,7 +263,7 @@ ResizeBufferIfNecessary(render_command_buffer* Buffer, s32 DataSize)
|
||||||
// NewSize = Buffer->CommandMemorySize + (2 * DataSize);
|
// NewSize = Buffer->CommandMemorySize + (2 * DataSize);
|
||||||
s32 SpaceAvailable = Buffer->CommandMemorySize - Buffer->CommandMemoryUsed;
|
s32 SpaceAvailable = Buffer->CommandMemorySize - Buffer->CommandMemoryUsed;
|
||||||
s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point
|
s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point
|
||||||
s32 AdditionSize = GSMax(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
|
s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
|
||||||
s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
|
s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
|
||||||
Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory,
|
Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory,
|
||||||
Buffer->CommandMemorySize,
|
Buffer->CommandMemorySize,
|
||||||
|
@ -285,7 +291,7 @@ PushQuad3DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* C
|
||||||
internal s32
|
internal s32
|
||||||
PushQuad2DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* Constructor, s32 QuadCount, s32 DataSize, u8* MemStart)
|
PushQuad2DBatch (render_command_buffer* Buffer, render_quad_batch_constructor* Constructor, s32 QuadCount, s32 DataSize, u8* MemStart)
|
||||||
{
|
{
|
||||||
GSZeroMemory(MemStart, DataSize);
|
ZeroMemoryBlock(MemStart, DataSize);
|
||||||
|
|
||||||
Constructor->Max = QuadCount;
|
Constructor->Max = QuadCount;
|
||||||
Constructor->Count = 0;
|
Constructor->Count = 0;
|
||||||
|
@ -316,6 +322,15 @@ struct quad_batch_constructor_reserved_range
|
||||||
s32 OnePastLast;
|
s32 OnePastLast;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal quad_batch_constructor_reserved_range
|
||||||
|
ReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded)
|
||||||
|
{
|
||||||
|
quad_batch_constructor_reserved_range Result = {};
|
||||||
|
Result.OnePastLast = Constructor->Count + TrisNeeded;
|
||||||
|
Result.Start = Result.OnePastLast - TrisNeeded;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal quad_batch_constructor_reserved_range
|
internal quad_batch_constructor_reserved_range
|
||||||
ThreadSafeReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded)
|
ThreadSafeReserveRangeInQuadConstructor(render_quad_batch_constructor* Constructor, s32 TrisNeeded)
|
||||||
{
|
{
|
||||||
|
@ -331,6 +346,8 @@ SetTri3DInBatch (render_quad_batch_constructor* Constructor, s32 TriIndex,
|
||||||
v2 UV0, v2 UV1, v2 UV2,
|
v2 UV0, v2 UV1, v2 UV2,
|
||||||
v4 C0, v4 C1, v4 C2)
|
v4 C0, v4 C1, v4 C2)
|
||||||
{
|
{
|
||||||
|
//Assert(P0.w != 0 && P1.w != 0 && P2.w != 0); // Passing vectors, rather than positions. Will draw wrong
|
||||||
|
|
||||||
// Vertecies
|
// Vertecies
|
||||||
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 0)] = P0;
|
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 0)] = P0;
|
||||||
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 1)] = P1;
|
Constructor->Vertecies[BATCH_3D_VERTEX_INDEX(TriIndex, 1)] = P1;
|
||||||
|
@ -355,6 +372,7 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
|
||||||
v4 C0, v4 C1, v4 C2)
|
v4 C0, v4 C1, v4 C2)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
// TODO(Peter): I think we avoid doing cross thread filling of a batch so do we need this?
|
||||||
s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor);
|
s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor);
|
||||||
SetTri3DInBatch(Constructor, Tri, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
SetTri3DInBatch(Constructor, Tri, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
||||||
};
|
};
|
||||||
|
@ -362,7 +380,7 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
|
||||||
internal void
|
internal void
|
||||||
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color)
|
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color)
|
||||||
{
|
{
|
||||||
Assert(Constructor->Count + 2 < Constructor->Max);
|
Assert(Constructor->Count + 2 <= Constructor->Max);
|
||||||
PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color, Color, Color);
|
PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color, Color, Color);
|
||||||
PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color, Color, Color);
|
PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color, Color, Color);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +391,7 @@ PushQuad3DOnBatch (render_quad_batch_constructor* Constructor,
|
||||||
v2 UV0, v2 UV1, v2 UV2, v2 UV3,
|
v2 UV0, v2 UV1, v2 UV2, v2 UV3,
|
||||||
v4 C0, v4 C1, v4 C2, v4 C3)
|
v4 C0, v4 C1, v4 C2, v4 C3)
|
||||||
{
|
{
|
||||||
Assert(Constructor->Count < Constructor->Max);
|
Assert(Constructor->Count <= Constructor->Max);
|
||||||
PushTri3DOnBatch(Constructor, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
PushTri3DOnBatch(Constructor, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
||||||
PushTri3DOnBatch(Constructor, P0, P2, P3, UV0, UV2, UV3, C0, C2, C3);
|
PushTri3DOnBatch(Constructor, P0, P2, P3, UV0, UV2, UV3, C0, C2, C3);
|
||||||
}
|
}
|
||||||
|
@ -472,7 +490,7 @@ internal void
|
||||||
PushLine2DOnBatch (render_quad_batch_constructor* Constructor, v2 P0, v2 P1, r32 Thickness, v4 Color)
|
PushLine2DOnBatch (render_quad_batch_constructor* Constructor, v2 P0, v2 P1, r32 Thickness, v4 Color)
|
||||||
{
|
{
|
||||||
r32 HalfThickness = Thickness / 2.0f;
|
r32 HalfThickness = Thickness / 2.0f;
|
||||||
v2 Perpendicular = Normalize(PerpendicularCCW(P1 - P0)) * HalfThickness;
|
v2 Perpendicular = V2Normalize(V2PerpendicularCCW(P1 - P0)) * HalfThickness;
|
||||||
|
|
||||||
PushQuad2DOnBatch(Constructor, P0 - Perpendicular, P1 - Perpendicular, P1 + Perpendicular, P0 + Perpendicular,
|
PushQuad2DOnBatch(Constructor, P0 - Perpendicular, P1 - Perpendicular, P1 + Perpendicular, P0 + Perpendicular,
|
||||||
v2{0, 0}, v2{1, 1}, Color);
|
v2{0, 0}, v2{1, 1}, Color);
|
||||||
|
@ -501,8 +519,8 @@ PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
|
||||||
{
|
{
|
||||||
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
||||||
|
|
||||||
Command->ModelView = GetCameraModelViewMatrix(Camera);
|
Command->ModelView = M44Transpose(GetCameraModelViewMatrix(Camera));
|
||||||
Command->Projection = GetCameraPerspectiveProjectionMatrix(Camera);
|
Command->Projection = M44Transpose(GetCameraPerspectiveProjectionMatrix(Camera));
|
||||||
|
|
||||||
Command->ViewOffsetX = (r32)OffsetX;
|
Command->ViewOffsetX = (r32)OffsetX;
|
||||||
Command->ViewOffsetY = (r32)OffsetY;
|
Command->ViewOffsetY = (r32)OffsetY;
|
||||||
|
@ -514,25 +532,18 @@ PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
|
||||||
return Command;
|
return Command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
PushRenderPerspective(render_command_buffer* Buffer, rect2 Viewport, camera Camera)
|
||||||
|
{
|
||||||
|
PushRenderPerspective(Buffer, Viewport.Min.x, Viewport.Min.y, Rect2Width(Viewport), Rect2Height(Viewport), Camera);
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight)
|
PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight)
|
||||||
{
|
{
|
||||||
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
||||||
Command->ModelView = m44{
|
Command->ModelView = M44Identity();
|
||||||
1, 0, 0, 0,
|
Command->Projection = M44ProjectionOrtho((r32)ViewWidth, (r32)ViewHeight, 0, 100, ViewWidth, 0, ViewHeight, 0);
|
||||||
0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
0, 0, 0, 1
|
|
||||||
};
|
|
||||||
|
|
||||||
r32 a = 2.0f / ViewWidth;
|
|
||||||
r32 b = 2.0f / ViewHeight;
|
|
||||||
Command->Projection = m44{
|
|
||||||
a, 0, 0, 0,
|
|
||||||
0, b, 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
-1, -1, 0, 1
|
|
||||||
};
|
|
||||||
|
|
||||||
Command->ViewOffsetX = (r32)OffsetX;
|
Command->ViewOffsetX = (r32)OffsetX;
|
||||||
Command->ViewOffsetY = (r32)OffsetY;
|
Command->ViewOffsetY = (r32)OffsetY;
|
||||||
|
@ -542,6 +553,12 @@ PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY,
|
||||||
Command->UseDepthBuffer = false;;
|
Command->UseDepthBuffer = false;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
PushRenderOrthographic(render_command_buffer* Buffer, rect2 Viewport)
|
||||||
|
{
|
||||||
|
PushRenderOrthographic(Buffer, Viewport.Min.x, Viewport.Min.y, Rect2Width(Viewport), Rect2Height(Viewport));
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushRenderClearScreen (render_command_buffer* Buffer)
|
PushRenderClearScreen (render_command_buffer* Buffer)
|
||||||
{
|
{
|
||||||
|
@ -571,6 +588,13 @@ PushRenderQuad2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 Color)
|
||||||
PushQuad2DOnBatch(&Batch, Min, Max, Color);
|
PushQuad2DOnBatch(&Batch, Min, Max, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
PushRenderQuad2D(render_command_buffer* Buffer, v2 P0, v2 P1, v2 P2, v2 P3, v4 Color)
|
||||||
|
{
|
||||||
|
render_quad_batch_constructor Batch = PushRenderQuad2DBatch(Buffer, 1);
|
||||||
|
PushQuad2DOnBatch(&Batch, P0, P1, P2, P3, v2{0,0}, v2{1,1}, Color);
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushRenderLine2D (render_command_buffer* Buffer, v2 P0, v2 P1, r32 Thickness, v4 Color)
|
PushRenderLine2D (render_command_buffer* Buffer, v2 P0, v2 P1, r32 Thickness, v4 Color)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,42 +10,42 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <gs_string.h>
|
||||||
|
|
||||||
#include "gs/gs_language.h"
|
#include "gs/gs_language.h"
|
||||||
#include "gs/gs_string.h"
|
#include "gs/gs_string.h"
|
||||||
#include "../meta/gs_meta_lexer.h"
|
#include "../meta/gs_meta_lexer.h"
|
||||||
#include "gs/gs_vector.h"
|
#include "gs/gs_vector.h"
|
||||||
|
|
||||||
#define STRING_BUFFER_SIZE 512
|
#define gs_string_BUFFER_SIZE 512
|
||||||
struct string_buffer
|
struct gs_string_buffer
|
||||||
{
|
{
|
||||||
char* Memory;
|
char* Memory;
|
||||||
s32 Size;
|
s32 Size;
|
||||||
string_buffer* Next;
|
gs_string_buffer* Next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct string_writer
|
struct gs_string_writer
|
||||||
{
|
{
|
||||||
char* Cursor;
|
char* Cursor;
|
||||||
s32 UsedInString;
|
s32 UsedIngs_string;
|
||||||
string_buffer* Buffer;
|
gs_string_buffer* Buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal string_buffer*
|
internal gs_string_buffer*
|
||||||
GrowStringBuffer (string_buffer* Buffer)
|
Growgs_stringBuffer (gs_string_buffer* Buffer)
|
||||||
{
|
{
|
||||||
string_buffer* Result;
|
gs_string_buffer* Result;
|
||||||
if (Buffer->Next)
|
if (Buffer->Next)
|
||||||
{
|
{
|
||||||
Result = GrowStringBuffer(Buffer->Next);
|
Result = Growgs_stringBuffer(Buffer->Next);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Result = (string_buffer*)malloc(sizeof(string_buffer));
|
Result = (gs_string_buffer*)malloc(sizeof(gs_string_buffer));
|
||||||
Result->Memory = (char*)malloc(sizeof(char) * STRING_BUFFER_SIZE);
|
Result->Memory = (char*)malloc(sizeof(char) * gs_string_BUFFER_SIZE);
|
||||||
memset(Result->Memory, 0, STRING_BUFFER_SIZE);
|
memset(Result->Memory, 0, gs_string_BUFFER_SIZE);
|
||||||
Result->Size = STRING_BUFFER_SIZE;
|
Result->Size = gs_string_BUFFER_SIZE;
|
||||||
Result->Next = 0;
|
Result->Next = 0;
|
||||||
|
|
||||||
Buffer->Next = Result;
|
Buffer->Next = Result;
|
||||||
|
@ -54,28 +54,28 @@ GrowStringBuffer (string_buffer* Buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
WriteString(string_writer* Writer, char* String, s32 Length)
|
Writegs_string(gs_string_writer* Writer, char* gs_string, s32 Length)
|
||||||
{
|
{
|
||||||
char* Src = String;
|
char* Src = gs_string;
|
||||||
char* Dst = Writer->Cursor;
|
char* Dst = Writer->Cursor;
|
||||||
s32 LengthWritten = 0;
|
s32 LengthWritten = 0;
|
||||||
|
|
||||||
while (*Src && Writer->UsedInString < Writer->Buffer->Size &&LengthWritten < Length)
|
while (*Src && Writer->UsedIngs_string < Writer->Buffer->Size &&LengthWritten < Length)
|
||||||
{
|
{
|
||||||
LengthWritten++;
|
LengthWritten++;
|
||||||
*Dst++ = *Src++;
|
*Dst++ = *Src++;
|
||||||
Writer->UsedInString++;
|
Writer->UsedIngs_string++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Writer->Cursor = Dst;
|
Writer->Cursor = Dst;
|
||||||
|
|
||||||
if (*Src && Writer->UsedInString == Writer->Buffer->Size)
|
if (*Src && Writer->UsedIngs_string == Writer->Buffer->Size)
|
||||||
{
|
{
|
||||||
*(Dst - 1) = 0; // Null terminate the buffer
|
*(Dst - 1) = 0; // Null terminate the buffer
|
||||||
Writer->Buffer = GrowStringBuffer(Writer->Buffer);
|
Writer->Buffer = Growgs_stringBuffer(Writer->Buffer);
|
||||||
Writer->Cursor = Writer->Buffer->Memory;
|
Writer->Cursor = Writer->Buffer->Memory;
|
||||||
Writer->UsedInString = 0;
|
Writer->UsedIngs_string = 0;
|
||||||
WriteString(Writer, (Src - 1), (Length - LengthWritten) + 1);
|
Writegs_string(Writer, (Src - 1), (Length - LengthWritten) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,15 +141,15 @@ int main(int ArgCount, char* Args[])
|
||||||
control_box_pairs* StartPair = NextControlBoxPair;
|
control_box_pairs* StartPair = NextControlBoxPair;
|
||||||
s32 PairsCount = 0;
|
s32 PairsCount = 0;
|
||||||
|
|
||||||
if (StringsEqual(Tokenizer.At, "EOF"))
|
if (gs_stringsEqual(Tokenizer.At, "EOF"))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
EatToCharacterInclusive(&Tokenizer, '{');
|
EatToCharacterInclusive(&Tokenizer, '{');
|
||||||
EatWhitespace(&Tokenizer);
|
EatWhitespace(&Tokenizer);
|
||||||
Assert(StringsEqual(Tokenizer.At, "neighbors: ["));
|
Assert(gs_stringsEqual(Tokenizer.At, "neighbors: ["));
|
||||||
Tokenizer.At += StringLength("neighbors: [");
|
Tokenizer.At += gs_stringLength("neighbors: [");
|
||||||
|
|
||||||
// Parse Neighbors
|
// Parse Neighbors
|
||||||
while(*Tokenizer.At && *Tokenizer.At != ']')
|
while(*Tokenizer.At && *Tokenizer.At != ']')
|
||||||
|
@ -177,8 +177,8 @@ int main(int ArgCount, char* Args[])
|
||||||
EatWhitespace(&Tokenizer);
|
EatWhitespace(&Tokenizer);
|
||||||
|
|
||||||
//Parse IP
|
//Parse IP
|
||||||
Assert(StringsEqual(Tokenizer.At, "ip: "));
|
Assert(gs_stringsEqual(Tokenizer.At, "ip: "));
|
||||||
Tokenizer.At += StringLength("ip: ");
|
Tokenizer.At += gs_stringLength("ip: ");
|
||||||
NextControlBox->Address = (char*)malloc(sizeof(char) * 13);
|
NextControlBox->Address = (char*)malloc(sizeof(char) * 13);
|
||||||
memcpy(NextControlBox->Address, Tokenizer.At, 13);
|
memcpy(NextControlBox->Address, Tokenizer.At, 13);
|
||||||
Tokenizer.At += 13;
|
Tokenizer.At += 13;
|
||||||
|
@ -186,27 +186,27 @@ int main(int ArgCount, char* Args[])
|
||||||
|
|
||||||
// Parse X
|
// Parse X
|
||||||
EatWhitespace(&Tokenizer);
|
EatWhitespace(&Tokenizer);
|
||||||
Assert(StringsEqual(Tokenizer.At, "x: "));
|
Assert(gs_stringsEqual(Tokenizer.At, "x: "));
|
||||||
Tokenizer.At += StringLength("x: ");
|
Tokenizer.At += gs_stringLength("x: ");
|
||||||
NextControlBox->X = ParseFloat(Tokenizer.At);
|
NextControlBox->X = ParseFloat(Tokenizer.At);
|
||||||
EatToCharacterInclusive(&Tokenizer, ';');
|
EatToCharacterInclusive(&Tokenizer, ';');
|
||||||
// Parse Y
|
// Parse Y
|
||||||
EatWhitespace(&Tokenizer);
|
EatWhitespace(&Tokenizer);
|
||||||
Assert(StringsEqual(Tokenizer.At, "y: "));
|
Assert(gs_stringsEqual(Tokenizer.At, "y: "));
|
||||||
Tokenizer.At += StringLength("y: ");
|
Tokenizer.At += gs_stringLength("y: ");
|
||||||
NextControlBox->Y = ParseFloat(Tokenizer.At);
|
NextControlBox->Y = ParseFloat(Tokenizer.At);
|
||||||
EatToCharacterInclusive(&Tokenizer, ';');
|
EatToCharacterInclusive(&Tokenizer, ';');
|
||||||
// Parse Z
|
// Parse Z
|
||||||
EatWhitespace(&Tokenizer);
|
EatWhitespace(&Tokenizer);
|
||||||
Assert(StringsEqual(Tokenizer.At, "z: "));
|
Assert(gs_stringsEqual(Tokenizer.At, "z: "));
|
||||||
Tokenizer.At += StringLength("z: ");
|
Tokenizer.At += gs_stringLength("z: ");
|
||||||
NextControlBox->Z = ParseFloat(Tokenizer.At);
|
NextControlBox->Z = ParseFloat(Tokenizer.At);
|
||||||
EatToCharacterInclusive(&Tokenizer, ';');
|
EatToCharacterInclusive(&Tokenizer, ';');
|
||||||
|
|
||||||
// Parse ID
|
// Parse ID
|
||||||
EatWhitespace(&Tokenizer);
|
EatWhitespace(&Tokenizer);
|
||||||
Assert(StringsEqual(Tokenizer.At, "id: "));
|
Assert(gs_stringsEqual(Tokenizer.At, "id: "));
|
||||||
Tokenizer.At += StringLength("id: ");
|
Tokenizer.At += gs_stringLength("id: ");
|
||||||
NextControlBox->ID = ParseSignedInt(Tokenizer.At);
|
NextControlBox->ID = ParseSignedInt(Tokenizer.At);
|
||||||
EatToCharacterInclusive(&Tokenizer, ';');
|
EatToCharacterInclusive(&Tokenizer, ';');
|
||||||
|
|
||||||
|
@ -278,36 +278,36 @@ int main(int ArgCount, char* Args[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string_buffer OutputFileBuffer = {};
|
gs_string_buffer OutputFileBuffer = {};
|
||||||
OutputFileBuffer.Memory = (char*)malloc(sizeof(char) * STRING_BUFFER_SIZE);
|
OutputFileBuffer.Memory = (char*)malloc(sizeof(char) * gs_string_BUFFER_SIZE);
|
||||||
OutputFileBuffer.Size = STRING_BUFFER_SIZE;
|
OutputFileBuffer.Size = gs_string_BUFFER_SIZE;
|
||||||
OutputFileBuffer.Next = 0;
|
OutputFileBuffer.Next = 0;
|
||||||
|
|
||||||
string_writer RefWriter = {};
|
gs_string_writer RefWriter = {};
|
||||||
RefWriter.Cursor = OutputFileBuffer.Memory;
|
RefWriter.Cursor = OutputFileBuffer.Memory;
|
||||||
RefWriter.UsedInString = 0;
|
RefWriter.UsedIngs_string = 0;
|
||||||
RefWriter.Buffer = &OutputFileBuffer;
|
RefWriter.Buffer = &OutputFileBuffer;
|
||||||
string_writer* Writer = &RefWriter;
|
gs_string_writer* Writer = &RefWriter;
|
||||||
|
|
||||||
char StringBuffer[512];
|
char gs_stringBuffer[512];
|
||||||
s32 Len = 0;
|
s32 Len = 0;
|
||||||
|
|
||||||
Len = sprintf_s(StringBuffer, 512, "control_box_count %d\n", ControlBoxesUsed);
|
Len = sprintf_s(gs_stringBuffer, 512, "control_box_count %d\n", ControlBoxesUsed);
|
||||||
WriteString(Writer, StringBuffer, Len);
|
Writegs_string(Writer, gs_stringBuffer, Len);
|
||||||
Len = sprintf_s(StringBuffer, 512, "led_strip_count %d\n\n", ControlBoxPairsUsed);
|
Len = sprintf_s(gs_stringBuffer, 512, "led_strip_count %d\n\n", ControlBoxPairsUsed);
|
||||||
WriteString(Writer, StringBuffer, Len);
|
Writegs_string(Writer, gs_stringBuffer, Len);
|
||||||
|
|
||||||
for (s32 c = 0; c < ControlBoxesUsed; c++)
|
for (s32 c = 0; c < ControlBoxesUsed; c++)
|
||||||
{
|
{
|
||||||
control_box* Box = ControlBoxes + c;
|
control_box* Box = ControlBoxes + c;
|
||||||
Len = sprintf_s(StringBuffer, 512,
|
Len = sprintf_s(gs_stringBuffer, 512,
|
||||||
"control_box { %d, \"%s\", (%f, %f, %f) }\n",
|
"control_box { %d, \"%s\", (%f, %f, %f) }\n",
|
||||||
Box->ID, Box->Address,
|
Box->ID, Box->Address,
|
||||||
Box->X, Box->Y, Box->Z);
|
Box->X, Box->Y, Box->Z);
|
||||||
WriteString(Writer, StringBuffer, Len);
|
Writegs_string(Writer, gs_stringBuffer, Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteString(Writer, "\n", 1);
|
Writegs_string(Writer, "\n", 1);
|
||||||
|
|
||||||
#define UNIVERSES_PER_BOX 25
|
#define UNIVERSES_PER_BOX 25
|
||||||
s32 UniversesPerBox[64];
|
s32 UniversesPerBox[64];
|
||||||
|
@ -316,7 +316,7 @@ int main(int ArgCount, char* Args[])
|
||||||
UniversesPerBox[u] = UNIVERSES_PER_BOX * u;
|
UniversesPerBox[u] = UNIVERSES_PER_BOX * u;
|
||||||
}
|
}
|
||||||
|
|
||||||
char LEDStripFormatString[] = "led_strip { %d, %d, %d, INTERPOLATE_POINTS, (%f, %f, %f), (%f, %f, %f), 144 } \n";
|
char LEDStripFormatgs_string[] = "led_strip { %d, %d, %d, INTERPOLATE_POINTS, (%f, %f, %f), (%f, %f, %f), 144 } \n";
|
||||||
for (s32 s = 0; s < ControlBoxPairsUsed; s++)
|
for (s32 s = 0; s < ControlBoxPairsUsed; s++)
|
||||||
{
|
{
|
||||||
control_box_pairs* Pair = ControlBoxPairs + s;
|
control_box_pairs* Pair = ControlBoxPairs + s;
|
||||||
|
@ -332,15 +332,15 @@ int main(int ArgCount, char* Args[])
|
||||||
r32 EndY = ControlBoxes[Pair->End].Y;
|
r32 EndY = ControlBoxes[Pair->End].Y;
|
||||||
r32 EndZ = ControlBoxes[Pair->End].Z;
|
r32 EndZ = ControlBoxes[Pair->End].Z;
|
||||||
|
|
||||||
Len = sprintf_s(StringBuffer, 512,
|
Len = sprintf_s(gs_stringBuffer, 512,
|
||||||
LEDStripFormatString,
|
LEDStripFormatgs_string,
|
||||||
Pair->Start, Universe, 0,
|
Pair->Start, Universe, 0,
|
||||||
StartX, StartY, StartZ,
|
StartX, StartY, StartZ,
|
||||||
EndX, EndY, EndZ);
|
EndX, EndY, EndZ);
|
||||||
WriteString(Writer, StringBuffer, Len);
|
Writegs_string(Writer, gs_stringBuffer, Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteString(Writer, "\n", 1);
|
Writegs_string(Writer, "\n", 1);
|
||||||
|
|
||||||
for (s32 sp = 0; sp < ExtraStripsUsed; sp++)
|
for (s32 sp = 0; sp < ExtraStripsUsed; sp++)
|
||||||
{
|
{
|
||||||
|
@ -349,20 +349,20 @@ int main(int ArgCount, char* Args[])
|
||||||
s32 Universe = UniversesPerBox[Strip->BoxID];
|
s32 Universe = UniversesPerBox[Strip->BoxID];
|
||||||
UniversesPerBox[Strip->BoxID]++;
|
UniversesPerBox[Strip->BoxID]++;
|
||||||
|
|
||||||
Len = sprintf_s(StringBuffer, 512,
|
Len = sprintf_s(gs_stringBuffer, 512,
|
||||||
LEDStripFormatString,
|
LEDStripFormatgs_string,
|
||||||
Strip->BoxID, Universe, 0,
|
Strip->BoxID, Universe, 0,
|
||||||
Strip->Start.x, Strip->Start.y, Strip->Start.z,
|
Strip->Start.x, Strip->Start.y, Strip->Start.z,
|
||||||
Strip->End.x, Strip->End.y, Strip->End.z);
|
Strip->End.x, Strip->End.y, Strip->End.z);
|
||||||
WriteString(Writer, StringBuffer, Len);
|
Writegs_string(Writer, gs_stringBuffer, Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteString(Writer, "END_OF_ASSEMBLY_FILE", StringLength("END_OF_ASSEMBLY_FILE"));
|
Writegs_string(Writer, "END_OF_ASSEMBLY_FILE", gs_stringLength("END_OF_ASSEMBLY_FILE"));
|
||||||
|
|
||||||
*Writer->Cursor = 0;
|
*Writer->Cursor = 0;
|
||||||
|
|
||||||
FILE* OutputFile = fopen("F:/data/radialumia.fold", "w");
|
FILE* OutputFile = fopen("F:/data/radialumia.fold", "w");
|
||||||
string_buffer* BufferCursor = &OutputFileBuffer;
|
gs_string_buffer* BufferCursor = &OutputFileBuffer;
|
||||||
while(BufferCursor)
|
while(BufferCursor)
|
||||||
{
|
{
|
||||||
fprintf(OutputFile, BufferCursor->Memory);
|
fprintf(OutputFile, BufferCursor->Memory);
|
||||||
|
|
|
@ -7,13 +7,12 @@ PanelType_HierarchyView,
|
||||||
PanelType_NodeGraph,
|
PanelType_NodeGraph,
|
||||||
PanelType_ProfilerView,
|
PanelType_ProfilerView,
|
||||||
};
|
};
|
||||||
global_variable s32 GlobalPanelDefsCount = 7;
|
global s32 GlobalPanelDefsCount = 6;
|
||||||
global_variable panel_definition GlobalPanelDefs[] = {
|
global panel_definition GlobalPanelDefs[] = {
|
||||||
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
|
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
|
||||||
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
|
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
|
||||||
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands, AnimationTimeline_CommandsCount },
|
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands, AnimationTimeline_CommandsCount },
|
||||||
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
|
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
|
||||||
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
|
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
|
||||||
{ "Node Graph", 10, NodeGraph_Init, NodeGraph_Cleanup, NodeGraph_Render, NodeGraph_Commands, NodeGraph_CommandsCount },
|
|
||||||
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
|
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ MetaTag_panel_type_profiler,
|
||||||
MetaTag_panel_render,
|
MetaTag_panel_render,
|
||||||
MetaTag_panel_type_dmx_view,
|
MetaTag_panel_type_dmx_view,
|
||||||
};
|
};
|
||||||
gsm_meta_tag MetaTagStrings[] = {
|
gsm_meta_tag MetaTaggs_strings[] = {
|
||||||
{ "panel_type_file_view", 20 },
|
{ "panel_type_file_view", 20 },
|
||||||
{ "panel_type_node_graph", 21 },
|
{ "panel_type_node_graph", 21 },
|
||||||
{ "node_output", 11 },
|
{ "node_output", 11 },
|
||||||
|
@ -35,6 +35,7 @@ gsm_meta_tag MetaTagStrings[] = {
|
||||||
};
|
};
|
||||||
enum gsm_struct_type
|
enum gsm_struct_type
|
||||||
{
|
{
|
||||||
|
gsm_StructType_r32,
|
||||||
gsm_StructType_solid_color_data,
|
gsm_StructType_solid_color_data,
|
||||||
gsm_StructType_v4,
|
gsm_StructType_v4,
|
||||||
gsm_StructType_float,
|
gsm_StructType_float,
|
||||||
|
@ -42,11 +43,8 @@ enum gsm_struct_type
|
||||||
gsm_StructType_pixel,
|
gsm_StructType_pixel,
|
||||||
gsm_StructType_u8,
|
gsm_StructType_u8,
|
||||||
gsm_StructType_s32,
|
gsm_StructType_s32,
|
||||||
gsm_StructType_sin_wave_data,
|
|
||||||
gsm_StructType_r32,
|
|
||||||
gsm_StructType_revolving_discs_data,
|
gsm_StructType_revolving_discs_data,
|
||||||
gsm_StructType_vertical_color_fade_data,
|
gsm_StructType_vertical_color_fade_data,
|
||||||
gsm_StructType_multiply_patterns_data,
|
|
||||||
gsm_StructType_Count,
|
gsm_StructType_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,13 +78,6 @@ static gsm_struct_member_type_info StructMembers_solid_color_data[] = {
|
||||||
{ "Color", 5, (u64)&((solid_color_data*)0)->Color, {MetaTag_node_input, }, 1},
|
{ "Color", 5, (u64)&((solid_color_data*)0)->Color, {MetaTag_node_input, }, 1},
|
||||||
{ "Result", 6, (u64)&((solid_color_data*)0)->Result, {MetaTag_node_output, }, 1},
|
{ "Result", 6, (u64)&((solid_color_data*)0)->Result, {MetaTag_node_output, }, 1},
|
||||||
};
|
};
|
||||||
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
|
|
||||||
{ "Period", 6, (u64)&((sin_wave_data*)0)->Period, {MetaTag_node_input, }, 1},
|
|
||||||
{ "Min", 3, (u64)&((sin_wave_data*)0)->Min, {MetaTag_node_input, }, 1},
|
|
||||||
{ "Max", 3, (u64)&((sin_wave_data*)0)->Max, {MetaTag_node_input, }, 1},
|
|
||||||
{ "Result", 6, (u64)&((sin_wave_data*)0)->Result, {MetaTag_node_input, }, 1},
|
|
||||||
{ "Accumulator", 11, (u64)&((sin_wave_data*)0)->Accumulator, {}, 0},
|
|
||||||
};
|
|
||||||
static gsm_struct_member_type_info StructMembers_revolving_discs_data[] = {
|
static gsm_struct_member_type_info StructMembers_revolving_discs_data[] = {
|
||||||
{ "Rotation", 8, (u64)&((revolving_discs_data*)0)->Rotation, {MetaTag_node_input, }, 1},
|
{ "Rotation", 8, (u64)&((revolving_discs_data*)0)->Rotation, {MetaTag_node_input, }, 1},
|
||||||
{ "ThetaZ", 6, (u64)&((revolving_discs_data*)0)->ThetaZ, {MetaTag_node_input, }, 1},
|
{ "ThetaZ", 6, (u64)&((revolving_discs_data*)0)->ThetaZ, {MetaTag_node_input, }, 1},
|
||||||
|
@ -103,24 +94,17 @@ static gsm_struct_member_type_info StructMembers_vertical_color_fade_data[] = {
|
||||||
{ "Max", 3, (u64)&((vertical_color_fade_data*)0)->Max, {MetaTag_node_input, }, 1},
|
{ "Max", 3, (u64)&((vertical_color_fade_data*)0)->Max, {MetaTag_node_input, }, 1},
|
||||||
{ "Result", 6, (u64)&((vertical_color_fade_data*)0)->Result, {MetaTag_node_output, }, 1},
|
{ "Result", 6, (u64)&((vertical_color_fade_data*)0)->Result, {MetaTag_node_output, }, 1},
|
||||||
};
|
};
|
||||||
static gsm_struct_member_type_info StructMembers_multiply_patterns_data[] = {
|
|
||||||
{ "A", 1, (u64)&((multiply_patterns_data*)0)->A, {MetaTag_node_input, }, 1},
|
|
||||||
{ "B", 1, (u64)&((multiply_patterns_data*)0)->B, {MetaTag_node_input, }, 1},
|
|
||||||
{ "Result", 6, (u64)&((multiply_patterns_data*)0)->Result, {MetaTag_node_output, }, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
static gsm_struct_type_info StructTypes[] = {
|
static gsm_struct_type_info StructTypes[] = {
|
||||||
{ gsm_StructType_solid_color_data, "solid_color_data", 16, 36, 0, 0, StructMembers_solid_color_data, 2 },
|
{ gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 },
|
||||||
|
{ gsm_StructType_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_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 5 },
|
||||||
{ gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 },
|
{ 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_color_buffer, "color_buffer", 12, 16, 0, 0, StructMembers_color_buffer, 3 },
|
||||||
{ gsm_StructType_pixel, "pixel", 5, 3, 0, 0, StructMembers_pixel, 2 },
|
{ gsm_StructType_pixel, "pixel", 5, 0, 0, 0, StructMembers_pixel, 2 },
|
||||||
{ gsm_StructType_u8, "u8", 2, 1, 0, 0, 0, 0 },
|
{ gsm_StructType_u8, "u8", 2, 0, 0, 0, 0, 0 },
|
||||||
{ gsm_StructType_s32, "s32", 3, 4, 0, 0, 0, 0 },
|
{ gsm_StructType_s32, "s32", 3, 0, 0, 0, 0, 0 },
|
||||||
{ gsm_StructType_sin_wave_data, "sin_wave_data", 13, 20, 0, 0, StructMembers_sin_wave_data, 5 },
|
{ gsm_StructType_revolving_discs_data, "revolving_discs_data", 20, 56, 0, 0, StructMembers_revolving_discs_data, 8 },
|
||||||
{ gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 },
|
{ gsm_StructType_vertical_color_fade_data, "vertical_color_fade_data", 24, 40, 0, 0, StructMembers_vertical_color_fade_data, 4 },
|
||||||
{ 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 },
|
|
||||||
};
|
};
|
||||||
static gsm_u32 StructTypesCount = 12;
|
static gsm_u32 StructTypesCount = 12;
|
||||||
|
|
|
@ -67,7 +67,7 @@ gsosx_CreateWindow(NSApplication* App, int Width, int Height, id Title)
|
||||||
[App setMainMenu: MenuBar];
|
[App setMainMenu: MenuBar];
|
||||||
|
|
||||||
NSMenu* AppMenu = [NSMenu alloc];
|
NSMenu* AppMenu = [NSMenu alloc];
|
||||||
id QuitTitle = [@"Quit " stringByAppendingString: Title];
|
id QuitTitle = [@"Quit " gs_stringByAppendinggs_string: Title];
|
||||||
id QuitMenuItem = [[NSMenuItem alloc] initWithTitle: QuitTitle action: @selector(terminate:) keyEquivalent: @"q"];
|
id QuitMenuItem = [[NSMenuItem alloc] initWithTitle: QuitTitle action: @selector(terminate:) keyEquivalent: @"q"];
|
||||||
[AppMenu addItem: QuitMenuItem];
|
[AppMenu addItem: QuitMenuItem];
|
||||||
[AppMenuItem setSubmenu: AppMenu];
|
[AppMenuItem setSubmenu: AppMenu];
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
#ifndef INTERFACE_H
|
#ifndef INTERFACE_H
|
||||||
|
|
||||||
enum string_alignment
|
enum gs_string_alignment
|
||||||
{
|
{
|
||||||
Align_Left,
|
Align_Left,
|
||||||
Align_Center,
|
Align_Center,
|
||||||
|
@ -60,10 +60,10 @@ DrawCharacterRightAligned (render_quad_batch_constructor* BatchConstructor, char
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v2
|
internal v2
|
||||||
DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* String, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* gs_string, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
||||||
{
|
{
|
||||||
v2 RegisterPosition = InitialRegisterPosition;
|
v2 RegisterPosition = InitialRegisterPosition;
|
||||||
char* C = String;
|
char* C = gs_string;
|
||||||
for (s32 i = 0; i < Length; i++)
|
for (s32 i = 0; i < Length; i++)
|
||||||
{
|
{
|
||||||
v2 PositionAfterCharacter = DrawCharacterLeftAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
|
v2 PositionAfterCharacter = DrawCharacterLeftAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
|
||||||
|
@ -74,10 +74,10 @@ DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Leng
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v2
|
internal v2
|
||||||
DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* String, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* gs_string, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
||||||
{
|
{
|
||||||
v2 RegisterPosition = InitialRegisterPosition;
|
v2 RegisterPosition = InitialRegisterPosition;
|
||||||
char* C = String + Length - 1;
|
char* C = gs_string + Length - 1;
|
||||||
for (s32 i = Length - 1; i >= 0; i--)
|
for (s32 i = Length - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
v2 PositionAfterCharacter = DrawCharacterRightAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
|
v2 PositionAfterCharacter = DrawCharacterRightAligned(BatchConstructor, *C, *Font, RegisterPosition, Color);
|
||||||
|
@ -88,7 +88,7 @@ DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Len
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v2
|
internal v2
|
||||||
DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Font, v2 Position, v4 Color, string_alignment Alignment = Align_Left)
|
DrawString(render_command_buffer* RenderBuffer, gs_string String, bitmap_font* Font, v2 Position, v4 Color, gs_string_alignment Alignment = Align_Left)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
v2 LowerRight = Position;
|
v2 LowerRight = Position;
|
||||||
|
@ -129,7 +129,7 @@ DrawCursor (render_quad_batch_constructor* BatchConstructor, v2 Position, v4 Col
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v2
|
internal v2
|
||||||
DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 CursorPosition, bitmap_font* Font, v2 Position, v4 Color, v4 CursorColor, string_alignment Alignment = Align_Left)
|
Drawgs_stringWithCursor (render_command_buffer* RenderBuffer, gs_string String, s32 CursorPosition, bitmap_font* Font, v2 Position, v4 Color, v4 CursorColor, gs_string_alignment Alignment = Align_Left)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
v2 LowerRight = Position;
|
v2 LowerRight = Position;
|
||||||
|
@ -153,21 +153,21 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
||||||
String.Length - CursorPosition,
|
String.Length - CursorPosition,
|
||||||
String.Memory + CursorPosition,
|
String.Str + CursorPosition,
|
||||||
RegisterPosition, Font, Color);
|
RegisterPosition, Font, Color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Alignment == Align_Right)
|
else if (Alignment == Align_Right)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||||
CursorPosition, String.Memory,
|
CursorPosition, String.Str,
|
||||||
RegisterPosition, Font, Color);
|
RegisterPosition, Font, Color);
|
||||||
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
||||||
if (String.Length - CursorPosition > 0)
|
if (String.Length - CursorPosition > 0)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||||
String.Length - CursorPosition,
|
String.Length - CursorPosition,
|
||||||
String.Memory + CursorPosition,
|
String.Str + CursorPosition,
|
||||||
RegisterPosition, Font, Color);
|
RegisterPosition, Font, Color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ struct interface_config
|
||||||
|
|
||||||
struct ui_layout
|
struct ui_layout
|
||||||
{
|
{
|
||||||
rect Bounds;
|
rect2 Bounds;
|
||||||
v2 Margin;
|
v2 Margin;
|
||||||
r32 RowHeight;
|
r32 RowHeight;
|
||||||
r32 RowYAt;
|
r32 RowYAt;
|
||||||
|
@ -220,7 +220,7 @@ struct ui_interface
|
||||||
};
|
};
|
||||||
|
|
||||||
static ui_layout
|
static ui_layout
|
||||||
ui_CreateLayout(ui_interface Interface, rect Bounds)
|
ui_CreateLayout(ui_interface Interface, rect2 Bounds)
|
||||||
{
|
{
|
||||||
ui_layout Result = {0};
|
ui_layout Result = {0};
|
||||||
Result.Bounds = Bounds;
|
Result.Bounds = Bounds;
|
||||||
|
@ -263,7 +263,7 @@ ui_EndRow(ui_layout* Layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
|
ui_TryReserveElementBounds(ui_layout* Layout, rect2* Bounds)
|
||||||
{
|
{
|
||||||
b32 Result = true;
|
b32 Result = true;
|
||||||
if (!Layout->DrawHorizontal)
|
if (!Layout->DrawHorizontal)
|
||||||
|
@ -289,7 +289,7 @@ ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r32 ElementWidth = gs_Width(Layout->Bounds) / Layout->ColumnsMax;
|
r32 ElementWidth = Rect2Width(Layout->Bounds) / Layout->ColumnsMax;
|
||||||
Bounds->Min = {
|
Bounds->Min = {
|
||||||
Layout->Bounds.Min.x + (ElementWidth * Layout->ColumnsCount) + Layout->Margin.x,
|
Layout->Bounds.Min.x + (ElementWidth * Layout->ColumnsCount) + Layout->Margin.x,
|
||||||
Layout->RowYAt
|
Layout->RowYAt
|
||||||
|
@ -309,18 +309,18 @@ ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rect
|
static rect2
|
||||||
ui_ReserveTextLineBounds(ui_interface Interface, string Text, ui_layout* Layout)
|
ui_ReserveTextLineBounds(ui_interface Interface, gs_string Text, ui_layout* Layout)
|
||||||
{
|
{
|
||||||
rect Bounds = {0};
|
rect2 Bounds = {0};
|
||||||
|
|
||||||
return Bounds;
|
return Bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rect
|
static rect2
|
||||||
ui_ReserveElementBounds(ui_layout* Layout)
|
ui_ReserveElementBounds(ui_layout* Layout)
|
||||||
{
|
{
|
||||||
rect Bounds = {0};
|
rect2 Bounds = {0};
|
||||||
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
||||||
{
|
{
|
||||||
InvalidCodePath;
|
InvalidCodePath;
|
||||||
|
@ -328,10 +328,10 @@ ui_ReserveElementBounds(ui_layout* Layout)
|
||||||
return Bounds;
|
return Bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rect
|
static rect2
|
||||||
ui_LayoutRemaining(ui_layout Layout)
|
ui_LayoutRemaining(ui_layout Layout)
|
||||||
{
|
{
|
||||||
rect Result = Layout.Bounds;
|
rect2 Result = Layout.Bounds;
|
||||||
Result.Max.y = Layout.RowYAt;
|
Result.Max.y = Layout.RowYAt;
|
||||||
if (Layout.DrawHorizontal)
|
if (Layout.DrawHorizontal)
|
||||||
{
|
{
|
||||||
|
@ -352,19 +352,19 @@ ui_GetTextLineHeight(ui_interface Interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ui_FillRect(ui_interface* Interface, rect Bounds, v4 Color)
|
ui_FillRect(ui_interface* Interface, rect2 Bounds, v4 Color)
|
||||||
{
|
{
|
||||||
PushRenderQuad2D(Interface->RenderBuffer, gs_RectExpand(Bounds), Color);
|
PushRenderQuad2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ui_OutlineRect(ui_interface* Interface, rect Bounds, r32 Thickness, v4 Color)
|
ui_OutlineRect(ui_interface* Interface, rect2 Bounds, r32 Thickness, v4 Color)
|
||||||
{
|
{
|
||||||
PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color);
|
PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
ui_DrawString(ui_interface* Interface, string String, rect Bounds, v4 Color, string_alignment Alignment = Align_Left)
|
ui_DrawString(ui_interface* Interface, gs_string String, rect2 Bounds, v4 Color, gs_string_alignment Alignment = Align_Left)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(Interface->RenderBuffer,
|
render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(Interface->RenderBuffer,
|
||||||
|
@ -392,9 +392,9 @@ ui_DrawString(ui_interface* Interface, string String, rect Bounds, v4 Color, str
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ui_LayoutDrawString(ui_interface* Interface, ui_layout* Layout, string String, v4 Color, string_alignment Alignment = Align_Left)
|
ui_LayoutDrawString(ui_interface* Interface, ui_layout* Layout, gs_string String, v4 Color, gs_string_alignment Alignment = Align_Left)
|
||||||
{
|
{
|
||||||
rect Bounds = {0};
|
rect2 Bounds = {0};
|
||||||
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
||||||
{
|
{
|
||||||
// TODO(NAME): Not invalid, just haven't implemented yet.
|
// TODO(NAME): Not invalid, just haven't implemented yet.
|
||||||
|
@ -405,18 +405,18 @@ ui_LayoutDrawString(ui_interface* Interface, ui_layout* Layout, string String, v
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ui_TextBox(ui_interface* Interface, rect Bounds, string Text, v4 BGColor, v4 TextColor)
|
ui_TextBox(ui_interface* Interface, rect2 Bounds, gs_string Text, v4 BGColor, v4 TextColor)
|
||||||
{
|
{
|
||||||
ui_FillRect(Interface, Bounds, BGColor);
|
ui_FillRect(Interface, Bounds, BGColor);
|
||||||
ui_DrawString(Interface, Text, Bounds, TextColor);
|
ui_DrawString(Interface, Text, Bounds, TextColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_Button(ui_interface* Interface, string Text, rect Bounds, v4 InactiveColor, v4 HoverColor, v4 ClickedColor)
|
ui_Button(ui_interface* Interface, gs_string Text, rect2 Bounds, v4 InactiveColor, v4 HoverColor, v4 ClickedColor)
|
||||||
{
|
{
|
||||||
b32 Pressed = false;
|
b32 Pressed = false;
|
||||||
v4 ButtonBG = InactiveColor;
|
v4 ButtonBG = InactiveColor;
|
||||||
if (gs_PointIsInRect(Interface->Mouse.Pos, Bounds))
|
if (PointIsInRect(Bounds, Interface->Mouse.Pos))
|
||||||
{
|
{
|
||||||
ButtonBG = HoverColor;
|
ButtonBG = HoverColor;
|
||||||
if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState))
|
if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState))
|
||||||
|
@ -430,7 +430,7 @@ ui_Button(ui_interface* Interface, string Text, rect Bounds, v4 InactiveColor, v
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_Button(ui_interface* Interface, string Text, rect Bounds)
|
ui_Button(ui_interface* Interface, gs_string Text, rect2 Bounds)
|
||||||
{
|
{
|
||||||
v4 BGColor = Interface->Style.ButtonColor_Inactive;
|
v4 BGColor = Interface->Style.ButtonColor_Inactive;
|
||||||
v4 HoverColor = Interface->Style.ButtonColor_Active;
|
v4 HoverColor = Interface->Style.ButtonColor_Active;
|
||||||
|
@ -463,16 +463,16 @@ ui_GetListItemColors(ui_interface* Interface, u32 ListItemIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_ListButton(ui_interface* Interface, string Text, rect Bounds, u32 ListItemIndex)
|
ui_ListButton(ui_interface* Interface, gs_string Text, rect2 Bounds, u32 ListItemIndex)
|
||||||
{
|
{
|
||||||
list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex);
|
list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex);
|
||||||
return ui_Button(Interface, Text, Bounds, Colors.Hover, Colors.Selected, Colors.BGColor);
|
return ui_Button(Interface, Text, Bounds, Colors.Hover, Colors.Selected, Colors.BGColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text, v4 BGColor, v4 HoverColor, v4 SelectColor)
|
ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, gs_string Text, v4 BGColor, v4 HoverColor, v4 SelectColor)
|
||||||
{
|
{
|
||||||
rect ButtonBounds = {0};
|
rect2 ButtonBounds = {0};
|
||||||
if (!ui_TryReserveElementBounds(Layout, &ButtonBounds))
|
if (!ui_TryReserveElementBounds(Layout, &ButtonBounds))
|
||||||
{
|
{
|
||||||
ButtonBounds = ui_ReserveTextLineBounds(*Interface, Text, Layout);
|
ButtonBounds = ui_ReserveTextLineBounds(*Interface, Text, Layout);
|
||||||
|
@ -481,7 +481,7 @@ ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text, v4 BGCo
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text)
|
ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, gs_string Text)
|
||||||
{
|
{
|
||||||
v4 BGColor = Interface->Style.ButtonColor_Inactive;
|
v4 BGColor = Interface->Style.ButtonColor_Inactive;
|
||||||
v4 HoverColor = Interface->Style.ButtonColor_Active;
|
v4 HoverColor = Interface->Style.ButtonColor_Active;
|
||||||
|
@ -490,16 +490,16 @@ ui_LayoutButton(ui_interface* Interface, ui_layout* Layout, string Text)
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_LayoutListButton(ui_interface* Interface, ui_layout* Layout, string Text, u32 ListItemIndex)
|
ui_LayoutListButton(ui_interface* Interface, ui_layout* Layout, gs_string Text, u32 ListItemIndex)
|
||||||
{
|
{
|
||||||
list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex);
|
list_item_colors Colors = ui_GetListItemColors(Interface, ListItemIndex);
|
||||||
return ui_LayoutButton(Interface, Layout, Text, Colors.Hover, Colors.Selected, Colors.BGColor);
|
return ui_LayoutButton(Interface, Layout, Text, Colors.Hover, Colors.Selected, Colors.BGColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
ui_LayoutListEntry(ui_interface* Interface, ui_layout* Layout, string Text, u32 Index)
|
ui_LayoutListEntry(ui_interface* Interface, ui_layout* Layout, gs_string Text, u32 Index)
|
||||||
{
|
{
|
||||||
rect Bounds = {0};
|
rect2 Bounds = {0};
|
||||||
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
||||||
{
|
{
|
||||||
// TODO(Peter): this isn't really invalid, but I don't have a concrete use case
|
// TODO(Peter): this isn't really invalid, but I don't have a concrete use case
|
||||||
|
@ -527,7 +527,7 @@ enum selection_state
|
||||||
|
|
||||||
struct interface_list
|
struct interface_list
|
||||||
{
|
{
|
||||||
rect ListBounds;
|
rect2 ListBounds;
|
||||||
|
|
||||||
v2 ListElementDimensions;
|
v2 ListElementDimensions;
|
||||||
v2 ElementLabelIndent;
|
v2 ElementLabelIndent;
|
||||||
|
@ -540,10 +540,10 @@ struct interface_list
|
||||||
s32 ListElementsCount;
|
s32 ListElementsCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
DrawListElementBackground(interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer)
|
DrawListElementBackground(interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer)
|
||||||
{
|
{
|
||||||
rect LineBounds = {};
|
rect2 LineBounds = {};
|
||||||
LineBounds.Min = v2{
|
LineBounds.Min = v2{
|
||||||
List->ListBounds.Min.x,
|
List->ListBounds.Min.x,
|
||||||
List->ListBounds.Max.y - (List->ListElementDimensions.y * (List->ListElementsCount + 1))
|
List->ListBounds.Max.y - (List->ListElementDimensions.y * (List->ListElementsCount + 1))
|
||||||
|
@ -551,7 +551,7 @@ DrawListElementBackground(interface_list* List, mouse_state Mouse, render_comman
|
||||||
LineBounds.Max = LineBounds.Min + List->ListElementDimensions;
|
LineBounds.Max = LineBounds.Min + List->ListElementDimensions;
|
||||||
|
|
||||||
v4 Color = List->LineBGColors[List->ListElementsCount % List->LineBGColorsCount];
|
v4 Color = List->LineBGColors[List->ListElementsCount % List->LineBGColorsCount];
|
||||||
if (PointIsInRange(Mouse.Pos, LineBounds.Min, LineBounds.Max))
|
if (PointIsInRect(LineBounds, Mouse.Pos))
|
||||||
{
|
{
|
||||||
Color = List->LineBGHoverColor;
|
Color = List->LineBGHoverColor;
|
||||||
}
|
}
|
||||||
|
@ -560,10 +560,10 @@ DrawListElementBackground(interface_list* List, mouse_state Mouse, render_comman
|
||||||
return LineBounds;
|
return LineBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
DrawListElement(string Label, interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer, interface_config Interface)
|
DrawListElement(gs_string Label, interface_list* List, mouse_state Mouse, render_command_buffer* RenderBuffer, interface_config Interface)
|
||||||
{
|
{
|
||||||
rect Bounds = DrawListElementBackground(List, Mouse, RenderBuffer);
|
rect2 Bounds = DrawListElementBackground(List, Mouse, RenderBuffer);
|
||||||
|
|
||||||
v2 LabelPosition = Bounds.Min + List->ElementLabelIndent;
|
v2 LabelPosition = Bounds.Min + List->ElementLabelIndent;
|
||||||
DrawString(RenderBuffer, Label, Interface.Font, LabelPosition, List->TextColor);
|
DrawString(RenderBuffer, Label, Interface.Font, LabelPosition, List->TextColor);
|
||||||
|
@ -578,27 +578,34 @@ EvaluateColorChannelSlider (render_command_buffer* RenderBuffer, v4 ChannelMask,
|
||||||
{
|
{
|
||||||
r32 Result = Current;
|
r32 Result = Current;
|
||||||
|
|
||||||
|
// TODO(Peter): Can this come from outside the function? Would rather pass rect around than min/max
|
||||||
|
rect2 Rect = rect2{ Min, Max };
|
||||||
|
|
||||||
render_quad_batch_constructor Batch = PushRenderQuad2DBatch(RenderBuffer, 2);
|
render_quad_batch_constructor Batch = PushRenderQuad2DBatch(RenderBuffer, 2);
|
||||||
|
|
||||||
v4 LeftColor = ChannelMask * 0;
|
v4 LeftColor = ChannelMask * 0;
|
||||||
LeftColor.a = 1.f;
|
LeftColor.a = 1.f;
|
||||||
v4 RightColor = ChannelMask;
|
v4 RightColor = ChannelMask;
|
||||||
PushQuad2DOnBatch(&Batch,
|
PushQuad2DOnBatch(&Batch,
|
||||||
Min, v2{Max.x, Min.y}, Max, v2{Min.x, Max.y},
|
RectBottomLeft(Rect), RectBottomRight(Rect),
|
||||||
|
RectTopRight(Rect), RectTopLeft(Rect),
|
||||||
v2{0, 0}, v2{1, 0}, v2{1, 1}, v2{0, 1},
|
v2{0, 0}, v2{1, 0}, v2{1, 1}, v2{0, 1},
|
||||||
LeftColor, RightColor, RightColor, LeftColor);
|
LeftColor, RightColor, RightColor, LeftColor);
|
||||||
|
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
if (PointIsInRange(Mouse.DownPos, Min, Max))
|
if (PointIsInRect(Rect, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
Result = ((r32)Mouse.Pos.x - Min.x) / (Max.x - Min.x);
|
Result = ((r32)Mouse.Pos.x - Min.x) / (Max.x - Min.x);
|
||||||
Result = GSClamp01(Result);
|
Result = Clamp01(Result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r32 DragBarWidth = 8;
|
r32 DragBarWidth = 8;
|
||||||
v2 DragBarMin = v2{GSLerp(Min.x, Max.x, Result) - (DragBarWidth / 2), Min.y - 2};
|
v2 DragBarMin = v2{
|
||||||
|
LerpR32(Result, Min.x, Max.x) - (DragBarWidth / 2),
|
||||||
|
Min.y - 2
|
||||||
|
};
|
||||||
v2 DragBarMax = DragBarMin + v2{DragBarWidth, (Max.y - Min.y) + 4};
|
v2 DragBarMax = DragBarMin + v2{DragBarWidth, (Max.y - Min.y) + 4};
|
||||||
|
|
||||||
PushQuad2DOnBatch(&Batch, DragBarMin, DragBarMax, v4{.3f, .3f, .3f, 1.f});
|
PushQuad2DOnBatch(&Batch, DragBarMin, DragBarMax, v4{.3f, .3f, .3f, 1.f});
|
||||||
|
@ -612,16 +619,18 @@ EvaluateColorPicker (render_command_buffer* RenderBuffer, v4* Value, v2 PanelMin
|
||||||
b32 ShouldClose = false;
|
b32 ShouldClose = false;
|
||||||
|
|
||||||
v2 PanelMax = v2{400, 500};
|
v2 PanelMax = v2{400, 500};
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) && !PointIsInRange(Mouse.Pos, PanelMin, PanelMax))
|
// TODO(Peter): Can this get passed from outside? rather pass rect2 than min/max pairs
|
||||||
|
rect2 PanelRect = rect2{PanelMin, PanelMax};
|
||||||
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) && !PointIsInRect(PanelRect, Mouse.Pos))
|
||||||
{
|
{
|
||||||
ShouldClose = true;
|
ShouldClose = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PushRenderQuad2D(RenderBuffer, PanelMin, PanelMax, v4{.5f, .5f, .5f, 1.f});
|
PushRenderQuad2D(RenderBuffer, PanelRect.Min, PanelRect.Max, v4{.5f, .5f, .5f, 1.f});
|
||||||
|
|
||||||
v2 TitleMin = v2{PanelMin.x + 5, PanelMax.y - (Config.Font->PixelHeight + 5)};
|
v2 TitleMin = v2{PanelRect.Min.x + 5, PanelRect.Max.y - (Config.Font->PixelHeight + 5)};
|
||||||
DrawString(RenderBuffer, MakeStringLiteral("Color Picker"), Config.Font,
|
DrawString(RenderBuffer, MakeString("Color Picker"), Config.Font,
|
||||||
TitleMin, WhiteV4);
|
TitleMin, WhiteV4);
|
||||||
|
|
||||||
v2 SliderDim = v2{(PanelMax.x - PanelMin.x) - 20, 32};
|
v2 SliderDim = v2{(PanelMax.x - PanelMin.x) - 20, 32};
|
||||||
|
@ -650,13 +659,13 @@ struct search_lister_result
|
||||||
b32 ShouldRemainOpen;
|
b32 ShouldRemainOpen;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, string SearchString, s32 Offset);
|
typedef gs_string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, gs_string Searchgs_string, s32 Offset);
|
||||||
|
|
||||||
internal search_lister_result
|
internal search_lister_result
|
||||||
EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string Title,
|
EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, gs_string Title,
|
||||||
string* ItemList, s32* ListLUT, s32 ListLength,
|
gs_string* ItemList, s32* ListLUT, s32 ListLength,
|
||||||
s32 HotItem,
|
s32 HotItem,
|
||||||
string* SearchString, s32 SearchStringCursorPosition)
|
gs_string* Searchgs_string, s32 Searchgs_stringCursorPosition)
|
||||||
{
|
{
|
||||||
search_lister_result Result = {};
|
search_lister_result Result = {};
|
||||||
Result.ShouldRemainOpen = true;
|
Result.ShouldRemainOpen = true;
|
||||||
|
@ -666,24 +675,24 @@ EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string
|
||||||
InvalidCodePath;
|
InvalidCodePath;
|
||||||
#if 0
|
#if 0
|
||||||
// Title Bar
|
// Title Bar
|
||||||
rect TitleBarBounds = rect{v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}};
|
rect2 TitleBarBounds = rect2{v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}};
|
||||||
ui_FillRect(Interface, TitleBarBounds, v4{.3f, .3f, .3f, 1.f});
|
ui_FillRect(Interface, TitleBarBounds, v4{.3f, .3f, .3f, 1.f});
|
||||||
ui_DrawString(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
|
ui_Drawgs_string(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
|
||||||
|
|
||||||
MakeStringBuffer(DebugString, 256);
|
MakeStringBuffer(Debuggs_string, 256);
|
||||||
PrintF(&DebugString, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
|
PrintF(&Debuggs_string, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
|
||||||
rect DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
|
rect2 DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
|
||||||
ui_DrawString(Interface, DebugString, DebugBounds, Interface->Style.TextColor);
|
ui_Drawgs_string(Interface, Debuggs_string, DebugBounds, Interface->Style.TextColor);
|
||||||
|
|
||||||
// Search Bar
|
// Search Bar
|
||||||
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
|
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
|
||||||
DrawStringWithCursor(RenderBuffer, *SearchString, SearchStringCursorPosition, Font, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4);
|
Drawgs_stringWithCursor(RenderBuffer, *Searchgs_string, Searchgs_stringCursorPosition, Font, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4);
|
||||||
TopLeft.y -= 30;
|
TopLeft.y -= 30;
|
||||||
|
|
||||||
for (s32 i = 0; i < ListLength; i++)
|
for (s32 i = 0; i < ListLength; i++)
|
||||||
{
|
{
|
||||||
s32 FilteredIndex = ListLUT[i];
|
s32 FilteredIndex = ListLUT[i];
|
||||||
string ListItemString = ItemList[FilteredIndex];
|
gs_string ListItemgs_string = ItemList[FilteredIndex];
|
||||||
|
|
||||||
v2 Min = v2{TopLeft.x, TopLeft.y - 30};
|
v2 Min = v2{TopLeft.x, TopLeft.y - 30};
|
||||||
v2 Max = Min + Dimension - v2{0, Config.Margin.y};
|
v2 Max = Min + Dimension - v2{0, Config.Margin.y};
|
||||||
|
@ -694,7 +703,7 @@ EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string
|
||||||
ButtonColor = Config.ButtonColor_Active;
|
ButtonColor = Config.ButtonColor_Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui_Button(Interface, ListItemString, rect{Min, Max}))
|
if (ui_Button(Interface, ListItemgs_string, rect2{Min, Max}))
|
||||||
{
|
{
|
||||||
Result.SelectedItem = i;
|
Result.SelectedItem = i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
#ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
global_variable v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f};
|
global v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f};
|
||||||
|
|
||||||
//
|
//
|
||||||
struct animation_timeline_state
|
struct animation_timeline_state
|
||||||
|
@ -15,7 +15,7 @@ struct animation_timeline_state
|
||||||
};
|
};
|
||||||
|
|
||||||
inline u32
|
inline u32
|
||||||
GetFrameFromPointInAnimationPanel(v2 Point, rect PanelBounds, frame_range VisibleRange)
|
GetFrameFromPointInAnimationPanel(v2 Point, rect2 PanelBounds, frame_range VisibleRange)
|
||||||
{
|
{
|
||||||
r32 HorizontalPercentOfBounds = (Point.x - PanelBounds.Min.x) / (PanelBounds.Max.x - PanelBounds.Min.x);
|
r32 HorizontalPercentOfBounds = (Point.x - PanelBounds.Min.x) / (PanelBounds.Max.x - PanelBounds.Min.x);
|
||||||
u32 VisibleFramesCount = GetFrameCount(VisibleRange);
|
u32 VisibleFramesCount = GetFrameCount(VisibleRange);
|
||||||
|
@ -24,10 +24,10 @@ GetFrameFromPointInAnimationPanel(v2 Point, rect PanelBounds, frame_range Visibl
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s32
|
inline s32
|
||||||
GetXPositionFromFrameInAnimationPanel (u32 Frame, rect PanelBounds, frame_range VisibleRange)
|
GetXPositionFromFrameInAnimationPanel (u32 Frame, rect2 PanelBounds, frame_range VisibleRange)
|
||||||
{
|
{
|
||||||
r32 PercentOfTimeline = (r32)(Frame - VisibleRange.Min) / (r32)GetFrameCount(VisibleRange);
|
r32 PercentOfTimeline = (r32)(Frame - VisibleRange.Min) / (r32)GetFrameCount(VisibleRange);
|
||||||
s32 XPositionAtFrame = (PercentOfTimeline * gs_Width(PanelBounds)) + PanelBounds.Min.x;
|
s32 XPositionAtFrame = (PercentOfTimeline * Rect2Width(PanelBounds)) + PanelBounds.Min.x;
|
||||||
return XPositionAtFrame;
|
return XPositionAtFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
|
||||||
|
|
||||||
OPERATION_STATE_DEF(drag_time_marker_operation_state)
|
OPERATION_STATE_DEF(drag_time_marker_operation_state)
|
||||||
{
|
{
|
||||||
rect TimelineBounds;
|
rect2 TimelineBounds;
|
||||||
s32 StartFrame;
|
s32 StartFrame;
|
||||||
s32 EndFrame;
|
s32 EndFrame;
|
||||||
};
|
};
|
||||||
|
@ -90,7 +90,7 @@ input_command DragTimeMarkerCommands [] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
StartDragTimeMarker(rect TimelineBounds, frame_range VisibleFrames, app_state* State)
|
StartDragTimeMarker(rect2 TimelineBounds, frame_range VisibleFrames, app_state* State)
|
||||||
{
|
{
|
||||||
operation_mode* DragTimeMarkerMode = ActivateOperationModeWithCommands(&State->Modes, DragTimeMarkerCommands, UpdateDragTimeMarker);
|
operation_mode* DragTimeMarkerMode = ActivateOperationModeWithCommands(&State->Modes, DragTimeMarkerCommands, UpdateDragTimeMarker);
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ StartDragTimeMarker(rect TimelineBounds, frame_range VisibleFrames, app_state* S
|
||||||
|
|
||||||
OPERATION_STATE_DEF(drag_animation_clip_state)
|
OPERATION_STATE_DEF(drag_animation_clip_state)
|
||||||
{
|
{
|
||||||
rect TimelineBounds;
|
rect2 TimelineBounds;
|
||||||
frame_range VisibleRange;
|
frame_range VisibleRange;
|
||||||
frame_range ClipRange;
|
frame_range ClipRange;
|
||||||
};
|
};
|
||||||
|
@ -122,7 +122,7 @@ AttemptToSnapPosition(u32 SnappingFrame, u32 SnapToFrame)
|
||||||
{
|
{
|
||||||
u32 Result = SnappingFrame;
|
u32 Result = SnappingFrame;
|
||||||
s32 SnapDistance = 5;
|
s32 SnapDistance = 5;
|
||||||
if (GSAbs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance)
|
if (Abs((s32)SnappingFrame - (s32)SnapToFrame) <= SnapDistance)
|
||||||
{
|
{
|
||||||
Result = SnapToFrame;
|
Result = SnapToFrame;
|
||||||
}
|
}
|
||||||
|
@ -134,13 +134,13 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
||||||
drag_animation_clip_state* OpState = (drag_animation_clip_state*)Operation.OpStateMemory;
|
drag_animation_clip_state* OpState = (drag_animation_clip_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
r32 ClipInitialStartFrameXPercent = FrameToPercentRange(OpState->ClipRange.Min, OpState->VisibleRange);
|
r32 ClipInitialStartFrameXPercent = FrameToPercentRange(OpState->ClipRange.Min, OpState->VisibleRange);
|
||||||
u32 ClipInitialStartFrameXPosition = GSLerp(OpState->TimelineBounds.Min.x,
|
u32 ClipInitialStartFrameXPosition = LerpR32(ClipInitialStartFrameXPercent,
|
||||||
OpState->TimelineBounds.Max.x,
|
OpState->TimelineBounds.Min.x,
|
||||||
ClipInitialStartFrameXPercent);
|
OpState->TimelineBounds.Max.x);
|
||||||
r32 ClipInitialEndFrameXPercent = FrameToPercentRange(OpState->ClipRange.Max, OpState->VisibleRange);
|
r32 ClipInitialEndFrameXPercent = FrameToPercentRange(OpState->ClipRange.Max, OpState->VisibleRange);
|
||||||
u32 ClipInitialEndFrameXPosition = GSLerp(OpState->TimelineBounds.Min.x,
|
u32 ClipInitialEndFrameXPosition = LerpR32(ClipInitialEndFrameXPercent,
|
||||||
OpState->TimelineBounds.Max.x,
|
OpState->TimelineBounds.Min.x,
|
||||||
ClipInitialEndFrameXPercent);
|
OpState->TimelineBounds.Max.x);
|
||||||
|
|
||||||
u32 FrameAtMouseDownX = GetFrameFromPointInAnimationPanel(Mouse.DownPos, OpState->TimelineBounds, OpState->VisibleRange);
|
u32 FrameAtMouseDownX = GetFrameFromPointInAnimationPanel(Mouse.DownPos, OpState->TimelineBounds, OpState->VisibleRange);
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GSAbs(Mouse.DownPos.x - ClipInitialStartFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
|
if (Abs(Mouse.DownPos.x - ClipInitialStartFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
|
||||||
{
|
{
|
||||||
s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
|
s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
|
||||||
if (FrameOffset < 0)
|
if (FrameOffset < 0)
|
||||||
|
@ -176,7 +176,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
||||||
}
|
}
|
||||||
AnimationBlock->Range.Min = NewStartFrame;
|
AnimationBlock->Range.Min = NewStartFrame;
|
||||||
}
|
}
|
||||||
else if (GSAbs(Mouse.DownPos.x - ClipInitialEndFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
|
else if (Abs(Mouse.DownPos.x - ClipInitialEndFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
|
||||||
{
|
{
|
||||||
r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset;
|
r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset;
|
||||||
if (FrameOffset > 0)
|
if (FrameOffset > 0)
|
||||||
|
@ -228,8 +228,8 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
||||||
|
|
||||||
s32 PlayableStartFrame = State->AnimationSystem.PlayableRange.Min;
|
s32 PlayableStartFrame = State->AnimationSystem.PlayableRange.Min;
|
||||||
s32 PlayableEndFrame = State->AnimationSystem.PlayableRange.Max;
|
s32 PlayableEndFrame = State->AnimationSystem.PlayableRange.Max;
|
||||||
AnimationBlock->Range.Min = (u32)GSClamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame);
|
AnimationBlock->Range.Min = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Min, PlayableEndFrame);
|
||||||
AnimationBlock->Range.Max = (u32)GSClamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame);
|
AnimationBlock->Range.Max = (u32)Clamp(PlayableStartFrame, (s32)AnimationBlock->Range.Max, PlayableEndFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
input_command DragAnimationClipCommands [] = {
|
input_command DragAnimationClipCommands [] = {
|
||||||
|
@ -237,7 +237,7 @@ input_command DragAnimationClipCommands [] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
SelectAndBeginDragAnimationBlock(gs_list_handle BlockHandle, frame_range VisibleRange, rect TimelineBounds, app_state* State)
|
SelectAndBeginDragAnimationBlock(gs_list_handle BlockHandle, frame_range VisibleRange, rect2 TimelineBounds, app_state* State)
|
||||||
{
|
{
|
||||||
SelectAnimationBlock(BlockHandle, State);
|
SelectAnimationBlock(BlockHandle, State);
|
||||||
|
|
||||||
|
@ -289,20 +289,20 @@ AnimationTimeline_Cleanup(panel* Panel, app_state* State)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBuffer, frame_range VisibleFrames, rect BarBounds, mouse_state Mouse, app_state* State)
|
DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBuffer, frame_range VisibleFrames, rect2 BarBounds, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
string TempString = PushString(&State->Transient, 256);
|
gs_string TempString = PushString(&State->Transient, 256);
|
||||||
|
|
||||||
s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min;
|
s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min;
|
||||||
|
|
||||||
r32 BarHeight = gs_Height(BarBounds);
|
r32 BarHeight = Rect2Height(BarBounds);
|
||||||
r32 BarWidth = gs_Width(BarBounds);
|
r32 BarWidth = Rect2Width(BarBounds);
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, gs_RectExpand(BarBounds), v4{.16f, .16f, .16f, 1.f});
|
PushRenderQuad2D(RenderBuffer, BarBounds.Min, BarBounds.Max, v4{.16f, .16f, .16f, 1.f});
|
||||||
|
|
||||||
// Mouse clicked inside frame nubmer bar -> change current frame on timeline
|
// Mouse clicked inside frame nubmer bar -> change current frame on timeline
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
|
||||||
PointIsInRange(Mouse.DownPos, gs_RectExpand(BarBounds)))
|
PointIsInRect(BarBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
StartDragTimeMarker(BarBounds, VisibleFrames, State);
|
StartDragTimeMarker(BarBounds, VisibleFrames, State);
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBu
|
||||||
u32 Frame = PercentToFrameInRange(Percent, VisibleFrames);
|
u32 Frame = PercentToFrameInRange(Percent, VisibleFrames);
|
||||||
PrintF(&TempString, "%d", Frame);
|
PrintF(&TempString, "%d", Frame);
|
||||||
r32 FramePercent = FrameToPercentRange(Frame, VisibleFrames);
|
r32 FramePercent = FrameToPercentRange(Frame, VisibleFrames);
|
||||||
r32 FrameX = GSLerp(BarBounds.Min.x, BarBounds.Max.x, FramePercent);
|
r32 FrameX = LerpR32(FramePercent, BarBounds.Min.x, BarBounds.Max.x);
|
||||||
v2 FrameTextPos = v2{FrameX, BarBounds.Min.y + 2};
|
v2 FrameTextPos = v2{FrameX, BarBounds.Min.y + 2};
|
||||||
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, FrameTextPos, WhiteV4);
|
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, FrameTextPos, WhiteV4);
|
||||||
}
|
}
|
||||||
|
@ -324,29 +324,28 @@ DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBu
|
||||||
if (FrameIsInRange(AnimationSystem->CurrentFrame, VisibleFrames))
|
if (FrameIsInRange(AnimationSystem->CurrentFrame, VisibleFrames))
|
||||||
{
|
{
|
||||||
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, VisibleFrames);
|
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, VisibleFrames);
|
||||||
r32 SliderX = GSLerp(BarBounds.Min.x, BarBounds.Max.x, FrameAtPercentVisibleRange);
|
r32 SliderX = LerpR32(FrameAtPercentVisibleRange, BarBounds.Min.x, BarBounds.Max.x);
|
||||||
|
|
||||||
|
PrintF(&TempString, "%d", AnimationSystem->CurrentFrame);
|
||||||
|
|
||||||
u32 FrameNumberCharCount = GetU32NumberOfCharactersNeeded(AnimationSystem->CurrentFrame);
|
|
||||||
// space for each character + a margin on either side
|
// space for each character + a margin on either side
|
||||||
r32 SliderWidth = (8 * FrameNumberCharCount) + 8;
|
r32 SliderWidth = (8 * TempString.Length) + 8;
|
||||||
r32 SliderHalfWidth = SliderWidth / 2.f;
|
r32 SliderHalfWidth = SliderWidth / 2.f;
|
||||||
v2 HeadMin = v2{SliderX - SliderHalfWidth, BarBounds.Min.y};
|
v2 HeadMin = v2{SliderX - SliderHalfWidth, BarBounds.Min.y};
|
||||||
v2 HeadMax = v2{SliderX + SliderHalfWidth, BarBounds.Max.y};
|
v2 HeadMax = v2{SliderX + SliderHalfWidth, BarBounds.Max.y};
|
||||||
PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor);
|
PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor);
|
||||||
|
|
||||||
PrintF(&TempString, "%d", AnimationSystem->CurrentFrame);
|
|
||||||
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, HeadMin + v2{6, 4}, WhiteV4);
|
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, HeadMin + v2{6, 4}, WhiteV4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal frame_range
|
internal frame_range
|
||||||
DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_state* TimelineState, render_command_buffer* RenderBuffer, rect BarBounds, mouse_state Mouse)
|
DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_state* TimelineState, render_command_buffer* RenderBuffer, rect2 BarBounds, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
frame_range Result = {0};
|
frame_range Result = {0};
|
||||||
|
|
||||||
r32 BarHeight = gs_Height(BarBounds);
|
r32 BarHeight = Rect2Height(BarBounds);
|
||||||
r32 BarWidth = gs_Width(BarBounds);
|
r32 BarWidth = Rect2Width(BarBounds);
|
||||||
PushRenderQuad2D(RenderBuffer, gs_RectExpand(BarBounds), v4{.16f, .16f, .16f, 1.f});
|
PushRenderQuad2D(RenderBuffer, BarBounds.Min, BarBounds.Max, v4{.16f, .16f, .16f, 1.f});
|
||||||
|
|
||||||
r32 PlayableFrames = (r32)GetFrameCount(AnimationSystem->PlayableRange);
|
r32 PlayableFrames = (r32)GetFrameCount(AnimationSystem->PlayableRange);
|
||||||
v2 SliderBarDim = v2{25, BarHeight};
|
v2 SliderBarDim = v2{25, BarHeight};
|
||||||
|
@ -354,22 +353,24 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
|
||||||
// Convert Frames To Pixels
|
// Convert Frames To Pixels
|
||||||
r32 VisibleMinPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Min, AnimationSystem->PlayableRange);
|
r32 VisibleMinPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Min, AnimationSystem->PlayableRange);
|
||||||
r32 VisibleMaxPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Max, AnimationSystem->PlayableRange);
|
r32 VisibleMaxPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Max, AnimationSystem->PlayableRange);
|
||||||
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * gs_Width(BarBounds)), BarBounds.Min.y};
|
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * Rect2Width(BarBounds)), BarBounds.Min.y};
|
||||||
v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (VisibleMaxPercentPlayable * gs_Width(BarBounds)) - 25, BarBounds.Min.y};
|
v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (VisibleMaxPercentPlayable * Rect2Width(BarBounds)) - 25, BarBounds.Min.y};
|
||||||
|
|
||||||
|
rect2 SliderBarRange = rect2{ RangeMinSliderMin, RangeMinSliderMin + SliderBarDim };
|
||||||
|
|
||||||
if (MouseButtonHeldDown(Mouse.LeftButtonState) ||
|
if (MouseButtonHeldDown(Mouse.LeftButtonState) ||
|
||||||
MouseButtonTransitionedUp(Mouse.LeftButtonState))
|
MouseButtonTransitionedUp(Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
v2 MouseDragOffset = Mouse.Pos - Mouse.DownPos;
|
v2 MouseDragOffset = Mouse.Pos - Mouse.DownPos;
|
||||||
if (PointIsInRange(Mouse.DownPos, RangeMinSliderMin, RangeMinSliderMin + SliderBarDim))
|
if (PointIsInRect(SliderBarRange, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
r32 NewSliderX = RangeMinSliderMin.x + MouseDragOffset.x;
|
r32 NewSliderX = RangeMinSliderMin.x + MouseDragOffset.x;
|
||||||
RangeMinSliderMin.x = GSClamp(BarBounds.Min.x, NewSliderX, RangeMaxSliderMin.x - SliderBarDim.x);
|
RangeMinSliderMin.x = Clamp(BarBounds.Min.x, NewSliderX, RangeMaxSliderMin.x - SliderBarDim.x);
|
||||||
}
|
}
|
||||||
if (PointIsInRange(Mouse.DownPos, RangeMaxSliderMin, RangeMaxSliderMin + SliderBarDim))
|
if (PointIsInRect(SliderBarRange, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
r32 NewSliderX = RangeMaxSliderMin.x + MouseDragOffset.x;
|
r32 NewSliderX = RangeMaxSliderMin.x + MouseDragOffset.x;
|
||||||
RangeMaxSliderMin.x = GSClamp(RangeMinSliderMin.x + SliderBarDim.x, NewSliderX, BarBounds.Max.x - SliderBarDim.x);
|
RangeMaxSliderMin.x = Clamp(RangeMinSliderMin.x + SliderBarDim.x, NewSliderX, BarBounds.Max.x - SliderBarDim.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,19 +397,19 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
|
||||||
#define LAYER_HEIGHT 52
|
#define LAYER_HEIGHT 52
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawLayerMenu(animation_system* AnimationSystem, rect PanelDim, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
DrawLayerMenu(animation_system* AnimationSystem, rect2 PanelDim, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
v2 LayerDim = { gs_Width(PanelDim), LAYER_HEIGHT };
|
v2 LayerDim = { Rect2Width(PanelDim), LAYER_HEIGHT };
|
||||||
v2 LayerListMin = PanelDim.Min + v2{0, 24};
|
v2 LayerListMin = PanelDim.Min + v2{0, 24};
|
||||||
for (u32 LayerIndex = 0; LayerIndex < AnimationSystem->LayersCount; LayerIndex++)
|
for (u32 LayerIndex = 0; LayerIndex < AnimationSystem->LayersCount; LayerIndex++)
|
||||||
{
|
{
|
||||||
anim_layer* Layer = AnimationSystem->Layers + LayerIndex;
|
anim_layer* Layer = AnimationSystem->Layers + LayerIndex;
|
||||||
rect LayerBounds = {0};
|
rect2 LayerBounds = {0};
|
||||||
LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * LayerIndex) };
|
LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * LayerIndex) };
|
||||||
LayerBounds.Max = LayerBounds.Min + LayerDim;
|
LayerBounds.Max = LayerBounds.Min + LayerDim;
|
||||||
|
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
|
||||||
gs_PointIsInRect(Mouse.Pos, LayerBounds))
|
PointIsInRect(LayerBounds, Mouse.Pos))
|
||||||
{
|
{
|
||||||
State->SelectedAnimationLayer = LayerIndex;
|
State->SelectedAnimationLayer = LayerIndex;
|
||||||
}
|
}
|
||||||
|
@ -416,18 +417,18 @@ DrawLayerMenu(animation_system* AnimationSystem, rect PanelDim, render_command_b
|
||||||
v2 LayerTextPos = { LayerBounds.Min.x + 6, LayerBounds.Max.y - 16};
|
v2 LayerTextPos = { LayerBounds.Min.x + 6, LayerBounds.Max.y - 16};
|
||||||
if (State->SelectedAnimationLayer == LayerIndex)
|
if (State->SelectedAnimationLayer == LayerIndex)
|
||||||
{
|
{
|
||||||
PushRenderBoundingBox2D(RenderBuffer, gs_RectExpand(LayerBounds), 1, WhiteV4);
|
PushRenderBoundingBox2D(RenderBuffer, LayerBounds.Min, LayerBounds.Max, 1, WhiteV4);
|
||||||
}
|
}
|
||||||
DrawString(RenderBuffer, Layer->Name, State->Interface.Style.Font, LayerTextPos, WhiteV4);
|
DrawString(RenderBuffer, Layer->Name, State->Interface.Style.Font, LayerTextPos, WhiteV4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal rect
|
internal rect2
|
||||||
DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect TimelineBounds, render_command_buffer* RenderBuffer)
|
DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect2 TimelineBounds, render_command_buffer* RenderBuffer)
|
||||||
{
|
{
|
||||||
rect BlockBounds = {};
|
rect2 BlockBounds = {};
|
||||||
|
|
||||||
r32 TimelineWidth = gs_Width(TimelineBounds);
|
r32 TimelineWidth = Rect2Width(TimelineBounds);
|
||||||
|
|
||||||
u32 ClampedBlockStartFrame = ClampFrameToRange(AnimationBlock.Range.Min, VisibleFrames);
|
u32 ClampedBlockStartFrame = ClampFrameToRange(AnimationBlock.Range.Min, VisibleFrames);
|
||||||
r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, VisibleFrames);
|
r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, VisibleFrames);
|
||||||
|
@ -448,18 +449,18 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
|
||||||
}
|
}
|
||||||
|
|
||||||
internal gs_list_handle
|
internal gs_list_handle
|
||||||
DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect PanelBounds, gs_list_handle SelectedBlockHandle, ui_interface* Interface, app_state* State)
|
DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect2 PanelBounds, gs_list_handle SelectedBlockHandle, ui_interface* Interface, app_state* State)
|
||||||
{
|
{
|
||||||
string TempString = PushString(&State->Transient, 256);
|
gs_string Tempgs_string = PushString(&State->Transient, 256);
|
||||||
gs_list_handle Result = SelectedBlockHandle;
|
gs_list_handle Result = SelectedBlockHandle;
|
||||||
|
|
||||||
rect LayerMenuBounds, TimelineBounds;
|
rect2 LayerMenuBounds, TimelineBounds;
|
||||||
gs_VSplitRectAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
|
RectVSplitAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
|
||||||
|
|
||||||
// In Top To Bottom Order
|
// In Top To Bottom Order
|
||||||
rect TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
|
rect2 TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
|
||||||
gs_HSplitRectAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
|
RectHSplitAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
|
||||||
gs_HSplitRectAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
|
RectHSplitAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
|
||||||
|
|
||||||
// TODO(Peter): Clean Up
|
// TODO(Peter): Clean Up
|
||||||
DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse);
|
DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse);
|
||||||
|
@ -500,8 +501,8 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
||||||
BlockColor = PinkV4;
|
BlockColor = PinkV4;
|
||||||
}
|
}
|
||||||
// TODO(Peter): Clean Up
|
// TODO(Peter): Clean Up
|
||||||
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
|
rect2 BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
|
||||||
if (gs_PointIsInRect(Interface->Mouse.Pos, BlockBounds))
|
if (PointIsInRect(BlockBounds, Interface->Mouse.Pos))
|
||||||
{
|
{
|
||||||
DragBlockHandle = CurrentBlockHandle;
|
DragBlockHandle = CurrentBlockHandle;
|
||||||
}
|
}
|
||||||
|
@ -519,8 +520,8 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
||||||
if (FrameIsInRange(AnimationSystem->CurrentFrame, AdjustedViewRange))
|
if (FrameIsInRange(AnimationSystem->CurrentFrame, AdjustedViewRange))
|
||||||
{
|
{
|
||||||
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
|
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
|
||||||
r32 SliderX = GSLerp(TimelineBounds.Min.x, TimelineBounds.Max.x, FrameAtPercentVisibleRange);
|
r32 SliderX = LerpR32(FrameAtPercentVisibleRange, TimelineBounds.Min.x, TimelineBounds.Max.x);
|
||||||
rect SliderBounds = {
|
rect2 SliderBounds = {
|
||||||
v2{ SliderX, TimelineBounds.Min.y },
|
v2{ SliderX, TimelineBounds.Min.y },
|
||||||
v2{ SliderX + 1, TimelineBounds.Max.y }
|
v2{ SliderX + 1, TimelineBounds.Max.y }
|
||||||
};
|
};
|
||||||
|
@ -531,7 +532,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
||||||
ui_OutlineRect(Interface, TimelineFrameBarBounds, 1.f, RedV4);
|
ui_OutlineRect(Interface, TimelineFrameBarBounds, 1.f, RedV4);
|
||||||
ui_OutlineRect(Interface, TimelineBlockDisplayBounds, 1.f, RedV4);
|
ui_OutlineRect(Interface, TimelineBlockDisplayBounds, 1.f, RedV4);
|
||||||
|
|
||||||
if (MouseDownAndNotHandled && gs_PointIsInRect(Interface->Mouse.Pos, TimelineBounds))
|
if (MouseDownAndNotHandled && PointIsInRect(TimelineBounds, Interface->Mouse.Pos))
|
||||||
{
|
{
|
||||||
DeselectCurrentAnimationBlock(State);
|
DeselectCurrentAnimationBlock(State);
|
||||||
}
|
}
|
||||||
|
@ -554,13 +555,13 @@ animation_clip GlobalAnimationClips[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawAnimationClipsList(rect PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayer, animation_system* AnimationSystem)
|
DrawAnimationClipsList(rect2 PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayer, animation_system* AnimationSystem)
|
||||||
{
|
{
|
||||||
ui_layout Layout = ui_CreateLayout(*Interface, PanelBounds);
|
ui_layout Layout = ui_CreateLayout(*Interface, PanelBounds);
|
||||||
for (s32 i = 0; i < GlobalAnimationClipsCount; i++)
|
for (s32 i = 0; i < GlobalAnimationClipsCount; i++)
|
||||||
{
|
{
|
||||||
animation_clip Clip = GlobalAnimationClips[i];
|
animation_clip Clip = GlobalAnimationClips[i];
|
||||||
string ClipName = MakeString(Clip.Name, Clip.NameLength);
|
gs_string ClipName = MakeString(Clip.Name, Clip.NameLength);
|
||||||
if (ui_LayoutListEntry(Interface, &Layout, ClipName, i))
|
if (ui_LayoutListEntry(Interface, &Layout, ClipName, i))
|
||||||
{
|
{
|
||||||
AddAnimationBlockAtCurrentTime(i + 1, SelectedAnimationLayer, AnimationSystem);
|
AddAnimationBlockAtCurrentTime(i + 1, SelectedAnimationLayer, AnimationSystem);
|
||||||
|
@ -572,7 +573,7 @@ DrawAnimationClipsList(rect PanelBounds, ui_interface* Interface, u32 SelectedAn
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_animation_timeline);
|
GSMetaTag(panel_type_animation_timeline);
|
||||||
internal void
|
internal void
|
||||||
AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
AnimationTimeline_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
animation_timeline_state* TimelineState = (animation_timeline_state*)Panel.PanelStateMemory;
|
animation_timeline_state* TimelineState = (animation_timeline_state*)Panel.PanelStateMemory;
|
||||||
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
||||||
|
@ -580,24 +581,24 @@ AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* R
|
||||||
ui_interface* Interface = &State->Interface;
|
ui_interface* Interface = &State->Interface;
|
||||||
animation_system* AnimationSystem = &State->AnimationSystem;
|
animation_system* AnimationSystem = &State->AnimationSystem;
|
||||||
|
|
||||||
rect TitleBarBounds, PanelContentsBounds;
|
rect2 TitleBarBounds, PanelContentsBounds;
|
||||||
gs_HSplitRectAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds);
|
RectHSplitAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds);
|
||||||
rect AnimationListBounds, TimelineBounds;
|
rect2 AnimationListBounds, TimelineBounds;
|
||||||
gs_VSplitRectAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds);
|
RectVSplitAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds);
|
||||||
|
|
||||||
ui_FillRect(Interface, TitleBarBounds, Interface->Style.PanelBGColors[0]);
|
ui_FillRect(Interface, TitleBarBounds, Interface->Style.PanelBGColors[0]);
|
||||||
ui_layout TitleBarLayout = ui_CreateLayout(*Interface, TitleBarBounds);
|
ui_layout TitleBarLayout = ui_CreateLayout(*Interface, TitleBarBounds);
|
||||||
ui_StartRow(&TitleBarLayout, 3);
|
ui_StartRow(&TitleBarLayout, 3);
|
||||||
{
|
{
|
||||||
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Pause")))
|
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Pause")))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||||
}
|
}
|
||||||
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Play")))
|
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Play")))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||||
}
|
}
|
||||||
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeStringLiteral("Stop")))
|
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Stop")))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||||
State->AnimationSystem.CurrentFrame = 0;
|
State->AnimationSystem.CurrentFrame = 0;
|
||||||
|
@ -605,7 +606,7 @@ AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* R
|
||||||
}
|
}
|
||||||
ui_EndRow(&TitleBarLayout);
|
ui_EndRow(&TitleBarLayout);
|
||||||
|
|
||||||
if (gs_Height(TimelineBounds) > 0)
|
if (Rect2Height(TimelineBounds) > 0)
|
||||||
{
|
{
|
||||||
SelectedBlockHandle = DrawAnimationTimeline(AnimationSystem, TimelineState, TimelineBounds, SelectedBlockHandle, Interface, State);
|
SelectedBlockHandle = DrawAnimationTimeline(AnimationSystem, TimelineState, TimelineBounds, SelectedBlockHandle, Interface, State);
|
||||||
DrawAnimationClipsList(AnimationListBounds, Interface, State->SelectedAnimationLayer, &State->AnimationSystem);
|
DrawAnimationClipsList(AnimationListBounds, Interface, State->SelectedAnimationLayer, &State->AnimationSystem);
|
||||||
|
|
|
@ -74,7 +74,7 @@ DrawSACNUniversePixels (render_command_buffer* RenderBuffer, sacn_universe* ToDr
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_dmx_view);
|
GSMetaTag(panel_type_dmx_view);
|
||||||
internal void
|
internal void
|
||||||
DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
DMXView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// :NoLongerFunctionalSACNCodeButThatsOk
|
// :NoLongerFunctionalSACNCodeButThatsOk
|
||||||
|
@ -82,7 +82,7 @@ DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffe
|
||||||
|
|
||||||
universe_view_operation_state* OpState = (universe_view_operation_state*)Operation.OpStateMemory;
|
universe_view_operation_state* OpState = (universe_view_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
string TitleBarString = InitializeEmptyString(PushArray(State->Transient, char, 64), 64);
|
gs_string TitleBargs_string = InitializeEmptygs_string(PushArray(State->Transient, char, 64), 64);
|
||||||
|
|
||||||
v2 DisplayArea_Dimension = v2{600, 600};
|
v2 DisplayArea_Dimension = v2{600, 600};
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ DMXView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffe
|
||||||
if (OpState->Zoom > .5f)
|
if (OpState->Zoom > .5f)
|
||||||
{
|
{
|
||||||
v2 TitleDisplayStart = UniverseDisplayTopLeft + v2{0, 12};
|
v2 TitleDisplayStart = UniverseDisplayTopLeft + v2{0, 12};
|
||||||
PrintF(&TitleBarString, "Universe %d", Universe->Universe);
|
PrintF(&TitleBargs_string, "Universe %d", Universe->Universe);
|
||||||
DrawString(RenderBuffer, TitleBarString, State->Interface.Font,
|
DrawString(RenderBuffer, TitleBargs_string, State->Interface.Font,
|
||||||
TitleDisplayStart, WhiteV4);
|
TitleDisplayStart, WhiteV4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
struct file_view_state
|
struct file_view_state
|
||||||
{
|
{
|
||||||
string WorkingDirectory;
|
gs_string WorkingDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
input_command* FileView_Commands = 0;
|
input_command* FileView_Commands = 0;
|
||||||
|
@ -36,18 +36,18 @@ FileView_Cleanup(panel* Panel, app_state* State)
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_file_view);
|
GSMetaTag(panel_type_file_view);
|
||||||
internal void
|
internal void
|
||||||
FileView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
FileView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
rect HeaderBounds = {0};
|
rect2 HeaderBounds = {0};
|
||||||
HeaderBounds.Min = {PanelBounds.Min.x, PanelBounds.Max.y - 32};
|
HeaderBounds.Min = {PanelBounds.Min.x, PanelBounds.Max.y - 32};
|
||||||
HeaderBounds.Max = PanelBounds.Max;
|
HeaderBounds.Max = PanelBounds.Max;
|
||||||
|
|
||||||
rect ListBounds = {0};
|
rect2 ListBounds = {0};
|
||||||
ListBounds.Min = PanelBounds.Min;
|
ListBounds.Min = PanelBounds.Min;
|
||||||
ListBounds.Max = gs_BottomRight(HeaderBounds);
|
ListBounds.Max = RectBottomRight(HeaderBounds);
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, gs_RectExpand(HeaderBounds), PinkV4);
|
PushRenderQuad2D(RenderBuffer, HeaderBounds.Min, HeaderBounds.Max, PinkV4);
|
||||||
PushRenderQuad2D(RenderBuffer, gs_RectExpand(ListBounds), RedV4);
|
PushRenderQuad2D(RenderBuffer, ListBounds.Min, ListBounds.Max, RedV4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,13 @@ HierarchyView_Cleanup(panel* Panel, app_state* State)
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_hierarchy);
|
GSMetaTag(panel_type_hierarchy);
|
||||||
internal void
|
internal void
|
||||||
HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
HierarchyView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
ui_layout Layout = ui_CreateLayout(State->Interface, PanelBounds);
|
ui_layout Layout = ui_CreateLayout(State->Interface, PanelBounds);
|
||||||
string TempString = PushString(&State->Transient, 256);
|
gs_string Tempgs_string = PushString(&State->Transient, 256);
|
||||||
u32 LineCount = (u32)(gs_Height(PanelBounds) / Layout.RowHeight) + 1;
|
u32 LineCount = (u32)(Rect2Height(PanelBounds) / Layout.RowHeight) + 1;
|
||||||
u32 AssembliesToDraw = GSMin(LineCount, State->Assemblies.Count);
|
u32 AssembliesToDraw = Min(LineCount, State->Assemblies.Count);
|
||||||
rect* LineBounds = PushArray(&State->Transient, rect, LineCount);
|
rect2* LineBounds = PushArray(&State->Transient, rect2, LineCount);
|
||||||
|
|
||||||
// Fill in alternating color rows for the backgrounds
|
// Fill in alternating color rows for the backgrounds
|
||||||
for (u32 Line = 0; Line < LineCount; Line++)
|
for (u32 Line = 0; Line < LineCount; Line++)
|
||||||
|
@ -46,13 +46,13 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
|
||||||
for (u32 AssemblyIndex = 0; AssemblyIndex < AssembliesToDraw; AssemblyIndex++)
|
for (u32 AssemblyIndex = 0; AssemblyIndex < AssembliesToDraw; AssemblyIndex++)
|
||||||
{
|
{
|
||||||
assembly Assembly = State->Assemblies.Values[AssemblyIndex];
|
assembly Assembly = State->Assemblies.Values[AssemblyIndex];
|
||||||
PrintF(&TempString, "%S", Assembly.Name);
|
PrintF(&Tempgs_string, "%S", Assembly.Name);
|
||||||
|
|
||||||
ui_layout ItemLayout = ui_CreateLayout(State->Interface, LineBounds[AssemblyIndex]);
|
ui_layout ItemLayout = ui_CreateLayout(State->Interface, LineBounds[AssemblyIndex]);
|
||||||
ui_StartRow(&ItemLayout, 2);
|
ui_StartRow(&ItemLayout, 2);
|
||||||
{
|
{
|
||||||
ui_LayoutDrawString(&State->Interface, &ItemLayout, TempString, State->Interface.Style.TextColor);
|
ui_LayoutDrawString(&State->Interface, &ItemLayout, Tempgs_string, State->Interface.Style.TextColor);
|
||||||
if (ui_LayoutListButton(&State->Interface, &ItemLayout, MakeStringLiteral("X"), AssemblyIndex))
|
if (ui_LayoutListButton(&State->Interface, &ItemLayout, MakeString("X"), AssemblyIndex))
|
||||||
{
|
{
|
||||||
UnloadAssembly(AssemblyIndex, State, Context);
|
UnloadAssembly(AssemblyIndex, State, Context);
|
||||||
}
|
}
|
||||||
|
@ -63,15 +63,22 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
|
||||||
if (AssembliesToDraw < LineCount)
|
if (AssembliesToDraw < LineCount)
|
||||||
{
|
{
|
||||||
// NOTE(Peter): Add assembly button
|
// NOTE(Peter): Add assembly button
|
||||||
PrintF(&TempString, "+ Add Assembly");
|
PrintF(&Tempgs_string, "+ Add Assembly");
|
||||||
if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw))
|
if (ui_ListButton(&State->Interface, Tempgs_string, LineBounds[AssembliesToDraw], AssembliesToDraw))
|
||||||
{
|
{
|
||||||
string FilePath = PushString(&State->Transient, 256);
|
gs_string FilePath = PushString(&State->Transient, 256);
|
||||||
|
|
||||||
|
// TODO(Peter): Took out file opening temporarily while I get things back up and running.
|
||||||
|
// Ideally we can just write our own file lister using the new filehandler so that
|
||||||
|
// execution doesn't suspend while we try and open a file
|
||||||
|
InvalidCodePath;
|
||||||
|
#if 0
|
||||||
b32 Success = GetFilePath(Context, &FilePath, "Foldhaus Files\0*.fold\0\0");
|
b32 Success = GetFilePath(Context, &FilePath, "Foldhaus Files\0*.fold\0\0");
|
||||||
if (Success)
|
if (Success)
|
||||||
{
|
{
|
||||||
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, FilePath, State->GlobalLog);
|
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, FilePath.ConstString, State->GlobalLog);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ ProfilerView_Cleanup(panel* Panel, app_state* State)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, memory_arena* Memory)
|
RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, gs_memory_arena* Memory)
|
||||||
{
|
{
|
||||||
v4 ThreadColors[] = {
|
v4 ThreadColors[] = {
|
||||||
v4{.73f, .33f, .83f, 1},
|
v4{.73f, .33f, .83f, 1},
|
||||||
|
@ -35,8 +35,8 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
|
||||||
v4{.74f, .40f, .25f, 1},
|
v4{.74f, .40f, .25f, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
rect Bounds = ui_LayoutRemaining(Layout);
|
rect2 Bounds = ui_LayoutRemaining(Layout);
|
||||||
r32 Width = gs_Width(Bounds);
|
r32 Width = Rect2Width(Bounds);
|
||||||
r32 DepthHeight = 64;
|
r32 DepthHeight = 64;
|
||||||
|
|
||||||
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
||||||
|
@ -48,7 +48,8 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
|
||||||
scope_record* HotRecord = 0;
|
scope_record* HotRecord = 0;
|
||||||
scope_name* HotRecordName = 0;
|
scope_name* HotRecordName = 0;
|
||||||
|
|
||||||
MakeStringBuffer(String, 256);
|
char Backbuffer[256];
|
||||||
|
gs_string String = MakeString(Backbuffer, 0, 256);
|
||||||
for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
|
for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
|
||||||
{
|
{
|
||||||
scope_record* Record = ThreadScopeCalls->Calls + i;
|
scope_record* Record = ThreadScopeCalls->Calls + i;
|
||||||
|
@ -59,14 +60,14 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
|
||||||
r32 PixelStart = Bounds.Min.x + (Width * PercentStart);
|
r32 PixelStart = Bounds.Min.x + (Width * PercentStart);
|
||||||
r32 PixelEnd = Bounds.Min.x + (Width * PercentEnd);
|
r32 PixelEnd = Bounds.Min.x + (Width * PercentEnd);
|
||||||
r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight);
|
r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight);
|
||||||
rect ScopeBounds = {
|
rect2 ScopeBounds = {
|
||||||
v2{ PixelStart, MinY },
|
v2{ PixelStart, MinY },
|
||||||
v2{ PixelEnd, MinY + (DepthHeight - 4) }
|
v2{ PixelEnd, MinY + (DepthHeight - 4) }
|
||||||
};
|
};
|
||||||
if (gs_Width(ScopeBounds) >= 1)
|
if (Rect2Width(ScopeBounds) >= 1)
|
||||||
{
|
{
|
||||||
v4 Color = ThreadColors[0];
|
v4 Color = ThreadColors[0];
|
||||||
if (gs_PointIsInRect(Interface->Mouse.Pos, ScopeBounds))
|
if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
|
||||||
{
|
{
|
||||||
Color = GreenV4;
|
Color = GreenV4;
|
||||||
HotRecord = Record;
|
HotRecord = Record;
|
||||||
|
@ -81,23 +82,26 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_layout Layout, deb
|
||||||
if (HotRecord != 0)
|
if (HotRecord != 0)
|
||||||
{
|
{
|
||||||
PrintF(&String, "%S : %d - %d", HotRecordName->Name, HotRecord->StartCycles, HotRecord->EndCycles);
|
PrintF(&String, "%S : %d - %d", HotRecordName->Name, HotRecord->StartCycles, HotRecord->EndCycles);
|
||||||
ui_TextBox(Interface, gs_MakeRectMinWidth(Interface->Mouse.Pos, v2{256, 32}), String, BlackV4, WhiteV4);
|
|
||||||
|
rect2 TextBounds = MakeRect2MinDim(Interface->Mouse.Pos, v2{256, 32});
|
||||||
|
ui_TextBox(Interface, TextBounds, String, BlackV4, WhiteV4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, memory_arena* Memory)
|
RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debug_frame* VisibleFrame, gs_memory_arena* Memory)
|
||||||
{
|
{
|
||||||
MakeStringBuffer(String, 256);
|
char Backbuffer[256];
|
||||||
|
gs_string String = MakeString(Backbuffer, 0, 256);
|
||||||
|
|
||||||
r32 ColumnWidths[] = {256, 128, 128, 128, 128};
|
r32 ColumnWidths[] = {256, 128, 128, 128, 128};
|
||||||
ui_StartRow(&Layout, 5, &ColumnWidths[0]);
|
ui_StartRow(&Layout, 5, &ColumnWidths[0]);
|
||||||
{
|
{
|
||||||
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Procedure"), Interface->Style.TextColor);
|
ui_LayoutDrawString(Interface, &Layout, MakeString("Procedure"), Interface->Style.TextColor);
|
||||||
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("% Frame"), Interface->Style.TextColor);
|
ui_LayoutDrawString(Interface, &Layout, MakeString("% Frame"), Interface->Style.TextColor);
|
||||||
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Seconds"), Interface->Style.TextColor);
|
ui_LayoutDrawString(Interface, &Layout, MakeString("Seconds"), Interface->Style.TextColor);
|
||||||
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Cycles"), Interface->Style.TextColor);
|
ui_LayoutDrawString(Interface, &Layout, MakeString("Cycles"), Interface->Style.TextColor);
|
||||||
ui_LayoutDrawString(Interface, &Layout, MakeStringLiteral("Calls"), Interface->Style.TextColor);
|
ui_LayoutDrawString(Interface, &Layout, MakeString("Calls"), Interface->Style.TextColor);
|
||||||
}
|
}
|
||||||
ui_EndRow(&Layout);
|
ui_EndRow(&Layout);
|
||||||
|
|
||||||
|
@ -133,25 +137,27 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_layout Layout, debu
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_profiler);
|
GSMetaTag(panel_type_profiler);
|
||||||
internal void
|
internal void
|
||||||
ProfilerView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
ProfilerView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
memory_arena* Memory = &State->Transient;
|
gs_memory_arena* Memory = &State->Transient;
|
||||||
string String = InitializeEmptyString(PushArray(Memory, char, 256), 256);
|
gs_string String = PushString(Memory, 256);
|
||||||
|
|
||||||
v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 };
|
v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 };
|
||||||
|
|
||||||
r32 FrameListHeight = 64;
|
r32 FrameListHeight = 64;
|
||||||
rect FrameListBounds, ProcListBounds;
|
rect2 FrameListBounds, ProcListBounds;
|
||||||
gs_HSplitRectAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
|
RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
|
||||||
rect FrameListInner = gs_InsetRect(FrameListBounds, 4);
|
rect2 FrameListInner = RectInset(FrameListBounds, 4);
|
||||||
|
|
||||||
r32 SingleFrameStep = gs_Width(FrameListInner) / DEBUG_FRAME_COUNT;
|
r32 SingleFrameStep = Rect2Width(FrameListInner) / DEBUG_FRAME_COUNT;
|
||||||
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
|
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
|
||||||
|
|
||||||
ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4);
|
ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4);
|
||||||
if (gs_PointIsInRect(Context.Mouse.Pos, FrameListBounds) && MouseButtonHeldDown(Context.Mouse.LeftButtonState))
|
if (MouseButtonHeldDown(Context.Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
v2 LocalMouse = gs_TransformPointIntoRectSpace(Context.Mouse.Pos, FrameListBounds);
|
if (PointIsInRect(FrameListBounds, Context.Mouse.Pos))
|
||||||
|
{
|
||||||
|
v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos);
|
||||||
s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
|
s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
|
||||||
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
|
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
|
||||||
{
|
{
|
||||||
|
@ -159,14 +165,15 @@ ProfilerView_Render(panel Panel, rect PanelBounds, render_command_buffer* Render
|
||||||
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
|
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rect FrameBounds = gs_MakeRectMinWidth(FrameListInner.Min, v2{SingleFrameWidth, gs_Height(FrameListInner)});
|
rect2 FrameBounds = MakeRect2MinDim(FrameListInner.Min, v2{SingleFrameWidth, Rect2Height(FrameListInner)});
|
||||||
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
|
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
|
||||||
{
|
{
|
||||||
rect PositionedFrameBounds = gs_TranslateRectX(FrameBounds, F * SingleFrameStep);
|
rect2 PositionedFrameBounds = Rect2TranslateX(FrameBounds, F * SingleFrameStep);
|
||||||
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
|
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
|
||||||
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
|
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
|
||||||
v4 Color = FrameColors[GSClamp(0, FramesAgo, 3)];
|
v4 Color = FrameColors[Clamp(0, FramesAgo, 3)];
|
||||||
ui_FillRect(&State->Interface, PositionedFrameBounds, Color);
|
ui_FillRect(&State->Interface, PositionedFrameBounds, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,11 @@ OPERATION_RENDER_PROC(Update3DViewMouseRotate)
|
||||||
|
|
||||||
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
|
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
|
||||||
|
|
||||||
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale);
|
m44 XRotation = M44RotationX(-TotalDeltaPos.y * State->PixelsToWorldScale);
|
||||||
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale);
|
m44 YRotation = M44RotationY(TotalDeltaPos.x * State->PixelsToWorldScale);
|
||||||
m44 Combined = XRotation * YRotation;
|
m44 Combined = XRotation * YRotation;
|
||||||
|
|
||||||
State->Camera.Position = V3(Combined * OpState->CameraStartPos);
|
State->Camera.Position = (Combined * OpState->CameraStartPos).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
|
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
|
||||||
|
@ -40,17 +40,17 @@ FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
|
||||||
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
|
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
|
||||||
&State->Modes,
|
&State->Modes,
|
||||||
mouse_rotate_view_operation_state);
|
mouse_rotate_view_operation_state);
|
||||||
OpState->CameraStartPos = V4(State->Camera.Position, 1);
|
OpState->CameraStartPos = ToV4Point(State->Camera.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|
||||||
GSMetaTag(panel_commands);
|
GSMetaTag(panel_commands);
|
||||||
GSMetaTag(panel_type_sculpture_view);
|
GSMetaTag(panel_type_sculpture_view);
|
||||||
global_variable input_command SculptureView_Commands[] = {
|
global input_command SculptureView_Commands[] = {
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
|
||||||
};
|
};
|
||||||
global_variable s32 SculptureView_CommandsCount = 1;
|
global s32 SculptureView_CommandsCount = 1;
|
||||||
|
|
||||||
GSMetaTag(panel_init);
|
GSMetaTag(panel_init);
|
||||||
GSMetaTag(panel_type_sculpture_view);
|
GSMetaTag(panel_type_sculpture_view);
|
||||||
|
@ -76,23 +76,26 @@ struct draw_leds_job_data
|
||||||
s32 StartIndex;
|
s32 StartIndex;
|
||||||
s32 OnePastLastIndex;
|
s32 OnePastLastIndex;
|
||||||
render_quad_batch_constructor* Batch;
|
render_quad_batch_constructor* Batch;
|
||||||
m44 ModelViewMatrix;
|
quad_batch_constructor_reserved_range BatchReservedRange;
|
||||||
r32 LEDHalfWidth;
|
r32 LEDHalfWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData)
|
DrawLEDsInBufferRangeJob (gs_thread_context Context, gs_data JobData)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
draw_leds_job_data* Data = (draw_leds_job_data*)JobData;
|
draw_leds_job_data* Data = (draw_leds_job_data*)JobData.Memory;
|
||||||
|
|
||||||
s32 LEDCount = Data->OnePastLastIndex - Data->StartIndex;
|
s32 LEDCount = Data->OnePastLastIndex - Data->StartIndex;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// TODO(Peter): Why are we doing this here? Shouldn't we be able to tell what the range
|
// TODO(Peter): Why are we doing this here? Shouldn't we be able to tell what the range
|
||||||
// needs to be at the time of creation? That way its all on one thread and we're not
|
// needs to be at the time of creation? That way its all on one thread and we're not
|
||||||
// worried about locking up.
|
// worried about locking up.
|
||||||
quad_batch_constructor_reserved_range BatchReservedRange = ThreadSafeReserveRangeInQuadConstructor(Data->Batch, LEDCount * 2);
|
quad_batch_constructor_reserved_range BatchReservedRange = ThreadSafeReserveRangeInQuadConstructor(Data->Batch, LEDCount * 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
s32 TrisUsed = 0;
|
s32 TrisUsed = 0;
|
||||||
|
|
||||||
r32 HalfWidth = Data->LEDHalfWidth;
|
r32 HalfWidth = Data->LEDHalfWidth;
|
||||||
|
@ -113,77 +116,101 @@ DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData)
|
||||||
v4 Color = v4{PixelColor.R / 255.f, PixelColor.G / 255.f, PixelColor.B / 255.f, 1.0f};
|
v4 Color = v4{PixelColor.R / 255.f, PixelColor.G / 255.f, PixelColor.B / 255.f, 1.0f};
|
||||||
|
|
||||||
v4 Position = Data->LedBuffer.Positions[LedIndex];
|
v4 Position = Data->LedBuffer.Positions[LedIndex];
|
||||||
m44 FaceCameraMatrix = GetLookAtMatrix(Position, Data->CameraPosition);
|
m44 FaceCameraMatrix = M44LookAt(Position, Data->CameraPosition);
|
||||||
v4 PositionOffset = V4(Position.xyz, 0); // Ensure PositionOffset is a vector, not a point
|
v4 PositionOffset = ToV4Vec(Position.xyz);
|
||||||
|
|
||||||
v4 P0 = (FaceCameraMatrix * P0_In) + PositionOffset;
|
v4 P0 = (FaceCameraMatrix * P0_In) + PositionOffset;
|
||||||
v4 P1 = (FaceCameraMatrix * P1_In) + PositionOffset;
|
v4 P1 = (FaceCameraMatrix * P1_In) + PositionOffset;
|
||||||
v4 P2 = (FaceCameraMatrix * P2_In) + PositionOffset;
|
v4 P2 = (FaceCameraMatrix * P2_In) + PositionOffset;
|
||||||
v4 P3 = (FaceCameraMatrix * P3_In) + PositionOffset;
|
v4 P3 = (FaceCameraMatrix * P3_In) + PositionOffset;
|
||||||
|
|
||||||
SetTri3DInBatch(Data->Batch, BatchReservedRange.Start + TrisUsed++,
|
SetTri3DInBatch(Data->Batch, Data->BatchReservedRange.Start + TrisUsed++,
|
||||||
P0, P1, P2, UV0, UV1, UV2, Color, Color, Color);
|
P0, P1, P2, UV0, UV1, UV2, Color, Color, Color);
|
||||||
SetTri3DInBatch(Data->Batch, BatchReservedRange.Start + TrisUsed++,
|
SetTri3DInBatch(Data->Batch, Data->BatchReservedRange.Start + TrisUsed++,
|
||||||
P0, P2, P3, UV0, UV2, UV3, Color, Color, Color);
|
P0, P2, P3, UV0, UV2, UV3, Color, Color, Color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
DrawQuad(render_command_buffer* RenderBuffer, v4 C, r32 Rad, v4 Color)
|
||||||
|
{
|
||||||
|
v4 P0 = C + v4{-Rad,-Rad,0,0};
|
||||||
|
v4 P1 = C + v4{ Rad,-Rad,0,0};
|
||||||
|
v4 P2 = C + v4{ Rad,Rad,0,0};
|
||||||
|
v4 P3 = C + v4{ -Rad,Rad,0,0};
|
||||||
|
PushRenderQuad3D(RenderBuffer, P0, P1, P2, P3, Color);
|
||||||
|
}
|
||||||
|
|
||||||
GSMetaTag(panel_render);
|
GSMetaTag(panel_render);
|
||||||
GSMetaTag(panel_type_sculpture_view);
|
GSMetaTag(panel_type_sculpture_view);
|
||||||
internal void
|
internal void
|
||||||
SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
SculptureView_Render(panel Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(RenderSculpture);
|
DEBUG_TRACK_SCOPE(RenderSculpture);
|
||||||
|
|
||||||
r32 PanelWidth = PanelBounds.Max.x - PanelBounds.Min.x;
|
// TODO(Peter): @MajorFix
|
||||||
r32 PanelHeight = PanelBounds.Max.y - PanelBounds.Min.y;
|
// NOTE(Peter): Just returning from this function to make sure that this isn't a problem as I go and try to fix
|
||||||
State->Camera.AspectRatio = PanelWidth / PanelHeight;
|
// the other panels
|
||||||
|
return;
|
||||||
|
|
||||||
m44 ModelViewMatrix = GetCameraModelViewMatrix(State->Camera);
|
|
||||||
m44 ProjectionMatrix = GetCameraPerspectiveProjectionMatrix(State->Camera);
|
|
||||||
|
|
||||||
r32 LEDHalfWidth = .5f;
|
State->Camera.AspectRatio = RectAspectRatio(PanelBounds);
|
||||||
|
|
||||||
PushRenderPerspective(RenderBuffer, PanelBounds.Min.x, PanelBounds.Min.y, PanelWidth, PanelHeight, State->Camera);
|
PushRenderPerspective(RenderBuffer, PanelBounds, State->Camera);
|
||||||
|
|
||||||
m44 FaceCameraMatrix = GetLookAtMatrix(v4{0, 0, 0, 1}, V4(State->Camera.Position, 1));
|
|
||||||
|
|
||||||
u32 MaxLEDsPerJob = 2048;
|
u32 MaxLEDsPerJob = 2048;
|
||||||
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal);
|
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal);
|
||||||
|
|
||||||
u32 FocusPixel = 256;
|
u32 FocusPixel = 256;
|
||||||
|
|
||||||
for (u32 i = 0; i < State->Assemblies.Count; i++)
|
for (u32 BufferIndex = 0; BufferIndex < State->LedSystem.BuffersCount; BufferIndex++)
|
||||||
{
|
{
|
||||||
assembly Assembly = State->Assemblies.Values[i];
|
led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, BufferIndex);
|
||||||
led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, Assembly.LedBufferIndex);
|
u32 JobsNeeded = U32DivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
|
||||||
u32 JobsNeeded = IntegerDivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
|
|
||||||
|
|
||||||
// TODO(Peter): TEMPORARY - identify this pixel
|
|
||||||
LedBuffer->Colors[FocusPixel] = pixel{ 255, 0, 255 };
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
u32 NextLEDIndex = 0;
|
||||||
for (u32 Job = 0; Job < JobsNeeded; Job++)
|
for (u32 Job = 0; Job < JobsNeeded; Job++)
|
||||||
{
|
{
|
||||||
draw_leds_job_data* JobData = PushStruct(&State->Transient, draw_leds_job_data);
|
gs_data Data = PushSizeToData(&State->Transient, sizeof(draw_leds_job_data));
|
||||||
|
draw_leds_job_data* JobData = (draw_leds_job_data*)Data.Memory;
|
||||||
JobData->LedBuffer = *LedBuffer;
|
JobData->LedBuffer = *LedBuffer;
|
||||||
JobData->StartIndex = Job * MaxLEDsPerJob;
|
JobData->StartIndex = NextLEDIndex;
|
||||||
JobData->OnePastLastIndex = GSMin(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount);
|
JobData->OnePastLastIndex = Min(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount);
|
||||||
|
s32 JobLedCount = JobData->OnePastLastIndex - JobData->StartIndex;
|
||||||
JobData->Batch = &RenderLEDsBatch;
|
JobData->Batch = &RenderLEDsBatch;
|
||||||
JobData->ModelViewMatrix = ModelViewMatrix;
|
JobData->BatchReservedRange = ReserveRangeInQuadConstructor(JobData->Batch, JobLedCount * 2);
|
||||||
JobData->LEDHalfWidth = LEDHalfWidth;
|
JobData->LEDHalfWidth = .5f;
|
||||||
|
|
||||||
JobData->CameraPosition = V4(State->Camera.Position, 1);
|
JobData->CameraPosition = ToV4Point(State->Camera.Position);
|
||||||
|
|
||||||
Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, DrawLEDsInBufferRangeJob, JobData, "Sculpture Draw LEDS");
|
Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, (thread_proc*)DrawLEDsInBufferRangeJob, Data, ConstString("Sculpture Draw LEDS"));
|
||||||
|
|
||||||
|
NextLEDIndex = JobData->OnePastLastIndex;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
gs_data Data = PushSizeToData(&State->Transient, sizeof(draw_leds_job_data));
|
||||||
|
draw_leds_job_data* JobData = (draw_leds_job_data*)Data.Memory;
|
||||||
|
JobData->LedBuffer = *LedBuffer;
|
||||||
|
JobData->StartIndex = 0;
|
||||||
|
JobData->OnePastLastIndex = LedBuffer->LedCount;
|
||||||
|
s32 JobLedCount = JobData->OnePastLastIndex - JobData->StartIndex;
|
||||||
|
JobData->Batch = &RenderLEDsBatch;
|
||||||
|
JobData->BatchReservedRange = ReserveRangeInQuadConstructor(JobData->Batch, JobLedCount * 2);
|
||||||
|
JobData->LEDHalfWidth = .5f;
|
||||||
|
|
||||||
|
JobData->CameraPosition = ToV4Point(State->Camera.Position);
|
||||||
|
|
||||||
|
Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, (thread_proc*)DrawLEDsInBufferRangeJob, Data, ConstString("Sculpture Draw LEDS"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u32 f = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Peter): I don't like the fact that setting an orthographic view inside a panel render function
|
// TODO(Peter): I don't like the fact that setting an orthographic view inside a panel render function
|
||||||
// needs to relyon the window bounds rather than the panel bounds. Ideally the panel only needs to know where
|
// needs to relyon the window bounds rather than the panel bounds. Ideally the panel only needs to know where
|
||||||
// itself is, and nothing else.
|
// itself is, and nothing else.
|
||||||
PushRenderOrthographic(RenderBuffer,
|
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
||||||
State->WindowBounds.Min.x, State->WindowBounds.Min.y,
|
|
||||||
State->WindowBounds.Max.x, State->WindowBounds.Max.y);
|
|
||||||
|
|
||||||
if (State->Assemblies.Count > 0)
|
if (State->Assemblies.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -196,9 +223,9 @@ SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
|
||||||
v4 LedProjectedPosition = Matrix * LedPosition;
|
v4 LedProjectedPosition = Matrix * LedPosition;
|
||||||
v2 LedOnScreenPosition = LedProjectedPosition.xy;
|
v2 LedOnScreenPosition = LedProjectedPosition.xy;
|
||||||
|
|
||||||
string TempString = PushString(&State->Transient, 256);
|
gs_string Tempgs_string = PushString(&State->Transient, 256);
|
||||||
PrintF(&TempString, "%f %f", LedOnScreenPosition.x, LedOnScreenPosition.y);
|
PrintF(&Tempgs_string, "%f %f", LedOnScreenPosition.x, LedOnScreenPosition.y);
|
||||||
DrawString(RenderBuffer, TempString, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4);
|
DrawString(RenderBuffer, Tempgs_string, State->Interface.Style.Font, v2{PanelBounds.Min.x + 100, PanelBounds.Max.y - 200}, WhiteV4);
|
||||||
|
|
||||||
v2 BoxHalfDim = v2{ 25, 25 };
|
v2 BoxHalfDim = v2{ 25, 25 };
|
||||||
v2 BoxMin = LedOnScreenPosition - BoxHalfDim;
|
v2 BoxMin = LedOnScreenPosition - BoxHalfDim;
|
||||||
|
@ -206,7 +233,7 @@ SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
|
||||||
PushRenderBoundingBox2D(RenderBuffer, BoxMin, BoxMax, 2.0f, TealV4);
|
PushRenderBoundingBox2D(RenderBuffer, BoxMin, BoxMax, 2.0f, TealV4);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.GeneralWorkQueue->DoQueueWorkUntilDone(Context.GeneralWorkQueue, 0);
|
Context.GeneralWorkQueue->CompleteQueueWork(Context.GeneralWorkQueue, Context.ThreadContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOLDHAUS_PANEL_SCULPTURE_VIEW_H
|
#define FOLDHAUS_PANEL_SCULPTURE_VIEW_H
|
||||||
|
|
|
@ -160,11 +160,11 @@ VHD_PackLength_(u8* Buffer, u32 Length, b32 IncludeLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal cid
|
internal cid
|
||||||
StringToCID_ (const char* String)
|
gs_stringToCID_ (const char* gs_string)
|
||||||
{
|
{
|
||||||
cid Result = {};
|
cid Result = {};
|
||||||
|
|
||||||
const char* Src = String;
|
const char* Src = gs_string;
|
||||||
u8* Dest = &Result.Bytes[0];
|
u8* Dest = &Result.Bytes[0];
|
||||||
b32 FirstNibble = true;
|
b32 FirstNibble = true;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ InitStreamHeader (u8* Buffer, s32 BufferSize,
|
||||||
Cursor = PackB2(Cursor, RLP_PREAMBLE_SIZE);
|
Cursor = PackB2(Cursor, RLP_PREAMBLE_SIZE);
|
||||||
Cursor = PackB2(Cursor, RLP_POSTAMBLE_SIZE);
|
Cursor = PackB2(Cursor, RLP_POSTAMBLE_SIZE);
|
||||||
|
|
||||||
GSMemCopy(ACN_IDENTIFIER, Cursor, ACN_IDENTIFIER_SIZE);
|
CopyMemoryTo(ACN_IDENTIFIER, Cursor, ACN_IDENTIFIER_SIZE);
|
||||||
Cursor += ACN_IDENTIFIER_SIZE;
|
Cursor += ACN_IDENTIFIER_SIZE;
|
||||||
|
|
||||||
// TODO(Peter): If you never use this anywhere else, go back and remove the parameters
|
// TODO(Peter): If you never use this anywhere else, go back and remove the parameters
|
||||||
|
@ -243,7 +243,7 @@ InitStreamHeader (u8* Buffer, s32 BufferSize,
|
||||||
|
|
||||||
// framing source name
|
// framing source name
|
||||||
// :Check
|
// :Check
|
||||||
GSMemCopy(SourceName, (char*)Cursor, SOURCE_NAME_SIZE);
|
CopyMemoryTo(SourceName, (char*)Cursor, SOURCE_NAME_SIZE);
|
||||||
Cursor[SOURCE_NAME_SIZE - 1] = '\0';
|
Cursor[SOURCE_NAME_SIZE - 1] = '\0';
|
||||||
Cursor += SOURCE_NAME_SIZE;
|
Cursor += SOURCE_NAME_SIZE;
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ InitializeSACN (context Context)
|
||||||
|
|
||||||
s32 Multicast_TimeToLive = 20;
|
s32 Multicast_TimeToLive = 20;
|
||||||
SACN.SendSocket = Context.PlatformGetSocketHandle(Multicast_TimeToLive);
|
SACN.SendSocket = Context.PlatformGetSocketHandle(Multicast_TimeToLive);
|
||||||
SACN.CID = StringToCID_ ("{67F9D986-544E-4abb-8986-D5F79382586C}");
|
SACN.CID = gs_stringToCID_ ("{67F9D986-544E-4abb-8986-D5F79382586C}");
|
||||||
|
|
||||||
return SACN;
|
return SACN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ struct solid_color_data
|
||||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||||
void SolidColorProc(solid_color_data* Data)
|
void SolidColorProc(solid_color_data* Data)
|
||||||
{
|
{
|
||||||
u8 R = (u8)GSClamp(0.f, (Data->Color.r * 255), 255.f);
|
u8 R = (u8)Clamp(0.f, (Data->Color.r * 255), 255.f);
|
||||||
u8 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f);
|
u8 G = (u8)Clamp(0.f, (Data->Color.g * 255), 255.f);
|
||||||
u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f);
|
u8 B = (u8)Clamp(0.f, (Data->Color.b * 255), 255.f);
|
||||||
|
|
||||||
for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++)
|
for (s32 LedIndex = 0; LedIndex < Data->Result.LEDCount; LedIndex++)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +64,7 @@ void VerticalColorFadeProc(vertical_color_fade_data* Data)
|
||||||
v4 LedPosition = Data->Result.LedPositions[LedIndex];
|
v4 LedPosition = Data->Result.LedPositions[LedIndex];
|
||||||
|
|
||||||
r32 Amount = (LedPosition.y - Data->Min) / Range;
|
r32 Amount = (LedPosition.y - Data->Min) / Range;
|
||||||
Amount = GSClamp01(1.0f - Amount);
|
Amount = Clamp01(1.0f - Amount);
|
||||||
|
|
||||||
Data->Result.Colors[LedIndex].R = (u8)(R * Amount);
|
Data->Result.Colors[LedIndex].R = (u8)(R * Amount);
|
||||||
Data->Result.Colors[LedIndex].G = (u8)(G * Amount);
|
Data->Result.Colors[LedIndex].G = (u8)(G * Amount);
|
||||||
|
@ -107,14 +107,14 @@ void RevolvingDiscs(revolving_discs_data* Data)
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
pixel Color = {
|
pixel Color = {
|
||||||
(u8)(GSClamp01(Data->Color.r) * 255),
|
(u8)(Clamp01(Data->Color.r) * 255),
|
||||||
(u8)(GSClamp01(Data->Color.g) * 255),
|
(u8)(Clamp01(Data->Color.g) * 255),
|
||||||
(u8)(GSClamp01(Data->Color.b) * 255),
|
(u8)(Clamp01(Data->Color.b) * 255),
|
||||||
};
|
};
|
||||||
|
|
||||||
v4 Center = v4{0, 0, 0, 1};
|
v4 Center = v4{0, 0, 0, 1};
|
||||||
v4 Normal = v4{GSCos(Data->ThetaZ), 0, GSSin(Data->ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
v4 Normal = v4{CosR32(Data->ThetaZ), 0, SinR32(Data->ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
||||||
v4 Right = Cross(Normal, v4{0, 1, 0, 0});
|
v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
|
||||||
|
|
||||||
v4 FrontCenter = Center + (Normal * Data->DiscWidth);
|
v4 FrontCenter = Center + (Normal * Data->DiscWidth);
|
||||||
v4 BackCenter = Center - (Normal * Data->DiscWidth);
|
v4 BackCenter = Center - (Normal * Data->DiscWidth);
|
||||||
|
@ -129,13 +129,13 @@ void RevolvingDiscs(revolving_discs_data* Data)
|
||||||
v4 ToFront = Position + FrontCenter;
|
v4 ToFront = Position + FrontCenter;
|
||||||
v4 ToBack = Position + BackCenter;
|
v4 ToBack = Position + BackCenter;
|
||||||
|
|
||||||
r32 ToFrontDotNormal = Dot(ToFront, Normal);
|
r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
|
||||||
r32 ToBackDotNormal = Dot(ToBack, Normal);
|
r32 ToBackDotNormal = V4Dot(ToBack, Normal);
|
||||||
|
|
||||||
ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000);
|
ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
|
||||||
ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000);
|
ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
|
||||||
|
|
||||||
r32 SqDistToCenter = MagSqr(Position);
|
r32 SqDistToCenter = V4MagSquared(Position);
|
||||||
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
||||||
{
|
{
|
||||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
||||||
|
|
|
@ -16,14 +16,13 @@
|
||||||
|
|
||||||
#include "../gs_libs/gs_win32.cpp"
|
#include "../gs_libs/gs_win32.cpp"
|
||||||
#include "win32_foldhaus_memory.h"
|
#include "win32_foldhaus_memory.h"
|
||||||
#include "win32_foldhaus_fileio.h"
|
|
||||||
#include "win32_foldhaus_dll.h"
|
#include "win32_foldhaus_dll.h"
|
||||||
#include "win32_foldhaus_timing.h"
|
#include "win32_foldhaus_timing.h"
|
||||||
|
|
||||||
#include "foldhaus_renderer.cpp"
|
#include "foldhaus_renderer.cpp"
|
||||||
|
|
||||||
global_variable b32 Running = false;
|
global b32 Running = false;
|
||||||
global_variable b32 WindowIsActive = false;
|
global b32 WindowIsActive = false;
|
||||||
|
|
||||||
char DLLName[] = "foldhaus.dll";
|
char DLLName[] = "foldhaus.dll";
|
||||||
char WorkingDLLName[] = "foldhaus_temp.dll";
|
char WorkingDLLName[] = "foldhaus_temp.dll";
|
||||||
|
@ -31,6 +30,317 @@ char DLLLockFileName[] = "lock.tmp";
|
||||||
|
|
||||||
window MainWindow;
|
window MainWindow;
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
|
||||||
|
internal gs_string
|
||||||
|
Win32DumpErrorAndPrepareMessageBoxString(gs_memory_arena* Arena, char* Format, ...)
|
||||||
|
{
|
||||||
|
s32 Error = GetLastError();
|
||||||
|
gs_string ErrorDump = PushString(Arena, 4096);
|
||||||
|
PrintF(&ErrorDump,
|
||||||
|
R"FOO(Win32 Error: %s\n
|
||||||
|
Error Code: %d\n
|
||||||
|
)FOO",
|
||||||
|
__FUNCTION__,
|
||||||
|
Error);
|
||||||
|
|
||||||
|
va_list Args;
|
||||||
|
va_start(Args, Format);
|
||||||
|
PrintFArgsList(&ErrorDump, Format, Args);
|
||||||
|
va_end(Args);
|
||||||
|
|
||||||
|
gs_data ErrorDumpData = StringToData(ErrorDump);
|
||||||
|
|
||||||
|
HANDLE FileHandle = CreateFileA("./crashdump.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD BytesWritten = 0;
|
||||||
|
if (WriteFile(FileHandle, ErrorDumpData.Memory, ErrorDumpData.Size, &BytesWritten, NULL))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
CloseHandle(FileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
AppendPrintF(&ErrorDump, "Program will attempt to continue. See crashdump.txt for info");
|
||||||
|
NullTerminate(&ErrorDump);
|
||||||
|
|
||||||
|
return ErrorDump;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PRINT(Win32DebugPrint)
|
||||||
|
{
|
||||||
|
Assert(IsNullTerminated(Message));
|
||||||
|
OutputDebugStringA(Message.Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PrintLastError() PrintLastError_(__FILE__, __LINE__)
|
||||||
|
internal void
|
||||||
|
PrintLastError_(char* File, u32 Line)
|
||||||
|
{
|
||||||
|
char DebugStringData[256];
|
||||||
|
gs_string DebugString = MakeString(DebugStringData, 0, 256);
|
||||||
|
u32 Error = GetLastError();
|
||||||
|
PrintF(&DebugString, "%s Line %d: Win32 Error %d\n\0", File, Line, Error);
|
||||||
|
OutputDebugStringA(DebugString.Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal HINSTANCE
|
||||||
|
GetHInstance()
|
||||||
|
{
|
||||||
|
HINSTANCE Result = GetModuleHandle(NULL);
|
||||||
|
if (Result == NULL)
|
||||||
|
{
|
||||||
|
PrintLastError();
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
//
|
||||||
|
// Fie I/O
|
||||||
|
|
||||||
|
internal u64
|
||||||
|
Win32HighLowToU64(u32 LowPart, u32 HighPart)
|
||||||
|
{
|
||||||
|
ULARGE_INTEGER Time = {};
|
||||||
|
Time.LowPart = LowPart;
|
||||||
|
Time.HighPart = HighPart;
|
||||||
|
u64 Result = Time.QuadPart;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal u64
|
||||||
|
Win32FileTimeToU64(FILETIME FileTime)
|
||||||
|
{
|
||||||
|
u64 Result = Win32HighLowToU64(FileTime.dwLowDateTime, FileTime.dwHighDateTime);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_FILE_INFO(Win32GetFileInfo)
|
||||||
|
{
|
||||||
|
Assert(IsNullTerminated(Path));
|
||||||
|
gs_file_info Result = {};
|
||||||
|
HANDLE FileHandle = CreateFileA(Path.Str, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
Result.Path = Path;
|
||||||
|
Result.FileSize = (u64)GetFileSize(FileHandle, NULL) + 1;
|
||||||
|
FILETIME CreationTime, LastWriteTime;
|
||||||
|
if (GetFileTime(FileHandle, &CreationTime, (LPFILETIME)0, &LastWriteTime))
|
||||||
|
{
|
||||||
|
Result.CreationTime = Win32FileTimeToU64(CreationTime);
|
||||||
|
Result.LastWriteTime = Win32FileTimeToU64(LastWriteTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintLastError();
|
||||||
|
}
|
||||||
|
CloseHandle(FileHandle);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ_ENTIRE_FILE(Win32ReadEntireFile)
|
||||||
|
{
|
||||||
|
Assert(DataIsNonEmpty(Memory));
|
||||||
|
Assert(IsNullTerminated(Path));
|
||||||
|
|
||||||
|
gs_file Result = {0};
|
||||||
|
u32 Error = 0;
|
||||||
|
Result.FileInfo.Path = Path;
|
||||||
|
|
||||||
|
HANDLE FileHandle = CreateFileA(Path.Str, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD BytesRead = 0;
|
||||||
|
if (ReadFile(FileHandle, (LPVOID)Memory.Memory, Memory.Size - 1, (LPDWORD)(&BytesRead), NULL))
|
||||||
|
{
|
||||||
|
Memory.Memory[Memory.Size - 1] = 0;
|
||||||
|
Result.Data = Memory;
|
||||||
|
|
||||||
|
gs_string AbsolutePath = PushString(FileHandler.Transient, 512);
|
||||||
|
AbsolutePath.Length = GetFullPathNameA(Path.Str, AbsolutePath.Size, AbsolutePath.Str, NULL);
|
||||||
|
if (AbsolutePath.Length == 0)
|
||||||
|
{
|
||||||
|
Error = GetLastError();
|
||||||
|
InvalidCodePath;
|
||||||
|
}
|
||||||
|
Result.FileInfo.AbsolutePath = AbsolutePath.ConstString;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NOTE(Peter): If we get to this error case, it means that the file exists,
|
||||||
|
// and was successfully opened, but we can't read from it. I'm choosing to
|
||||||
|
// treat this as a legitimate error at this point.
|
||||||
|
gs_string Message = Win32DumpErrorAndPrepareMessageBoxString(FileHandler.Transient, "Attempting to read file: %S", Path);
|
||||||
|
if (MessageBox(NULL, Message.Str, "Error", MB_OK) == IDOK)
|
||||||
|
{
|
||||||
|
PostQuitMessage(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(FileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_ENTIRE_FILE(Win32WriteEntireFile)
|
||||||
|
{
|
||||||
|
Assert(DataIsNonEmpty(Data));
|
||||||
|
Assert(IsNullTerminated(Path));
|
||||||
|
|
||||||
|
bool Success = false;
|
||||||
|
HANDLE FileHandle = CreateFileA(Path.Str, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD BytesWritten = 0;
|
||||||
|
if (WriteFile(FileHandle, Data.Memory, Data.Size, &BytesWritten, NULL))
|
||||||
|
{
|
||||||
|
Success = (BytesWritten == Data.Size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gs_string Message = Win32DumpErrorAndPrepareMessageBoxString(FileHandler.Transient, "Attempting to write to file: %S", Path);
|
||||||
|
MessageBox(NULL, Message.Str, "Error", MB_OK);
|
||||||
|
}
|
||||||
|
CloseHandle(FileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal FILETIME
|
||||||
|
GetFileLastWriteTime(char* Path)
|
||||||
|
{
|
||||||
|
FILETIME Result = {};
|
||||||
|
|
||||||
|
WIN32_FIND_DATA FindData = {};
|
||||||
|
HANDLE FileHandle = FindFirstFileA(Path, &FindData);
|
||||||
|
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
Result = FindData.ftLastWriteTime;
|
||||||
|
FindClose(FileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO(Peter): :ErrorLogging
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct temp_file_list_entry
|
||||||
|
{
|
||||||
|
gs_file_info Info;
|
||||||
|
temp_file_list_entry* Next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct temp_file_list
|
||||||
|
{
|
||||||
|
temp_file_list_entry* First;
|
||||||
|
temp_file_list_entry* Last;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal u32
|
||||||
|
Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list* TempList, gs_const_string Path, gs_memory_arena* Storage, b32 Flags)
|
||||||
|
{
|
||||||
|
u32 FilesCount = 0;
|
||||||
|
|
||||||
|
u32 IndexOfLastSlash = FindLastFromSet(Path, "\\/");
|
||||||
|
gs_const_string SearchPath = Substring(Path, 0, IndexOfLastSlash + 1);
|
||||||
|
|
||||||
|
WIN32_FIND_DATA FindFileData;
|
||||||
|
HANDLE SearchHandle = FindFirstFile(Path.Str, &FindFileData);
|
||||||
|
if (SearchHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
|
if (HasFlag(Flags, EnumerateDirectory_Recurse))
|
||||||
|
{
|
||||||
|
gs_const_string SubDirName = ConstString(FindFileData.cFileName);
|
||||||
|
if (!StringsEqual(SubDirName, ConstString(".")) &&
|
||||||
|
!StringsEqual(SubDirName, ConstString("..")))
|
||||||
|
{
|
||||||
|
gs_string SubDirectoryPath = PushString(FileHandler.Transient, SearchPath.Length + SubDirName.Length + 3);
|
||||||
|
PrintF(&SubDirectoryPath, "%S%S/*\0", SearchPath, SubDirName);
|
||||||
|
FilesCount += Win32EnumerateDirectoryIntoTempList(FileHandler, TempList, SubDirectoryPath.ConstString, Storage, Flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasFlag(Flags, EnumerateDirectory_IncludeDirectories))
|
||||||
|
{
|
||||||
|
FilesCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp_file_list_entry* File = PushStruct(FileHandler.Transient, temp_file_list_entry);
|
||||||
|
File->Info.FileSize = Win32HighLowToU64(FindFileData.nFileSizeLow, FindFileData.nFileSizeHigh);
|
||||||
|
File->Info.CreationTime = Win32FileTimeToU64(FindFileData.ftCreationTime);
|
||||||
|
File->Info.LastWriteTime = Win32FileTimeToU64(FindFileData.ftLastWriteTime);
|
||||||
|
File->Next = 0;
|
||||||
|
|
||||||
|
u32 FileNameLength = CharArrayLength(FindFileData.cFileName);
|
||||||
|
|
||||||
|
// NOTE(Peter): String Storage
|
||||||
|
// Storing the string in the final storage means we don't have to copy the string later, and all
|
||||||
|
// strings will be continguous in memory at the calling site, though they will be before the array
|
||||||
|
gs_string FileName = PushString(Storage, SearchPath.Length + FileNameLength + 1);
|
||||||
|
PrintF(&FileName, "%S%.*s", SearchPath, FileName.Size, FindFileData.cFileName);
|
||||||
|
NullTerminate(&FileName);
|
||||||
|
File->Info.Path = FileName.ConstString;
|
||||||
|
|
||||||
|
SLLPushOrInit(TempList->First, TempList->Last, File);
|
||||||
|
FilesCount += 1;
|
||||||
|
}
|
||||||
|
}while(FindNextFile(SearchHandle, &FindFileData));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return FilesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUMERATE_DIRECTORY(Win32EnumerateDirectory)
|
||||||
|
{
|
||||||
|
Assert(IsNullTerminated(Path));
|
||||||
|
gs_file_info_array Result = {};
|
||||||
|
|
||||||
|
temp_file_list TempList = {};
|
||||||
|
Result.MaxCount = Win32EnumerateDirectoryIntoTempList(FileHandler, &TempList, Path, Storage, Flags);
|
||||||
|
|
||||||
|
Result.Values = PushArray(Storage, gs_file_info, Result.MaxCount);
|
||||||
|
for (temp_file_list_entry* FileAt = TempList.First;
|
||||||
|
FileAt != 0;
|
||||||
|
FileAt = FileAt->Next)
|
||||||
|
{
|
||||||
|
// NOTE(Peter): We don't copy the file name here because its already in Storage.
|
||||||
|
// See String Storage note above ^^
|
||||||
|
Result.Values[Result.Count++] = FileAt->Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
//
|
||||||
|
// Job System
|
||||||
|
|
||||||
struct worker_thread_entry
|
struct worker_thread_entry
|
||||||
{
|
{
|
||||||
b32 IsValid;
|
b32 IsValid;
|
||||||
|
@ -39,11 +349,42 @@ struct worker_thread_entry
|
||||||
|
|
||||||
struct worker_thread_info
|
struct worker_thread_info
|
||||||
{
|
{
|
||||||
s32 ID;
|
gs_thread_context ThreadContext;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
work_queue* Queue;
|
gs_work_queue* Queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal s32
|
||||||
|
Win32GetThreadId()
|
||||||
|
{
|
||||||
|
s32 Result = GetCurrentThreadId();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal gs_thread_context
|
||||||
|
Win32CreateThreadContext(gs_memory_arena* Transient = 0)
|
||||||
|
{
|
||||||
|
gs_thread_context Result = {0};
|
||||||
|
Result.ThreadInfo.ThreadID = Win32GetThreadId();
|
||||||
|
Result.Allocator = CreateAllocator(Win32Alloc, Win32Free);
|
||||||
|
if (Transient != 0)
|
||||||
|
{
|
||||||
|
Result.Transient = Transient;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result.Transient = (gs_memory_arena*)AllocatorAlloc(Result.Allocator, sizeof(gs_memory_arena)).Memory;
|
||||||
|
*Result.Transient = CreateMemoryArena(Result.Allocator);
|
||||||
|
}
|
||||||
|
Result.FileHandler = CreateFileHandler(Win32GetFileInfo,
|
||||||
|
Win32ReadEntireFile,
|
||||||
|
Win32WriteEntireFile,
|
||||||
|
Win32EnumerateDirectory,
|
||||||
|
Result.Transient);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
|
PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -51,18 +392,18 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
|
||||||
// overflowing the buffer
|
// overflowing the buffer
|
||||||
if (Queue->JobsCount >= Queue->JobsMax)
|
if (Queue->JobsCount >= Queue->JobsMax)
|
||||||
{
|
{
|
||||||
string DebugString = MakeString((char*)malloc(256), 256);
|
gs_string DebugString = MakeString((char*)malloc(256), 256);
|
||||||
for (u32 i = 0; i < Queue->JobsCount; i++)
|
for (u32 i = 0; i < Queue->JobsCount; i++)
|
||||||
{
|
{
|
||||||
PrintF(&DebugString, "%d %s\n", i, Queue->Jobs[i].JobName);
|
PrintF(&DebugString, "%d %s\n", i, Queue->Jobs[i].JobName);
|
||||||
NullTerminate(&DebugString);
|
NullTerminate(&DebugString);
|
||||||
OutputDebugStringA(DebugString.Memory);
|
OutputDebugStringA(DebugString.Str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Assert(Queue->JobsCount < Queue->JobsMax);
|
Assert(Queue->JobsCount < Queue->JobsMax);
|
||||||
|
|
||||||
worker_thread_job* Job = Queue->Jobs + Queue->JobsCount;
|
gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount;
|
||||||
Job->WorkProc = WorkProc;
|
Job->WorkProc = WorkProc;
|
||||||
Job->Data = Data;
|
Job->Data = Data;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -78,7 +419,7 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal worker_thread_entry
|
internal worker_thread_entry
|
||||||
CompleteAndTakeNextJob(work_queue* Queue, worker_thread_entry Completed)
|
CompleteAndTakeNextJob(gs_work_queue* Queue, worker_thread_entry Completed, gs_thread_context Context)
|
||||||
{
|
{
|
||||||
if (Completed.IsValid)
|
if (Completed.IsValid)
|
||||||
{
|
{
|
||||||
|
@ -106,16 +447,16 @@ CompleteAndTakeNextJob(work_queue* Queue, worker_thread_entry Completed)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DO_QUEUE_WORK_UNTIL_DONE(Win32DoQueueWorkUntilDone)
|
COMPLETE_QUEUE_WORK(Win32DoQueueWorkUntilDone)
|
||||||
{
|
{
|
||||||
worker_thread_entry Entry = {};
|
worker_thread_entry Entry = {};
|
||||||
Entry.IsValid = false;
|
Entry.IsValid = false;
|
||||||
while (Queue->JobsCompleted < Queue->JobsCount)
|
while (Queue->JobsCompleted < Queue->JobsCount)
|
||||||
{
|
{
|
||||||
Entry = CompleteAndTakeNextJob(Queue, Entry);
|
Entry = CompleteAndTakeNextJob(Queue, Entry, Context);
|
||||||
if (Entry.IsValid)
|
if (Entry.IsValid)
|
||||||
{
|
{
|
||||||
Queue->Jobs[Entry.Index].WorkProc(ThreadID, Queue->Jobs[Entry.Index].Data);
|
Queue->Jobs[Entry.Index].WorkProc(Context, Queue->Jobs[Entry.Index].Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,15 +465,17 @@ DWORD WINAPI
|
||||||
WorkerThreadProc (LPVOID InputThreadInfo)
|
WorkerThreadProc (LPVOID InputThreadInfo)
|
||||||
{
|
{
|
||||||
worker_thread_info* ThreadInfo = (worker_thread_info*)InputThreadInfo;
|
worker_thread_info* ThreadInfo = (worker_thread_info*)InputThreadInfo;
|
||||||
|
ThreadInfo->ThreadContext = Win32CreateThreadContext();
|
||||||
|
|
||||||
worker_thread_entry Entry = {};
|
worker_thread_entry Entry = {};
|
||||||
Entry.IsValid = false;
|
Entry.IsValid = false;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry);
|
ClearArena(ThreadInfo->ThreadContext.Transient);
|
||||||
|
Entry = CompleteAndTakeNextJob(ThreadInfo->Queue, Entry, ThreadInfo->ThreadContext);
|
||||||
if (Entry.IsValid)
|
if (Entry.IsValid)
|
||||||
{
|
{
|
||||||
ThreadInfo->Queue->Jobs[Entry.Index].WorkProc(ThreadInfo->ID,
|
ThreadInfo->Queue->Jobs[Entry.Index].WorkProc(ThreadInfo->ThreadContext,
|
||||||
ThreadInfo->Queue->Jobs[Entry.Index].Data);
|
ThreadInfo->Queue->Jobs[Entry.Index].Data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -188,13 +531,13 @@ PLATFORM_GET_SOCKET_HANDLE(Win32GetSocketHandle)
|
||||||
{
|
{
|
||||||
s32 NewDictionaryMax = Win32SocketHandleMax + SOCKET_DICTIONARY_GROW_SIZE;
|
s32 NewDictionaryMax = Win32SocketHandleMax + SOCKET_DICTIONARY_GROW_SIZE;
|
||||||
s32 NewDictionaryDataSize = NewDictionaryMax * sizeof(win32_socket);
|
s32 NewDictionaryDataSize = NewDictionaryMax * sizeof(win32_socket);
|
||||||
u8* DictionaryMemory = Win32Alloc(NewDictionaryDataSize);
|
u8* DictionaryMemory = (u8*)Win32Alloc(NewDictionaryDataSize, 0);
|
||||||
Assert(DictionaryMemory);
|
Assert(DictionaryMemory);
|
||||||
|
|
||||||
win32_socket* NewValues = (win32_socket*)(DictionaryMemory);
|
win32_socket* NewValues = (win32_socket*)(DictionaryMemory);
|
||||||
if (SocketValues)
|
if (SocketValues)
|
||||||
{
|
{
|
||||||
GSMemCopy(SocketValues, NewValues, sizeof(win32_socket) * NewDictionaryMax);
|
CopyMemoryTo(SocketValues, NewValues, sizeof(win32_socket) * NewDictionaryMax);
|
||||||
Win32Free((u8*)SocketValues, sizeof(win32_socket) * Win32SocketHandleCount);
|
Win32Free((u8*)SocketValues, sizeof(win32_socket) * Win32SocketHandleCount);
|
||||||
}
|
}
|
||||||
SocketValues = NewValues;
|
SocketValues = NewValues;
|
||||||
|
@ -512,7 +855,7 @@ internal void
|
||||||
DebugPrint (char* Format, ...)
|
DebugPrint (char* Format, ...)
|
||||||
{
|
{
|
||||||
char Buffer[256];
|
char Buffer[256];
|
||||||
string StringBuffer = MakeString(Buffer, 256);
|
gs_string StringBuffer = MakeString(Buffer, 256);
|
||||||
va_list Args;
|
va_list Args;
|
||||||
va_start(Args, Format);
|
va_start(Args, Format);
|
||||||
PrintF(&StringBuffer, Format, Args);
|
PrintF(&StringBuffer, Format, Args);
|
||||||
|
@ -521,7 +864,7 @@ DebugPrint (char* Format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
SetApplicationLinks (context* Context, win32_dll_refresh DLL, work_queue* WorkQueue)
|
SetApplicationLinks (context* Context, win32_dll_refresh DLL, gs_work_queue* WorkQueue)
|
||||||
{
|
{
|
||||||
if (DLL.IsValid)
|
if (DLL.IsValid)
|
||||||
{
|
{
|
||||||
|
@ -539,27 +882,22 @@ SetApplicationLinks (context* Context, win32_dll_refresh DLL, work_queue* WorkQu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Peter): :Redundant remove
|
||||||
internal u8*
|
internal u8*
|
||||||
DEBUGAlloc(s32 ElementSize, s32 ElementCount)
|
DEBUGAlloc(s32 ElementSize, s32 ElementCount)
|
||||||
{
|
{
|
||||||
return Win32Alloc(ElementSize * ElementCount);
|
return (u8*)Win32Alloc(ElementSize * ElementCount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Peter): :Redundant remove
|
||||||
internal u8*
|
internal u8*
|
||||||
Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
|
Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
|
||||||
{
|
{
|
||||||
u8* NewMemory = Win32Alloc(NewSize);
|
u8* NewMemory = (u8*)Win32Alloc(NewSize, 0);
|
||||||
GSMemCopy(Buf, NewMemory, OldSize);
|
CopyMemoryTo(Buf, NewMemory, OldSize);
|
||||||
return NewMemory;
|
return NewMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
|
||||||
Win32GetThreadId()
|
|
||||||
{
|
|
||||||
s32 Result = GetCurrentThreadId();
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(Peter): Only meant to take one of the values specified below:
|
// NOTE(Peter): Only meant to take one of the values specified below:
|
||||||
// IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM,
|
// IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM,
|
||||||
// IDC_ICON, IDC_NO, IDC_SIZE, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE,
|
// IDC_ICON, IDC_NO, IDC_SIZE, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE,
|
||||||
|
@ -577,6 +915,36 @@ Win32LoadSystemCursor(char* CursorIdentifier)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
PrintMatrix(m44 M, gs_thread_context Context)
|
||||||
|
{
|
||||||
|
gs_string PrintString = AllocatorAllocString(Context.Allocator, 256);
|
||||||
|
PrintF(&PrintString, "[\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n]\n",
|
||||||
|
M.Array[0], M.Array[1], M.Array[2], M.Array[3],
|
||||||
|
M.Array[4], M.Array[5], M.Array[6], M.Array[7],
|
||||||
|
M.Array[8], M.Array[9], M.Array[10], M.Array[11],
|
||||||
|
M.Array[12], M.Array[13], M.Array[14], M.Array[15]);
|
||||||
|
NullTerminate(&PrintString);
|
||||||
|
OutputDebugStringA(PrintString.Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
v4 PerspectiveDivide(v4 A)
|
||||||
|
{
|
||||||
|
v4 Result = {0, 0, 0, 1};
|
||||||
|
Result.x = A.x / A.w;
|
||||||
|
Result.y = A.y / A.w;
|
||||||
|
Result.z = A.z / A.w;
|
||||||
|
Result.w = A.w;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
v4 ToScreen(v4 P, rect2 WindowBounds)
|
||||||
|
{
|
||||||
|
v4 Result = P;
|
||||||
|
Result.x = RemapR32(P.x, -1, 1, WindowBounds.Min.x, WindowBounds.Max.x);
|
||||||
|
Result.y = RemapR32(P.y, -1, 1, WindowBounds.Min.y, WindowBounds.Max.y);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
int WINAPI
|
int WINAPI
|
||||||
WinMain (
|
WinMain (
|
||||||
HINSTANCE HInstance,
|
HINSTANCE HInstance,
|
||||||
|
@ -585,6 +953,171 @@ WinMain (
|
||||||
INT NCmdShow
|
INT NCmdShow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
gs_thread_context ThreadContext = Win32CreateThreadContext();
|
||||||
|
|
||||||
|
{
|
||||||
|
m44 Before = m44{
|
||||||
|
0, 1, 2, 3,
|
||||||
|
4, 5, 6, 7,
|
||||||
|
8, 9, 10, 11,
|
||||||
|
12, 13, 14, 15
|
||||||
|
};
|
||||||
|
m44 After = M44Transpose(Before);
|
||||||
|
OutputDebugStringA("Before:\n");
|
||||||
|
PrintMatrix(Before, ThreadContext);
|
||||||
|
OutputDebugStringA("\n\n");
|
||||||
|
OutputDebugStringA("After:\n");
|
||||||
|
PrintMatrix(After, ThreadContext);
|
||||||
|
OutputDebugStringA("\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
v4 Before = {1, 2, 3, 4};
|
||||||
|
m44 Transform = {};
|
||||||
|
for (u32 i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
Transform.Array[i] = i + 1;
|
||||||
|
}
|
||||||
|
v4 After = Transform * Before;
|
||||||
|
Assert(V4Mag(After - v4{30, 70, 110, 150}) < .00000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Translation
|
||||||
|
v4 Before = {0, 0, 0, 1};
|
||||||
|
m44 Translation = M44Translation(v4{5, 5, 5, 0});
|
||||||
|
v4 After = Translation * Before;
|
||||||
|
Assert((After == v4{5, 5, 5, 1}));
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // X Rotation
|
||||||
|
v4 Before = {0, 5, 0, 1};
|
||||||
|
m44 Forward = M44RotationX(HalfPiR32);
|
||||||
|
m44 Backward = M44RotationX(-HalfPiR32);
|
||||||
|
v4 After = Forward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
|
||||||
|
After = Backward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Y Rotation
|
||||||
|
v4 Before = {5, 0, 0, 1};
|
||||||
|
m44 Forward = M44RotationY(HalfPiR32);
|
||||||
|
m44 Backward = M44RotationY(-HalfPiR32);
|
||||||
|
v4 After = Forward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
|
||||||
|
After = Backward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Z Rotation
|
||||||
|
v4 Before = {0, 5, 0, 1};
|
||||||
|
m44 Forward = M44RotationZ(HalfPiR32);
|
||||||
|
m44 Backward = M44RotationZ(-HalfPiR32);
|
||||||
|
v4 After = Forward * Before;
|
||||||
|
Assert(V4Mag(After - v4{-5, 0, 0, 1}) < .000001f);
|
||||||
|
After = Backward * Before;
|
||||||
|
Assert(V4Mag(After - v4{5, 0, 0, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Combined X Rotation
|
||||||
|
v4 Before = {0, 5, 0, 1};
|
||||||
|
m44 Forward = M44Rotation(v3{HalfPiR32, 0, 0});
|
||||||
|
m44 Backward = M44Rotation(v3{-HalfPiR32, 0, 0});
|
||||||
|
v4 After = Forward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
|
||||||
|
After = Backward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Combined Y Rotation
|
||||||
|
v4 Before = {5, 0, 0, 1};
|
||||||
|
m44 Forward = M44Rotation(v3{0, HalfPiR32, 0});
|
||||||
|
m44 Backward = M44Rotation(v3{0, -HalfPiR32, 0});
|
||||||
|
v4 After = Forward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, -5, 1}) < .000001f);
|
||||||
|
After = Backward * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 0, 5, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Combined Z Rotation
|
||||||
|
v4 Before = {0, 5, 0, 1};
|
||||||
|
m44 Forward = M44Rotation(v3{0, 0, HalfPiR32});
|
||||||
|
m44 Backward = M44Rotation(v3{0, 0, -HalfPiR32});
|
||||||
|
v4 After = Forward * Before;
|
||||||
|
Assert(V4Mag(After - v4{-5, 0, 0, 1}) < .000001f);
|
||||||
|
After = Backward * Before;
|
||||||
|
Assert(V4Mag(After - v4{5, 0, 0, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Translate then Rotate
|
||||||
|
v4 Before = v4{0, 0, 0, 1};
|
||||||
|
|
||||||
|
m44 Translation = M44Translation(v4{5, 0, 0, 0});
|
||||||
|
m44 Rotation = M44Rotation(v3{0, 0, HalfPiR32});
|
||||||
|
m44 Composite = Rotation * Translation;
|
||||||
|
|
||||||
|
v4 Inbetween = Translation * Before;
|
||||||
|
v4 After = Rotation * Inbetween;
|
||||||
|
Assert(V4Mag(After - v4{0, 5, 0, 1}) < .000001f);
|
||||||
|
|
||||||
|
After = Composite * Before;
|
||||||
|
Assert(V4Mag(After - v4{0, 5, 0, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Two translations
|
||||||
|
v4 Before = v4{0, 0, 0, 1};
|
||||||
|
m44 TranslationA = M44Translation(v4{5, 0, 0, 0});
|
||||||
|
m44 TranslationB = M44Translation(v4{0, 5, 0, 0});
|
||||||
|
v4 After = TranslationB * TranslationA * Before;
|
||||||
|
Assert(V4Mag(After - v4{5, 5, 0, 1}) < .000001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Perspective Transform
|
||||||
|
rect2 WindowBounds = rect2{
|
||||||
|
v2{0, 0},
|
||||||
|
v2{1440.0f, 768.0f},
|
||||||
|
};
|
||||||
|
|
||||||
|
m44 Matrix = M44Translation(v4{0, 0, -200, 0}) * M44Rotation(v3{0, DegToRadR32(45), 0});
|
||||||
|
m44 Projection = M44ProjectionPerspective(45, RectAspectRatio(WindowBounds), 0.1f, 500);
|
||||||
|
|
||||||
|
r32 Rad = 25;
|
||||||
|
v4 P0 = Matrix * v4{-Rad, -Rad, 0, 1};
|
||||||
|
v4 P1 = Matrix * v4{Rad, -Rad, 0, 1};
|
||||||
|
v4 P2 = Matrix * v4{Rad, Rad, 0, 1};
|
||||||
|
v4 P3 = Matrix * v4{-Rad, Rad, 0, 1};
|
||||||
|
|
||||||
|
v4 P0P = Projection * P0;
|
||||||
|
v4 P1P = Projection * P1;
|
||||||
|
v4 P2P = Projection * P2;
|
||||||
|
v4 P3P = Projection * P3;
|
||||||
|
|
||||||
|
v4 P0PD = PerspectiveDivide(P0P);
|
||||||
|
v4 P1PD = PerspectiveDivide(P1P);
|
||||||
|
v4 P2PD = PerspectiveDivide(P2P);
|
||||||
|
v4 P3PD = PerspectiveDivide(P3P);
|
||||||
|
|
||||||
|
v4 P0S = ToScreen(P0PD, WindowBounds);
|
||||||
|
P0S.w = 1;
|
||||||
|
|
||||||
|
v4 P1S = ToScreen(P1PD, WindowBounds);
|
||||||
|
P1S.w = 1;
|
||||||
|
|
||||||
|
v4 P2S = ToScreen(P2PD, WindowBounds);
|
||||||
|
P2S.w = 1;
|
||||||
|
|
||||||
|
v4 P3S = ToScreen(P3PD, WindowBounds);
|
||||||
|
P3S.w = 1;
|
||||||
|
|
||||||
|
Assert(V4Mag(P0S - v4{630.11401, 256.88202, 0.99930286, 1}) < 0.00001f);
|
||||||
|
Assert(V4Mag(P1S - v4{795.28662, 277.52859, 0.99948108, 1}) < 0.00001f);
|
||||||
|
Assert(V4Mag(P2S - v4{795.28662, 490.47144, 0.99948108, 1}) < 0.00001f);
|
||||||
|
Assert(V4Mag(P3S - v4{630.11401, 511.11798, 0.99930286, 1}) < 0.00001f);
|
||||||
|
|
||||||
|
//PushRenderQuad2D(RenderBuffer, P0S.xy, P1S.xy, P2S.xy, P3S.xy, WhiteV4);
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
||||||
Win32UpdateWindowDimension(&MainWindow);
|
Win32UpdateWindowDimension(&MainWindow);
|
||||||
|
|
||||||
|
@ -612,7 +1145,7 @@ WinMain (
|
||||||
input_queue InputQueue;
|
input_queue InputQueue;
|
||||||
{
|
{
|
||||||
s32 InputQueueMemorySize = sizeof(input_entry) * 32;
|
s32 InputQueueMemorySize = sizeof(input_entry) * 32;
|
||||||
u8* InputQueueMemory = Win32Alloc(InputQueueMemorySize);
|
u8* InputQueueMemory = (u8*)Win32Alloc(InputQueueMemorySize, 0);
|
||||||
InputQueue = InitializeInputQueue(InputQueueMemory, InputQueueMemorySize);
|
InputQueue = InitializeInputQueue(InputQueueMemory, InputQueueMemorySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,31 +1158,31 @@ WinMain (
|
||||||
WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * PLATFORM_THREAD_COUNT);
|
WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * PLATFORM_THREAD_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
work_queue WorkQueue = {};
|
HANDLE WorkQueueSemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS);
|
||||||
WorkQueue.SemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS);
|
|
||||||
|
gs_work_queue WorkQueue = {};
|
||||||
|
WorkQueue.SemaphoreHandle = &WorkQueueSemaphoreHandle;
|
||||||
WorkQueue.JobsMax = 512;
|
WorkQueue.JobsMax = 512;
|
||||||
WorkQueue.Jobs = (worker_thread_job*)Win32Alloc(sizeof(worker_thread_job) * WorkQueue.JobsMax);
|
WorkQueue.Jobs = (gs_threaded_job*)Win32Alloc(sizeof(gs_threaded_job) * WorkQueue.JobsMax, 0);
|
||||||
WorkQueue.NextJobIndex = 0;
|
WorkQueue.NextJobIndex = 0;
|
||||||
WorkQueue.PushWorkOnQueue = Win32PushWorkOnQueue;
|
WorkQueue.PushWorkOnQueue = Win32PushWorkOnQueue;
|
||||||
WorkQueue.DoQueueWorkUntilDone = Win32DoQueueWorkUntilDone;
|
WorkQueue.CompleteQueueWork = Win32DoQueueWorkUntilDone;
|
||||||
WorkQueue.ResetWorkQueue = ResetWorkQueue;
|
WorkQueue.ResetWorkQueue = ResetWorkQueue;
|
||||||
|
|
||||||
OutputDebugStringA("Hellooooo\n");
|
|
||||||
|
|
||||||
for (s32 i = 0; i < PLATFORM_THREAD_COUNT; i++)
|
for (s32 i = 0; i < PLATFORM_THREAD_COUNT; i++)
|
||||||
{
|
{
|
||||||
// ID = 0 is reserved for this thread
|
// ID = 0 is reserved for this thread
|
||||||
WorkerThreads[i].ID = i + 1;
|
|
||||||
WorkerThreads[i].Queue = &WorkQueue;
|
WorkerThreads[i].Queue = &WorkQueue;
|
||||||
WorkerThreads[i].Handle = CreateThread(0, 0, &WorkerThreadProc, (void*)&WorkerThreads[i], 0, 0);
|
WorkerThreads[i].Handle = CreateThread(0, 0, &WorkerThreadProc, (void*)&WorkerThreads[i], 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 InitialMemorySize = Megabytes(64);
|
s32 InitialMemorySize = MB(64);
|
||||||
u8* InitialMemory = Win32Alloc(InitialMemorySize);
|
u8* InitialMemory = (u8*)Win32Alloc(InitialMemorySize, 0);
|
||||||
context Context = {};
|
context Context = {};
|
||||||
|
Context.ThreadContext = ThreadContext;
|
||||||
Context.MemorySize = InitialMemorySize;
|
Context.MemorySize = InitialMemorySize;
|
||||||
Context.MemoryBase = InitialMemory;
|
Context.MemoryBase = InitialMemory;
|
||||||
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||||
Context.Mouse = {0};
|
Context.Mouse = {0};
|
||||||
|
|
||||||
// Cursors
|
// Cursors
|
||||||
|
@ -663,12 +1196,6 @@ WinMain (
|
||||||
|
|
||||||
// Platform functions
|
// Platform functions
|
||||||
Context.GeneralWorkQueue = &WorkQueue;
|
Context.GeneralWorkQueue = &WorkQueue;
|
||||||
Context.PlatformMemory.Alloc = Win32Alloc;
|
|
||||||
Context.PlatformMemory.Free = Win32Free;
|
|
||||||
Context.PlatformMemory.Realloc = Win32Realloc;
|
|
||||||
Context.FileHandler.ReadEntireFile = Win32ReadEntireFile;
|
|
||||||
Context.FileHandler.WriteEntireFile = Win32WriteEntireFile;
|
|
||||||
Context.FileHandler.GetFilePath = Win32SystemDialogueOpenFile;
|
|
||||||
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
||||||
Context.PlatformGetSocketHandle = Win32GetSocketHandle;
|
Context.PlatformGetSocketHandle = Win32GetSocketHandle;
|
||||||
Context.PlatformSetSocketOption = Win32SetSocketOption;
|
Context.PlatformSetSocketOption = Win32SetSocketOption;
|
||||||
|
@ -692,8 +1219,8 @@ WinMain (
|
||||||
WSADATA WSAData;
|
WSADATA WSAData;
|
||||||
WSAStartup(MAKEWORD(2, 2), &WSAData);
|
WSAStartup(MAKEWORD(2, 2), &WSAData);
|
||||||
|
|
||||||
s32 RenderMemorySize = Megabytes(12);
|
s32 RenderMemorySize = MB(12);
|
||||||
u8* RenderMemory = Win32Alloc(RenderMemorySize);
|
u8* RenderMemory = (u8*)Win32Alloc(RenderMemorySize, 0);
|
||||||
render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(RenderMemory, RenderMemorySize, Win32Realloc);
|
render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(RenderMemory, RenderMemorySize, Win32Realloc);
|
||||||
|
|
||||||
Context.InitializeApplication(Context);
|
Context.InitializeApplication(Context);
|
||||||
|
@ -733,7 +1260,7 @@ WinMain (
|
||||||
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse);
|
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||||
RenderBuffer.ViewWidth = MainWindow.Width;
|
RenderBuffer.ViewWidth = MainWindow.Width;
|
||||||
RenderBuffer.ViewHeight = MainWindow.Height;
|
RenderBuffer.ViewHeight = MainWindow.Height;
|
||||||
Context.DeltaTime = LastFrameSecondsElapsed;
|
Context.DeltaTime = LastFrameSecondsElapsed;
|
||||||
|
|
|
@ -22,15 +22,15 @@ struct win32_dll_refresh
|
||||||
};
|
};
|
||||||
|
|
||||||
internal int
|
internal int
|
||||||
Win32DLLStringLength(char* String)
|
Win32DLLgs_stringLength(char* gs_string)
|
||||||
{
|
{
|
||||||
char* At = String;
|
char* At = gs_string;
|
||||||
while (*At) { At++; };
|
while (*At) { At++; };
|
||||||
return At - String;
|
return At - gs_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal int
|
internal int
|
||||||
Win32DLLConcatStrings(int ALength, char* A, int BLength, char* B, int DestLength, char* Dest)
|
Win32DLLConcatgs_strings(int ALength, char* A, int BLength, char* B, int DestLength, char* Dest)
|
||||||
{
|
{
|
||||||
char* Dst = Dest;
|
char* Dst = Dest;
|
||||||
char* AAt = A;
|
char* AAt = A;
|
||||||
|
@ -112,14 +112,14 @@ InitializeDLLHotReloading(char* SourceDLLName,
|
||||||
ExePath.Path = (char*)VirtualAlloc(NULL, ExePath.PathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
ExePath.Path = (char*)VirtualAlloc(NULL, ExePath.PathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
GetApplicationPath(&ExePath);
|
GetApplicationPath(&ExePath);
|
||||||
|
|
||||||
Win32DLLConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path,
|
||||||
Win32DLLStringLength(SourceDLLName), SourceDLLName,
|
Win32DLLgs_stringLength(SourceDLLName), SourceDLLName,
|
||||||
MAX_PATH, Result.SourceDLLPath);
|
MAX_PATH, Result.SourceDLLPath);
|
||||||
Win32DLLConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path,
|
||||||
Win32DLLStringLength(WorkingDLLFileName), WorkingDLLFileName,
|
Win32DLLgs_stringLength(WorkingDLLFileName), WorkingDLLFileName,
|
||||||
MAX_PATH, Result.WorkingDLLPath);
|
MAX_PATH, Result.WorkingDLLPath);
|
||||||
Win32DLLConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
Win32DLLConcatgs_strings(ExePath.IndexOfLastSlash, ExePath.Path,
|
||||||
Win32DLLStringLength(LockFileName), LockFileName,
|
Win32DLLgs_stringLength(LockFileName), LockFileName,
|
||||||
MAX_PATH, Result.LockFilePath);
|
MAX_PATH, Result.LockFilePath);
|
||||||
|
|
||||||
Win32Free((u8*)ExePath.Path, ExePath.PathLength);
|
Win32Free((u8*)ExePath.Path, ExePath.PathLength);
|
||||||
|
|
|
@ -8,138 +8,5 @@
|
||||||
//
|
//
|
||||||
#ifndef WIN32_FOLDHAUS_FILEIO_H
|
#ifndef WIN32_FOLDHAUS_FILEIO_H
|
||||||
|
|
||||||
PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile)
|
|
||||||
{
|
|
||||||
platform_memory_result Result = {};
|
|
||||||
Result.Error = PlatformMemory_NoError;
|
|
||||||
|
|
||||||
Assert(IsNullTerminated(Path));
|
|
||||||
HANDLE FileHandle = CreateFileA (Path.Memory, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
|
|
||||||
if (FileHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
DWORD FileSize = GetFileSize(FileHandle, NULL);
|
|
||||||
Result.Data.Base = (u8*)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
|
||||||
if (Result.Data.Base)
|
|
||||||
{
|
|
||||||
Result.Data.Size = FileSize;
|
|
||||||
|
|
||||||
s32 BytesRead = 0;
|
|
||||||
if (ReadFile(FileHandle, (LPVOID)Result.Data.Base, FileSize, (LPDWORD)(&BytesRead), NULL))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u32 Error = GetLastError();
|
|
||||||
VirtualFree(Result.Data.Base, 0, MEM_RELEASE);
|
|
||||||
Result.Data.Size = 0;
|
|
||||||
Result.Error = PlatformMemory_UnknownError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result.Error = PlatformMemory_UnknownError;
|
|
||||||
}
|
|
||||||
CloseHandle(FileHandle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result.Error = PlatformMemory_FileNotFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile)
|
|
||||||
{
|
|
||||||
Assert(IsNullTerminated(Path));
|
|
||||||
b32 Result = false;
|
|
||||||
HANDLE FileHandle = CreateFileA (
|
|
||||||
Path.Memory,
|
|
||||||
GENERIC_WRITE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
CREATE_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (FileHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
DWORD BytesWritten = 0;
|
|
||||||
|
|
||||||
b32 WriteSuccess = WriteFile(FileHandle,
|
|
||||||
Contents, Size,
|
|
||||||
&BytesWritten,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (WriteSuccess && BytesWritten == (u32)Size)
|
|
||||||
{
|
|
||||||
CloseHandle(FileHandle);
|
|
||||||
Result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal FILETIME
|
|
||||||
GetFileLastWriteTime(char* Path)
|
|
||||||
{
|
|
||||||
FILETIME Result = {};
|
|
||||||
|
|
||||||
WIN32_FIND_DATA FindData = {};
|
|
||||||
HANDLE FileHandle = FindFirstFileA(Path, &FindData);
|
|
||||||
|
|
||||||
if (FileHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
Result = FindData.ftLastWriteTime;
|
|
||||||
FindClose(FileHandle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO(Peter): :ErrorLogging
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile)
|
|
||||||
{
|
|
||||||
b32 Result = false;
|
|
||||||
|
|
||||||
PathBuffer->Memory[0] = 0;
|
|
||||||
|
|
||||||
OPENFILENAMEA OpenFileName = {};
|
|
||||||
OpenFileName.lStructSize = sizeof(OpenFileName);
|
|
||||||
OpenFileName.hwndOwner = NULL;
|
|
||||||
OpenFileName.lpstrFilter = FilterStrings;
|
|
||||||
OpenFileName.lpstrCustomFilter = NULL; // NOTE(Peter): for preserving last filter string chosen
|
|
||||||
OpenFileName.nMaxCustFilter = 0; // NOTE(Peter): ignored since we left CustomFilter null
|
|
||||||
OpenFileName.nFilterIndex = 1;
|
|
||||||
OpenFileName.lpstrFile = PathBuffer->Memory;
|
|
||||||
OpenFileName.nMaxFile = PathBuffer->Max;
|
|
||||||
OpenFileName.lpstrFileTitle = NULL;
|
|
||||||
OpenFileName.nMaxFileTitle = 0; // NOTE(Peter): Ignored since fileTitle is null
|
|
||||||
OpenFileName.lpstrInitialDir = NULL;
|
|
||||||
OpenFileName.lpstrTitle = NULL;
|
|
||||||
OpenFileName.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
|
|
||||||
OpenFileName.lpstrDefExt = NULL;
|
|
||||||
|
|
||||||
Result = GetOpenFileNameA (&OpenFileName);
|
|
||||||
|
|
||||||
PathBuffer->Length = CharArrayLength(PathBuffer->Memory);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WIN32_FOLDHAUS_FILEIO_H
|
#define WIN32_FOLDHAUS_FILEIO_H
|
||||||
#endif // WIN32_FOLDHAUS_FILEIO_H
|
#endif // WIN32_FOLDHAUS_FILEIO_H
|
|
@ -8,17 +8,21 @@
|
||||||
//
|
//
|
||||||
#ifndef WIN32_FOLDHAUS_MEMORY_H
|
#ifndef WIN32_FOLDHAUS_MEMORY_H
|
||||||
|
|
||||||
PLATFORM_ALLOC(Win32Alloc)
|
ALLOCATOR_ALLOC(Win32Alloc)
|
||||||
{
|
{
|
||||||
u8* Result = (u8*)VirtualAlloc(NULL, Size,
|
u8* Result = (u8*)VirtualAlloc(NULL, Size,
|
||||||
MEM_COMMIT | MEM_RESERVE,
|
MEM_COMMIT | MEM_RESERVE,
|
||||||
PAGE_EXECUTE_READWRITE);
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
if (ResultSize != 0)
|
||||||
|
{
|
||||||
|
*ResultSize = Size;
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PLATFORM_FREE(Win32Free)
|
ALLOCATOR_FREE(Win32Free)
|
||||||
{
|
{
|
||||||
b32 Result = VirtualFree(Base, 0, MEM_RELEASE);
|
b32 Result = VirtualFree(Ptr, 0, MEM_RELEASE);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
{
|
{
|
||||||
s32 Error = GetLastError();
|
s32 Error = GetLastError();
|
||||||
|
@ -26,18 +30,6 @@ PLATFORM_FREE(Win32Free)
|
||||||
// to know what it could possibly be.
|
// to know what it could possibly be.
|
||||||
InvalidCodePath;
|
InvalidCodePath;
|
||||||
}
|
}
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLATFORM_REALLOC(Win32Realloc)
|
|
||||||
{
|
|
||||||
u8* NewMemory = Win32Alloc(NewSize);
|
|
||||||
if (Base)
|
|
||||||
{
|
|
||||||
GSMemCopy(Base, NewMemory, OldSize);
|
|
||||||
Win32Free(Base, OldSize);
|
|
||||||
}
|
|
||||||
return NewMemory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WIN32_FOLDHAUS_MEMORY_H
|
#define WIN32_FOLDHAUS_MEMORY_H
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef GS_LANGUAGE_H
|
#ifndef GS_LANGUAGE_H
|
||||||
|
|
||||||
|
#if 0
|
||||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__)
|
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
|
||||||
|
@ -42,6 +43,8 @@ typedef long long int s64;
|
||||||
typedef float r32;
|
typedef float r32;
|
||||||
typedef double r64;
|
typedef double r64;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _STDINT
|
#ifndef _STDINT
|
||||||
|
|
||||||
#define INT8_MIN (-128)
|
#define INT8_MIN (-128)
|
||||||
|
|
|
@ -314,7 +314,7 @@ PlatformRealloc(platform_memory_handler Platform, gs_mem_u8* Head, gs_mem_u32 Ol
|
||||||
Result = PlatformAlloc(Platform, NewSize);
|
Result = PlatformAlloc(Platform, NewSize);
|
||||||
if (Head != 0 && OldSize != 0)
|
if (Head != 0 && OldSize != 0)
|
||||||
{
|
{
|
||||||
GSMemCopy(Head, Result, OldSize);
|
CopyMemoryTo(Head, Result, OldSize);
|
||||||
PlatformFree(Platform, Head, OldSize);
|
PlatformFree(Platform, Head, OldSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,8 +336,6 @@ FreeMemoryArena(memory_arena* Arena)
|
||||||
PlatformFree(Arena->PlatformMemory, (u8*)Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount);
|
PlatformFree(Arena->PlatformMemory, (u8*)Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IsPowerOfTwo(v) ((v != 0) && ((v & (v - 1)) == 0))
|
|
||||||
|
|
||||||
inline gs_mem_u32
|
inline gs_mem_u32
|
||||||
GetAlignmentOffset (gs_mem_u64 Address, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask)
|
GetAlignmentOffset (gs_mem_u64 Address, gs_mem_u32 Alignment, gs_mem_u32 AlignmentMask)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,7 @@ Write(string Text, string_builder* StringBuilder)
|
||||||
// Copy what there is room for
|
// Copy what there is room for
|
||||||
s32 SpaceAvailable = StringBuilder->Head->String.Max - StringBuilder->Head->String.Length;
|
s32 SpaceAvailable = StringBuilder->Head->String.Max - StringBuilder->Head->String.Length;
|
||||||
|
|
||||||
ConcatString(TextLeft, GSMin(SpaceAvailable, TextLeft.Length), &StringBuilder->Head->String);
|
ConcatString(TextLeft, Min(SpaceAvailable, TextLeft.Length), &StringBuilder->Head->String);
|
||||||
TextLeft.Memory += SpaceAvailable;
|
TextLeft.Memory += SpaceAvailable;
|
||||||
TextLeft.Length -= SpaceAvailable;
|
TextLeft.Length -= SpaceAvailable;
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ WriteStringBuilderToFile(string_builder StringBuilder, FILE* WriteFile)
|
||||||
while (BufferAt)
|
while (BufferAt)
|
||||||
{
|
{
|
||||||
string String = BufferAt->String;
|
string String = BufferAt->String;
|
||||||
fwrite(String.Memory, 1, String.Length, WriteFile);
|
fwrite(String.Str, 1, String.Length, WriteFile);
|
||||||
BufferAt = BufferAt->Next;
|
BufferAt = BufferAt->Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -105,25 +105,12 @@ union v4
|
||||||
|
|
||||||
union m33
|
union m33
|
||||||
{
|
{
|
||||||
struct
|
float E[3][3];
|
||||||
{
|
|
||||||
float a; float b; float c;
|
|
||||||
float d; float e; float f;
|
|
||||||
float g; float h; float i;
|
|
||||||
};
|
|
||||||
float E[9];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
union m44
|
union m44
|
||||||
{
|
{
|
||||||
struct
|
float E[4][4];
|
||||||
{
|
|
||||||
float a; float b; float c; float d;
|
|
||||||
float e; float f; float g; float h;
|
|
||||||
float i; float j; float k; float l;
|
|
||||||
float m; float n; float o; float p;
|
|
||||||
};
|
|
||||||
float E[16];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
@ -648,10 +635,10 @@ PointIsInRange (v2 _P, v2 _Min, v2 _Max)
|
||||||
static bool
|
static bool
|
||||||
PointIsInRangeSafe (v2 _P, v2 _Min, v2 _Max)
|
PointIsInRangeSafe (v2 _P, v2 _Min, v2 _Max)
|
||||||
{
|
{
|
||||||
s32 MinX = GSMin(_Min.x, _Max.x);
|
s32 MinX = Min(_Min.x, _Max.x);
|
||||||
s32 MinY = GSMin(_Min.y, _Max.y);
|
s32 MinY = Min(_Min.y, _Max.y);
|
||||||
s32 MaxX = GSMax(_Min.x, _Max.x);
|
s32 MaxX = Max(_Min.x, _Max.x);
|
||||||
s32 MaxY = GSMax(_Min.y, _Max.y);
|
s32 MaxY = Max(_Min.y, _Max.y);
|
||||||
|
|
||||||
return (_P.x >= MinX && _P.x <= MaxX &&
|
return (_P.x >= MinX && _P.x <= MaxX &&
|
||||||
_P.y >= MinY && _P.y <= MaxY);
|
_P.y >= MinY && _P.y <= MaxY);
|
||||||
|
@ -1438,11 +1425,11 @@ void TestVectorMatrixMultiplication ()
|
||||||
|
|
||||||
// Utility Functions
|
// Utility Functions
|
||||||
TestClean((GSSqrt(4.f) == 2.f), "Vector Square Root");
|
TestClean((GSSqrt(4.f) == 2.f), "Vector Square Root");
|
||||||
TestClean((GSLerp(0.f, 1.f, .5f) == .5f), "Vector Lerp");
|
TestClean((Lerp(0.f, 1.f, .5f) == .5f), "Vector Lerp");
|
||||||
TestClean((GSMin(-.25f, 5.f) == -.25f), "Vector Min");
|
TestClean((Min(-.25f, 5.f) == -.25f), "Vector Min");
|
||||||
TestClean((GSMax(-.25f, 5.f) == 5.f), "Vector Max");
|
TestClean((Max(-.25f, 5.f) == 5.f), "Vector Max");
|
||||||
TestClean((GSClamp(-2.f, -3.f, 5.f) == -2.f), "Vector Clamp, Lower Than Range");
|
TestClean((Clamp(-2.f, -3.f, 5.f) == -2.f), "Vector Clamp, Lower Than Range");
|
||||||
TestClean((GSClamp(-2.f, 6.f, 5.f) == 5.f), "Vector Clamp, Higher Than Range");
|
TestClean((Clamp(-2.f, 6.f, 5.f) == 5.f), "Vector Clamp, Higher Than Range");
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Vector Functions
|
// Vector Functions
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct handle_window_msg_result
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
global_variable win32_state GlobalWin32State;
|
global win32_state GlobalWin32State;
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
internal s32 Win32StringLength(char* String);
|
internal s32 Win32StringLength(char* String);
|
||||||
|
@ -66,9 +66,8 @@ internal void Win32DisplayBufferInWindow(win32_offscreen_buffer* Buffer
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
|
|
||||||
internal PLATFORM_ALLOC(Win32Alloc);
|
internal ALLOCATOR_ALLOC(Win32Alloc);
|
||||||
internal PLATFORM_FREE(Win32Free);
|
internal ALLOCATOR_FREE(Win32Free);
|
||||||
internal PLATFORM_REALLOC(Win32Realloc);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
// Utils
|
// Utils
|
||||||
|
|
|
@ -218,8 +218,8 @@ GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelEnumGen, s
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteF(PanelEnumGen, "enum panel_type {\n");
|
WriteF(PanelEnumGen, "enum panel_type {\n");
|
||||||
WriteF(PanelCodeGen, "global_variable s32 GlobalPanelDefsCount = %d;\n", Panels.Used);
|
WriteF(PanelCodeGen, "global s32 GlobalPanelDefsCount = %d;\n", Panels.Used);
|
||||||
WriteF(PanelCodeGen, "global_variable panel_definition GlobalPanelDefs[] = {\n");
|
WriteF(PanelCodeGen, "global panel_definition GlobalPanelDefs[] = {\n");
|
||||||
for (u32 i = 0; i < Panels.Used; i++)
|
for (u32 i = 0; i < Panels.Used; i++)
|
||||||
{
|
{
|
||||||
panel_elements* Panel = Panels.GetElementAtIndex(i);
|
panel_elements* Panel = Panels.GetElementAtIndex(i);
|
||||||
|
|
|
@ -14,13 +14,32 @@ struct errors
|
||||||
u32 Used;
|
u32 Used;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ErrorReallocArray(base, type, oldcount, newcount) (type*)ErrorRealloc_((u8*)(base), (u64)(sizeof(type) * oldcount), (u64)(sizeof(type) * newcount))
|
||||||
|
internal u8*
|
||||||
|
ErrorRealloc_(u8* Base, u64 OldSize, u64 NewSize)
|
||||||
|
{
|
||||||
|
Assert(NewSize > 0);
|
||||||
|
u8* Result = (u8*)malloc(NewSize);
|
||||||
|
if (Base != 0 && OldSize > 0)
|
||||||
|
{
|
||||||
|
GSMemCopy(Base, Result, OldSize);
|
||||||
|
free(Base);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushFError (errors* Errors, char* Format, ...)
|
PushFError (errors* Errors, char* Format, ...)
|
||||||
{
|
{
|
||||||
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
|
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
Errors->BuffersCount += 1;
|
Errors->BuffersCount += 1;
|
||||||
Errors->Buffers = (error_buffer*)realloc(Errors->Buffers, sizeof(error_buffer*) * Errors->BuffersCount);
|
Errors->Buffers = (error_buffer*)realloc(Errors->Buffers, sizeof(error_buffer*) * Errors->BuffersCount);
|
||||||
|
#else
|
||||||
|
Errors->Buffers = ErrorReallocArray(Errors->Buffers, error_buffer, Errors->BuffersCount, Errors->BuffersCount + 1);
|
||||||
|
Errors->BuffersCount += 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
error_buffer* NewBuffer = Errors->Buffers + (Errors->BuffersCount - 1);
|
error_buffer* NewBuffer = Errors->Buffers + (Errors->BuffersCount - 1);
|
||||||
NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE);
|
NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE);
|
||||||
|
@ -28,8 +47,8 @@ PushFError (errors* Errors, char* Format, ...)
|
||||||
|
|
||||||
for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++)
|
for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++)
|
||||||
{
|
{
|
||||||
NewBuffer->Contents[i].Memory = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH);
|
NewBuffer->Contents[i].Str = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH);
|
||||||
NewBuffer->Contents[i].Max = ERROR_MAX_LENGTH;
|
NewBuffer->Contents[i].Size = ERROR_MAX_LENGTH;
|
||||||
NewBuffer->Contents[i].Length = 0;
|
NewBuffer->Contents[i].Length = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
struct token_selection_spec
|
struct token_selection_spec
|
||||||
{
|
{
|
||||||
b32 MatchText;
|
b32 MatchText;
|
||||||
string Text;
|
gs_string Text;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal s32
|
internal s32
|
||||||
|
@ -160,69 +160,69 @@ GetNextToken (tokenizer* Tokenizer)
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundDefine;
|
Result.Type = Token_PoundDefine;
|
||||||
EatPreprocessor(Tokenizer);
|
EatPreprocessor(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "undef"))
|
else if (TokenAtEquals(Tokenizer, "undef"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundUndef;
|
Result.Type = Token_PoundUndef;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "include"))
|
else if (TokenAtEquals(Tokenizer, "include"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundInclude;
|
Result.Type = Token_PoundInclude;
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "ifdef"))
|
else if (TokenAtEquals(Tokenizer, "ifdef"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundIfDef;
|
Result.Type = Token_PoundIfDef;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "ifndef"))
|
else if (TokenAtEquals(Tokenizer, "ifndef"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundIfNDef;
|
Result.Type = Token_PoundIfNDef;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "if"))
|
else if (TokenAtEquals(Tokenizer, "if"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundIf;
|
Result.Type = Token_PoundIf;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "elif"))
|
else if (TokenAtEquals(Tokenizer, "elif"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundElif;
|
Result.Type = Token_PoundElif;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "else"))
|
else if (TokenAtEquals(Tokenizer, "else"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundElse;
|
Result.Type = Token_PoundElse;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "endif"))
|
else if (TokenAtEquals(Tokenizer, "endif"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundEndif;
|
Result.Type = Token_PoundEndif;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "error"))
|
else if (TokenAtEquals(Tokenizer, "error"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundError;
|
Result.Type = Token_PoundError;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
else if (TokenAtEquals(Tokenizer, "pragma"))
|
else if (TokenAtEquals(Tokenizer, "pragma"))
|
||||||
{
|
{
|
||||||
Result.Type = Token_PoundPragma;
|
Result.Type = Token_PoundPragma;
|
||||||
EatToNewLine(Tokenizer);
|
EatToNewLine(Tokenizer);
|
||||||
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
|
Result.Text.Length = Tokenizer->At - Result.Text.Str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsNumeric(C))
|
else if (IsNumericExtended(C))
|
||||||
{
|
{
|
||||||
Result.Type = Token_Number;
|
Result.Type = Token_Number;
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ GetNextToken (tokenizer* Tokenizer)
|
||||||
else if (C == '\'')
|
else if (C == '\'')
|
||||||
{
|
{
|
||||||
Result.Type = Token_Char;
|
Result.Type = Token_Char;
|
||||||
Result.Text.Memory = Tokenizer->At;
|
Result.Text.Str = Tokenizer->At;
|
||||||
if (Tokenizer->At[0] && Tokenizer->At[0] == '\\')
|
if (Tokenizer->At[0] && Tokenizer->At[0] == '\\')
|
||||||
{
|
{
|
||||||
++Tokenizer->At;
|
++Tokenizer->At;
|
||||||
|
@ -245,7 +245,7 @@ GetNextToken (tokenizer* Tokenizer)
|
||||||
{
|
{
|
||||||
Result.Type = Token_String;
|
Result.Type = Token_String;
|
||||||
// replace the length added by the quote
|
// replace the length added by the quote
|
||||||
Result.Text.Memory = Tokenizer->At;
|
Result.Text.Str = Tokenizer->At;
|
||||||
Result.Text.Length = EatString(Tokenizer);
|
Result.Text.Length = EatString(Tokenizer);
|
||||||
}
|
}
|
||||||
// NOTE(Peter): This is after comment parsing so that the division operator
|
// NOTE(Peter): This is after comment parsing so that the division operator
|
||||||
|
|
Loading…
Reference in New Issue