Animation Playlists, lots of cleanup, settings file stuff, etc.
This commit is contained in:
parent
5ddca7fbac
commit
6b137154bc
|
@ -3,3 +3,4 @@ meta_run_tree/
|
|||
process/
|
||||
reference/
|
||||
working_data/
|
||||
nssm_log.log
|
|
@ -160,6 +160,9 @@ struct animation_system
|
|||
animation_array Animations;
|
||||
|
||||
animation_repeat_mode RepeatMode;
|
||||
animation_handle_array Playlist;
|
||||
u32 PlaylistAt;
|
||||
r32 PlaylistFadeTime;
|
||||
|
||||
// NOTE(Peter): The frame currently being displayed/processed. you
|
||||
// can see which frame you're on by looking at the time slider on the timeline
|
||||
|
@ -621,14 +624,21 @@ AnimationFadeGroup_Update(animation_fade_group* Group, r32 DeltaTime)
|
|||
internal void
|
||||
AnimationFadeGroup_FadeTo(animation_fade_group* Group, animation_handle To, r32 Duration)
|
||||
{
|
||||
// complete current fade if there is one in progress
|
||||
if (IsValid(Group->To))
|
||||
if (IsValid(Group->From))
|
||||
{
|
||||
AnimationFadeGroup_Advance(Group);
|
||||
}
|
||||
// complete current fade if there is one in progress
|
||||
if (IsValid(Group->To))
|
||||
{
|
||||
AnimationFadeGroup_Advance(Group);
|
||||
}
|
||||
|
||||
Group->To = To;
|
||||
Group->FadeDuration = Duration;
|
||||
Group->To = To;
|
||||
Group->FadeDuration = Duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
Group->From = To;
|
||||
}
|
||||
}
|
||||
|
||||
// System
|
||||
|
@ -750,7 +760,15 @@ AnimationSystem_Update(animation_system* System, r32 DeltaTime)
|
|||
|
||||
case AnimationRepeat_Loop:
|
||||
{
|
||||
// TODO(pjs):
|
||||
Assert(System->Playlist.Count > 0);
|
||||
u32 NextIndex = System->PlaylistAt;
|
||||
System->PlaylistAt = (System->PlaylistAt + 1) % System->Playlist.Count;
|
||||
animation_handle Next = System->Playlist.Handles[NextIndex];
|
||||
|
||||
AnimationFadeGroup_FadeTo(&System->ActiveFadeGroup,
|
||||
Next,
|
||||
System->PlaylistFadeTime);
|
||||
System->CurrentFrame = 0;
|
||||
}break;
|
||||
|
||||
InvalidDefaultCase;
|
||||
|
@ -759,6 +777,15 @@ AnimationSystem_Update(animation_system* System, r32 DeltaTime)
|
|||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
AnimationSystem_FadeToPlaylist(animation_system* System, animation_handle_array Playlist)
|
||||
{
|
||||
System->Playlist = Playlist;
|
||||
System->PlaylistAt = 0;
|
||||
|
||||
AnimationFadeGroup_FadeTo(&System->ActiveFadeGroup, Playlist.Handles[0], System->PlaylistFadeTime);
|
||||
}
|
||||
|
||||
inline bool
|
||||
AnimationSystem_NeedsRender(animation_system System)
|
||||
{
|
||||
|
|
|
@ -120,6 +120,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
// zero the Transient arena when we clear it so it wouldn't be a problem, but it is technically
|
||||
// incorrect to clear the arena, and then access the memory later.
|
||||
ClearArena(State->Transient);
|
||||
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
||||
|
||||
if (State->RunEditor)
|
||||
{
|
||||
|
@ -129,6 +130,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
AnimationSystem_Update(&State->AnimationSystem, Context->DeltaTime);
|
||||
if (AnimationSystem_NeedsRender(State->AnimationSystem))
|
||||
{
|
||||
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
||||
AnimationSystem_RenderToLedBuffers(&State->AnimationSystem,
|
||||
State->Assemblies,
|
||||
&State->LedSystem,
|
||||
|
@ -138,7 +140,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
State->UserSpaceDesc.UserData.Memory);
|
||||
}
|
||||
|
||||
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
||||
US_CustomUpdate(&State->UserSpaceDesc, State, Context);
|
||||
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
||||
|
||||
AssemblyDebug_OverrideOutput(State->AssemblyDebugState,
|
||||
State->Assemblies,
|
||||
|
@ -149,6 +153,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
Editor_Render(State, Context, RenderBuffer);
|
||||
}
|
||||
|
||||
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
||||
BuildAssemblyData(State, *Context, OutputData);
|
||||
}
|
||||
|
||||
|
|
|
@ -1065,7 +1065,7 @@ Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
|||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % BL_FLOWER_COUNT];
|
||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
||||
|
||||
|
|
|
@ -556,6 +556,41 @@ Win32_SendOutputData(gs_thread_context ThreadContext, addressed_data_buffer_list
|
|||
|
||||
}
|
||||
|
||||
// Time
|
||||
internal system_time
|
||||
Win32GetSystemTime()
|
||||
{
|
||||
system_time Result = {};
|
||||
|
||||
SYSTEMTIME WinLocalTime;
|
||||
GetLocalTime(&WinLocalTime);
|
||||
|
||||
SYSTEMTIME WinSysTime;
|
||||
FILETIME WinSysFileTime;
|
||||
GetSystemTime(&WinSysTime);
|
||||
if (SystemTimeToFileTime((const SYSTEMTIME*)&WinSysTime, &WinSysFileTime))
|
||||
{
|
||||
ULARGE_INTEGER SysTime = {};
|
||||
SysTime.LowPart = WinSysFileTime.dwLowDateTime;
|
||||
SysTime.HighPart = WinSysFileTime.dwHighDateTime;
|
||||
|
||||
Result.NanosSinceEpoch = SysTime.QuadPart;
|
||||
Result.Year = WinLocalTime.wYear;
|
||||
Result.Month = WinLocalTime.wMonth;
|
||||
Result.Day = WinLocalTime.wDay;
|
||||
Result.Hour = WinLocalTime.wHour;
|
||||
Result.Minute = WinLocalTime.wMinute;
|
||||
Result.Second = WinLocalTime.wSecond;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 Error = GetLastError();
|
||||
InvalidCodePath;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain (
|
||||
HINSTANCE HInstance,
|
||||
|
@ -636,6 +671,8 @@ WinMain (
|
|||
|
||||
Context.InitializeApplication(Context);
|
||||
|
||||
system_time StartTime = Win32GetSystemTime();
|
||||
|
||||
Running = true;
|
||||
Context.WindowIsVisible = true;
|
||||
while (Running)
|
||||
|
@ -647,31 +684,8 @@ WinMain (
|
|||
DEBUG_TRACK_SCOPE(MainLoop);
|
||||
|
||||
{
|
||||
// update system time
|
||||
SYSTEMTIME WinLocalTime;
|
||||
GetLocalTime(&WinLocalTime);
|
||||
|
||||
SYSTEMTIME WinSysTime;
|
||||
FILETIME WinSysFileTime;
|
||||
GetSystemTime(&WinSysTime);
|
||||
if (!SystemTimeToFileTime((const SYSTEMTIME*)&WinSysTime, &WinSysFileTime))
|
||||
{
|
||||
u32 Error = GetLastError();
|
||||
InvalidCodePath;
|
||||
}
|
||||
ULARGE_INTEGER SysTime = {};
|
||||
SysTime.LowPart = WinSysFileTime.dwLowDateTime;
|
||||
SysTime.HighPart = WinSysFileTime.dwHighDateTime;
|
||||
|
||||
Context.SystemTime_Last = Context.SystemTime_Current;
|
||||
|
||||
Context.SystemTime_Current.NanosSinceEpoch = SysTime.QuadPart;
|
||||
Context.SystemTime_Current.Year = WinLocalTime.wYear;
|
||||
Context.SystemTime_Current.Month = WinLocalTime.wMonth;
|
||||
Context.SystemTime_Current.Day = WinLocalTime.wDay;
|
||||
Context.SystemTime_Current.Hour = WinLocalTime.wHour;
|
||||
Context.SystemTime_Current.Minute = WinLocalTime.wMinute;
|
||||
Context.SystemTime_Current.Second = WinLocalTime.wSecond;
|
||||
Context.SystemTime_Current = Win32GetSystemTime();
|
||||
|
||||
#define PRINT_SYSTEM_TIME 0
|
||||
#if PRINT_SYSTEM_TIME
|
||||
|
@ -682,6 +696,11 @@ WinMain (
|
|||
Context.SystemTime_Current.Minute,
|
||||
Context.SystemTime_Current.Second,
|
||||
Context.SystemTime_Current.NanosSinceEpoch);
|
||||
|
||||
u64 NanosElapsed = Context.SystemTime_Current.NanosSinceEpoch - StartTime.NanosSinceEpoch;
|
||||
r64 SecondsElapsed = (r64)NanosElapsed * NanosToSeconds;
|
||||
|
||||
PrintF(&T, "%lld %f Seconds\n", NanosElapsed, SecondsElapsed);
|
||||
NullTerminate(&T);
|
||||
OutputDebugStringA(T.Str);
|
||||
#endif
|
||||
|
|
|
@ -174,6 +174,16 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
|
|||
CloseSocket(Data->SocketManager, ListenSocket);
|
||||
}
|
||||
|
||||
internal void
|
||||
BlumenLumen_SetPatternMode(bl_pattern_mode Mode, r32 FadeDuration, animation_system* System, blumen_lumen_state* BLState)
|
||||
{
|
||||
BLState->PatternMode = Mode;
|
||||
animation_handle_array Playlist = BLState->ModeAnimations[Mode];
|
||||
System->RepeatMode = AnimationRepeat_Loop;
|
||||
System->PlaylistFadeTime = FadeDuration;
|
||||
AnimationSystem_FadeToPlaylist(System, Playlist);
|
||||
}
|
||||
|
||||
internal void
|
||||
BlumenLumen_LoadPatterns(app_state* State)
|
||||
{
|
||||
|
@ -298,7 +308,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
|||
BLState->ModeAnimations[BlumenPattern_Standard] = LoadAllAnimationsInDir(AmbientPatternFolder, BLState, State, Context);
|
||||
BLState->ModeAnimations[BlumenPattern_VoiceCommand] = LoadAllAnimationsInDir(VoicePatternFolder, BLState, State, Context);
|
||||
|
||||
State->AnimationSystem.ActiveFadeGroup.From = BLState->ModeAnimations[BlumenPattern_Standard].Handles[0];
|
||||
BlumenLumen_SetPatternMode(BlumenPattern_Standard, 5, &State->AnimationSystem, BLState);
|
||||
#endif
|
||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||
|
||||
|
@ -333,21 +343,16 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
BLState->AssemblyColors[0] = NewHue;
|
||||
BLState->AssemblyColors[1] = NewHue;
|
||||
BLState->AssemblyColors[2] = NewHue;
|
||||
|
||||
animation_handle NewAnim = BLState->ModeAnimations[BlumenPattern_VoiceCommand].Handles[0];
|
||||
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
|
||||
NewAnim,
|
||||
VoiceCommandFadeDuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 AssemblyIdx = BLState->LastAssemblyColorSet;
|
||||
BLState->AssemblyColors[AssemblyIdx] = NewHue;
|
||||
BLState->LastAssemblyColorSet = (BLState->LastAssemblyColorSet + 1) % 3;
|
||||
}
|
||||
|
||||
BLState->PatternMode = BlumenPattern_VoiceCommand;
|
||||
// TODO(PS): get current time so we can fade back after
|
||||
// a while
|
||||
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState);
|
||||
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -361,8 +366,18 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
Motor.Temperature = (T[0] << 8 |
|
||||
T[1] << 0);
|
||||
|
||||
motor_packet CurrPos = Motor.Pos;
|
||||
motor_packet LastPos = BLState->LastKnownMotorState;
|
||||
DEBUG_ReceivedMotorPositions(LastPos, Motor.Pos, Context->ThreadContext);
|
||||
|
||||
for (u32 i = 0; i < BL_FLOWER_COUNT; i++)
|
||||
{
|
||||
if (LastPos.FlowerPositions[i] != CurrPos.FlowerPositions[i])
|
||||
{
|
||||
BLState->LastTimeMotorStateChanged[i] = Context->SystemTime_Current.NanosSinceEpoch;
|
||||
}
|
||||
}
|
||||
|
||||
BLState->LastKnownMotorState = Motor.Pos;
|
||||
|
||||
}break;
|
||||
|
@ -373,11 +388,11 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
|
||||
if (Temp.Temperature > 0)
|
||||
{
|
||||
BLState->BrightnessPercent = .25f;
|
||||
BLState->BrightnessPercent = HighTemperatureBrightnessPercent;
|
||||
}
|
||||
else
|
||||
{
|
||||
BLState->BrightnessPercent = 1.f;
|
||||
BLState->BrightnessPercent = FullBrightnessPercent;
|
||||
}
|
||||
|
||||
DEBUG_ReceivedTemperature(Temp, Context->ThreadContext);
|
||||
|
@ -387,6 +402,23 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
}
|
||||
}
|
||||
|
||||
// Transition back to standard mode after some time
|
||||
if (BLState->PatternMode == BlumenPattern_VoiceCommand)
|
||||
{
|
||||
u64 LastChangeClock = BLState->TimeLastSetToVoiceMode.NanosSinceEpoch;
|
||||
u64 NowClocks = Context->SystemTime_Current.NanosSinceEpoch;
|
||||
s64 NanosSinceChange = NowClocks - LastChangeClock;
|
||||
r64 SecondsSinceChange = (r64)NanosSinceChange * NanosToSeconds;
|
||||
|
||||
if (SecondsSinceChange > VoiceCommandSustainDuration)
|
||||
{
|
||||
BLState->PatternMode = BlumenPattern_Standard;
|
||||
animation_handle NewAnim = BLState->ModeAnimations[BlumenPattern_Standard].Handles[0];
|
||||
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
|
||||
NewAnim,
|
||||
VoiceCommandFadeDuration);
|
||||
}
|
||||
}
|
||||
|
||||
// Open / Close the Motor
|
||||
if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue))
|
||||
|
@ -441,38 +473,42 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
DEBUG_SentMotorCommand(MotorCommand.MotorPacket, Context->ThreadContext);
|
||||
}
|
||||
}
|
||||
// Dim the leds based on temp data
|
||||
for (u32 i = 0; i < State->LedSystem.BuffersCount; i++)
|
||||
|
||||
// When a motor state changes to being open, wait to turn Upper Leds on
|
||||
// in order to hide the fact that they are turning off
|
||||
motor_packet CurrMotorPos = BLState->LastKnownMotorState;
|
||||
u64 NowNanos = Context->SystemTime_Current.NanosSinceEpoch;
|
||||
for (u32 i = 0; i < BL_FLOWER_COUNT; i++)
|
||||
{
|
||||
led_buffer Buffer = State->LedSystem.Buffers[i];
|
||||
for (u32 j = 0; j < Buffer.LedCount; j++)
|
||||
// have to map from "assembly load order" to
|
||||
// the order that the clear core is referencing the
|
||||
// motors by
|
||||
assembly Assembly = State->Assemblies.Values[i];
|
||||
u64 AssemblyCCIndex = GetCCIndex(Assembly, BLState);
|
||||
u8 MotorPos = CurrMotorPos.FlowerPositions[AssemblyCCIndex];
|
||||
|
||||
if ((MotorPos == MotorState_Open || MotorPos == MotorState_MostlyOpen) &&
|
||||
!BLState->ShouldDimUpperLeds[i])
|
||||
{
|
||||
pixel* Color = Buffer.Colors + j;
|
||||
Color->R = Color->R * BLState->BrightnessPercent;
|
||||
Color->G = Color->G * BLState->BrightnessPercent;
|
||||
Color->B = Color->B * BLState->BrightnessPercent;
|
||||
u64 ChangedNanos = BLState->LastTimeMotorStateChanged[i];
|
||||
u64 NanosSinceChanged = NowNanos - ChangedNanos;
|
||||
r64 SecondsSinceChanged = (r64)NanosSinceChanged * NanosToSeconds;
|
||||
if (SecondsSinceChanged > TurnUpperLedsOffAfterMotorCloseCommandDelay)
|
||||
{
|
||||
BLState->ShouldDimUpperLeds[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(PS): If the flowers are mostly open or full open
|
||||
// we mask off the top leds to prevent them from overheating
|
||||
// while telescoped inside the flower
|
||||
motor_packet CurrMotorPos = BLState->LastKnownMotorState;
|
||||
for (u32 a = 0; a < State->Assemblies.Count; a++)
|
||||
for (u32 a = 0; a < BL_FLOWER_COUNT; a++)
|
||||
{
|
||||
assembly Assembly = State->Assemblies.Values[a];
|
||||
u64 AssemblyCCIndex = GetCCIndex(Assembly, BLState);
|
||||
|
||||
u8 MotorPos = CurrMotorPos.FlowerPositions[AssemblyCCIndex];
|
||||
|
||||
if (MotorPos == MotorState_Closed ||
|
||||
MotorPos == MotorState_HalfOpen)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!BLState->ShouldDimUpperLeds[a]) continue;
|
||||
|
||||
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++)
|
||||
{
|
||||
|
@ -486,6 +522,22 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
}
|
||||
}
|
||||
|
||||
// Dim the leds based on temp data
|
||||
if (!BLState->DEBUG_IgnoreWeatherDimmingLeds)
|
||||
{
|
||||
for (u32 i = 0; i < State->LedSystem.BuffersCount; i++)
|
||||
{
|
||||
led_buffer Buffer = State->LedSystem.Buffers[i];
|
||||
for (u32 j = 0; j < Buffer.LedCount; j++)
|
||||
{
|
||||
pixel* Color = Buffer.Colors + j;
|
||||
Color->R = Color->R * BLState->BrightnessPercent;
|
||||
Color->G = Color->G * BLState->BrightnessPercent;
|
||||
Color->B = Color->B * BLState->BrightnessPercent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send Status Packet
|
||||
{
|
||||
system_time LastSendTime = BLState->LastStatusUpdateTime;
|
||||
|
@ -524,7 +576,7 @@ US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI)
|
|||
{
|
||||
motor_packet PendingPacket = BLState->DEBUG_PendingMotorPacket;
|
||||
|
||||
for (u32 MotorIndex = 0; MotorIndex < 3; MotorIndex++)
|
||||
for (u32 MotorIndex = 0; MotorIndex < BL_FLOWER_COUNT; MotorIndex++)
|
||||
{
|
||||
gs_string Label = PushStringF(State->Transient, 32, "Motor %d", MotorIndex);
|
||||
ui_BeginRow(I, 5);
|
||||
|
@ -567,6 +619,40 @@ US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI)
|
|||
DEBUG_SentMotorCommand(Packet.MotorPacket, Context.ThreadContext);
|
||||
}
|
||||
|
||||
motor_packet MotorPos = BLState->LastKnownMotorState;
|
||||
ui_Label(I, MakeString("Current Motor Positions"));
|
||||
{
|
||||
for (u32 i = 0; i < BL_FLOWER_COUNT; i++)
|
||||
{
|
||||
ui_BeginRow(I, 2);
|
||||
gs_string MotorStr = PushStringF(State->Transient, 32,
|
||||
"Motor %d",
|
||||
i);
|
||||
ui_Label(I, MotorStr);
|
||||
|
||||
gs_string StateStr = {};
|
||||
switch (MotorPos.FlowerPositions[i])
|
||||
{
|
||||
case MotorState_Closed: {
|
||||
StateStr = MakeString("Closed");
|
||||
} break;
|
||||
case MotorState_HalfOpen: {
|
||||
StateStr = MakeString("Half Open");
|
||||
} break;
|
||||
case MotorState_MostlyOpen: {
|
||||
StateStr = MakeString("Mostly Open");
|
||||
} break;
|
||||
case MotorState_Open: {
|
||||
StateStr = MakeString("Open");
|
||||
} break;
|
||||
}
|
||||
|
||||
ui_Label(I, StateStr);
|
||||
ui_EndRow(I);
|
||||
}
|
||||
}
|
||||
|
||||
BLState->DEBUG_IgnoreWeatherDimmingLeds = ui_LabeledToggle(I, MakeString("Ignore Weather Dimming Leds"), BLState->DEBUG_IgnoreWeatherDimmingLeds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -145,11 +145,8 @@ struct blumen_lumen_state
|
|||
mic_listen_job_data MicListenJobData;
|
||||
|
||||
motor_packet LastKnownMotorState;
|
||||
|
||||
r64 TimeElapsed;
|
||||
|
||||
animation_handle AnimHandles[3];
|
||||
u32 CurrAnim;
|
||||
u64 LastTimeMotorStateChanged[BL_FLOWER_COUNT];
|
||||
b8 ShouldDimUpperLeds[BL_FLOWER_COUNT];
|
||||
|
||||
// NOTE(pjs): Based on temperature data from weatherman
|
||||
// dim the leds.
|
||||
|
@ -158,7 +155,7 @@ struct blumen_lumen_state
|
|||
|
||||
system_time LastSendTime;
|
||||
|
||||
phrase_hue AssemblyColors[3];
|
||||
phrase_hue AssemblyColors[BL_FLOWER_COUNT];
|
||||
u32 LastAssemblyColorSet;
|
||||
|
||||
// The indices of this array are the index the clear core uses to
|
||||
|
@ -171,12 +168,13 @@ struct blumen_lumen_state
|
|||
|
||||
bl_pattern_mode PatternMode;
|
||||
animation_handle_array ModeAnimations[BlumenPattern_Count];
|
||||
u32 CurrentAnimation;
|
||||
|
||||
phrase_hue_map PhraseHueMap;
|
||||
system_time TimeLastSetToVoiceMode;
|
||||
|
||||
// Debug
|
||||
motor_packet DEBUG_PendingMotorPacket;
|
||||
bool DEBUG_IgnoreWeatherDimmingLeds;
|
||||
};
|
||||
|
||||
#include "message_queue.cpp"
|
||||
|
|
|
@ -3,16 +3,35 @@
|
|||
#ifndef BLUMEN_LUMEN_SETTINGS_H
|
||||
#define BLUMEN_LUMEN_SETTINGS_H
|
||||
|
||||
// Hey you never know, might need to change this some day lololol
|
||||
// The number of flowers in the sculpture. Used to size all sorts of
|
||||
// arrays. Maybe don't touch this unless you really know what you're doing?
|
||||
#define BL_FLOWER_COUNT 3
|
||||
|
||||
// The path to the three flower assembly files
|
||||
// PS is 90% sure you don't need to touch these ever
|
||||
gs_const_string Flower0AssemblyPath = ConstString("data/ss_blumen_one.fold");
|
||||
gs_const_string Flower1AssemblyPath = ConstString("data/ss_blumen_two.fold");
|
||||
gs_const_string Flower2AssemblyPath = ConstString("data/ss_blumen_three.fold");
|
||||
|
||||
// The path to the phrase map CSV. Can be an absolute path, or relative
|
||||
// to the app_run_tree folder
|
||||
gs_const_string PhraseMapCSVPath = ConstString("data/flower_codes.csv");
|
||||
char PhraseMapCSVSeparator = ',';
|
||||
|
||||
// Search Strings for which folders to find ambient animation files and
|
||||
// voice animation files in.
|
||||
// these search patterns should always end in *.foldanim so they only
|
||||
// return valid animation files
|
||||
gs_const_string AmbientPatternFolder = ConstString("data/blumen_animations/ambient_patterns/*.foldanim");
|
||||
gs_const_string VoicePatternFolder = ConstString("data/blumen_animations/audio_responses/*.foldanim");
|
||||
|
||||
// The times of day when the motors should be open.
|
||||
// these are in the format { Start_Hour, Start_Minute, End_Hour, End_Minute }
|
||||
// Hours are in the range 0-23 inclusive
|
||||
// Minutes are in the range 0-59 inclusive
|
||||
// NOTE: There is no need to modify the MotorOpenTimesCount variable -
|
||||
// it is a compile time constant that gets calculated automatically
|
||||
global time_range MotorOpenTimes[] = {
|
||||
{ 00, 30, 00, 40 },
|
||||
{ 00, 50, 01, 00 },
|
||||
|
@ -59,8 +78,52 @@ global time_range MotorOpenTimes[] = {
|
|||
{ 14, 30, 14, 40 },
|
||||
{ 14, 50, 15, 00 },
|
||||
};
|
||||
global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes);
|
||||
global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); // do not edit
|
||||
|
||||
// How long it takes to fade from the default pattern to the
|
||||
// voice activated pattern
|
||||
r32 VoiceCommandFadeDuration = 1.0f; // in seconds
|
||||
|
||||
// How long the voice activated pattern will remain active
|
||||
// without additional voice commands, before fading back to
|
||||
// default behaviour.
|
||||
// ie.
|
||||
// if this is set to 30 seconds, upon receiving a voice command
|
||||
// lumenarium will fade to the requested pattern/color palette
|
||||
// and then wait 30 seconds before fading back to the original
|
||||
// pattern. If, in that 30 second window, another voice command
|
||||
// is issued, lumenarium will reset the 30 second counter.
|
||||
r64 VoiceCommandSustainDuration = 30.0; // in seconds
|
||||
|
||||
// When we send a Motor Close command, we don't want the upper leds to
|
||||
// immediately turn off. Instead, we want to wait until the flower is
|
||||
// at least some of the way closed. This variable dictates how long
|
||||
// we wait for.
|
||||
// For example:
|
||||
// 1. We send a 'motor close' command to the clear core
|
||||
// 2. the clear core sends back a 'motor closed' state packet
|
||||
// 3. We begin a timer
|
||||
// 4. When the timer reaches the value set in this variable,
|
||||
// we turn the upper leds off.
|
||||
//
|
||||
// NOTE: This is not a symmetric operation. When we send a 'motor open'
|
||||
// command, we want to immediately turn the upper leds on so they appear
|
||||
// to have been on the whole time.
|
||||
r64 TurnUpperLedsOffAfterMotorCloseCommandDelay = 5.0; // in seconds
|
||||
|
||||
// NOTE: Temperature & Time of Day Based Led Brightness Settings
|
||||
|
||||
// The percent brightness we set leds to during high temperatures.
|
||||
// A value in the range 0:1 inclusive
|
||||
// This is multiplied by each pixels R, G, & B channels before being
|
||||
// sent. So if it is set to .1f, then the maximum brightness value sent
|
||||
// to any channel of any pixel will be 25 (255 * .1 = 25).
|
||||
r32 HighTemperatureBrightnessPercent = .25f;
|
||||
|
||||
// The percent brightness we set leds to when no other conditions apply
|
||||
// A value in the range 0:1 inclusive.
|
||||
// Probably wants to be something high like 1 but we might want to
|
||||
// lower it for heat reasons?
|
||||
r32 FullBrightnessPercent = 1.0f;
|
||||
|
||||
#endif //BLUMEN_LUMEN_SETTINGS_H
|
||||
|
|
|
@ -2709,8 +2709,30 @@ PushSize_(gs_memory_arena* Arena, u64 Size, char* Location)
|
|||
{
|
||||
CursorEntry = MemoryArenaNewCursor(Arena, Size, Location);
|
||||
}
|
||||
Assert(CursorEntry);
|
||||
Assert(CursorHasRoom(CursorEntry->Cursor, Size));
|
||||
|
||||
if (!CursorEntry || !CursorHasRoom(CursorEntry->Cursor, Size))
|
||||
{
|
||||
__debugbreak();
|
||||
|
||||
CursorEntry = 0;
|
||||
for (u64 i = 0;
|
||||
i < Arena->CursorsCount;
|
||||
i++)
|
||||
{
|
||||
gs_memory_cursor_list* At = Arena->Cursors + i;
|
||||
if (CursorHasRoom(At->Cursor, Size))
|
||||
{
|
||||
CursorEntry = At;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!CursorEntry)
|
||||
{
|
||||
CursorEntry = MemoryArenaNewCursor(Arena, Size, Location);
|
||||
}
|
||||
}
|
||||
//Assert(CursorEntry);
|
||||
//Assert(CursorHasRoom(CursorEntry->Cursor, Size));
|
||||
#else
|
||||
|
||||
gs_memory_cursor_list* CursorEntry = Arena->CursorList;
|
||||
|
|
|
@ -137,6 +137,9 @@ global_const r64 MinR64 = -MaxR64;
|
|||
global_const r64 SmallestPositiveR64 = 4.94065645841247e-324;
|
||||
global_const r64 EpsilonR64 = 1.11022302462515650e-16;
|
||||
|
||||
global_const r64 NanosToSeconds = 1 / 10000000.0;
|
||||
global_const r64 SecondsToNanos = 10000000.0;
|
||||
|
||||
// TODO: va_start and va_arg replacements
|
||||
|
||||
internal r32
|
||||
|
|
Loading…
Reference in New Issue