Pulled the leds out of assemblies and into their own subsystem.

This commit is contained in:
Peter Slattery 2020-06-15 15:36:50 -07:00
parent bfd9d6671c
commit 69db4b436c
12 changed files with 390 additions and 313 deletions

View File

@ -5,7 +5,7 @@
// //
#ifndef FOLDHAUS_ANIMATION #ifndef FOLDHAUS_ANIMATION
#define ANIMATION_PROC(name) void name(assembly_led_buffer* Assembly, r32 Time) #define ANIMATION_PROC(name) void name(led_buffer* Assembly, r32 Time)
typedef ANIMATION_PROC(animation_proc); typedef ANIMATION_PROC(animation_proc);
struct frame_range struct frame_range
@ -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; memory_arena* Storage;
gs_list<animation_block> Blocks; gs_list<animation_block> Blocks;
anim_layer* Layers; anim_layer* Layers;
@ -143,7 +143,7 @@ AddLayer (string Name, animation_system* AnimationSystem, blend_mode BlendMode =
Result = AnimationSystem->LayersCount++; Result = AnimationSystem->LayersCount++;
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); CopyStringTo(Name, &NewLayer->Name);
NewLayer->BlendMode = BlendMode; NewLayer->BlendMode = BlendMode;
return Result; return Result;

View File

@ -58,6 +58,8 @@ struct assembly_tokenizer
char* At; char* At;
u32 LineNumber; u32 LineNumber;
bool ParsingIsValid;
}; };
internal bool internal bool
@ -128,12 +130,12 @@ ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T)
} }
else else
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
} }
else else
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
return Result; return Result;
} }
@ -148,7 +150,7 @@ ReadFieldEnd(assembly_tokenizer* T)
} }
else else
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
return Result; return Result;
} }
@ -228,7 +230,7 @@ ReadStringField(assembly_field Field, assembly_tokenizer* T, memory_arena* Arena
} }
else else
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
} }
return Result; return Result;
@ -243,7 +245,7 @@ ReadFloatField(assembly_field Field, assembly_tokenizer* T)
Result = ReadFloat(T); Result = ReadFloat(T);
if (!ReadFieldEnd(T)) if (!ReadFieldEnd(T))
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
} }
return Result; return Result;
@ -258,7 +260,7 @@ ReadIntField(assembly_field Field, assembly_tokenizer* T)
Result = ReadInt(T); Result = ReadInt(T);
if (!ReadFieldEnd(T)) if (!ReadFieldEnd(T))
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
} }
return Result; return Result;
@ -279,16 +281,31 @@ ReadV3Field(assembly_field Field, assembly_tokenizer* T)
if (AdvanceIfTokenEquals(T, ",")) if (AdvanceIfTokenEquals(T, ","))
{ {
Result.z = ReadFloat(T); Result.z = ReadFloat(T);
if (AdvanceIfTokenEquals(T, ")")) if (AdvanceIfTokenEquals(T, ")"))
{ {
if (!ReadFieldEnd(T)) if (!ReadFieldEnd(T))
{ {
// TODO(Peter): Error T->ParsingIsValid = false;
} }
} }
else
{
T->ParsingIsValid = false;
} }
} }
else
{
T->ParsingIsValid = false;
}
}
else
{
T->ParsingIsValid = false;
}
}
else
{
T->ParsingIsValid = false;
} }
} }
return Result; return Result;
@ -315,15 +332,15 @@ ReadStructClosing(assembly_tokenizer* T)
return Result; return Result;
} }
internal void internal bool
ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient) ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
{ {
Assert(Assembly->Arena.Alloc != 0);
Assembly->LedCountTotal = 0; Assembly->LedCountTotal = 0;
assembly_tokenizer Tokenizer = {}; assembly_tokenizer Tokenizer = {};
Tokenizer.Text = FileText; Tokenizer.Text = FileText;
Tokenizer.At = Tokenizer.Text.Memory; Tokenizer.At = Tokenizer.Text.Memory;
Tokenizer.ParsingIsValid = true;
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);
@ -349,8 +366,7 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
StripAt->EndPosition = ReadV3Field(AssemblyField_End, &Tokenizer); StripAt->EndPosition = ReadV3Field(AssemblyField_End, &Tokenizer);
if (!ReadStructClosing(&Tokenizer)) if (!ReadStructClosing(&Tokenizer))
{ {
// TODO(Peter): Error Tokenizer.ParsingIsValid = false;
InvalidCodePath;
} }
} }
@ -372,19 +388,27 @@ ParseAssemblyFile(assembly* Assembly, string FileText, memory_arena* Transient)
TagAt->ValueHash = HashString(TagValue); TagAt->ValueHash = HashString(TagValue);
if (!ReadStructClosing(&Tokenizer)) if (!ReadStructClosing(&Tokenizer))
{ {
// TODO(Peter): Error Tokenizer.ParsingIsValid = false;
InvalidCodePath;
} }
} }
else
{
Tokenizer.ParsingIsValid = false;
}
} }
if (!ReadStructClosing(&Tokenizer)) if (!ReadStructClosing(&Tokenizer))
{ {
// TODO(Peter): Error Tokenizer.ParsingIsValid = false;
InvalidCodePath;
} }
} }
else
{
Tokenizer.ParsingIsValid = false;
} }
}
return Tokenizer.ParsingIsValid;
} }
#define ASSEMBLY_PARSER_CPP #define ASSEMBLY_PARSER_CPP

View File

