Draws a score bar across the top 8 rows of the multicolor bitmap at
$E000-$E13F (320 bytes), with HARE on the far left, SCOOT on the far
right, and 5 pips for each player between them.
A pip is 8x8 pixels (2 cells wide x 1 cell tall = 16 bitmap bytes):
filled = 1-pixel white border around a 6x6 black block; empty = an 8x8
white square (the border alone). Pips are packed 2 cells each with
no gap, so adjacent pip borders merge into a 2-px white vertical
divider.
Labels use a hand-built 4x8 font (1 byte per row, top 4 bits = 4
pixels) for the 8 chars H/A/R/E/S/C/O/T (64 bytes total). Each font
row is expanded 1bpp -> 2bpp via a 16-byte lookup table (expand4):
each '1' becomes '11' (white, from color RAM), each '0' becomes '00'
(background black, from $D021).
score_render() also rewrites the top 40 cells' attributes
(screen memory = 0, color RAM = 1) so the score bar's palette is
exactly 2 colors. Scores are clamped to 0..5 on render to defend
against double-tap bugs in Phase 4.
Replace helloworld.c with main.c. Add memmap_setup/restore (banks out
KERNAL+BASIC+CHAR ROMs so $E000-$FFFF is free for the 8 KB bitmap and
$D000-$DFFF is I/O), show_screen(n) which copies the title .bin to
$E000 and the .attr to $D000 (screen memory in multicolor bitmap mode)
then flips the VIC into BMM=1 MCM=1 CSEL=1 RSEL=1 DEN=1 with bitmap
base CB13=1 and screen base VM13-VM10=4 ($D018 = 0x48), and
input_fire(port) which reads bit 4 of CIA1 $DC00/$DC01.
build.sh default target is now main.c -> whack_hare.prg (still
builds helloworld explicitly via the existing -c flag if needed).
Verified: ./build.sh -e runs the title screen in oscar64's built-in
emulator and exits cleanly. .map shows code at $0880-$09A6 and
embedded title data at $09A7-$2CCF, well within the 38 KB main
region. .prg is 9428 bytes, well under the 202-block LOAD"*",8,1
limit.
Concerns for Phase 3 (score bar): the score bar will overlay the top
8 pixel rows of the bitmap ($E000-$E13F, 320 bytes). show_screen()
will continue to copy the full .bin to $E000; score_render() will be
called immediately after and overwrite the top 320 bytes. This keeps
show_screen() dumb and lets the score bar be re-rendered on state
change without re-copying the whole 8 KB bitmap.
Adds tools/convert_screens.py which converts each source PNG to a
160x200 multicolor bitmap (8000 B .bin) plus a 1000 B .attr screen-
memory table, following c64-wiki Multicolor_Bitmap_Mode:
- 2-bit pixel: 00=$D021, 01=attr high nibble, 10=attr low nibble,
11=color RAM nibble.
- Per 4x8 cell: $D021 is forced into the 4-color set (it's global);
the other 3 are the 3 most common non-d021 colors in the cell.
- Pixels snap to the nearest of those 4, then packed 4-per-byte
MSB-first into the bitmap; attr byte = (cell_color_2 << 4) |
cell_color_1 (low nibble = '10' color, high = '01' color).
Tried two downscale strategies on all 5 source images; both produce
visually equivalent output at the ~9x source-to-target scale. Picked
Strategy A (direct 160x200 LANCZOS) as default because it's simpler
and slightly faster; Strategy B (LANCZOS 320x200 then 2x BOX 160x200)
remains available via --strategy. See the script docstring for the
detailed rationale.
$D021 is auto-picked as the most common C64 palette color in the
downscaled image (turns out to be black for 4 of 5 screens, dark grey
for waiting2). The .d021 sidecar files document this value so Phase 2
can program the VIC without re-deriving it.
The '11' color (color RAM nibble per cell) is not stored in .attr (no
room in 1000 B). Default is to leave color RAM at the C64 boot value
(black), which gives effectively 3 unique colors per cell + 1 global.
Phase 2 can either accept this or extend the format with a per-cell
color RAM table.
Generated files are checked in so the build doesn't depend on Python.
Output sizes verified: each .bin is exactly 8000 B, each .attr is
exactly 1000 B, total 9000 B per screen. The .bin files are not all
zero (sanity check passed).
VICE x64 is a GUI emulator that requires a real X11/Wayland display.
In this headless environment the KERNAL/BASIC/CHAR/1541 ROMs had to be
fetched manually, autostart produced blank screenshots (no display
to render to), and no other C64 emulator is installed. The oscar64
built-in emulator (-e) is the practical headless test tool. VICE is
left in build.sh as -v / -V for interactive use in a real terminal
session, but tasks.md and README.md are updated to reflect that the
development loop and all Verify steps use the oscar64 emulator.
Removed the failed test artifacts from src/build/.