more debug functionality.

This commit is contained in:
PS 2021-01-16 16:37:56 -08:00
parent 4798002dfc
commit 35a3793015
8 changed files with 233 additions and 91 deletions

View File

@ -20,6 +20,21 @@ AssemblyDebug_Cleanup(panel* Panel, app_state* State)
} }
// TODO(pjs): This is really blumen specific
#define FSC(f,c) FlowerStripToChannel((f), (c))
internal u8
FlowerStripToChannel(u8 Flower, u8 Channel)
{
Assert(Flower < 3);
Assert(Channel < 8);
u8 Result = 0;
Result |= (Flower & 0x03) << 3;
Result |= (Channel & 0x07);
return Result;
}
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_file_view); GSMetaTag(panel_type_file_view);
internal void internal void
@ -28,11 +43,6 @@ AssemblyDebug_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren
ui_interface* Interface = &State->Interface; ui_interface* Interface = &State->Interface;
ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Assembly Debug Layout")); 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]); gs_string OverrideStr = MakeString(OverrideTypeStrings[State->AssemblyDebugState.Override]);
if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr)) if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr))
{ {
@ -44,7 +54,37 @@ AssemblyDebug_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren
} }
} }
} }
if (State->AssemblyDebugState.Override == ADS_Override_TagWhite ||
State->AssemblyDebugState.Override == ADS_Override_TagStripWhite)
{
ui_LabeledTextEntry(Interface, MakeString("Tag Name"), &State->AssemblyDebugState.TagName);
ui_LabeledTextEntry(Interface, MakeString("Tag Value"), &State->AssemblyDebugState.TagValue);
if (State->AssemblyDebugState.Override == ADS_Override_TagStripWhite)
{
ui_EndLabeledDropdown(Interface); ui_EndLabeledDropdown(Interface);
State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly);
State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip);
}
}
else if (State->AssemblyDebugState.Override == ADS_Override_ChannelWhite)
{
u64 Board = 0;
u64 Strip = 0;
Board = ui_LabeledTextEntryU64(Interface, MakeString("Board"), Board);
Strip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), Strip);
State->AssemblyDebugState.TargetChannel = FSC(Board, Strip);
}
else
{
ui_EndLabeledDropdown(Interface);
State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly);
State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip);
}
} }
#define FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H #define FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H

View File