@ -70,13 +70,16 @@ RELOAD_STATIC_DATA(ReloadStaticData)
INITIALIZE_APPLICATION(InitializeApplication) INITIALIZE_APPLICATION(InitializeApplication)
{ {
app_state* State = (app_state*)Context.MemoryBase; app_state* State = (app_state*)Context.MemoryBase;
*State = {};
State->Permanent = {}; State->Permanent = {};
State->Permanent.Alloc = (gs_memory_alloc*)Context.PlatformAlloc; State->Permanent.PlatformMemory = Context.PlatformMemory;
State->Permanent.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
State->Transient = {}; State->Transient = {};
State->Transient.FindAddressRule = FindAddress_InLastBufferOnly; State->Transient.FindAddressRule = FindAddress_InLastBufferOnly;
State->Transient.Alloc = (gs_memory_alloc*)Context.PlatformAlloc; State->Transient.PlatformMemory = Context.PlatformMemory;
State->Transient.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
State->Assemblies.CountMax = 8;
State->Assemblies.Values = PushArray(&State->Permanent, assembly, State->Assemblies.CountMax);
State->GlobalLog = PushStruct(&State->Transient, event_log); State->GlobalLog = PushStruct(&State->Transient, event_log);
*State->GlobalLog = {0}; *State->GlobalLog = {0};
@ -175,6 +178,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->Camera.Position = v3{0, 0, -250}; State->Camera.Position = v3{0, 0, -250};
State->Camera.LookAt = v3{0, 0, 0}; State->Camera.LookAt = v3{0, 0, 0};
State->LedSystem = LedSystemInitialize(Context.PlatformMemory, 128);
#if 1 #if 1
string SculpturePath = MakeStringLiteral("data/blumen_lumen_v2.fold"); string SculpturePath = MakeStringLiteral("data/blumen_lumen_v2.fold");
LoadAssembly(State, Context, SculpturePath); LoadAssembly(State, Context, SculpturePath);
@ -189,12 +194,12 @@ INITIALIZE_APPLICATION(InitializeApplication)
// Setup Operation Modes // Setup Operation Modes
State->Modes.ActiveModesCount = 0; State->Modes.ActiveModesCount = 0;
State->Modes.Arena = {}; State->Modes.Arena = {};
State->Modes.Arena.Alloc = (gs_memory_alloc*)Context.PlatformAlloc; State->Modes.Arena.PlatformMemory = Context.PlatformMemory;
State->Modes.Arena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly; State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
{ // Animation PLAYGROUND { // Animation PLAYGROUND
State->AnimationSystem = {}; State->AnimationSystem = {};
State->AnimationSystem.Storage = &State->Permanent;
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f; State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
State->AnimationSystem.PlayableRange.Min = 0; State->AnimationSystem.PlayableRange.Min = 0;
State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem); State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
@ -273,21 +278,24 @@ HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_
} }
internal dmx_buffer_list* internal dmx_buffer_list*
CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena) CreateDMXBuffers(assembly Assembly, led_system* LedSystem, s32 BufferHeaderSize, memory_arena* Arena)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex);
dmx_buffer_list* Result = 0; dmx_buffer_list* Result = 0;
dmx_buffer_list* Head = 0; dmx_buffer_list* Head = 0;
s32 BufferSize = BufferHeaderSize + 512; s32 BufferSize = BufferHeaderSize + 512;
for (u32 Range = 0; Range < Assembly.LEDUniverseMapCount; Range++) for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
{ {
leds_in_universe_range LEDUniverseRange = Assembly.LEDUniverseMap[Range]; v2_strip Strip = Assembly.Strips[StripIndex];
dmx_buffer_list* NewBuffer = PushStruct(Arena, dmx_buffer_list); dmx_buffer_list* NewBuffer = PushStruct(Arena, dmx_buffer_list);
NewBuffer->Buffer.Universe = LEDUniverseRange.Universe; NewBuffer->Buffer.Universe = Strip.StartUniverse;
NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize); NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize);
NewBuffer->Buffer.TotalSize = BufferSize; NewBuffer->Buffer.TotalSize = BufferSize;
NewBuffer->Buffer.HeaderSize = BufferHeaderSize; NewBuffer->Buffer.HeaderSize = BufferHeaderSize;
@ -302,13 +310,12 @@ CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena)
Head = NewBuffer; Head = NewBuffer;
u8* DestChannel = Head->Buffer.Base + BufferHeaderSize; u8* DestChannel = Head->Buffer.Base + BufferHeaderSize;
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
LEDIdx < LEDUniverseRange.RangeOnePastLast;
LEDIdx++)
{
led LED = Assembly.LEDBuffer.LEDs[LEDIdx];
pixel Color = Assembly.LEDBuffer.Colors[LED.Index];
for (u32 i = 0; i < Strip.LedCount; i++)
{
u32 LedIndex = Strip.LedLUT[i];
led LED = LedBuffer->Leds[LedIndex];
pixel Color = LedBuffer->Colors[LED.Index];
DestChannel[0] = Color.R; DestChannel[0] = Color.R;
DestChannel[1] = Color.G; DestChannel[1] = Color.G;
@ -366,11 +373,11 @@ UPDATE_AND_RENDER(UpdateAndRender)
CurrentBlocks[Block.Layer] = Block; CurrentBlocks[Block.Layer] = Block;
} }
assembly_led_buffer* LayerLEDBuffers = PushArray(&State->Transient, assembly_led_buffer, CurrentBlocksMax); led_buffer* LayerLEDBuffers = PushArray(&State->Transient, led_buffer, CurrentBlocksMax);
for (u32 AssemblyIndex = 0; AssemblyIndex < State->ActiveAssemblyIndecies.Used; AssemblyIndex++) for (u32 AssemblyIndex = 0; AssemblyIndex < State->Assemblies.Count; AssemblyIndex++)
{ {
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(AssemblyIndex); assembly* Assembly = &State->Assemblies.Values[AssemblyIndex];
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle); led_buffer* AssemblyLedBuffer = LedSystemGetBuffer(&State->LedSystem, Assembly->LedBufferIndex);
arena_snapshot ResetAssemblyMemorySnapshot = TakeSnapshotOfArena(&State->Transient); arena_snapshot ResetAssemblyMemorySnapshot = TakeSnapshotOfArena(&State->Transient);
@ -380,8 +387,8 @@ UPDATE_AND_RENDER(UpdateAndRender)
animation_block Block = CurrentBlocks[Layer]; animation_block Block = CurrentBlocks[Layer];
// Prep Temp Buffer // Prep Temp Buffer
LayerLEDBuffers[Layer] = Assembly->LEDBuffer; LayerLEDBuffers[Layer] = *AssemblyLedBuffer;
LayerLEDBuffers[Layer].Colors = PushArray(&State->Transient, pixel, Assembly->LEDBuffer.LEDCount); LayerLEDBuffers[Layer].Colors = PushArray(&State->Transient, pixel, AssemblyLedBuffer->LedCount);
u32 FramesIntoBlock = CurrentFrame - Block.Range.Min; u32 FramesIntoBlock = CurrentFrame - Block.Range.Min;
r32 SecondsIntoBlock = FramesIntoBlock * State->AnimationSystem.SecondsPerFrame; r32 SecondsIntoBlock = FramesIntoBlock * State->AnimationSystem.SecondsPerFrame;
@ -418,41 +425,41 @@ UPDATE_AND_RENDER(UpdateAndRender)
{ {
case BlendMode_Overwrite: case BlendMode_Overwrite:
{ {
for (u32 LED = 0; LED < Assembly->LEDBuffer.LEDCount; LED++) for (u32 LED = 0; LED < AssemblyLedBuffer->LedCount; LED++)
{ {
Assembly->LEDBuffer.Colors[LED] = LayerLEDBuffers[Layer].Colors[LED]; AssemblyLedBuffer->Colors[LED] = LayerLEDBuffers[Layer].Colors[LED];
} }
}break; }break;
case BlendMode_Add: case BlendMode_Add:
{ {
for (u32 LED = 0; LED < Assembly->LEDBuffer.LEDCount; LED++) for (u32 LED = 0; LED < AssemblyLedBuffer->LedCount; LED++)
{ {
u32 R = (u32)Assembly->LEDBuffer.Colors[LED].R + (u32)LayerLEDBuffers[Layer].Colors[LED].R; u32 R = (u32)AssemblyLedBuffer->Colors[LED].R + (u32)LayerLEDBuffers[Layer].Colors[LED].R;
u32 G = (u32)Assembly->LEDBuffer.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)Assembly->LEDBuffer.Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B; u32 B = (u32)AssemblyLedBuffer->Colors[LED].B + (u32)LayerLEDBuffers[Layer].Colors[LED].B;
Assembly->LEDBuffer.Colors[LED].R = (u8)GSMin(R, (u32)255); AssemblyLedBuffer->Colors[LED].R = (u8)GSMin(R, (u32)255);
Assembly->LEDBuffer.Colors[LED].G = (u8)GSMin(G, (u32)255); AssemblyLedBuffer->Colors[LED].G = (u8)GSMin(G, (u32)255);
Assembly->LEDBuffer.Colors[LED].B = (u8)GSMin(B, (u32)255); AssemblyLedBuffer->Colors[LED].B = (u8)GSMin(B, (u32)255);
} }
}break; }break;
case BlendMode_Multiply: case BlendMode_Multiply:
{ {
for (u32 LED = 0; LED < Assembly->LEDBuffer.LEDCount; LED++) for (u32 LED = 0; LED < AssemblyLedBuffer->LedCount; LED++)
{ {
r32 DR = (r32)Assembly->LEDBuffer.Colors[LED].R / 255.f; r32 DR = (r32)AssemblyLedBuffer->Colors[LED].R / 255.f;
r32 DG = (r32)Assembly->LEDBuffer.Colors[LED].G / 255.f; r32 DG = (r32)AssemblyLedBuffer->Colors[LED].G / 255.f;
r32 DB = (r32)Assembly->LEDBuffer.Colors[LED].B / 255.f; r32 DB = (r32)AssemblyLedBuffer->Colors[LED].B / 255.f;
r32 SR = (r32)LayerLEDBuffers[Layer].Colors[LED].R / 255.f; r32 SR = (r32)LayerLEDBuffers[Layer].Colors[LED].R / 255.f;
r32 SG = (r32)LayerLEDBuffers[Layer].Colors[LED].G / 255.f; r32 SG = (r32)LayerLEDBuffers[Layer].Colors[LED].G / 255.f;
r32 SB = (r32)LayerLEDBuffers[Layer].Colors[LED].B / 255.f; r32 SB = (r32)LayerLEDBuffers[Layer].Colors[LED].B / 255.f;
Assembly->LEDBuffer.Colors[LED].R = (u8)((DR * SR) * 255.f); AssemblyLedBuffer->Colors[LED].R = (u8)((DR * SR) * 255.f);
Assembly->LEDBuffer.Colors[LED].G = (u8)((DG * SG) * 255.f); AssemblyLedBuffer->Colors[LED].G = (u8)((DG * SG) * 255.f);
Assembly->LEDBuffer.Colors[LED].B = (u8)((DB * SB) * 255.f); AssemblyLedBuffer->Colors[LED].B = (u8)((DB * SB) * 255.f);
} }
}break; }break;
} }
@ -464,17 +471,12 @@ UPDATE_AND_RENDER(UpdateAndRender)
s32 HeaderSize = State->NetworkProtocolHeaderSize; s32 HeaderSize = State->NetworkProtocolHeaderSize;
dmx_buffer_list* DMXBuffers = 0; dmx_buffer_list* DMXBuffers = 0;
// TODO(Peter): Come back and re add this in. It was tanking frame rate after for (u32 i = 0; i < State->Assemblies.Count; i++)
// updates to the assembly file format
#if 0
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
{ {
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i); assembly* Assembly = &State->Assemblies.Values[i];
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle); dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, &State->LedSystem, HeaderSize, &State->Transient);
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, HeaderSize, &State->Transient);
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers); DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
} }
#endif
//DEBUG_IF(GlobalDebugServices->Interface.SendSACNData) //DEBUG_IF(GlobalDebugServices->Interface.SendSACNData)
{ {
@ -530,10 +532,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
{ {
DEBUG_TRACK_SCOPE(OverflowChecks); DEBUG_TRACK_SCOPE(OverflowChecks);
AssertAllocationsNoOverflow(State->Permanent); AssertAllocationsNoOverflow(State->Permanent);
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++) for (u32 i = 0; i < State->Assemblies.Count; i++)
{ {
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i); assembly* Assembly = &State->Assemblies.Values[i];
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle);
AssertAllocationsNoOverflow(Assembly->Arena); AssertAllocationsNoOverflow(Assembly->Arena);
} }
} }

