Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
2fa1a9b178
|
@ -25,12 +25,12 @@ SET LastError=%ERRORLEVEL%
|
||||||
|
|
||||||
del lock.tmp
|
del lock.tmp
|
||||||
|
|
||||||
cl %CommonCompilerFlags% %SourceCodePath%\platform_win32\win32_foldhaus.cpp /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib opengl32.lib dsound.lib Ws2_32.lib Comdlg32.lib
|
cl %CommonCompilerFlags% %SourceCodePath%\platform_win32\win32_foldhaus.cpp /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib opengl32.lib dsound.lib Ws2_32.lib Comdlg32.lib Winspool.lib
|
||||||
|
|
||||||
|
|
||||||
REM COMPILE UTILITY EXES
|
REM COMPILE UTILITY EXES
|
||||||
|
|
||||||
cl %CommonCompilerFlags% %ProjectDevPath%\src\serial_monitor\first.cpp /Feserial_monitor.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib
|
cl %CommonCompilerFlags% %ProjectDevPath%\src\serial_monitor\first.cpp /Feserial_monitor.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib Winspool.lib
|
||||||
|
|
||||||
cl %CommonCompilerFlags% %ProjectDevPath%\src\sculpture_gen\gen_blumen_lumen.cpp /Fegen_blumen_lumen.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib
|
cl %CommonCompilerFlags% %ProjectDevPath%\src\sculpture_gen\gen_blumen_lumen.cpp /Fegen_blumen_lumen.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib
|
||||||
|
|
||||||
|
|
|
@ -752,6 +752,17 @@ ui_PushOverlayLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gs_string
|
||||||
|
ui_PushLayoutCategoryName(ui_interface* Interface, gs_string Category, u32 Value)
|
||||||
|
{
|
||||||
|
gs_string Result = PushStringF(Interface->PerFrameMemory,
|
||||||
|
Category.Length + 25,
|
||||||
|
"%S%d",
|
||||||
|
Category.ConstString,
|
||||||
|
Value);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static ui_widget*
|
static ui_widget*
|
||||||
ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name)
|
ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name)
|
||||||
{
|
{
|
||||||
|
@ -770,6 +781,12 @@ ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir
|
||||||
Interface->ActiveLayout = Result;
|
Interface->ActiveLayout = Result;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
static ui_widget*
|
||||||
|
ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Category, u32 Value)
|
||||||
|
{
|
||||||
|
gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Value);
|
||||||
|
return ui_PushLayout(Interface, Bounds, FillDir, Name);
|
||||||
|
}
|
||||||
|
|
||||||
static ui_widget*
|
static ui_widget*
|
||||||
ui_PushLayout(ui_interface* Interface, gs_string Name, bool Inset = true)
|
ui_PushLayout(ui_interface* Interface, gs_string Name, bool Inset = true)
|
||||||
|
@ -837,7 +854,16 @@ ui_PopLayout(ui_interface* Interface, gs_string LayoutName)
|
||||||
// NOTE(pjs): If this isn't true then a layout was opened without being closed
|
// NOTE(pjs): If this isn't true then a layout was opened without being closed
|
||||||
// Go check for ui_PushLayout, ui_BeginDropdown, ui_BeginRow, etc that don't have
|
// Go check for ui_PushLayout, ui_BeginDropdown, ui_BeginRow, etc that don't have
|
||||||
// a corresponding ui_Pop/ui_End*
|
// a corresponding ui_Pop/ui_End*
|
||||||
Assert(StringsEqual(Layout->String, LayoutName));
|
//
|
||||||
|
// We use StringsEqualUpToLength here becuase its possible that
|
||||||
|
// the current layout used the Category + Identifier method
|
||||||
|
// for generating Layout->String. And if Identifier was a string
|
||||||
|
// that was edited within the scope of this layout, then
|
||||||
|
// Layout->String and LayoutName will no longer match.
|
||||||
|
//
|
||||||
|
// This is a compromise that will at least let us know if
|
||||||
|
// we aren't popping all our layouts correctly.
|
||||||
|
Assert(StringsEqualUpToLength(Layout->String, LayoutName, LayoutName.Length));
|
||||||
|
|
||||||
ui_ExpandToFitChildren(Layout);
|
ui_ExpandToFitChildren(Layout);
|
||||||
|
|
||||||
|
@ -851,6 +877,12 @@ ui_PopLayout(ui_interface* Interface, gs_string LayoutName)
|
||||||
ui_CommitBounds(Interface->ActiveLayout, Layout->Bounds);
|
ui_CommitBounds(Interface->ActiveLayout, Layout->Bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void
|
||||||
|
ui_PopLayout(ui_interface* Interface, gs_string Category, u32 Value)
|
||||||
|
{
|
||||||
|
gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Value);
|
||||||
|
ui_PopLayout(Interface, Name);
|
||||||
|
}
|
||||||
|
|
||||||
static ui_widget*
|
static ui_widget*
|
||||||
ui_BeginRow(ui_interface* Interface, u32 ColumnsMax)
|
ui_BeginRow(ui_interface* Interface, u32 ColumnsMax)
|
||||||
|
@ -1050,6 +1082,7 @@ ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget, rect2 Bounds)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OutChar(&State->EditString, Interface->TempInputString.Str[i]);
|
OutChar(&State->EditString, Interface->TempInputString.Str[i]);
|
||||||
|
Interface->CursorPosition += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ struct animation_timeline_state
|
||||||
frame_range VisibleRange;
|
frame_range VisibleRange;
|
||||||
handle SelectedBlockHandle;
|
handle SelectedBlockHandle;
|
||||||
animation_handle EditingAnimationHandle;
|
animation_handle EditingAnimationHandle;
|
||||||
u32 SelectedAnimationLayer;
|
s32 SelectedAnimationLayer;
|
||||||
|
|
||||||
|
animation_handle NextActiveAnim;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline u32
|
inline u32
|
||||||
|
@ -263,7 +265,8 @@ AnimationTimeline_AddAnimationBlockCommand(animation_timeline_state* TimelineSta
|
||||||
if ((EndFrame - StartFrame) > 0)
|
if ((EndFrame - StartFrame) > 0)
|
||||||
{
|
{
|
||||||
animation_pattern_handle PatternHandle = Patterns_IndexToHandle(0);
|
animation_pattern_handle PatternHandle = Patterns_IndexToHandle(0);
|
||||||
u32 Layer = TimelineState->SelectedAnimationLayer;
|
s32 Layer = TimelineState->SelectedAnimationLayer;
|
||||||
|
Assert(Layer >= 0);
|
||||||
|
|
||||||
handle NewBlockHandle = Animation_AddBlock(ActiveAnim, StartFrame, EndFrame, PatternHandle, Layer);
|
handle NewBlockHandle = Animation_AddBlock(ActiveAnim, StartFrame, EndFrame, PatternHandle, Layer);
|
||||||
|
|
||||||
|
@ -504,13 +507,10 @@ PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback)
|
||||||
|
|
||||||
if (FileInfo.Path.Length > 0)
|
if (FileInfo.Path.Length > 0)
|
||||||
{
|
{
|
||||||
gs_file AnimFile = ReadEntireFile(Context.ThreadContext.FileHandler, FileInfo.Path);
|
animation_handle NewAnimHandle = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem,
|
||||||
|
State->Patterns,
|
||||||
gs_string AnimFileString = MakeString((char*)AnimFile.Data.Memory, AnimFile.Data.Size);
|
Context,
|
||||||
animation NewAnim = AnimParser_Parse(AnimFileString, State->AnimationSystem.Storage, State->Patterns);
|
FileInfo.Path);
|
||||||
NewAnim.FileInfo = AnimFile.FileInfo;
|
|
||||||
|
|
||||||
animation_handle NewAnimHandle = AnimationArray_Push(&State->AnimationSystem.Animations, NewAnim);
|
|
||||||
State->AnimationSystem.ActiveFadeGroup.From = NewAnimHandle;
|
State->AnimationSystem.ActiveFadeGroup.From = NewAnimHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,7 +639,7 @@ LayerList_Render(animation_timeline_state* TimelineState, animation* ActiveAnim,
|
||||||
if (ActiveAnim)
|
if (ActiveAnim)
|
||||||
{
|
{
|
||||||
v2 LayerTextPos = {};
|
v2 LayerTextPos = {};
|
||||||
for (u32 i = 0; i < ActiveAnim->Layers.Count; i++)
|
for (s32 i = 0; i < (s32)ActiveAnim->Layers.Count; i++)
|
||||||
{
|
{
|
||||||
anim_layer* Layer = ActiveAnim->Layers.Values + i;
|
anim_layer* Layer = ActiveAnim->Layers.Values + i;
|
||||||
|
|
||||||
|
@ -762,11 +762,9 @@ PANEL_MODAL_OVERRIDE_CALLBACK(AnimInfoView_SaveAnimFileCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
AnimationTimeline_SetActiveAnimation (animation_handle Handle, animation_timeline_state* TimelineState,
|
AnimationTimeline_SetActiveAnimation (animation_handle Handle, animation_timeline_state* TimelineState)
|
||||||
animation_system* System)
|
|
||||||
{
|
{
|
||||||
System->ActiveFadeGroup.From = Handle;
|
TimelineState->NextActiveAnim = Handle;
|
||||||
TimelineState->EditingAnimationHandle = Handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -774,8 +772,9 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn
|
||||||
{
|
{
|
||||||
animation_system* AnimSystem = &State->AnimationSystem;
|
animation_system* AnimSystem = &State->AnimationSystem;
|
||||||
|
|
||||||
|
animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From;
|
||||||
ui_interface* Interface = &State->Interface;
|
ui_interface* Interface = &State->Interface;
|
||||||
ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout"));
|
ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout"), ActiveAnimHandle.Index);
|
||||||
|
|
||||||
ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBG);
|
ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBG);
|
||||||
|
|
||||||
|
@ -796,7 +795,7 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn
|
||||||
{
|
{
|
||||||
animation_handle NewHandle = {};
|
animation_handle NewHandle = {};
|
||||||
NewHandle.Index = i;
|
NewHandle.Index = i;
|
||||||
AnimationTimeline_SetActiveAnimation(NewHandle, TimelineState, AnimSystem);
|
AnimationTimeline_SetActiveAnimation(NewHandle, TimelineState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,18 +805,22 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn
|
||||||
{
|
{
|
||||||
if (ui_Button(Interface, MakeString("New")))
|
if (ui_Button(Interface, MakeString("New")))
|
||||||
{
|
{
|
||||||
animation NewAnim = {};
|
animation_desc Desc = {};
|
||||||
NewAnim.Name = PushString(State->AnimationSystem.Storage, 256);
|
Desc.NameSize = 256;
|
||||||
|
Desc.LayersCount = 8;
|
||||||
|
Desc.BlocksCount = 8;
|
||||||
|
Desc.MinFrames = 0;
|
||||||
|
Desc.MaxFrames = SecondsToFrames(15, State->AnimationSystem);
|
||||||
|
|
||||||
|
animation NewAnim = Animation_Create(Desc, &State->AnimationSystem);
|
||||||
animation_handle NewAnimHandle = AnimationArray_Push(&State->AnimationSystem.Animations, NewAnim);
|
animation_handle NewAnimHandle = AnimationArray_Push(&State->AnimationSystem.Animations, NewAnim);
|
||||||
State->AnimationSystem.ActiveFadeGroup.From = NewAnimHandle;
|
AnimationTimeline_SetActiveAnimation(NewAnimHandle, TimelineState);
|
||||||
}
|
}
|
||||||
if (ActiveAnim && ui_Button(Interface, MakeString("Save")))
|
if (ActiveAnim && ui_Button(Interface, MakeString("Save")))
|
||||||
{
|
{
|
||||||
// Save Animation File
|
// Save Animation File
|
||||||
// TODO(pjs): If you created the animation via the "new" button, there won't be a file attached.
|
// TODO(pjs): If you created the animation via the "new" button, there won't be a file attached.
|
||||||
// need to use the file browser to create a file
|
// need to use the file browser to create a file
|
||||||
animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From;
|
|
||||||
animation ActiveAnimation = *AnimationArray_GetSafe(State->AnimationSystem.Animations, ActiveAnimHandle);
|
animation ActiveAnimation = *AnimationArray_GetSafe(State->AnimationSystem.Animations, ActiveAnimHandle);
|
||||||
|
|
||||||
if (!ActiveAnimation.FileInfo.Path.Str)
|
if (!ActiveAnimation.FileInfo.Path.Str)
|
||||||
|
@ -853,22 +856,26 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn
|
||||||
|
|
||||||
ui_Label(Interface, MakeString("Layer"));
|
ui_Label(Interface, MakeString("Layer"));
|
||||||
|
|
||||||
u32 LayerIndex = TimelineState->SelectedAnimationLayer;
|
s32 LayerIndex = TimelineState->SelectedAnimationLayer;
|
||||||
anim_layer* SelectedLayer = ActiveAnim->Layers.Values + LayerIndex;
|
anim_layer* SelectedLayer = 0;
|
||||||
|
if (LayerIndex >= 0)
|
||||||
ui_TextEntry(Interface, MakeString("Layer Name"), &SelectedLayer->Name);
|
|
||||||
gs_string BlendStr = BlendModeStrings[SelectedLayer->BlendMode];
|
|
||||||
if (ui_BeginLabeledDropdown(Interface, MakeString("Blend Mode"), BlendStr))
|
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < BlendMode_Count; i++)
|
SelectedLayer = ActiveAnim->Layers.Values + LayerIndex;
|
||||||
|
|
||||||
|
ui_TextEntry(Interface, MakeString("Layer Name"), &SelectedLayer->Name);
|
||||||
|
gs_string BlendStr = BlendModeStrings[SelectedLayer->BlendMode];
|
||||||
|
if (ui_BeginLabeledDropdown(Interface, MakeString("Blend Mode"), BlendStr))
|
||||||
{
|
{
|
||||||
if (ui_Button(Interface, BlendModeStrings[i]))
|
for (u32 i = 0; i < BlendMode_Count; i++)
|
||||||
{
|
{
|
||||||
SelectedLayer->BlendMode = (blend_mode)i;
|
if (ui_Button(Interface, BlendModeStrings[i]))
|
||||||
|
{
|
||||||
|
SelectedLayer->BlendMode = (blend_mode)i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui_EndLabeledDropdown(Interface);
|
||||||
}
|
}
|
||||||
ui_EndLabeledDropdown(Interface);
|
|
||||||
|
|
||||||
ui_Label(Interface, MakeString("Pattern"));
|
ui_Label(Interface, MakeString("Pattern"));
|
||||||
|
|
||||||
|
@ -917,11 +924,12 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer*
|
||||||
|
|
||||||
animation* ActiveAnim = 0;
|
animation* ActiveAnim = 0;
|
||||||
animation_handle Handle = State->AnimationSystem.ActiveFadeGroup.From;
|
animation_handle Handle = State->AnimationSystem.ActiveFadeGroup.From;
|
||||||
TimelineState->EditingAnimationHandle = Handle;
|
|
||||||
if (IsValid(Handle))
|
if (IsValid(Handle))
|
||||||
{
|
{
|
||||||
animation_array Animations = State->AnimationSystem.Animations;
|
animation_array Animations = State->AnimationSystem.Animations;
|
||||||
ActiveAnim = AnimationArray_GetSafe(Animations, Handle);
|
ActiveAnim = AnimationArray_GetSafe(Animations, Handle);
|
||||||
|
TimelineState->EditingAnimationHandle = Handle;
|
||||||
|
TimelineState->NextActiveAnim = Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_FillRect(&State->Interface, PanelBounds, v4{.1f,.1f,.1f,1.f});
|
ui_FillRect(&State->Interface, PanelBounds, v4{.1f,.1f,.1f,1.f});
|
||||||
|
@ -944,6 +952,14 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer*
|
||||||
LayerList_Render(TimelineState, ActiveAnim, LayersBounds, Panel, RenderBuffer, State, Context);
|
LayerList_Render(TimelineState, ActiveAnim, LayersBounds, Panel, RenderBuffer, State, Context);
|
||||||
TimeRange_Render(TimelineState, ActiveAnim, TimeRangeBounds, RenderBuffer, State, Context);
|
TimeRange_Render(TimelineState, ActiveAnim, TimeRangeBounds, RenderBuffer, State, Context);
|
||||||
AnimInfoView_Render(TimelineState, ActiveAnim, InfoBounds, Panel, RenderBuffer, State, Context);
|
AnimInfoView_Render(TimelineState, ActiveAnim, InfoBounds, Panel, RenderBuffer, State, Context);
|
||||||
|
|
||||||
|
if (!AnimHandlesAreEqual(TimelineState->NextActiveAnim,
|
||||||
|
Handle))
|
||||||
|
{
|
||||||
|
State->AnimationSystem.ActiveFadeGroup.From = TimelineState->NextActiveAnim;
|
||||||
|
TimelineState->EditingAnimationHandle = TimelineState->NextActiveAnim;
|
||||||
|
TimelineState->SelectedAnimationLayer = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
#define FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
#ifndef FOLDHAUS_ANIMATION
|
#ifndef FOLDHAUS_ANIMATION
|
||||||
|
|
||||||
#define ANIMATION_PROC(name) void name(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
#define ANIMATION_PROC(name) void name(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
typedef ANIMATION_PROC(animation_proc);
|
typedef ANIMATION_PROC(animation_proc);
|
||||||
|
|
||||||
struct frame_range
|
struct frame_range
|
||||||
|
@ -164,6 +164,8 @@ struct animation_system
|
||||||
r32 SecondsPerFrame;
|
r32 SecondsPerFrame;
|
||||||
b32 TimelineShouldAdvance;
|
b32 TimelineShouldAdvance;
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
bool Multithreaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE(pjs): A Pattern is a named procedure which can be used as
|
// NOTE(pjs): A Pattern is a named procedure which can be used as
|
||||||
|
@ -174,6 +176,7 @@ struct animation_pattern
|
||||||
char* Name;
|
char* Name;
|
||||||
s32 NameLength;
|
s32 NameLength;
|
||||||
animation_proc* Proc;
|
animation_proc* Proc;
|
||||||
|
bool Multithreaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct animation_pattern_array
|
struct animation_pattern_array
|
||||||
|
@ -250,9 +253,14 @@ Patterns_Create(gs_memory_arena* Arena, s32 CountMax)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Patterns_PushPattern(array, proc) Patterns_PushPattern_((array), (proc), Stringify(proc), sizeof(Stringify(proc)) - 1)
|
#define PATTERN_MULTITHREADED true
|
||||||
|
#define PATTERN_SINGLETHREADED false
|
||||||
|
|
||||||
|
#define Patterns_PushPattern(array, proc, multithread) \
|
||||||
|
Patterns_PushPattern_((array), (proc), Stringify(proc), sizeof(Stringify(proc)) - 1, (multithread))
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Patterns_PushPattern_(animation_pattern_array* Array, animation_proc* Proc, char* Name, u32 NameLength)
|
Patterns_PushPattern_(animation_pattern_array* Array, animation_proc* Proc, char* Name, u32 NameLength, bool Multithreaded)
|
||||||
{
|
{
|
||||||
Assert(Array->Count < Array->CountMax);
|
Assert(Array->Count < Array->CountMax);
|
||||||
|
|
||||||
|
@ -260,6 +268,7 @@ Patterns_PushPattern_(animation_pattern_array* Array, animation_proc* Proc, char
|
||||||
Pattern.Name = Name;
|
Pattern.Name = Name;
|
||||||
Pattern.NameLength = NameLength;
|
Pattern.NameLength = NameLength;
|
||||||
Pattern.Proc = Proc;
|
Pattern.Proc = Proc;
|
||||||
|
Pattern.Multithreaded = Multithreaded;
|
||||||
|
|
||||||
Array->Values[Array->Count++] = Pattern;
|
Array->Values[Array->Count++] = Pattern;
|
||||||
}
|
}
|
||||||
|
@ -410,6 +419,38 @@ AnimationArray_GetSafe(animation_array Array, animation_handle Handle)
|
||||||
//
|
//
|
||||||
// Animation
|
// Animation
|
||||||
|
|
||||||
|
typedef struct animation_desc
|
||||||
|
{
|
||||||
|
u32 NameSize;
|
||||||
|
char* Name;
|
||||||
|
|
||||||
|
u32 LayersCount;
|
||||||
|
u32 BlocksCount;
|
||||||
|
|
||||||
|
u32 MinFrames;
|
||||||
|
u32 MaxFrames;
|
||||||
|
} animation_desc;
|
||||||
|
|
||||||
|
internal animation
|
||||||
|
Animation_Create(animation_desc Desc, animation_system* System)
|
||||||
|
{
|
||||||
|
animation Result = {};
|
||||||
|
u32 NameLen = Desc.NameSize;
|
||||||
|
if (Desc.Name)
|
||||||
|
{
|
||||||
|
NameLen = Max(CStringLength(Desc.Name), NameLen);
|
||||||
|
Result.Name = PushStringF(System->Storage, NameLen, "%s", Desc.Name);
|
||||||
|
} else {
|
||||||
|
Result.Name = PushStringF(System->Storage, NameLen, "[New Animation]");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.Layers = AnimLayerArray_Create(System->Storage, Desc.LayersCount);
|
||||||
|
Result.Blocks_ = AnimBlockArray_Create(System->Storage, Desc.BlocksCount);
|
||||||
|
Result.PlayableRange.Min = Desc.MinFrames;
|
||||||
|
Result.PlayableRange.Max = Desc.MaxFrames;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal handle
|
internal handle
|
||||||
Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, animation_pattern_handle AnimationProcHandle, u32 LayerIndex)
|
Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, animation_pattern_handle AnimationProcHandle, u32 LayerIndex)
|
||||||
{
|
{
|
||||||
|
@ -604,6 +645,9 @@ AnimationSystem_Init(animation_system_desc Desc)
|
||||||
Clear(&Result.ActiveFadeGroup.To);
|
Clear(&Result.ActiveFadeGroup.To);
|
||||||
Result.ActiveFadeGroup.FadeElapsed = 0;
|
Result.ActiveFadeGroup.FadeElapsed = 0;
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
Result.Multithreaded = true;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,14 +89,79 @@ struct pattern_args
|
||||||
u8* UserData;
|
u8* UserData;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
struct render_anim_to_led_buffer_job_data
|
||||||
AnimationSystem_RenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, animation_pattern_array Patterns, pattern_args PatternArgs)
|
|
||||||
{
|
{
|
||||||
|
animation_pattern Pattern;
|
||||||
|
led_buffer Buffer;
|
||||||
|
led_buffer_range BufferRange;
|
||||||
|
pattern_args PatternArgs;
|
||||||
|
r32 SecondsIntoBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AnimationSystem_RenderAnimationToLedBufferJob(gs_thread_context Context, gs_data Data)
|
||||||
|
{
|
||||||
|
render_anim_to_led_buffer_job_data JobData = *(render_anim_to_led_buffer_job_data*)Data.Memory;
|
||||||
|
JobData.Pattern.Proc(&JobData.Buffer,
|
||||||
|
JobData.BufferRange,
|
||||||
|
JobData.PatternArgs.Assembly,
|
||||||
|
JobData.SecondsIntoBlock,
|
||||||
|
JobData.PatternArgs.Transient,
|
||||||
|
JobData.PatternArgs.UserData);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MULTITHREAD_PATTERN_RENDERING 1
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AnimationSystem_BeginRenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, animation_pattern_array Patterns, pattern_args PatternArgs,
|
||||||
|
context Context)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
u32 FramesIntoBlock = System->CurrentFrame - Block.Range.Min;
|
u32 FramesIntoBlock = System->CurrentFrame - Block.Range.Min;
|
||||||
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
|
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
|
||||||
|
|
||||||
animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle);
|
animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle);
|
||||||
Pattern.Proc(Buffer, PatternArgs.Assembly, SecondsIntoBlock, PatternArgs.Transient, PatternArgs.UserData);
|
|
||||||
|
if (System->Multithreaded && Pattern.Multithreaded)
|
||||||
|
{
|
||||||
|
u32 JobsCount = 4;
|
||||||
|
u32 LedsPerJob = Buffer->LedCount / JobsCount;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < JobsCount; i++)
|
||||||
|
{
|
||||||
|
gs_data Data = PushSizeToData(Context.ThreadContext.Transient, sizeof(render_anim_to_led_buffer_job_data));
|
||||||
|
render_anim_to_led_buffer_job_data* JobData = (render_anim_to_led_buffer_job_data*)Data.Memory;
|
||||||
|
JobData->Pattern = Pattern;
|
||||||
|
JobData->Buffer = *Buffer;
|
||||||
|
JobData->BufferRange.First = LedsPerJob * i;
|
||||||
|
JobData->BufferRange.OnePastLast = LedsPerJob * (i + 1);
|
||||||
|
JobData->PatternArgs = PatternArgs;
|
||||||
|
JobData->SecondsIntoBlock = SecondsIntoBlock;
|
||||||
|
|
||||||
|
Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue,
|
||||||
|
(thread_proc*)AnimationSystem_RenderAnimationToLedBufferJob,
|
||||||
|
Data,
|
||||||
|
ConstString("Render Pattern To Buffer"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
led_buffer_range Range = {};
|
||||||
|
Range.First = 0;
|
||||||
|
Range.OnePastLast = Buffer->LedCount;
|
||||||
|
|
||||||
|
Pattern.Proc(Buffer, Range, PatternArgs.Assembly, SecondsIntoBlock, PatternArgs.Transient, PatternArgs.UserData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AnimationSystem_EndRenderBlockToLedBuffer (animation_system* System, context Context)
|
||||||
|
{
|
||||||
|
if (System->Multithreaded)
|
||||||
|
{
|
||||||
|
Context.GeneralWorkQueue->CompleteQueueWork(Context.GeneralWorkQueue, Context.ThreadContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(pjs): This mirrors animation_layer_frame to account
|
// NOTE(pjs): This mirrors animation_layer_frame to account
|
||||||
|
@ -114,7 +179,8 @@ RenderAnimationToLedBuffer (animation_system* System,
|
||||||
layer_led_buffer* LayerBuffers,
|
layer_led_buffer* LayerBuffers,
|
||||||
led_buffer* AssemblyLedBuffer,
|
led_buffer* AssemblyLedBuffer,
|
||||||
animation_pattern_array Patterns,
|
animation_pattern_array Patterns,
|
||||||
gs_memory_arena* Transient)
|
gs_memory_arena* Transient,
|
||||||
|
context Context)
|
||||||
{
|
{
|
||||||
led_buffer AccBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient);
|
led_buffer AccBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient);
|
||||||
|
|
||||||
|
@ -144,15 +210,17 @@ RenderAnimationToLedBuffer (animation_system* System,
|
||||||
{
|
{
|
||||||
led_buffer TempBuffer = LayerBuffers[Layer].HotBuffer;
|
led_buffer TempBuffer = LayerBuffers[Layer].HotBuffer;
|
||||||
animation_block Block = LayerFrame.Hot;
|
animation_block Block = LayerFrame.Hot;
|
||||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, Patterns, PatternArgs);
|
AnimationSystem_BeginRenderBlockToLedBuffer(System, Block, &TempBuffer, Patterns, PatternArgs, Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LayerFrame.HasNextHot)
|
if (LayerFrame.HasNextHot)
|
||||||
{
|
{
|
||||||
led_buffer TempBuffer = LayerBuffers[Layer].NextHotBuffer;
|
led_buffer TempBuffer = LayerBuffers[Layer].NextHotBuffer;
|
||||||
animation_block Block = LayerFrame.NextHot;
|
animation_block Block = LayerFrame.NextHot;
|
||||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, Patterns, PatternArgs);
|
AnimationSystem_BeginRenderBlockToLedBuffer(System, Block, &TempBuffer, Patterns, PatternArgs, Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnimationSystem_EndRenderBlockToLedBuffer(System, Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blend together any layers that have a hot and next hot buffer
|
// Blend together any layers that have a hot and next hot buffer
|
||||||
|
@ -193,8 +261,11 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
|
||||||
led_system* LedSystem,
|
led_system* LedSystem,
|
||||||
animation_pattern_array Patterns,
|
animation_pattern_array Patterns,
|
||||||
gs_memory_arena* Transient,
|
gs_memory_arena* Transient,
|
||||||
|
context Context,
|
||||||
u8* UserData)
|
u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
s32 CurrentFrame = System->CurrentFrame;
|
s32 CurrentFrame = System->CurrentFrame;
|
||||||
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
|
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
|
||||||
|
|
||||||
|
@ -231,7 +302,8 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
|
||||||
FromLayerBuffers,
|
FromLayerBuffers,
|
||||||
AssemblyLedBuffer,
|
AssemblyLedBuffer,
|
||||||
Patterns,
|
Patterns,
|
||||||
Transient);
|
Transient,
|
||||||
|
Context);
|
||||||
led_buffer ConsolidatedBuffer = FromBuffer;
|
led_buffer ConsolidatedBuffer = FromBuffer;
|
||||||
|
|
||||||
if (ToAnim) {
|
if (ToAnim) {
|
||||||
|
@ -241,7 +313,8 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
|
||||||
ToLayerBuffers,
|
ToLayerBuffers,
|
||||||
AssemblyLedBuffer,
|
AssemblyLedBuffer,
|
||||||
Patterns,
|
Patterns,
|
||||||
Transient);
|
Transient,
|
||||||
|
Context);
|
||||||
|
|
||||||
r32 BlendPercent = FadeGroup.FadeElapsed / FadeGroup.FadeDuration;
|
r32 BlendPercent = FadeGroup.FadeElapsed / FadeGroup.FadeDuration;
|
||||||
LedBuffer_Blend(FromBuffer, ToBuffer, &ConsolidatedBuffer, LedBlend_Lerp, (u8*)&BlendPercent);
|
LedBuffer_Blend(FromBuffer, ToBuffer, &ConsolidatedBuffer, LedBlend_Lerp, (u8*)&BlendPercent);
|
||||||
|
|
|
@ -182,9 +182,23 @@ AnimParser_Parse(gs_string File, gs_memory_arena* Arena, animation_pattern_array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
internal animation
|
||||||
|
AnimParser_Parse(gs_data File, gs_memory_arena* Arena, animation_pattern_array AnimPatterns)
|
||||||
|
{
|
||||||
|
gs_string FileString = MakeString((char*)File.Memory, File.Size);
|
||||||
|
return AnimParser_Parse(FileString, Arena, AnimPatterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal animation_handle
|
||||||
|
AnimationSystem_LoadAnimationFromFile(animation_system* System, animation_pattern_array AnimPatterns, context Context, gs_const_string FilePath)
|
||||||
|
{
|
||||||
|
gs_file AnimFile = ReadEntireFile(Context.ThreadContext.FileHandler, FilePath);
|
||||||
|
animation NewAnim = AnimParser_Parse(AnimFile.Data, System->Storage, AnimPatterns);
|
||||||
|
NewAnim.FileInfo = AnimFile.FileInfo;
|
||||||
|
animation_handle NewAnimHandle = AnimationArray_Push(&System->Animations, NewAnim);
|
||||||
|
return NewAnimHandle;
|
||||||
|
}
|
||||||
#define FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
#define FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
||||||
#endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
#endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
|
@ -32,6 +32,12 @@ struct led_buffer
|
||||||
v4* Positions;
|
v4* Positions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct led_buffer_range
|
||||||
|
{
|
||||||
|
u32 First;
|
||||||
|
u32 OnePastLast;
|
||||||
|
};
|
||||||
|
|
||||||
struct led_system
|
struct led_system
|
||||||
{
|
{
|
||||||
gs_allocator PlatformMemory;
|
gs_allocator PlatformMemory;
|
||||||
|
@ -184,6 +190,8 @@ LedBuffer_ClearToBlack(led_buffer* Buffer)
|
||||||
internal void
|
internal void
|
||||||
LedBuffer_Copy(led_buffer From, led_buffer* To)
|
LedBuffer_Copy(led_buffer From, led_buffer* To)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
Assert(From.LedCount == To->LedCount);
|
Assert(From.LedCount == To->LedCount);
|
||||||
u32 LedCount = To->LedCount;
|
u32 LedCount = To->LedCount;
|
||||||
for (u32 i = 0; i < LedCount; i++)
|
for (u32 i = 0; i < LedCount; i++)
|
||||||
|
@ -195,6 +203,8 @@ LedBuffer_Copy(led_buffer From, led_buffer* To)
|
||||||
internal void
|
internal void
|
||||||
LedBuffer_Blend(led_buffer A, led_buffer B, led_buffer* Dest, led_blend_proc* BlendProc, u8* UserData)
|
LedBuffer_Blend(led_buffer A, led_buffer B, led_buffer* Dest, led_blend_proc* BlendProc, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
Assert(A.LedCount == B.LedCount);
|
Assert(A.LedCount == B.LedCount);
|
||||||
Assert(Dest->LedCount == A.LedCount);
|
Assert(Dest->LedCount == A.LedCount);
|
||||||
Assert(BlendProc);
|
Assert(BlendProc);
|
||||||
|
@ -211,6 +221,8 @@ LedBuffer_Blend(led_buffer A, led_buffer B, led_buffer* Dest, led_blend_proc* Bl
|
||||||
internal led_buffer
|
internal led_buffer
|
||||||
LedBuffer_CreateCopyCleared (led_buffer Buffer, gs_memory_arena* Arena)
|
LedBuffer_CreateCopyCleared (led_buffer Buffer, gs_memory_arena* Arena)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
led_buffer Result = {};
|
led_buffer Result = {};
|
||||||
Result.LedCount = Buffer.LedCount;
|
Result.LedCount = Buffer.LedCount;
|
||||||
Result.Positions = Buffer.Positions;
|
Result.Positions = Buffer.Positions;
|
||||||
|
|
|
@ -95,6 +95,21 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->RunEditor = true;
|
State->RunEditor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BuildAssemblyData (app_state* State, context Context, addressed_data_buffer_list* OutputData)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define SEND_DATA
|
||||||
|
#ifdef SEND_DATA
|
||||||
|
// NOTE(pjs): Building data buffers to be sent out to the sculpture
|
||||||
|
// This array is used on the platform side to actually send the information
|
||||||
|
assembly_array SACNAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaSACN, State->Transient);
|
||||||
|
assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient);
|
||||||
|
SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem);
|
||||||
|
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
UPDATE_AND_RENDER(UpdateAndRender)
|
UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
@ -119,6 +134,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
&State->LedSystem,
|
&State->LedSystem,
|
||||||
State->Patterns,
|
State->Patterns,
|
||||||
State->Transient,
|
State->Transient,
|
||||||
|
*Context,
|
||||||
State->UserSpaceDesc.UserData.Memory);
|
State->UserSpaceDesc.UserData.Memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,20 +149,21 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
Editor_Render(State, Context, RenderBuffer);
|
Editor_Render(State, Context, RenderBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SEND_DATA
|
BuildAssemblyData(State, *Context, OutputData);
|
||||||
#ifdef SEND_DATA
|
|
||||||
// NOTE(pjs): Building data buffers to be sent out to the sculpture
|
|
||||||
// This array is used on the platform side to actually send the information
|
|
||||||
assembly_array SACNAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaSACN, State->Transient);
|
|
||||||
assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient);
|
|
||||||
SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem);
|
|
||||||
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP_APPLICATION(CleanupApplication)
|
CLEANUP_APPLICATION(CleanupApplication)
|
||||||
{
|
{
|
||||||
app_state* State = (app_state*)Context.MemoryBase;
|
app_state* State = (app_state*)Context.MemoryBase;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < State->Assemblies.Count; i++)
|
||||||
|
{
|
||||||
|
assembly Assembly = State->Assemblies.Values[i];
|
||||||
|
led_buffer LedBuffer = State->LedSystem.Buffers[Assembly.LedBufferIndex];
|
||||||
|
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0});
|
||||||
|
}
|
||||||
|
BuildAssemblyData(State, Context, OutputData);
|
||||||
|
|
||||||
US_CustomCleanup(&State->UserSpaceDesc, State, Context);
|
US_CustomCleanup(&State->UserSpaceDesc, State, Context);
|
||||||
SACN_Cleanup(&State->SACN, Context);
|
SACN_Cleanup(&State->SACN, Context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ typedef UPDATE_AND_RENDER(update_and_render);
|
||||||
#define RELOAD_STATIC_DATA(name) void name(context Context, debug_services* DebugServices)
|
#define RELOAD_STATIC_DATA(name) void name(context Context, debug_services* DebugServices)
|
||||||
typedef RELOAD_STATIC_DATA(reload_static_data);
|
typedef RELOAD_STATIC_DATA(reload_static_data);
|
||||||
|
|
||||||
#define CLEANUP_APPLICATION(name) void name(context Context)
|
#define CLEANUP_APPLICATION(name) void name(context Context, addressed_data_buffer_list* OutputData)
|
||||||
typedef CLEANUP_APPLICATION(cleanup_application);
|
typedef CLEANUP_APPLICATION(cleanup_application);
|
||||||
|
|
||||||
// Platform Functions
|
// Platform Functions
|
||||||
|
|
|
@ -411,30 +411,30 @@ GetColor(v4* Colors, u32 ColorsCount, r32 Percent)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
SolidColorPattern(led_buffer* Leds, pixel Color)
|
SolidColorPattern(led_buffer* Leds, led_buffer_range Range, pixel Color)
|
||||||
{
|
{
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
Leds->Colors[LedIndex] = Color;
|
Leds->Colors[LedIndex] = Color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Blue(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Blue(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
pixel Blue = pixel{0, 0, 255};
|
pixel Blue = pixel{0, 0, 255};
|
||||||
SolidColorPattern(Leds, Blue);
|
SolidColorPattern(Leds, Range, Blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Green(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Green(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
pixel Green = pixel{0, 255, 0};
|
pixel Green = pixel{0, 255, 0};
|
||||||
SolidColorPattern(Leds, Green);
|
SolidColorPattern(Leds, Range, Green);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_FlowerColors(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_FlowerColors(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 CycleTime = 10;
|
r32 CycleTime = 10;
|
||||||
r32 CyclePercent = ModR32(Time, CycleTime) / CycleTime;
|
r32 CyclePercent = ModR32(Time, CycleTime) / CycleTime;
|
||||||
|
@ -442,7 +442,7 @@ Pattern_FlowerColors(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_ar
|
||||||
v4 CA = GetColor(FlowerAColors, FLOWER_COLORS_COUNT, CyclePercent);
|
v4 CA = GetColor(FlowerAColors, FLOWER_COLORS_COUNT, CyclePercent);
|
||||||
v4 CB = GetColor(FlowerAColors, FLOWER_COLORS_COUNT, 1.0f - CyclePercent);
|
v4 CB = GetColor(FlowerAColors, FLOWER_COLORS_COUNT, 1.0f - CyclePercent);
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
r32 Pct = (Abs(ModR32(P.y, 150) / 150) + CycleTime) * PiR32;
|
r32 Pct = (Abs(ModR32(P.y, 150) / 150) + CycleTime) * PiR32;
|
||||||
|
@ -453,7 +453,7 @@ Pattern_FlowerColors(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_ar
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
TestPatternOne(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
TestPatternOne(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
led_strip_list BlumenStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Blumen Lumen"), Transient);
|
led_strip_list BlumenStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Blumen Lumen"), Transient);
|
||||||
led_strip_list RadiaStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Radialumia"), Transient);
|
led_strip_list RadiaStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Radialumia"), Transient);
|
||||||
|
@ -485,7 +485,7 @@ TestPatternOne(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
TestPatternTwo(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
TestPatternTwo(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 PeriodicTime = (Time / PiR32) * 2;
|
r32 PeriodicTime = (Time / PiR32) * 2;
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ TestPatternTwo(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T
|
||||||
r32 OuterRadiusSquared = 1000000;
|
r32 OuterRadiusSquared = 1000000;
|
||||||
r32 InnerRadiusSquared = 0;
|
r32 InnerRadiusSquared = 0;
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 Position = Leds->Positions[LedIndex];
|
v4 Position = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ TestPatternTwo(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
TestPatternThree(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
TestPatternThree(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
v4 GreenCenter = v4{0, 0, 150, 1};
|
v4 GreenCenter = v4{0, 0, 150, 1};
|
||||||
r32 GreenRadius = Abs(SinR32(Time)) * 200;
|
r32 GreenRadius = Abs(SinR32(Time)) * 200;
|
||||||
|
@ -548,7 +548,7 @@ TestPatternThree(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena*
|
||||||
r32 FadeDist = 35;
|
r32 FadeDist = 35;
|
||||||
|
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 LedPosition = Leds->Positions[LedIndex];
|
v4 LedPosition = Leds->Positions[LedIndex];
|
||||||
u8 Red = 0;
|
u8 Red = 0;
|
||||||
|
@ -702,7 +702,7 @@ while (Hue > 360.0f) { Hue -= 360.0f; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_HueShift(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 Height = SinR32(Time) * 25;
|
r32 Height = SinR32(Time) * 25;
|
||||||
|
|
||||||
|
@ -713,7 +713,7 @@ Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena*
|
||||||
v4 HSV = { CycleProgress * 360, 1, 1, 1 };
|
v4 HSV = { CycleProgress * 360, 1, 1, 1 };
|
||||||
v4 RGB = HSVToRGB(HSV);
|
v4 RGB = HSVToRGB(HSV);
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 Pos = Leds->Positions[LedIndex];
|
v4 Pos = Leds->Positions[LedIndex];
|
||||||
r32 Dist = Pos.y - Height;
|
r32 Dist = Pos.y - Height;
|
||||||
|
@ -732,7 +732,7 @@ Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena*
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_HueFade(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 HueBase = ModR32(Time * 50, 360);
|
r32 HueBase = ModR32(Time * 50, 360);
|
||||||
|
|
||||||
|
@ -740,7 +740,7 @@ Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena*
|
||||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 Pos = Leds->Positions[LedIndex];
|
v4 Pos = Leds->Positions[LedIndex];
|
||||||
r32 Hue = HueBase + Pos.y + Pos.x;
|
r32 Hue = HueBase + Pos.y + Pos.x;
|
||||||
|
@ -752,9 +752,9 @@ Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena*
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_AllGreen(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_AllGreen(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
u32 I = LedIndex + 1;
|
u32 I = LedIndex + 1;
|
||||||
Leds->Colors[LedIndex] = {};
|
Leds->Colors[LedIndex] = {};
|
||||||
|
@ -781,7 +781,7 @@ PatternHash(r32 Seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Spots(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Spots(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
pixel ColorA = { 0, 255, 255 };
|
pixel ColorA = { 0, 255, 255 };
|
||||||
pixel ColorB = { 255, 0, 255 };
|
pixel ColorB = { 255, 0, 255 };
|
||||||
|
@ -790,7 +790,7 @@ Pattern_Spots(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Tr
|
||||||
Time *= Speed;
|
Time *= Speed;
|
||||||
r32 ScaleA = 2 * SinR32(Time / 5);
|
r32 ScaleA = 2 * SinR32(Time / 5);
|
||||||
r32 ScaleB = 2.4f * CosR32(Time / 2.5f);
|
r32 ScaleB = 2.4f * CosR32(Time / 2.5f);
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
r32 V = P.y;
|
r32 V = P.y;
|
||||||
|
@ -807,10 +807,10 @@ Pattern_Spots(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Tr
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_LighthouseRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_LighthouseRainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v2 Vector = v2{
|
v2 Vector = v2{
|
||||||
Leds->Positions[LedIndex].x,
|
Leds->Positions[LedIndex].x,
|
||||||
|
@ -828,7 +828,7 @@ Pattern_LighthouseRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memo
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_SmoothGrowRainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 FillCycleTime = ModR32(Time, 7.0f) / 7.0f;
|
r32 FillCycleTime = ModR32(Time, 7.0f) / 7.0f;
|
||||||
r32 ColorCycleTime = ModR32(Time, 21.0f) / 21.0f;
|
r32 ColorCycleTime = ModR32(Time, 21.0f) / 21.0f;
|
||||||
|
@ -850,7 +850,7 @@ Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memo
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_GrowAndFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_GrowAndFade(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 PercentCycle = ModR32(Time, 10) / 10;
|
r32 PercentCycle = ModR32(Time, 10) / 10;
|
||||||
v4 HSV = { PercentCycle * 360, 1, 1, 1 };
|
v4 HSV = { PercentCycle * 360, 1, 1, 1 };
|
||||||
|
@ -859,7 +859,7 @@ Pattern_GrowAndFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_are
|
||||||
r32 RefHeight = -100 + (Smoothstep(PercentCycle * 1.4f) * 400);
|
r32 RefHeight = -100 + (Smoothstep(PercentCycle * 1.4f) * 400);
|
||||||
r32 RefBrightness = 1.0f - Smoothstep(PercentCycle);
|
r32 RefBrightness = 1.0f - Smoothstep(PercentCycle);
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
|
@ -873,7 +873,7 @@ Pattern_GrowAndFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_are
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_ColorToWhite(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_ColorToWhite(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 FadeBottomBase = 50;
|
r32 FadeBottomBase = 50;
|
||||||
r32 FadeTop = 125;
|
r32 FadeTop = 125;
|
||||||
|
@ -935,7 +935,7 @@ Pattern_ColorToWhite(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_ar
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_FlowerColorToWhite(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_FlowerColorToWhite(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 FadeBottomBase = 50;
|
r32 FadeBottomBase = 50;
|
||||||
r32 FadeTop = 125;
|
r32 FadeTop = 125;
|
||||||
|
@ -999,7 +999,7 @@ v4* FBC = &FlowerBColors[0];
|
||||||
v4* FCC = &FlowerCColors[0];
|
v4* FCC = &FlowerCColors[0];
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_BasicFlowers(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_BasicFlowers(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
if (TLastFrame > Time)
|
if (TLastFrame > Time)
|
||||||
{
|
{
|
||||||
|
@ -1042,16 +1042,11 @@ Pattern_BasicFlowers(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_ar
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Wavy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Wavy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
}
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_Patchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
|
@ -1072,8 +1067,14 @@ Pattern_Patchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
//Leds->Colors[LedIndex] = pixel{NV, NV, NV};
|
//Leds->Colors[LedIndex] = pixel{NV, NV, NV};
|
||||||
}
|
}
|
||||||
#elif 1
|
}
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
|
internal void
|
||||||
|
Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
r32 LedRange = 300.0f;
|
r32 LedRange = 300.0f;
|
||||||
|
@ -1093,37 +1094,17 @@ Pattern_Patchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T
|
||||||
v4 C = CA + CB;
|
v4 C = CA + CB;
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
r32 LedRange = 300.0f;
|
|
||||||
r32 ScaleFactor = 1.0f / LedRange;
|
|
||||||
v3 Pp = P.xyz + v3{150, 100, 0};
|
|
||||||
|
|
||||||
r32 NoiseA = Fbm3D((Pp / 35), Time * 0.5f);
|
|
||||||
//NoiseA = PowR32(NoiseA, 3);
|
|
||||||
NoiseA = Smoothstep(NoiseA);
|
|
||||||
v4 CA = v4{1, 0, 1, 1} * NoiseA;
|
|
||||||
|
|
||||||
r32 NoiseB = Noise3D((Pp / 35) + v3{0, 0, Time * 5});
|
|
||||||
NoiseB = PowR32(NoiseB, 3);
|
|
||||||
NoiseB = Smoothstep(NoiseB);
|
|
||||||
v4 CB = v4{0, 1, 1, 1};
|
|
||||||
|
|
||||||
v4 C = V4Lerp(NoiseB, CA, CB);
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Leafy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Leafy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
v4* Colors = &FlowerBColors[0];
|
v4* Colors = &FlowerBColors[0];
|
||||||
|
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
|
@ -1177,15 +1158,70 @@ Pattern_Leafy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Tr
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_LeafyPatchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_LeafyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
r32 LedRange = 300.0f;
|
||||||
|
r32 ScaleFactor = 1.0f / LedRange;
|
||||||
|
v3 Pp = P.xyz + v3{150, 100, 0};
|
||||||
|
|
||||||
|
r32 NoiseA = Fbm3D((Pp / 35), Time * 0.5f);
|
||||||
|
//NoiseA = PowR32(NoiseA, 3);
|
||||||
|
NoiseA = Smoothstep(NoiseA);
|
||||||
|
v4 CA = v4{1, 0, 1, 1} * NoiseA;
|
||||||
|
|
||||||
|
r32 NoiseB = Noise3D((Pp / 35) + v3{0, 0, Time * 5});
|
||||||
|
NoiseB = PowR32(NoiseB, 3);
|
||||||
|
NoiseB = Smoothstep(NoiseB);
|
||||||
|
v4 CB = v4{0, 1, 1, 1};
|
||||||
|
|
||||||
|
v4 C = V4Lerp(NoiseB, CA, CB);
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_WavyPatchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
gs_random_series Random = InitRandomSeries(24601);
|
||||||
|
|
||||||
|
r32 LightSpeedMin = 1;
|
||||||
|
r32 LightSpeedMax = 5;
|
||||||
|
|
||||||
|
r32 LightHueMin = (ModR32(Time, 10) / 10) * 360;
|
||||||
|
r32 LightHueMax = ModR32((LightHueMin + 45), 360) ;
|
||||||
|
|
||||||
|
s32 LightTailLength = 10;
|
||||||
|
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
|
||||||
|
{
|
||||||
|
v2_strip Strip = Assembly.Strips[StripIndex];
|
||||||
|
|
||||||
|
r32 LightHue = LerpR32(NextRandomUnilateral(&Random),
|
||||||
|
LightHueMin,
|
||||||
|
LightHueMax);
|
||||||
|
r32 LightStartHeight = NextRandomUnilateral(&Random);
|
||||||
|
r32 LightSpeed = LerpR32(NextRandomUnilateral(&Random),
|
||||||
|
LightSpeedMin,
|
||||||
|
LightSpeedMax);
|
||||||
|
r32 LightCurrentHeight = LightStartHeight + (LightSpeed * Time * 0.1f);
|
||||||
|
s32 StartIndex = (s32)(LightCurrentHeight * (r32)Strip.LedCount) % Strip.LedCount;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < LightTailLength; i++)
|
||||||
|
{
|
||||||
|
s32 StripLedIndex = StartIndex + i;
|
||||||
|
if (StripLedIndex >= (s32)Strip.LedCount) continue;
|
||||||
|
|
||||||
|
u32 LedIndex = Strip.LedLUT[StripLedIndex];
|
||||||
|
r32 PctTail = ((r32)i / (r32)LightTailLength);
|
||||||
|
v4 C = HSVToRGB(v4{LightHue, 1, 1, 1}) * PctTail;
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BLUMEN_PATTERNS_H
|
#define BLUMEN_PATTERNS_H
|
||||||
|
|
|
@ -396,7 +396,7 @@ Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer*
|
||||||
{
|
{
|
||||||
if (BufferAt->ComPort.Length > 0)
|
if (BufferAt->ComPort.Length > 0)
|
||||||
{
|
{
|
||||||
HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 2000000, 8, NOPARITY, 1);
|
HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 2000000, 8, NOPARITY, 1, Context.Transient);
|
||||||
if (SerialPort != INVALID_HANDLE_VALUE)
|
if (SerialPort != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
if (Win32SerialPort_Write(SerialPort, BufferAt->Data))
|
if (Win32SerialPort_Write(SerialPort, BufferAt->Data))
|
||||||
|
@ -524,9 +524,39 @@ SetWorkingDirectory(HINSTANCE HInstance, gs_thread_context ThreadContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../../gs_libs/gs_path.h"
|
#include "../../gs_libs/gs_path.h"
|
||||||
|
|
||||||
#include "../../gs_libs/gs_csv.h"
|
#include "../../gs_libs/gs_csv.h"
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32_SendOutputData(gs_thread_context ThreadContext, addressed_data_buffer_list OutputData)
|
||||||
|
{
|
||||||
|
bool Multithread = true;
|
||||||
|
if (Multithread)
|
||||||
|
{
|
||||||
|
for (addressed_data_buffer* At = OutputData.Root;
|
||||||
|
At != 0;
|
||||||
|
At = At->Next)
|
||||||
|
{
|
||||||
|
gs_data ProcArg = {};
|
||||||
|
ProcArg.Memory = (u8*)At;
|
||||||
|
ProcArg.Size = sizeof(addressed_data_buffer);
|
||||||
|
Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffer_Job, ProcArg, ConstString("Send UART Data"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (addressed_data_buffer* At = OutputData.Root;
|
||||||
|
At != 0;
|
||||||
|
At = At->Next)
|
||||||
|
{
|
||||||
|
gs_data ProcArg = {};
|
||||||
|
ProcArg.Memory = (u8*)At;
|
||||||
|
ProcArg.Size = sizeof(addressed_data_buffer);
|
||||||
|
Win32_SendAddressedDataBuffer_Job(ThreadContext, ProcArg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int WINAPI
|
int WINAPI
|
||||||
WinMain (
|
WinMain (
|
||||||
HINSTANCE HInstance,
|
HINSTANCE HInstance,
|
||||||
|
@ -707,31 +737,7 @@ WinMain (
|
||||||
|
|
||||||
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
|
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
|
||||||
|
|
||||||
bool Multithread = false;
|
Win32_SendOutputData(ThreadContext, OutputData);
|
||||||
if (Multithread)
|
|
||||||
{
|
|
||||||
for (addressed_data_buffer* At = OutputData.Root;
|
|
||||||
At != 0;
|
|
||||||
At = At->Next)
|
|
||||||
{
|
|
||||||
gs_data ProcArg = {};
|
|
||||||
ProcArg.Memory = (u8*)At;
|
|
||||||
ProcArg.Size = sizeof(addressed_data_buffer);
|
|
||||||
Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffer_Job, ProcArg, ConstString("Send UART Data"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (addressed_data_buffer* At = OutputData.Root;
|
|
||||||
At != 0;
|
|
||||||
At = At->Next)
|
|
||||||
{
|
|
||||||
gs_data ProcArg = {};
|
|
||||||
ProcArg.Memory = (u8*)At;
|
|
||||||
ProcArg.Size = sizeof(addressed_data_buffer);
|
|
||||||
Win32_SendAddressedDataBuffer_Job(ThreadContext, ProcArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderCommandBuffer(RenderBuffer);
|
RenderCommandBuffer(RenderBuffer);
|
||||||
ClearRenderBuffer(&RenderBuffer);
|
ClearRenderBuffer(&RenderBuffer);
|
||||||
|
@ -759,7 +765,9 @@ WinMain (
|
||||||
LastFrameEnd = GetWallClock();
|
LastFrameEnd = GetWallClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.CleanupApplication(Context);
|
Context.CleanupApplication(Context, &OutputData);
|
||||||
|
Win32_SendOutputData(ThreadContext, OutputData);
|
||||||
|
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
||||||
|
|
||||||
Win32WorkQueue_Cleanup();
|
Win32WorkQueue_Cleanup();
|
||||||
//Win32_TestCode_SocketReading_Cleanup();
|
//Win32_TestCode_SocketReading_Cleanup();
|
||||||
|
|
|
@ -70,20 +70,74 @@ Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Par
|
||||||
bool Success = SetCommState(ComPortHandle, &ControlSettings);
|
bool Success = SetCommState(ComPortHandle, &ControlSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gs_const_string_array
|
||||||
|
Win32SerialPorts_List(gs_memory_arena* Arena, gs_memory_arena* Transient)
|
||||||
|
{
|
||||||
|
gs_const_string_array Result = {};
|
||||||
|
|
||||||
|
DWORD SizeNeeded0 = 0;
|
||||||
|
DWORD CountReturned0 = 0;
|
||||||
|
EnumPorts(NULL, 1, 0, 0, &SizeNeeded0, &CountReturned0);
|
||||||
|
Assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
|
||||||
|
DWORD SizeNeeded1 = 0;
|
||||||
|
DWORD CountReturned1 = 0;
|
||||||
|
PORT_INFO_1* PortsArray = (PORT_INFO_1*)PushSize(Transient, SizeNeeded0);
|
||||||
|
if (EnumPorts(NULL,
|
||||||
|
1,
|
||||||
|
(u8*)PortsArray,
|
||||||
|
SizeNeeded0,
|
||||||
|
&SizeNeeded1,
|
||||||
|
&CountReturned1))
|
||||||
|
{
|
||||||
|
Result.CountMax = (u64)CountReturned1;
|
||||||
|
Result.Strings = PushArray(Arena, gs_const_string, Result.CountMax);
|
||||||
|
|
||||||
|
for (; Result.Count < Result.CountMax; Result.Count++)
|
||||||
|
{
|
||||||
|
u64 Index = Result.Count;
|
||||||
|
u64 StrLen = CStringLength(PortsArray[Index].pName);
|
||||||
|
gs_string Str = PushString(Arena, StrLen);
|
||||||
|
PrintF(&Str, "%.*s", StrLen, PortsArray[Index].pName);
|
||||||
|
Result.Strings[Result.Count] = Str.ConstString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Win32SerialPort_Exists(char* PortName, gs_memory_arena* Transient)
|
||||||
|
{
|
||||||
|
bool Result = false;
|
||||||
|
if (PortName != 0)
|
||||||
|
{
|
||||||
|
gs_const_string PortIdent = ConstString(PortName);
|
||||||
|
u32 IdentBegin = FindLast(PortIdent, '\\') + 1;
|
||||||
|
PortIdent = Substring(PortIdent, IdentBegin, PortIdent.Length);
|
||||||
|
|
||||||
|
gs_const_string_array PortsAvailable = Win32SerialPorts_List(Transient, Transient);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < PortsAvailable.Count; i++)
|
||||||
|
{
|
||||||
|
gs_const_string AvailablePortName = PortsAvailable.Strings[i];
|
||||||
|
if (StringsEqualUpToLength(AvailablePortName, PortIdent, PortIdent.Length))
|
||||||
|
{
|
||||||
|
Result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
Win32SerialPort_Open(char* PortName)
|
Win32SerialPort_Open(char* PortName, gs_memory_arena* Transient)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
HANDLE ComPortHandle = INVALID_HANDLE_VALUE;;
|
HANDLE ComPortHandle = INVALID_HANDLE_VALUE;;
|
||||||
|
|
||||||
WIN32_FIND_DATA FindData;
|
if (Win32SerialPort_Exists(PortName, Transient))
|
||||||
HANDLE ComPortExists = FindFirstFile(PortName, &FindData);
|
|
||||||
|
|
||||||
// TODO(PS): we aren't sure yet if FindFirstFile will actually work
|
|
||||||
// for the purpose of checking to see if a ComPort actually exists.
|
|
||||||
// When you go to Foldspace next time, make sure we are still connecting
|
|
||||||
// the sculpture
|
|
||||||
if (ComPortExists != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
ComPortHandle = CreateFile(PortName,
|
ComPortHandle = CreateFile(PortName,
|
||||||
|
@ -289,7 +343,7 @@ Win32SerialArray_Get(gs_const_string PortName)
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits, gs_memory_arena* Transient)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
@ -297,7 +351,7 @@ Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize,
|
||||||
if (PortHandle == INVALID_HANDLE_VALUE)
|
if (PortHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Assert(IsNullTerminated(PortName));
|
Assert(IsNullTerminated(PortName));
|
||||||
PortHandle = Win32SerialPort_Open(PortName.Str);
|
PortHandle = Win32SerialPort_Open(PortName.Str, Transient);
|
||||||
if (PortHandle != INVALID_HANDLE_VALUE)
|
if (PortHandle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Win32SerialPort_SetState(PortHandle, BaudRate, ByteSize, Parity, StopBits);
|
Win32SerialPort_SetState(PortHandle, BaudRate, ByteSize, Parity, StopBits);
|
||||||
|
|
|
@ -43,6 +43,9 @@ MessageQueue_Write(blumen_network_msg_queue* Queue, gs_data Msg)
|
||||||
Assert(Msg.Size <= DEFAULT_QUEUE_ENTRY_SIZE);
|
Assert(Msg.Size <= DEFAULT_QUEUE_ENTRY_SIZE);
|
||||||
|
|
||||||
u32 Index = Queue->WriteHead;
|
u32 Index = Queue->WriteHead;
|
||||||
|
Assert(Index >= 0 &&
|
||||||
|
Index < BLUMEN_MESSAGE_QUEUE_COUNT);
|
||||||
|
|
||||||
gs_data* Dest = Queue->Buffers + Index;
|
gs_data* Dest = Queue->Buffers + Index;
|
||||||
CopyMemoryTo(Msg.Memory, Dest->Memory, Msg.Size);
|
CopyMemoryTo(Msg.Memory, Dest->Memory, Msg.Size);
|
||||||
Dest->Size = Msg.Size;
|
Dest->Size = Msg.Size;
|
||||||
|
@ -50,7 +53,7 @@ MessageQueue_Write(blumen_network_msg_queue* Queue, gs_data Msg)
|
||||||
// NOTE(pjs): We increment write head at the end of writing so that
|
// NOTE(pjs): We increment write head at the end of writing so that
|
||||||
// a reader thread doesn't pull the message off before we've finished
|
// a reader thread doesn't pull the message off before we've finished
|
||||||
// filling it out
|
// filling it out
|
||||||
Queue->WriteHead++;
|
Queue->WriteHead = (Queue->WriteHead + 1) % BLUMEN_MESSAGE_QUEUE_COUNT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,25 +119,28 @@ BlumenLumen_LoadPatterns(app_state* State)
|
||||||
}
|
}
|
||||||
|
|
||||||
Patterns->Count = 0;
|
Patterns->Count = 0;
|
||||||
Patterns_PushPattern(Patterns, TestPatternOne);
|
Patterns_PushPattern(Patterns, TestPatternOne, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, TestPatternTwo);
|
Patterns_PushPattern(Patterns, TestPatternTwo, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, TestPatternThree);
|
Patterns_PushPattern(Patterns, TestPatternThree, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_AllGreen);
|
Patterns_PushPattern(Patterns, Pattern_AllGreen, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_HueShift);
|
Patterns_PushPattern(Patterns, Pattern_HueShift, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_HueFade);
|
Patterns_PushPattern(Patterns, Pattern_HueFade, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Spots);
|
Patterns_PushPattern(Patterns, Pattern_Spots, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_LighthouseRainbow);
|
Patterns_PushPattern(Patterns, Pattern_LighthouseRainbow, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_SmoothGrowRainbow);
|
Patterns_PushPattern(Patterns, Pattern_SmoothGrowRainbow, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_GrowAndFade);
|
Patterns_PushPattern(Patterns, Pattern_GrowAndFade, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_ColorToWhite);
|
Patterns_PushPattern(Patterns, Pattern_ColorToWhite, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Blue);
|
Patterns_PushPattern(Patterns, Pattern_Blue, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Green);
|
Patterns_PushPattern(Patterns, Pattern_Green, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_FlowerColors);
|
Patterns_PushPattern(Patterns, Pattern_FlowerColors, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_FlowerColorToWhite);
|
Patterns_PushPattern(Patterns, Pattern_FlowerColorToWhite, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_BasicFlowers);
|
Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED);
|
||||||
// 15
|
// 15
|
||||||
Patterns_PushPattern(Patterns, Pattern_Patchy);
|
Patterns_PushPattern(Patterns, Pattern_Wavy, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Leafy);
|
Patterns_PushPattern(Patterns, Pattern_Patchy, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_Leafy, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_LeafyPatchy, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_WavyPatchy, PATTERN_SINGLETHREADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v4
|
internal v4
|
||||||
|
@ -180,46 +186,45 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
gs_const_string SculpturePath = ConstString("data/test_blumen.fold");
|
gs_const_string SculpturePath = ConstString("data/test_blumen.fold");
|
||||||
LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog);
|
LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog);
|
||||||
|
|
||||||
|
#if 0
|
||||||
{ // Animation PLAYGROUND
|
{ // Animation PLAYGROUND
|
||||||
animation Anim0 = {0};
|
animation_desc Desc = {};
|
||||||
Anim0.Name = PushStringF(&State->Permanent, 256, "test_anim_zero");
|
Desc.NameSize = 256;
|
||||||
Anim0.Layers = AnimLayerArray_Create(State->AnimationSystem.Storage, 8);
|
Desc.LayersCount = 8;
|
||||||
Anim0.Blocks_ = AnimBlockArray_Create(State->AnimationSystem.Storage, 8);
|
Desc.BlocksCount = 8;
|
||||||
Anim0.PlayableRange.Min = 0;
|
Desc.MinFrames = 0;
|
||||||
Anim0.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
Desc.MaxFrames = SecondsToFrames(15, State->AnimationSystem);
|
||||||
|
|
||||||
|
animation_desc Desc0 = Desc;
|
||||||
|
Desc.Name = "test_anim_zero";
|
||||||
|
animation Anim0 = Animation_Create(Desc0, &State->AnimationSystem);
|
||||||
Animation_AddLayer(&Anim0, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
Animation_AddLayer(&Anim0, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
||||||
|
|
||||||
Animation_AddBlock(&Anim0, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(15), 0);
|
Animation_AddBlock(&Anim0, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(15), 0);
|
||||||
|
|
||||||
BLState->AnimHandles[0] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim0);
|
BLState->AnimHandles[0] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim0);
|
||||||
|
|
||||||
animation Anim1 = {0};
|
animation_desc Desc1 = Desc;
|
||||||
Anim1.Name = PushStringF(&State->Permanent, 256, "test_anim_one");
|
Desc1.Name = "test_anim_one";
|
||||||
Anim1.Layers = AnimLayerArray_Create(State->AnimationSystem.Storage, 8);
|
animation Anim1 = Animation_Create(Desc1, &State->AnimationSystem);
|
||||||
Anim1.Blocks_ = AnimBlockArray_Create(State->AnimationSystem.Storage, 8);
|
|
||||||
Anim1.PlayableRange.Min = 0;
|
|
||||||
Anim1.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
|
||||||
Animation_AddLayer(&Anim1, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
Animation_AddLayer(&Anim1, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
||||||
|
|
||||||
Animation_AddBlock(&Anim1, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(12), 0);
|
Animation_AddBlock(&Anim1, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(12), 0);
|
||||||
|
|
||||||
BLState->AnimHandles[1] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim1);
|
BLState->AnimHandles[1] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim1);
|
||||||
|
|
||||||
animation Anim2 = {0};
|
animation_desc Desc2 = Desc;
|
||||||
Anim2.Name = PushStringF(&State->Permanent, 256, "i_love_you");
|
Desc2.Name = "i_love_you";
|
||||||
Anim2.Layers = AnimLayerArray_Create(State->AnimationSystem.Storage, 8);
|
animation Anim2 = Animation_Create(Desc2, &State->AnimationSystem);;
|
||||||
Anim2.Blocks_ = AnimBlockArray_Create(State->AnimationSystem.Storage, 8);
|
|
||||||
Anim2.PlayableRange.Min = 0;
|
|
||||||
Anim2.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
|
||||||
Animation_AddLayer(&Anim2, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
Animation_AddLayer(&Anim2, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
||||||
|
Animation_AddBlock(&Anim2, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(20), 0);
|
||||||
Animation_AddBlock(&Anim2, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(16), 0);
|
|
||||||
|
|
||||||
BLState->AnimHandles[2] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim2);
|
BLState->AnimHandles[2] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim2);
|
||||||
|
|
||||||
State->AnimationSystem.ActiveFadeGroup.From = BLState->AnimHandles[2];
|
State->AnimationSystem.ActiveFadeGroup.From = BLState->AnimHandles[2];
|
||||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
|
||||||
} // End Animation Playground
|
} // End Animation Playground
|
||||||
|
#endif
|
||||||
|
animation_handle DemoPatternsAnim = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem,
|
||||||
|
State->Patterns,
|
||||||
|
Context,
|
||||||
|
ConstString("data/demo_patterns.foldanim"));
|
||||||
|
State->AnimationSystem.ActiveFadeGroup.From = DemoPatternsAnim;
|
||||||
|
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||||
|
|
||||||
for (u32 i = 0; i < FLOWER_COLORS_COUNT; i++)
|
for (u32 i = 0; i < FLOWER_COLORS_COUNT; i++)
|
||||||
{
|
{
|
||||||
|
@ -404,6 +409,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Dim the leds based on temp data
|
// Dim the leds based on temp data
|
||||||
|
#define DIM_LED_BRIGHTNESS 1
|
||||||
#if DIM_LED_BRIGHTNESS
|
#if DIM_LED_BRIGHTNESS
|
||||||
for (u32 i = 0; i < State->LedSystem.BuffersCount; i++)
|
for (u32 i = 0; i < State->LedSystem.BuffersCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -417,7 +423,25 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(pjs): dim stem to 50%
|
// TODO(PS): This should really only happen if we think the
|
||||||
|
// flower _might_ be open
|
||||||
|
for (u32 a = 0; a < State->Assemblies.Count; a++)
|
||||||
|
{
|
||||||
|
assembly Assembly = State->Assemblies.Values[a];
|
||||||
|
led_buffer Buffer = State->LedSystem.Buffers[Assembly.LedBufferIndex];
|
||||||
|
|
||||||
|
led_strip_list TopStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("section"), ConstString("inner_bloom"), State->Transient);
|
||||||
|
for (u32 s = 0; s < TopStrips.Count; s++)
|
||||||
|
{
|
||||||
|
u32 SIndex = TopStrips.StripIndices[s];
|
||||||
|
v2_strip Strip = Assembly.Strips[SIndex];
|
||||||
|
for (u32 l = 0; l < Strip.LedCount; l++)
|
||||||
|
{
|
||||||
|
u32 LIndex = Strip.LedLUT[l];
|
||||||
|
Buffer.Colors[LIndex] = {0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Send Status Packet
|
// Send Status Packet
|
||||||
|
|
|
@ -1557,6 +1557,25 @@ FindFirst(gs_string String, char C)
|
||||||
return FindFirst(String.ConstString, 0, C);
|
return FindFirst(String.ConstString, 0, C);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal s64
|
||||||
|
FindLast(char* String, s64 StartIndex, char C)
|
||||||
|
{
|
||||||
|
s64 Result = -1;
|
||||||
|
s64 i = 0;
|
||||||
|
while (String[i] != 0 && i < StartIndex)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (String[i])
|
||||||
|
{
|
||||||
|
if (String[i] == C)
|
||||||
|
{
|
||||||
|
Result = i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
internal s64
|
internal s64
|
||||||
FindLast(gs_const_string String, u64 StartIndex, char C)
|
FindLast(gs_const_string String, u64 StartIndex, char C)
|
||||||
{
|
{
|
||||||
|
|
|
@ -232,7 +232,7 @@ struct u64_array
|
||||||
# define InvalidDefaultCase default: { AssertBreak("invalid default case"); } break;
|
# define InvalidDefaultCase default: { AssertBreak("invalid default case"); } break;
|
||||||
# define StaticAssert(c) \
|
# define StaticAssert(c) \
|
||||||
enum { \
|
enum { \
|
||||||
Glue(gs_AssertFail_, __LINE__) = 1 / (int)(!!(c)), \
|
Glue(gs_AssertFail_, __LINE__) = 1 / (int)(!!(c)), \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define Assert(c)
|
# define Assert(c)
|
||||||
|
@ -560,7 +560,7 @@ struct gs_const_string_array
|
||||||
{
|
{
|
||||||
gs_const_string* Strings;
|
gs_const_string* Strings;
|
||||||
u64 Count;
|
u64 Count;
|
||||||
u64 Used;
|
u64 CountMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gs_string_array
|
struct gs_string_array
|
||||||
|
@ -579,6 +579,27 @@ CStringLength(char* Str)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
CStringsEqual(char* A, char* B)
|
||||||
|
{
|
||||||
|
bool Result = true;
|
||||||
|
|
||||||
|
char* AAt = A;
|
||||||
|
char* BAt = B;
|
||||||
|
while (AAt[0] && BAt[0])
|
||||||
|
{
|
||||||
|
if (AAt[0] != BAt[0])
|
||||||
|
{
|
||||||
|
Result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AAt++;
|
||||||
|
BAt++;
|
||||||
|
}
|
||||||
|
if (AAt[0] != 0 || BAt[0] != 0) { Result = false; }
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
#define StringExpand(str) (int)(str).Length, (str).Str
|
#define StringExpand(str) (int)(str).Length, (str).Str
|
||||||
#define LitString(cstr) gs_const_string{(char*)(cstr), CStringLength((char*)cstr) }
|
#define LitString(cstr) gs_const_string{(char*)(cstr), CStringLength((char*)cstr) }
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ int main(int ArgCount, char** Args)
|
||||||
{
|
{
|
||||||
gs_thread_context Ctx = Win32CreateThreadContext();
|
gs_thread_context Ctx = Win32CreateThreadContext();
|
||||||
|
|
||||||
HANDLE SerialHandle = Win32SerialPort_Open("\\\\.\\COM9");
|
HANDLE SerialHandle = Win32SerialPort_Open("\\\\.\\COM9", Ctx.Transient);
|
||||||
Win32SerialPort_SetState(SerialHandle, 2000000, 8, 0, 1);
|
Win32SerialPort_SetState(SerialHandle, 2000000, 8, 0, 1);
|
||||||
|
|
||||||
gs_const_string OutFileName = ConstString("./serial_dump.data");
|
gs_const_string OutFileName = ConstString("./serial_dump.data");
|
||||||
|
|
Loading…
Reference in New Issue