@ -27,14 +27,6 @@ ProfilerView_Cleanup(panel* Panel, app_state* State)
internal void internal void
RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, debug_frame* VisibleFrame, gs_memory_arena* Transient) RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, debug_frame* VisibleFrame, gs_memory_arena* Transient)
{ {
v4 ThreadColors[] = {
v4{.73f, .33f, .83f, 1},
v4{0, .50f, .50f, 1},
v4{.83f, 0, 0, 1},
v4{.33f, .49f, .83f, 1},
v4{.74f, .40f, .25f, 1},
};
rect2 Bounds = ui_LayoutRemaining(*Layout); rect2 Bounds = ui_LayoutRemaining(*Layout);
r32 Width = Rect2Width(Bounds); r32 Width = Rect2Width(Bounds);
r32 DepthHeight = 32; r32 DepthHeight = 32;
@ -52,6 +44,14 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, de
r32 ThreadScopeMin = Bounds.Max.y; r32 ThreadScopeMin = Bounds.Max.y;
//PrintF(&String, "Thread %d", ThreadCalls.ThreadId);
//ui_Label(Interface, String, rect2{ThreadScopeMin);
r32 Hue = (r32)(t) / (r32)(VisibleFrame->ThreadCount);
Hue += (.5f * (t % 2));
v4 ThreadHSV = v4{ 360.0f * Hue, .5f, 1.0f, 1.0f };
v4 ThreadRGB = HSVToRGB(ThreadHSV);
for (s32 i = 0; i < ThreadCalls.Count; i++) for (s32 i = 0; i < ThreadCalls.Count; i++)
{ {
scope_record* Record = ThreadCalls.Calls + i; scope_record* Record = ThreadCalls.Calls + i;
@ -75,7 +75,7 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, de
if (Rect2Width(ScopeBounds) >= 1) if (Rect2Width(ScopeBounds) >= 1)
{ {
v4 Color = ThreadColors[t]; v4 Color = ThreadRGB;
if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos)) if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
{ {
Color = GreenV4; Color = GreenV4;

View File

@ -256,20 +256,11 @@ AssemblyStripsGetWithTagValue(assembly Assembly, gs_const_string TagName, gs_con
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++) for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
{ {
v2_strip StripAt = Assembly.Strips[StripIndex]; v2_strip StripAt = Assembly.Strips[StripIndex];
for (u32 j = 0; j < StripAt.TagsCount; j++) if (AssemblyStrip_HasTagValue(StripAt, NameHash, ValueHash))
{
v2_tag TagAt = StripAt.Tags[j];
if (TagAt.NameHash == NameHash)
{
// NOTE(pjs): We can pass an empty string to the Value parameter,
// and it will match all values of Tag
if (ValueHash == 0 || ValueHash == TagAt.ValueHash)
{ {
Result.StripIndices[Result.Count++] = StripIndex; Result.StripIndices[Result.Count++] = StripIndex;
} }
} }
}
}
return Result; return Result;
} }

View File

@ -204,5 +204,26 @@ StripGenData_CountLeds(strip_gen_data Data)
return Result; return Result;
} }
internal bool
AssemblyStrip_HasTagValue(v2_strip Strip, u64 NameHash, u64 ValueHash)
{
bool Result = false;
for (u32 i = 0; i < Strip.TagsCount; i++)
{
v2_tag TagAt = Strip.Tags[i];
if (TagAt.NameHash == NameHash)
{
// NOTE(pjs): We can pass an empty string to the Value parameter,
// and it will match all values of Tag
if (ValueHash == 0 || ValueHash == TagAt.ValueHash)
{
Result = true;
break;
}
}
}
return Result;
}
#define FOLDHAUS_ASSEMBLY_H #define FOLDHAUS_ASSEMBLY_H
#endif // FOLDHAUS_ASSEMBLY_H #endif // FOLDHAUS_ASSEMBLY_H

View File

@ -14,6 +14,11 @@ enum override_type
ADS_Override_AllRed, ADS_Override_AllRed,
ADS_Override_AllGreen, ADS_Override_AllGreen,
ADS_Override_AllBlue, ADS_Override_AllBlue,
ADS_Override_AllOff,
ADS_Override_AllWhite,
ADS_Override_TagWhite,
ADS_Override_TagStripWhite,
ADS_Override_ChannelWhite,
ADS_Override_Count, ADS_Override_Count,
}; };
@ -25,17 +30,74 @@ global gs_const_string OverrideTypeStrings[] = {
LitString("Override_AllRed" ), LitString("Override_AllRed" ),
LitString("Override_AllGreen" ), LitString("Override_AllGreen" ),
LitString("Override_AllBlue" ), LitString("Override_AllBlue" ),
LitString("ADS_Override_AllOff" ),
LitString("ADS_Override_AllWhite" ),
LitString("ADS_Override_TagWhite" ),
LitString("ADS_Override_TagStripWhite" ),
LitString("ADS_Override_ChannelWhite," ),
LitString("Override_Count"), LitString("Override_Count"),
}; };
struct assembly_debug_state struct assembly_debug_state
{ {
override_type Override; override_type Override;
u32 TargetAssembly; u32 TargetAssembly;
u32 TargetStrip; u32 TargetStrip;
gs_string TagName;
gs_string TagValue;
pixel TargetColor; pixel TargetColor;
u32 TargetChannel;
}; };
internal assembly_debug_state
AssemblyDebug_Create(gs_memory_arena* Storage)
{
assembly_debug_state Result = {};
Result.TagName = PushString(Storage, 256);
Result.TagValue = PushString(Storage, 256);
return Result;
}
internal void
AssemblyDebug_OverrideStripWithColor(v2_strip Strip, led_buffer LedBuffer, pixel Color)
{
for (u32 i = 0; i < Strip.LedCount; i++)
{
u32 LedIdx = Strip.LedLUT[i];
LedBuffer.Colors[LedIdx] = Color;
}
}
internal void
AssemblyDebug_OverrideWithColor(assembly Assembly, led_buffer LedBuffer, pixel Color)
{
for (u32 s = 0; s < Assembly.StripCount; s++)
{
v2_strip Strip = Assembly.Strips[s];
AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, Color);
}
}
internal void
AssemblyDebug_OverrideTagValueWithColor(assembly Assembly, led_buffer LedBuffer, pixel Color, gs_string TagName, gs_string TagValue)
{
u64 NameHash = HashDJB2ToU32(StringExpand(TagName));
u64 ValueHash = HashDJB2ToU32(StringExpand(TagValue));
for (u32 s = 0; s < Assembly.StripCount; s++)
{
v2_strip Strip = Assembly.Strips[s];
if (AssemblyStrip_HasTagValue(Strip, NameHash, ValueHash))
{
AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, Color);
}
}
}
internal void internal void
AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assemblies, led_system LedSystem) AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assemblies, led_system LedSystem)
{ {
@ -50,11 +112,7 @@ AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assembli
case ADS_Override_Strip: case ADS_Override_Strip:
{ {
v2_strip Strip = Assembly.Strips[State.TargetStrip]; v2_strip Strip = Assembly.Strips[State.TargetStrip];
for (u32 i = 0; i < Strip.LedCount; i++) AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, State.TargetColor);
{
u32 LedIdx = Strip.LedLUT[i];
LedBuffer.Colors[LedIdx] = State.TargetColor;
}
}break; }break;
case ADS_Override_SoloStrip: case ADS_Override_SoloStrip:
@ -69,49 +127,66 @@ AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assembli
Color = State.TargetColor; Color = State.TargetColor;
} }
for (u32 i = 0; i < Strip.LedCount; i++) AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, Color);
{
u32 LedIdx = Strip.LedLUT[i];
LedBuffer.Colors[LedIdx] = Color;
}
} }
}break; }break;
case ADS_Override_AllRed: case ADS_Override_AllRed:
{ {
for (u32 s = 0; s < Assembly.StripCount; s++) AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{255, 0, 0});
{
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; }break;
case ADS_Override_AllGreen: case ADS_Override_AllGreen:
{ {
for (u32 s = 0; s < Assembly.StripCount; s++) AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 255, 0});
{
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; }break;
case ADS_Override_AllBlue: case ADS_Override_AllBlue:
{ {
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 255});
}break;
case ADS_Override_AllOff:
{
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0});
}break;
case ADS_Override_AllWhite:
{
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{255, 255, 255});
}break;
case ADS_Override_TagWhite:
{
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0});
AssemblyDebug_OverrideTagValueWithColor(Assembly, LedBuffer, pixel{255, 255, 255}, State.TagName, State.TagValue);
}break;
case ADS_Override_TagStripWhite:
{
u64 NameHash = HashDJB2ToU32(StringExpand(State.TagName));
u64 ValueHash = HashDJB2ToU32(StringExpand(State.TagValue));
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0});
v2_strip Strip = Assembly.Strips[State.TargetStrip];
if (AssemblyStrip_HasTagValue(Strip, NameHash, ValueHash))
{
AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer,
pixel{255, 255, 255});
}
}break;
case ADS_Override_ChannelWhite:
{
AssemblyDebug_OverrideWithColor(Assembly, LedBuffer, pixel{0, 0, 0});
for (u32 s = 0; s < Assembly.StripCount; s++) for (u32 s = 0; s < Assembly.StripCount; s++)
{ {
v2_strip Strip = Assembly.Strips[s]; v2_strip Strip = Assembly.Strips[s];
for (u32 i = 0; i < Strip.LedCount; i++) if (Strip.UARTAddr.Channel == State.TargetChannel)
{ {
u32 LedIdx = Strip.LedLUT[i]; AssemblyDebug_OverrideStripWithColor(Strip, LedBuffer, pixel{255, 255, 255});
LedBuffer.Colors[LedIdx] = pixel{0, 0, 255};
} }
} }
}break; }break;

View File

@ -75,6 +75,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->SACN = SACN_Initialize(Context); State->SACN = SACN_Initialize(Context);
State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128); State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128);
State->AssemblyDebugState = AssemblyDebug_Create(&State->Permanent);
GlobalDebugServices->Interface.RenderSculpture = true; GlobalDebugServices->Interface.RenderSculpture = true;

View File

@ -981,10 +981,10 @@ ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget, rect2 Bounds)
{ {
ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id);
// TODO(pjs): Backspace?
for (u32 i = 0; i < Interface->TempInputString.Length; i++) for (u32 i = 0; i < Interface->TempInputString.Length; i++)
{ {
if (Interface->TempInputString.Str[i] == '\b') if (Interface->TempInputString.Str[i] == '\b' &&
State->EditString.Length > 0)
{ {
State->EditString.Length -= 1; State->EditString.Length -= 1;
} }
@ -1529,6 +1529,15 @@ ui_LabeledToggle(ui_interface* Interface, gs_string Label, bool Value)
return Result; return Result;
} }
internal void
ui_LabeledTextEntry(ui_interface* Interface, gs_string Label, gs_string* Value)
{
ui_BeginLabelRow(Interface, Label);
ui_TextEntry(Interface, Label, Value);
ui_EndRow(Interface);
}
internal u64 internal u64
ui_LabeledTextEntryU64(ui_interface* Interface, gs_string Label, u32 Value) ui_LabeledTextEntryU64(ui_interface* Interface, gs_string Label, u32 Value)
{ {

View File

@ -102,20 +102,21 @@ typedef struct
internal void internal void
BuildFlower(gs_string* OutputBuffer, flower_desc Desc) BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
{ {
// the flower stem
loop_desc FlowerStem = {}; #if 1
FlowerStem.CenterStart = v3{0, -1.5f, 0} + Desc.Pos; // the bloom stem inner
FlowerStem.CenterEnd = v3{0, .5f, 0} + Desc.Pos; loop_desc BloomStemInner = {};
FlowerStem.Radius = .05f; BloomStemInner.CenterStart = v3{0, 1.4f, 0} + Desc.Pos;
FlowerStem.SegmentsCount = 6; BloomStemInner.CenterEnd = v3{0, .9f, 0} + Desc.Pos;
FlowerStem.SubsegmentsCount = 1; BloomStemInner.Radius = .05f;
FlowerStem.SubsegmentLeds = 300; BloomStemInner.SegmentsCount = 6;
//FlowerStem.ChannelStart = 0; BloomStemInner.SubsegmentsCount = 3;
FlowerStem.ChannelsArray = Desc.StemChannels; BloomStemInner.SubsegmentLeds = 35;
FlowerStem.ComPort = Desc.ComPort; BloomStemInner.ChannelsArray = Desc.BloomInnerChannels;
FlowerStem.SectionTagValue = "stem"; BloomStemInner.ComPort = Desc.ComPort;
FlowerStem.FlowerTagValue = Desc.FlowerTagValue; BloomStemInner.SectionTagValue = "inner_bloom";
BuildLoop(OutputBuffer, FlowerStem); BloomStemInner.FlowerTagValue = Desc.FlowerTagValue;
BuildLoop(OutputBuffer, BloomStemInner);
// the bloom stem outer // the bloom stem outer
loop_desc BloomStemOuter = {}; loop_desc BloomStemOuter = {};
@ -125,27 +126,29 @@ BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
BloomStemOuter.SegmentsCount = 9; BloomStemOuter.SegmentsCount = 9;
BloomStemOuter.SubsegmentsCount = 3; BloomStemOuter.SubsegmentsCount = 3;
BloomStemOuter.SubsegmentLeds = 41; BloomStemOuter.SubsegmentLeds = 41;
//BloomStemOuter.ChannelStart = 7;
BloomStemOuter.ChannelsArray = Desc.BloomOuterChannels; BloomStemOuter.ChannelsArray = Desc.BloomOuterChannels;
BloomStemOuter.ComPort = Desc.ComPort; BloomStemOuter.ComPort = Desc.ComPort;
BloomStemOuter.SectionTagValue = "outer_bloom"; BloomStemOuter.SectionTagValue = "outer_bloom";
BloomStemOuter.FlowerTagValue = Desc.FlowerTagValue; BloomStemOuter.FlowerTagValue = Desc.FlowerTagValue;
BuildLoop(OutputBuffer, BloomStemOuter); BuildLoop(OutputBuffer, BloomStemOuter);
#endif
#if 1
// the flower stem
loop_desc FlowerStem = {};
FlowerStem.CenterStart = v3{0, -1.5f, 0} + Desc.Pos;
FlowerStem.CenterEnd = v3{0, .5f, 0} + Desc.Pos;
FlowerStem.Radius = .05f;
FlowerStem.SegmentsCount = 6;
FlowerStem.SubsegmentsCount = 1;
FlowerStem.SubsegmentLeds = 300;
FlowerStem.ChannelsArray = Desc.StemChannels;
FlowerStem.ComPort = Desc.ComPort;
FlowerStem.SectionTagValue = "stem";
FlowerStem.FlowerTagValue = Desc.FlowerTagValue;
BuildLoop(OutputBuffer, FlowerStem);
#endif
// the bloom stem inner
loop_desc BloomStemInner = {};
BloomStemInner.CenterStart = v3{0, 1.4f, 0} + Desc.Pos;
BloomStemInner.CenterEnd = v3{0, .9f, 0} + Desc.Pos;
BloomStemInner.Radius = .05f;
BloomStemInner.SegmentsCount = 6;
BloomStemInner.SubsegmentsCount = 3;
BloomStemInner.SubsegmentLeds = 35;
//BloomStemInner.ChannelStart = 17;
BloomStemInner.ChannelsArray = Desc.BloomInnerChannels;
BloomStemInner.ComPort = Desc.ComPort;
BloomStemInner.SectionTagValue = "inner_bloom";
BloomStemInner.FlowerTagValue = Desc.FlowerTagValue;
BuildLoop(OutputBuffer, BloomStemInner);
} }
// Just for brevity, no real function provided // Just for brevity, no real function provided
@ -169,7 +172,7 @@ int main(int ArgCount, char** Args)
gs_string OutputBuffer = PushString(Ctx.Transient, MB(4)); gs_string OutputBuffer = PushString(Ctx.Transient, MB(4));
char* ComPort = "\\\\.\\COM8"; char* ComPort = "\\\\.\\COM3";
WriteAssemblyUARTOpen(&OutputBuffer, WriteAssemblyUARTOpen(&OutputBuffer,
"Blumen Lumen - Silver Spring", "Blumen Lumen - Silver Spring",
100, 100,
@ -178,7 +181,7 @@ int main(int ArgCount, char** Args)
""); "");
u32 StemChannels[] = { FSC(2, 1), FSC(2, 2), FSC(2, 3), FSC(2, 4), FSC(2, 5), FSC(2, 6) }; 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) }; 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, 7) };
u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) }; u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) };
flower_desc F0 = {}; flower_desc F0 = {};
F0.Pos = v3{-1, 0, 0}; F0.Pos = v3{-1, 0, 0};
@ -189,14 +192,16 @@ int main(int ArgCount, char** Args)
F0.BloomInnerChannels = BloomInnerChannels; F0.BloomInnerChannels = BloomInnerChannels;
BuildFlower(&OutputBuffer, F0); BuildFlower(&OutputBuffer, F0);
#if 1
flower_desc F1 = {}; flower_desc F1 = {};
F1.Pos = v3{0, 0, 0}; F1.Pos = v3{0, 0, 0};
F1.ComPort = "\\\\.\\COM9"; F1.ComPort = "\\\\.\\COM6";
F1.FlowerTagValue = "center"; F1.FlowerTagValue = "center";
F1.StemChannels = StemChannels; F1.StemChannels = StemChannels;
F1.BloomInnerChannels = BloomInnerChannels; F1.BloomInnerChannels = BloomInnerChannels;
F1.BloomOuterChannels = BloomOuterChannels; F1.BloomOuterChannels = BloomOuterChannels;
BuildFlower(&OutputBuffer, F1); BuildFlower(&OutputBuffer, F1);
#endif
/* /*
flower_desc F2 = {}; flower_desc F2 = {};