Starfield

Source: src/starfield.c · 61 lines · 4 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

paletteCount() · source line 14
static unsigned paletteCount(starfield_palette_t palette)
  1. Exit this functionreturn palette == STARFIELD_COLOUR ? sizeof(colour_colours) / sizeof(colour_colours[0]) : sizeof(greyscale_colours) / sizeof(greyscale_colours[0]);
Read original function source
static unsigned paletteCount(starfield_palette_t palette)
{
    return palette == STARFIELD_COLOUR ? sizeof(colour_colours) / sizeof(colour_colours[0]) :
        sizeof(greyscale_colours) / sizeof(greyscale_colours[0]);
}
starfield_initialize() · source line 20
void starfield_initialize(starfield_t *field, unsigned count, int left, int top,
                          int width, int height, starfield_palette_t palette)

Calls into this documentation:

  1. Decisionfield == NULL || width <= 0 || height <= 0
    True
    1. Exit this functionreturn;
    False

    Continue after this decision.

  2. Executefield->count = count > STARFIELD_MAX_STARS ? STARFIELD_MAX_STARS : (uint8_t)count;
  3. Executefield->palette = palette;
  4. Executeconst unsigned shades = paletteCount(palette);
  5. FOR loopunsigned i = 0; i < field->count; ++i

    Repeat body while the loop condition permits; then continue below.

      1. Executefield->stars[i] = (starfield_star_t){ .x = (uint16_t)(left + esp_random() % (unsigned)width), .y = (uint16_t)(top + esp_random() % (unsigned)height), .twinkle_delay = 150U + esp_random() % 651U, .shade = (uint8_t)(esp_random() % shades), };
Read original function source
void starfield_initialize(starfield_t *field, unsigned count, int left, int top,
                          int width, int height, starfield_palette_t palette)
{
    if (field == NULL || width <= 0 || height <= 0) return;
    field->count = count > STARFIELD_MAX_STARS ? STARFIELD_MAX_STARS : (uint8_t)count;
    field->palette = palette;
    const unsigned shades = paletteCount(palette);
    for (unsigned i = 0; i < field->count; ++i) {
        field->stars[i] = (starfield_star_t){
            .x = (uint16_t)(left + esp_random() % (unsigned)width),
            .y = (uint16_t)(top + esp_random() % (unsigned)height),
            .twinkle_delay = 150U + esp_random() % 651U,
            .shade = (uint8_t)(esp_random() % shades),
        };
    }
}
starfield_update() · source line 37
void starfield_update(starfield_t *field, uint32_t elapsed_ms)

Calls into this documentation:

  1. Decisionfield == NULL
    True
    1. Exit this functionreturn;
    False

    Continue after this decision.

  2. Executeconst unsigned shades = paletteCount(field->palette);
  3. FOR loopunsigned i = 0; i < field->count; ++i

    Repeat body while the loop condition permits; then continue below.

      1. Executestarfield_star_t *star = &field->stars[i];
      2. Decisionelapsed_ms < star->twinkle_delay
        True
          1. Executestar->twinkle_delay -= elapsed_ms;
        False
          1. Executestar->shade = (uint8_t)((star->shade + 1U + esp_random() % (shades - 1U)) % shades);
          2. Executestar->twinkle_delay = 150U + esp_random() % 651U;
Read original function source
void starfield_update(starfield_t *field, uint32_t elapsed_ms)
{
    if (field == NULL) return;
    const unsigned shades = paletteCount(field->palette);
    for (unsigned i = 0; i < field->count; ++i) {
        starfield_star_t *star = &field->stars[i];
        if (elapsed_ms < star->twinkle_delay) {
            star->twinkle_delay -= elapsed_ms;
        } else {
            star->shade = (uint8_t)((star->shade + 1U + esp_random() % (shades - 1U)) % shades);
            star->twinkle_delay = 150U + esp_random() % 651U;
        }
    }
}
starfield_draw() · source line 52
void starfield_draw(uint16_t *frame, const starfield_t *field)