View File

@ -49,13 +49,6 @@ enum network_protocol
NetworkProtocol_Count, NetworkProtocol_Count,
}; };
struct led_buffer
{
led* Leds;
pixel* Colors;
led_buffer* Next;
};
struct app_state struct app_state
{ {
rect WindowBounds; rect WindowBounds;
@ -68,9 +61,8 @@ struct app_state
streaming_acn SACN; streaming_acn SACN;
s32 TotalLEDsCount; led_system LedSystem;
gs_list<assembly> AssemblyList; assembly_array Assemblies;
gs_list<gs_list_handle> ActiveAssemblyIndecies;
camera Camera; camera Camera;
r32 PixelsToWorldScale; r32 PixelsToWorldScale;
@ -98,28 +90,28 @@ internal void OpenColorPicker(app_state* State, v4* Address);
// BEGIN TEMPORARY PATTERNS // BEGIN TEMPORARY PATTERNS
internal void internal void
TestPatternOne(assembly_led_buffer* Assembly, r32 Time) TestPatternOne(led_buffer* Assembly, r32 Time)
{ {
for (u32 LEDIdx = 0; LEDIdx < Assembly->LEDCount; LEDIdx++) for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
{ {
led LED = Assembly->LEDs[LEDIdx]; led Led = Assembly->Leds[LedIndex];
if (LED.Position.x < 0) if (Led.Position.x < 0)
{ {
Assembly->Colors[LED.Index].R = 255; Assembly->Colors[Led.Index].R = 255;
Assembly->Colors[LED.Index].B = 255; Assembly->Colors[Led.Index].B = 255;
Assembly->Colors[LED.Index].G = 255; Assembly->Colors[Led.Index].G = 255;
} }
else else
{ {
Assembly->Colors[LED.Index].R = 0; Assembly->Colors[Led.Index].R = 0;
Assembly->Colors[LED.Index].B = 0; Assembly->Colors[Led.Index].B = 0;
Assembly->Colors[LED.Index].G = 0; Assembly->Colors[Led.Index].G = 0;
} }
} }
} }
internal void internal void
TestPatternTwo(assembly_led_buffer* Assembly, r32 Time) TestPatternTwo(led_buffer* Assembly, r32 Time)
{ {
r32 PeriodicTime = (Time / PI) * 2; r32 PeriodicTime = (Time / PI) * 2;
@ -138,11 +130,11 @@ TestPatternTwo(assembly_led_buffer* Assembly, r32 Time)
r32 OuterRadiusSquared = 1000000; r32 OuterRadiusSquared = 1000000;
r32 InnerRadiusSquared = 0; r32 InnerRadiusSquared = 0;
for (u32 LEDIdx = 0; LEDIdx < Assembly->LEDCount; LEDIdx++) for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
{ {
led LED = Assembly->LEDs[LEDIdx]; led Led = Assembly->Leds[LedIndex];
v4 Position = LED.Position; v4 Position = Led.Position;
v4 ToFront = Position + FrontCenter; v4 ToFront = Position + FrontCenter;
v4 ToBack = Position + BackCenter; v4 ToBack = Position + BackCenter;
@ -158,22 +150,22 @@ TestPatternTwo(assembly_led_buffer* Assembly, r32 Time)
{ {
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0)) if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
{ {
Assembly->Colors[LED.Index] = Color; Assembly->Colors[Led.Index] = Color;
} }
else else
{ {
//Assembly->Colors[LED.Index] = {}; //Assembly->Colors[Led.Index] = {};
} }
} }
else else
{ {
//Assembly->Colors[LED.Index] = {}; //Assembly->Colors[Led.Index] = {};
} }
} }
} }
internal void internal void
TestPatternThree(assembly_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 = GSAbs(GSSin(Time)) * 200;
@ -184,25 +176,25 @@ TestPatternThree(assembly_led_buffer* Assembly, r32 Time)
r32 FadeDist = 35; r32 FadeDist = 35;
for (u32 LEDIdx = 0; LEDIdx < Assembly->LEDCount; LEDIdx++) for (u32 LedIndex = 0; LedIndex < Assembly->LedCount; LedIndex++)
{ {
led LED = Assembly->LEDs[LEDIdx]; led Led = Assembly->Leds[LedIndex];
u8 Red = 0; u8 Red = 0;
u8 Green = 0; u8 Green = 0;
u8 Blue = 0; u8 Blue = 0;
r32 GreenDist = GSAbs(Mag(LED.Position - GreenCenter) - GreenRadius); r32 GreenDist = GSAbs(Mag(Led.Position - GreenCenter) - GreenRadius);
r32 GreenBrightness = GSClamp(0.f, FadeDist - GSAbs(GreenDist), FadeDist); r32 GreenBrightness = GSClamp(0.f, FadeDist - GSAbs(GreenDist), FadeDist);
Green = (u8)(GreenBrightness * 255); Green = (u8)(GreenBrightness * 255);
r32 TealDist = GSAbs(Mag(LED.Position - TealCenter) - TealRadius); r32 TealDist = GSAbs(Mag(Led.Position - TealCenter) - TealRadius);
r32 TealBrightness = GSClamp(0.f, FadeDist - GSAbs(TealDist), FadeDist); r32 TealBrightness = GSClamp(0.f, FadeDist - GSAbs(TealDist), FadeDist);
Red = (u8)(TealBrightness * 255); Red = (u8)(TealBrightness * 255);
Blue = (u8)(TealBrightness * 255); Blue = (u8)(TealBrightness * 255);
Assembly->Colors[LED.Index].R = Red; Assembly->Colors[Led.Index].R = Red;
Assembly->Colors[LED.Index].B = Green; Assembly->Colors[Led.Index].B = Green;
Assembly->Colors[LED.Index].G = Green; Assembly->Colors[Led.Index].G = Green;
} }
} }

