ColemanCDA
(Alsey Coleman Miller)
July 13, 2026, 9:48am
1
main ← feature/ipod
opened 03:11AM - 13 Jul 26 UTC
## Summary
A fifth port of `CelesteCore`: a **Rockbox plugin** for the iPod Nan… o 2G, with the engine compiled as **Embedded Swift for `armv4t-none-none-eabi`** — the Nano's FPU-less ARM940T — and linked into `celeste.rock` by Rockbox's own build system. Verified playable on hardware at a steady 30 Hz, with sound effects.
Architecturally this inverts the 3DS port: Rockbox calls the C `plugin_start()` in `ports/iPod/plugin/celeste.c`, which owns the loop, buttons, pacing, and blitting, and calls three `@_cdecl` Swift entry points (`celeste_init` / `celeste_frame` / `celeste_restart`). The 128×128 canvas renders 1:1, centered on the 176×132 RGB565 LCD.
## Highlights
- **Swift on ARMv4T**: the prebuilt `armv4t-none-none-eabi` Embedded Swift stdlib (swift-6.3.2+) makes this work out of the box; the entire runtime surface the plugin supplies is a ~350-line C shim (TLSF-backed allocator, non-atomic `__atomic_*` stubs — safe on a single-core plugin whose Swift never leaves the main thread — EABI mem helpers, and soft-float `sinf`/`fmodf`/`floorf`).
- **Symbol-audit gate**: `scripts/check-undefined.sh` fails the build if the Swift object grows a dependency the shim doesn't satisfy, turning cryptic GNU ld errors into actionable ones.
- **SFX audio**: `tools/gen_audio.py` packs the SDL2 port's WAVs into `sfx.bin` (~1.5 MB, deployed to `/.rockbox/celeste/`, loaded into the audio buffer at startup — far too big for the 512 KB plugin buffer) mixed through Rockbox's channel-mixer API, the same one the Doom plugin uses. Music is a later phase.
- **Controls** (click wheel): LEFT/RIGHT move, MENU/PLAY up/down, SELECT jump, **wheel flick = dash** (edge-triggered, so momentary scroll events suffice), HOLD switch pauses. A 4-frame vertical-assist window makes diagonal dashes forgiving.
- **Core fixes that surfaced on this target**: `destroyObject` now resets entities in place instead of reallocating (heap churn on every death/smoke particle), and `Entity.reset()` was added to support that.
- **Build**: `make rock` runs Rockbox's in-tree build against a pinned checkout; the arm-elf-eabi-gcc 9.5 toolchain builds in Docker on macOS (GCC 9.5 can't be built with an arm64 Darwin host) and natively on Linux. `make sim`/`make run-sim` drive the Rockbox UI simulator with a C stub standing in for the ARM-only Swift objects. `make install IPOD=/Volumes/<name>` deploys.
- **CI**: a fast per-PR job builds + audits the armv4t archive; a push-to-main job builds the full `celeste.rock` on a native Linux runner with the cross toolchain cached, uploading it as an artifact.
Final `.rock` is ~130 KB (text 102 KB + data 28 KB + bss 33 KB) against the 512 KB plugin buffer.
## Test plan
- [x] On-device (Nano 2G): title screen, full gameplay, death/respawn, pause menu, quit, USB handling
- [x] SFX audible on device; silent fallback when `sfx.bin` is absent
- [x] Rockbox UI simulator: loop/blit/input/pause scaffolding via `celeste_stub.c`
- [x] SDL2 port still builds (shared-core changes are guarded)
- [x] `nm -u` allowlist audit + size report on every build
Summary
A fifth port of CelesteCore: a Rockbox plugin for the iPod Nano 2G, with the engine compiled as Embedded Swift for armv4t-none-none-eabi — the Nano's FPU-less ARM940T — and linked into celeste.rock by Rockbox's own build system. Verified playable on hardware at a steady 30 Hz, with sound effects.
Rockbox calls the C plugin_start() in ports/iPod/plugin/celeste.c, which owns the loop, buttons, pacing, and blitting, and calls three @_cdecl Swift entry points (celeste_init / celeste_frame / celeste_restart). The 128×128 canvas renders 1:1, centered on the 176×132 RGB565 LCD.
Final .rock is ~130 KB (text 102 KB + data 28 KB + bss 33 KB) against the 512 KB plugin buffer.
5 Likes
Very cool project. Getting Embedded Swift running on an old Armv4t device and keeping it playable at 30 Hz is impressive. I'd be interested to see more details about the toolchain and any challenges you ran into with such limited hardware.