Calls into this documentation:

  1. Decisionframe == NULL || field == NULL
    True
    1. Exit this functionreturn;
    False

    Continue after this decision.

  2. Executeconst uint16_t *colours = field->palette == STARFIELD_COLOUR ? colour_colours : greyscale_colours;
  3. Executeconst unsigned shades = paletteCount(field->palette);
  4. FOR loopunsigned i = 0; i < field->count; ++i

    Repeat body while the loop condition permits; then continue below.

      1. Executeconst starfield_star_t *star = &field->stars[i];
      2. Executefill_rect(frame, star->x, star->y, 1, 1, colours[star->shade % shades]);
Read original function source
void starfield_draw(uint16_t *frame, const starfield_t *field)
{
    if (frame == NULL || field == NULL) return;
    const uint16_t *colours = field->palette == STARFIELD_COLOUR ? colour_colours : greyscale_colours;
    const unsigned shades = paletteCount(field->palette);
    for (unsigned i = 0; i < field->count; ++i) {
        const starfield_star_t *star = &field->stars[i];
        fill_rect(frame, star->x, star->y, 1, 1, colours[star->shade % shades]);
    }
}
Complete original file, including constants and data
/* Coded By JD(2026) */
#error "Reference listing only — not provided as build-ready source."
#include "starfield.h"
#include "esp_random.h"
#include "game_graphics.h"
#include <stddef.h>

static const uint16_t greyscale_colours[] = {
    RGB565(48, 48, 48), RGB565(88, 88, 88), RGB565(136, 136, 136),
    RGB565(192, 192, 192), RGB565(248, 248, 248),
};
static const uint16_t colour_colours[] = {
    COLOR_DARKCYAN, COLOR_CYAN, COLOR_YELLOW, COLOR_MAGENTA, COLOR_LIGHTGRAY, COLOR_RED,
};

static unsigned paletteCount(starfield_palette_t palette)
{
    return palette == STARFIELD_COLOUR ? sizeof(colour_colours) / sizeof(colour_colours[0]) :
        sizeof(greyscale_colours) / sizeof(greyscale_colours[0]);
}

void starfield_initialize(starfield_t *field, unsigned count, int left, int top,
                          int width, int height, starfield_palette_t palette)
{
    if (field == NULL || width <= 0 || height <= 0) return;
    field->count = count > STARFIELD_MAX_STARS ? STARFIELD_MAX_STARS : (uint8_t)count;
    field->palette = palette;
    const unsigned shades = paletteCount(palette);
    for (unsigned i = 0; i < field->count; ++i) {
        field->stars[i] = (starfield_star_t){
            .x = (uint16_t)(left + esp_random() % (unsigned)width),
            .y = (uint16_t)(top + esp_random() % (unsigned)height),
            .twinkle_delay = 150U + esp_random() % 651U,
            .shade = (uint8_t)(esp_random() % shades),
        };
    }
}

void starfield_update(starfield_t *field, uint32_t elapsed_ms)
{
    if (field == NULL) return;
    const unsigned shades = paletteCount(field->palette);
    for (unsigned i = 0; i < field->count; ++i) {
        starfield_star_t *star = &field->stars[i];
        if (elapsed_ms < star->twinkle_delay) {
            star->twinkle_delay -= elapsed_ms;
        } else {
            star->shade = (uint8_t)((star->shade + 1U + esp_random() % (shades - 1U)) % shades);
            star->twinkle_delay = 150U + esp_random() % 651U;
        }
    }
}

void starfield_draw(uint16_t *frame, const starfield_t *field)
{
    if (frame == NULL || field == NULL) return;
    const uint16_t *colours = field->palette == STARFIELD_COLOUR ? colour_colours : greyscale_colours;
    const unsigned shades = paletteCount(field->palette);
    for (unsigned i = 0; i < field->count; ++i) {
        const starfield_star_t *star = &field->stars[i];
        fill_rect(frame, star->x, star->y, 1, 1, colours[star->shade % shades]);
    }
}