Matrix
Source: src/matrix.c · 158 lines · 8 functions.
Screen captures
Views of this part running on the Mini Arcade.

Screen / module overview
- Enter Matrix
Seed the random generator. Initialise up to 40 falling columns and select speed X4.
- Handle controls
E cycles speed. A counts secret presses: 15 presses, with no gap longer than 750 ms, calls addGold(666).
- Wait for next update
updateMatrix() returns until 40 ms has passed.
- Advance every column
Add column speed multiplied by the selected speed. Reset columns after their entire trails leave the display.
- Publish a frame
Set frame_ready. matrixTakeFrame() returns the flag and clears it.
- Draw and repeat
Clear black; draw white heads and fading green glyphs or binary digits. Draw speed text. Repeat until stopped.
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
next_random() · source line 49
static uint32_t next_random(void)
- Execute
random_state ^= random_state << 13; - Execute
random_state ^= random_state >> 17; - Execute
random_state ^= random_state << 5; - Exit this function
return random_state;
Read original function source
static uint32_t next_random(void)
{
random_state ^= random_state << 13;
random_state ^= random_state >> 17;
random_state ^= random_state << 5;
return random_state;
}reset_column() · source line 57
static void reset_column(matrix_column_t *column)
Calls into this documentation:
- Execute
column->y = -(float)(next_random() % LCD_HEIGHT); - Execute
column->speed = (float)(8U + next_random() % 17U) / 10.0f; - Execute
column->length = 8U + next_random() % 15U;
Read original function source
static void reset_column(matrix_column_t *column)
{
column->y = -(float)(next_random() % LCD_HEIGHT);
column->speed = (float)(8U + next_random() % 17U) / 10.0f;
column->length = 8U + next_random() % 15U;
}startMatrix() · source line 64
void startMatrix(uint32_t now_ms)
Calls into this documentation:
- Execute
random_state = esp_random(); - Decision
random_state == 0UTrue- Execute
random_state = 0x9E3779B9U;
FalseContinue after this decision.
- Execute
column_count = LCD_WIDTH / CHAR_WIDTH; - Decision
column_count > MAX_COLUMNSTrue- Execute
column_count = MAX_COLUMNS;
FalseContinue after this decision.
- FOR loop
unsigned index = 0; index < column_count; ++indexRepeat body while the loop condition permits; then continue below.
- Execute
columns[index].x = (int)index * CHAR_WIDTH; - Execute
reset_column(&columns[index]);
- Execute
last_frame = now_ms; - Execute
last_secret_press = 0; - Execute
secret_press_count = 0; - Execute
speed_index = AI_SPEED_DEFAULT_INDEX; - Execute
frame_ready = true; - Execute
running = true;
Read original function source
void startMatrix(uint32_t now_ms)
{
random_state = esp_random();
if (random_state == 0U) random_state = 0x9E3779B9U;
column_count = LCD_WIDTH / CHAR_WIDTH;
if (column_count > MAX_COLUMNS) column_count = MAX_COLUMNS;
for (unsigned index = 0; index < column_count; ++index) {
columns[index].x = (int)index * CHAR_WIDTH;
reset_column(&columns[index]);
}
last_frame = now_ms;
last_secret_press = 0;
secret_press_count = 0;
speed_index = AI_SPEED_DEFAULT_INDEX;
frame_ready = true;
running = true;
}stopMatrix() · source line 82
void stopMatrix(void)
- Execute
running = false; - Execute
frame_ready = false; - Execute
secret_press_count = 0;
Read original function source
void stopMatrix(void)
{
running = false;
frame_ready = false;
secret_press_count = 0;
}matrixAction() · source line 89
void matrixAction(bool secret_press, bool speed, uint32_t now_ms)
Calls into this documentation:
- Decision
!runningTrue- Exit this function
return;
FalseContinue after this decision.
- Decision
speedTrue- Execute
cycleAISpeed(&speed_index); - Exit this function
return;
FalseContinue after this decision.
- Decision
!secret_pressTrue- Exit this function
return;
FalseContinue after this decision.
- Decision
secret_press_count != 0U && now_ms - last_secret_press > SECRET_PRESS_WINDOW_MSTrue- Execute
secret_press_count = 0;
FalseContinue after this decision.
- Execute
last_secret_press = now_ms; - Execute
++secret_press_count; - Decision
secret_press_count < SECRET_PRESS_COUNTTrue- Exit this function
return;
FalseContinue after this decision.
- Execute
addGold(666U); - Execute
last_secret_press = 0; - Execute
secret_press_count = 0;
Read original function source
void matrixAction(bool secret_press, bool speed, uint32_t now_ms)
{
if (!running) return;
if (speed) {
cycleAISpeed(&speed_index);
return;
}
if (!secret_press) return;
if (secret_press_count != 0U &&
now_ms - last_secret_press > SECRET_PRESS_WINDOW_MS) {
secret_press_count = 0;
}
last_secret_press = now_ms;
++secret_press_count;
if (secret_press_count < SECRET_PRESS_COUNT) return;
addGold(666U);
last_secret_press = 0;
secret_press_count = 0;
}updateMatrix() · source line 109
void updateMatrix(uint32_t now_ms)
Calls into this documentation:
- Decision
!running || now_ms - last_frame < FRAME_INTERVAL_MSTrue- Exit this function
return;
FalseContinue after this decision.
- Execute
last_frame = now_ms; - FOR loop
unsigned index = 0; index < column_count; ++indexRepeat body while the loop condition permits; then continue below.
- Execute
matrix_column_t *column = &columns[index]; - Execute
column->y += column->speed * (float)(1U << speed_index); - Decision
column->y - (float)(column->length * CHAR_HEIGHT) > LCD_HEIGHTTrue- Execute
reset_column(column);
FalseContinue after this decision.
- Execute
frame_ready = true;
Read original function source
void updateMatrix(uint32_t now_ms)
{
if (!running || now_ms - last_frame < FRAME_INTERVAL_MS) return;
last_frame = now_ms;
for (unsigned index = 0; index < column_count; ++index) {
matrix_column_t *column = &columns[index];
column->y += column->speed * (float)(1U << speed_index);
if (column->y - (float)(column->length * CHAR_HEIGHT) > LCD_HEIGHT) {
reset_column(column);
}
}
frame_ready = true;
}matrixTakeFrame() · source line 123
bool matrixTakeFrame(void)
- Execute
const bool ready = frame_ready; - Execute
frame_ready = false; - Exit this function
return ready;
Read original function source
bool matrixTakeFrame(void)
{
const bool ready = frame_ready;
frame_ready = false;
return ready;
}drawMatrix() · source line 130
void drawMatrix(uint16_t *frame)
Calls into this documentation:
- Execute
clear(frame, COLOR_BLACK); - FOR loop
unsigned column_index = 0; column_index < column_count; ++column_indexRepeat body while the loop condition permits; then continue below.
- Execute
const matrix_column_t *column = &columns[column_index]; - FOR loop
unsigned character_index = 0; character_index < column->length; ++character_indexRepeat body while the loop condition permits; then continue below.
- Execute
const int y = (int)column->y - (int)(character_index * CHAR_HEIGHT); - Decision
y < -CHAR_HEIGHT || y >= LCD_HEIGHTTrue- Next loop iteration
continue;
FalseContinue after this decision.
- Execute
const uint16_t color = character_index == 0U ? COLOR_WHITE : RGB565(0, (220 - (int)character_index * 12) > 20 ? 220 - (int)character_index * 12 : 20, 0); - Decision
next_random() % 5U == 0UTrue- Execute
const unsigned glyph = next_random() % (sizeof(matrix_glyphs) / sizeof(matrix_glyphs[0])); - Execute
draw_bitmap_scaled(frame, column->x, y, matrix_glyphs[glyph], 8, 8, 8, 8, color);
False- Execute
const char character[2] = { next_random() & 1U ? '1' : '0', '\0' }; - Execute
draw_text(frame, column->x, y, character, 1, color);
- Execute
draw_text(frame, 4, 156, "E SPEED", 1, COLOR_LIGHTGREEN); - Execute
draw_text(frame, 58, 156, aiSpeedShortText(speed_index), 1, COLOR_WHITE);
Read original function source
void drawMatrix(uint16_t *frame)
{
clear(frame, COLOR_BLACK);
for (unsigned column_index = 0; column_index < column_count; ++column_index) {
const matrix_column_t *column = &columns[column_index];
for (unsigned character_index = 0; character_index < column->length;
++character_index) {
const int y = (int)column->y - (int)(character_index * CHAR_HEIGHT);
if (y < -CHAR_HEIGHT || y >= LCD_HEIGHT) continue;
const uint16_t color = character_index == 0U ? COLOR_WHITE :
RGB565(0, (220 - (int)character_index * 12) > 20 ?
220 - (int)character_index * 12 : 20, 0);
if (next_random() % 5U == 0U) {
const unsigned glyph = next_random() %
(sizeof(matrix_glyphs) / sizeof(matrix_glyphs[0]));
draw_bitmap_scaled(frame, column->x, y, matrix_glyphs[glyph],
8, 8, 8, 8, color);
} else {
const char character[2] = {
next_random() & 1U ? '1' : '0', '\0'
};
draw_text(frame, column->x, y, character, 1, color);
}
}
}
draw_text(frame, 4, 156, "E SPEED", 1, COLOR_LIGHTGREEN);
draw_text(frame, 58, 156, aiSpeedShortText(speed_index), 1, COLOR_WHITE);
}Complete original file, including constants and data
/* Coded By JD(2026) */
#error "Reference listing only — not provided as build-ready source."
#include "matrix.h"
#include "game_graphics.h"
#include "PET2001_font.h"
#include "gold.h"
#include "ai_speed.h"
#include "esp_random.h"
#define MAX_COLUMNS 40U
#define CHAR_WIDTH 8
#define CHAR_HEIGHT 8
#define FRAME_INTERVAL_MS 40U
#define SECRET_PRESS_WINDOW_MS 750U
#define SECRET_PRESS_COUNT 15U
typedef struct {
int x;
float y;
float speed;
uint8_t length;
} matrix_column_t;
static const uint8_t matrix_glyphs[][8] = {
{0x7E,0x42,0x5A,0x5A,0x5A,0x42,0x7E,0x00},
{0x18,0x7E,0x18,0x24,0x42,0x81,0x00,0x00},
{0x7E,0x08,0x3E,0x2A,0x3E,0x08,0x08,0x00},
{0x42,0x24,0x18,0x24,0x42,0x00,0x00,0x00},
{0x7E,0x10,0x3C,0x10,0x7E,0x00,0x00,0x00},
{0x7E,0x08,0x18,0x08,0x7E,0x00,0x00,0x00},
{0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x3C,0x42,0x02,0x3E,0x42,0x3C,0x00,0x00},
{0x7E,0x08,0x3E,0x08,0x7E,0x00,0x00,0x00},
{0x42,0x24,0x18,0x18,0x18,0x00,0x00,0x00},
{0x00,0x3E,0x29,0x4A,0x08,0x18,0x70,0x00},
{0x80,0xF8,0xCC,0xC6,0xC6,0xCC,0xF8,0x80},
{0x60,0xC0,0xA0,0x10,0x2C,0x0A,0x0A,0x0C},
{0x3C,0x7E,0xFF,0x5A,0x18,0x18,0x3C,0x7E},
};
static matrix_column_t columns[MAX_COLUMNS];
static unsigned column_count;
static uint32_t random_state;
static uint32_t last_frame;
static uint32_t last_secret_press;
static uint8_t secret_press_count;
static uint8_t speed_index;
static bool running;
static bool frame_ready;
static uint32_t next_random(void)
{
random_state ^= random_state << 13;
random_state ^= random_state >> 17;
random_state ^= random_state << 5;
return random_state;
}
static void reset_column(matrix_column_t *column)
{
column->y = -(float)(next_random() % LCD_HEIGHT);
column->speed = (float)(8U + next_random() % 17U) / 10.0f;
column->length = 8U + next_random() % 15U;
}
void startMatrix(uint32_t now_ms)
{
random_state = esp_random();
if (random_state == 0U) random_state = 0x9E3779B9U;
column_count = LCD_WIDTH / CHAR_WIDTH;
if (column_count > MAX_COLUMNS) column_count = MAX_COLUMNS;
for (unsigned index = 0; index < column_count; ++index) {
columns[index].x = (int)index * CHAR_WIDTH;
reset_column(&columns[index]);
}
last_frame = now_ms;
last_secret_press = 0;
secret_press_count = 0;
speed_index = AI_SPEED_DEFAULT_INDEX;
frame_ready = true;
running = true;
}
void stopMatrix(void)
{
running = false;
frame_ready = false;
secret_press_count = 0;
}
void matrixAction(bool secret_press, bool speed, uint32_t now_ms)
{
if (!running) return;
if (speed) {
cycleAISpeed(&speed_index);
return;
}
if (!secret_press) return;
if (secret_press_count != 0U &&
now_ms - last_secret_press > SECRET_PRESS_WINDOW_MS) {
secret_press_count = 0;
}
last_secret_press = now_ms;
++secret_press_count;
if (secret_press_count < SECRET_PRESS_COUNT) return;
addGold(666U);
last_secret_press = 0;
secret_press_count = 0;
}
void updateMatrix(uint32_t now_ms)
{
if (!running || now_ms - last_frame < FRAME_INTERVAL_MS) return;
last_frame = now_ms;
for (unsigned index = 0; index < column_count; ++index) {
matrix_column_t *column = &columns[index];
column->y += column->speed * (float)(1U << speed_index);
if (column->y - (float)(column->length * CHAR_HEIGHT) > LCD_HEIGHT) {
reset_column(column);
}
}
frame_ready = true;
}
bool matrixTakeFrame(void)
{
const bool ready = frame_ready;
frame_ready = false;
return ready;
}
void drawMatrix(uint16_t *frame)
{
clear(frame, COLOR_BLACK);
for (unsigned column_index = 0; column_index < column_count; ++column_index) {
const matrix_column_t *column = &columns[column_index];
for (unsigned character_index = 0; character_index < column->length;
++character_index) {
const int y = (int)column->y - (int)(character_index * CHAR_HEIGHT);
if (y < -CHAR_HEIGHT || y >= LCD_HEIGHT) continue;
const uint16_t color = character_index == 0U ? COLOR_WHITE :
RGB565(0, (220 - (int)character_index * 12) > 20 ?
220 - (int)character_index * 12 : 20, 0);
if (next_random() % 5U == 0U) {
const unsigned glyph = next_random() %
(sizeof(matrix_glyphs) / sizeof(matrix_glyphs[0]));
draw_bitmap_scaled(frame, column->x, y, matrix_glyphs[glyph],
8, 8, 8, 8, color);
} else {
const char character[2] = {
next_random() & 1U ? '1' : '0', '\0'
};
drawPet2001TextTransparent(frame, column->x, y, character, color, 1);
}
}
}
drawPet2001TextTransparent(frame, 4, 156, "E SPEED", COLOR_LIGHTGREEN, 1);
drawPet2001TextTransparent(frame, 58, 156, aiSpeedShortText(speed_index), COLOR_WHITE, 1);
}