Pet2001 Font
Source: src/pet2001_font.c · 138 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
drawPet2001Glyph() · source line 13
void drawPet2001Glyph(uint16_t *frame, int x, int y, uint8_t glyph, bool reverse,
uint16_t foreground, uint16_t background, int scale)Calls into this documentation:
- Decision
frame == NULL || scale <= 0 || scale > INT_MAX / PET2001_FONT_GLYPH_WIDTHTrue- Exit this function
return;
FalseContinue after this decision.
- FOR loop
unsigned row = 0U; row < PET2001_FONT_GLYPH_HEIGHT; ++rowRepeat body while the loop condition permits; then continue below.
- Execute
const uint8_t bits = PET2001_FONT[glyph][row]; - FOR loop
unsigned column = 0U; column < PET2001_FONT_GLYPH_WIDTH; ++columnRepeat body while the loop condition permits; then continue below.
- Execute
bool pixel = (bits & (0x80U >> column)) != 0U; - Decision
reverseTrue- Execute
pixel = !pixel;
FalseContinue after this decision.
- Execute
fill_rect(frame, x + (int)column * scale, y + (int)row * scale, scale, scale, pixel ? foreground : background);
Read original function source
void drawPet2001Glyph(uint16_t *frame, int x, int y, uint8_t glyph, bool reverse,
uint16_t foreground, uint16_t background, int scale)
{
if (frame == NULL || scale <= 0 || scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH) return;
for (unsigned row = 0U; row < PET2001_FONT_GLYPH_HEIGHT; ++row) {
const uint8_t bits = PET2001_FONT[glyph][row];
for (unsigned column = 0U; column < PET2001_FONT_GLYPH_WIDTH; ++column) {
bool pixel = (bits & (0x80U >> column)) != 0U;
if (reverse) pixel = !pixel;
fill_rect(frame, x + (int)column * scale, y + (int)row * scale,
scale, scale, pixel ? foreground : background);
}
}
}drawPet2001Char() · source line 29
void drawPet2001Char(uint16_t *frame, int x, int y, uint8_t character,
uint16_t foreground, uint16_t background, int scale)Calls into this documentation:
- Execute
drawPet2001Glyph(frame, x, y, character & 0x7FU, (character & 0x80U) != 0U, foreground, background, scale);
Read original function source
void drawPet2001Char(uint16_t *frame, int x, int y, uint8_t character,
uint16_t foreground, uint16_t background, int scale)
{
drawPet2001Glyph(frame, x, y, character & 0x7FU, (character & 0x80U) != 0U,
foreground, background, scale);
}petCodeFromAscii() · source line 36
static uint8_t petCodeFromAscii(char character)
- Decision
character >= 'A' && character <= 'Z'True- Exit this function
return (uint8_t)(character - 'A' + 1);
FalseContinue after this decision.
- Decision
character >= 'a' && character <= 'z'True- Exit this function
return (uint8_t)(character - 'a' + 1);
FalseContinue after this decision.
- Exit this function
return (uint8_t)character;
Read original function source
static uint8_t petCodeFromAscii(char character)
{
if (character >= 'A' && character <= 'Z') return (uint8_t)(character - 'A' + 1);
if (character >= 'a' && character <= 'z') return (uint8_t)(character - 'a' + 1);
return (uint8_t)character;
}drawPet2001AsciiCharTransformed() · source line 43
void drawPet2001AsciiCharTransformed(uint16_t *frame, int centre_x, int centre_y,
char character, float scale, float angle_degrees,
uint16_t foreground)Calls into this documentation:
- Execute
const uint8_t glyph = petCodeFromAscii(character); - Execute
draw_bitmap_transformed(frame, centre_x, centre_y, PET2001_FONT[glyph], PET2001_FONT_GLYPH_WIDTH, PET2001_FONT_GLYPH_HEIGHT, scale, angle_degrees, foreground);
Read original function source
void drawPet2001AsciiCharTransformed(uint16_t *frame, int centre_x, int centre_y,
char character, float scale, float angle_degrees,
uint16_t foreground)
{
const uint8_t glyph = petCodeFromAscii(character);
draw_bitmap_transformed(frame, centre_x, centre_y, PET2001_FONT[glyph],
PET2001_FONT_GLYPH_WIDTH, PET2001_FONT_GLYPH_HEIGHT,
scale, angle_degrees, foreground);
}drawPet2001TextTransformed() · source line 53
void drawPet2001TextTransformed(uint16_t *frame, int destination_centre_x,
int destination_centre_y, const char *text,
int source_scale, float transform_scale,
float angle_degrees, uint16_t foreground)Calls into this documentation:
- Decision
frame == NULL || text == NULL || source_scale <= 0 || source_scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH || transform_scale <= 0.0f || !isfinite(transform_scale) || !isfinite(angle_degrees)True- Exit this function
return;
FalseContinue after this decision.
- Execute
const size_t length = strlen(text); - Decision
length == 0U || length > (size_t)INT_MAX / (PET2001_FONT_GLYPH_WIDTH * source_scale)True- Exit this function
return;
FalseContinue after this decision.
- Execute
const int source_width = (int)length * PET2001_FONT_GLYPH_WIDTH * source_scale; - Execute
const int source_height = PET2001_FONT_GLYPH_HEIGHT * source_scale; - Execute
const float radians = angle_degrees * 0.01745329252f; - Execute
const float cosine = cosf(radians), sine = sinf(radians); - Execute
const float centre_x = ((float)source_width - 1.0f) * 0.5f; - Execute
const float centre_y = ((float)source_height - 1.0f) * 0.5f; - FOR loop
size_t character = 0U; character < length; ++characterRepeat body while the loop condition permits; then continue below.
- Execute
const uint8_t *glyph = PET2001_FONT[petCodeFromAscii(text[character])]; - Execute
const int glyph_x = (int)character * PET2001_FONT_GLYPH_WIDTH * source_scale; - FOR loop
int row = 0; row < (int)PET2001_FONT_GLYPH_HEIGHT; ++rowRepeat body while the loop condition permits; then continue below.
- FOR loop
int column = 0; column < (int)PET2001_FONT_GLYPH_WIDTH; ++columnRepeat body while the loop condition permits; then continue below.
- Decision
(glyph[row] & (0x80U >> column)) == 0UTrue- Next loop iteration
continue;
FalseContinue after this decision.
- FOR loop
int pixel_y = 0; pixel_y < source_scale; ++pixel_yRepeat body while the loop condition permits; then continue below.
- FOR loop
int pixel_x = 0; pixel_x < source_scale; ++pixel_xRepeat body while the loop condition permits; then continue below.
- Execute
const float source_x = glyph_x + column * source_scale + pixel_x - centre_x; - Execute
const float source_y = row * source_scale + pixel_y - centre_y; - Execute
const int destination_x = (int)lroundf(destination_centre_x + (cosine * source_x - sine * source_y) * transform_scale); - Execute
const int destination_y = (int)lroundf(destination_centre_y + (sine * source_x + cosine * source_y) * transform_scale); - Decision
destination_x >= 0 && destination_x < LCD_WIDTH && destination_y >= 0 && destination_y < LCD_HEIGHTTrue- Execute
frame[(size_t)destination_y * LCD_WIDTH + destination_x] = foreground;
FalseContinue after this decision.
Read original function source
void drawPet2001TextTransformed(uint16_t *frame, int destination_centre_x,
int destination_centre_y, const char *text,
int source_scale, float transform_scale,
float angle_degrees, uint16_t foreground)
{
if (frame == NULL || text == NULL || source_scale <= 0 ||
source_scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH ||
transform_scale <= 0.0f || !isfinite(transform_scale) ||
!isfinite(angle_degrees)) return;
const size_t length = strlen(text);
if (length == 0U || length > (size_t)INT_MAX /
(PET2001_FONT_GLYPH_WIDTH * source_scale)) return;
const int source_width = (int)length * PET2001_FONT_GLYPH_WIDTH * source_scale;
const int source_height = PET2001_FONT_GLYPH_HEIGHT * source_scale;
const float radians = angle_degrees * 0.01745329252f;
const float cosine = cosf(radians), sine = sinf(radians);
const float centre_x = ((float)source_width - 1.0f) * 0.5f;
const float centre_y = ((float)source_height - 1.0f) * 0.5f;
for (size_t character = 0U; character < length; ++character) {
const uint8_t *glyph = PET2001_FONT[petCodeFromAscii(text[character])];
const int glyph_x = (int)character * PET2001_FONT_GLYPH_WIDTH * source_scale;
for (int row = 0; row < (int)PET2001_FONT_GLYPH_HEIGHT; ++row) {
for (int column = 0; column < (int)PET2001_FONT_GLYPH_WIDTH; ++column) {
if ((glyph[row] & (0x80U >> column)) == 0U) continue;
for (int pixel_y = 0; pixel_y < source_scale; ++pixel_y) {
for (int pixel_x = 0; pixel_x < source_scale; ++pixel_x) {
const float source_x = glyph_x + column * source_scale + pixel_x - centre_x;
const float source_y = row * source_scale + pixel_y - centre_y;
const int destination_x = (int)lroundf(destination_centre_x +
(cosine * source_x - sine * source_y) * transform_scale);
const int destination_y = (int)lroundf(destination_centre_y +
(sine * source_x + cosine * source_y) * transform_scale);
if (destination_x >= 0 && destination_x < LCD_WIDTH &&
destination_y >= 0 && destination_y < LCD_HEIGHT)
frame[(size_t)destination_y * LCD_WIDTH + destination_x] = foreground;
}
}
}
}
}
}drawPet2001Text() · source line 98
void drawPet2001Text(uint16_t *frame, int x, int y, const char *text, bool reverse,
uint16_t foreground, uint16_t background, int scale)Calls into this documentation:
- Decision
frame == NULL || text == NULL || scale <= 0 || scale > INT_MAX / PET2001_FONT_GLYPH_WIDTHTrue- Exit this function
return;
FalseContinue after this decision.
- FOR loop
size_t index = 0U; text[index] != '\0'; ++indexRepeat body while the loop condition permits; then continue below.
- Execute
uint8_t character = petCodeFromAscii(text[index]); - Decision
reverseTrue- Execute
character |= 0x80U;
FalseContinue after this decision.
- Execute
drawPet2001Char(frame, x + (int)index * PET2001_FONT_GLYPH_WIDTH * scale, y, character, foreground, background, scale);
Read original function source
void drawPet2001Text(uint16_t *frame, int x, int y, const char *text, bool reverse,
uint16_t foreground, uint16_t background, int scale)
{
if (frame == NULL || text == NULL || scale <= 0 ||
scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH) return;
for (size_t index = 0U; text[index] != '\0'; ++index) {
uint8_t character = petCodeFromAscii(text[index]);
if (reverse) character |= 0x80U;
drawPet2001Char(frame, x + (int)index * PET2001_FONT_GLYPH_WIDTH * scale, y,
character, foreground, background, scale);
}
}drawPet2001TextTransparent() · source line 112
void drawPet2001TextTransparent(uint16_t *frame, int x, int y, const char *text,
uint16_t foreground, int scale)Calls into this documentation:
- Decision
frame == NULL || text == NULL || scale <= 0 || scale > INT_MAX / PET2001_FONT_GLYPH_WIDTHTrue- Exit this function
return;
FalseContinue after this decision.
- FOR loop
size_t index = 0U; text[index] != '\0'; ++indexRepeat body while the loop condition permits; then continue below.
- Execute
const uint8_t *glyph = PET2001_FONT[petCodeFromAscii(text[index])]; - Execute
const int glyph_x = x + (int)index * PET2001_FONT_GLYPH_WIDTH * scale; - FOR loop
unsigned row = 0U; row < PET2001_FONT_GLYPH_HEIGHT; ++rowRepeat body while the loop condition permits; then continue below.
- FOR loop
unsigned column = 0U; column < PET2001_FONT_GLYPH_WIDTH; ++columnRepeat body while the loop condition permits; then continue below.
- Decision
(glyph[row] & (0x80U >> column)) == 0UTrue- Next loop iteration
continue;
FalseContinue after this decision.
- Execute
fill_rect(frame, glyph_x + (int)column * scale, y + (int)row * scale, scale, scale, foreground);
Read original function source
void drawPet2001TextTransparent(uint16_t *frame, int x, int y, const char *text,
uint16_t foreground, int scale)
{
if (frame == NULL || text == NULL || scale <= 0 ||
scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH) return;
for (size_t index = 0U; text[index] != '\0'; ++index) {
const uint8_t *glyph = PET2001_FONT[petCodeFromAscii(text[index])];
const int glyph_x = x + (int)index * PET2001_FONT_GLYPH_WIDTH * scale;
for (unsigned row = 0U; row < PET2001_FONT_GLYPH_HEIGHT; ++row) {
for (unsigned column = 0U; column < PET2001_FONT_GLYPH_WIDTH; ++column) {
if ((glyph[row] & (0x80U >> column)) == 0U) continue;
fill_rect(frame, glyph_x + (int)column * scale, y + (int)row * scale,
scale, scale, foreground);
}
}
}
}drawPet2001TextCentredTransparent() · source line 131
void drawPet2001TextCentredTransparent(uint16_t *frame, int centre_x, int y,
const char *text, uint16_t foreground, int scale)Calls into this documentation:
- Decision
text == NULL || scale <= 0 || strlen(text) > (size_t)INT_MAX / (PET2001_FONT_GLYPH_WIDTH * scale)True- Exit this function
return;
FalseContinue after this decision.
- Execute
const int width = (int)strlen(text) * PET2001_FONT_GLYPH_WIDTH * scale; - Execute
drawPet2001TextTransparent(frame, centre_x - width / 2, y, text, foreground, scale);
Read original function source
void drawPet2001TextCentredTransparent(uint16_t *frame, int centre_x, int y,
const char *text, uint16_t foreground, int scale)
{
if (text == NULL || scale <= 0 ||
strlen(text) > (size_t)INT_MAX / (PET2001_FONT_GLYPH_WIDTH * scale)) return;
const int width = (int)strlen(text) * PET2001_FONT_GLYPH_WIDTH * scale;
drawPet2001TextTransparent(frame, centre_x - width / 2, y, text, foreground, scale);
}Complete original file, including constants and data
/* Coded By JD(2026) */
#error "Reference listing only — not provided as build-ready source."
// Own the single global PET 2001 character-ROM definition.
#define PET2001_FONT_IMPLEMENTATION
#include "PET2001_font.h"
#include <stdbool.h>
#include <stddef.h>
#include <limits.h>
#include <math.h>
#include <string.h>
#include "game_graphics.h"
void drawPet2001Glyph(uint16_t *frame, int x, int y, uint8_t glyph, bool reverse,
uint16_t foreground, uint16_t background, int scale)
{
if (frame == NULL || scale <= 0 || scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH) return;
for (unsigned row = 0U; row < PET2001_FONT_GLYPH_HEIGHT; ++row) {
const uint8_t bits = PET2001_FONT[glyph][row];
for (unsigned column = 0U; column < PET2001_FONT_GLYPH_WIDTH; ++column) {
bool pixel = (bits & (0x80U >> column)) != 0U;
if (reverse) pixel = !pixel;
fill_rect(frame, x + (int)column * scale, y + (int)row * scale,
scale, scale, pixel ? foreground : background);
}
}
}
void drawPet2001Char(uint16_t *frame, int x, int y, uint8_t character,
uint16_t foreground, uint16_t background, int scale)
{
drawPet2001Glyph(frame, x, y, character & 0x7FU, (character & 0x80U) != 0U,
foreground, background, scale);
}
static uint8_t petCodeFromAscii(char character)
{
if (character >= 'A' && character <= 'Z') return (uint8_t)(character - 'A' + 1);
if (character >= 'a' && character <= 'z') return (uint8_t)(character - 'a' + 1);
return (uint8_t)character;
}
void drawPet2001AsciiCharTransformed(uint16_t *frame, int centre_x, int centre_y,
char character, float scale, float angle_degrees,
uint16_t foreground)
{
const uint8_t glyph = petCodeFromAscii(character);
draw_bitmap_transformed(frame, centre_x, centre_y, PET2001_FONT[glyph],
PET2001_FONT_GLYPH_WIDTH, PET2001_FONT_GLYPH_HEIGHT,
scale, angle_degrees, foreground);
}
void drawPet2001TextTransformed(uint16_t *frame, int destination_centre_x,
int destination_centre_y, const char *text,
int source_scale, float transform_scale,
float angle_degrees, uint16_t foreground)
{
if (frame == NULL || text == NULL || source_scale <= 0 ||
source_scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH ||
transform_scale <= 0.0f || !isfinite(transform_scale) ||
!isfinite(angle_degrees)) return;
const size_t length = strlen(text);
if (length == 0U || length > (size_t)INT_MAX /
(PET2001_FONT_GLYPH_WIDTH * source_scale)) return;
const int source_width = (int)length * PET2001_FONT_GLYPH_WIDTH * source_scale;
const int source_height = PET2001_FONT_GLYPH_HEIGHT * source_scale;
const float radians = angle_degrees * 0.01745329252f;
const float cosine = cosf(radians), sine = sinf(radians);
const float centre_x = ((float)source_width - 1.0f) * 0.5f;
const float centre_y = ((float)source_height - 1.0f) * 0.5f;
for (size_t character = 0U; character < length; ++character) {
const uint8_t *glyph = PET2001_FONT[petCodeFromAscii(text[character])];
const int glyph_x = (int)character * PET2001_FONT_GLYPH_WIDTH * source_scale;
for (int row = 0; row < (int)PET2001_FONT_GLYPH_HEIGHT; ++row) {
for (int column = 0; column < (int)PET2001_FONT_GLYPH_WIDTH; ++column) {
if ((glyph[row] & (0x80U >> column)) == 0U) continue;
for (int pixel_y = 0; pixel_y < source_scale; ++pixel_y) {
for (int pixel_x = 0; pixel_x < source_scale; ++pixel_x) {
const float source_x = glyph_x + column * source_scale + pixel_x - centre_x;
const float source_y = row * source_scale + pixel_y - centre_y;
const int destination_x = (int)lroundf(destination_centre_x +
(cosine * source_x - sine * source_y) * transform_scale);
const int destination_y = (int)lroundf(destination_centre_y +
(sine * source_x + cosine * source_y) * transform_scale);
if (destination_x >= 0 && destination_x < LCD_WIDTH &&
destination_y >= 0 && destination_y < LCD_HEIGHT)
frame[(size_t)destination_y * LCD_WIDTH + destination_x] = foreground;
}
}
}
}
}
}
void drawPet2001Text(uint16_t *frame, int x, int y, const char *text, bool reverse,
uint16_t foreground, uint16_t background, int scale)
{
if (frame == NULL || text == NULL || scale <= 0 ||
scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH) return;
for (size_t index = 0U; text[index] != '\0'; ++index) {
uint8_t character = petCodeFromAscii(text[index]);
if (reverse) character |= 0x80U;
drawPet2001Char(frame, x + (int)index * PET2001_FONT_GLYPH_WIDTH * scale, y,
character, foreground, background, scale);
}
}
void drawPet2001TextTransparent(uint16_t *frame, int x, int y, const char *text,
uint16_t foreground, int scale)
{
if (frame == NULL || text == NULL || scale <= 0 ||
scale > INT_MAX / PET2001_FONT_GLYPH_WIDTH) return;
for (size_t index = 0U; text[index] != '\0'; ++index) {
const uint8_t *glyph = PET2001_FONT[petCodeFromAscii(text[index])];
const int glyph_x = x + (int)index * PET2001_FONT_GLYPH_WIDTH * scale;
for (unsigned row = 0U; row < PET2001_FONT_GLYPH_HEIGHT; ++row) {
for (unsigned column = 0U; column < PET2001_FONT_GLYPH_WIDTH; ++column) {
if ((glyph[row] & (0x80U >> column)) == 0U) continue;
fill_rect(frame, glyph_x + (int)column * scale, y + (int)row * scale,
scale, scale, foreground);
}
}
}
}
void drawPet2001TextCentredTransparent(uint16_t *frame, int centre_x, int y,
const char *text, uint16_t foreground, int scale)
{
if (text == NULL || scale <= 0 ||
strlen(text) > (size_t)INT_MAX / (PET2001_FONT_GLYPH_WIDTH * scale)) return;
const int width = (int)strlen(text) * PET2001_FONT_GLYPH_WIDTH * scale;
drawPet2001TextTransparent(frame, centre_x - width / 2, y, text, foreground, scale);
}