aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorgbc dev <gbc@localhost>2026-07-15 10:17:19 +0200
committergbc dev <gbc@localhost>2026-07-15 10:17:19 +0200
commit458b9934afaa87e73af3154da3c98f045a954bbb (patch)
tree9ee6a6547f7512338e0a48952a56cf2702506872 /tools
parentgbctl: 'hud' kills any existing HUD pane before spawning (no double-HUD) (diff)
downloadsl0pboy-458b9934afaa87e73af3154da3c98f045a954bbb.tar.gz
sl0pboy-458b9934afaa87e73af3154da3c98f045a954bbb.tar.xz
sl0pboy-458b9934afaa87e73af3154da3c98f045a954bbb.zip
gbhud: live joypad display (cute Game Boy layout, buttons light up)
New INPUT section reads hJoyHeld (0xFFB4) and draws a d-pad cross + A/B circles + SEL/START pills; held buttons glow bright green, idle ones dim grey.
Diffstat (limited to 'tools')
-rwxr-xr-xtools/gbhud.py20
1 files changed, 20 insertions, 0 deletions
diff --git a/tools/gbhud.py b/tools/gbhud.py
index cb8b914..84e6b82 100755
--- a/tools/gbhud.py
+++ b/tools/gbhud.py
@@ -94,6 +94,7 @@ class Mem:
0xD340: self.read(0xD340, 0x60),
0xD520: self.read(0xD520, 0x20),
0xD720: self.read(0xD720, 0x20),
+ 0xFFB0: self.read(0xFFB0, 0x10), # HRAM: hJoyHeld @ 0xFFB4
}
def b(self, addr):
for base, blk in self.blocks.items():
@@ -120,6 +121,21 @@ def bar(cur, mx, width=10):
ANSI = re.compile(r"\x1b\[[0-9;]*m")
def vlen(x): return len(ANSI.sub("", x))
+# hJoyHeld bit layout: A=0 B=1 SELECT=2 START=3 RIGHT=4 LEFT=5 UP=6 DOWN=7
+def render_input(held):
+ def lit(s, on): # bright-green + bold = a lit button; dim grey = idle
+ return (f"\x1b[1;92m{s}\x1b[0m" if on else f"\x1b[2;90m{s}\x1b[0m")
+ U, D = held>>6&1, held>>7&1
+ L, R = held>>5&1, held>>4&1
+ A, B = held&1, held>>1&1
+ SE, ST = held>>2&1, held>>3&1
+ return [
+ " " + lit("▲", U) + " " + lit("Ⓑ", B) + " " + lit("Ⓐ", A),
+ lit("◄", L) + " " + lit("✜", 0) + " " + lit("►", R) + " " +
+ lit("▁SEL▁", SE) + " " + lit("▁START▁", ST),
+ " " + lit("▼", D),
+ ]
+
W = 46
def render(m, S, MAPS):
def s(name): return S.get(name, 0)
@@ -142,6 +158,10 @@ def render(m, S, MAPS):
row(f"{WH}{MAPS.get(mapid,'?')}{RESET} {DIM}(0x{mapid:02X}){RESET} tileset {m.b(s('wCurMapTileset'))}")
row(f"pos {YE}x={x:<2} y={y:<2}{RESET} facing {YE}{facing}{RESET}")
+ hr("INPUT")
+ for ln in render_input(m.b(0xFFB4)):
+ row(ln)
+
hr("MOVEMENT / COLLISION")
walk = m.b(s("wWalkCounter")); joyig = m.b(s("wJoyIgnore"))
front = m.b(s("wTileInFrontOfPlayer")); standing = m.b(s("wTilePlayerStandingOn"))