romdevtools 0.16.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +75 -16
- package/CHANGELOG.md +316 -0
- package/examples/README.md +2 -0
- package/examples/atari2600/templates/platformer.asm +460 -0
- package/examples/atari2600/templates/racing.asm +463 -0
- package/examples/atari2600/templates/shmup.asm +386 -0
- package/examples/atari2600/templates/sports.asm +362 -0
- package/examples/atari7800/templates/default.c +49 -5
- package/examples/atari7800/templates/hello_sprite.c +48 -4
- package/examples/atari7800/templates/music_demo.c +47 -2
- package/examples/atari7800/templates/platformer.c +43 -4
- package/examples/atari7800/templates/puzzle.c +39 -4
- package/examples/atari7800/templates/racing.c +39 -4
- package/examples/atari7800/templates/shmup.c +40 -2
- package/examples/atari7800/templates/sports.c +36 -5
- package/examples/c64/templates/platformer.c +19 -5
- package/examples/c64/templates/puzzle.c +32 -2
- package/examples/c64/templates/shmup.c +28 -2
- package/examples/c64/templates/sports.c +30 -2
- package/examples/c64/templates/tile_engine.c +77 -27
- package/examples/gb/templates/default.c +110 -16
- package/examples/gb/templates/hello_sprite.c +15 -6
- package/examples/gb/templates/music_demo.c +36 -0
- package/examples/gb/templates/platformer.c +28 -6
- package/examples/gb/templates/puzzle.c +35 -4
- package/examples/gb/templates/racing.c +75 -10
- package/examples/gb/templates/shmup.c +41 -3
- package/examples/gb/templates/sports.c +51 -3
- package/examples/gb/templates/tile_engine.c +3 -2
- package/examples/gba/templates/gba_hello.c +29 -11
- package/examples/gba/templates/maxmod_demo.c +36 -2
- package/examples/gba/templates/platformer.c +3 -1
- package/examples/gba/templates/puzzle.c +15 -3
- package/examples/gba/templates/racing.c +65 -3
- package/examples/gba/templates/shmup.c +41 -4
- package/examples/gba/templates/sports.c +36 -2
- package/examples/gba/templates/tonc_hello.c +41 -5
- package/examples/gba/templates/tonc_hello_sprite.c +35 -1
- package/examples/gbc/templates/default.c +103 -26
- package/examples/gbc/templates/hello_sprite.c +12 -3
- package/examples/gbc/templates/music_demo.c +56 -12
- package/examples/gbc/templates/platformer.c +28 -6
- package/examples/gbc/templates/puzzle.c +35 -4
- package/examples/gbc/templates/racing.c +88 -21
- package/examples/gbc/templates/shmup.c +37 -3
- package/examples/gbc/templates/sports.c +48 -3
- package/examples/gbc/templates/tile_engine.c +3 -2
- package/examples/genesis/main.s +53 -1
- package/examples/genesis/templates/hello_sprite.c +25 -3
- package/examples/genesis/templates/puzzle.c +37 -3
- package/examples/genesis/templates/racing.c +44 -11
- package/examples/genesis/templates/sgdk_hello.c +34 -1
- package/examples/genesis/templates/shmup.c +31 -1
- package/examples/genesis/templates/shmup_2p.c +31 -0
- package/examples/genesis/templates/xgm2_demo.c +20 -0
- package/examples/gg/templates/default.c +56 -18
- package/examples/gg/templates/hello_sprite.c +25 -2
- package/examples/gg/templates/music_demo.c +24 -2
- package/examples/gg/templates/platformer.c +18 -12
- package/examples/gg/templates/puzzle.c +38 -7
- package/examples/gg/templates/racing.c +58 -9
- package/examples/gg/templates/shmup.c +47 -3
- package/examples/gg/templates/sports.c +57 -16
- package/examples/gg/templates/tile_engine.c +12 -6
- package/examples/lynx/templates/default.c +39 -8
- package/examples/lynx/templates/hello_sprite.c +15 -1
- package/examples/lynx/templates/music_demo.c +13 -1
- package/examples/lynx/templates/puzzle.c +28 -1
- package/examples/lynx/templates/racing.c +34 -7
- package/examples/lynx/templates/shmup.c +42 -3
- package/examples/lynx/templates/sports.c +29 -2
- package/examples/msx/platformer/main.c +213 -0
- package/examples/msx/puzzle/main.c +250 -0
- package/examples/msx/racing/main.c +249 -0
- package/examples/msx/shmup/main.c +288 -0
- package/examples/msx/sports/main.c +182 -0
- package/examples/nes/templates/default.c +67 -19
- package/examples/nes/templates/hello_sprite.c +35 -0
- package/examples/nes/templates/music_demo.c +40 -0
- package/examples/nes/templates/platformer.c +65 -6
- package/examples/nes/templates/puzzle.c +67 -6
- package/examples/nes/templates/racing.c +45 -13
- package/examples/nes/templates/shmup.c +51 -2
- package/examples/nes/templates/sports.c +51 -6
- package/examples/pce/catch_game/main.c +22 -3
- package/examples/pce/music_sfx/main.c +28 -1
- package/examples/pce/platformer/main.c +283 -0
- package/examples/pce/puzzle/main.c +304 -0
- package/examples/pce/racing/main.c +304 -0
- package/examples/pce/shmup/main.c +346 -0
- package/examples/pce/sports/main.c +254 -0
- package/examples/pce/sprite_move/main.c +7 -2
- package/examples/sms/main.c +35 -6
- package/examples/sms/templates/hello_sprite.c +29 -3
- package/examples/sms/templates/music_demo.c +18 -4
- package/examples/sms/templates/puzzle.c +34 -5
- package/examples/sms/templates/racing.c +39 -2
- package/examples/sms/templates/shmup.c +41 -2
- package/examples/sms/templates/shmup_2p.c +24 -1
- package/examples/sms/templates/sports.c +47 -4
- package/examples/snes/main.asm +108 -17
- package/examples/snes/templates/c-hello-data.asm +23 -0
- package/examples/snes/templates/c-hello.c +18 -1
- package/examples/snes/templates/default.c +50 -28
- package/examples/snes/templates/hello_sprite-data.asm +23 -0
- package/examples/snes/templates/hello_sprite.c +17 -1
- package/examples/snes/templates/music_demo-data.asm +23 -0
- package/examples/snes/templates/music_demo.c +22 -4
- package/examples/snes/templates/platformer-data.asm +22 -0
- package/examples/snes/templates/platformer.c +20 -2
- package/examples/snes/templates/puzzle-data.asm +22 -0
- package/examples/snes/templates/puzzle.c +21 -2
- package/examples/snes/templates/racing-data.asm +22 -0
- package/examples/snes/templates/racing.c +17 -1
- package/examples/snes/templates/shmup-data.asm +22 -0
- package/examples/snes/templates/shmup.c +20 -1
- package/examples/snes/templates/sports-data.asm +22 -0
- package/examples/snes/templates/sports.c +16 -1
- package/package.json +1 -1
- package/src/cheats/gamegenie.js +0 -1
- package/src/cli/smoke.js +1 -3
- package/src/cores/wasm/vice_x64_libretro.js +1 -1
- package/src/cores/wasm/vice_x64_libretro.wasm +0 -0
- package/src/host/LibretroHost.js +191 -16
- package/src/host/callbacks.js +9 -1
- package/src/host/chafa-render.js +2 -0
- package/src/host/dsp-state.js +2 -2
- package/src/host/gpgx-state.js +4 -0
- package/src/host/types.js +15 -8
- package/src/http/routes.js +1 -1
- package/src/http/tool-registry.js +26 -1
- package/src/mcp/server.js +1 -1
- package/src/mcp/state.js +36 -0
- package/src/mcp/tools/address-to-symbol.js +0 -1
- package/src/mcp/tools/art-loaders.js +1 -1
- package/src/mcp/tools/cart-parts.js +75 -4
- package/src/mcp/tools/classify-region.js +1 -1
- package/src/mcp/tools/diff-roms.js +1 -1
- package/src/mcp/tools/disasm-rebuild.js +507 -0
- package/src/mcp/tools/disasm.js +97 -9
- package/src/mcp/tools/find-references.js +1 -2
- package/src/mcp/tools/font-map.js +1 -1
- package/src/mcp/tools/frame.js +168 -3
- package/src/mcp/tools/index.js +0 -49
- package/src/mcp/tools/input-layout.js +0 -1
- package/src/mcp/tools/input.js +33 -3
- package/src/mcp/tools/lifecycle.js +18 -4
- package/src/mcp/tools/lospec.js +0 -19
- package/src/mcp/tools/platform-docs.js +1 -1
- package/src/mcp/tools/platform-tools.js +4 -4
- package/src/mcp/tools/project.js +54 -11
- package/src/mcp/tools/reinject.js +0 -1
- package/src/mcp/tools/rom-id.js +2 -2
- package/src/mcp/tools/snippets.js +2 -2
- package/src/mcp/tools/sprite-pipeline.js +1 -2
- package/src/mcp/tools/state.js +201 -14
- package/src/mcp/tools/tile-inspect.js +1 -1
- package/src/mcp/tools/toolchain.js +105 -12
- package/src/mcp/tools/watch-memory.js +137 -16
- package/src/platforms/_guides/ROMHACKING_PLAYBOOK.md +34 -0
- package/src/platforms/atari2600/TROUBLESHOOTING.md +6 -0
- package/src/platforms/atari7800/TROUBLESHOOTING.md +6 -0
- package/src/platforms/c64/MENTAL_MODEL.md +45 -1
- package/src/platforms/c64/TROUBLESHOOTING.md +6 -0
- package/src/platforms/c64/d64.js +280 -0
- package/src/platforms/c64/sid.js +0 -2
- package/src/platforms/common/metasprite-adapters.js +1 -1
- package/src/platforms/common/metasprite-codegen.js +3 -3
- package/src/platforms/common/registers.js +5 -3
- package/src/platforms/gb/MENTAL_MODEL.md +10 -0
- package/src/platforms/gb/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gb/lib/c/gb_runtime.c +4 -4
- package/src/platforms/gba/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gbc/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gbc/lib/c/gb_runtime.c +4 -4
- package/src/platforms/genesis/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gg/TROUBLESHOOTING.md +6 -0
- package/src/platforms/lynx/TROUBLESHOOTING.md +6 -0
- package/src/platforms/msx/MENTAL_MODEL.md +10 -6
- package/src/platforms/msx/TROUBLESHOOTING.md +6 -0
- package/src/platforms/nes/MENTAL_MODEL.md +63 -2
- package/src/platforms/nes/TROUBLESHOOTING.md +6 -0
- package/src/platforms/nes/image-to-tilemap.js +3 -0
- package/src/platforms/nes/lib/asm/famitone2.s +5 -1
- package/src/platforms/pce/MENTAL_MODEL.md +9 -4
- package/src/platforms/pce/TROUBLESHOOTING.md +6 -0
- package/src/platforms/pce/lib/c/pce_video.c +1 -1
- package/src/platforms/sms/TROUBLESHOOTING.md +6 -0
- package/src/platforms/snes/TROUBLESHOOTING.md +6 -0
- package/src/platforms/snes/brr.js +0 -2
- package/src/playtest/playtest.js +0 -7
- package/src/rom-id/identifier.js +15 -0
- package/src/toolchains/asar/asar.js +0 -9
- package/src/toolchains/assemble-snippet.js +30 -12
- package/src/toolchains/cc65/ines.js +145 -0
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +14 -1
- package/src/toolchains/cc65/presets/nes/chr-rom.cfg +83 -0
- package/src/toolchains/cc65/presets/nes/chr-rom.crt0.s +153 -0
- package/src/toolchains/common/reassemble.js +10 -3
- package/src/toolchains/common/sdk-cache.js +1 -1
- package/src/toolchains/genesis-c/genesis-c.js +5 -3
- package/src/toolchains/index.js +27 -3
- package/src/toolchains/parse-errors.js +78 -1
- package/src/toolchains/sdcc/preflight-lint.js +5 -1
- package/src/toolchains/sdcc/sdcc.js +1 -1
- package/src/toolchains/sjasm/sjasm.js +1 -1
- package/src/toolchains/snes-c/snes-c.js +2 -2
- package/src/toolchains/vasm68k/vasm68k.js +2 -4
- package/src/toolchains/wladx/wladx.js +1 -1
|
@@ -26,16 +26,22 @@
|
|
|
26
26
|
#include "snes_sfx.c"
|
|
27
27
|
|
|
28
28
|
extern char tilfont, palfont;
|
|
29
|
+
extern char tilbg, palbg; /* wallpaper tile + palette (data.asm) */
|
|
29
30
|
|
|
30
31
|
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
31
32
|
* No public prototype in console.h, so declare it; call once per frame. */
|
|
32
33
|
extern void consoleVblank(void);
|
|
33
34
|
|
|
35
|
+
/* BG1 wallpaper map: a full 32x32 screen of the 4-colour tile so the
|
|
36
|
+
* screen never reads as a flat/blank backdrop. Filled at runtime. */
|
|
37
|
+
static u16 bg_map[32 * 32];
|
|
38
|
+
|
|
34
39
|
int main(void) {
|
|
35
40
|
u16 pad;
|
|
36
41
|
u16 prev = 0;
|
|
37
42
|
u16 frame = 0;
|
|
38
43
|
u8 music_running;
|
|
44
|
+
u16 i;
|
|
39
45
|
|
|
40
46
|
/* ── Text-mode setup (PVSnesLib convention) ─────────────────── */
|
|
41
47
|
consoleSetTextMapPtr(0x6800);
|
|
@@ -47,11 +53,18 @@ int main(void) {
|
|
|
47
53
|
* registers — point BG0 at the same font ($3000) + map ($6800). */
|
|
48
54
|
bgSetGfxPtr(0, 0x3000);
|
|
49
55
|
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
50
|
-
bgSetDisable(1);
|
|
51
|
-
bgSetDisable(2);
|
|
52
56
|
|
|
53
|
-
/*
|
|
54
|
-
|
|
57
|
+
/* BG1 = full-screen wallpaper so the screen never reads as blank.
|
|
58
|
+
* Tiles -> VRAM $2000, map -> VRAM $4000 (clear of the console gfx
|
|
59
|
+
* $3000 / map $6800). Map entries use palette block 1 (0x0400) so the
|
|
60
|
+
* wallpaper palette doesn't disturb the console font palette in block 0
|
|
61
|
+
* (HUD text stays legible). */
|
|
62
|
+
bgInitTileSet(1, (u8 *)&tilbg, (u8 *)&palbg, 1,
|
|
63
|
+
32, 32, BG_16COLORS, 0x2000);
|
|
64
|
+
for (i = 0; i < 32 * 32; i++) bg_map[i] = 0x0400;
|
|
65
|
+
bgInitMapSet(1, (u8 *)bg_map, sizeof(bg_map), SC_32x32, 0x4000);
|
|
66
|
+
bgSetEnable(1);
|
|
67
|
+
bgSetDisable(2);
|
|
55
68
|
|
|
56
69
|
consoleDrawText( 8, 6, "SNES MUSIC DEMO");
|
|
57
70
|
consoleDrawText( 3, 11, "B = SHOOT SFX");
|
|
@@ -60,6 +73,11 @@ int main(void) {
|
|
|
60
73
|
|
|
61
74
|
setScreenOn();
|
|
62
75
|
|
|
76
|
+
/* Upload SPC driver + sample bank + song table to ARAM. sfx_init() must
|
|
77
|
+
* run AFTER setScreenOn() (snes_sfx.h:63) — if the SPC stalls before the
|
|
78
|
+
* screen is on you get a black/forced-blank screen forever. */
|
|
79
|
+
sfx_init();
|
|
80
|
+
|
|
63
81
|
/* Auto-start music. */
|
|
64
82
|
sfx_music_play();
|
|
65
83
|
music_running = 1;
|
|
@@ -322,4 +322,26 @@ palsprite:
|
|
|
322
322
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
323
323
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
324
324
|
|
|
325
|
+
; ── Background wallpaper (one 8x8 4bpp tile, 4 solid colour quadrants) ──
|
|
326
|
+
; Tiled across BG1 it paints the whole screen in four muted colours so the
|
|
327
|
+
; playfield never reads as a flat/blank backdrop. Quadrant->colour: TL=1,
|
|
328
|
+
; TR=2, BL=3, BR=4. 4bpp plane order: bytes 0-15 = rows 0-7 plane0/plane1
|
|
329
|
+
; pairs, bytes 16-31 = rows 0-7 plane2/plane3 pairs.
|
|
330
|
+
tilbg:
|
|
331
|
+
.db $F0, $0F, $F0, $0F, $F0, $0F, $F0, $0F ; rows 0-3: p0=left p1=right
|
|
332
|
+
.db $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; rows 4-7: p0+p1 = left
|
|
333
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00 ; rows 0-3: p2/p3 = 0
|
|
334
|
+
.db $0F, $00, $0F, $00, $0F, $00, $0F, $00 ; rows 4-7: p2 = right
|
|
335
|
+
|
|
336
|
+
palbg:
|
|
337
|
+
; 16-colour BG palette; only 1-4 used (the four wallpaper quadrant tones).
|
|
338
|
+
.db $00, $00 ; 0 unused (BG fully opaque)
|
|
339
|
+
.db $C4, $30 ; 1 dark blue
|
|
340
|
+
.db $42, $29 ; 2 dark teal
|
|
341
|
+
.db $88, $30 ; 3 dark purple
|
|
342
|
+
.db $C6, $24 ; 4 dark slate
|
|
343
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
344
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
345
|
+
.db $00, $00, $00, $00, $00, $00
|
|
346
|
+
|
|
325
347
|
.ends
|
|
@@ -23,11 +23,16 @@
|
|
|
23
23
|
|
|
24
24
|
extern char tilfont, palfont;
|
|
25
25
|
extern char tilsprite, palsprite;
|
|
26
|
+
extern char tilbg, palbg; /* wallpaper tile + palette (data.asm) */
|
|
26
27
|
|
|
27
28
|
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
28
29
|
* No public prototype in console.h, so declare it; call once per frame. */
|
|
29
30
|
extern void consoleVblank(void);
|
|
30
31
|
|
|
32
|
+
/* BG1 wallpaper map: a full 32x32 screen of the 4-colour tile so the
|
|
33
|
+
* playfield reads as a real backdrop, not flat blank. Filled at runtime. */
|
|
34
|
+
static u16 bg_map[32 * 32];
|
|
35
|
+
|
|
31
36
|
typedef struct { s16 x, y, w, h; } Rect;
|
|
32
37
|
|
|
33
38
|
#define WORLD_W 512
|
|
@@ -80,7 +85,17 @@ int main(void) {
|
|
|
80
85
|
* registers — point BG0 at the same font ($3000) + map ($6800). */
|
|
81
86
|
bgSetGfxPtr(0, 0x3000);
|
|
82
87
|
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
83
|
-
|
|
88
|
+
|
|
89
|
+
/* BG1 = full-screen wallpaper so the playfield never reads as blank.
|
|
90
|
+
* Tiles -> VRAM $2000, map -> VRAM $4000 (clear of sprites $0000 and
|
|
91
|
+
* the console gfx $3000 / map $6800). Map entries use palette block 1
|
|
92
|
+
* (0x0400) so the wallpaper palette doesn't disturb the console font
|
|
93
|
+
* palette in block 0 (HUD text stays legible). */
|
|
94
|
+
bgInitTileSet(1, (u8 *)&tilbg, (u8 *)&palbg, 1,
|
|
95
|
+
32, 32, BG_16COLORS, 0x2000);
|
|
96
|
+
for (i = 0; i < 32 * 32; i++) bg_map[i] = 0x0400;
|
|
97
|
+
bgInitMapSet(1, (u8 *)bg_map, sizeof(bg_map), SC_32x32, 0x4000);
|
|
98
|
+
bgSetEnable(1);
|
|
84
99
|
bgSetDisable(2);
|
|
85
100
|
|
|
86
101
|
oamInitGfxSet(&tilsprite, 32, &palsprite, 32, 0, 0x0000, OBJ_SIZE8_L16);
|
|
@@ -92,10 +107,13 @@ int main(void) {
|
|
|
92
107
|
consoleDrawText( 9, 12, "|64");
|
|
93
108
|
consoleDrawText(17, 12, "|128");
|
|
94
109
|
consoleDrawText(25, 12, "|192");
|
|
95
|
-
sfx_init();
|
|
96
110
|
|
|
97
111
|
oamSet(0, 32, 100, 3, 0, 0, 0, 0);
|
|
112
|
+
/* Screen ON first, THEN sound. sfx_init() must run AFTER setScreenOn()
|
|
113
|
+
* (snes_sfx.h:63) — if the SPC stalls before the screen is on you get a
|
|
114
|
+
* black/forced-blank screen forever. */
|
|
98
115
|
setScreenOn();
|
|
116
|
+
sfx_init();
|
|
99
117
|
|
|
100
118
|
while (1) {
|
|
101
119
|
pad = padsCurrent(0);
|
|
@@ -309,4 +309,26 @@ palfont:
|
|
|
309
309
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
310
310
|
.db $00, $00
|
|
311
311
|
|
|
312
|
+
; ── Background wallpaper (one 8x8 4bpp tile, 4 solid colour quadrants) ──
|
|
313
|
+
; Tiled across BG1 it paints the whole screen in four muted colours so the
|
|
314
|
+
; playfield never reads as a flat/blank backdrop. Quadrant->colour: TL=1,
|
|
315
|
+
; TR=2, BL=3, BR=4. 4bpp plane order: bytes 0-15 = rows 0-7 plane0/plane1
|
|
316
|
+
; pairs, bytes 16-31 = rows 0-7 plane2/plane3 pairs.
|
|
317
|
+
tilbg:
|
|
318
|
+
.db $F0, $0F, $F0, $0F, $F0, $0F, $F0, $0F ; rows 0-3: p0=left p1=right
|
|
319
|
+
.db $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; rows 4-7: p0+p1 = left
|
|
320
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00 ; rows 0-3: p2/p3 = 0
|
|
321
|
+
.db $0F, $00, $0F, $00, $0F, $00, $0F, $00 ; rows 4-7: p2 = right
|
|
322
|
+
|
|
323
|
+
palbg:
|
|
324
|
+
; 16-colour BG palette; only 1-4 used (the four wallpaper quadrant tones).
|
|
325
|
+
.db $00, $00 ; 0 unused (BG fully opaque)
|
|
326
|
+
.db $C4, $30 ; 1 dark blue
|
|
327
|
+
.db $42, $29 ; 2 dark teal
|
|
328
|
+
.db $88, $30 ; 3 dark purple
|
|
329
|
+
.db $C6, $24 ; 4 dark slate
|
|
330
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
331
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
332
|
+
.db $00, $00, $00, $00, $00, $00
|
|
333
|
+
|
|
312
334
|
.ends
|
|
@@ -15,11 +15,16 @@
|
|
|
15
15
|
#include "snes_sfx.c"
|
|
16
16
|
|
|
17
17
|
extern char tilfont, palfont;
|
|
18
|
+
extern char tilbg, palbg; /* wallpaper tile + palette (data.asm) */
|
|
18
19
|
|
|
19
20
|
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
20
21
|
* No public prototype in console.h, so declare it; call once per frame. */
|
|
21
22
|
extern void consoleVblank(void);
|
|
22
23
|
|
|
24
|
+
/* BG1 wallpaper map: a full 32x32 screen of the 4-colour tile so the
|
|
25
|
+
* playfield reads as a real backdrop, not flat blank. Filled at runtime. */
|
|
26
|
+
static u16 bg_map[32 * 32];
|
|
27
|
+
|
|
23
28
|
#define COLS 6
|
|
24
29
|
#define ROWS 12
|
|
25
30
|
|
|
@@ -136,6 +141,7 @@ static void render_score(void) {
|
|
|
136
141
|
int main(void) {
|
|
137
142
|
s16 r, c;
|
|
138
143
|
u16 pad, prev = 0, fall_rate;
|
|
144
|
+
u16 i;
|
|
139
145
|
u8 t;
|
|
140
146
|
|
|
141
147
|
consoleSetTextMapPtr(0x6800);
|
|
@@ -147,7 +153,17 @@ int main(void) {
|
|
|
147
153
|
* registers — point BG0 at the same font ($3000) + map ($6800). */
|
|
148
154
|
bgSetGfxPtr(0, 0x3000);
|
|
149
155
|
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
150
|
-
|
|
156
|
+
|
|
157
|
+
/* BG1 = full-screen wallpaper so the playfield never reads as blank.
|
|
158
|
+
* Tiles -> VRAM $2000, map -> VRAM $4000 (clear of sprites $0000 and
|
|
159
|
+
* the console gfx $3000 / map $6800). Map entries use palette block 1
|
|
160
|
+
* (0x0400) so the wallpaper palette doesn't disturb the console font
|
|
161
|
+
* palette in block 0 (HUD/grid text stays legible). */
|
|
162
|
+
bgInitTileSet(1, (u8 *)&tilbg, (u8 *)&palbg, 1,
|
|
163
|
+
32, 32, BG_16COLORS, 0x2000);
|
|
164
|
+
for (i = 0; i < 32 * 32; i++) bg_map[i] = 0x0400;
|
|
165
|
+
bgInitMapSet(1, (u8 *)bg_map, sizeof(bg_map), SC_32x32, 0x4000);
|
|
166
|
+
bgSetEnable(1);
|
|
151
167
|
bgSetDisable(2);
|
|
152
168
|
|
|
153
169
|
for (r = 0; r < ROWS; r++)
|
|
@@ -160,10 +176,13 @@ int main(void) {
|
|
|
160
176
|
|
|
161
177
|
consoleDrawText(14, 2, "SCORE");
|
|
162
178
|
consoleDrawText(2, 26, "LR MOVE A ROT START DROP");
|
|
163
|
-
sfx_init();
|
|
164
179
|
draw_grid();
|
|
165
180
|
|
|
181
|
+
/* Screen ON first, THEN sound. sfx_init() must run AFTER setScreenOn()
|
|
182
|
+
* (snes_sfx.h:63) — if the SPC stalls before the screen is on you get a
|
|
183
|
+
* black/forced-blank screen forever. */
|
|
166
184
|
setScreenOn();
|
|
185
|
+
sfx_init();
|
|
167
186
|
|
|
168
187
|
while (1) {
|
|
169
188
|
pad = padsCurrent(0);
|
|
@@ -328,4 +328,26 @@ palsprite:
|
|
|
328
328
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
329
329
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
330
330
|
|
|
331
|
+
; ── Background wallpaper (one 8x8 4bpp tile, 4 solid colour quadrants) ──
|
|
332
|
+
; Tiled across BG1 it paints the whole screen in four muted colours so the
|
|
333
|
+
; playfield never reads as a flat/blank backdrop. Quadrant->colour: TL=1,
|
|
334
|
+
; TR=2, BL=3, BR=4. 4bpp plane order: bytes 0-15 = rows 0-7 plane0/plane1
|
|
335
|
+
; pairs, bytes 16-31 = rows 0-7 plane2/plane3 pairs.
|
|
336
|
+
tilbg:
|
|
337
|
+
.db $F0, $0F, $F0, $0F, $F0, $0F, $F0, $0F ; rows 0-3: p0=left p1=right
|
|
338
|
+
.db $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; rows 4-7: p0+p1 = left
|
|
339
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00 ; rows 0-3: p2/p3 = 0
|
|
340
|
+
.db $0F, $00, $0F, $00, $0F, $00, $0F, $00 ; rows 4-7: p2 = right
|
|
341
|
+
|
|
342
|
+
palbg:
|
|
343
|
+
; 16-colour BG palette; only 1-4 used (the four wallpaper quadrant tones).
|
|
344
|
+
.db $00, $00 ; 0 unused (BG fully opaque)
|
|
345
|
+
.db $C4, $30 ; 1 dark blue
|
|
346
|
+
.db $42, $29 ; 2 dark teal
|
|
347
|
+
.db $88, $30 ; 3 dark purple
|
|
348
|
+
.db $C6, $24 ; 4 dark slate
|
|
349
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
350
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
351
|
+
.db $00, $00, $00, $00, $00, $00
|
|
352
|
+
|
|
331
353
|
.ends
|
|
@@ -12,11 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
extern char tilfont, palfont;
|
|
14
14
|
extern char tilsprite, palsprite;
|
|
15
|
+
extern char tilbg, palbg; /* wallpaper tile + palette (data.asm) */
|
|
15
16
|
|
|
16
17
|
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
17
18
|
* No public prototype in console.h, so declare it; call once per frame. */
|
|
18
19
|
extern void consoleVblank(void);
|
|
19
20
|
|
|
21
|
+
/* BG1 wallpaper map: a full 32x32 screen of the 4-colour tile so the
|
|
22
|
+
* playfield reads as a real backdrop, not flat blank. Filled at runtime. */
|
|
23
|
+
static u16 bg_map[32 * 32];
|
|
24
|
+
|
|
20
25
|
#define LANE_LEFT_X 72
|
|
21
26
|
#define LANE_MID_X 124
|
|
22
27
|
#define LANE_RIGHT_X 176
|
|
@@ -103,6 +108,7 @@ static void draw_road(void) {
|
|
|
103
108
|
int main(void) {
|
|
104
109
|
u16 pad;
|
|
105
110
|
u8 i;
|
|
111
|
+
u16 bi;
|
|
106
112
|
s16 step;
|
|
107
113
|
|
|
108
114
|
consoleSetTextMapPtr(0x6800);
|
|
@@ -114,7 +120,17 @@ int main(void) {
|
|
|
114
120
|
* registers — point BG0 at the same font ($3000) + map ($6800). */
|
|
115
121
|
bgSetGfxPtr(0, 0x3000);
|
|
116
122
|
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
117
|
-
|
|
123
|
+
|
|
124
|
+
/* BG1 = full-screen wallpaper so the playfield never reads as blank.
|
|
125
|
+
* Tiles -> VRAM $2000, map -> VRAM $4000 (clear of sprites $0000 and
|
|
126
|
+
* the console gfx $3000 / map $6800). Map entries use palette block 1
|
|
127
|
+
* (0x0400) so the wallpaper palette doesn't disturb the console font
|
|
128
|
+
* palette in block 0 (HUD/road text stays legible). */
|
|
129
|
+
bgInitTileSet(1, (u8 *)&tilbg, (u8 *)&palbg, 1,
|
|
130
|
+
32, 32, BG_16COLORS, 0x2000);
|
|
131
|
+
for (bi = 0; bi < 32 * 32; bi++) bg_map[bi] = 0x0400;
|
|
132
|
+
bgInitMapSet(1, (u8 *)bg_map, sizeof(bg_map), SC_32x32, 0x4000);
|
|
133
|
+
bgSetEnable(1);
|
|
118
134
|
bgSetDisable(2);
|
|
119
135
|
|
|
120
136
|
/* 2 sprite tiles × 32 bytes = 64 bytes */
|
|
@@ -351,4 +351,26 @@ palsprite:
|
|
|
351
351
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
352
352
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
353
353
|
|
|
354
|
+
; ── Background wallpaper (one 8×8 4bpp tile, 4 solid colour quadrants) ──
|
|
355
|
+
; Tiled across BG1 it paints the whole screen in four muted colours so the
|
|
356
|
+
; playfield never reads as a flat/blank backdrop. Quadrant→colour: TL=1,
|
|
357
|
+
; TR=2, BL=3, BR=4. 4bpp plane order: bytes 0-15 = rows 0-7 plane0/plane1
|
|
358
|
+
; pairs, bytes 16-31 = rows 0-7 plane2/plane3 pairs.
|
|
359
|
+
tilbg:
|
|
360
|
+
.db $F0, $0F, $F0, $0F, $F0, $0F, $F0, $0F ; rows 0-3: p0=left p1=right
|
|
361
|
+
.db $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; rows 4-7: p0+p1 = left
|
|
362
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00 ; rows 0-3: p2/p3 = 0
|
|
363
|
+
.db $0F, $00, $0F, $00, $0F, $00, $0F, $00 ; rows 4-7: p2 = right
|
|
364
|
+
|
|
365
|
+
palbg:
|
|
366
|
+
; 16-colour BG palette; only 1-4 used (the four wallpaper quadrant tones).
|
|
367
|
+
.db $00, $00 ; 0 unused (BG fully opaque)
|
|
368
|
+
.db $C4, $30 ; 1 dark blue
|
|
369
|
+
.db $42, $29 ; 2 dark teal
|
|
370
|
+
.db $88, $30 ; 3 dark purple
|
|
371
|
+
.db $C6, $24 ; 4 dark slate
|
|
372
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
373
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
374
|
+
.db $00, $00, $00, $00, $00, $00
|
|
375
|
+
|
|
354
376
|
.ends
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
extern char tilfont, palfont;
|
|
33
33
|
extern char tilsprite, palsprite;
|
|
34
|
+
extern char tilbg, palbg; /* wallpaper tile + palette (data.asm) */
|
|
34
35
|
|
|
35
36
|
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
36
37
|
* No public prototype in console.h, so declare it; call once per frame. */
|
|
@@ -39,6 +40,10 @@ extern void consoleVblank(void);
|
|
|
39
40
|
/* OAM is addressed by BYTE OFFSET; sprite slot N = offset N*4. */
|
|
40
41
|
#define SPR(slot) ((slot) << 2)
|
|
41
42
|
|
|
43
|
+
/* BG1 wallpaper map: a full 32×32 screen of the 4-colour tile so the
|
|
44
|
+
* playfield reads as a real backdrop, not flat blank. Filled at runtime. */
|
|
45
|
+
static u16 bg_map[32 * 32];
|
|
46
|
+
|
|
42
47
|
#define MAX_BULLETS 6
|
|
43
48
|
#define MAX_ENEMIES 6
|
|
44
49
|
|
|
@@ -124,7 +129,21 @@ int main(void) {
|
|
|
124
129
|
* font ($3000) + map ($6800) so the HUD text renders. */
|
|
125
130
|
bgSetGfxPtr(0, 0x3000);
|
|
126
131
|
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
127
|
-
|
|
132
|
+
|
|
133
|
+
/* BG1 = full-screen wallpaper so the playfield never reads as blank.
|
|
134
|
+
* Tiles → VRAM $2000, map → VRAM $4000 (clear of sprites $0000 and the
|
|
135
|
+
* console gfx $3000 / map $6800). One 8×8 tile = 32 bytes of gfx +
|
|
136
|
+
* 32 bytes of palette. */
|
|
137
|
+
bgInitTileSet(1, (u8 *)&tilbg, (u8 *)&palbg,
|
|
138
|
+
1, /* load palbg into CGRAM palette block 1 */
|
|
139
|
+
32, 32, BG_16COLORS, 0x2000);
|
|
140
|
+
/* Every map entry: tile 0, palette block 1 (bits 10-12 = 1 → 0x0400),
|
|
141
|
+
* so the wallpaper uses palbg and leaves the console font palette
|
|
142
|
+
* (block 0) untouched — HUD text stays white/legible. */
|
|
143
|
+
for (i = 0; i < 32 * 32; i++) bg_map[i] = 0x0400;
|
|
144
|
+
bgInitMapSet(1, (u8 *)bg_map, sizeof(bg_map), SC_32x32, 0x4000);
|
|
145
|
+
bgSetEnable(1);
|
|
146
|
+
|
|
128
147
|
bgSetDisable(2);
|
|
129
148
|
setPaletteColor(0, RGB5(0, 0, 6)); /* dark-blue backdrop (CGRAM 0) */
|
|
130
149
|
|
|
@@ -323,4 +323,26 @@ palsprite:
|
|
|
323
323
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
324
324
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
325
325
|
|
|
326
|
+
; ── Background wallpaper (one 8x8 4bpp tile, 4 solid colour quadrants) ──
|
|
327
|
+
; Tiled across BG1 it paints the whole screen in four muted colours so the
|
|
328
|
+
; playfield never reads as a flat/blank backdrop. Quadrant->colour: TL=1,
|
|
329
|
+
; TR=2, BL=3, BR=4. 4bpp plane order: bytes 0-15 = rows 0-7 plane0/plane1
|
|
330
|
+
; pairs, bytes 16-31 = rows 0-7 plane2/plane3 pairs.
|
|
331
|
+
tilbg:
|
|
332
|
+
.db $F0, $0F, $F0, $0F, $F0, $0F, $F0, $0F ; rows 0-3: p0=left p1=right
|
|
333
|
+
.db $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; rows 4-7: p0+p1 = left
|
|
334
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00 ; rows 0-3: p2/p3 = 0
|
|
335
|
+
.db $0F, $00, $0F, $00, $0F, $00, $0F, $00 ; rows 4-7: p2 = right
|
|
336
|
+
|
|
337
|
+
palbg:
|
|
338
|
+
; 16-colour BG palette; only 1-4 used (the four wallpaper quadrant tones).
|
|
339
|
+
.db $00, $00 ; 0 unused (BG fully opaque)
|
|
340
|
+
.db $C4, $30 ; 1 dark blue
|
|
341
|
+
.db $42, $29 ; 2 dark teal
|
|
342
|
+
.db $88, $30 ; 3 dark purple
|
|
343
|
+
.db $C6, $24 ; 4 dark slate
|
|
344
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
345
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
346
|
+
.db $00, $00, $00, $00, $00, $00
|
|
347
|
+
|
|
326
348
|
.ends
|
|
@@ -15,11 +15,16 @@
|
|
|
15
15
|
|
|
16
16
|
extern char tilfont, palfont;
|
|
17
17
|
extern char tilsprite, palsprite;
|
|
18
|
+
extern char tilbg, palbg; /* wallpaper tile + palette (data.asm) */
|
|
18
19
|
|
|
19
20
|
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
20
21
|
* No public prototype in console.h, so declare it; call once per frame. */
|
|
21
22
|
extern void consoleVblank(void);
|
|
22
23
|
|
|
24
|
+
/* BG1 wallpaper map: a full 32x32 screen of the 4-colour tile so the
|
|
25
|
+
* court reads as a real backdrop, not flat blank. Filled at runtime. */
|
|
26
|
+
static u16 bg_map[32 * 32];
|
|
27
|
+
|
|
23
28
|
#define COURT_TOP 16
|
|
24
29
|
#define COURT_BOT 208
|
|
25
30
|
#define PADDLE_H 24
|
|
@@ -96,7 +101,17 @@ int main(void) {
|
|
|
96
101
|
* registers — point BG0 at the same font ($3000) + map ($6800). */
|
|
97
102
|
bgSetGfxPtr(0, 0x3000);
|
|
98
103
|
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
99
|
-
|
|
104
|
+
|
|
105
|
+
/* BG1 = full-screen wallpaper so the court never reads as blank.
|
|
106
|
+
* Tiles -> VRAM $2000, map -> VRAM $4000 (clear of sprites $0000 and
|
|
107
|
+
* the console gfx $3000 / map $6800). Map entries use palette block 1
|
|
108
|
+
* (0x0400) so the wallpaper palette doesn't disturb the console font
|
|
109
|
+
* palette in block 0 (HUD/court text stays legible). */
|
|
110
|
+
bgInitTileSet(1, (u8 *)&tilbg, (u8 *)&palbg, 1,
|
|
111
|
+
32, 32, BG_16COLORS, 0x2000);
|
|
112
|
+
for (i = 0; i < 32 * 32; i++) bg_map[i] = 0x0400;
|
|
113
|
+
bgInitMapSet(1, (u8 *)bg_map, sizeof(bg_map), SC_32x32, 0x4000);
|
|
114
|
+
bgSetEnable(1);
|
|
100
115
|
bgSetDisable(2);
|
|
101
116
|
|
|
102
117
|
oamInitGfxSet(&tilsprite, 32, &palsprite, 32, 0, 0x0000, OBJ_SIZE8_L16);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "romdevtools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Tool server giving coding agents full control of homebrew ROM development AND reverse-engineering/romhacking across 14 retro platforms (NES, SNES, GB, Genesis, Atari, C64, PC Engine, MSX, ...) via WASM toolchains + emulator cores. Use over plain HTTP, as an Agent Skill, or as an MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/mcp/server.js",
|
package/src/cheats/gamegenie.js
CHANGED
|
@@ -446,7 +446,6 @@ export function decodeWithDevice(code, platform) {
|
|
|
446
446
|
|
|
447
447
|
/** Format a raw ADDR:VAL[:COMPARE] code from decoded parts (hex, no 0x). */
|
|
448
448
|
export function encodeRaw({ address, value, compare }) {
|
|
449
|
-
const h = (n, w) => (n & ((1 << (4 * w)) - 1) >>> 0).toString(16).toUpperCase().padStart(w, "0");
|
|
450
449
|
const addrHex = (address >>> 0).toString(16).toUpperCase();
|
|
451
450
|
const valHex = (value & 0xFF).toString(16).toUpperCase().padStart(2, "0");
|
|
452
451
|
return compare != null
|
package/src/cli/smoke.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// temp file and loaded into the matching libretro core. Platform is
|
|
15
15
|
// inferred from the file extension if not given.
|
|
16
16
|
|
|
17
|
-
import { writeFile, mkdtemp
|
|
17
|
+
import { writeFile, mkdtemp } from "node:fs/promises";
|
|
18
18
|
import { existsSync, statSync } from "node:fs";
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import path from "node:path";
|
|
@@ -108,12 +108,10 @@ async function playCommand(romPath, opts) {
|
|
|
108
108
|
|
|
109
109
|
// Extract zip if needed
|
|
110
110
|
let actualPath = romPath;
|
|
111
|
-
let extracted = false;
|
|
112
111
|
if (path.extname(romPath).toLowerCase() === ".zip") {
|
|
113
112
|
console.error(`unzipping ${path.basename(romPath)}...`);
|
|
114
113
|
const { tempPath, originalName } = await extractFirstRomFromZip(romPath);
|
|
115
114
|
actualPath = tempPath;
|
|
116
|
-
extracted = true;
|
|
117
115
|
console.error(` → ${originalName} (${statSync(tempPath).size} bytes)`);
|
|
118
116
|
}
|
|
119
117
|
|