debug and profiler improvements. implemented sending data to multiple destinations on a per strip basis, rather than a full sculpture basis. new patterns. Added user data to patterns.
This commit is contained in:
parent
914523cb60
commit
4798002dfc
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// File: blumen_lumen.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2021-01-15
|
||||
//
|
||||
#ifndef BLUMEN_LUMEN_H
|
||||
|
||||
typedef struct motor_packet
|
||||
{
|
||||
u8 FlowerPositions[3];
|
||||
} motor_packet;
|
||||
|
||||
|
||||
#define BLUMEN_LUMEN_H
|
||||
#endif // BLUMEN_LUMEN_H
|
|
@ -897,6 +897,8 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer*
|
|||
{
|
||||
animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state);
|
||||
|
||||
ui_FillRect(&State->Interface, PanelBounds, v4{.1f,.1f,.1f,1.f});
|
||||
|
||||
rect2 TimelineBounds, InfoBounds;
|
||||
RectVSplit(PanelBounds, 300, &InfoBounds, &TimelineBounds);
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// File: foldhaus_panel_assembly_debug.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2021-01-15
|
||||
//
|
||||
#ifndef FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H
|
||||
|
||||
GSMetaTag(panel_init);
|
||||
GSMetaTag(panel_type_file_view);
|
||||
internal void
|
||||
AssemblyDebug_Init(panel* Panel, app_state* State, context Context)
|
||||
{
|
||||
}
|
||||
|
||||
GSMetaTag(panel_cleanup);
|
||||
GSMetaTag(panel_type_file_view);
|
||||
internal void
|
||||
AssemblyDebug_Cleanup(panel* Panel, app_state* State)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GSMetaTag(panel_render);
|
||||
GSMetaTag(panel_type_file_view);
|
||||
internal void
|
||||
AssemblyDebug_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||
{
|
||||
ui_interface* Interface = &State->Interface;
|
||||
ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Assembly Debug Layout"));
|
||||
|
||||
State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly);
|
||||
|
||||
State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip);
|
||||
|
||||
|
||||
gs_string OverrideStr = MakeString(OverrideTypeStrings[State->AssemblyDebugState.Override]);
|
||||
if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr))
|
||||
{
|
||||
for (u32 i = 0; i < ADS_Override_Count; i++)
|
||||
{
|
||||
if (ui_Button(Interface, MakeString(OverrideTypeStrings[i])))
|
||||
{
|
||||
State->AssemblyDebugState.Override = (override_type)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
ui_EndLabeledDropdown(Interface);
|
||||
}
|
||||
|
||||
#define FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H
|
||||
#endif // FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H
|
|
@ -37,32 +37,45 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, de
|
|||
|
||||
rect2 Bounds = ui_LayoutRemaining(*Layout);
|
||||
r32 Width = Rect2Width(Bounds);
|
||||
r32 DepthHeight = 64;
|
||||
r32 DepthHeight = 32;
|
||||
|
||||
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
||||
s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles;
|
||||
r32 FrameTotalCycles = (r32)(VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles);
|
||||
|
||||
debug_scope_record_list* ThreadScopeCalls = GetScopeListForThreadInFrame(GlobalDebugServices,
|
||||
VisibleFrame);
|
||||
r32 NextThreadTop = Bounds.Max.y;
|
||||
|
||||
for (s32 t = 0; t < VisibleFrame->ThreadCount; t++)
|
||||
{
|
||||
debug_scope_record_list ThreadCalls = VisibleFrame->ThreadCalls[t];
|
||||
|
||||
gs_string String = PushString(Transient, 256);
|
||||
for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
|
||||
{
|
||||
scope_record* Record = ThreadScopeCalls->Calls + i;
|
||||
scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash);
|
||||
r32 PercentStart = (r32)(Record->StartCycles - FrameStartCycles) / (r32)FrameTotalCycles;
|
||||
r32 PercentEnd = (r32)(Record->EndCycles - FrameStartCycles) / (r32)FrameTotalCycles;
|
||||
|
||||
r32 PixelStart = Bounds.Min.x + (Width * PercentStart);
|
||||
r32 PixelEnd = Bounds.Min.x + (Width * PercentEnd);
|
||||
r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight);
|
||||
r32 ThreadScopeMin = Bounds.Max.y;
|
||||
|
||||
for (s32 i = 0; i < ThreadCalls.Count; i++)
|
||||
{
|
||||
scope_record* Record = ThreadCalls.Calls + i;
|
||||
scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash);
|
||||
s64 OffsetStart = Record->StartCycles - FrameStartCycles;
|
||||
s64 OffsetEnd = Record->EndCycles - FrameStartCycles;
|
||||
r32 PercentStart = (r32)(OffsetStart) / FrameTotalCycles;
|
||||
r32 PercentEnd = (r32)(OffsetEnd) / FrameTotalCycles;
|
||||
r32 PercentWidth = PercentEnd - PercentStart;
|
||||
|
||||
rect2 ScopeBounds = {
|
||||
v2{ PixelStart, MinY },
|
||||
v2{ PixelEnd, MinY + (DepthHeight - 4) }
|
||||
v2{0, 0},
|
||||
v2{PercentWidth * Width, DepthHeight - 4},
|
||||
};
|
||||
v2 Offset = {
|
||||
Bounds.Min.x + (PercentStart * Width),
|
||||
NextThreadTop - ((Record->CallDepth + 1) * DepthHeight)
|
||||
};
|
||||
ScopeBounds = Rect2Translate(ScopeBounds, Offset);
|
||||
ThreadScopeMin = Min(ScopeBounds.Min.y, ThreadScopeMin);
|
||||
|
||||
if (Rect2Width(ScopeBounds) >= 1)
|
||||
{
|
||||
v4 Color = ThreadColors[0];
|
||||
v4 Color = ThreadColors[t];
|
||||
if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
|
||||
{
|
||||
Color = GreenV4;
|
||||
|
@ -70,7 +83,7 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, de
|
|||
ui_BeginMousePopup(Interface, rect2{ 25, 25, 300, 57 }, LayoutDirection_TopDown, MakeString("Hover"));
|
||||
{
|
||||
s64 Cycles = (Record->EndCycles - Record->StartCycles);
|
||||
r64 PercentFrame = (r64)(Cycles) / (r64)(FrameTotalCycles);
|
||||
r32 PercentFrame = (r32)(Cycles) / FrameTotalCycles;
|
||||
PrintF(&String, "%S : %.2f%% frame | %dcy",
|
||||
Name->Name,
|
||||
PercentFrame,
|
||||
|
@ -84,6 +97,9 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, de
|
|||
ui_OutlineRect(Interface, ScopeBounds, 1, BlackV4);
|
||||
}
|
||||
}
|
||||
|
||||
NextThreadTop = ThreadScopeMin;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Creation Date: 2020-10-17
|
||||
//
|
||||
#ifndef FOLDHAUS_PANEL_TYPES_CPP
|
||||
global s32 GlobalPanelDefsCount = 6;
|
||||
global s32 GlobalPanelDefsCount = 7;
|
||||
global panel_definition GlobalPanelDefs[] = {
|
||||
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
|
||||
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
|
||||
|
@ -12,6 +12,7 @@ global panel_definition GlobalPanelDefs[] = {
|
|||
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
|
||||
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
|
||||
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
|
||||
{ "Assembly Debug", 14, AssemblyDebug_Init, AssemblyDebug_Cleanup, AssemblyDebug_Render, 0, 0 },
|
||||
};
|
||||
#define FOLDHAUS_PANEL_TYPES_CPP
|
||||
#endif // FOLDHAUS_PANEL_TYPES_CPP
|
|
@ -12,6 +12,7 @@ enum panel_type {
|
|||
PanelType_HierarchyView,
|
||||
PanelType_NodeGraph,
|
||||
PanelType_ProfilerView,
|
||||
PanelType_AssemblyDebug,
|
||||
};
|
||||
#define FOLDHAUS_PANEL_TYPES_H
|
||||
#endif // FOLDHAUS_PANEL_TYPES_H
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
#ifndef FOLDHAUS_ANIMATION
|
||||
|
||||
#define ANIMATION_PROC(name) void name(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
#define ANIMATION_PROC(name) void name(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
typedef ANIMATION_PROC(animation_proc);
|
||||
|
||||
struct frame_range
|
||||
|
|
|
@ -81,20 +81,22 @@ LedBlend_GetProc(blend_mode BlendMode)
|
|||
}
|
||||
|
||||
internal void
|
||||
AnimationSystem_RenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, assembly Assembly, animation_pattern_array Patterns, gs_memory_arena* Transient)
|
||||
AnimationSystem_RenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, assembly Assembly, animation_pattern_array Patterns, gs_memory_arena* Transient,
|
||||
u8* UserData)
|
||||
{
|
||||
u32 FramesIntoBlock = System->CurrentFrame - Block.Range.Min;
|
||||
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
|
||||
|
||||
animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle);
|
||||
Pattern.Proc(Buffer, Assembly, SecondsIntoBlock, Transient);
|
||||
Pattern.Proc(Buffer, Assembly, SecondsIntoBlock, Transient, UserData);
|
||||
}
|
||||
|
||||
internal void
|
||||
AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Assemblies,
|
||||
led_system* LedSystem,
|
||||
animation_pattern_array Patterns,
|
||||
gs_memory_arena* Transient)
|
||||
gs_memory_arena* Transient,
|
||||
u8* UserData)
|
||||
{
|
||||
s32 CurrentFrame = System->CurrentFrame;
|
||||
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
|
||||
|
@ -148,14 +150,14 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
|
|||
{
|
||||
led_buffer TempBuffer = LayerBuffers[Layer].HotBuffer;
|
||||
animation_block Block = LayerFrame.Hot;
|
||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient);
|
||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient, UserData);
|
||||
}
|
||||
|
||||
if (LayerFrame.HasNextHot)
|
||||
{
|
||||
led_buffer TempBuffer = LayerBuffers[Layer].NextHotBuffer;
|
||||
animation_block Block = LayerFrame.NextHot;
|
||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient);
|
||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient, UserData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,6 @@ struct assembly_array
|
|||
assembly* Values;
|
||||
};
|
||||
|
||||
|
||||
internal led_buffer*
|
||||
LedSystemGetBuffer(led_system* System, u32 Index)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
//
|
||||
// File: foldhaus_assembly_debug.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2021-01-15
|
||||
//
|
||||
#ifndef FOLDHAUS_ASSEMBLY_DEBUG_H
|
||||
|
||||
enum override_type
|
||||
{
|
||||
ADS_Override_None,
|
||||
|
||||
ADS_Override_Strip,
|
||||
ADS_Override_SoloStrip,
|
||||
ADS_Override_AllRed,
|
||||
ADS_Override_AllGreen,
|
||||
ADS_Override_AllBlue,
|
||||
|
||||
ADS_Override_Count,
|
||||
};
|
||||
|
||||
global gs_const_string OverrideTypeStrings[] = {
|
||||
LitString("Override_None"),
|
||||
LitString("Override_Strip"),
|
||||
LitString("Override_SoloStrip" ),
|
||||
LitString("Override_AllRed" ),
|
||||
LitString("Override_AllGreen" ),
|
||||
LitString("Override_AllBlue" ),
|
||||
LitString("Override_Count"),
|
||||
};
|
||||
|
||||
struct assembly_debug_state
|
||||
{
|
||||
override_type Override;
|
||||
u32 TargetAssembly;
|
||||
u32 TargetStrip;
|
||||
pixel TargetColor;
|
||||
};
|
||||
|
||||
internal void
|
||||
AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assemblies, led_system LedSystem)
|
||||
{
|
||||
if (State.Override == ADS_Override_None) return;
|
||||
State.TargetColor = pixel{255,255,255};
|
||||
|
||||
assembly Assembly = Assemblies.Values[State.TargetAssembly];
|
||||
led_buffer LedBuffer = LedSystem.Buffers[Assembly.LedBufferIndex];
|
||||
|
||||
switch (State.Override)
|
||||
{
|
||||
case ADS_Override_Strip:
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[State.TargetStrip];
|
||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||
{
|
||||
u32 LedIdx = Strip.LedLUT[i];
|
||||
LedBuffer.Colors[LedIdx] = State.TargetColor;
|
||||
}
|
||||
}break;
|
||||
|
||||
case ADS_Override_SoloStrip:
|
||||
{
|
||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[s];
|
||||
|
||||
pixel Color = pixel{0,0,0};
|
||||
if (s == State.TargetStrip)
|
||||
{
|
||||
Color = State.TargetColor;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||
{
|
||||
u32 LedIdx = Strip.LedLUT[i];
|
||||
LedBuffer.Colors[LedIdx] = Color;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case ADS_Override_AllRed:
|
||||
{
|
||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[s];
|
||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||
{
|
||||
u32 LedIdx = Strip.LedLUT[i];
|
||||
LedBuffer.Colors[LedIdx] = pixel{255, 0, 0};
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case ADS_Override_AllGreen:
|
||||
{
|
||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[s];
|
||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||
{
|
||||
u32 LedIdx = Strip.LedLUT[i];
|
||||
LedBuffer.Colors[LedIdx] = pixel{0, 255, 0};
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case ADS_Override_AllBlue:
|
||||
{
|
||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[s];
|
||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||
{
|
||||
u32 LedIdx = Strip.LedLUT[i];
|
||||
LedBuffer.Colors[LedIdx] = pixel{0, 0, 255};
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case ADS_Override_None:
|
||||
{
|
||||
}break;
|
||||
|
||||
InvalidDefaultCase;
|
||||
}
|
||||
|
||||
if (State.Override )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define FOLDHAUS_ASSEMBLY_DEBUG_H
|
||||
#endif // FOLDHAUS_ASSEMBLY_DEBUG_H
|
|
@ -56,7 +56,7 @@ UART_DrawAll_Create(gs_memory_cursor* WriteCursor)
|
|||
}
|
||||
|
||||
internal void
|
||||
UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem)
|
||||
UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem, gs_memory_arena* Transient)
|
||||
{
|
||||
uart_channel ChannelSettings = {0};
|
||||
ChannelSettings.ElementsCount = 3;
|
||||
|
@ -71,17 +71,82 @@ UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assembli
|
|||
assembly Assembly = Assemblies.Values[AssemblyIdx];
|
||||
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex);
|
||||
|
||||
u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages
|
||||
TotalBufferSize += MessageBaseSize; // DrawAll message
|
||||
TotalBufferSize += ChannelSettings.ElementsCount * Assembly.LedCountTotal; // pixels * channels per pixel
|
||||
struct strips_to_data_buffer
|
||||
{
|
||||
gs_const_string ComPort;
|
||||
u32* StripIndices;
|
||||
u32 StripIndicesCount;
|
||||
u32 StripIndicesCountMax;
|
||||
|
||||
addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize);
|
||||
AddressedDataBuffer_SetCOMPort(Buffer, Assembly.UARTComPort.ConstString);
|
||||
gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data);
|
||||
u64 LedCount;
|
||||
|
||||
strips_to_data_buffer* Next;
|
||||
};
|
||||
|
||||
strips_to_data_buffer* BuffersNeededHead = 0;
|
||||
strips_to_data_buffer* BuffersNeededTail = 0;
|
||||
|
||||
for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++)
|
||||
{
|
||||
v2_strip StripAt = Assembly.Strips[StripIdx];
|
||||
|
||||
// If there is a buffer for this com port already created
|
||||
// we use that
|
||||
strips_to_data_buffer* BufferSelected = 0;
|
||||
for (strips_to_data_buffer* At = BuffersNeededHead;
|
||||
At!= 0;
|
||||
At = At->Next)
|
||||
{
|
||||
if (StringsEqual(At->ComPort, StripAt.UARTAddr.ComPort.ConstString))
|
||||
{
|
||||
BufferSelected = At;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no existing buffer for this com port
|
||||
// create a new one
|
||||
if (!BufferSelected)
|
||||
{
|
||||
BufferSelected = PushStruct(Transient, strips_to_data_buffer);
|
||||
*BufferSelected = {};
|
||||
BufferSelected->ComPort = StripAt.UARTAddr.ComPort.ConstString;
|
||||
// we don't know at this point how many indices per
|
||||
// com port so just make enough room to fit all the strips
|
||||
// if necessary
|
||||
BufferSelected->StripIndicesCountMax = Assembly.StripCount;
|
||||
BufferSelected->StripIndices = PushArray(Transient, u32, BufferSelected->StripIndicesCountMax);
|
||||
BufferSelected->LedCount = 0;
|
||||
BufferSelected->Next = 0;
|
||||
|
||||
SLLPushOrInit(BuffersNeededHead, BuffersNeededTail, BufferSelected);
|
||||
}
|
||||
|
||||
Assert(BufferSelected->StripIndicesCount < BufferSelected->StripIndicesCountMax);
|
||||
u32 Index = BufferSelected->StripIndicesCount++;
|
||||
BufferSelected->StripIndices[Index] = StripIdx;
|
||||
BufferSelected->LedCount += StripAt.LedCount;
|
||||
}
|
||||
|
||||
for (strips_to_data_buffer* At = BuffersNeededHead;
|
||||
At!= 0;
|
||||
At = At->Next)
|
||||
{
|
||||
u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages
|
||||
TotalBufferSize += MessageBaseSize; // DrawAll message
|
||||
TotalBufferSize += ChannelSettings.ElementsCount * At->LedCount; // pixels * channels per pixel
|
||||
|
||||
addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize);
|
||||
gs_const_string ComPort = At->ComPort;
|
||||
AddressedDataBuffer_SetCOMPort(Buffer, ComPort);
|
||||
|
||||
gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data);
|
||||
|
||||
for (u32 i = 0; i < At->StripIndicesCount; i++)
|
||||
{
|
||||
u32 StripIdx = At->StripIndices[i];
|
||||
v2_strip StripAt = Assembly.Strips[StripIdx];
|
||||
|
||||
ChannelSettings.PixelsCount = StripAt.LedCount;
|
||||
UART_SetChannelBuffer_Create(&WriteCursor, ChannelSettings, StripAt, *LedBuffer);
|
||||
}
|
||||
|
@ -89,6 +154,7 @@ UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assembli
|
|||
UART_DrawAll_Create(&WriteCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define FOLDHAUS_UART_CPP
|
||||
|
|
|
@ -25,6 +25,7 @@ ClearAndPushPatterns(animation_pattern_array* Patterns)
|
|||
Patterns_PushPattern(Patterns, Pattern_Spots);
|
||||
Patterns_PushPattern(Patterns, Pattern_LighthouseRainbow);
|
||||
Patterns_PushPattern(Patterns, Pattern_SmoothGrowRainbow);
|
||||
Patterns_PushPattern(Patterns, Pattern_GrowAndFade);
|
||||
}
|
||||
|
||||
RELOAD_STATIC_DATA(ReloadStaticData)
|
||||
|
@ -133,16 +134,20 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
State->Assemblies,
|
||||
&State->LedSystem,
|
||||
State->Patterns,
|
||||
State->Transient);
|
||||
State->Transient,
|
||||
State->UserData.Memory);
|
||||
}
|
||||
|
||||
AssemblyDebug_OverrideOutput(State->AssemblyDebugState,
|
||||
State->Assemblies,
|
||||
State->LedSystem);
|
||||
|
||||
// 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);
|
||||
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient);
|
||||
|
||||
Editor_Render(State, Context, RenderBuffer);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "engine/assembly/foldhaus_assembly.h"
|
||||
#include "engine/assembly/foldhaus_assembly_parser.cpp"
|
||||
#include "engine/assembly/foldhaus_assembly_debug.h"
|
||||
|
||||
#include "engine/sacn/foldhaus_sacn.h"
|
||||
#include "engine/uart/foldhaus_uart.h"
|
||||
|
@ -51,6 +52,7 @@ struct app_state
|
|||
streaming_acn SACN;
|
||||
led_system LedSystem;
|
||||
assembly_array Assemblies;
|
||||
assembly_debug_state AssemblyDebugState;
|
||||
animation_system AnimationSystem;
|
||||
event_log* GlobalLog;
|
||||
animation_pattern_array Patterns;
|
||||
|
@ -65,411 +67,17 @@ struct app_state
|
|||
ui_interface Interface;
|
||||
panel_system PanelSystem;
|
||||
panel* HotPanel;
|
||||
|
||||
// User Space
|
||||
//
|
||||
gs_data UserData;
|
||||
};
|
||||
|
||||
internal void OpenColorPicker(app_state* State, v4* Address);
|
||||
|
||||
#include "engine/assembly/foldhaus_assembly.cpp"
|
||||
|
||||
// BEGIN TEMPORARY PATTERNS
|
||||
internal void
|
||||
TestPatternOne(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
led_strip_list BlumenStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Blumen Lumen"), Transient);
|
||||
led_strip_list RadiaStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Radialumia"), Transient);
|
||||
|
||||
for (u32 i = 0; i < BlumenStrips.Count; i++)
|
||||
{
|
||||
u32 StripIndex = BlumenStrips.StripIndices[i];
|
||||
v2_strip StripAt = Assembly.Strips[StripIndex];
|
||||
|
||||
for (u32 j = 0; j < StripAt.LedCount; j++)
|
||||
{
|
||||
u32 LedIndex = StripAt.LedLUT[j];
|
||||
Leds->Colors[LedIndex] = { 255, 0, 0 };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < RadiaStrips.Count; i++)
|
||||
{
|
||||
u32 StripIndex = RadiaStrips.StripIndices[i];
|
||||
v2_strip StripAt = Assembly.Strips[StripIndex];
|
||||
|
||||
for (u32 j = 0; j < StripAt.LedCount; j++)
|
||||
{
|
||||
u32 LedIndex = StripAt.LedLUT[j];
|
||||
Leds->Colors[LedIndex] = { 0, 255, 0 };
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 LedPosition = Leds->Positions[LedIndex];
|
||||
float PercentX = RemapClampedR32(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f);
|
||||
float PercentY = RemapClampedR32(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f);
|
||||
Leds->Colors[LedIndex].R = (u8)(PercentX * 255);
|
||||
Leds->Colors[LedIndex].G = (u8)(PercentY * 255);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
internal void
|
||||
TestPatternTwo(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
r32 PeriodicTime = (Time / PiR32) * 2;
|
||||
|
||||
r32 ZeroOneSin = (SinR32(PeriodicTime) * .5f) + .5f;
|
||||
r32 ZeroOneCos = (CosR32(PeriodicTime) * .5f) + .5f;
|
||||
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
||||
|
||||
v4 Center = v4{0, 0, 0, 1};
|
||||
r32 ThetaZ = Time / 2;
|
||||
v4 Normal = v4{CosR32(ThetaZ), 0, SinR32(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
||||
v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
|
||||
|
||||
v4 FrontCenter = Center + (Normal * 25);
|
||||
v4 BackCenter = Center - (Normal * 25);
|
||||
|
||||
r32 OuterRadiusSquared = 1000000;
|
||||
r32 InnerRadiusSquared = 0;
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 Position = Leds->Positions[LedIndex];
|
||||
|
||||
v4 ToFront = Position + FrontCenter;
|
||||
v4 ToBack = Position + BackCenter;
|
||||
|
||||
r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
|
||||
r32 ToBackDotNormal = V4Dot(ToBack, Normal);
|
||||
|
||||
ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
|
||||
ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
|
||||
|
||||
r32 SqDistToCenter = V4MagSquared(Position);
|
||||
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
||||
{
|
||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
||||
{
|
||||
Leds->Colors[LedIndex] = Color;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Leds->Colors[LedIndex] = {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Leds->Colors[LedIndex] = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
TestPatternThree(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
v4 GreenCenter = v4{0, 0, 150, 1};
|
||||
r32 GreenRadius = Abs(SinR32(Time)) * 200;
|
||||
|
||||
v4 TealCenter = v4{0, 0, 150, 1};
|
||||
r32 TealRadius = Abs(SinR32(Time + 1.5)) * 200;
|
||||
|
||||
r32 FadeDist = 35;
|
||||
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 LedPosition = Leds->Positions[LedIndex];
|
||||
u8 Red = 0;
|
||||
u8 Green = 0;
|
||||
u8 Blue = 0;
|
||||
|
||||
r32 GreenDist = Abs(V4Mag(LedPosition - GreenCenter) - GreenRadius);
|
||||
r32 GreenBrightness = Clamp(0.f, FadeDist - Abs(GreenDist), FadeDist);
|
||||
Green = (u8)(GreenBrightness * 255);
|
||||
|
||||
r32 TealDist = Abs(V4Mag(LedPosition - TealCenter) - TealRadius);
|
||||
r32 TealBrightness = Clamp(0.f, FadeDist - Abs(TealDist), FadeDist);
|
||||
Red = (u8)(TealBrightness * 255);
|
||||
Blue = (u8)(TealBrightness * 255);
|
||||
|
||||
Leds->Colors[LedIndex].R = Red;
|
||||
Leds->Colors[LedIndex].B = Green;
|
||||
Leds->Colors[LedIndex].G = Green;
|
||||
}
|
||||
}
|
||||
|
||||
v4 HSVToRGB (v4 In)
|
||||
{
|
||||
float Hue = In.x;
|
||||
/*
|
||||
while (Hue > 360.0f) { Hue -= 360.0f; }
|
||||
while (Hue < 0.0f) { Hue += 360.0f; }
|
||||
*/
|
||||
Hue = ModR32(Hue, 360.0f);
|
||||
if (Hue < 0) { Hue += 360.0f; }
|
||||
if (Hue == MinR32) { Hue = 0; }
|
||||
if (Hue == MaxR32) { Hue = 360; }
|
||||
Assert(Hue >= 0 && Hue < 360);
|
||||
|
||||
float Sat = In.y;
|
||||
float Value = In.z;
|
||||
|
||||
float hh, p, q, t, ff;
|
||||
long i;
|
||||
v4 Result = {};
|
||||
Result.a = In.a;
|
||||
|
||||
if(Sat <= 0.0f) { // < is bogus, just shuts up warnings
|
||||
Result.r = Value;
|
||||
Result.g = Value;
|
||||
Result.b = Value;
|
||||
return Result;
|
||||
}
|
||||
hh = Hue;
|
||||
if(hh >= 360.0f) hh = 0.0f;
|
||||
hh /= 60.0f;
|
||||
i = (long)hh;
|
||||
ff = hh - i;
|
||||
p = Value * (1.0f - Sat);
|
||||
q = Value * (1.0f - (Sat * ff));
|
||||
t = Value * (1.0f - (Sat * (1.0f - ff)));
|
||||
|
||||
switch(i) {
|
||||
case 0:
|
||||
{Result.r = Value;
|
||||
Result.g = t;
|
||||
Result.b = p;
|
||||
}break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
Result.r = q;
|
||||
Result.g = Value;
|
||||
Result.b = p;
|
||||
}break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
Result.r = p;
|
||||
Result.g = Value;
|
||||
Result.b = t;
|
||||
}break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
Result.r = p;
|
||||
Result.g = q;
|
||||
Result.b = Value;
|
||||
}break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
Result.r = t;
|
||||
Result.g = p;
|
||||
Result.b = Value;
|
||||
}break;
|
||||
|
||||
case 5:
|
||||
default:
|
||||
{
|
||||
Result.r = Value;
|
||||
Result.g = p;
|
||||
Result.b = q;
|
||||
}break;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
r32 Height = SinR32(Time) * 25;
|
||||
|
||||
r32 CycleLength = 5.0f;
|
||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 Pos = Leds->Positions[LedIndex];
|
||||
r32 Dist = Pos.y - Height;
|
||||
|
||||
v4 HSV = { (ModR32(Dist, 25) / 25) * 360, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
u8 R = (u8)(RGB.x * 255);
|
||||
u8 G = (u8)(RGB.y * 255);
|
||||
u8 B = (u8)(RGB.z * 255);
|
||||
|
||||
Leds->Colors[LedIndex].R = R;
|
||||
Leds->Colors[LedIndex].G = G;
|
||||
Leds->Colors[LedIndex].B = B;
|
||||
}
|
||||
}
|
||||
|
||||
internal pixel
|
||||
V4ToRGBPixel(v4 C)
|
||||
{
|
||||
pixel Result = {};
|
||||
Result.R = (u8)(C.x * 255);
|
||||
Result.G = (u8)(C.y * 255);
|
||||
Result.B = (u8)(C.z * 255);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
r32 HueBase = ModR32(Time * 50, 360);
|
||||
|
||||
r32 CycleLength = 5.0f;
|
||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 Pos = Leds->Positions[LedIndex];
|
||||
r32 Hue = HueBase + Pos.y + Pos.x;
|
||||
v4 HSV = { Hue, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_AllGreen(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
u32 I = LedIndex + 1;
|
||||
Leds->Colors[LedIndex] = {};
|
||||
if (I % 3 == 0)
|
||||
{
|
||||
Leds->Colors[LedIndex].R = 255;
|
||||
}
|
||||
else if (I % 3 == 1)
|
||||
{
|
||||
Leds->Colors[LedIndex].G = 255;
|
||||
}
|
||||
else if (I % 3 == 2)
|
||||
{
|
||||
Leds->Colors[LedIndex].B = 255;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal r32
|
||||
PatternHash(r32 Seed)
|
||||
{
|
||||
return FractR32(Seed * 17.0 * FractR32(Seed * 0.3183099));
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_Spots(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
pixel ColorA = { 0, 255, 255 };
|
||||
pixel ColorB = { 255, 0, 255 };
|
||||
|
||||
r32 Speed = .5f;
|
||||
Time *= Speed;
|
||||
r32 ScaleA = 2 * SinR32(Time / 5);
|
||||
r32 ScaleB = 2.4f * CosR32(Time / 2.5f);
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 P = Leds->Positions[LedIndex];
|
||||
r32 V = P.y;
|
||||
r32 Noise = .3f * PatternHash(V);
|
||||
r32 ThetaY = (Leds->Positions[LedIndex].y / 10) + Time + Noise;
|
||||
r32 ThetaX = (Leds->Positions[LedIndex].x / 13) + Time + Noise;
|
||||
r32 Fade = (ScaleA * SinR32(ThetaY)) + (ScaleB * CosR32(3 * ThetaX));
|
||||
Fade = RemapClampedR32(Fade, -1, 1, 0, 1);
|
||||
|
||||
Leds->Colors[LedIndex].R = (u8)LerpR32(Fade, ColorA.R, ColorB.R);
|
||||
Leds->Colors[LedIndex].G = (u8)LerpR32(Fade, ColorA.G, ColorB.G);
|
||||
Leds->Colors[LedIndex].B = (u8)LerpR32(Fade, ColorA.B, ColorB.B);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_LighthouseRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v2 Vector = v2{
|
||||
Leds->Positions[LedIndex].x,
|
||||
Leds->Positions[LedIndex].z
|
||||
};
|
||||
Vector = V2Normalize(Vector);
|
||||
|
||||
r32 Angle = V2Dot(RefVector, Vector);
|
||||
|
||||
#if 0
|
||||
r32 Fade = RemapR32(Angle, -1, 1, 0, 1);
|
||||
Leds->Colors[LedIndex].R = (u8)(Fade * 255);
|
||||
Leds->Colors[LedIndex].G = (u8)(Fade * 255);
|
||||
Leds->Colors[LedIndex].B = (u8)(Fade * 255);
|
||||
#endif
|
||||
|
||||
v4 HSV = { (Angle * 30) + (Time * 10) + Leds->Positions[LedIndex].y, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||
}
|
||||
}
|
||||
|
||||
internal r32
|
||||
Smoothstep(r32 T)
|
||||
{
|
||||
r32 Result = (T * T * (3 - (2 * T)));
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
||||
{
|
||||
r32 FillCycleTime = ModR32(Time, 7.0f) / 7.0f;
|
||||
r32 ColorCycleTime = ModR32(Time, 21.0f) / 21.0f;
|
||||
|
||||
//v4 HSV = { ColorCycleTime * 360, 1, 1, 1 };
|
||||
//v4 RGB0 = HSVToRGB(HSV);
|
||||
//HSV.x += ;
|
||||
//v4 RGB1 = HSVToRGB(HSV);
|
||||
|
||||
v4 HSV = { 0, 1, 1, 1 };
|
||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[s];
|
||||
|
||||
v4 RGB0 = HSVToRGB(HSV);
|
||||
for (u32 l = 0; l < Strip.LedCount; l++)
|
||||
{
|
||||
u32 LedIndex = Strip.LedLUT[l];
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB0);
|
||||
}
|
||||
|
||||
HSV.x += 15;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 P = Leds->Positions[LedIndex];
|
||||
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB0);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// END TEMPORARY PATTERNS
|
||||
#include "patterns/blumen_patterns.h"
|
||||
|
||||
internal void
|
||||
EndCurrentOperationMode(app_state* State)
|
||||
|
@ -485,6 +93,7 @@ EndCurrentOperationMode(app_state* State)
|
|||
#include "editor/panels/foldhaus_panel_dmx_view.h"
|
||||
#include "editor/panels/foldhaus_panel_animation_timeline.h"
|
||||
#include "editor/panels/foldhaus_panel_hierarchy.h"
|
||||
#include "editor/panels/foldhaus_panel_assembly_debug.h"
|
||||
|
||||
|
||||
#include "editor/panels/foldhaus_panel_types.cpp"
|
||||
|
|
|
@ -148,7 +148,7 @@ typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint);
|
|||
|
||||
// Worker Threads
|
||||
|
||||
#define PLATFORM_THREAD_COUNT 0
|
||||
#define PLATFORM_THREAD_COUNT 3
|
||||
|
||||
RESET_WORK_QUEUE(ResetWorkQueue)
|
||||
{
|
||||
|
|
|
@ -1513,11 +1513,35 @@ ui_EndMousePopup(ui_interface* Interface)
|
|||
}
|
||||
|
||||
//
|
||||
internal void
|
||||
ui_BeginLabelRow(ui_interface* Interface, gs_string Label, u32 Count = 2)
|
||||
{
|
||||
ui_BeginRow(Interface, Count);
|
||||
ui_Label(Interface, Label);
|
||||
}
|
||||
|
||||
internal bool
|
||||
ui_LabeledToggle(ui_interface* Interface, gs_string Label, bool Value)
|
||||
{
|
||||
ui_BeginLabelRow(Interface, Label);
|
||||
bool Result = ui_Toggle(Interface, Label, Value);
|
||||
ui_EndRow(Interface);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal u64
|
||||
ui_LabeledTextEntryU64(ui_interface* Interface, gs_string Label, u32 Value)
|
||||
{
|
||||
ui_BeginLabelRow(Interface, Label);
|
||||
u64 Result = ui_TextEntryU64(Interface, Label, Value);
|
||||
ui_EndRow(Interface);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal bool
|
||||
ui_BeginLabeledDropdown(ui_interface* Interface, gs_string Label, gs_string DropdownValue)
|
||||
{
|
||||
ui_BeginRow(Interface, 2);
|
||||
ui_Label(Interface, Label);
|
||||
ui_BeginLabelRow(Interface, Label);
|
||||
return ui_BeginDropdown(Interface, DropdownValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,395 @@
|
|||
//
|
||||
// File: blumen_patterns.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2021-01-15
|
||||
//
|
||||
#ifndef BLUMEN_PATTERNS_H
|
||||
|
||||
internal void
|
||||
TestPatternOne(led_buffer* Leds, 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 RadiaStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Radialumia"), Transient);
|
||||
|
||||
for (u32 i = 0; i < BlumenStrips.Count; i++)
|
||||
{
|
||||
u32 StripIndex = BlumenStrips.StripIndices[i];
|
||||
v2_strip StripAt = Assembly.Strips[StripIndex];
|
||||
|
||||
for (u32 j = 0; j < StripAt.LedCount; j++)
|
||||
{
|
||||
u32 LedIndex = StripAt.LedLUT[j];
|
||||
Leds->Colors[LedIndex] = { 255, 0, 0 };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < RadiaStrips.Count; i++)
|
||||
{
|
||||
u32 StripIndex = RadiaStrips.StripIndices[i];
|
||||
v2_strip StripAt = Assembly.Strips[StripIndex];
|
||||
|
||||
for (u32 j = 0; j < StripAt.LedCount; j++)
|
||||
{
|
||||
u32 LedIndex = StripAt.LedLUT[j];
|
||||
Leds->Colors[LedIndex] = { 0, 255, 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
TestPatternTwo(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
r32 PeriodicTime = (Time / PiR32) * 2;
|
||||
|
||||
r32 ZeroOneSin = (SinR32(PeriodicTime) * .5f) + .5f;
|
||||
r32 ZeroOneCos = (CosR32(PeriodicTime) * .5f) + .5f;
|
||||
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
||||
|
||||
v4 Center = v4{0, 0, 0, 1};
|
||||
r32 ThetaZ = Time / 2;
|
||||
v4 Normal = v4{CosR32(ThetaZ), 0, SinR32(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
||||
v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
|
||||
|
||||
v4 FrontCenter = Center + (Normal * 25);
|
||||
v4 BackCenter = Center - (Normal * 25);
|
||||
|
||||
r32 OuterRadiusSquared = 1000000;
|
||||
r32 InnerRadiusSquared = 0;
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 Position = Leds->Positions[LedIndex];
|
||||
|
||||
v4 ToFront = Position + FrontCenter;
|
||||
v4 ToBack = Position + BackCenter;
|
||||
|
||||
r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
|
||||
r32 ToBackDotNormal = V4Dot(ToBack, Normal);
|
||||
|
||||
ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
|
||||
ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
|
||||
|
||||
r32 SqDistToCenter = V4MagSquared(Position);
|
||||
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
||||
{
|
||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
||||
{
|
||||
Leds->Colors[LedIndex] = Color;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Leds->Colors[LedIndex] = {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Leds->Colors[LedIndex] = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
TestPatternThree(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
v4 GreenCenter = v4{0, 0, 150, 1};
|
||||
r32 GreenRadius = Abs(SinR32(Time)) * 200;
|
||||
|
||||
v4 TealCenter = v4{0, 0, 150, 1};
|
||||
r32 TealRadius = Abs(SinR32(Time + 1.5)) * 200;
|
||||
|
||||
r32 FadeDist = 35;
|
||||
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 LedPosition = Leds->Positions[LedIndex];
|
||||
u8 Red = 0;
|
||||
u8 Green = 0;
|
||||
u8 Blue = 0;
|
||||
|
||||
r32 GreenDist = Abs(V4Mag(LedPosition - GreenCenter) - GreenRadius);
|
||||
r32 GreenBrightness = Clamp(0.f, FadeDist - Abs(GreenDist), FadeDist);
|
||||
Green = (u8)(GreenBrightness * 255);
|
||||
|
||||
r32 TealDist = Abs(V4Mag(LedPosition - TealCenter) - TealRadius);
|
||||
r32 TealBrightness = Clamp(0.f, FadeDist - Abs(TealDist), FadeDist);
|
||||
Red = (u8)(TealBrightness * 255);
|
||||
Blue = (u8)(TealBrightness * 255);
|
||||
|
||||
Leds->Colors[LedIndex].R = Red;
|
||||
Leds->Colors[LedIndex].B = Green;
|
||||
Leds->Colors[LedIndex].G = Green;
|
||||
}
|
||||
}
|
||||
|
||||
v4 HSVToRGB (v4 In)
|
||||
{
|
||||
float Hue = In.x;
|
||||
/*
|
||||
while (Hue > 360.0f) { Hue -= 360.0f; }
|
||||
while (Hue < 0.0f) { Hue += 360.0f; }
|
||||
*/
|
||||
Hue = ModR32(Hue, 360.0f);
|
||||
if (Hue < 0) { Hue += 360.0f; }
|
||||
if (Hue == MinR32) { Hue = 0; }
|
||||
if (Hue == MaxR32) { Hue = 360; }
|
||||
Assert(Hue >= 0 && Hue < 360);
|
||||
|
||||
float Sat = In.y;
|
||||
float Value = In.z;
|
||||
|
||||
float hh, p, q, t, ff;
|
||||
long i;
|
||||
v4 Result = {};
|
||||
Result.a = In.a;
|
||||
|
||||
if(Sat <= 0.0f) { // < is bogus, just shuts up warnings
|
||||
Result.r = Value;
|
||||
Result.g = Value;
|
||||
Result.b = Value;
|
||||
return Result;
|
||||
}
|
||||
hh = Hue;
|
||||
if(hh >= 360.0f) hh = 0.0f;
|
||||
hh /= 60.0f;
|
||||
i = (long)hh;
|
||||
ff = hh - i;
|
||||
p = Value * (1.0f - Sat);
|
||||
q = Value * (1.0f - (Sat * ff));
|
||||
t = Value * (1.0f - (Sat * (1.0f - ff)));
|
||||
|
||||
switch(i) {
|
||||
case 0:
|
||||
{Result.r = Value;
|
||||
Result.g = t;
|
||||
Result.b = p;
|
||||
}break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
Result.r = q;
|
||||
Result.g = Value;
|
||||
Result.b = p;
|
||||
}break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
Result.r = p;
|
||||
Result.g = Value;
|
||||
Result.b = t;
|
||||
}break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
Result.r = p;
|
||||
Result.g = q;
|
||||
Result.b = Value;
|
||||
}break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
Result.r = t;
|
||||
Result.g = p;
|
||||
Result.b = Value;
|
||||
}break;
|
||||
|
||||
case 5:
|
||||
default:
|
||||
{
|
||||
Result.r = Value;
|
||||
Result.g = p;
|
||||
Result.b = q;
|
||||
}break;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
r32 Height = SinR32(Time) * 25;
|
||||
|
||||
r32 CycleLength = 5.0f;
|
||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 Pos = Leds->Positions[LedIndex];
|
||||
r32 Dist = Pos.y - Height;
|
||||
|
||||
v4 HSV = { (ModR32(Dist, 25) / 25) * 360, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
u8 R = (u8)(RGB.x * 255);
|
||||
u8 G = (u8)(RGB.y * 255);
|
||||
u8 B = (u8)(RGB.z * 255);
|
||||
|
||||
Leds->Colors[LedIndex].R = R;
|
||||
Leds->Colors[LedIndex].G = G;
|
||||
Leds->Colors[LedIndex].B = B;
|
||||
}
|
||||
}
|
||||
|
||||
internal pixel
|
||||
V4ToRGBPixel(v4 C)
|
||||
{
|
||||
pixel Result = {};
|
||||
Result.R = (u8)(C.x * 255);
|
||||
Result.G = (u8)(C.y * 255);
|
||||
Result.B = (u8)(C.z * 255);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
r32 HueBase = ModR32(Time * 50, 360);
|
||||
|
||||
r32 CycleLength = 5.0f;
|
||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 Pos = Leds->Positions[LedIndex];
|
||||
r32 Hue = HueBase + Pos.y + Pos.x;
|
||||
v4 HSV = { Hue, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_AllGreen(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
u32 I = LedIndex + 1;
|
||||
Leds->Colors[LedIndex] = {};
|
||||
if (I % 3 == 0)
|
||||
{
|
||||
Leds->Colors[LedIndex].R = 255;
|
||||
}
|
||||
else if (I % 3 == 1)
|
||||
{
|
||||
Leds->Colors[LedIndex].G = 255;
|
||||
}
|
||||
else if (I % 3 == 2)
|
||||
{
|
||||
Leds->Colors[LedIndex].B = 255;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal r32
|
||||
PatternHash(r32 Seed)
|
||||
{
|
||||
return FractR32(Seed * 17.0 * FractR32(Seed * 0.3183099));
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_Spots(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
pixel ColorA = { 0, 255, 255 };
|
||||
pixel ColorB = { 255, 0, 255 };
|
||||
|
||||
r32 Speed = .5f;
|
||||
Time *= Speed;
|
||||
r32 ScaleA = 2 * SinR32(Time / 5);
|
||||
r32 ScaleB = 2.4f * CosR32(Time / 2.5f);
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 P = Leds->Positions[LedIndex];
|
||||
r32 V = P.y;
|
||||
r32 Noise = .3f * PatternHash(V);
|
||||
r32 ThetaY = (Leds->Positions[LedIndex].y / 10) + Time + Noise;
|
||||
r32 ThetaX = (Leds->Positions[LedIndex].x / 13) + Time + Noise;
|
||||
r32 Fade = (ScaleA * SinR32(ThetaY)) + (ScaleB * CosR32(3 * ThetaX));
|
||||
Fade = RemapClampedR32(Fade, -1, 1, 0, 1);
|
||||
|
||||
Leds->Colors[LedIndex].R = (u8)LerpR32(Fade, ColorA.R, ColorB.R);
|
||||
Leds->Colors[LedIndex].G = (u8)LerpR32(Fade, ColorA.G, ColorB.G);
|
||||
Leds->Colors[LedIndex].B = (u8)LerpR32(Fade, ColorA.B, ColorB.B);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_LighthouseRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v2 Vector = v2{
|
||||
Leds->Positions[LedIndex].x,
|
||||
Leds->Positions[LedIndex].z
|
||||
};
|
||||
Vector = V2Normalize(Vector);
|
||||
|
||||
r32 Angle = V2Dot(RefVector, Vector);
|
||||
|
||||
v4 HSV = { (Angle * 30) + (Time * 10) + Leds->Positions[LedIndex].y, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||
}
|
||||
}
|
||||
|
||||
internal r32
|
||||
Smoothstep(r32 T)
|
||||
{
|
||||
r32 Result = (T * T * (3 - (2 * T)));
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
r32 FillCycleTime = ModR32(Time, 7.0f) / 7.0f;
|
||||
r32 ColorCycleTime = ModR32(Time, 21.0f) / 21.0f;
|
||||
|
||||
v4 HSV = { 0, 1, 1, 1 };
|
||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||
{
|
||||
v2_strip Strip = Assembly.Strips[s];
|
||||
|
||||
v4 RGB0 = HSVToRGB(HSV);
|
||||
for (u32 l = 0; l < Strip.LedCount; l++)
|
||||
{
|
||||
u32 LedIndex = Strip.LedLUT[l];
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB0);
|
||||
}
|
||||
|
||||
HSV.x += 15;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_GrowAndFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
r32 PercentCycle = ModR32(Time, 10) / 10;
|
||||
v4 HSV = { PercentCycle * 360, 1, 1, 1 };
|
||||
v4 RGB = HSVToRGB(HSV);
|
||||
|
||||
r32 RefHeight = -100 + (Smoothstep(PercentCycle * 1.4f) * 400);
|
||||
r32 RefBrightness = 1.0f - Smoothstep(PercentCycle);
|
||||
|
||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||
{
|
||||
v4 P = Leds->Positions[LedIndex];
|
||||
|
||||
v4 RgbFaded = v4{};
|
||||
if (P.y < RefHeight)
|
||||
{
|
||||
RgbFaded = RGB * RefBrightness;
|
||||
}
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RgbFaded);
|
||||
}
|
||||
}
|
||||
|
||||
#define BLUMEN_PATTERNS_H
|
||||
#endif // BLUMEN_PATTERNS_H
|
|
@ -371,17 +371,13 @@ Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
|
|||
}
|
||||
|
||||
internal void
|
||||
Win32_SendAddressedDataBuffers(gs_thread_context Context, addressed_data_buffer_list OutputData)
|
||||
Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
u32 BuffersSent = 0;
|
||||
u32 DataSizeSent = 0;
|
||||
|
||||
for (addressed_data_buffer* BufferAt = OutputData.Root;
|
||||
BufferAt != 0;
|
||||
BufferAt = BufferAt->Next)
|
||||
{
|
||||
switch(BufferAt->AddressType)
|
||||
{
|
||||
case AddressType_NetworkIP:
|
||||
|
@ -410,7 +406,9 @@ Win32_SendAddressedDataBuffers(gs_thread_context Context, addressed_data_buffer_
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
OutputDebugStringA("Skipping data buffer because its COM Port isn't set");
|
||||
#endif
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -418,17 +416,11 @@ Win32_SendAddressedDataBuffers(gs_thread_context Context, addressed_data_buffer_
|
|||
}
|
||||
}
|
||||
|
||||
gs_string OutputStr = AllocatorAllocString(Context.Allocator, 256);
|
||||
PrintF(&OutputStr, "Buffers Sent: %d | Size Sent: %d\n", BuffersSent, DataSizeSent);
|
||||
NullTerminate(&OutputStr);
|
||||
OutputDebugStringA(OutputStr.Str);
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32_SendAddressedDataBuffers_Job(gs_thread_context Context, gs_data Arg)
|
||||
Win32_SendAddressedDataBuffer_Job(gs_thread_context Context, gs_data Arg)
|
||||
{
|
||||
addressed_data_buffer_list* OutputData = (addressed_data_buffer_list*)Arg.Memory;
|
||||
Win32_SendAddressedDataBuffers(Context, *OutputData);
|
||||
addressed_data_buffer* OutputData = (addressed_data_buffer*)Arg.Memory;
|
||||
Win32_SendAddressedDataBuffer(Context, OutputData);
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -570,11 +562,16 @@ WinMain (
|
|||
ClearRenderBuffer(&RenderBuffer);
|
||||
|
||||
if (true)
|
||||
{
|
||||
for (addressed_data_buffer* At = OutputData.Root;
|
||||
At != 0;
|
||||
At = At->Next)
|
||||
{
|
||||
gs_data ProcArg = {};
|
||||
ProcArg.Memory = (u8*)&OutputData;
|
||||
ProcArg.Size = sizeof(OutputData);
|
||||
Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffers_Job, ProcArg, ConstString("Send UART Data"));
|
||||
ProcArg.Memory = (u8*)At;
|
||||
ProcArg.Size = sizeof(addressed_data_buffer);
|
||||
Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffer_Job, ProcArg, ConstString("Send UART Data"));
|
||||
}
|
||||
}
|
||||
|
||||
Mouse_Advance(&Context);
|
||||
|
@ -583,7 +580,7 @@ WinMain (
|
|||
SwapBuffers(DeviceContext);
|
||||
ReleaseDC(MainWindow.Handle, DeviceContext);
|
||||
|
||||
//Win32DoQueueWorkUntilDone(&WorkQueue, Context.ThreadContext);
|
||||
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
||||
|
||||
s64 FinishedWorkTime = GetWallClock();
|
||||
r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency);
|
||||
|
|
|
@ -175,7 +175,7 @@ int main(int ArgCount, char** Args)
|
|||
100,
|
||||
v3{0, 0, 0},
|
||||
69,
|
||||
ComPort);
|
||||
"");
|
||||
|
||||
u32 StemChannels[] = { FSC(2, 1), FSC(2, 2), FSC(2, 3), FSC(2, 4), FSC(2, 5), FSC(2, 6) };
|
||||
u32 BloomOuterChannels[] = { FSC(1, 0), FSC(1, 1), FSC(1, 2), FSC(1, 3), FSC(1, 4), FSC(1, 5), FSC(1, 6), FSC(1, 7), FSC(2, 0) };
|
||||
|
@ -189,15 +189,16 @@ int main(int ArgCount, char** Args)
|
|||
F0.BloomInnerChannels = BloomInnerChannels;
|
||||
BuildFlower(&OutputBuffer, F0);
|
||||
|
||||
/*
|
||||
flower_desc F1 = {};
|
||||
F1.Pos = v3{0, 0, 0};
|
||||
F1.ComPort = "\\\\.\\COM9";
|
||||
F1.FlowerTagValue = "center";
|
||||
F1.StemChannels = StemChannels;
|
||||
F1.BloomInnerChannels = BloomInnerChannels;
|
||||
F1.BloomOuterChannels = BloomOuterChannels;
|
||||
BuildFlower(&OutputBuffer, F1);
|
||||
|
||||
/*
|
||||
flower_desc F2 = {};
|
||||
F2.Pos = v3{1, 0, 0};
|
||||
F2.FlowerTagValue = "right";
|
||||
|
|
|
@ -28,8 +28,12 @@ WriteAssemblyUARTOpen(gs_string* Buffer, char* Name, u32 Scale, v3 Center, u32 S
|
|||
WriteIndented(Buffer, 0, "assembly_center: (%f, %f, %f);\n", Center.x, Center.y, Center.z);
|
||||
WriteIndented(Buffer, 0, "led_strip_count: %d;\n", StripCount);
|
||||
WriteIndented(Buffer, 0, "output_mode: \"UART\";\n");
|
||||
|
||||
if (ComPort)
|
||||
{
|
||||
WriteIndented(Buffer, 0, "com_port: \"%s\";\n", ComPort);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
WriteLedStripOpen(gs_string* Buffer, u32 Channel, char* ComPort)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// File: test_motor_header.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2021-01-14
|
||||
//
|
||||
#ifndef TEST_MOTOR_HEADER_H
|
||||
|
||||
struct
|
||||
{
|
||||
u8 MotorOnePos;
|
||||
u8 MotorTwoPos;
|
||||
u8 MotorThreePos;
|
||||
} typedef packet;
|
||||
|
||||
static packet
|
||||
UnpackPacket
|
||||
|
||||
#define TEST_MOTOR_HEADER_H
|
||||
#endif // TEST_MOTOR_HEADER_H
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// File: test_sound_interface_packet.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2021-01-14
|
||||
//
|
||||
#ifndef TEST_SOUND_INTERFACE_PACKET_H
|
||||
|
||||
enum selectable_patterns
|
||||
{
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 PrimaryColor[3];
|
||||
u8 SecondaryColor[3];
|
||||
u32 PatternIndex; // Set via selectable_patterns
|
||||
u8 Speed; //
|
||||
} sound_interface_packet;
|
||||
|
||||
// expects V to be in the range -1:1
|
||||
u8 FloatToSpeed (float V)
|
||||
{
|
||||
u8 Result = (u8)(((V + 1) / 2) * 255);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
#define TEST_SOUND_INTERFACE_PACKET_H
|
||||
#endif // TEST_SOUND_INTERFACE_PACKET_H
|
Loading…
Reference in New Issue