108 lines
2.8 KiB
C
108 lines
2.8 KiB
C
|
#define LC_PERIOD 60000
|
||
|
#define LC_FREQ 1.0 / LC_PERIOD
|
||
|
|
||
|
struct Color {
|
||
|
float r, g, b;
|
||
|
};
|
||
|
|
||
|
#define COLOR_RED {1, 0, 0}
|
||
|
#define COLOR_GREEN {0, 1, 0}
|
||
|
#define COLOR_BLUE {0, 0, 1}
|
||
|
#define COLOR_ORANGE {1, 0.3, 0}
|
||
|
#define COLOR_YELLOW {1, 1, 0}
|
||
|
#define COLOR_PURPLE {0.4, 0, 1}
|
||
|
|
||
|
Color lc_multiplyColor(Color c, float x) {
|
||
|
return {c.r * x, c.g * x, c.b * x};
|
||
|
}
|
||
|
|
||
|
Color lc_interpolateColor(Color c1, Color c2, float x) {
|
||
|
Color c;
|
||
|
c.r = (1 - x) * c1.r + x * c2.r;
|
||
|
c.g = (1 - x) * c1.g + x * c2.g;
|
||
|
c.b = (1 - x) * c1.b + x * c2.b;
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
|
||
|
typedef Color (*lc_timeFunction)(unsigned int);
|
||
|
|
||
|
// Simple sin function with the same period as the standard LC_PERIOD.
|
||
|
Color lc_tf_greenLight(unsigned int elapsed_ms) {
|
||
|
double x = pow(sin(PI * LC_FREQ * 10 * elapsed_ms), 2);
|
||
|
return {0, x, 0};
|
||
|
}
|
||
|
|
||
|
// Fast sin function.
|
||
|
Color lc_tf_SinFast(unsigned int elapsed_ms) {
|
||
|
double x = (sin(2 * PI * LC_FREQ * 100 * elapsed_ms) + 1) / 2;
|
||
|
return {0, x, 0};
|
||
|
}
|
||
|
|
||
|
// Helper function for color-pulsing time functions.
|
||
|
Color lc_colorPulsar(unsigned int elapsed_ms, Color* colors, unsigned int count) {
|
||
|
const unsigned int colorPeriod = LC_PERIOD / count;
|
||
|
double x = (sin(2 * PI * LC_FREQ * count * elapsed_ms - PI / 2) + 1) / 2;
|
||
|
for (unsigned int i = 1; i <= count; i++) {
|
||
|
if (elapsed_ms < colorPeriod * i) {
|
||
|
return lc_multiplyColor(colors[i - 1], x);
|
||
|
}
|
||
|
}
|
||
|
return lc_multiplyColor({1, 1, 1}, x);
|
||
|
}
|
||
|
|
||
|
// Red, Green, then Blue pulse.
|
||
|
Color lc_tf_rgbPulse(unsigned int elapsed_ms) {
|
||
|
const Color colors[3];
|
||
|
colors[0] = COLOR_RED;
|
||
|
colors[1] = COLOR_GREEN;
|
||
|
colors[2] = COLOR_BLUE;
|
||
|
return lc_colorPulsar(elapsed_ms, colors, 3);
|
||
|
}
|
||
|
|
||
|
// Rainbow color function.
|
||
|
Color lc_tf_rainbowPulse(unsigned int elapsed_ms) {
|
||
|
const Color colors[6];
|
||
|
colors[0] = COLOR_RED;
|
||
|
colors[1] = COLOR_ORANGE;
|
||
|
colors[2] = COLOR_YELLOW;
|
||
|
colors[3] = COLOR_GREEN;
|
||
|
colors[4] = COLOR_BLUE;
|
||
|
colors[5] = COLOR_PURPLE;
|
||
|
return lc_colorPulsar(elapsed_ms, colors, 6);
|
||
|
}
|
||
|
|
||
|
Color lc_tf_yellowGreen(unsigned int elapsed_ms) {
|
||
|
const Color colors[2];
|
||
|
colors[0] = COLOR_YELLOW;
|
||
|
colors[1] = COLOR_GREEN;
|
||
|
return lc_colorPulsar(elapsed_ms, colors, 2);
|
||
|
}
|
||
|
|
||
|
// Flame
|
||
|
Color lc_tf_flame(unsigned int elapsed_ms) {
|
||
|
float colorValue = (sin(2 * PI * LC_FREQ * 10 * elapsed_ms) + 1) / 2;
|
||
|
float flameCoefficients[] = {
|
||
|
0.1, 0.35, 0.04, 0.75, 0.92, 0.55, 0.4, 0.22, 0.64, 0.85
|
||
|
};
|
||
|
const unsigned int fc_count = 10;
|
||
|
float flameIntensity = 0;
|
||
|
for (int i = 0; i < fc_count; i++) {
|
||
|
flameIntensity += (sin(2 * flameCoefficients[i] * elapsed_ms) + 1) / 2;
|
||
|
}
|
||
|
flameIntensity /= fc_count;
|
||
|
Color flame = lc_interpolateColor({1.0, 0.025, 0}, {1.0, 0.1, 0}, colorValue);
|
||
|
return lc_multiplyColor(flame, flameIntensity);
|
||
|
}
|
||
|
|
||
|
lc_timeFunction LC_TIME_FUNCTIONS[] = {
|
||
|
&lc_tf_flame,
|
||
|
&lc_tf_greenLight,
|
||
|
&lc_tf_yellowGreen,
|
||
|
&lc_tf_SinFast,
|
||
|
&lc_tf_rgbPulse,
|
||
|
&lc_tf_rainbowPulse
|
||
|
};
|
||
|
|
||
|
#define LC_TIME_FUNCTION_COUNT 6
|