View File

@ -5,38 +5,106 @@
// //
#ifndef FOLDHAUS_ASSEMBLY_CPP #ifndef FOLDHAUS_ASSEMBLY_CPP
internal void // Led System
ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 RootPosition)
{
Assembly->LEDBuffer.LEDCount = 0;
Assembly->LEDBuffer.Colors = PushArray(&Assembly->Arena, pixel, Assembly->LedCountTotal);
Assembly->LEDBuffer.LEDs = PushArray(&Assembly->Arena, led, Assembly->LedCountTotal);
Assembly->LEDUniverseMapCount = Assembly->LedCountTotal;
Assembly->LEDUniverseMap = PushArray(&Assembly->Arena, leds_in_universe_range, Assembly->LedCountTotal);
// Add LEDs internal led_system
LedSystemInitialize(platform_memory_handler PlatformMemory, u32 BuffersMax)
{
led_system Result = {};
Result.PlatformMemory = PlatformMemory;
// TODO(Peter): Since we have access to PlatformMemory, just realloc Buffers when we fill it up
Result.BuffersCountMax = BuffersMax;
Result.Buffers = PlatformAllocArray(PlatformMemory, led_buffer, Result.BuffersCountMax);
return Result;
}
internal u32
LedSystemTakeFreeBuffer(led_system* System, u32 LedCount)
{
s32 Result = -1;
if (System->BuffersCount < System->BuffersCountMax)
{
Result = System->BuffersCount++;
}
else
{
// NOTE(Peter): Look for a buffer that's flagged as empty
for (u32 i = 0; i < System->BuffersCount; i++)
{
if (System->Buffers[i].LedCount == 0
&& System->Buffers[i].Colors == 0
&& System->Buffers[i].Leds == 0)
{
Result = i;
break;
}
}
Assert(Result >= 0); // NOTE(Peter): We ran out of room for led buffers
}
led_buffer* Buffer = &System->Buffers[Result];
Buffer->LedCount = LedCount;
Buffer->Colors = PlatformAllocArray(System->PlatformMemory, pixel, Buffer->LedCount);
Buffer->Leds = PlatformAllocArray(System->PlatformMemory, led, Buffer->LedCount);
System->LedsCountTotal += LedCount;
return (u32)Result;
}
internal void
LedSystemFreeBuffer(led_system* System, u32 BufferIndex)
{
Assert(BufferIndex < System->BuffersCountMax);
led_buffer* Buffer = &System->Buffers[BufferIndex];
PlatformFreeArray(System->PlatformMemory, Buffer->Colors, pixel, Buffer->LedCount);
PlatformFreeArray(System->PlatformMemory, Buffer->Leds, led, Buffer->LedCount);
System->LedsCountTotal -= Buffer->LedCount;
*Buffer = {};
}
internal led_buffer*
LedSystemGetBuffer(led_system* System, u32 Index)
{
led_buffer* Result = &System->Buffers[Index];
return Result;
}
internal void
LedBufferSetLed(led_buffer* Buffer, u32 Led, v4 Position)
{
Assert(Led < Buffer->LedCount);
Buffer->Leds[Led].Position = Position;
Buffer->Leds[Led].Index = Led;
}
// Assembly
internal void
ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 RootPosition, led_system* LedSystem)
{
Assembly->LedBufferIndex = LedSystemTakeFreeBuffer(LedSystem, Assembly->LedCountTotal);
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex);
// Add Leds
u32 LedsAdded = 0;
for (u32 StripIdx = 0; StripIdx < Assembly->StripCount; StripIdx++) for (u32 StripIdx = 0; StripIdx < Assembly->StripCount; StripIdx++)
{ {
//led_strip_definition StripDef = Definition.LEDStrips[StripIdx]; //led_strip_definition StripDef = Definition.LedStrips[StripIdx];
v2_strip* StripAt = &Assembly->Strips[StripIdx]; v2_strip* StripAt = &Assembly->Strips[StripIdx];
StripAt->LedLUT = PushArray(&Assembly->Arena, u32, StripAt->LedCount);
leds_in_universe_range* LEDUniverseRange = &Assembly->LEDUniverseMap[StripIdx];
LEDUniverseRange->Universe = StripAt->StartUniverse;
LEDUniverseRange->RangeStart = Assembly->LEDBuffer.LEDCount;
LEDUniverseRange->RangeOnePastLast = Assembly->LEDBuffer.LEDCount + StripAt->LedCount;
v4 WS_StripStart = RootPosition + V4(StripAt->StartPosition * Assembly->Scale, 1); v4 WS_StripStart = RootPosition + V4(StripAt->StartPosition * Assembly->Scale, 1);
v4 WS_StripEnd = RootPosition + V4(StripAt->EndPosition * Assembly->Scale, 1); v4 WS_StripEnd = RootPosition + V4(StripAt->EndPosition * Assembly->Scale, 1);
s32 LEDsInStripCount = StripAt->LedCount;
v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)LEDsInStripCount; v4 SingleStep = (WS_StripEnd - WS_StripStart) / (r32)StripAt->LedCount;
for (s32 Step = 0; Step < LEDsInStripCount; Step++) for (u32 Step = 0; Step < StripAt->LedCount; Step++)
{ {
s32 LEDIndex = Assembly->LEDBuffer.LEDCount; s32 LedIndex = LedsAdded++;
Assembly->LEDBuffer.LEDs[LEDIndex].Position = WS_StripStart + (SingleStep * Step); v4 LedPosition = WS_StripStart + (SingleStep * Step);
Assembly->LEDBuffer.LEDs[LEDIndex].Index = LEDIndex; LedBufferSetLed(LedBuffer, LedIndex, LedPosition);
Assembly->LEDBuffer.LEDCount += 1; StripAt->LedLUT[Step] = LedIndex;
} }
} }
} }
@ -47,30 +115,33 @@ ConstructAssemblyFromDefinition (assembly* Assembly, string AssemblyName, v4 Roo
static v4 TempAssemblyOffsets[] = { v4{0, 0, 0, 0}, v4{250, 0, 75, 0}, v4{-250, 0, 75, 0} }; static v4 TempAssemblyOffsets[] = { v4{0, 0, 0, 0}, v4{250, 0, 75, 0}, v4{-250, 0, 75, 0} };
s32 TempAssemblyOffsetsCount = 3; s32 TempAssemblyOffsetsCount = 3;
// TODO(Peter): Don't reference State, pull back to the Led buffer and Assembly Array
internal void internal void
LoadAssembly (app_state* State, context Context, string Path) LoadAssembly (app_state* State, context Context, string Path)
{ {
platform_memory_result AssemblyFile = ReadEntireFile(Context, Path); platform_memory_result AssemblyFile = ReadEntireFile(Context, Path);
if (AssemblyFile.Error == PlatformMemory_NoError) if (AssemblyFile.Error == PlatformMemory_NoError && AssemblyFile.Size > 0)
{ {
string AssemblyFileText = MakeString((char*)AssemblyFile.Base); string AssemblyFileText = MakeString((char*)AssemblyFile.Base);
Assert(State->Assemblies.Count < State->Assemblies.CountMax);
assembly* NewAssembly = &State->Assemblies.Values[State->Assemblies.Count++];
s32 IndexOfLastSlash = FastLastIndexOfCharInCharArray(Path.Memory, Path.Length, '\\'); s32 IndexOfLastSlash = FastLastIndexOfCharInCharArray(Path.Memory, Path.Length, '\\');
string FileName = Substring(Path, IndexOfLastSlash + 1); string FileName = Substring(Path, IndexOfLastSlash + 1);
assembly NewAssembly = {}; NewAssembly->Arena.PlatformMemory = Context.PlatformMemory;
NewAssembly.Arena.Alloc = (gs_memory_alloc*)Context.PlatformAlloc; if (ParseAssemblyFile(NewAssembly, AssemblyFileText, &State->Transient))
NewAssembly.Arena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc; {
ParseAssemblyFile(&NewAssembly, AssemblyFileText, &State->Transient); v4 Offset = TempAssemblyOffsets[State->Assemblies.Count % TempAssemblyOffsetsCount];
ConstructAssemblyFromDefinition(NewAssembly, FileName, Offset, &State->LedSystem);
v4 Offset = TempAssemblyOffsets[State->ActiveAssemblyIndecies.Used % TempAssemblyOffsetsCount]; PlatformFree(Context.PlatformMemory, AssemblyFile.Base, AssemblyFile.Size);
ConstructAssemblyFromDefinition(&NewAssembly, FileName, Offset); }
gs_list_handle NewAssemblyHandle = State->AssemblyList.PushElementOnList(NewAssembly); else
{
State->ActiveAssemblyIndecies.PushElementOnList(NewAssemblyHandle); FreeMemoryArena(&NewAssembly->Arena);
State->TotalLEDsCount += NewAssembly.LEDBuffer.LEDCount; State->Assemblies.Count -= 1;
}
Context.PlatformFree(AssemblyFile.Base, AssemblyFile.Size);
} }
else else
{ {
@ -81,20 +152,12 @@ LoadAssembly (app_state* State, context Context, string Path)
internal void internal void
UnloadAssembly (u32 AssemblyIndex, app_state* State, context Context) UnloadAssembly (u32 AssemblyIndex, app_state* State, context Context)
{ {
assembly* Assembly = State->AssemblyList.GetElementAtIndex(AssemblyIndex); Assert(AssemblyIndex < State->Assemblies.Count);
State->TotalLEDsCount -= Assembly->LEDBuffer.LEDCount; assembly* Assembly = &State->Assemblies.Values[AssemblyIndex];
FreeMemoryArena(&Assembly->Arena, (gs_memory_free*)Context.PlatformFree); LedSystemFreeBuffer(&State->LedSystem, Assembly->LedBufferIndex);
FreeMemoryArena(&Assembly->Arena);
State->AssemblyList.FreeElementAtIndex(AssemblyIndex); u32 LastAssemblyIndex = --State->Assemblies.Count;
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++) State->Assemblies.Values[AssemblyIndex] = State->Assemblies.Values[LastAssemblyIndex];
{
gs_list_handle Handle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i);
if (Handle.Index == AssemblyIndex)
{
State->ActiveAssemblyIndecies.FreeElementAtIndex(i);
break;
}
}
} }

View File

@ -7,6 +7,7 @@
struct led struct led
{ {
// TODO(Peter): Pretty sure we don't need this. led and pixel are always parallel arrays
s32 Index; s32 Index;
v4 Position; v4 Position;
}; };
@ -22,22 +23,22 @@ union pixel
u8 Channels[3]; u8 Channels[3];
}; };
// NOTE(Peter): This structure is so we can keep track of struct led_buffer
// what LEDs output to which DMX universe. You don't need
// to use it anywhere else, as all the data for patterns,
// colors, and groups is/will be stored elsewhere.
struct leds_in_universe_range
{ {
s32 RangeStart; u32 LedCount;
s32 RangeOnePastLast; pixel* Colors;
s32 Universe; led* Leds;
}; };
struct assembly_led_buffer struct led_system
{ {
u32 LEDCount; platform_memory_handler PlatformMemory;
pixel* Colors;
led* LEDs; u32 BuffersCountMax;
u32 BuffersCount;
led_buffer* Buffers;
u32 LedsCountTotal;
}; };
struct v2_tag struct v2_tag
@ -49,6 +50,7 @@ struct v2_tag
struct v2_strip struct v2_strip
{ {
s32 ControlBoxID; // TODO(Peter): I don't think we need this anymore s32 ControlBoxID; // TODO(Peter): I don't think we need this anymore
// TODO(Peter): Add in info for Serial, ArtNet, etc.
s32 StartUniverse; s32 StartUniverse;
s32 StartChannel; s32 StartChannel;
@ -72,17 +74,19 @@ struct assembly
string FilePath; string FilePath;
r32 Scale; r32 Scale;
s32 LedCountTotal;
u32 LedBufferIndex;
u32 StripCount; u32 StripCount;
v2_strip* Strips; v2_strip* Strips;
s32 LedCountTotal;
assembly_led_buffer LEDBuffer;
u32 LEDUniverseMapCount;
leds_in_universe_range* LEDUniverseMap;
}; };
struct assembly_array
{
u32 CountMax;
u32 Count;
assembly* Values;
};
#define FOLDHAUS_ASSEMBLY_H #define FOLDHAUS_ASSEMBLY_H
#endif // FOLDHAUS_ASSEMBLY_H #endif // FOLDHAUS_ASSEMBLY_H

View File

@ -88,15 +88,6 @@ struct system_path
s32 IndexOfLastSlash; s32 IndexOfLastSlash;
}; };
#define PLATFORM_ALLOC(name) u8* name(s32 Size)
typedef PLATFORM_ALLOC(platform_alloc);
#define PLATFORM_FREE(name) b32 name(u8* Base, s32 Size)
typedef PLATFORM_FREE(platform_free);
#define PLATFORM_REALLOC(name) u8* name(u8* Base, u32 OldSize, u32 NewSize)
typedef PLATFORM_REALLOC(platform_realloc);
#define PLATFORM_READ_ENTIRE_FILE(name) platform_memory_result name(string Path) #define PLATFORM_READ_ENTIRE_FILE(name) platform_memory_result name(string Path)
typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file); typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file);
@ -264,10 +255,7 @@ struct context
// Platform Services // Platform Services
work_queue* GeneralWorkQueue; work_queue* GeneralWorkQueue;
platform_alloc* PlatformAlloc; platform_memory_handler PlatformMemory;
platform_free* PlatformFree;
platform_realloc* PlatformRealloc;
platform_file_handler FileHandler; platform_file_handler FileHandler;
platform_write_entire_file* PlatformWriteEntireFile; platform_write_entire_file* PlatformWriteEntireFile;

View File

@ -37,14 +37,14 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
u32 LineCount = (u32)(gs_Height(PanelBounds) / Layout.RowHeight) + 1; u32 LineCount = (u32)(gs_Height(PanelBounds) / Layout.RowHeight) + 1;
u32 LinesDrawn = 0; u32 LinesDrawn = 0;
u32 AssembliesToDraw = GSMin(LineCount, State->ActiveAssemblyIndecies.Used); u32 AssembliesToDraw = GSMin(LineCount, State->Assemblies.Count);
for (; LinesDrawn < AssembliesToDraw; LinesDrawn++) for (u32 AssemblyIndex = 0; AssemblyIndex < AssembliesToDraw; AssemblyIndex++)
{ {
rect Bounds = ui_ReserveElementBounds(&Layout); rect Bounds = ui_ReserveElementBounds(&Layout);
v4 ListItemBGColor = ui_GetListItemBGColor(State->Interface_.Style, LinesDrawn); v4 ListItemBGColor = ui_GetListItemBGColor(State->Interface_.Style, AssemblyIndex);
ui_FillRect(&State->Interface_, Bounds, ListItemBGColor); ui_FillRect(&State->Interface_, Bounds, ListItemBGColor);
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(LinesDrawn);
assembly Assembly = *State->AssemblyList.GetElementWithHandle(AssemblyHandle); assembly Assembly = State->Assemblies.Values[AssemblyIndex];
PrintF(&TempString, "%S", Assembly.Name); PrintF(&TempString, "%S", Assembly.Name);
ui_layout ItemLayout = ui_CreateLayout(State->Interface_, Bounds); ui_layout ItemLayout = ui_CreateLayout(State->Interface_, Bounds);
@ -53,10 +53,12 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
ui_LayoutDrawString(&State->Interface_, &ItemLayout, TempString, State->Interface_.Style.TextColor); ui_LayoutDrawString(&State->Interface_, &ItemLayout, TempString, State->Interface_.Style.TextColor);
if (ui_LayoutButton(&State->Interface_, &ItemLayout, MakeStringLiteral("X"), ListItemBGColor, ListItemHover, ListItemSelected)) if (ui_LayoutButton(&State->Interface_, &ItemLayout, MakeStringLiteral("X"), ListItemBGColor, ListItemHover, ListItemSelected))
{ {
UnloadAssembly(AssemblyHandle.Index, State, Context); UnloadAssembly(AssemblyIndex, State, Context);
} }
} }
ui_EndRow(&ItemLayout); ui_EndRow(&ItemLayout);
LinesDrawn += 1;
} }
if (LinesDrawn < LineCount) if (LinesDrawn < LineCount)

