Display and UI¶
The UI is the part of this device people actually remember, and it is also the part where inventing something plausible is easiest and worst. So the rule here is stricter than elsewhere: screens are built from the archive's records, not written in code.
The display pipe¶
The panel is driven through the real pipe, with the firmware's own register values, including the tear-effect interrupt at 216 Hz.
The pipe composites more than one hardware window, and this settles something that looks like a UI question and is not. On a real-library boot:
| Window | Format | Geometry | Contents |
|---|---|---|---|
| 0 | 7 | 320×240 at (0,0) | premultiplied BGRA -- the UI, with its right half fully transparent |
| 1 | 3 | 240×240 at (80,0) | RGB565 -- the album art, composited underneath |
So the preview pane's cover is not drawn by the UI at all. The hardware puts a second surface behind a hole in the first. An emulator that read the 16bpp window at 32bpp produced artwork with the wrong geometry, and the bug was in the model, not the firmware.
Unmeasured pixel formats are refused rather than drawn, so a wrong guess shows up as a refusal instead of a plausible picture.
Screens build themselves¶
The archive is the UI. The code walks records; it does not encode screens.
| Record | What it decides |
|---|---|
SCST |
which controller class a screen uses |
ITEM |
a menu's rows, their labels, their value properties |
SORC |
where a row's value comes from |
CEVT |
key and control event bindings |
SEVT |
screen event bindings -- including where a chosen row goes |
TEVT |
timed events |
145 classes decode from the registry, 108 of them distinct, and a boot resolves live classes through the record. All eight navigator verbs dispatch on the archive's own bindings -- including two bindings that are dead, which the device also ignores. Reproducing the dead ones is the point: it means the dispatcher was recovered rather than reconstructed from what happens to be used.
The mistake this rule exists to prevent¶
An early table in this project said the Music row meant a particular screen. It read like recovered
work and was invented. The truth was two lookups away: the method raises an event, and the layout's
SEVT record names the target.
So the standing rule is: if a constant is about to be chosen in C, stop -- the archive or the code already states it. Go and find where.
The same shape showed up again later, and was again data: a row press on Albums or Artists did
nothing because those screens carry no CEVT at all, and the binding lives in the layout's SEVT
as list.chosen -> HandleSelect. The destinations were never missing. They were in a record nobody
had walked.
Slots, templates and a rule about indices¶
A slot on a screen is found by template, not by index. The status bar comes from
StatusBarWhite_Template on every screen, which is why a hand-built status bar class could be
deleted outright -- and the gate for that deletion was that the Language screen's frame came out
byte-identical, zero pixels different.
Retiring the invented backdrop on Home changed 736 pixels, and those 736 pixels were the invention going away.
Lists¶
Every list takes its row class from the ITEM record. Label insets and row pitch match the retail
firmware measured side by side in the emulator -- which is how a row pitch of 22 against the device's
24, and a list font of 77 against 75, were found and fixed.
Media list titles (class 0x7800) and their counts with correct singular and plural forms (class
0x6380) read out of the archive's own strings.
Album rows draw the artwork pair the builder's way: split from font metrics, the separator as a rule
at row.bottom - 1, and the .ithmb cell as the stride. Three bugs lived in that row unlooked-at
until it was measured against the original -- including a stride formula that agreed with every album
cover and was wrong the moment a poster was not square.
Text¶
FreeType, from upstream, at the configuration the image shows. Apple did not write a rasteriser here and neither will Chikuma. Fonts and colours are named resources whose values are recoverable exactly -- which is also why the wanted night mode is data rather than code.
Comparing against the original¶
Because both firmwares boot the same disk on the same machine, a screen is checked by subtraction: drive both, screenshot both, diff. Several screens are byte-identical. Where they are not, the number of differing pixels is the claim.