Demo Stage Plasma
Source: src/demo_stage_plasma.c · 143 lines · 8 functions.
Module entry points
These functions are exposed to the rest of the project. Open one to follow its decisions and the helpers it calls.
How to read these diagrams
Each function has its own expandable diagram using the actual expressions and statements from this file. Decisions split into True and False; loop bodies are indented. Returns end the function immediately; break and continue follow their C meanings. Arrows between statements show their order when execution reaches them.
These are structural source diagrams before preprocessing, not runtime traces. Conditional compilation and macros remain source expressions. Ternary choices remain inside their statement. Calls are linked separately; callback execution and task scheduling are not inferred.
Functions in this file
buildStageThirteenSineTable() · source line 54
static void buildStageThirteenSineTable(void)
- Decision
stage_thirteen_sine_table_readyTrue- Exit this function
return;
FalseContinue after this decision.
- FOR loop
unsigned index = 0U; index < DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE; ++indexRepeat body while the loop condition permits; then continue below.
- Execute
const float radians = (float)index * 2.0f * DEMO_STAGE_THIRTEEN_PI / (float)DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE; - Execute
stage_thirteen_sine_table[index] = (int8_t)lroundf(sinf(radians) * 127.0f);
- Execute
stage_thirteen_sine_table_ready = true;
Read original function source
static void buildStageThirteenSineTable(void)
{
if (stage_thirteen_sine_table_ready) return;
for (unsigned index = 0U; index < DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE; ++index) {
const float radians = (float)index * 2.0f * DEMO_STAGE_THIRTEEN_PI /
(float)DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE;
stage_thirteen_sine_table[index] = (int8_t)lroundf(sinf(radians) * 127.0f);
}
stage_thirteen_sine_table_ready = true;
}buildStageThirteenGradient() · source line 65
static void buildStageThirteenGradient(uint16_t *colours, uint8_t red, uint8_t green,
uint8_t blue)- FOR loop
unsigned index = 0U; index < DEMO_STAGE_THIRTEEN_GRADIENT_STEPS; ++indexRepeat body while the loop condition permits; then continue below.
- Execute
const unsigned distance = index <= DEMO_STAGE_THIRTEEN_GRADIENT_PEAK ? index : DEMO_STAGE_THIRTEEN_GRADIENT_STEPS - 1U - index; - Execute
const float fraction = (float)distance / (float)DEMO_STAGE_THIRTEEN_GRADIENT_PEAK; - Execute
const unsigned intensity = (unsigned)lroundf(powf(fraction, DEMO_STAGE_THIRTEEN_GRADIENT_GAMMA) * 255.0f); - Execute
colours[index] = RGB565((unsigned)red * intensity / 255U, (unsigned)green * intensity / 255U, (unsigned)blue * intensity / 255U);
Read original function source
static void buildStageThirteenGradient(uint16_t *colours, uint8_t red, uint8_t green,
uint8_t blue)
{
for (unsigned index = 0U; index < DEMO_STAGE_THIRTEEN_GRADIENT_STEPS; ++index) {
const unsigned distance = index <= DEMO_STAGE_THIRTEEN_GRADIENT_PEAK ?
index : DEMO_STAGE_THIRTEEN_GRADIENT_STEPS - 1U - index;
const float fraction = (float)distance / (float)DEMO_STAGE_THIRTEEN_GRADIENT_PEAK;
const unsigned intensity = (unsigned)lroundf(powf(fraction,
DEMO_STAGE_THIRTEEN_GRADIENT_GAMMA) * 255.0f);
colours[index] = RGB565((unsigned)red * intensity / 255U,
(unsigned)green * intensity / 255U,
(unsigned)blue * intensity / 255U);
}
}buildStageThirteenPalettes() · source line 80
static void buildStageThirteenPalettes(void)
Calls into this documentation:
- Decision
stage_thirteen_palettes_readyTrue- Exit this function
return;
FalseContinue after this decision.
- Execute
buildStageThirteenGradient(demo_plasma_red_colours, 255U, 0U, 0U); - Execute
buildStageThirteenGradient(demo_plasma_blue_colours, 0U, 80U, 255U); - Execute
buildStageThirteenGradient(demo_plasma_green_colours, 0U, 255U, 32U); - Execute
stage_thirteen_palettes_ready = true;
Read original function source
static void buildStageThirteenPalettes(void)
{
if (stage_thirteen_palettes_ready) return;
buildStageThirteenGradient(demo_plasma_red_colours, 255U, 0U, 0U);
buildStageThirteenGradient(demo_plasma_blue_colours, 0U, 80U, 255U);
buildStageThirteenGradient(demo_plasma_green_colours, 0U, 255U, 32U);
stage_thirteen_palettes_ready = true;
}demoStagePlasmaInitialize() · source line 89
void demoStagePlasmaInitialize(void)
Calls into this documentation:
- Execute
buildStageThirteenSineTable(); - Execute
buildStageThirteenPalettes();
Read original function source
void demoStagePlasmaInitialize(void)
{
buildStageThirteenSineTable();
buildStageThirteenPalettes();
}demoStagePlasmaStart() · source line 95
void demoStagePlasmaStart(void)
Calls into this documentation:
- Execute
demoStagePlasmaInitialize(); - Execute
stage_thirteen_effect_elapsed_ms = 0U; - Execute
plasma_palette_index = DEMO_PLASMA_RED_PALETTE_INDEX;
Read original function source
void demoStagePlasmaStart(void)
{
demoStagePlasmaInitialize();
stage_thirteen_effect_elapsed_ms = 0U;
plasma_palette_index = DEMO_PLASMA_RED_PALETTE_INDEX;
}demoStagePlasmaNextPalette() · source line 102
void demoStagePlasmaNextPalette(void)
- Execute
plasma_palette_index = (plasma_palette_index + 1U) % DEMO_PLASMA_PALETTE_COUNT;
Read original function source
void demoStagePlasmaNextPalette(void)
{
plasma_palette_index = (plasma_palette_index + 1U) % DEMO_PLASMA_PALETTE_COUNT;
}demoStagePlasmaUpdate() · source line 107
void demoStagePlasmaUpdate(uint32_t elapsed_ms)
- Execute
stage_thirteen_effect_elapsed_ms += elapsed_ms;
Read original function source
void demoStagePlasmaUpdate(uint32_t elapsed_ms)
{
stage_thirteen_effect_elapsed_ms += elapsed_ms;
}demoStagePlasmaDraw() · source line 112
void demoStagePlasmaDraw(uint16_t *frame)
Calls into this documentation:
- Execute
const int block_size = DEMO_STAGE_THIRTEEN_BLOCK_SIZE; - Execute
const demo_plasma_palette_t *palette = &demo_plasma_palettes[plasma_palette_index]; - Execute
const int palette_count = (int)palette->colour_count; - Execute
const unsigned phase_one = stage_thirteen_effect_elapsed_ms / DEMO_STAGE_THIRTEEN_WAVE_ONE_MS; - Execute
const unsigned phase_two = stage_thirteen_effect_elapsed_ms / DEMO_STAGE_THIRTEEN_WAVE_TWO_MS; - Execute
const unsigned phase_three = stage_thirteen_effect_elapsed_ms / DEMO_STAGE_THIRTEEN_WAVE_THREE_MS; - Execute
const unsigned phase_four = stage_thirteen_effect_elapsed_ms / DEMO_STAGE_THIRTEEN_WAVE_FOUR_MS; - FOR loop
int y = 0; y < LCD_HEIGHT; y += block_sizeRepeat body while the loop condition permits; then continue below.
- FOR loop
int x = 0; x < LCD_WIDTH; x += block_sizeRepeat body while the loop condition permits; then continue below.
- Execute
const unsigned cell_x = (unsigned)(x / block_size); - Execute
const unsigned cell_y = (unsigned)(y / block_size); - Execute
const int plasma_value = stage_thirteen_sine_table[(cell_x * 5U + phase_one) & 255U] + stage_thirteen_sine_table[(cell_y * 7U + phase_two) & 255U] + stage_thirteen_sine_table[((cell_x + cell_y) * 4U + phase_three) & 255U] + stage_thirteen_sine_table[(cell_x * 3U + cell_y * 6U + phase_four) & 255U]; - Execute
const int palette_index = (plasma_value + 508) * palette_count / 1017; - Execute
const int visible_width = x + block_size <= LCD_WIDTH ? block_size : LCD_WIDTH - x; - Execute
const int visible_height = y + block_size <= LCD_HEIGHT ? block_size : LCD_HEIGHT - y; - Execute
fill_rect(frame, x, y, visible_width, visible_height, palette->colours[palette_index]);
Read original function source
void demoStagePlasmaDraw(uint16_t *frame)
{
const int block_size = DEMO_STAGE_THIRTEEN_BLOCK_SIZE;
const demo_plasma_palette_t *palette = &demo_plasma_palettes[plasma_palette_index];
const int palette_count = (int)palette->colour_count;
const unsigned phase_one = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_ONE_MS;
const unsigned phase_two = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_TWO_MS;
const unsigned phase_three = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_THREE_MS;
const unsigned phase_four = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_FOUR_MS;
for (int y = 0; y < LCD_HEIGHT; y += block_size) {
for (int x = 0; x < LCD_WIDTH; x += block_size) {
const unsigned cell_x = (unsigned)(x / block_size);
const unsigned cell_y = (unsigned)(y / block_size);
const int plasma_value =
stage_thirteen_sine_table[(cell_x * 5U + phase_one) & 255U] +
stage_thirteen_sine_table[(cell_y * 7U + phase_two) & 255U] +
stage_thirteen_sine_table[((cell_x + cell_y) * 4U + phase_three) & 255U] +
stage_thirteen_sine_table[(cell_x * 3U + cell_y * 6U + phase_four) & 255U];
// Four waves range from -508 to 508; convert that to a palette index.
const int palette_index = (plasma_value + 508) * palette_count / 1017;
const int visible_width = x + block_size <= LCD_WIDTH ? block_size : LCD_WIDTH - x;
const int visible_height = y + block_size <= LCD_HEIGHT ? block_size : LCD_HEIGHT - y;
fill_rect(frame, x, y, visible_width, visible_height,
palette->colours[palette_index]);
}
}
}Complete original file, including constants and data
/* Coded By JD(2026) */
#error "Reference listing only — not provided as build-ready source."
#include "demo_stage_plasma.h"
#include "game_graphics.h"
#include <math.h>
#include <stddef.h>
#include <stdbool.h>
// Segment 13 -- full-screen demo-scene plasma beneath Demo's normal PET ticker.
// Smaller blocks make the moving plasma surface smoother but increase the number
// of RGB565 fills per frame; keep this at least 1 pixel.
#define DEMO_STAGE_THIRTEEN_BLOCK_SIZE 2
// Each cyclic ramp must be odd: the centre entry is the full base colour, while
// both endpoints are black. More steps soften the colour changes between cells.
#define DEMO_STAGE_THIRTEEN_GRADIENT_STEPS 33U
#define DEMO_STAGE_THIRTEEN_GRADIENT_PEAK (DEMO_STAGE_THIRTEEN_GRADIENT_STEPS / 2U)
// Values below 1.0 leave black faster, thickening coloured bands while keeping
// black only at each true trough. Raise toward 1.0 for more dark space.
#define DEMO_STAGE_THIRTEEN_GRADIENT_GAMMA 0.50f
#define DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE 256U
// Each wave advances by one lookup-table position at its own interval. Lower
// values make that wave move faster; differing values stop one obvious loop.
#define DEMO_STAGE_THIRTEEN_WAVE_ONE_MS 12U
#define DEMO_STAGE_THIRTEEN_WAVE_TWO_MS 17U
#define DEMO_STAGE_THIRTEEN_WAVE_THREE_MS 22U
#define DEMO_STAGE_THIRTEEN_WAVE_FOUR_MS 28U
#define DEMO_STAGE_THIRTEEN_PI 3.14159265f
// The palettes are generated dark-to-bright-to-dark, so the four-wave sum
// produces moving highlights rather than a hard colour wrap. B cycles them.
typedef struct {
const uint16_t *colours;
size_t colour_count;
} demo_plasma_palette_t;
static uint16_t demo_plasma_red_colours[DEMO_STAGE_THIRTEEN_GRADIENT_STEPS];
static uint16_t demo_plasma_blue_colours[DEMO_STAGE_THIRTEEN_GRADIENT_STEPS];
static uint16_t demo_plasma_green_colours[DEMO_STAGE_THIRTEEN_GRADIENT_STEPS];
#define DEMO_PLASMA_RED_PALETTE_INDEX 0U
static const demo_plasma_palette_t demo_plasma_palettes[] = {
{ demo_plasma_red_colours, sizeof(demo_plasma_red_colours) / sizeof(demo_plasma_red_colours[0]) },
{ demo_plasma_blue_colours, sizeof(demo_plasma_blue_colours) / sizeof(demo_plasma_blue_colours[0]) },
{ demo_plasma_green_colours, sizeof(demo_plasma_green_colours) / sizeof(demo_plasma_green_colours[0]) },
};
#define DEMO_PLASMA_PALETTE_COUNT (sizeof(demo_plasma_palettes) / sizeof(demo_plasma_palettes[0]))
static int8_t stage_thirteen_sine_table[DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE];
static bool stage_thirteen_sine_table_ready;
static bool stage_thirteen_palettes_ready;
static size_t plasma_palette_index;
static uint32_t stage_thirteen_effect_elapsed_ms;
static void buildStageThirteenSineTable(void)
{
if (stage_thirteen_sine_table_ready) return;
for (unsigned index = 0U; index < DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE; ++index) {
const float radians = (float)index * 2.0f * DEMO_STAGE_THIRTEEN_PI /
(float)DEMO_STAGE_THIRTEEN_SINE_TABLE_SIZE;
stage_thirteen_sine_table[index] = (int8_t)lroundf(sinf(radians) * 127.0f);
}
stage_thirteen_sine_table_ready = true;
}
static void buildStageThirteenGradient(uint16_t *colours, uint8_t red, uint8_t green,
uint8_t blue)
{
for (unsigned index = 0U; index < DEMO_STAGE_THIRTEEN_GRADIENT_STEPS; ++index) {
const unsigned distance = index <= DEMO_STAGE_THIRTEEN_GRADIENT_PEAK ?
index : DEMO_STAGE_THIRTEEN_GRADIENT_STEPS - 1U - index;
const float fraction = (float)distance / (float)DEMO_STAGE_THIRTEEN_GRADIENT_PEAK;
const unsigned intensity = (unsigned)lroundf(powf(fraction,
DEMO_STAGE_THIRTEEN_GRADIENT_GAMMA) * 255.0f);
colours[index] = RGB565((unsigned)red * intensity / 255U,
(unsigned)green * intensity / 255U,
(unsigned)blue * intensity / 255U);
}
}
static void buildStageThirteenPalettes(void)
{
if (stage_thirteen_palettes_ready) return;
buildStageThirteenGradient(demo_plasma_red_colours, 255U, 0U, 0U);
buildStageThirteenGradient(demo_plasma_blue_colours, 0U, 80U, 255U);
buildStageThirteenGradient(demo_plasma_green_colours, 0U, 255U, 32U);
stage_thirteen_palettes_ready = true;
}
void demoStagePlasmaInitialize(void)
{
buildStageThirteenSineTable();
buildStageThirteenPalettes();
}
void demoStagePlasmaStart(void)
{
demoStagePlasmaInitialize();
stage_thirteen_effect_elapsed_ms = 0U;
plasma_palette_index = DEMO_PLASMA_RED_PALETTE_INDEX;
}
void demoStagePlasmaNextPalette(void)
{
plasma_palette_index = (plasma_palette_index + 1U) % DEMO_PLASMA_PALETTE_COUNT;
}
void demoStagePlasmaUpdate(uint32_t elapsed_ms)
{
stage_thirteen_effect_elapsed_ms += elapsed_ms;
}
void demoStagePlasmaDraw(uint16_t *frame)
{
const int block_size = DEMO_STAGE_THIRTEEN_BLOCK_SIZE;
const demo_plasma_palette_t *palette = &demo_plasma_palettes[plasma_palette_index];
const int palette_count = (int)palette->colour_count;
const unsigned phase_one = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_ONE_MS;
const unsigned phase_two = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_TWO_MS;
const unsigned phase_three = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_THREE_MS;
const unsigned phase_four = stage_thirteen_effect_elapsed_ms /
DEMO_STAGE_THIRTEEN_WAVE_FOUR_MS;
for (int y = 0; y < LCD_HEIGHT; y += block_size) {
for (int x = 0; x < LCD_WIDTH; x += block_size) {
const unsigned cell_x = (unsigned)(x / block_size);
const unsigned cell_y = (unsigned)(y / block_size);
const int plasma_value =
stage_thirteen_sine_table[(cell_x * 5U + phase_one) & 255U] +
stage_thirteen_sine_table[(cell_y * 7U + phase_two) & 255U] +
stage_thirteen_sine_table[((cell_x + cell_y) * 4U + phase_three) & 255U] +
stage_thirteen_sine_table[(cell_x * 3U + cell_y * 6U + phase_four) & 255U];
// Four waves range from -508 to 508; convert that to a palette index.
const int palette_index = (plasma_value + 508) * palette_count / 1017;
const int visible_width = x + block_size <= LCD_WIDTH ? block_size : LCD_WIDTH - x;
const int visible_height = y + block_size <= LCD_HEIGHT ? block_size : LCD_HEIGHT - y;
fill_rect(frame, x, y, visible_width, visible_height,
palette->colours[palette_index]);
}
}
}