View File

@ -154,21 +154,21 @@ SculptureView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
FaceCameraMatrix = FaceCameraMatrix; FaceCameraMatrix = FaceCameraMatrix;
u32 MaxLEDsPerJob = 2048; u32 MaxLEDsPerJob = 2048;
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->TotalLEDsCount); render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->LedSystem.LedsCountTotal);
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++) for (u32 i = 0; i < State->Assemblies.Count; i++)
{ {
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i); assembly Assembly = State->Assemblies.Values[i];
assembly Assembly = *State->AssemblyList.GetElementWithHandle(AssemblyHandle); led_buffer* LedBuffer = LedSystemGetBuffer(&State->LedSystem, Assembly.LedBufferIndex);
u32 JobsNeeded = IntegerDivideRoundUp(Assembly.LEDBuffer.LEDCount, MaxLEDsPerJob); u32 JobsNeeded = IntegerDivideRoundUp(LedBuffer->LedCount, MaxLEDsPerJob);
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); draw_leds_job_data* JobData = PushStruct(&State->Transient, draw_leds_job_data);
JobData->LEDs = Assembly.LEDBuffer.LEDs; JobData->LEDs = LedBuffer->Leds;
JobData->Colors = Assembly.LEDBuffer.Colors; JobData->Colors = LedBuffer->Colors;
JobData->StartIndex = Job * MaxLEDsPerJob; JobData->StartIndex = Job * MaxLEDsPerJob;
JobData->OnePastLastIndex = GSMin(JobData->StartIndex + MaxLEDsPerJob, Assembly.LEDBuffer.LEDCount); JobData->OnePastLastIndex = GSMin(JobData->StartIndex + MaxLEDsPerJob, LedBuffer->LedCount);
JobData->Batch = &RenderLEDsBatch; JobData->Batch = &RenderLEDsBatch;
JobData->FaceCameraMatrix; JobData->FaceCameraMatrix;
JobData->ModelViewMatrix = ModelViewMatrix; JobData->ModelViewMatrix = ModelViewMatrix;

