Message sending to weatherman
This commit is contained in:
parent
c054a0e6b6
commit
9fc984d6f2
|
@ -133,12 +133,14 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
Editor_Render(State, Context, RenderBuffer);
|
Editor_Render(State, Context, RenderBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SEND_DATA
|
||||||
// NOTE(pjs): Building data buffers to be sent out to the sculpture
|
// 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
|
// 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 SACNAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaSACN, State->Transient);
|
||||||
assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient);
|
assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient);
|
||||||
SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem);
|
SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem);
|
||||||
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient);
|
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP_APPLICATION(CleanupApplication)
|
CLEANUP_APPLICATION(CleanupApplication)
|
||||||
|
|
|
@ -189,6 +189,20 @@ GetSecondsElapsed (s64 Start, s64 End, s64 PerformanceCountFrequency)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct system_time
|
||||||
|
{
|
||||||
|
u64 NanosSinceEpoch;
|
||||||
|
|
||||||
|
s32 Year;
|
||||||
|
s32 Month;
|
||||||
|
s32 Day;
|
||||||
|
s32 Hour; // [0:23]
|
||||||
|
s32 Minute;
|
||||||
|
s32 Second;
|
||||||
|
} system_time;
|
||||||
|
|
||||||
|
#define STATUS_PACKET_FREQ_SECONDS 5
|
||||||
|
|
||||||
struct context
|
struct context
|
||||||
{
|
{
|
||||||
gs_thread_context ThreadContext;
|
gs_thread_context ThreadContext;
|
||||||
|
@ -218,6 +232,9 @@ struct context
|
||||||
platform_draw_font_codepoint* PlatformDrawFontCodepoint;
|
platform_draw_font_codepoint* PlatformDrawFontCodepoint;
|
||||||
|
|
||||||
platform_get_socket_handle* PlatformGetSocketHandle;
|
platform_get_socket_handle* PlatformGetSocketHandle;
|
||||||
|
|
||||||
|
system_time SystemTime_Last;
|
||||||
|
system_time SystemTime_Current;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FOLDHAUS_PLATFORM_H
|
#define FOLDHAUS_PLATFORM_H
|
||||||
|
|
|
@ -7,6 +7,242 @@
|
||||||
|
|
||||||
#define FLOWER_COLORS_COUNT 12
|
#define FLOWER_COLORS_COUNT 12
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Smoothstep(r32 T)
|
||||||
|
{
|
||||||
|
r32 Result = (T * T * (3 - (2 * T)));
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
internal r32
|
||||||
|
Smoothstep(r32 T, r32 A, r32 B)
|
||||||
|
{
|
||||||
|
return LerpR32(Smoothstep(T), A, B);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v2
|
||||||
|
FloorV2(v2 P)
|
||||||
|
{
|
||||||
|
v2 Result = {};
|
||||||
|
Result.x = FloorR32(P.x);
|
||||||
|
Result.y = FloorR32(P.y);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
internal v3
|
||||||
|
FloorV3(v3 P)
|
||||||
|
{
|
||||||
|
v3 Result = {};
|
||||||
|
Result.x = FloorR32(P.x);
|
||||||
|
Result.y = FloorR32(P.y);
|
||||||
|
Result.z = FloorR32(P.z);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v2
|
||||||
|
FractV2(v2 P)
|
||||||
|
{
|
||||||
|
v2 Result = {};
|
||||||
|
Result.x = FractR32(P.x);
|
||||||
|
Result.y = FractR32(P.y);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
internal v3
|
||||||
|
FractV3(v3 P)
|
||||||
|
{
|
||||||
|
v3 Result = {};
|
||||||
|
Result.x = FractR32(P.x);
|
||||||
|
Result.y = FractR32(P.y);
|
||||||
|
Result.z = FractR32(P.z);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v2
|
||||||
|
SinV2(v2 P)
|
||||||
|
{
|
||||||
|
v2 Result = {};
|
||||||
|
Result.x = SinR32(P.x);
|
||||||
|
Result.y = SinR32(P.y);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
internal v3
|
||||||
|
SinV3(v3 P)
|
||||||
|
{
|
||||||
|
v3 Result = {};
|
||||||
|
Result.x = SinR32(P.x);
|
||||||
|
Result.y = SinR32(P.y);
|
||||||
|
Result.y = SinR32(P.z);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Hash1(v2 P)
|
||||||
|
{
|
||||||
|
v2 Result = FractV2( P * 0.3183099f ) * 50.f;
|
||||||
|
return FractR32(P.x * P.y * (P.x + P.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Hash1(r32 N)
|
||||||
|
{
|
||||||
|
return FractR32(N * 17.0f * FractR32(N * 0.3183099f));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v2
|
||||||
|
Hash2(r32 N)
|
||||||
|
{
|
||||||
|
v2 P = V2MultiplyPairwise(SinV2(v2{N,N+1.0f}), v2{43758.5453123f,22578.1459123f});
|
||||||
|
return FractV2(P);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v2
|
||||||
|
Hash2(v2 P)
|
||||||
|
{
|
||||||
|
v2 K = v2{ 0.3183099f, 0.3678794f };
|
||||||
|
v2 Kp = v2{K.y, K.x};
|
||||||
|
v2 R = V2MultiplyPairwise(P, K) + Kp;
|
||||||
|
return FractV2( K * 16.0f * FractR32( P.x * P.y * (P.x + P.y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal v3
|
||||||
|
Hash3(v2 P)
|
||||||
|
{
|
||||||
|
v3 Q = v3{};
|
||||||
|
Q.x = V2Dot(P, v2{127.1f, 311.7f});
|
||||||
|
Q.y = V2Dot(P, v2{267.5f, 183.3f});
|
||||||
|
Q.z = V2Dot(P, v2{419.2f, 371.9f});
|
||||||
|
return FractV3(SinV3(Q) * 43758.5453f);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Random(v2 N)
|
||||||
|
{
|
||||||
|
v2 V = v2{12.9898f, 4.1414f};
|
||||||
|
return FractR32(SinR32(V2Dot(N, V)) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Noise2D(v2 P)
|
||||||
|
{
|
||||||
|
v2 IP = FloorV2(P);
|
||||||
|
v2 U = FractV2(P);
|
||||||
|
U = V2MultiplyPairwise(U, U);
|
||||||
|
U = V2MultiplyPairwise(U, ((U * 2.0f) + v2{-3, -3}));
|
||||||
|
|
||||||
|
r32 A = LerpR32(U.x, Random(IP), Random(IP + v2{1.0f, 0}));
|
||||||
|
r32 B = LerpR32(U.x, Random(IP + v2{0, 1}), Random(IP + v2{1, 1}));
|
||||||
|
r32 Res = LerpR32(U.y, A, B);
|
||||||
|
|
||||||
|
return Res * Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Noise3D(v3 Pp)
|
||||||
|
{
|
||||||
|
v3 P = FloorV3(Pp);
|
||||||
|
v3 W = FractV3(Pp);
|
||||||
|
|
||||||
|
//v3 U = W * W * W * (W * (W * 6.0f - 15.0f) + 10.0f);
|
||||||
|
v3 U = V3MultiplyPairwise(W, W * 6.0f - v3{15, 15, 15});
|
||||||
|
U = U + v3{10, 10, 10};
|
||||||
|
U = V3MultiplyPairwise(U, W);
|
||||||
|
U = V3MultiplyPairwise(U, W);
|
||||||
|
U = V3MultiplyPairwise(U, W);
|
||||||
|
|
||||||
|
r32 N = P.x + 317.0f * P.y + 157.0f * P.z;
|
||||||
|
|
||||||
|
r32 A = Hash1(N + 0.0f);
|
||||||
|
r32 B = Hash1(N + 1.0f);
|
||||||
|
r32 C = Hash1(N + 317.0f);
|
||||||
|
r32 D = Hash1(N + 317.0f);
|
||||||
|
r32 E = Hash1(N + 157.0f);
|
||||||
|
r32 F = Hash1(N + 158.0f);
|
||||||
|
r32 G = Hash1(N + 474.0f);
|
||||||
|
r32 H = Hash1(N + 475.0f);
|
||||||
|
|
||||||
|
r32 K0 = A;
|
||||||
|
r32 K1 = B - A;
|
||||||
|
r32 K2 = C - A;
|
||||||
|
r32 K3 = E - A;
|
||||||
|
r32 K4 = A - B - C + D;
|
||||||
|
r32 K5 = A - C - E + G;
|
||||||
|
r32 K6 = A - B - E + F;
|
||||||
|
r32 K7 = A + B + C - D + E - F - G + H;
|
||||||
|
|
||||||
|
return -1.0f + 2.0f * (K0 +
|
||||||
|
K1 * U.x +
|
||||||
|
K2 * U.y +
|
||||||
|
K3 * U.z +
|
||||||
|
K4 * U.x * U.y +
|
||||||
|
K5 * U.y + U.z +
|
||||||
|
K6 * U.z * U.x +
|
||||||
|
K7 * U.x * U.y * U.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Fbm2D(v2 P)
|
||||||
|
{
|
||||||
|
r32 R = 0;
|
||||||
|
r32 Amp = 1.0;
|
||||||
|
r32 Freq = 1.0;
|
||||||
|
for (u32 i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
R += Amp * Noise2D(P * Freq);
|
||||||
|
Amp *= 0.5f;
|
||||||
|
Freq *= 1.0f / 0.5f;
|
||||||
|
}
|
||||||
|
return R;
|
||||||
|
}
|
||||||
|
|
||||||
|
global m44 M3 = m44{
|
||||||
|
0.00f, 0.80f, 0.60f, 0,
|
||||||
|
-0.80f, 0.36f, -0.48f, 0,
|
||||||
|
-0.60f, -0.48f, 0.64f, 0,
|
||||||
|
0, 0, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Fbm3D(v3 P)
|
||||||
|
{
|
||||||
|
v3 X = P;
|
||||||
|
r32 F = 2.0f;
|
||||||
|
r32 S = 0.5f;
|
||||||
|
r32 A = 0.0f;
|
||||||
|
r32 B = 0.5f;
|
||||||
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
r32 N = Noise3D(X);
|
||||||
|
A += B * N;
|
||||||
|
B *= S;
|
||||||
|
v4 Xp = M3 * ToV4Point(X);
|
||||||
|
X = Xp.xyz * F;
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Voronoise(v2 P, r32 U, r32 V)
|
||||||
|
{
|
||||||
|
r32 K = 1.0f + 63.0f + PowR32(1.0f - V, 6.0f);
|
||||||
|
|
||||||
|
v2 I = FloorV2(P);
|
||||||
|
v2 F = FractV2(P);
|
||||||
|
|
||||||
|
v2 A = v2{0, 0};
|
||||||
|
for (s32 y = -2; y <= 2; y++)
|
||||||
|
{
|
||||||
|
for (s32 x = -2; x <= 2; x++)
|
||||||
|
{
|
||||||
|
v2 G = v2{(r32)x, (r32)y};
|
||||||
|
v3 O = V3MultiplyPairwise(Hash3(I + G), v3{U, U, 1.0f});
|
||||||
|
v2 D = G - F + O.xy;
|
||||||
|
r32 W = PowR32(1.0f - Smoothstep(V2Mag(D), 0.0f, 1.414f), K);
|
||||||
|
A += v2{O.z * W, W};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return A.x / A.y;
|
||||||
|
}
|
||||||
|
|
||||||
pixel FlowerAColors[FLOWER_COLORS_COUNT] = {
|
pixel FlowerAColors[FLOWER_COLORS_COUNT] = {
|
||||||
{ 232,219,88 },
|
{ 232,219,88 },
|
||||||
{ 232,219,88 },
|
{ 232,219,88 },
|
||||||
|
@ -507,13 +743,6 @@ Pattern_LighthouseRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal r32
|
|
||||||
Smoothstep(r32 T)
|
|
||||||
{
|
|
||||||
r32 Result = (T * T * (3 - (2 * T)));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
@ -726,5 +955,98 @@ Pattern_BasicFlowers(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_ar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Wavy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Patchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
|
v3 Pp = P.xyz;
|
||||||
|
|
||||||
|
r32 Noise = Fbm3D((Pp / 1000) + (v3{Time, -Time, SinR32(Time)} * 0.1f));
|
||||||
|
Noise = RemapR32(Noise, -1, 1, 0, 1);
|
||||||
|
Noise = Smoothstep(Noise, 0, 1);
|
||||||
|
u8 NV = (u8)(Noise * 255);
|
||||||
|
|
||||||
|
v3 BSeed = v3{P.z, P.x, P.y};
|
||||||
|
r32 BNoise = 1.0f; //Fbm3D(BSeed / 50);
|
||||||
|
|
||||||
|
pixel C = GetColor(&FlowerAColors[0], FLOWER_COLORS_COUNT, Noise);
|
||||||
|
C.R = (u8)((r32)C.R * BNoise);
|
||||||
|
C.G = (u8)((r32)C.G * BNoise);
|
||||||
|
C.B = (u8)((r32)C.B * BNoise);
|
||||||
|
|
||||||
|
Leds->Colors[LedIndex] = C;
|
||||||
|
//Leds->Colors[LedIndex] = pixel{NV, NV, NV};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Leafy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
pixel* Colors = &FlowerBColors[0];
|
||||||
|
|
||||||
|
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
r32 RefPos = P.y + Noise2D(v2{P.x, P.z} * 50);
|
||||||
|
|
||||||
|
r32 B = 0;
|
||||||
|
|
||||||
|
pixel C = {};
|
||||||
|
|
||||||
|
r32 BandWidth = 5;
|
||||||
|
r32 TransitionPeriod = 5.0f;
|
||||||
|
u32 BandCount = 10;
|
||||||
|
for (u32 Band = 0; Band < BandCount; Band++)
|
||||||
|
{
|
||||||
|
r32 BandSeed = RemapR32(Hash1((r32)Band), -1, 1, 0, 1);
|
||||||
|
r32 BandDelay = BandSeed * TransitionPeriod;
|
||||||
|
r32 BandTransitionDuration = RemapR32(Hash1((r32)Band * 3.413f), -1, 1, 0, 1) * TransitionPeriod;
|
||||||
|
r32 BandPercent = Smoothstep(ModR32(Time + BandDelay, BandTransitionDuration) / TransitionPeriod, 0, 1);
|
||||||
|
r32 BandHeight = 150 - BandPercent * 250;
|
||||||
|
|
||||||
|
r32 BandDist = Abs(RefPos - BandHeight);
|
||||||
|
|
||||||
|
//B += Max(0, BandWidth - BandDist);
|
||||||
|
B = Max(0, BandWidth - BandDist);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
//pixel BandColor = GetColor(Colors, FLOWER_COLORS_COUNT, BandSeed);
|
||||||
|
pixel BandColor = Colors[Band % FLOWER_COLORS_COUNT];
|
||||||
|
C.R = C.R + (BandColor.R * B);
|
||||||
|
C.G = C.G + (BandColor.G * B);
|
||||||
|
C.B = C.B + (BandColor.B * B);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 V = (u8)(B * 255);
|
||||||
|
//pixel C = { V, V, V };
|
||||||
|
Leds->Colors[LedIndex] = C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_LeafyPatchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_WavyPatchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#define BLUMEN_PATTERNS_H
|
#define BLUMEN_PATTERNS_H
|
||||||
#endif // BLUMEN_PATTERNS_H
|
#endif // BLUMEN_PATTERNS_H
|
|
@ -620,6 +620,47 @@ WinMain (
|
||||||
}
|
}
|
||||||
DEBUG_TRACK_SCOPE(MainLoop);
|
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;
|
||||||
|
|
||||||
|
#define PRINT_SYSTEM_TIME 0
|
||||||
|
#if PRINT_SYSTEM_TIME
|
||||||
|
gs_string T = PushStringF(Context.ThreadContext.Transient,
|
||||||
|
256,
|
||||||
|
"%d %d %d - %lld\n",
|
||||||
|
Context.SystemTime_Current.Hour,
|
||||||
|
Context.SystemTime_Current.Minute,
|
||||||
|
Context.SystemTime_Current.Second,
|
||||||
|
Context.SystemTime_Current.NanosSinceEpoch);
|
||||||
|
NullTerminate(&T);
|
||||||
|
OutputDebugStringA(T.Str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
ResetInputQueue(&InputQueue);
|
ResetInputQueue(&InputQueue);
|
||||||
|
|
||||||
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false);
|
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false);
|
||||||
|
|
|
@ -151,6 +151,10 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
||||||
// ??
|
// ??
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
case ERROR_NO_SUCH_DEVICE:
|
||||||
|
{
|
||||||
|
}break;
|
||||||
|
|
||||||
case ERROR_INVALID_HANDLE:
|
case ERROR_INVALID_HANDLE:
|
||||||
InvalidDefaultCase;
|
InvalidDefaultCase;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,67 @@
|
||||||
//
|
//
|
||||||
#ifndef BLUMEN_LUMEN_CPP
|
#ifndef BLUMEN_LUMEN_CPP
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
MessageQueue_CanRead(blumen_network_msg_queue* Queue)
|
||||||
|
{
|
||||||
|
bool Result = (Queue->ReadHead != Queue->WriteHead);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal gs_data
|
||||||
|
MessageQueue_Read(blumen_network_msg_queue* Queue)
|
||||||
|
{
|
||||||
|
gs_data Result = {};
|
||||||
|
u32 ReadIndex = Queue->ReadHead++;
|
||||||
|
if (Queue->ReadHead >= BLUMEN_MESSAGE_QUEUE_COUNT)
|
||||||
|
{
|
||||||
|
Queue->ReadHead = 0;
|
||||||
|
}
|
||||||
|
Result = Queue->Buffers[ReadIndex];
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// KB(1) is just bigger than any packet we send. Good for now
|
||||||
|
#define DEFAULT_QUEUE_ENTRY_SIZE KB(1)
|
||||||
|
|
||||||
|
internal void
|
||||||
|
MessageQueue_Init(blumen_network_msg_queue* Queue, gs_memory_arena* Arena)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < BLUMEN_MESSAGE_QUEUE_COUNT; i++)
|
||||||
|
{
|
||||||
|
Queue->Buffers[i] = PushSizeToData(Arena, DEFAULT_QUEUE_ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal gs_data*
|
||||||
|
MessageQueue_GetWrite(blumen_network_msg_queue* Queue)
|
||||||
|
{
|
||||||
|
u32 Index = Queue->WriteHead++;
|
||||||
|
gs_data* Result = &Queue->Buffers[Index];
|
||||||
|
Assert(Result->Size > 0);
|
||||||
|
|
||||||
|
if (Queue->WriteHead >= PACKETS_MAX)
|
||||||
|
{
|
||||||
|
Queue->WriteHead = 0;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
MessageQueue_Write(blumen_network_msg_queue* Queue, gs_data Msg)
|
||||||
|
{
|
||||||
|
gs_data* Dest = MessageQueue_GetWrite(Queue);
|
||||||
|
Assert(Msg.Size <= DEFAULT_QUEUE_ENTRY_SIZE);
|
||||||
|
CopyMemoryTo(Msg.Memory, Dest->Memory, Msg.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
MessageQueue_CanWrite(blumen_network_msg_queue Queue)
|
||||||
|
{
|
||||||
|
bool Result = ((Queue.WriteHead >= Queue.ReadHead) ||
|
||||||
|
(Queue.WriteHead < Queue.ReadHead));
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
|
BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
|
||||||
|
@ -32,23 +93,13 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
|
||||||
Msg = SocketRecieve(Data->SocketManager, Data->ListenSocket, Ctx->Transient);
|
Msg = SocketRecieve(Data->SocketManager, Data->ListenSocket, Ctx->Transient);
|
||||||
if (Msg.Size > 0)
|
if (Msg.Size > 0)
|
||||||
{
|
{
|
||||||
Data->MicPacketBuffer->Values[Data->MicPacketBuffer->WriteHead++] = Msg;
|
MessageQueue_Write(Data->IncomingMsgQueue, Msg);
|
||||||
if (Data->MicPacketBuffer->WriteHead >= PACKETS_MAX)
|
|
||||||
{
|
|
||||||
Data->MicPacketBuffer->WriteHead = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Data->OutgoingMsgQueue->ReadHead != Data->OutgoingMsgQueue->WriteHead)
|
while (MessageQueue_CanRead(Data->OutgoingMsgQueue))
|
||||||
{
|
{
|
||||||
u32 ReadIndex = Data->OutgoingMsgQueue->ReadHead++;
|
Msg = MessageQueue_Read(Data->OutgoingMsgQueue);
|
||||||
if (Data->OutgoingMsgQueue->ReadHead >= BLUMEN_MESSAGE_QUEUE_COUNT)
|
|
||||||
{
|
|
||||||
Data->OutgoingMsgQueue->ReadHead = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Msg = Data->OutgoingMsgQueue->Buffers[ReadIndex];
|
|
||||||
u32 Address = WeathermanIPV4;
|
u32 Address = WeathermanIPV4;
|
||||||
u32 Port = WeathermanPort;
|
u32 Port = WeathermanPort;
|
||||||
s32 Flags = 0;
|
s32 Flags = 0;
|
||||||
|
@ -88,6 +139,9 @@ BlumenLumen_LoadPatterns(app_state* State)
|
||||||
Patterns_PushPattern(Patterns, Pattern_FlowerColors);
|
Patterns_PushPattern(Patterns, Pattern_FlowerColors);
|
||||||
Patterns_PushPattern(Patterns, Pattern_FlowerColorToWhite);
|
Patterns_PushPattern(Patterns, Pattern_FlowerColorToWhite);
|
||||||
Patterns_PushPattern(Patterns, Pattern_BasicFlowers);
|
Patterns_PushPattern(Patterns, Pattern_BasicFlowers);
|
||||||
|
// 15
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_Patchy);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_Leafy);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal pixel
|
internal pixel
|
||||||
|
@ -116,10 +170,13 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)Result.Memory;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)Result.Memory;
|
||||||
BLState->Running = true;
|
BLState->Running = true;
|
||||||
|
BLState->BrightnessPercent = 1;
|
||||||
|
MessageQueue_Init(&BLState->IncomingMsgQueue, &State->Permanent);
|
||||||
|
MessageQueue_Init(&BLState->OutgoingMsgQueue, &State->Permanent);
|
||||||
|
|
||||||
BLState->MicListenJobData.Running = &BLState->Running;
|
BLState->MicListenJobData.Running = &BLState->Running;
|
||||||
BLState->MicListenJobData.SocketManager = Context.SocketManager;
|
BLState->MicListenJobData.SocketManager = Context.SocketManager;
|
||||||
BLState->MicListenJobData.MicPacketBuffer = &BLState->MicPacketBuffer;
|
BLState->MicListenJobData.IncomingMsgQueue = &BLState->IncomingMsgQueue;
|
||||||
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
|
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
|
||||||
BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185");
|
BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185");
|
||||||
|
|
||||||
|
@ -163,8 +220,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
Anim2.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
Anim2.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
||||||
Animation_AddLayer(&Anim2, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
Animation_AddLayer(&Anim2, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
||||||
|
|
||||||
Animation_AddBlock(&Anim2, 0, 100, Patterns_IndexToHandle(5), 0);
|
Animation_AddBlock(&Anim2, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(17), 0);
|
||||||
Animation_AddBlock(&Anim2, 50, Anim0.PlayableRange.Max, Patterns_IndexToHandle(10), 0);
|
|
||||||
|
|
||||||
BLState->AnimHandles[2] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim2);
|
BLState->AnimHandles[2] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim2);
|
||||||
|
|
||||||
|
@ -204,26 +260,26 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
gs_string GreenString = MakeString("green");
|
gs_string GreenString = MakeString("green");
|
||||||
gs_string ILoveYouString = MakeString("i_love_you");
|
gs_string ILoveYouString = MakeString("i_love_you");
|
||||||
|
|
||||||
while (BLState->MicPacketBuffer.ReadHead != BLState->MicPacketBuffer.WriteHead)
|
while (MessageQueue_CanRead(&BLState->IncomingMsgQueue))
|
||||||
{
|
{
|
||||||
gs_data PacketData = BLState->MicPacketBuffer.Values[BLState->MicPacketBuffer.ReadHead++];
|
gs_data PacketData = MessageQueue_Read(&BLState->IncomingMsgQueue);
|
||||||
|
|
||||||
u8 PacketType = PacketData.Memory[0];
|
blumen_packet Packet = *(blumen_packet*)PacketData.Memory;
|
||||||
switch (PacketType) {
|
switch (Packet.Type) {
|
||||||
case PacketType_PatternCommand:
|
case PacketType_PatternCommand:
|
||||||
{
|
{
|
||||||
microphone_packet Packet = *(microphone_packet*)(PacketData.Memory + 1);
|
microphone_packet Mic = Packet.MicPacket;
|
||||||
|
|
||||||
u32 NameLen = CStringLength(Packet.AnimationFileName);
|
u32 NameLen = CStringLength(Mic.AnimationFileName);
|
||||||
if (StringEqualsCharArray(BlueString.ConstString, Packet.AnimationFileName, NameLen))
|
if (StringEqualsCharArray(BlueString.ConstString, Mic.AnimationFileName, NameLen))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.ActiveFadeGroup.From.Index = 0;
|
State->AnimationSystem.ActiveFadeGroup.From.Index = 0;
|
||||||
}
|
}
|
||||||
else if (StringEqualsCharArray(GreenString.ConstString, Packet.AnimationFileName, NameLen))
|
else if (StringEqualsCharArray(GreenString.ConstString, Mic.AnimationFileName, NameLen))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.ActiveFadeGroup.From.Index = 1;
|
State->AnimationSystem.ActiveFadeGroup.From.Index = 1;
|
||||||
}
|
}
|
||||||
else if (StringEqualsCharArray(ILoveYouString.ConstString, Packet.AnimationFileName, NameLen))
|
else if (StringEqualsCharArray(ILoveYouString.ConstString, Mic.AnimationFileName, NameLen))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.ActiveFadeGroup.From.Index = 2;
|
State->AnimationSystem.ActiveFadeGroup.From.Index = 2;
|
||||||
}
|
}
|
||||||
|
@ -233,13 +289,13 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
|
|
||||||
case PacketType_MotorState:
|
case PacketType_MotorState:
|
||||||
{
|
{
|
||||||
motor_packet Packet = *(motor_packet*)(PacketData.Memory + 1);
|
motor_packet Motor = Packet.MotorPacket;
|
||||||
BLState->LastKnownMotorState = Packet;
|
BLState->LastKnownMotorState = Motor;
|
||||||
|
|
||||||
gs_string Temp = PushStringF(State->Transient, 256, "Received Motor States: %d %d %d\n",
|
gs_string Temp = PushStringF(State->Transient, 256, "Received Motor States: %d %d %d\n",
|
||||||
Packet.FlowerPositions[0],
|
Motor.FlowerPositions[0],
|
||||||
Packet.FlowerPositions[1],
|
Motor.FlowerPositions[1],
|
||||||
Packet.FlowerPositions[2]);
|
Motor.FlowerPositions[2]);
|
||||||
NullTerminate(&Temp);
|
NullTerminate(&Temp);
|
||||||
|
|
||||||
OutputDebugStringA(Temp.Str);
|
OutputDebugStringA(Temp.Str);
|
||||||
|
@ -247,66 +303,97 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
|
|
||||||
case PacketType_Temperature:
|
case PacketType_Temperature:
|
||||||
{
|
{
|
||||||
temp_packet Packet = *(temp_packet*)(PacketData.Memory + 1);
|
temp_packet Temp = Packet.TempPacket;
|
||||||
|
|
||||||
gs_string Temp = PushStringF(State->Transient, 256, "Temperature: %d\n",
|
if (Temp.Temperature > 21)
|
||||||
Packet.Temperature);
|
{
|
||||||
NullTerminate(&Temp);
|
BLState->BrightnessPercent = .5f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BLState->BrightnessPercent = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
OutputDebugStringA(Temp.Str);
|
gs_string TempStr = PushStringF(State->Transient, 256, "Temperature: %d\n",
|
||||||
|
Temp.Temperature);
|
||||||
|
NullTerminate(&TempStr);
|
||||||
|
OutputDebugStringA(TempStr.Str);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
InvalidDefaultCase;
|
InvalidDefaultCase;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (BLState->MicPacketBuffer.ReadHead >= PACKETS_MAX)
|
// Open / Close the Motor
|
||||||
|
|
||||||
|
if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue))
|
||||||
{
|
{
|
||||||
BLState->MicPacketBuffer.ReadHead = 0;
|
for (u32 i = 0; i < MotorOpenTimesCount; i++)
|
||||||
|
{
|
||||||
|
time_range Range = MotorOpenTimes[i];
|
||||||
|
|
||||||
|
bool CurrTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Current, Range);
|
||||||
|
bool LastTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Last, Range);
|
||||||
|
|
||||||
|
if (CurrTimeInRange && !LastTimeInRange)
|
||||||
|
{
|
||||||
|
OutputDebugString("Open\n");
|
||||||
|
gs_data* Msg = MessageQueue_GetWrite(&BLState->OutgoingMsgQueue);
|
||||||
|
|
||||||
|
blumen_packet* Packet = (blumen_packet*)Msg->Memory;
|
||||||
|
Packet->Type = PacketType_MotorState;
|
||||||
|
Packet->MotorPacket.FlowerPositions[0] = 2;
|
||||||
|
Packet->MotorPacket.FlowerPositions[1] = 2;
|
||||||
|
Packet->MotorPacket.FlowerPositions[2] = 2;
|
||||||
|
}
|
||||||
|
else if (!CurrTimeInRange && LastTimeInRange)
|
||||||
|
{
|
||||||
|
OutputDebugString("Close\n");
|
||||||
|
gs_data* Msg = MessageQueue_GetWrite(&BLState->OutgoingMsgQueue);
|
||||||
|
|
||||||
|
blumen_packet* Packet = (blumen_packet*)Msg->Memory;
|
||||||
|
Packet->Type = PacketType_MotorState;
|
||||||
|
Packet->MotorPacket.FlowerPositions[0] = 1;
|
||||||
|
Packet->MotorPacket.FlowerPositions[1] = 1;
|
||||||
|
Packet->MotorPacket.FlowerPositions[2] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false && MotorTimeElapsed > 0)
|
// Dim the leds based on temp data
|
||||||
|
for (u32 i = 0; i < State->LedSystem.BuffersCount; i++)
|
||||||
{
|
{
|
||||||
// NOTE(pjs):
|
led_buffer Buffer = State->LedSystem.Buffers[i];
|
||||||
MotorTimeElapsed = 0;
|
for (u32 j = 0; j < Buffer.LedCount; j++)
|
||||||
u8 Position = LastPosition;
|
|
||||||
if (LastPosition == 2)
|
|
||||||
{
|
{
|
||||||
LastPosition = 1;
|
pixel* Color = Buffer.Colors + j;
|
||||||
|
Color->R = Color->R * BLState->BrightnessPercent;
|
||||||
|
Color->G = Color->G * BLState->BrightnessPercent;
|
||||||
|
Color->B = Color->B * BLState->BrightnessPercent;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LastPosition = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((BLState->OutgoingMsgQueue.WriteHead >= BLState->OutgoingMsgQueue.ReadHead) ||
|
// Send Status Packet
|
||||||
(BLState->OutgoingMsgQueue.WriteHead < BLState->OutgoingMsgQueue.ReadHead))
|
|
||||||
{
|
{
|
||||||
u32 WriteIndex = BLState->OutgoingMsgQueue.WriteHead;
|
system_time LastSendTime = BLState->LastStatusUpdateTime;
|
||||||
|
s64 NanosSinceLastSend = ((s64)Context->SystemTime_Current.NanosSinceEpoch - (s64)LastSendTime.NanosSinceEpoch);
|
||||||
|
s64 SecondsSinceLastSend = NanosSinceLastSend * 1000000000;
|
||||||
|
if (SecondsSinceLastSend >= STATUS_PACKET_FREQ_SECONDS)
|
||||||
|
{
|
||||||
|
BLState->LastStatusUpdateTime = Context->SystemTime_Current;
|
||||||
|
gs_data* Msg = MessageQueue_GetWrite(&BLState->OutgoingMsgQueue);
|
||||||
|
|
||||||
gs_data* Msg = BLState->OutgoingMsgQueue.Buffers + WriteIndex;
|
OutputDebugString("Sending Status\n");
|
||||||
if (Msg->Size == 0)
|
|
||||||
{
|
|
||||||
*Msg = PushSizeToData(&State->Permanent, sizeof(motor_packet));
|
|
||||||
}
|
|
||||||
motor_packet* Packet = (motor_packet*)Msg->Memory;
|
|
||||||
Packet->FlowerPositions[0] = Position;
|
|
||||||
Packet->FlowerPositions[1] = Position;
|
|
||||||
Packet->FlowerPositions[2] = Position;
|
|
||||||
|
|
||||||
// NOTE(pjs): We increment the write head AFTER we've written so that
|
blumen_packet* Packet = (blumen_packet*)Msg->Memory;
|
||||||
// the network thread doesn't think the buffer is ready to send before
|
Packet->Type = PacketType_LumenariumStatus;
|
||||||
// the data is set. We want to avoid the case of:
|
Packet->StatusPacket.NextMotorEventType = 0;
|
||||||
// 1. Main Thread increments write head to 1
|
Packet->StatusPacket.NextEventTime = 0;
|
||||||
// 2. Network Thread thinks theres a new message to send at 0
|
|
||||||
// 3. Network Thread sends the message at 0
|
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
|
||||||
// 4. Main Thread sets the message at 0
|
CopyMemoryTo(ActiveAnim->Name.Str, Packet->StatusPacket.AnimFileName,
|
||||||
BLState->OutgoingMsgQueue.WriteHead += 1;
|
Min(ActiveAnim->Name.Length, 32));
|
||||||
if (BLState->OutgoingMsgQueue.WriteHead >= BLUMEN_MESSAGE_QUEUE_COUNT)
|
|
||||||
{
|
|
||||||
BLState->OutgoingMsgQueue.WriteHead = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ enum bl_python_packet_type
|
||||||
PacketType_PatternCommand = 1,
|
PacketType_PatternCommand = 1,
|
||||||
PacketType_MotorState = 2,
|
PacketType_MotorState = 2,
|
||||||
PacketType_Temperature = 3,
|
PacketType_Temperature = 3,
|
||||||
|
PacketType_LumenariumStatus = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
@ -35,6 +36,32 @@ typedef struct temp_packet
|
||||||
{
|
{
|
||||||
s8 Temperature;
|
s8 Temperature;
|
||||||
} temp_packet;
|
} temp_packet;
|
||||||
|
|
||||||
|
enum motor_event_type
|
||||||
|
{
|
||||||
|
MotorEvent_Close = 0,
|
||||||
|
MotorEvent_Open = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct status_packet
|
||||||
|
{
|
||||||
|
u8 NextMotorEventType;
|
||||||
|
u32 NextEventTime;
|
||||||
|
char AnimFileName[32];
|
||||||
|
} status_packet;
|
||||||
|
|
||||||
|
typedef struct blumen_packet
|
||||||
|
{
|
||||||
|
bl_python_packet_type Type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
motor_packet MotorPacket;
|
||||||
|
microphone_packet MicPacket;
|
||||||
|
temp_packet TempPacket;
|
||||||
|
status_packet StatusPacket;
|
||||||
|
};
|
||||||
|
} blumen_packet;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#define BLUMEN_MESSAGE_QUEUE_COUNT 32
|
#define BLUMEN_MESSAGE_QUEUE_COUNT 32
|
||||||
|
@ -51,17 +78,41 @@ struct mic_listen_job_data
|
||||||
bool* Running;
|
bool* Running;
|
||||||
|
|
||||||
platform_socket_manager* SocketManager;
|
platform_socket_manager* SocketManager;
|
||||||
packet_ringbuffer* MicPacketBuffer;
|
blumen_network_msg_queue* IncomingMsgQueue;
|
||||||
platform_socket_handle_ ListenSocket;
|
platform_socket_handle_ ListenSocket;
|
||||||
|
|
||||||
blumen_network_msg_queue* OutgoingMsgQueue;
|
blumen_network_msg_queue* OutgoingMsgQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct time_range
|
||||||
|
{
|
||||||
|
s32 StartHour;
|
||||||
|
s32 StartMinute;
|
||||||
|
|
||||||
|
s32 EndHour;
|
||||||
|
s32 EndMinute;
|
||||||
|
} time_range;
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
SystemTimeIsInTimeRange(system_time SysTime, time_range Range)
|
||||||
|
{
|
||||||
|
bool Result = (SysTime.Hour >= Range.StartHour &&
|
||||||
|
SysTime.Minute >= Range.StartMinute &&
|
||||||
|
SysTime.Hour <= Range.EndHour &&
|
||||||
|
SysTime.Minute <= Range.EndMinute);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
global time_range MotorOpenTimes[] = {
|
||||||
|
{ 14, 28, 14, 29 }
|
||||||
|
};
|
||||||
|
global u32 MotorOpenTimesCount = 1;
|
||||||
|
|
||||||
struct blumen_lumen_state
|
struct blumen_lumen_state
|
||||||
{
|
{
|
||||||
bool Running;
|
bool Running;
|
||||||
|
|
||||||
packet_ringbuffer MicPacketBuffer;
|
blumen_network_msg_queue IncomingMsgQueue;
|
||||||
blumen_network_msg_queue OutgoingMsgQueue;
|
blumen_network_msg_queue OutgoingMsgQueue;
|
||||||
|
|
||||||
temp_job_req JobReq;
|
temp_job_req JobReq;
|
||||||
|
@ -75,6 +126,11 @@ struct blumen_lumen_state
|
||||||
|
|
||||||
animation_handle AnimHandles[3];
|
animation_handle AnimHandles[3];
|
||||||
u32 CurrAnim;
|
u32 CurrAnim;
|
||||||
|
|
||||||
|
// NOTE(pjs): Based on temperature data from weatherman
|
||||||
|
// dim the leds.
|
||||||
|
r32 BrightnessPercent;
|
||||||
|
system_time LastStatusUpdateTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,9 @@ int main(int ArgCount, char** Args)
|
||||||
printf("%.*s\n", (u32)OutputBuffer.Length, OutputBuffer.Str);
|
printf("%.*s\n", (u32)OutputBuffer.Length, OutputBuffer.Str);
|
||||||
//printf("%d\n", StripCount);
|
//printf("%d\n", StripCount);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue