Embed controls.png into binary so it can run from any directory
The spritesheet is compiled in as a C byte array. An external controls.png in cwd still takes precedence for skinning. Includes tools/embed_png.py to regenerate the header if the asset changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8f8cbc97c7
commit
7e67589150
@ -15,16 +15,16 @@ See `docs/sdlamp2-fsd.md` for the full functional specification and changelog.
|
||||
```sh
|
||||
./build.sh # macOS — builds to build/sdlamp2
|
||||
./build_aarch64.sh # Linux aarch64 variant
|
||||
cd build && ./sdlamp2 [audio_directory]
|
||||
./build/sdlamp2 [audio_directory]
|
||||
```
|
||||
|
||||
The binary must be run from `build/` because it loads `controls.png` from the current working directory. Audio directory defaults to cwd if not specified.
|
||||
The controls spritesheet (`controls.png`) is embedded in the binary. If an external `controls.png` exists in the current working directory it takes precedence, allowing custom skins. Audio directory defaults to cwd if not specified.
|
||||
|
||||
No test suite, no linter, no Makefile/CMake.
|
||||
|
||||
## Architecture
|
||||
|
||||
Single-file C program: `src/sdlamp2.c` (~650 lines). No headers, no separate compilation units.
|
||||
Single-file C program: `src/sdlamp2.c` (~650 lines). One generated header: `src/controls_png.h` (embedded PNG byte array — regenerate with `./tools/embed_png.py build/controls.png src/controls_png.h` if the spritesheet changes).
|
||||
|
||||
Key sections in order:
|
||||
- **Decoder struct** — holds all FFmpeg state (format/codec contexts, swr resampler, album art texture)
|
||||
|
||||
@ -43,6 +43,11 @@ This document specifies the functional requirements for an SDL2 based media play
|
||||
|
||||
## 6. Changelog
|
||||
|
||||
### 2026-02-13 — Embed controls spritesheet into binary
|
||||
|
||||
- **Embedded asset**: `controls.png` is now compiled into the binary as a C byte array (`src/controls_png.h`), eliminating the requirement to run from the `build/` directory.
|
||||
- **External override**: If a `controls.png` file exists in the current working directory, it is loaded in preference to the embedded data, preserving the ability to use custom skins.
|
||||
|
||||
### 2026-02-11 — Debug flag for input diagnostics
|
||||
|
||||
- **`--debug` flag**: New command-line option (`./sdlamp2 --debug [audio_dir]`) that enables verbose logging of all SDL input events to stdout. Designed to diagnose controller issues on retro handheld devices where non-standard controllers may not be recognized by SDL's GameController API.
|
||||
|
||||
2123
src/controls_png.h
Normal file
2123
src/controls_png.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,8 @@
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
|
||||
#include "controls_png.h"
|
||||
|
||||
#define MAX_FILES 64
|
||||
#define SEEK_SECONDS 10.0
|
||||
|
||||
@ -626,6 +628,12 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
SDL_Surface* controls_surface = IMG_Load("controls.png");
|
||||
if (!controls_surface) {
|
||||
SDL_RWops* rw = SDL_RWFromConstMem(controls_png_data, controls_png_size);
|
||||
if (rw) {
|
||||
controls_surface = IMG_Load_RW(rw, 1);
|
||||
}
|
||||
}
|
||||
if (!controls_surface) {
|
||||
panic_and_abort("Could not load controls asset!", SDL_GetError());
|
||||
}
|
||||
|
||||
29
tools/embed_png.py
Executable file
29
tools/embed_png.py
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# embed_png.py — Convert a PNG file into a C header with a byte array.
|
||||
#
|
||||
# Usage: ./tools/embed_png.py build/controls.png src/controls_png.h
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print(f"Usage: {sys.argv[0]} <input.png> <output.h>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
input_path = sys.argv[1]
|
||||
output_path = sys.argv[2]
|
||||
|
||||
data = open(input_path, "rb").read()
|
||||
|
||||
with open(output_path, "w") as out:
|
||||
out.write("/* Auto-generated from controls.png — do not edit */\n\n")
|
||||
out.write("static const unsigned char controls_png_data[] = {\n")
|
||||
for i in range(0, len(data), 16):
|
||||
chunk = data[i : i + 16]
|
||||
out.write(" " + ", ".join(f"0x{b:02x}" for b in chunk) + ",\n")
|
||||
out.write("};\n\n")
|
||||
out.write(f"static const unsigned int controls_png_size = {len(data)};\n")
|
||||
|
||||
print(f"{input_path} -> {output_path} ({len(data)} bytes)")
|
||||
Loading…
x
Reference in New Issue
Block a user