View File

@ -663,9 +663,9 @@ WinMain (
// Platform functions // Platform functions
Context.GeneralWorkQueue = &WorkQueue; Context.GeneralWorkQueue = &WorkQueue;
Context.PlatformAlloc = Win32Alloc; Context.PlatformMemory.Alloc = Win32Alloc;
Context.PlatformFree = Win32Free; Context.PlatformMemory.Free = Win32Free;
Context.PlatformRealloc = Win32Realloc; Context.PlatformMemory.Realloc = Win32Realloc;
Context.FileHandler.ReadEntireFile = Win32ReadEntireFile; Context.FileHandler.ReadEntireFile = Win32ReadEntireFile;
Context.FileHandler.WriteEntireFile = Win32WriteEntireFile; Context.FileHandler.WriteEntireFile = Win32WriteEntireFile;
Context.FileHandler.GetFilePath = Win32SystemDialogueOpenFile; Context.FileHandler.GetFilePath = Win32SystemDialogueOpenFile;

View File

@ -133,6 +133,8 @@ PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile)
Result = GetOpenFileNameA (&OpenFileName); Result = GetOpenFileNameA (&OpenFileName);
PathBuffer->Length = CharArrayLength(PathBuffer->Memory);
return Result; return Result;
} }

View File

@ -192,9 +192,21 @@ enum gs_memory_find_address_rule
FindAddress_Count, FindAddress_Count,
}; };
typedef void* gs_memory_alloc(gs_mem_u32 Size); #define PLATFORM_ALLOC(name) u8* name(s32 Size)
typedef void* gs_memory_realloc(void* Address, gs_mem_u32 OldSize, gs_mem_u32 NewSize); typedef PLATFORM_ALLOC(platform_alloc);
typedef void gs_memory_free(void* Address, gs_mem_u32 Size);
#define PLATFORM_FREE(name) b32 name(u8* Base, s32 Size)
typedef PLATFORM_FREE(platform_free);
#define PLATFORM_REALLOC(name) u8* name(u8* Base, u32 OldSize, u32 NewSize)
typedef PLATFORM_REALLOC(platform_realloc);
struct platform_memory_handler
{
platform_alloc* Alloc;
platform_free* Free;
platform_realloc* Realloc;
};
#ifndef GS_MEMORY_BUFFER_SIZE #ifndef GS_MEMORY_BUFFER_SIZE
#define GS_MEMORY_BUFFER_SIZE 1024 #define GS_MEMORY_BUFFER_SIZE 1024
@ -237,8 +249,8 @@ struct memory_arena
gs_memory_find_address_rule FindAddressRule; gs_memory_find_address_rule FindAddressRule;
gs_memory_expansion_rule ExpansionRule; gs_memory_expansion_rule ExpansionRule;
gs_memory_alloc* Alloc;
gs_memory_realloc* Realloc; platform_memory_handler PlatformMemory;
#ifdef GS_MEMORY_TRACK_ALLOCATIONS #ifdef GS_MEMORY_TRACK_ALLOCATIONS
tracked_allocation_buffer** AllocationBuffers; tracked_allocation_buffer** AllocationBuffers;
@ -266,31 +278,62 @@ struct arena_snapshot
#endif #endif
}; };
#define PlatformFreeArray(platform, base, type, count) PlatformFree((platform), (gs_mem_u8*)(base), sizeof(type) * (count))
#define ArenaFree(arena, base, size) PlatformFree((arena).PlatformMemory, (gs_mem_u8*)(base), (gs_mem_u32)(size))
static void static void
FreeMemoryArena(memory_arena* Arena, gs_memory_free* Free = 0) PlatformFree(platform_memory_handler Platform, gs_mem_u8* Base, gs_mem_u32 Size)
{ {
if (Free) Assert(Platform.Free != 0);
Platform.Free(Base, Size);
}
#define PlatformAllocArray(platform, type, size) (type*)PlatformAlloc((platform), sizeof(type) * (size))
#define ArenaAlloc(arena, size) PlatformAlloc((arena).PlatformMemory, (gs_mem_u32)(size))
#define ArenaAllocStruct(arena, type) (type*)PlatformAlloc((arena).PlatformMemory, sizeof(type))
#define ArenaAllocArray(arena, type, size) (type*)PlatformAlloc((arena).PlatformMemory, sizeof(type) * (size))
static gs_mem_u8*
PlatformAlloc(platform_memory_handler Platform, gs_mem_u32 Size)
{
Assert(Platform.Alloc != 0);
gs_mem_u8* Result = Platform.Alloc(Size);
return Result;
}
#define ArenaRealloc(arena, base, oldSize, newSize) PlatformRealloc((arena).PlatformMemory, (gs_mem_u8*)(base), (gs_mem_u32)(oldSize), (gs_mem_u32)(newSize))
#define ArenaReallocArray(arena, base, type, oldCount, newCount) (type*)PlatformRealloc((arena).PlatformMemory, (gs_mem_u8*)(base), sizeof(type) * oldCount, sizeof(type) * newCount)
static gs_mem_u8*
PlatformRealloc(platform_memory_handler Platform, gs_mem_u8* Head, gs_mem_u32 OldSize, gs_mem_u32 NewSize)
{
gs_mem_u8* Result = 0;
if (Platform.Realloc != 0)
{ {
for (gs_mem_u32 i = 0; i < Arena->BuffersCount; i++) Result = Platform.Realloc(Head, OldSize, NewSize);
{ }
memory_buffer* Buffer = Arena->Buffers + i; else if (Platform.Alloc != 0 && Platform.Free != 0)
Free(Buffer->Buffer, Buffer->Size); {
Result = PlatformAlloc(Platform, NewSize);
if (Head != 0 && OldSize != 0)
{
GSMemCopy(Head, Result, OldSize);
PlatformFree(Platform, Head, OldSize);
} }
Free(Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount);
} }
else else
{ {
#ifdef GS_MEMORY_NO_STD_LIBS InvalidCodePath;
GSMem_Assert(0); }
#else return Result;
}
static void
FreeMemoryArena(memory_arena* Arena)
{
for (gs_mem_u32 i = 0; i < Arena->BuffersCount; i++) for (gs_mem_u32 i = 0; i < Arena->BuffersCount; i++)
{ {
memory_buffer* Buffer = Arena->Buffers + i; memory_buffer* Buffer = Arena->Buffers + i;
free(Buffer->Buffer); PlatformFree(Arena->PlatformMemory, Buffer->Buffer, Buffer->Size);
}
free(Arena->Buffers);
#endif
} }
PlatformFree(Arena->PlatformMemory, (u8*)Arena->Buffers, sizeof(memory_buffer) * Arena->BuffersCount);
} }
#define IsPowerOfTwo(v) ((v != 0) && ((v & (v - 1)) == 0)) #define IsPowerOfTwo(v) ((v != 0) && ((v & (v - 1)) == 0))
@ -344,65 +387,17 @@ FindAlignedAddressInBufferWithRoom(memory_arena* Arena, gs_mem_u32 Size, gs_mem_
return Result; return Result;
} }
static gs_mem_u8*
ArenaAlloc(memory_arena* Arena, gs_mem_u32 Size)
{
gs_mem_u8* Result = 0;
if (Arena->Alloc)
{
Result = (gs_mem_u8*)Arena->Alloc(sizeof(gs_mem_u8) * Size);
}
else
{
#ifdef GS_MEMORY_NO_STD_LIBS
// NOTE(Peter): If you specify no std libs AND don't supply a allocation function
// we should assert as this is an invalid codepath
GSMem_Assert(0);
#else
Result = (gs_mem_u8*)malloc(sizeof(gs_mem_u8) * Size);
#endif
}
return Result;
}
static gs_mem_u8*
ArenaRealloc(memory_arena* Arena, gs_mem_u8* Head, gs_mem_u32 OldSize, gs_mem_u32 NewSize)
{
gs_mem_u8* Result = 0;
if (Arena->Realloc != 0)
{
Result = (gs_mem_u8*)Arena->Realloc(Head, OldSize, NewSize);
}
else
{
#ifdef GS_MEMORY_NO_STD_LIBS
// NOTE(Peter): If you specify no std libs AND don't supply a reallocation function
// we should assert as this is an invalid codepath
GSMem_Assert(0);
#else
Result = (gs_mem_u8*)realloc(Head, NewSize);
#endif
}
return Result;
}
static memory_buffer* static memory_buffer*
GrowArena(memory_arena* Arena, gs_mem_u32 SizeNeeded) GrowArena(memory_arena* Arena, gs_mem_u32 SizeNeeded)
{ {
GSMem_Assert(Arena->ExpansionRule != MemoryExpansion_Disallowed); GSMem_Assert(Arena->ExpansionRule != MemoryExpansion_Disallowed);
if (Arena->ExpansionRule == MemoryExpansion_OnlyIfFunctionsProvided)
{
GSMem_Assert((Arena->Alloc != 0) && (Arena->Realloc != 0));
}
gs_mem_u32 NewBuffersCount = (Arena->BuffersCount + 1); gs_mem_u32 NewBuffersCount = (Arena->BuffersCount + 1);
#if 0
gs_mem_u32 OldBuffersSize = sizeof(memory_buffer) * Arena->BuffersCount; gs_mem_u32 OldBuffersSize = sizeof(memory_buffer) * Arena->BuffersCount;
gs_mem_u32 NewBuffersSize = sizeof(memory_buffer) * NewBuffersCount; gs_mem_u32 NewBuffersSize = sizeof(memory_buffer) * NewBuffersCount;
Arena->Buffers = (memory_buffer*)ArenaRealloc(Arena, (gs_mem_u8*)Arena->Buffers, OldBuffersSize, NewBuffersSize); #endif
Arena->Buffers = ArenaReallocArray(*Arena, Arena->Buffers, memory_buffer, Arena->BuffersCount, NewBuffersCount);
Arena->BuffersCount = NewBuffersCount; Arena->BuffersCount = NewBuffersCount;
memory_buffer* NewBuffer = Arena->Buffers + (Arena->BuffersCount - 1); memory_buffer* NewBuffer = Arena->Buffers + (Arena->BuffersCount - 1);
@ -412,7 +407,7 @@ GrowArena(memory_arena* Arena, gs_mem_u32 SizeNeeded)
NewBuffer->Size = SizeNeeded; NewBuffer->Size = SizeNeeded;
} }
NewBuffer->Buffer = ArenaAlloc(Arena, sizeof(gs_mem_u8) * NewBuffer->Size); NewBuffer->Buffer = ArenaAllocArray(*Arena, gs_mem_u8, NewBuffer->Size);
NewBuffer->Used = 0; NewBuffer->Used = 0;
Arena->TotalSize += NewBuffer->Size; Arena->TotalSize += NewBuffer->Size;
@ -433,14 +428,20 @@ TrackAllocation(memory_arena* Arena, gs_mem_u8* Head, gs_mem_u32 Size, char* Fil
if (Arena->AllocationsUsed >= AllocationsMax) if (Arena->AllocationsUsed >= AllocationsMax)
{ {
gs_mem_u32 NewAllocationBuffersCount = Arena->AllocationBuffersCount + 1; gs_mem_u32 NewAllocationBuffersCount = Arena->AllocationBuffersCount + 1;
Arena->AllocationBuffers = (tracked_allocation_buffer**)ArenaRealloc(Arena, #if 0
gs_mem_u32 OldSize = Arena->AllocationBuffersCount * sizeof(void*);
gs_mem_u32 NewSize = NewAllocationBuffersCount * sizeof(void*);
Arena->AllocationBuffers = (tracked_allocation_buffer**)PlatformRealloc(Arena->PlatformMemory,
(gs_mem_u8*)Arena->AllocationBuffers, (gs_mem_u8*)Arena->AllocationBuffers,
Arena->AllocationBuffersCount * sizeof(void*), OldSize, NewSize);
NewAllocationBuffersCount * sizeof(void*)); #else
Arena->AllocationBuffers = ArenaReallocArray(*Arena, Arena->AllocationBuffers, tracked_allocation_buffer*, Arena->AllocationBuffersCount, NewAllocationBuffersCount);
#endif
Arena->AllocationBuffersCount = NewAllocationBuffersCount; Arena->AllocationBuffersCount = NewAllocationBuffersCount;
gs_mem_u32 NewBufferIndex = Arena->AllocationBuffersCount - 1; gs_mem_u32 NewBufferIndex = Arena->AllocationBuffersCount - 1;
Arena->AllocationBuffers[NewBufferIndex] = (tracked_allocation_buffer*)ArenaAlloc(Arena, sizeof(tracked_allocation_buffer)); Arena->AllocationBuffers[NewBufferIndex] = ArenaAllocStruct(*Arena, tracked_allocation_buffer);
} }
gs_mem_u32 AllocationIndex = Arena->AllocationsUsed++; gs_mem_u32 AllocationIndex = Arena->AllocationsUsed++;