Rename game from Whack Hare! to Nyuller
All references updated: - src/build.sh: PRG=nyuller.prg, D64=nyuller.d64, disk name 'ny', all grep/pgrep patterns updated, all comments updated - All 10 header files: include guards WHACK_HARE_* → NYULLER_* - C source comments: 'Whack Hare!' → 'Nyuller' - README.md: updated build command output path - GAME.md: title updated - tasks.md: all whack_hare.prg → nyuller.prg - src/AGENT_CONTEXT.md: project name updated - tools/convert_screens.py: project name updated Build artifacts renamed: whack_hare.* → nyuller.*, whack.d64 → nyuller.d64 Note: title screen image (source_images/screen_title.png) still shows 'WHACKED' logo — that's a visual asset, not a code reference.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# GAME.md — *Whack Hare!*
|
# GAME.md — *Nyuller*
|
||||||
|
|
||||||
A two-player reaction-time duel for the Commodore 64. Two players stand
|
A two-player reaction-time duel for the Commodore 64. Two players stand
|
||||||
back-to-back, take ten paces, and the first one to hit fire when the
|
back-to-back, take ten paces, and the first one to hit fire when the
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ git submodule update --init --recursive
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd src
|
cd src
|
||||||
./build.sh # compile main.c → build/whack_hare.prg (-O1)
|
./build.sh # compile main.c → build/nyuller.prg (-O1)
|
||||||
./build.sh -e # run in oscar64's built-in emulator (headless, fast)
|
./build.sh -e # run in oscar64's built-in emulator (headless, fast)
|
||||||
./build.sh -p # PLAY: launch VICE in background (see build.sh --help)
|
./build.sh -p # PLAY: launch VICE in background (see build.sh --help)
|
||||||
./build.sh -v # run in VICE x64 (foreground, blocks terminal)
|
./build.sh -v # run in VICE x64 (foreground, blocks terminal)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Project context for Whack Hare! subagent
|
# Project context for Nyuller subagent
|
||||||
|
|
||||||
You are implementing one phase of a C64 game called "Whack Hare!"
|
You are implementing one phase of a C64 game called "Nyuller."
|
||||||
(quick-draw duel between a rabbit and a kid on a scooter, first to 5
|
(quick-draw duel between a rabbit and a kid on a scooter, first to 5
|
||||||
wins). You will be given a specific phase task. This document is the
|
wins). You will be given a specific phase task. This document is the
|
||||||
context you need to do the work.
|
context you need to do the work.
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// audio.c — SID audio service for the Whack Hare! state machine.
|
// audio.c — SID audio service for the Nyuller state machine.
|
||||||
//
|
//
|
||||||
// The audio layer is a thin state-driven service. The game's
|
// The audio layer is a thin state-driven service. The game's
|
||||||
// per-state "enter" actions call audio_state_enter() to set up the
|
// per-state "enter" actions call audio_state_enter() to set up the
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
#ifndef WHACK_HARE_AUDIO_H
|
#ifndef NYULLER_AUDIO_H
|
||||||
#define WHACK_HARE_AUDIO_H
|
#define NYULLER_AUDIO_H
|
||||||
|
|
||||||
// audio.h — SID audio service for the Whack Hare! state machine.
|
// audio.h — SID audio service for the Nyuller state machine.
|
||||||
//
|
//
|
||||||
// The audio layer is a thin state-driven service: the game's per-state
|
// The audio layer is a thin state-driven service: the game's per-state
|
||||||
// "enter" actions call audio_state_enter() to set up the SID for that
|
// "enter" actions call audio_state_enter() to set up the SID for that
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_BANNER_H
|
#ifndef NYULLER_BANNER_H
|
||||||
#define WHACK_HARE_BANNER_H
|
#define NYULLER_BANNER_H
|
||||||
|
|
||||||
// banner.h — text banner rendering in the multicolor bitmap.
|
// banner.h — text banner rendering in the multicolor bitmap.
|
||||||
//
|
//
|
||||||
|
|||||||
+16
-16
@@ -2,7 +2,7 @@
|
|||||||
# build.sh — compile and optionally run a single C64 program with Oscar64.
|
# build.sh — compile and optionally run a single C64 program with Oscar64.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./build.sh # compile main.c → build/whack_hare.prg (-O1)
|
# ./build.sh # compile main.c → build/nyuller.prg (-O1)
|
||||||
# ./build.sh -e # run in oscar64's built-in emulator (headless, fast)
|
# ./build.sh -e # run in oscar64's built-in emulator (headless, fast)
|
||||||
# ./build.sh -p # PLAY: compile, wrap in .d64, launch VICE x64 detached
|
# ./build.sh -p # PLAY: compile, wrap in .d64, launch VICE x64 detached
|
||||||
# ./build.sh -P # PLAY: same as -p but with VICE x64sc (cycle-exact)
|
# ./build.sh -P # PLAY: same as -p but with VICE x64sc (cycle-exact)
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
# ./build.sh -g # compile with -g (adds source-level debug info)
|
# ./build.sh -g # compile with -g (adds source-level debug info)
|
||||||
#
|
#
|
||||||
# Output (in <repo>/build/):
|
# Output (in <repo>/build/):
|
||||||
# whack_hare.prg — loadable C64 program (run with x64, VICE, or real hw)
|
# nyuller.prg — loadable C64 program (run with x64, VICE, or real hw)
|
||||||
# whack_hare.asm — full 6502 listing
|
# nyuller.asm — full 6502 listing
|
||||||
# whack_hare.map — region/section/object placement
|
# nyuller.map — region/section/object placement
|
||||||
# whack_hare.lbl — VICE monitor label commands
|
# nyuller.lbl — VICE monitor label commands
|
||||||
# whack.d64 — disk image wrapping whack_hare.prg (for VICE autostart)
|
# nyuller.d64 — disk image wrapping nyuller.prg (for VICE autostart)
|
||||||
#
|
#
|
||||||
# For the development loop, use -e (oscar64's built-in emulator). It runs
|
# For the development loop, use -e (oscar64's built-in emulator). It runs
|
||||||
# without a display, needs no ROMs, and is faster than VICE. Use -p when
|
# without a display, needs no ROMs, and is faster than VICE. Use -p when
|
||||||
@@ -48,8 +48,8 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|||||||
OSCAR64_DIR="$ROOT/oscar64"
|
OSCAR64_DIR="$ROOT/oscar64"
|
||||||
OSCAR64_BIN="$OSCAR64_DIR/bin/oscar64"
|
OSCAR64_BIN="$OSCAR64_DIR/bin/oscar64"
|
||||||
BUILD_DIR="$ROOT/build"
|
BUILD_DIR="$ROOT/build"
|
||||||
PRG="$BUILD_DIR/whack_hare.prg"
|
PRG="$BUILD_DIR/nyuller.prg"
|
||||||
D64="$BUILD_DIR/whack.d64"
|
D64="$BUILD_DIR/nyuller.d64"
|
||||||
|
|
||||||
mkdir -p "$BUILD_DIR"
|
mkdir -p "$BUILD_DIR"
|
||||||
|
|
||||||
@@ -58,14 +58,14 @@ if [ "${1:-}" = "--kill" ]; then
|
|||||||
# pgrep -f uses ERE: + is a quantifier, so the regex must escape it.
|
# pgrep -f uses ERE: + is a quantifier, so the regex must escape it.
|
||||||
# x64(sc)? matches both "x64" and "x64sc". The process is launched
|
# x64(sc)? matches both "x64" and "x64sc". The process is launched
|
||||||
# with the literal argument string `+confirmonexit`.
|
# with the literal argument string `+confirmonexit`.
|
||||||
pids=$(pgrep -f "x64(sc)? \+confirmonexit.*whack\.d64" 2>/dev/null || true)
|
pids=$(pgrep -f "x64(sc)? \+confirmonexit.*nyuller\.d64" 2>/dev/null || true)
|
||||||
if [ -n "$pids" ]; then
|
if [ -n "$pids" ]; then
|
||||||
echo "killing VICE process(es): $pids"
|
echo "killing VICE process(es): $pids"
|
||||||
kill $pids 2>/dev/null || true
|
kill $pids 2>/dev/null || true
|
||||||
sleep 1
|
sleep 1
|
||||||
kill -9 $pids 2>/dev/null || true
|
kill -9 $pids 2>/dev/null || true
|
||||||
else
|
else
|
||||||
echo "no VICE process running (autostart of whack.d64)"
|
echo "no VICE process running (autostart of nyuller.d64)"
|
||||||
fi
|
fi
|
||||||
rm -f "$BUILD_DIR/vice.pid" "$BUILD_DIR/vice.log"
|
rm -f "$BUILD_DIR/vice.pid" "$BUILD_DIR/vice.log"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -132,11 +132,11 @@ build_d64() {
|
|||||||
echo "error: c1541 not found (needed to build the .d64 wrapper)" >&2
|
echo "error: c1541 not found (needed to build the .d64 wrapper)" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
c1541 -format wh,of d64 "$D64" >/dev/null 2>&1 || true
|
c1541 -format ny,of d64 "$D64" >/dev/null 2>&1 || true
|
||||||
c1541 "$D64" >/dev/null 2>&1 <<EOF || true
|
c1541 "$D64" >/dev/null 2>&1 <<EOF || true
|
||||||
write $PRG
|
write $PRG
|
||||||
EOF
|
EOF
|
||||||
if c1541 "$D64" 2>/dev/null <<EOF | grep -q "whack_hare.prg"
|
if c1541 "$D64" 2>/dev/null <<EOF | grep -q "nyuller.prg"
|
||||||
list
|
list
|
||||||
quit
|
quit
|
||||||
EOF
|
EOF
|
||||||
@@ -151,7 +151,7 @@ EOF
|
|||||||
# --- optional actions -----------------------------------------------------
|
# --- optional actions -----------------------------------------------------
|
||||||
case "$EMU_CMD" in
|
case "$EMU_CMD" in
|
||||||
"oscar64")
|
"oscar64")
|
||||||
echo "running whack_hare.prg in oscar64's built-in emulator"
|
echo "running nyuller.prg in oscar64's built-in emulator"
|
||||||
"$OSCAR64_BIN" -i="$OSCAR64_DIR/include" -o="$PRG" $OPT_FLAGS -e "$SRC"
|
"$OSCAR64_BIN" -i="$OSCAR64_DIR/include" -o="$PRG" $OPT_FLAGS -e "$SRC"
|
||||||
;;
|
;;
|
||||||
"x64"|"x64sc")
|
"x64"|"x64sc")
|
||||||
@@ -160,7 +160,7 @@ case "$EMU_CMD" in
|
|||||||
if [ -z "${DISPLAY:-}" ]; then
|
if [ -z "${DISPLAY:-}" ]; then
|
||||||
echo "warning: no \$DISPLAY set; VICE won't show a window" >&2
|
echo "warning: no \$DISPLAY set; VICE won't show a window" >&2
|
||||||
fi
|
fi
|
||||||
echo "running whack_hare in VICE ($EMU_CMD, blocking)"
|
echo "running nyuller in VICE ($EMU_CMD, blocking)"
|
||||||
"$EMU_CMD" +confirmonexit -autostart "$D64"
|
"$EMU_CMD" +confirmonexit -autostart "$D64"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -176,9 +176,9 @@ if [ -n "$PLAY_VICE" ]; then
|
|||||||
fi
|
fi
|
||||||
# If a previous VICE is still running, kill it before launching a
|
# If a previous VICE is still running, kill it before launching a
|
||||||
# new one — otherwise the two windows will fight for the same
|
# new one — otherwise the two windows will fight for the same
|
||||||
# display and the old one's whack_hare will keep running in the
|
# display and the old one's nyuller will keep running in the
|
||||||
# background.
|
# background.
|
||||||
existing=$(pgrep -f "x64(sc)? \+confirmonexit.*whack\.d64" 2>/dev/null || true)
|
existing=$(pgrep -f "x64(sc)? \+confirmonexit.*nyuller\.d64" 2>/dev/null || true)
|
||||||
if [ -n "$existing" ]; then
|
if [ -n "$existing" ]; then
|
||||||
echo "killing previous VICE process(es): $existing"
|
echo "killing previous VICE process(es): $existing"
|
||||||
kill $existing 2>/dev/null || true
|
kill $existing 2>/dev/null || true
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_DRAW_H
|
#ifndef NYULLER_DRAW_H
|
||||||
#define WHACK_HARE_DRAW_H
|
#define NYULLER_DRAW_H
|
||||||
|
|
||||||
// draw.h — DRAW screen counter rendering.
|
// draw.h — DRAW screen counter rendering.
|
||||||
//
|
//
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// game.c — Whack Hare! state machine.
|
// game.c — Nyuller state machine.
|
||||||
//
|
//
|
||||||
// See game.h for the transition diagram and game_init() / game_step()
|
// See game.h for the transition diagram and game_init() / game_step()
|
||||||
// documentation. Each state has an "enter" action (set the screen,
|
// documentation. Each state has an "enter" action (set the screen,
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
#ifndef WHACK_HARE_GAME_H
|
#ifndef NYULLER_GAME_H
|
||||||
#define WHACK_HARE_GAME_H
|
#define NYULLER_GAME_H
|
||||||
|
|
||||||
// game.h — Whack Hare! state machine.
|
// game.h — Nyuller state machine.
|
||||||
//
|
//
|
||||||
// States (see game.c for the per-state behavior and the transition
|
// States (see game.c for the per-state behavior and the transition
|
||||||
// diagram from GAME.md §9):
|
// diagram from GAME.md §9):
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_INPUT_H
|
#ifndef NYULLER_INPUT_H
|
||||||
#define WHACK_HARE_INPUT_H
|
#define NYULLER_INPUT_H
|
||||||
|
|
||||||
// input_fire(port) — returns 1 if the fire button on the given joystick
|
// input_fire(port) — returns 1 if the fire button on the given joystick
|
||||||
// port is currently pressed, 0 otherwise.
|
// port is currently pressed, 0 otherwise.
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// main.c — Whack Hare! entry point (Phase 5: raster IRQ + idle loop).
|
// main.c — Nyuller entry point (Phase 5: raster IRQ + idle loop).
|
||||||
//
|
//
|
||||||
// Flow:
|
// Flow:
|
||||||
// 1. memmap_setup() — bank out KERNAL/BASIC/CHAR ROM.
|
// 1. memmap_setup() — bank out KERNAL/BASIC/CHAR ROM.
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_MEMMAP_H
|
#ifndef NYULLER_MEMMAP_H
|
||||||
#define WHACK_HARE_MEMMAP_H
|
#define NYULLER_MEMMAP_H
|
||||||
|
|
||||||
#include <c64/memmap.h>
|
#include <c64/memmap.h>
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_NOTES_H
|
#ifndef NYULLER_NOTES_H
|
||||||
#define WHACK_HARE_NOTES_H
|
#define NYULLER_NOTES_H
|
||||||
|
|
||||||
// notes.h — 16-bit SID frequency values for the musical notes used by
|
// notes.h — 16-bit SID frequency values for the musical notes used by
|
||||||
// the game. PAL C64 (985248 Hz system clock); see the oscar64 sid.h
|
// the game. PAL C64 (985248 Hz system clock); see the oscar64 sid.h
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_SCORE_H
|
#ifndef NYULLER_SCORE_H
|
||||||
#define WHACK_HARE_SCORE_H
|
#define NYULLER_SCORE_H
|
||||||
|
|
||||||
// score.h — score state and rendering for the top-of-screen score bar.
|
// score.h — score state and rendering for the top-of-screen score bar.
|
||||||
//
|
//
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_SCREENS_H
|
#ifndef NYULLER_SCREENS_H
|
||||||
#define WHACK_HARE_SCREENS_H
|
#define NYULLER_SCREENS_H
|
||||||
|
|
||||||
// Screen IDs. Pass to show_screen() to switch to a new screen.
|
// Screen IDs. Pass to show_screen() to switch to a new screen.
|
||||||
#define SCREEN_TITLE 0
|
#define SCREEN_TITLE 0
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WHACK_HARE_TICK_H
|
#ifndef NYULLER_TICK_H
|
||||||
#define WHACK_HARE_TICK_H
|
#define NYULLER_TICK_H
|
||||||
|
|
||||||
// tick.h — 50 Hz raster IRQ setup for the game tick.
|
// tick.h — 50 Hz raster IRQ setup for the game tick.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Tasks — Whack Hare! implementation plan
|
# Tasks — Nyuller implementation plan
|
||||||
|
|
||||||
A phased, testable plan. Each phase ends with a *verify* step that
|
A phased, testable plan. Each phase ends with a *verify* step that
|
||||||
proves the phase works. Each phase is one or more commits. Stop at any
|
proves the phase works. Each phase is one or more commits. Stop at any
|
||||||
@@ -171,7 +171,7 @@ state.
|
|||||||
- `cd src && ./build.sh -e` displays the title screen in the
|
- `cd src && ./build.sh -e` displays the title screen in the
|
||||||
oscar64 built-in emulator for 5 seconds (or until fire is pressed)
|
oscar64 built-in emulator for 5 seconds (or until fire is pressed)
|
||||||
then exits.
|
then exits.
|
||||||
- (Optional, interactive) `x64 build/whack_hare.prg` in a real
|
- (Optional, interactive) `x64 build/nyuller.prg` in a real
|
||||||
terminal session displays the title screen on real timings.
|
terminal session displays the title screen on real timings.
|
||||||
Compare visually to `source_images/screen_title.png`.
|
Compare visually to `source_images/screen_title.png`.
|
||||||
- The .map file shows our code is in $0900-$1100-ish, well within
|
- The .map file shows our code is in $0900-$1100-ish, well within
|
||||||
@@ -304,7 +304,7 @@ random source.
|
|||||||
**Verify:**
|
**Verify:**
|
||||||
- The game still works in the oscar64 built-in emulator
|
- The game still works in the oscar64 built-in emulator
|
||||||
(`build.sh -e`).
|
(`build.sh -e`).
|
||||||
- (Optional, interactive) Launch `x64sc build/whack_hare.prg`
|
- (Optional, interactive) Launch `x64sc build/nyuller.prg`
|
||||||
in a real terminal to confirm the game runs at cycle-exact PAL
|
in a real terminal to confirm the game runs at cycle-exact PAL
|
||||||
timing (50.125 Hz). The state transitions happen on the right
|
timing (50.125 Hz). The state transitions happen on the right
|
||||||
raster lines. The 50 Hz tick is rock-solid.
|
raster lines. The 50 Hz tick is rock-solid.
|
||||||
@@ -363,7 +363,7 @@ becomes audible.
|
|||||||
- GAMEOVER: longer fanfare.
|
- GAMEOVER: longer fanfare.
|
||||||
- The cues are recognizable and feel right (timing, volume).
|
- The cues are recognizable and feel right (timing, volume).
|
||||||
- (Optional, interactive) Run the audio cues under `x64sc
|
- (Optional, interactive) Run the audio cues under `x64sc
|
||||||
build/whack_hare.prg` in a real terminal to confirm the
|
build/nyuller.prg` in a real terminal to confirm the
|
||||||
SID envelope generator timings are right; the oscar64 emulator
|
SID envelope generator timings are right; the oscar64 emulator
|
||||||
is fast but not always bit-accurate on SID timing, and the
|
is fast but not always bit-accurate on SID timing, and the
|
||||||
`x64sc` cycle-exact path is the one that matches real hardware.
|
`x64sc` cycle-exact path is the one that matches real hardware.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Convert a C64 game source PNG into multicolor-bitmap .bin + .attr files.
|
"""Convert a C64 game source PNG into multicolor-bitmap .bin + .attr files.
|
||||||
|
|
||||||
Phase 1 of the "Whack Hare!" C64 project. See tasks.md for the full spec.
|
Phase 1 of the "Nyuller" C64 project. See tasks.md for the full spec.
|
||||||
|
|
||||||
The C64 multicolor bitmap mode (VIC-II $D011 BMM=1, $D016 MCM=1) is a
|
The C64 multicolor bitmap mode (VIC-II $D011 BMM=1, $D016 MCM=1) is a
|
||||||
160x200-pixel, 2-bits-per-pixel, 4-colors-per-4x8-cell format. The
|
160x200-pixel, 2-bits-per-pixel, 4-colors-per-4x8-cell format. The
|
||||||
|
|||||||
Reference in New Issue
Block a user