romdev-mcp 0.1.1
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 +726 -0
- package/LICENSE +45 -0
- package/NOTICE +86 -0
- package/README.md +46 -0
- package/examples/README.md +36 -0
- package/examples/art-first-workflow/README.md +205 -0
- package/examples/atari2600/main.asm +143 -0
- package/examples/atari2600/templates/default.asm +183 -0
- package/examples/atari2600/templates/mini_invaders.asm +381 -0
- package/examples/atari2600/templates/music_demo.asm +322 -0
- package/examples/atari2600/templates/paddle.asm +345 -0
- package/examples/atari2600/templates/single_screen.asm +242 -0
- package/examples/atari7800/main.c +88 -0
- package/examples/atari7800/templates/default.c +183 -0
- package/examples/atari7800/templates/hello_sprite.c +141 -0
- package/examples/atari7800/templates/music_demo.c +123 -0
- package/examples/atari7800/templates/platformer.c +159 -0
- package/examples/atari7800/templates/puzzle.c +164 -0
- package/examples/atari7800/templates/racing.c +139 -0
- package/examples/atari7800/templates/shmup.c +148 -0
- package/examples/atari7800/templates/sports.c +207 -0
- package/examples/c64/main.c +63 -0
- package/examples/c64/templates/hello_sprite.c +117 -0
- package/examples/c64/templates/music_demo.c +131 -0
- package/examples/c64/templates/platformer.c +194 -0
- package/examples/c64/templates/puzzle.c +178 -0
- package/examples/c64/templates/racing.c +140 -0
- package/examples/c64/templates/shmup.c +201 -0
- package/examples/c64/templates/sports.c +109 -0
- package/examples/c64/templates/tile_engine.c +174 -0
- package/examples/gb/main.asm +106 -0
- package/examples/gb/main.c +49 -0
- package/examples/gb/templates/default.c +58 -0
- package/examples/gb/templates/hello_sprite.c +130 -0
- package/examples/gb/templates/music_demo.c +52 -0
- package/examples/gb/templates/platformer.c +178 -0
- package/examples/gb/templates/puzzle.c +217 -0
- package/examples/gb/templates/racing.c +158 -0
- package/examples/gb/templates/shmup.c +172 -0
- package/examples/gb/templates/sports.c +136 -0
- package/examples/gb/templates/tile_engine.c +280 -0
- package/examples/gba/templates/gba_hello.c +64 -0
- package/examples/gba/templates/maxmod_demo.c +105 -0
- package/examples/gba/templates/platformer.c +215 -0
- package/examples/gba/templates/puzzle.c +237 -0
- package/examples/gba/templates/racing.c +175 -0
- package/examples/gba/templates/shmup.c +197 -0
- package/examples/gba/templates/sports.c +177 -0
- package/examples/gba/templates/tonc_hello.c +72 -0
- package/examples/gba/templates/tonc_hello_sprite.c +109 -0
- package/examples/gbc/main.asm +123 -0
- package/examples/gbc/templates/default.c +61 -0
- package/examples/gbc/templates/hello_sprite.c +140 -0
- package/examples/gbc/templates/music_demo.c +63 -0
- package/examples/gbc/templates/platformer.c +181 -0
- package/examples/gbc/templates/puzzle.c +217 -0
- package/examples/gbc/templates/racing.c +164 -0
- package/examples/gbc/templates/shmup.c +188 -0
- package/examples/gbc/templates/sports.c +142 -0
- package/examples/gbc/templates/tile_engine.c +280 -0
- package/examples/genesis/main.s +161 -0
- package/examples/genesis/templates/hello_sprite.c +75 -0
- package/examples/genesis/templates/platformer.c +166 -0
- package/examples/genesis/templates/puzzle.c +240 -0
- package/examples/genesis/templates/racing.c +170 -0
- package/examples/genesis/templates/sgdk_hello.c +41 -0
- package/examples/genesis/templates/shmup.c +188 -0
- package/examples/genesis/templates/shmup_2p.c +244 -0
- package/examples/genesis/templates/sports.c +172 -0
- package/examples/genesis/templates/tile_engine.c +135 -0
- package/examples/genesis/templates/xgm2_demo.c +53 -0
- package/examples/genesis/templates/xgm2_demo_data.s +27 -0
- package/examples/gg/main.c +10 -0
- package/examples/gg/templates/default.c +156 -0
- package/examples/gg/templates/hello_sprite.c +90 -0
- package/examples/gg/templates/music_demo.c +156 -0
- package/examples/gg/templates/platformer.c +220 -0
- package/examples/gg/templates/puzzle.c +204 -0
- package/examples/gg/templates/racing.c +161 -0
- package/examples/gg/templates/shmup.c +188 -0
- package/examples/gg/templates/sports.c +137 -0
- package/examples/gg/templates/tile_engine.c +137 -0
- package/examples/lynx/main.c +4 -0
- package/examples/lynx/templates/default.c +41 -0
- package/examples/lynx/templates/hello_sprite.c +39 -0
- package/examples/lynx/templates/music_demo.c +37 -0
- package/examples/lynx/templates/platformer.c +72 -0
- package/examples/lynx/templates/puzzle.c +142 -0
- package/examples/lynx/templates/racing.c +94 -0
- package/examples/lynx/templates/shmup.c +132 -0
- package/examples/lynx/templates/sports.c +59 -0
- package/examples/nes/main.c +143 -0
- package/examples/nes/space-shooter/README.md +68 -0
- package/examples/nes/space-shooter/main.c +441 -0
- package/examples/nes/space-shooter/nes_runtime.c +347 -0
- package/examples/nes/space-shooter/nes_runtime.h +141 -0
- package/examples/nes/templates/default.c +41 -0
- package/examples/nes/templates/hello_sprite.c +104 -0
- package/examples/nes/templates/music_demo.c +80 -0
- package/examples/nes/templates/platformer.c +171 -0
- package/examples/nes/templates/puzzle.c +232 -0
- package/examples/nes/templates/racing.c +203 -0
- package/examples/nes/templates/shmup.c +228 -0
- package/examples/nes/templates/sports.c +205 -0
- package/examples/nes/templates/tile_engine.c +224 -0
- package/examples/porting-across-platforms/README.md +59 -0
- package/examples/sms/main.c +129 -0
- package/examples/sms/templates/default.c +110 -0
- package/examples/sms/templates/hello_sprite.c +90 -0
- package/examples/sms/templates/music_demo.c +151 -0
- package/examples/sms/templates/platformer.c +215 -0
- package/examples/sms/templates/puzzle.c +204 -0
- package/examples/sms/templates/racing.c +161 -0
- package/examples/sms/templates/shmup.c +167 -0
- package/examples/sms/templates/shmup_2p.c +219 -0
- package/examples/sms/templates/sports.c +147 -0
- package/examples/sms/templates/tile_engine.c +137 -0
- package/examples/snes/main.asm +70 -0
- package/examples/snes/templates/c-hello-data.asm +28 -0
- package/examples/snes/templates/c-hello.c +71 -0
- package/examples/snes/templates/default-data.asm +36 -0
- package/examples/snes/templates/default.c +74 -0
- package/examples/snes/templates/hello_sprite-data.asm +45 -0
- package/examples/snes/templates/hello_sprite.c +76 -0
- package/examples/snes/templates/music_demo-data.asm +20 -0
- package/examples/snes/templates/music_demo.c +83 -0
- package/examples/snes/templates/platformer-data.asm +27 -0
- package/examples/snes/templates/platformer.c +142 -0
- package/examples/snes/templates/puzzle-data.asm +14 -0
- package/examples/snes/templates/puzzle.c +199 -0
- package/examples/snes/templates/racing-data.asm +33 -0
- package/examples/snes/templates/racing.c +146 -0
- package/examples/snes/templates/shmup-data.asm +61 -0
- package/examples/snes/templates/shmup.c +199 -0
- package/examples/snes/templates/sports-data.asm +28 -0
- package/examples/snes/templates/sports.c +144 -0
- package/package.json +83 -0
- package/src/cli/smoke.js +283 -0
- package/src/cores/registry.js +95 -0
- package/src/host/LibretroHost.js +502 -0
- package/src/host/callbacks.js +444 -0
- package/src/host/chafa-render.js +170 -0
- package/src/host/coreLoader.js +57 -0
- package/src/host/cpu-state.js +422 -0
- package/src/host/dsp-state.js +188 -0
- package/src/host/framebuffer.js +115 -0
- package/src/host/gpgx-state.js +309 -0
- package/src/host/index.js +4 -0
- package/src/host/retroConstants.js +72 -0
- package/src/host/snes9x-state.js +35 -0
- package/src/host/types.js +280 -0
- package/src/mcp/disclosure.js +250 -0
- package/src/mcp/log.js +87 -0
- package/src/mcp/server.js +433 -0
- package/src/mcp/state.js +83 -0
- package/src/mcp/tools/address-to-symbol.js +151 -0
- package/src/mcp/tools/art-loaders.js +740 -0
- package/src/mcp/tools/assets.js +89 -0
- package/src/mcp/tools/audio.js +173 -0
- package/src/mcp/tools/cart-parts.js +649 -0
- package/src/mcp/tools/diff-roms.js +412 -0
- package/src/mcp/tools/disasm.js +980 -0
- package/src/mcp/tools/find-references.js +361 -0
- package/src/mcp/tools/font-map.js +353 -0
- package/src/mcp/tools/frame.js +249 -0
- package/src/mcp/tools/free-space.js +95 -0
- package/src/mcp/tools/index.js +351 -0
- package/src/mcp/tools/input-layout.js +215 -0
- package/src/mcp/tools/input.js +142 -0
- package/src/mcp/tools/lifecycle.js +110 -0
- package/src/mcp/tools/lospec.js +156 -0
- package/src/mcp/tools/memory.js +169 -0
- package/src/mcp/tools/metasprite-tools.js +261 -0
- package/src/mcp/tools/platform-docs.js +102 -0
- package/src/mcp/tools/platform-tools.js +1063 -0
- package/src/mcp/tools/platforms.js +86 -0
- package/src/mcp/tools/playtest.js +280 -0
- package/src/mcp/tools/preview-tile.js +360 -0
- package/src/mcp/tools/project.js +1885 -0
- package/src/mcp/tools/record.js +131 -0
- package/src/mcp/tools/rendering-context.js +700 -0
- package/src/mcp/tools/rom-id.js +256 -0
- package/src/mcp/tools/run-until.js +173 -0
- package/src/mcp/tools/snippets.js +235 -0
- package/src/mcp/tools/splice-chr.js +215 -0
- package/src/mcp/tools/sprite-pipeline.js +614 -0
- package/src/mcp/tools/state.js +99 -0
- package/src/mcp/tools/symbols.js +277 -0
- package/src/mcp/tools/tile-inspect.js +206 -0
- package/src/mcp/tools/toolchain.js +680 -0
- package/src/mcp/tools/watch-memory.js +212 -0
- package/src/mcp/tools/which-tiles.js +193 -0
- package/src/mcp/util.js +85 -0
- package/src/observer/bus.js +127 -0
- package/src/observer/livestream.html +589 -0
- package/src/observer/server.js +66 -0
- package/src/observer/tool-wrap.js +115 -0
- package/src/platforms/atari2600/MENTAL_MODEL.md +185 -0
- package/src/platforms/atari2600/TROUBLESHOOTING.md +155 -0
- package/src/platforms/atari2600/UPSTREAM_SOURCES.md +49 -0
- package/src/platforms/atari2600/lib/README.md +67 -0
- package/src/platforms/atari2600/lib/cc65-src/crt0.s +49 -0
- package/src/platforms/atari2600/lib/cc65-src/ctype.s +5 -0
- package/src/platforms/atari2600/lib/kernel_skeleton.asm +85 -0
- package/src/platforms/atari2600/lib/player_kernel.asm +87 -0
- package/src/platforms/atari2600/lib/playfield_kernel.asm +63 -0
- package/src/platforms/atari2600/lib/read_joystick.asm +76 -0
- package/src/platforms/atari2600/lib/score_kernel.asm +141 -0
- package/src/platforms/atari2600/lib/vcs_constants.h +97 -0
- package/src/platforms/atari2600/lib/vectors.asm +16 -0
- package/src/platforms/atari2600/tia.js +355 -0
- package/src/platforms/atari7800/MENTAL_MODEL.md +306 -0
- package/src/platforms/atari7800/TROUBLESHOOTING.md +195 -0
- package/src/platforms/atari7800/UPSTREAM_SOURCES.md +43 -0
- package/src/platforms/atari7800/lib/README.md +45 -0
- package/src/platforms/atari7800/lib/c/atari7800_music.c +215 -0
- package/src/platforms/atari7800/lib/c/atari7800_music.h +33 -0
- package/src/platforms/atari7800/lib/c/atari7800_sfx.c +74 -0
- package/src/platforms/atari7800/lib/c/atari7800_sfx.h +45 -0
- package/src/platforms/atari7800/lib/cc65-src/clock.s +69 -0
- package/src/platforms/atari7800/lib/cc65-src/clocks_per_sec.s +34 -0
- package/src/platforms/atari7800/lib/cc65-src/clrscr.s +27 -0
- package/src/platforms/atari7800/lib/cc65-src/conio.s +226 -0
- package/src/platforms/atari7800/lib/cc65-src/conio_font.s +278 -0
- package/src/platforms/atari7800/lib/cc65-src/cputc.s +139 -0
- package/src/platforms/atari7800/lib/cc65-src/crt0.s +71 -0
- package/src/platforms/atari7800/lib/cc65-src/ctype.s +5 -0
- package/src/platforms/atari7800/lib/cc65-src/exehdr.s +46 -0
- package/src/platforms/atari7800/lib/cc65-src/extra/mono.s +28 -0
- package/src/platforms/atari7800/lib/cc65-src/extzp.inc +15 -0
- package/src/platforms/atari7800/lib/cc65-src/extzp.s +15 -0
- package/src/platforms/atari7800/lib/cc65-src/get_tv.s +65 -0
- package/src/platforms/atari7800/lib/cc65-src/irq.s +36 -0
- package/src/platforms/atari7800/lib/cc65-src/joy/atari7800-stdjoy.s +197 -0
- package/src/platforms/atari7800/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/atari7800/lib/cc65-src/libref.s +8 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_clrscr.s +27 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_conio.s +231 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_cputc.s +102 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_font.s +2065 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_setcursor.s +214 -0
- package/src/platforms/atari7800/lib/cc65-src/setcursor.s +214 -0
- package/src/platforms/atari7800/lib/cc65-src/textcolor.s +53 -0
- package/src/platforms/atari7800/lib/cc65-src/wherex.s +19 -0
- package/src/platforms/atari7800/lib/cc65-src/wherey.s +19 -0
- package/src/platforms/atari7800/lib/display_list.asm +53 -0
- package/src/platforms/atari7800/lib/maria_init.asm +48 -0
- package/src/platforms/atari7800/lib/maria_registers.h +61 -0
- package/src/platforms/atari7800/lib/palette_load.asm +53 -0
- package/src/platforms/atari7800/lib/read_pad.asm +57 -0
- package/src/platforms/atari7800/lib/vblank_wait.asm +16 -0
- package/src/platforms/atari7800/maria.js +220 -0
- package/src/platforms/c64/MENTAL_MODEL.md +175 -0
- package/src/platforms/c64/TROUBLESHOOTING.md +130 -0
- package/src/platforms/c64/UPSTREAM_SOURCES.md +35 -0
- package/src/platforms/c64/image-to-tilemap.js +190 -0
- package/src/platforms/c64/lib/README.md +52 -0
- package/src/platforms/c64/lib/basic_stub.s +25 -0
- package/src/platforms/c64/lib/c/c64_music.c +248 -0
- package/src/platforms/c64/lib/c/c64_music.h +36 -0
- package/src/platforms/c64/lib/c/c64_sfx.c +94 -0
- package/src/platforms/c64/lib/c/c64_sfx.h +37 -0
- package/src/platforms/c64/lib/c64_registers.h +108 -0
- package/src/platforms/c64/lib/cc65-src/_scrsize.s +12 -0
- package/src/platforms/c64/lib/cc65-src/acc_c128_speed.s +5 -0
- package/src/platforms/c64/lib/cc65-src/acc_c64dtv_speed.s +64 -0
- package/src/platforms/c64/lib/cc65-src/acc_c65_speed.s +69 -0
- package/src/platforms/c64/lib/cc65-src/acc_chameleon_speed.s +100 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_c128.s +33 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_c64dtv.s +44 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_c65.s +55 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_chameleon.s +39 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_scpu.s +34 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_turbomaster.s +45 -0
- package/src/platforms/c64/lib/cc65-src/acc_scpu_speed.s +59 -0
- package/src/platforms/c64/lib/cc65-src/acc_turbomaster_speed.s +56 -0
- package/src/platforms/c64/lib/cc65-src/bordercolor.s +17 -0
- package/src/platforms/c64/lib/cc65-src/break.s +108 -0
- package/src/platforms/c64/lib/cc65-src/cgetc.s +62 -0
- package/src/platforms/c64/lib/cc65-src/clrscr.s +11 -0
- package/src/platforms/c64/lib/cc65-src/color.s +24 -0
- package/src/platforms/c64/lib/cc65-src/conio.s +10 -0
- package/src/platforms/c64/lib/cc65-src/cputc.s +105 -0
- package/src/platforms/c64/lib/cc65-src/crt0.s +117 -0
- package/src/platforms/c64/lib/cc65-src/devnum.s +7 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-65816.s +377 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-c256k.s +508 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-dqbb.s +447 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-georam.s +355 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-isepic.s +276 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-kerberos.s +281 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-ram.s +270 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-ramcart.s +297 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-reu.s +286 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-rrr.s +363 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-vdc.s +405 -0
- package/src/platforms/c64/lib/cc65-src/emd/dtv-himem.s +251 -0
- package/src/platforms/c64/lib/cc65-src/extra/soft80.s +71 -0
- package/src/platforms/c64/lib/cc65-src/extra/soft80mono.s +74 -0
- package/src/platforms/c64/lib/cc65-src/extra/tgimousedata.s +21 -0
- package/src/platforms/c64/lib/cc65-src/get_ostype.s +43 -0
- package/src/platforms/c64/lib/cc65-src/get_tv.s +20 -0
- package/src/platforms/c64/lib/cc65-src/gettime.s +83 -0
- package/src/platforms/c64/lib/cc65-src/irq.s +49 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-hitjoy.s +218 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-numpad.s +155 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-ptvjoy.s +146 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-stdjoy.s +111 -0
- package/src/platforms/c64/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/joy_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/kbhit.s +23 -0
- package/src/platforms/c64/lib/cc65-src/kbrepeat.s +14 -0
- package/src/platforms/c64/lib/cc65-src/kernal.s +53 -0
- package/src/platforms/c64/lib/cc65-src/kplot.s +22 -0
- package/src/platforms/c64/lib/cc65-src/libref.s +16 -0
- package/src/platforms/c64/lib/cc65-src/mainargs.s +137 -0
- package/src/platforms/c64/lib/cc65-src/mcbdefault.s +146 -0
- package/src/platforms/c64/lib/cc65-src/mcbspritedata.s +4 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-1351.s +467 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-inkwell.s +446 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-joy.s +451 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-pot.s +409 -0
- package/src/platforms/c64/lib/cc65-src/mouse_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/mouse_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/mouseref.s +23 -0
- package/src/platforms/c64/lib/cc65-src/pencalib.c +94 -0
- package/src/platforms/c64/lib/cc65-src/randomize.s +18 -0
- package/src/platforms/c64/lib/cc65-src/revers.s +27 -0
- package/src/platforms/c64/lib/cc65-src/ser/c64-swlink.s +484 -0
- package/src/platforms/c64/lib/cc65-src/ser_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/ser_stddrv.s +13 -0
- package/src/platforms/c64/lib/cc65-src/settime.s +84 -0
- package/src/platforms/c64/lib/cc65-src/soft80.inc +46 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cgetc.s +85 -0
- package/src/platforms/c64/lib/cc65-src/soft80_charset.s +182 -0
- package/src/platforms/c64/lib/cc65-src/soft80_color.s +159 -0
- package/src/platforms/c64/lib/cc65-src/soft80_conio.s +157 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeekc.s +148 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeekcolor.s +19 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeekrevers.s +15 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeeks.s +71 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cputc.s +521 -0
- package/src/platforms/c64/lib/cc65-src/soft80_kclrscr.s +76 -0
- package/src/platforms/c64/lib/cc65-src/soft80_kplot.s +63 -0
- package/src/platforms/c64/lib/cc65-src/soft80_scrsize.s +14 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_cgetc.s +67 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_color.s +65 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_conio.s +168 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_cpeekcolor.s +17 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_cputc.s +204 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_kclrscr.s +63 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_kplot.s +52 -0
- package/src/platforms/c64/lib/cc65-src/status.s +15 -0
- package/src/platforms/c64/lib/cc65-src/sysuname.s +37 -0
- package/src/platforms/c64/lib/cc65-src/tgi/c64-hi.s +881 -0
- package/src/platforms/c64/lib/cc65-src/tgi_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/tgi_stddrv.s +13 -0
- package/src/platforms/c64/lib/cc65-src/tmcommon.s +67 -0
- package/src/platforms/c64/lib/cc65-src/waitvsync.s +18 -0
- package/src/platforms/c64/lib/read_joystick.s +28 -0
- package/src/platforms/c64/lib/sid_play.s +48 -0
- package/src/platforms/c64/lib/sprite_table.s +73 -0
- package/src/platforms/c64/lib/vic_init.s +47 -0
- package/src/platforms/c64/sid.js +128 -0
- package/src/platforms/c64/vic.js +273 -0
- package/src/platforms/common/default-palette.js +139 -0
- package/src/platforms/common/image-to-tiles.js +407 -0
- package/src/platforms/common/intent.js +111 -0
- package/src/platforms/common/metasprite-adapters.js +279 -0
- package/src/platforms/common/metasprite-codegen.js +192 -0
- package/src/platforms/common/metasprite-core.js +201 -0
- package/src/platforms/common/metasprite.js +89 -0
- package/src/platforms/common/platform-palette.js +137 -0
- package/src/platforms/common/registers.js +329 -0
- package/src/platforms/common/render-tiles.js +86 -0
- package/src/platforms/common/screenshot-sprite.js +153 -0
- package/src/platforms/common/tile-decode.js +149 -0
- package/src/platforms/gb/MENTAL_MODEL.md +252 -0
- package/src/platforms/gb/TROUBLESHOOTING.md +221 -0
- package/src/platforms/gb/UPSTREAM_SOURCES.md +43 -0
- package/src/platforms/gb/image-to-tilemap.js +173 -0
- package/src/platforms/gb/lib/README.md +115 -0
- package/src/platforms/gb/lib/c/LICENSE-HUGEDRIVER +25 -0
- package/src/platforms/gb/lib/c/README.md +120 -0
- package/src/platforms/gb/lib/c/SDCC_GOTCHAS.md +189 -0
- package/src/platforms/gb/lib/c/gb_crt0.s +163 -0
- package/src/platforms/gb/lib/c/gb_hardware.h +113 -0
- package/src/platforms/gb/lib/c/gb_runtime.c +284 -0
- package/src/platforms/gb/lib/c/gb_runtime.h +145 -0
- package/src/platforms/gb/lib/c/hUGEDriver.c +191 -0
- package/src/platforms/gb/lib/c/hUGEDriver.h +95 -0
- package/src/platforms/gb/lib/c/hUGEDriver.upstream.asm +1908 -0
- package/src/platforms/gb/lib/c/lcd_init.c +19 -0
- package/src/platforms/gb/lib/c/patch-header.js +154 -0
- package/src/platforms/gb/lib/c/song_data.c +88 -0
- package/src/platforms/gb/lib/c/unroll.h +52 -0
- package/src/platforms/gb/lib/c/wait_vblank.c +14 -0
- package/src/platforms/gb/lib/dma_oam.asm +51 -0
- package/src/platforms/gb/lib/header.asm +56 -0
- package/src/platforms/gb/lib/joypad_read.asm +47 -0
- package/src/platforms/gb/lib/lcd_init.asm +44 -0
- package/src/platforms/gb/lib/load_palette.asm +25 -0
- package/src/platforms/gb/lib/load_tiles.asm +29 -0
- package/src/platforms/gb/lib/vblank_wait.asm +31 -0
- package/src/platforms/gb/ppu.js +574 -0
- package/src/platforms/gba/MENTAL_MODEL.md +203 -0
- package/src/platforms/gba/TROUBLESHOOTING.md +250 -0
- package/src/platforms/gba/UPSTREAM_SOURCES.md +41 -0
- package/src/platforms/gba/lib/arm-archives/libc.a +0 -0
- package/src/platforms/gba/lib/arm-archives/libgcc.a +0 -0
- package/src/platforms/gba/lib/arm-archives/libnosys.a +0 -0
- package/src/platforms/gba/lib/c/gba_sfx.c +81 -0
- package/src/platforms/gba/lib/c/gba_sfx.h +48 -0
- package/src/platforms/gba/lib/libgba/crtbegin.o +0 -0
- package/src/platforms/gba/lib/libgba/crtend.o +0 -0
- package/src/platforms/gba/lib/libgba/crti.o +0 -0
- package/src/platforms/gba/lib/libgba/crtn.o +0 -0
- package/src/platforms/gba/lib/libgba/gba_cart.ld +319 -0
- package/src/platforms/gba/lib/libgba/gba_crt0.s +258 -0
- package/src/platforms/gba/lib/libgba/include/BoyScout.h +128 -0
- package/src/platforms/gba/lib/libgba/include/disc.h +36 -0
- package/src/platforms/gba/lib/libgba/include/disc_io.h +64 -0
- package/src/platforms/gba/lib/libgba/include/dldi.h +112 -0
- package/src/platforms/gba/lib/libgba/include/erapi.h +195 -0
- package/src/platforms/gba/lib/libgba/include/fade.h +76 -0
- package/src/platforms/gba/lib/libgba/include/gba.h +47 -0
- package/src/platforms/gba/lib/libgba/include/gba_affine.h +83 -0
- package/src/platforms/gba/lib/libgba/include/gba_base.h +122 -0
- package/src/platforms/gba/lib/libgba/include/gba_compression.h +66 -0
- package/src/platforms/gba/lib/libgba/include/gba_console.h +55 -0
- package/src/platforms/gba/lib/libgba/include/gba_dma.h +100 -0
- package/src/platforms/gba/lib/libgba/include/gba_input.h +127 -0
- package/src/platforms/gba/lib/libgba/include/gba_interrupt.h +146 -0
- package/src/platforms/gba/lib/libgba/include/gba_multiboot.h +72 -0
- package/src/platforms/gba/lib/libgba/include/gba_sio.h +124 -0
- package/src/platforms/gba/lib/libgba/include/gba_sound.h +356 -0
- package/src/platforms/gba/lib/libgba/include/gba_sprites.h +195 -0
- package/src/platforms/gba/lib/libgba/include/gba_systemcalls.h +194 -0
- package/src/platforms/gba/lib/libgba/include/gba_timers.h +63 -0
- package/src/platforms/gba/lib/libgba/include/gba_types.h +60 -0
- package/src/platforms/gba/lib/libgba/include/gba_video.h +307 -0
- package/src/platforms/gba/lib/libgba/include/mappy.h +72 -0
- package/src/platforms/gba/lib/libgba/include/mbv2.h +90 -0
- package/src/platforms/gba/lib/libgba/include/xcomms.h +93 -0
- package/src/platforms/gba/lib/libgba/include/xcomms_cmd.h +53 -0
- package/src/platforms/gba/lib/libgba/libgba.seed.a +0 -0
- package/src/platforms/gba/lib/libgba/libgba.seed.hash +1 -0
- package/src/platforms/gba/lib/libgba/src/AffineSet.c +42 -0
- package/src/platforms/gba/lib/libgba/src/ArcTan.s +41 -0
- package/src/platforms/gba/lib/libgba/src/BoyScout/BoyScout.c +1242 -0
- package/src/platforms/gba/lib/libgba/src/BoyScout/GBASoundRegs.h +200 -0
- package/src/platforms/gba/lib/libgba/src/Compression.c +84 -0
- package/src/platforms/gba/lib/libgba/src/CpuSet.c +41 -0
- package/src/platforms/gba/lib/libgba/src/Div.s +58 -0
- package/src/platforms/gba/lib/libgba/src/DivArm.s +50 -0
- package/src/platforms/gba/lib/libgba/src/InterruptDispatcher.s +113 -0
- package/src/platforms/gba/lib/libgba/src/IntrWait.c +35 -0
- package/src/platforms/gba/lib/libgba/src/MultiBoot.s +33 -0
- package/src/platforms/gba/lib/libgba/src/Reset.s +49 -0
- package/src/platforms/gba/lib/libgba/src/Sound.s +48 -0
- package/src/platforms/gba/lib/libgba/src/Sqrt.s +34 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/disc.c +58 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/dldi.c +189 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/dldi_stub.s +78 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_cf_common.c +260 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_cf_common.h +72 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3_common.c +60 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3_common.h +48 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3cf.c +83 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3cf.h +45 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3sd.c +508 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3sd.h +45 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_mpcf.c +87 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_mpcf.h +42 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sc_common.c +47 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sc_common.h +43 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sccf.c +83 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sccf.h +45 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_scsd.c +385 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_scsd.h +48 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_scsd_s.s +139 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sd_common.c +203 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sd_common.h +108 -0
- package/src/platforms/gba/lib/libgba/src/fade.c +185 -0
- package/src/platforms/gba/lib/libgba/src/input.c +127 -0
- package/src/platforms/gba/lib/libgba/src/interrupt.c +116 -0
- package/src/platforms/gba/lib/libgba/src/mappy_print.c +74 -0
- package/src/platforms/gba/lib/libgba/src/mb2print.c +69 -0
- package/src/platforms/gba/lib/libgba/src/mbv2.c +230 -0
- package/src/platforms/gba/lib/libgba/src/mbv2.txt +119 -0
- package/src/platforms/gba/lib/libgba/src/xcomms.c +203 -0
- package/src/platforms/gba/lib/libgba/src/xcomms_print.c +56 -0
- package/src/platforms/gba/lib/libgba/sysinclude/_ansi.h +82 -0
- package/src/platforms/gba/lib/libgba/sysinclude/_newlib_version.h +11 -0
- package/src/platforms/gba/lib/libgba/sysinclude/_syslist.h +41 -0
- package/src/platforms/gba/lib/libgba/sysinclude/alloca.h +21 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ar.h +65 -0
- package/src/platforms/gba/lib/libgba/sysinclude/argz.h +33 -0
- package/src/platforms/gba/lib/libgba/sysinclude/assert.h +50 -0
- package/src/platforms/gba/lib/libgba/sysinclude/complex.h +150 -0
- package/src/platforms/gba/lib/libgba/sysinclude/cpio.h +30 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ctype.h +183 -0
- package/src/platforms/gba/lib/libgba/sysinclude/devctl.h +78 -0
- package/src/platforms/gba/lib/libgba/sysinclude/dirent.h +85 -0
- package/src/platforms/gba/lib/libgba/sysinclude/elf.h +3147 -0
- package/src/platforms/gba/lib/libgba/sysinclude/envlock.h +15 -0
- package/src/platforms/gba/lib/libgba/sysinclude/envz.h +16 -0
- package/src/platforms/gba/lib/libgba/sysinclude/errno.h +11 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fastmath.h +13 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fcntl.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fenv.h +42 -0
- package/src/platforms/gba/lib/libgba/sysinclude/float.h +631 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fnmatch.h +55 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ftw.h +66 -0
- package/src/platforms/gba/lib/libgba/sysinclude/getopt.h +185 -0
- package/src/platforms/gba/lib/libgba/sysinclude/glob.h +90 -0
- package/src/platforms/gba/lib/libgba/sysinclude/grp.h +86 -0
- package/src/platforms/gba/lib/libgba/sysinclude/iconv.h +63 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ieeefp.h +295 -0
- package/src/platforms/gba/lib/libgba/sysinclude/inttypes.h +345 -0
- package/src/platforms/gba/lib/libgba/sysinclude/iso646.h +45 -0
- package/src/platforms/gba/lib/libgba/sysinclude/langinfo.h +332 -0
- package/src/platforms/gba/lib/libgba/sysinclude/libgen.h +37 -0
- package/src/platforms/gba/lib/libgba/sysinclude/limits.h +168 -0
- package/src/platforms/gba/lib/libgba/sysinclude/locale.h +96 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_arc4random.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_default_types.h +250 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_endian.h +39 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_time.h +3 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_types.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/ansi.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/endian.h +69 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/fastmath.h +98 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/ieee.h +127 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/ieeefp.h +533 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/malloc.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/param.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/setjmp-dj.h +43 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/setjmp.h +524 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/stdlib.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/termios.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/time.h +15 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/types.h +13 -0
- package/src/platforms/gba/lib/libgba/sysinclude/malloc.h +173 -0
- package/src/platforms/gba/lib/libgba/sysinclude/math.h +645 -0
- package/src/platforms/gba/lib/libgba/sysinclude/memory.h +4 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ndbm.h +91 -0
- package/src/platforms/gba/lib/libgba/sysinclude/newlib.h +427 -0
- package/src/platforms/gba/lib/libgba/sysinclude/paths.h +9 -0
- package/src/platforms/gba/lib/libgba/sysinclude/pthread.h +456 -0
- package/src/platforms/gba/lib/libgba/sysinclude/pwd.h +83 -0
- package/src/platforms/gba/lib/libgba/sysinclude/reent.h +190 -0
- package/src/platforms/gba/lib/libgba/sysinclude/regdef.h +7 -0
- package/src/platforms/gba/lib/libgba/sysinclude/regex.h +103 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sched.h +112 -0
- package/src/platforms/gba/lib/libgba/sysinclude/search.h +64 -0
- package/src/platforms/gba/lib/libgba/sysinclude/setjmp.h +25 -0
- package/src/platforms/gba/lib/libgba/sysinclude/signal.h +35 -0
- package/src/platforms/gba/lib/libgba/sysinclude/spawn.h +111 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/ssp.h +76 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/stdio.h +101 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/stdlib.h +30 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/string.h +115 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/strings.h +55 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/unistd.h +93 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/wchar.h +97 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdarg.h +135 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdatomic.h +409 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdbool.h +51 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stddef.h +463 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdint.h +466 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdio.h +807 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdio_ext.h +79 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdlib.h +345 -0
- package/src/platforms/gba/lib/libgba/sysinclude/string.h +183 -0
- package/src/platforms/gba/lib/libgba/sysinclude/strings.h +80 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_default_fcntl.h +241 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_intsup.h +199 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_locale.h +12 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_pthreadtypes.h +233 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_sigset.h +43 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_stdint.h +90 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_timespec.h +52 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_timeval.h +60 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_types.h +228 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_tz_structs.h +24 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/cdefs.h +754 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/config.h +314 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/custom_file.h +2 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/dir.h +10 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/dirent.h +13 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/endian.h +207 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/errno.h +198 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/fcntl.h +12 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/features.h +551 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/fenv.h +90 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/file.h +2 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/iconvnls.h +77 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/iosupport.h +143 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/lock.h +75 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/param.h +35 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/queue.h +919 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/reent.h +913 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/resource.h +24 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/sched.h +69 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/select.h +94 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/signal.h +388 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/stat.h +179 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/statvfs.h +41 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/stdio.h +27 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/string.h +2 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/syslimits.h +61 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/time.h +448 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/timeb.h +40 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/times.h +32 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/timespec.h +63 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/tree.h +864 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/types.h +228 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/unistd.h +591 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/utime.h +22 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/wait.h +44 -0
- package/src/platforms/gba/lib/libgba/sysinclude/tar.h +43 -0
- package/src/platforms/gba/lib/libgba/sysinclude/termios.h +7 -0
- package/src/platforms/gba/lib/libgba/sysinclude/tgmath.h +127 -0
- package/src/platforms/gba/lib/libgba/sysinclude/threads.h +93 -0
- package/src/platforms/gba/lib/libgba/sysinclude/time.h +313 -0
- package/src/platforms/gba/lib/libgba/sysinclude/unctrl.h +42 -0
- package/src/platforms/gba/lib/libgba/sysinclude/unistd.h +6 -0
- package/src/platforms/gba/lib/libgba/sysinclude/utime.h +12 -0
- package/src/platforms/gba/lib/libgba/sysinclude/utmp.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/varargs.h +7 -0
- package/src/platforms/gba/lib/libgba/sysinclude/wchar.h +339 -0
- package/src/platforms/gba/lib/libgba/sysinclude/wctype.h +74 -0
- package/src/platforms/gba/lib/libgba/sysinclude/wordexp.h +53 -0
- package/src/platforms/gba/lib/libtonc/crtbegin.o +0 -0
- package/src/platforms/gba/lib/libtonc/crtend.o +0 -0
- package/src/platforms/gba/lib/libtonc/crti.o +0 -0
- package/src/platforms/gba/lib/libtonc/crtn.o +0 -0
- package/src/platforms/gba/lib/libtonc/gba_cart.ld +319 -0
- package/src/platforms/gba/lib/libtonc/gba_crt0.s +258 -0
- package/src/platforms/gba/lib/libtonc/include/tonc.h +72 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_asminc.h +132 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_bios.h +555 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_core.h +573 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_input.h +184 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_irq.h +121 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_legacy.h +481 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_libgba.h +537 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_math.h +692 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_memdef.h +962 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_memmap.h +583 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_nocash.h +51 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_oam.h +186 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_surface.h +461 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_text.h +270 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_tte.h +748 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_types.h +376 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_video.h +615 -0
- package/src/platforms/gba/lib/libtonc/libtonc.seed.a +0 -0
- package/src/platforms/gba/lib/libtonc/libtonc.seed.hash +1 -0
- package/src/platforms/gba/lib/libtonc/src/asm/clr_blend_fast.s +72 -0
- package/src/platforms/gba/lib/libtonc/src/asm/clr_fade_fast.s +74 -0
- package/src/platforms/gba/lib/libtonc/src/asm/div_lut.s +54 -0
- package/src/platforms/gba/lib/libtonc/src/asm/sin_lut.s +90 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_bios.s +289 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_bios_ex.s +97 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_isr_master.s +92 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_isr_nest.s +98 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_memcpy.s +126 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_memset.s +123 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_nocash.s +73 -0
- package/src/platforms/gba/lib/libtonc/src/font/sys8.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/sys8.s +46 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana10.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana10.s +293 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9.s +167 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9_b4.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9_b4.s +545 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9b.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9b.s +167 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9i.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9i.s +167 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_bitmap.c +289 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text.c +81 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text_bm.c +244 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text_map.c +122 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text_oam.c +113 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/toncfont.s +43 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bg.c +61 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bg_affine.c +112 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bmp16.c +240 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bmp8.c +314 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_color.c +368 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_core.c +237 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_input.c +118 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_irq.c +271 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_math.c +54 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_oam.c +76 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_obj_affine.c +146 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_sbmp16.c +369 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_sbmp8.c +405 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_schr4c.c +588 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_schr4r.c +462 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_surface.c +105 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_video.c +33 -0
- package/src/platforms/gba/lib/libtonc/src/tte/ase_drawg.c +83 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp16_drawg.c +72 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp16_drawg_b1cs.c +92 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp8_drawg.c +71 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp8_drawg_b1cs.c +104 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp8_drawg_b1cts_fast.s +115 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b1cts.c +76 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b1cts_fast.s +128 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b4cts.c +67 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b4cts_fast.s +127 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4r_drawg_b1cts.c +80 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4r_drawg_b1cts_fast.s +145 -0
- package/src/platforms/gba/lib/libtonc/src/tte/obj_drawg.c +61 -0
- package/src/platforms/gba/lib/libtonc/src/tte/se_drawg.c +110 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_ase.c +87 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_bmp.c +118 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_chr4c.c +86 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_chr4r.c +87 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_obj.c +84 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_se.c +96 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_iohook.c +264 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_main.c +756 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_types.s +119 -0
- package/src/platforms/gba/lib/maxmod/LICENSE-MAXMOD +23 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_defs.inc +117 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_format_mas.inc +108 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_macros.inc +195 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mas.inc +40 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mas_structs.inc +189 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mixer_ds.inc +46 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mixer_gba.inc +42 -0
- package/src/platforms/gba/lib/maxmod/asm_include/swi_gba.inc +23 -0
- package/src/platforms/gba/lib/maxmod/include/maxmod.h +412 -0
- package/src/platforms/gba/lib/maxmod/include/mm_types.h +333 -0
- package/src/platforms/gba/lib/maxmod/maxmod.seed.a +0 -0
- package/src/platforms/gba/lib/maxmod/maxmod.seed.hash +1 -0
- package/src/platforms/gba/lib/maxmod/music/chiptune.xm +0 -0
- package/src/platforms/gba/lib/maxmod/music/chiptune_soundbank.bin +0 -0
- package/src/platforms/gba/lib/maxmod/music/chiptune_soundbank.h +4 -0
- package/src/platforms/gba/lib/maxmod/music/make_chiptune_xm.js +203 -0
- package/src/platforms/gba/lib/maxmod/source/mm_effect.s +767 -0
- package/src/platforms/gba/lib/maxmod/source/mm_main.s +115 -0
- package/src/platforms/gba/lib/maxmod/source/mm_mas.s +4990 -0
- package/src/platforms/gba/lib/maxmod/source/mm_mas_arm.s +612 -0
- package/src/platforms/gba/lib/maxmod/source_gba/mm_init_default.s +98 -0
- package/src/platforms/gba/lib/maxmod/source_gba/mm_main_gba.s +292 -0
- package/src/platforms/gba/lib/maxmod/source_gba/mm_mixer_gba.s +1367 -0
- package/src/platforms/gba/lib/sysbase/gba_iosupport.c +138 -0
- package/src/platforms/gbc/MENTAL_MODEL.md +165 -0
- package/src/platforms/gbc/TROUBLESHOOTING.md +142 -0
- package/src/platforms/gbc/UPSTREAM_SOURCES.md +60 -0
- package/src/platforms/gbc/lib/c/LICENSE-HUGEDRIVER +25 -0
- package/src/platforms/gbc/lib/c/README.md +120 -0
- package/src/platforms/gbc/lib/c/SDCC_GOTCHAS.md +189 -0
- package/src/platforms/gbc/lib/c/gb_crt0.s +163 -0
- package/src/platforms/gbc/lib/c/gb_hardware.h +113 -0
- package/src/platforms/gbc/lib/c/gb_runtime.c +284 -0
- package/src/platforms/gbc/lib/c/gb_runtime.h +145 -0
- package/src/platforms/gbc/lib/c/hUGEDriver.c +191 -0
- package/src/platforms/gbc/lib/c/hUGEDriver.h +95 -0
- package/src/platforms/gbc/lib/c/hUGEDriver.upstream.asm +1908 -0
- package/src/platforms/gbc/lib/c/lcd_init.c +19 -0
- package/src/platforms/gbc/lib/c/patch-header.js +154 -0
- package/src/platforms/gbc/lib/c/song_data.c +88 -0
- package/src/platforms/gbc/lib/c/unroll.h +52 -0
- package/src/platforms/gbc/lib/c/wait_vblank.c +14 -0
- package/src/platforms/genesis/MENTAL_MODEL.md +223 -0
- package/src/platforms/genesis/TROUBLESHOOTING.md +193 -0
- package/src/platforms/genesis/UPSTREAM_SOURCES.md +52 -0
- package/src/platforms/genesis/image-to-tilemap.js +333 -0
- package/src/platforms/genesis/lib/README.md +157 -0
- package/src/platforms/genesis/lib/c/crtbegin.o +0 -0
- package/src/platforms/genesis/lib/c/crtend.o +0 -0
- package/src/platforms/genesis/lib/c/genesis.ld +44 -0
- package/src/platforms/genesis/lib/c/genesis_sfx.c +51 -0
- package/src/platforms/genesis/lib/c/genesis_sfx.h +49 -0
- package/src/platforms/genesis/lib/c/libc.a +0 -0
- package/src/platforms/genesis/lib/c/libgcc.a +0 -0
- package/src/platforms/genesis/lib/c/libm.a +0 -0
- package/src/platforms/genesis/lib/c/sega.s +71 -0
- package/src/platforms/genesis/lib/header.s +96 -0
- package/src/platforms/genesis/lib/nmi_safe.s +79 -0
- package/src/platforms/genesis/lib/pad_read.s +104 -0
- package/src/platforms/genesis/lib/sgdk/COPYING.RUNTIME +73 -0
- package/src/platforms/genesis/lib/sgdk/LICENSE +12 -0
- package/src/platforms/genesis/lib/sgdk/include/asm.h +52 -0
- package/src/platforms/genesis/lib/sgdk/include/asm_mac.i +9 -0
- package/src/platforms/genesis/lib/sgdk/include/bmp.h +690 -0
- package/src/platforms/genesis/lib/sgdk/include/config.h +208 -0
- package/src/platforms/genesis/lib/sgdk/include/dma.h +542 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/console.h +387 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/everdrive.h +116 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/fat16.h +84 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/flash-save/flash.h +164 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/flash-save/saveman.h +177 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/link_cable.h +316 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/minimusic/minimus.h +29 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/16c550.h +221 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/comm.h +93 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/gamejolt.h +541 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/jsmn.h +471 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/json.h +122 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/lsd.h +172 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/megawifi.h +984 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/mw-msg.h +392 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/ssf_ed_pro.h +38 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/ssf_ed_x7.h +73 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/serial/buffer.h +8 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/serial/serial.h +133 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/stb/stb_sprintf.h +1864 -0
- package/src/platforms/genesis/lib/sgdk/include/genesis.h +92 -0
- package/src/platforms/genesis/lib/sgdk/include/joy.h +482 -0
- package/src/platforms/genesis/lib/sgdk/include/kdebug.h +21 -0
- package/src/platforms/genesis/lib/sgdk/include/map.h +409 -0
- package/src/platforms/genesis/lib/sgdk/include/mapper.h +186 -0
- package/src/platforms/genesis/lib/sgdk/include/maths.h +1071 -0
- package/src/platforms/genesis/lib/sgdk/include/maths3D.h +480 -0
- package/src/platforms/genesis/lib/sgdk/include/memory.h +346 -0
- package/src/platforms/genesis/lib/sgdk/include/memory_base.h +37 -0
- package/src/platforms/genesis/lib/sgdk/include/object.h +171 -0
- package/src/platforms/genesis/lib/sgdk/include/pal.h +500 -0
- package/src/platforms/genesis/lib/sgdk/include/pool.h +171 -0
- package/src/platforms/genesis/lib/sgdk/include/psg.h +153 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/snd_dpcm2.h +79 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/snd_pcm.h +98 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/snd_pcm4.h +125 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/tab_vol.h +6 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/smp_null.h +6 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/smp_null_dpcm.h +6 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/sound.h +70 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/xgm.h +399 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/xgm2.h +389 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/z80_def.i80 +41 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/z80_fct.i80 +83 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/z80_mac.i80 +1476 -0
- package/src/platforms/genesis/lib/sgdk/include/sprite_eng.h +1095 -0
- package/src/platforms/genesis/lib/sgdk/include/sprite_eng_legacy.h +1030 -0
- package/src/platforms/genesis/lib/sgdk/include/sram.h +110 -0
- package/src/platforms/genesis/lib/sgdk/include/string.h +349 -0
- package/src/platforms/genesis/lib/sgdk/include/sys.h +511 -0
- package/src/platforms/genesis/lib/sgdk/include/tab_cnv.h +19 -0
- package/src/platforms/genesis/lib/sgdk/include/task.h +77 -0
- package/src/platforms/genesis/lib/sgdk/include/task_cst.h +33 -0
- package/src/platforms/genesis/lib/sgdk/include/timer.h +132 -0
- package/src/platforms/genesis/lib/sgdk/include/tools.h +450 -0
- package/src/platforms/genesis/lib/sgdk/include/types.h +320 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp.h +1150 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_bg.h +723 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_pal.h +101 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_spr.h +448 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_tile.h +1136 -0
- package/src/platforms/genesis/lib/sgdk/include/vram.h +270 -0
- package/src/platforms/genesis/lib/sgdk/include/ym2612.h +87 -0
- package/src/platforms/genesis/lib/sgdk/include/z80_ctrl.h +420 -0
- package/src/platforms/genesis/lib/sgdk/libmd.seed.a +0 -0
- package/src/platforms/genesis/lib/sgdk/libmd.seed.hash +1 -0
- package/src/platforms/genesis/lib/sgdk/md.ld +120 -0
- package/src/platforms/genesis/lib/sgdk/music/demo.vgm +0 -0
- package/src/platforms/genesis/lib/sgdk/music/demo.xgc +0 -0
- package/src/platforms/genesis/lib/sgdk/music/demo.xgm +0 -0
- package/src/platforms/genesis/lib/sgdk/res/image/font_default.png +0 -0
- package/src/platforms/genesis/lib/sgdk/res/image/sgdk_logo.png +0 -0
- package/src/platforms/genesis/lib/sgdk/res/libres.h +10 -0
- package/src/platforms/genesis/lib/sgdk/res/libres.res +5 -0
- package/src/platforms/genesis/lib/sgdk/res/libres.s +166 -0
- package/src/platforms/genesis/lib/sgdk/res/sound/stop_xgm.bin +0 -0
- package/src/platforms/genesis/lib/sgdk/rom_header.c +33 -0
- package/src/platforms/genesis/lib/sgdk/sega.preprocessed.s +364 -0
- package/src/platforms/genesis/lib/sgdk/sega.s +365 -0
- package/src/platforms/genesis/lib/sgdk/src/bmp.c +1539 -0
- package/src/platforms/genesis/lib/sgdk/src/bmp_a.s +3477 -0
- package/src/platforms/genesis/lib/sgdk/src/boot/rom_header.c +33 -0
- package/src/platforms/genesis/lib/sgdk/src/boot/sega.s +365 -0
- package/src/platforms/genesis/lib/sgdk/src/dma.c +782 -0
- package/src/platforms/genesis/lib/sgdk/src/dma_a.s +23 -0
- package/src/platforms/genesis/lib/sgdk/src/error_a.s +376 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/console.c +490 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/everdrive.c +285 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/fat16.c +610 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/flash-save/README.md +112 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/flash-save/flash.c +300 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/flash-save/saveman.c +641 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/link_cable.c +1758 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/CHANGELOG.md +31 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/LICENSE.txt +17 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/README.md +18 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/data.z80 +148 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/define.z80 +173 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/doc/api-c.md +80 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/doc/format.md +132 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/doc/teradrive.md +33 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/fm.z80 +363 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/main.z80 +433 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/minimus.c +129 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/minimus_drv.s80 +17 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/psg.z80 +231 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/track.z80 +398 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/util.z80 +98 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/16c550.c +84 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/README.md +849 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/comm.c +141 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/gamejolt.c +758 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/json.c +153 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/lsd.c +364 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/megawifi.c +1501 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/ssf_ed_pro.c +98 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/ssf_ed_x7.c +67 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/serial/buffer.c +69 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/serial/serial.c +158 -0
- package/src/platforms/genesis/lib/sgdk/src/joy.c +1361 -0
- package/src/platforms/genesis/lib/sgdk/src/kdebug.s +109 -0
- package/src/platforms/genesis/lib/sgdk/src/map.c +1915 -0
- package/src/platforms/genesis/lib/sgdk/src/mapper.c +280 -0
- package/src/platforms/genesis/lib/sgdk/src/maths.c +878 -0
- package/src/platforms/genesis/lib/sgdk/src/maths3D.c +480 -0
- package/src/platforms/genesis/lib/sgdk/src/maths3D_a.s +205 -0
- package/src/platforms/genesis/lib/sgdk/src/memory.c +760 -0
- package/src/platforms/genesis/lib/sgdk/src/memory_a.s +306 -0
- package/src/platforms/genesis/lib/sgdk/src/object.c +111 -0
- package/src/platforms/genesis/lib/sgdk/src/pal.c +484 -0
- package/src/platforms/genesis/lib/sgdk/src/pool.c +234 -0
- package/src/platforms/genesis/lib/sgdk/src/psg.c +82 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/drv_null.s80 +27 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/drv_xgm.s80 +3037 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/drv_dpcm2.s80 +984 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/drv_pcm.s80 +592 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/drv_pcm4.s80 +699 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/snd_dpcm2.c +172 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/snd_pcm.c +152 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/snd_pcm4.c +213 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/tab_vol.c +277 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/smp_null.s +22 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/smp_null_dpcm.s +15 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/sound.c +33 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm.c +683 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2.s80 +993 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_fct.i80 +611 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_mac.i80 +133 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_pcm_fct.i80 +114 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_pcm_mac.i80 +1444 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_psg_fct.i80 +491 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_psg_mac.i80 +43 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_ym_fct.i80 +1664 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_ym_mac.i80 +295 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2.c +1083 -0
- package/src/platforms/genesis/lib/sgdk/src/sprite_eng.c +2256 -0
- package/src/platforms/genesis/lib/sgdk/src/sprite_eng_legacy.c +2309 -0
- package/src/platforms/genesis/lib/sgdk/src/sram.c +30 -0
- package/src/platforms/genesis/lib/sgdk/src/sram_a.s +41 -0
- package/src/platforms/genesis/lib/sgdk/src/string.c +720 -0
- package/src/platforms/genesis/lib/sgdk/src/sys.c +1053 -0
- package/src/platforms/genesis/lib/sgdk/src/sys_a.s +74 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_cnv.c +129 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_log10.c +8201 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_log2.c +8201 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_sin.c +2058 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_sqrt.c +8201 -0
- package/src/platforms/genesis/lib/sgdk/src/task.s +148 -0
- package/src/platforms/genesis/lib/sgdk/src/timer.c +201 -0
- package/src/platforms/genesis/lib/sgdk/src/tools.c +1299 -0
- package/src/platforms/genesis/lib/sgdk/src/tools_a.s +979 -0
- package/src/platforms/genesis/lib/sgdk/src/types.c +18 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp.c +1060 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_bg.c +511 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_spr.c +322 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_tile.c +1011 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_tile_a.s +68 -0
- package/src/platforms/genesis/lib/sgdk/src/vram.c +273 -0
- package/src/platforms/genesis/lib/sgdk/src/ym2612.c +175 -0
- package/src/platforms/genesis/lib/sgdk/src/z80_ctrl.c +334 -0
- package/src/platforms/genesis/lib/sprite_table.s +129 -0
- package/src/platforms/genesis/lib/vblank_wait.s +73 -0
- package/src/platforms/genesis/lib/vdp_init.s +85 -0
- package/src/platforms/genesis/lib/wram.s +88 -0
- package/src/platforms/genesis/lib/z80_bootstrap.s +102 -0
- package/src/platforms/genesis/vdp.js +495 -0
- package/src/platforms/gg/MENTAL_MODEL.md +155 -0
- package/src/platforms/gg/TROUBLESHOOTING.md +91 -0
- package/src/platforms/gg/UPSTREAM_SOURCES.md +36 -0
- package/src/platforms/gg/lib/c/gg_crt0.s +112 -0
- package/src/platforms/gg/lib/c/gg_hw.h +62 -0
- package/src/platforms/gg/lib/c/gg_music.c +155 -0
- package/src/platforms/gg/lib/c/gg_music.h +89 -0
- package/src/platforms/gg/lib/c/gg_sfx.c +82 -0
- package/src/platforms/gg/lib/c/gg_sfx.h +40 -0
- package/src/platforms/gg/lib/c/joypad_read.c +22 -0
- package/src/platforms/gg/lib/c/load_palette.c +20 -0
- package/src/platforms/gg/lib/c/load_tiles.c +32 -0
- package/src/platforms/gg/lib/c/sprite_table.c +60 -0
- package/src/platforms/gg/lib/c/vblank_wait.c +10 -0
- package/src/platforms/gg/lib/c/vdp_init.c +58 -0
- package/src/platforms/index.js +7 -0
- package/src/platforms/lynx/MENTAL_MODEL.md +231 -0
- package/src/platforms/lynx/TROUBLESHOOTING.md +105 -0
- package/src/platforms/lynx/UPSTREAM_SOURCES.md +66 -0
- package/src/platforms/lynx/lib/c/lynx_music.c +63 -0
- package/src/platforms/lynx/lib/c/lynx_music.h +16 -0
- package/src/platforms/lynx/lib/c/lynx_sfx.c +147 -0
- package/src/platforms/lynx/lib/c/lynx_sfx.h +59 -0
- package/src/platforms/lynx/lib/cc65-src/bllhdr.s +18 -0
- package/src/platforms/lynx/lib/cc65-src/bootldr.s +195 -0
- package/src/platforms/lynx/lib/cc65-src/cgetc.s +69 -0
- package/src/platforms/lynx/lib/cc65-src/clock.s +87 -0
- package/src/platforms/lynx/lib/cc65-src/crt0.s +135 -0
- package/src/platforms/lynx/lib/cc65-src/defdir.s +29 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom.s +255 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom46.s +204 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom66.s +227 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom86.s +236 -0
- package/src/platforms/lynx/lib/cc65-src/exec.s +34 -0
- package/src/platforms/lynx/lib/cc65-src/exehdr.s +27 -0
- package/src/platforms/lynx/lib/cc65-src/extzp.inc +23 -0
- package/src/platforms/lynx/lib/cc65-src/extzp.s +30 -0
- package/src/platforms/lynx/lib/cc65-src/irq.s +45 -0
- package/src/platforms/lynx/lib/cc65-src/joy/lynx-stdjoy.s +93 -0
- package/src/platforms/lynx/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/kbhit.s +56 -0
- package/src/platforms/lynx/lib/cc65-src/libref.s +9 -0
- package/src/platforms/lynx/lib/cc65-src/load.s +41 -0
- package/src/platforms/lynx/lib/cc65-src/lseek.s +58 -0
- package/src/platforms/lynx/lib/cc65-src/lynx-cart.s +98 -0
- package/src/platforms/lynx/lib/cc65-src/lynx-snd.s +1270 -0
- package/src/platforms/lynx/lib/cc65-src/mainargs.s +24 -0
- package/src/platforms/lynx/lib/cc65-src/open.s +136 -0
- package/src/platforms/lynx/lib/cc65-src/oserror.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/read.s +44 -0
- package/src/platforms/lynx/lib/cc65-src/ser/lynx-comlynx.s +404 -0
- package/src/platforms/lynx/lib/cc65-src/ser_stat_stddrv.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/sysuname.s +39 -0
- package/src/platforms/lynx/lib/cc65-src/tgi/lynx-160-102-16.s +1075 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_colors.s +9 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_irq.s +11 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_stat_stddrv.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_stddrv.s +13 -0
- package/src/platforms/lynx/lib/cc65-src/uploader.s +81 -0
- package/src/platforms/nes/MENTAL_MODEL.md +301 -0
- package/src/platforms/nes/TROUBLESHOOTING.md +321 -0
- package/src/platforms/nes/UPSTREAM_SOURCES.md +31 -0
- package/src/platforms/nes/image-to-chr.js +195 -0
- package/src/platforms/nes/image-to-tilemap.js +415 -0
- package/src/platforms/nes/lib/README.md +40 -0
- package/src/platforms/nes/lib/asm/LICENSE-FAMITONE +40 -0
- package/src/platforms/nes/lib/asm/chr_ram_header.s +32 -0
- package/src/platforms/nes/lib/asm/famitone2.s +1258 -0
- package/src/platforms/nes/lib/asm/famitone_bridge.s +50 -0
- package/src/platforms/nes/lib/asm/music_data.s +238 -0
- package/src/platforms/nes/lib/c/chr_ram_runtime_hello_sprite.c +81 -0
- package/src/platforms/nes/lib/c/chr_ram_runtime_hud_row.c +101 -0
- package/src/platforms/nes/lib/c/nes_runtime.c +347 -0
- package/src/platforms/nes/lib/c/nes_runtime.h +153 -0
- package/src/platforms/nes/lib/c/nmi_handler.c +51 -0
- package/src/platforms/nes/lib/c/nmi_trampoline.s +25 -0
- package/src/platforms/nes/lib/cc65-src/Makefile.inc +9 -0
- package/src/platforms/nes/lib/cc65-src/_scrsize.s +24 -0
- package/src/platforms/nes/lib/cc65-src/cclear.s +29 -0
- package/src/platforms/nes/lib/cc65-src/chline.s +31 -0
- package/src/platforms/nes/lib/cc65-src/clock.s +31 -0
- package/src/platforms/nes/lib/cc65-src/clrscr.s +72 -0
- package/src/platforms/nes/lib/cc65-src/color.s +68 -0
- package/src/platforms/nes/lib/cc65-src/cpeekc.s +37 -0
- package/src/platforms/nes/lib/cc65-src/cpeekcolor.s +8 -0
- package/src/platforms/nes/lib/cc65-src/cpeekrevers.s +37 -0
- package/src/platforms/nes/lib/cc65-src/cputc.s +95 -0
- package/src/platforms/nes/lib/cc65-src/crt0.s +180 -0
- package/src/platforms/nes/lib/cc65-src/cvline.s +31 -0
- package/src/platforms/nes/lib/cc65-src/get_tv.s +37 -0
- package/src/platforms/nes/lib/cc65-src/gotox.s +21 -0
- package/src/platforms/nes/lib/cc65-src/gotoxy.s +22 -0
- package/src/platforms/nes/lib/cc65-src/gotoy.s +22 -0
- package/src/platforms/nes/lib/cc65-src/irq.s +19 -0
- package/src/platforms/nes/lib/cc65-src/joy/nes-stdjoy.s +102 -0
- package/src/platforms/nes/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/nes/lib/cc65-src/libref.s +9 -0
- package/src/platforms/nes/lib/cc65-src/mainargs.s +24 -0
- package/src/platforms/nes/lib/cc65-src/neschar.s +4616 -0
- package/src/platforms/nes/lib/cc65-src/ppu.s +158 -0
- package/src/platforms/nes/lib/cc65-src/ppubuf.s +117 -0
- package/src/platforms/nes/lib/cc65-src/randomize.s +18 -0
- package/src/platforms/nes/lib/cc65-src/revers.s +27 -0
- package/src/platforms/nes/lib/cc65-src/setcursor.s +37 -0
- package/src/platforms/nes/lib/cc65-src/sysuname.s +39 -0
- package/src/platforms/nes/lib/cc65-src/tgi/nes-64-56-2.s +480 -0
- package/src/platforms/nes/lib/cc65-src/tgi_stat_stddrv.s +14 -0
- package/src/platforms/nes/lib/cc65-src/tgi_stddrv.s +13 -0
- package/src/platforms/nes/lib/cc65-src/waitvsync.s +18 -0
- package/src/platforms/nes/lib/cc65-src/wherex.s +19 -0
- package/src/platforms/nes/lib/cc65-src/wherey.s +19 -0
- package/src/platforms/nes/lib/clear_nametable.s +38 -0
- package/src/platforms/nes/lib/clear_oam.s +18 -0
- package/src/platforms/nes/lib/load_palette.s +31 -0
- package/src/platforms/nes/lib/nmi_safe.s +65 -0
- package/src/platforms/nes/lib/oam_dma.s +16 -0
- package/src/platforms/nes/lib/read_pad.s +46 -0
- package/src/platforms/nes/lib/reset.s +46 -0
- package/src/platforms/nes/lib/sprite_table_populate.s +75 -0
- package/src/platforms/nes/lib/wait_vblank.s +12 -0
- package/src/platforms/nes/palette.js +39 -0
- package/src/platforms/nes/ppu.js +372 -0
- package/src/platforms/sms/MENTAL_MODEL.md +267 -0
- package/src/platforms/sms/TROUBLESHOOTING.md +124 -0
- package/src/platforms/sms/UPSTREAM_SOURCES.md +29 -0
- package/src/platforms/sms/image-to-tilemap.js +260 -0
- package/src/platforms/sms/lib/README.md +117 -0
- package/src/platforms/sms/lib/c/joypad_read.c +33 -0
- package/src/platforms/sms/lib/c/load_palette.c +24 -0
- package/src/platforms/sms/lib/c/load_tiles.c +32 -0
- package/src/platforms/sms/lib/c/sms_crt0.s +101 -0
- package/src/platforms/sms/lib/c/sms_hw.h +53 -0
- package/src/platforms/sms/lib/c/sms_music.c +178 -0
- package/src/platforms/sms/lib/c/sms_music.h +50 -0
- package/src/platforms/sms/lib/c/sms_sfx.c +82 -0
- package/src/platforms/sms/lib/c/sms_sfx.h +40 -0
- package/src/platforms/sms/lib/c/sprite_table.c +60 -0
- package/src/platforms/sms/lib/c/vblank_wait.c +10 -0
- package/src/platforms/sms/lib/c/vdp_init.c +58 -0
- package/src/platforms/sms/lib/header.s +33 -0
- package/src/platforms/sms/lib/joypad_read.s +40 -0
- package/src/platforms/sms/lib/load_palette.s +30 -0
- package/src/platforms/sms/lib/load_tiles.s +50 -0
- package/src/platforms/sms/lib/sprite_table.s +44 -0
- package/src/platforms/sms/lib/vblank_wait.s +36 -0
- package/src/platforms/sms/lib/vdp_init.s +47 -0
- package/src/platforms/sms/vdp.js +530 -0
- package/src/platforms/snes/MENTAL_MODEL.md +275 -0
- package/src/platforms/snes/TROUBLESHOOTING.md +208 -0
- package/src/platforms/snes/UPSTREAM_SOURCES.md +50 -0
- package/src/platforms/snes/brr.js +208 -0
- package/src/platforms/snes/image-to-tilemap.js +227 -0
- package/src/platforms/snes/lib/audio/apu_blob.asm +228 -0
- package/src/platforms/snes/lib/audio/apu_blob.bin +0 -0
- package/src/platforms/snes/lib/audio/explosion.brr +0 -0
- package/src/platforms/snes/lib/audio/sample_bank.bin +0 -0
- package/src/platforms/snes/lib/audio/shoot.brr +0 -0
- package/src/platforms/snes/lib/audio/spc_driver.asm +241 -0
- package/src/platforms/snes/lib/audio_pipeline.asm +62 -0
- package/src/platforms/snes/lib/c/crt0.asm +125 -0
- package/src/platforms/snes/lib/c/hdr.asm +50 -0
- package/src/platforms/snes/lib/c/snes_sfx.c +116 -0
- package/src/platforms/snes/lib/c/snes_sfx.h +96 -0
- package/src/platforms/snes/lib/c/snes_sfx_data.asm +25 -0
- package/src/platforms/snes/lib/cgram_upload.asm +43 -0
- package/src/platforms/snes/lib/lorom_header.asm +47 -0
- package/src/platforms/snes/lib/lorom_multibank.asm +66 -0
- package/src/platforms/snes/lib/nmi_safe.asm +77 -0
- package/src/platforms/snes/lib/oam_upload.asm +45 -0
- package/src/platforms/snes/lib/pad_read.asm +64 -0
- package/src/platforms/snes/lib/pvsneslib/LICENSE +21 -0
- package/src/platforms/snes/lib/pvsneslib/include/ctype.h +6 -0
- package/src/platforms/snes/lib/pvsneslib/include/float.h +4 -0
- package/src/platforms/snes/lib/pvsneslib/include/hdr.asm +47 -0
- package/src/platforms/snes/lib/pvsneslib/include/limits.h +13 -0
- package/src/platforms/snes/lib/pvsneslib/include/math.h +10 -0
- package/src/platforms/snes/lib/pvsneslib/include/setjmp.h +4 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/background.h +396 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/console.h +188 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/dma.h +381 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/input.h +289 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/interrupt.h +264 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/libversion.h +10 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/lzss.h +43 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/map.h +113 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/object.h +234 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/pixel.h +53 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/scores.h +66 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/snestypes.h +65 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/sound.h +245 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/sprite.h +456 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/video.h +465 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes.h +190 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdarg.h +28 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdbool.h +53 -0
- package/src/platforms/snes/lib/pvsneslib/include/stddef.h +27 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdint.h +7 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdio.h +9 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdlib.h +13 -0
- package/src/platforms/snes/lib/pvsneslib/include/string.h +19 -0
- package/src/platforms/snes/lib/pvsneslib/include/strings.h +5 -0
- package/src/platforms/snes/lib/pvsneslib/source/Makefile +87 -0
- package/src/platforms/snes/lib/pvsneslib/source/backgrounds.asm +834 -0
- package/src/platforms/snes/lib/pvsneslib/source/consoles.asm +1028 -0
- package/src/platforms/snes/lib/pvsneslib/source/crt0_snes.asm +329 -0
- package/src/platforms/snes/lib/pvsneslib/source/dmas.asm +1275 -0
- package/src/platforms/snes/lib/pvsneslib/source/hdr.asm +56 -0
- package/src/platforms/snes/lib/pvsneslib/source/input.asm +445 -0
- package/src/platforms/snes/lib/pvsneslib/source/libc.asm +485 -0
- package/src/platforms/snes/lib/pvsneslib/source/libc_c.c +1214 -0
- package/src/platforms/snes/lib/pvsneslib/source/libm.asm +510 -0
- package/src/platforms/snes/lib/pvsneslib/source/libtcc.asm +374 -0
- package/src/platforms/snes/lib/pvsneslib/source/lzsss.asm +256 -0
- package/src/platforms/snes/lib/pvsneslib/source/maps.asm +1078 -0
- package/src/platforms/snes/lib/pvsneslib/source/objects.asm +2881 -0
- package/src/platforms/snes/lib/pvsneslib/source/scores.asm +226 -0
- package/src/platforms/snes/lib/pvsneslib/source/sm_spc.asm +187 -0
- package/src/platforms/snes/lib/pvsneslib/source/snesmodwla.asm +1186 -0
- package/src/platforms/snes/lib/pvsneslib/source/sounds.asm +273 -0
- package/src/platforms/snes/lib/pvsneslib/source/sprites.asm +3946 -0
- package/src/platforms/snes/lib/pvsneslib/source/vblank.asm +917 -0
- package/src/platforms/snes/lib/pvsneslib/source/videos.asm +1137 -0
- package/src/platforms/snes/lib/reset_init.asm +31 -0
- package/src/platforms/snes/lib/sprite_table_populate.asm +122 -0
- package/src/platforms/snes/lib/vram_dma_upload.asm +42 -0
- package/src/platforms/snes/ppu.js +606 -0
- package/src/playtest/playtest.js +612 -0
- package/src/rom-id/identifier.js +421 -0
- package/src/rom-id/patch.js +217 -0
- package/src/toolchains/_worker/pool.js +253 -0
- package/src/toolchains/_worker/run.js +78 -0
- package/src/toolchains/_worker/wasm-worker.js +233 -0
- package/src/toolchains/arm-none-eabi-gcc/gcc.js +208 -0
- package/src/toolchains/asar/asar.js +542 -0
- package/src/toolchains/assemble-snippet.js +256 -0
- package/src/toolchains/cc65/cc65.js +395 -0
- package/src/toolchains/cc65/da65.js +119 -0
- package/src/toolchains/cc65/dbgparse.js +274 -0
- package/src/toolchains/cc65/preset-resolver.js +59 -0
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +79 -0
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.crt0.s +178 -0
- package/src/toolchains/cc65/presets/nes/chr-ram.cfg +76 -0
- package/src/toolchains/cc65/presets/nes/chr-ram.crt0.s +106 -0
- package/src/toolchains/common/ar.js +121 -0
- package/src/toolchains/common/sdk-cache.js +116 -0
- package/src/toolchains/common/symbols.js +139 -0
- package/src/toolchains/dasm/dasm.js +96 -0
- package/src/toolchains/gba-c/gba-c.js +832 -0
- package/src/toolchains/genesis-c/README.md +61 -0
- package/src/toolchains/genesis-c/genesis-c.js +598 -0
- package/src/toolchains/index.js +727 -0
- package/src/toolchains/m68k-elf-gcc/gcc.js +220 -0
- package/src/toolchains/m68kdasm.js +438 -0
- package/src/toolchains/parse-errors.js +258 -0
- package/src/toolchains/registry.js +67 -0
- package/src/toolchains/rgbds/rgbds.js +144 -0
- package/src/toolchains/sdcc/preflight-lint.js +295 -0
- package/src/toolchains/sdcc/sdcc.js +519 -0
- package/src/toolchains/sjasm/sjasm.js +85 -0
- package/src/toolchains/sm83dasm.js +194 -0
- package/src/toolchains/snes-c/snes-c.js +409 -0
- package/src/toolchains/tcc816/tcc816.js +79 -0
- package/src/toolchains/vasm68k/vasm68k.js +138 -0
- package/src/toolchains/wladx/wladx.js +120 -0
- package/src/toolchains/z80dasm.js +303 -0
|
@@ -0,0 +1,1063 @@
|
|
|
1
|
+
// Platform-aware inspection tools. The MCP surface stays generic — every
|
|
2
|
+
// tool takes a `platform` argument (or auto-detects from the loaded host)
|
|
3
|
+
// and dispatches to the right per-platform decoder under src/platforms/.
|
|
4
|
+
|
|
5
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { PNG } from "pngjs";
|
|
8
|
+
import { getHost } from "../state.js";
|
|
9
|
+
import { imageContent, jsonContent, safeTool, textContent } from "../util.js";
|
|
10
|
+
|
|
11
|
+
// Image-output contract: a PNG image goes to disk (path) OR comes back
|
|
12
|
+
// inline (inline:true). No path + not inline → error. The structured
|
|
13
|
+
// JSON (palette/sprite/tile data) is ALWAYS returned regardless.
|
|
14
|
+
function requireImageTarget(outPath, inline, tool) {
|
|
15
|
+
if (!outPath && !inline) {
|
|
16
|
+
throw new Error(`${tool}: pass outputPath (write the image to disk, returns {imagePath}) or inline:true (return the image in the response).`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
import { getCPUState } from "../../host/cpu-state.js";
|
|
20
|
+
import { getDspState } from "../../host/dsp-state.js";
|
|
21
|
+
import { decodeGenesisPSG, decodeGenesisYM2612 } from "../../host/gpgx-state.js";
|
|
22
|
+
|
|
23
|
+
/** Resolve the platform to inspect: explicit arg → currently loaded host. */
|
|
24
|
+
function resolvePlatform(host, requested) {
|
|
25
|
+
const p = requested ?? host.status.platform;
|
|
26
|
+
if (!p) throw new Error("no platform specified and no host loaded");
|
|
27
|
+
return p;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function registerPlatformTools(server, z, sessionKey) {
|
|
31
|
+
server.tool(
|
|
32
|
+
"inspectPatternTiles",
|
|
33
|
+
"Render tile/sprite art (pattern tables, CHR, tile RAM — terminology varies per platform) as " +
|
|
34
|
+
"a PNG. NES: returns 256×128 of both 4KB CHR banks.\n\n" +
|
|
35
|
+
"Source selection (cross-tool consistent with getTile / extractSpriteSheet):\n" +
|
|
36
|
+
" • No `path` set → reads from the running emulator. CHR-ROM cores read the iNES file " +
|
|
37
|
+
" on disk; CHR-RAM cores read the live VRAM (whatever the game has uploaded).\n" +
|
|
38
|
+
" • `path` set → reads directly from a ROM file on disk (no running emulator needed). " +
|
|
39
|
+
" Use this for surveying assets BEFORE loading.\n\n" +
|
|
40
|
+
"Response includes `source: \"file\" | \"emulator\"` and a textual note so you always know which. " +
|
|
41
|
+
"DEFAULT writes the PNG to outputPath and returns the JSON + {imagePath}; pass inline:true to get the image " +
|
|
42
|
+
"in the response (you must pass one or the other). The structured JSON is always returned.",
|
|
43
|
+
{
|
|
44
|
+
platform: z.string().optional().describe("Override platform; defaults to currently loaded."),
|
|
45
|
+
path: z.string().optional().describe("Optional ROM file. If set, reads CHR from disk instead of the running emulator."),
|
|
46
|
+
bpp: z.union([z.literal(2), z.literal(4), z.literal(8)]).default(4).describe("SNES only: bits-per-pixel of the tiles (2/4/8). Mode 1 BG1/BG2 are 4bpp (default), BG3 is 2bpp. snes9x doesn't expose PPU regs so this can't be auto-detected."),
|
|
47
|
+
tileBaseByte: z.number().int().min(0).default(0).describe("SNES only: byte offset into VRAM of tile 0 (the BG's character base). Default 0."),
|
|
48
|
+
paletteBase: z.number().int().min(0).max(255).default(0).describe("SNES only: CGRAM index of color 0 of the sub-palette used to colorize the sheet. Default 0."),
|
|
49
|
+
paletteIndex: z.number().int().min(0).max(3).default(0).describe("Genesis only: which CRAM sub-palette (0-3) to colorize the tile sheet with. Default 0."),
|
|
50
|
+
tileCount: z.number().int().min(0).default(0).describe("SNES/Genesis only: how many tiles to render. 0 (default) fills VRAM from tileBaseByte."),
|
|
51
|
+
outputPath: z.string().optional().describe("Absolute path to write the PNG to. Required unless inline:true."),
|
|
52
|
+
inline: z.boolean().default(false).describe("If true, return the image in the response instead of writing to disk. Default false — then outputPath is required."),
|
|
53
|
+
},
|
|
54
|
+
safeTool(async ({ platform, path: romPath, bpp, tileBaseByte, paletteBase, paletteIndex, tileCount, outputPath, inline }) => {
|
|
55
|
+
requireImageTarget(outputPath, inline, "inspectPatternTiles");
|
|
56
|
+
// Emit the PNG + structured JSON per the contract: inline returns the
|
|
57
|
+
// image in content[]; otherwise write to disk and return {imagePath}.
|
|
58
|
+
const emit = async (pngBuf, structured) => {
|
|
59
|
+
if (inline) {
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
imageContent(pngBuf.toString("base64")),
|
|
63
|
+
{ type: "text", text: JSON.stringify(structured) },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
await writeFile(outputPath, pngBuf);
|
|
68
|
+
const json = jsonContent({ ...structured, imagePath: outputPath });
|
|
69
|
+
json._observerImages = [{ kind: "image", mimeType: "image/png", base64: pngBuf.toString("base64") }];
|
|
70
|
+
return json;
|
|
71
|
+
};
|
|
72
|
+
// File-source path: read iNES directly from disk.
|
|
73
|
+
if (romPath) {
|
|
74
|
+
const p = platform ?? (/\.nes$/i.test(romPath) ? "nes" : null);
|
|
75
|
+
if (!p) throw new Error("inspectPatternTiles: pass platform explicitly when reading from a non-.nes file.");
|
|
76
|
+
if (p !== "nes") throw new Error(`inspectPatternTiles[file mode]: platform '${p}' not yet supported`);
|
|
77
|
+
const { readFile } = await import("node:fs/promises");
|
|
78
|
+
const bytes = new Uint8Array(await readFile(romPath));
|
|
79
|
+
const { chrFromINes } = await import("../../platforms/nes/ppu.js");
|
|
80
|
+
const { width, height, png, hasChr } = chrFromINes(bytes);
|
|
81
|
+
if (!hasChr) throw new Error(`'${romPath}' is a CHR-RAM cart — no graphics in the ROM file. Load it and call inspectPatternTiles without path.`);
|
|
82
|
+
return emit(png, { platform: p, source: "file", sourcePath: romPath, width, height });
|
|
83
|
+
}
|
|
84
|
+
const host = getHost(sessionKey);
|
|
85
|
+
const p = resolvePlatform(host, platform);
|
|
86
|
+
if (p === "nes") {
|
|
87
|
+
const { snapshotPatternTables } = await import("../../platforms/nes/ppu.js");
|
|
88
|
+
const { width, height, png, source, hasChr } = await snapshotPatternTables(host);
|
|
89
|
+
const note = source === "ines"
|
|
90
|
+
? `CHR pattern tables (${width}×${height}, both 4KB banks). Source: iNES file CHR-ROM bank — these tiles are baked into the ROM and never change at runtime.`
|
|
91
|
+
: hasChr === null
|
|
92
|
+
? `CHR pattern tables (${width}×${height}, live from CHR-RAM). Source: emulator's live CHR-RAM — these change as the game writes to PPU $0000-$1FFF. If you see blank tiles, your game hasn't uploaded tiles yet.`
|
|
93
|
+
: `CHR pattern tables (${width}×${height}, both 4KB banks, live from emulator).`;
|
|
94
|
+
const structuredSource = source === "ines" ? "file" : "emulator";
|
|
95
|
+
return emit(png, { platform: p, source: structuredSource, width, height, note });
|
|
96
|
+
}
|
|
97
|
+
if (p === "sms" || p === "gg") {
|
|
98
|
+
// SMS tiles live in VRAM at runtime — the cart has no fixed CHR
|
|
99
|
+
// region. Render all 448 tiles (the entire 16KB VRAM mapped to
|
|
100
|
+
// tiles), using the live first-BG-palette so colors look right.
|
|
101
|
+
const { snapshotPatternTiles, snapshotPalette } = await import("../../platforms/sms/vdp.js");
|
|
102
|
+
const { colors } = snapshotPalette(host, p);
|
|
103
|
+
// Use BG palette (entries 0..15) for rendering.
|
|
104
|
+
const bgPal = colors.slice(0, 16).map((c) => [c.r, c.g, c.b]);
|
|
105
|
+
const vramRegion = p === "gg" ? "gg_vram" : "sms_vram";
|
|
106
|
+
const vram = host.readMemory(vramRegion, 0, 0x4000);
|
|
107
|
+
const { renderSmsTilesheet } = await import("../../platforms/sms/vdp.js");
|
|
108
|
+
const { width, height, png, tileCount } = renderSmsTilesheet(vram, bgPal);
|
|
109
|
+
return emit(png, {
|
|
110
|
+
platform: p, source: "emulator", width, height, tileCount,
|
|
111
|
+
note: `${tileCount} tiles from 16 KB VRAM (covers tiles + name table + SAT — late ` +
|
|
112
|
+
`tiles will be noise from those regions). For the active BG pattern range, check ` +
|
|
113
|
+
`getRenderingContext().sms.bgTileDataBase.`,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (p === "gb" || p === "gbc") {
|
|
117
|
+
const { snapshotPatternTiles } = await import("../../platforms/gb/ppu.js");
|
|
118
|
+
const { width, height, png, tileCount } = snapshotPatternTiles(host, p);
|
|
119
|
+
return emit(png, {
|
|
120
|
+
platform: p, source: "emulator", width, height, tileCount,
|
|
121
|
+
note: `${tileCount} tiles from VRAM $8000-$97FF (the entire tile region). ` +
|
|
122
|
+
`Active BG/Window/sprite tile data area is selected by LCDC bit 4 — check ` +
|
|
123
|
+
`getRenderingContext().gb.bgTileDataBase.`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (p === "snes") {
|
|
127
|
+
const { renderSnesTilesheet, decodeCGRAM } = await import("../../platforms/snes/ppu.js");
|
|
128
|
+
const vram = host.readMemory("video_ram", 0, 0x10000);
|
|
129
|
+
const cgram = host.readMemory("snes_cgram", 0, 512);
|
|
130
|
+
const colors = decodeCGRAM(cgram);
|
|
131
|
+
const r = renderSnesTilesheet(vram, colors, {
|
|
132
|
+
bpp, tileBaseByte, paletteBase, tileCount: tileCount || undefined,
|
|
133
|
+
});
|
|
134
|
+
return emit(r.png, {
|
|
135
|
+
platform: p, source: "emulator", width: r.width, height: r.height,
|
|
136
|
+
tileCount: r.tileCount, bpp: r.bpp, note: r.note,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (p === "genesis") {
|
|
140
|
+
const { snapshotPatternTiles } = await import("../../platforms/genesis/vdp.js");
|
|
141
|
+
const r = snapshotPatternTiles(host, { paletteIndex, tileCount: tileCount || undefined });
|
|
142
|
+
return emit(r.png, {
|
|
143
|
+
platform: p, source: "emulator", width: r.width, height: r.height,
|
|
144
|
+
tileCount: r.tileCount, paletteIndex: r.paletteIndex, note: r.note,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`inspectPatternTiles not yet implemented for platform '${p}'`);
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
server.tool(
|
|
152
|
+
"inspectPalette",
|
|
153
|
+
"Read the loaded ROM's active color palette as a normalized {index,r,g,b,rawWord}[] list AND a PNG swatch sheet. Supported: NES (32 entries: 16 BG + 16 sprite), SNES (256 entries: BGR555 → expanded to 8bpc RGB), Genesis (64 entries: BGR XX nybbles → 8bpc), GB/GBC (4 grayscale shades for DMG; 32 colors for CGB). All return the same generic shape. " +
|
|
154
|
+
"The color list is ALWAYS returned. DEFAULT writes the swatch PNG to outputPath and returns {imagePath}; pass inline:true to get the image in the response (you must pass one or the other).",
|
|
155
|
+
{
|
|
156
|
+
platform: z.string().optional(),
|
|
157
|
+
outputPath: z.string().optional().describe("Absolute path to write the swatch PNG to. Required unless inline:true."),
|
|
158
|
+
inline: z.boolean().default(false).describe("If true, return the swatch image in the response instead of writing to disk. Default false — then outputPath is required."),
|
|
159
|
+
},
|
|
160
|
+
safeTool(async ({ platform, outputPath, inline }) => {
|
|
161
|
+
const host = getHost(sessionKey);
|
|
162
|
+
const p = resolvePlatform(host, platform);
|
|
163
|
+
requireImageTarget(outputPath, inline, "inspectPalette");
|
|
164
|
+
// The JSON (colors etc.) is ALWAYS returned; only the swatch PNG is gated.
|
|
165
|
+
const emit = async (structured, pngBuf) => {
|
|
166
|
+
if (inline) {
|
|
167
|
+
return {
|
|
168
|
+
content: [
|
|
169
|
+
{ type: "text", text: JSON.stringify(structured) },
|
|
170
|
+
imageContent(pngBuf.toString("base64")),
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
await writeFile(outputPath, pngBuf);
|
|
175
|
+
const json = jsonContent({ ...structured, imagePath: outputPath });
|
|
176
|
+
json._observerImages = [{ kind: "image", mimeType: "image/png", base64: pngBuf.toString("base64") }];
|
|
177
|
+
return json;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
if (p === "nes") {
|
|
181
|
+
const palette = host.readMemory("nes_palette", 0, 32);
|
|
182
|
+
const { renderPalettePng, paletteToGenericColors } = await import("../../platforms/nes/ppu.js");
|
|
183
|
+
const png = renderPalettePng(palette);
|
|
184
|
+
const colors = paletteToGenericColors(palette);
|
|
185
|
+
return emit({ platform: p, colors }, png);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (p === "snes") {
|
|
189
|
+
const cgram = host.readMemory("snes_cgram", 0, 512);
|
|
190
|
+
const { decodeCGRAM } = await import("../../platforms/snes/ppu.js");
|
|
191
|
+
const colors = decodeCGRAM(cgram);
|
|
192
|
+
const png = renderColorsAsPng(colors, 16); // 16x16 swatch grid
|
|
193
|
+
return emit({ platform: p, colors }, png);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (p === "genesis") {
|
|
197
|
+
const cram = host.readMemory("genesis_cram", 0, 128);
|
|
198
|
+
const { decodeGenesisCRAM } = await import("../../host/gpgx-state.js");
|
|
199
|
+
const colors = decodeGenesisCRAM(cram);
|
|
200
|
+
// 4 palettes × 16 entries = 64 colors; render as 4 rows of 16.
|
|
201
|
+
const png = renderColorsAsPng(colors, 16);
|
|
202
|
+
return emit({ platform: p, colors }, png);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (p === "sms" || p === "gg") {
|
|
206
|
+
const { snapshotPalette } = await import("../../platforms/sms/vdp.js");
|
|
207
|
+
const { colors, png } = snapshotPalette(host, p);
|
|
208
|
+
return emit({ platform: p, colors }, png);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (p === "gb" || p === "gbc") {
|
|
212
|
+
const { snapshotPalette } = await import("../../platforms/gb/ppu.js");
|
|
213
|
+
const { colors, png, raw } = snapshotPalette(host, p);
|
|
214
|
+
return emit({ platform: p, colors, raw }, png);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (p === "atari2600") {
|
|
218
|
+
const { snapshotPaletteSwatch } = await import("../../platforms/atari2600/tia.js");
|
|
219
|
+
const { colors, png } = snapshotPaletteSwatch(host);
|
|
220
|
+
return emit({ platform: p, colors,
|
|
221
|
+
note: "2600 has only 4 active colors at any moment (P0/P1/PF/BK). The TIA color regs change frequently as the kernel races the beam — this is a snapshot of the current state, NOT the full frame's colors." }, png);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (p === "atari7800") {
|
|
225
|
+
const { snapshotPalette } = await import("../../platforms/atari7800/maria.js");
|
|
226
|
+
const { colors, png, regs } = snapshotPalette(host);
|
|
227
|
+
return emit({ platform: p, colors, mariaRegs: regs }, png);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (p === "c64") {
|
|
231
|
+
const { snapshotPalette } = await import("../../platforms/c64/vic.js");
|
|
232
|
+
const { colors, png, current } = snapshotPalette(host);
|
|
233
|
+
return emit({
|
|
234
|
+
platform: p, colors, current,
|
|
235
|
+
note: "C64 palette is hardware-fixed (16 colors). `current` shows which indices the VIC-II is using right now for border/background/extra-bg. Programs can only choose indices, not RGB.",
|
|
236
|
+
}, png);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
throw new Error(`inspectPalette not yet wired for platform '${p}'. Supported: nes, snes, genesis, sms, gg, gb, gbc, atari2600, atari7800, c64.`);
|
|
240
|
+
}),
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
server.tool(
|
|
244
|
+
"getCPUState",
|
|
245
|
+
"Use this to read a CPU's {pc, registers, flags, sp}. Main CPU is wired for nes, snes, genesis, " +
|
|
246
|
+
"sms, gg, gb, gbc, atari2600, atari7800, c64. Secondary CPUs via `cpu`: `spc700` (SNES audio — tells " +
|
|
247
|
+
"'stuck in IPL' vs 'running' vs 'crashed into garbage ARAM') and `z80` (Genesis sound — held in reset " +
|
|
248
|
+
"until the 68k releases it via $A11100, so a fresh boot reads all-zero).",
|
|
249
|
+
{
|
|
250
|
+
platform: z.string().optional(),
|
|
251
|
+
cpu: z.enum(["main", "spc700", "z80"]).default("main").describe("Which CPU to inspect. main = platform's primary CPU. spc700 = SNES audio CPU (SNES only). z80 = Genesis sound CPU (Genesis only — held in reset until the 68k releases it, so may read all-zero on a fresh boot)."),
|
|
252
|
+
},
|
|
253
|
+
safeTool(async ({ platform, cpu }) => {
|
|
254
|
+
const host = getHost(sessionKey);
|
|
255
|
+
const p = resolvePlatform(host, platform);
|
|
256
|
+
const state = getCPUState(host, p, cpu);
|
|
257
|
+
if (!state) {
|
|
258
|
+
throw new Error(`getCPUState: no decoder for platform '${p}' cpu '${cpu}'. Main CPU is wired for nes, snes, genesis, sms, gg, gb, gbc, atari2600, atari7800, c64. Secondary CPUs: snes 'spc700' (genesis 'z80' not yet decoded).`);
|
|
259
|
+
}
|
|
260
|
+
return jsonContent({ platform: p, cpu, ...state });
|
|
261
|
+
}),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// ── getAudioState — unified sound-chip introspection ──────────────
|
|
265
|
+
// One tool, `chip` enum discriminator (mirrors getCPUState({cpu})).
|
|
266
|
+
// Subsumes the old getDspState / getPsgState / getYm2612State, which
|
|
267
|
+
// remain as thin deprecated aliases below for back-compat.
|
|
268
|
+
/** Run the chip decoder for one chip; returns the structured JSON object. */
|
|
269
|
+
function readAudioChip(chip) {
|
|
270
|
+
const host = getHost(sessionKey);
|
|
271
|
+
if (chip === "dsp") {
|
|
272
|
+
const p = resolvePlatform(host, "snes");
|
|
273
|
+
const dsp = getDspState(host, p);
|
|
274
|
+
if (!dsp) throw new Error("getAudioState chip:'dsp' is SNES only.");
|
|
275
|
+
const { regs, ...rest } = dsp;
|
|
276
|
+
return { platform: p, chip, ...rest, regsHex: Array.from(regs, (b) => b.toString(16).padStart(2, "0")).join("") };
|
|
277
|
+
}
|
|
278
|
+
if (chip === "ym2612") {
|
|
279
|
+
const blob = host.readMemory("genesis_ym2612", 0, 4096);
|
|
280
|
+
return { platform: "genesis", chip, ...decodeGenesisYM2612(blob) };
|
|
281
|
+
}
|
|
282
|
+
if (chip === "psg") {
|
|
283
|
+
const blob = host.readMemory("genesis_psg", 0, 1024);
|
|
284
|
+
return { platform: "genesis", chip, ...decodeGenesisPSG(blob) };
|
|
285
|
+
}
|
|
286
|
+
throw new Error(`getAudioState: unknown chip '${chip}'. Use 'dsp' (SNES), 'psg' (Genesis/SMS), or 'ym2612' (Genesis).`);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
server.tool(
|
|
290
|
+
"getAudioState",
|
|
291
|
+
"Use this to debug sound: decode a sound chip's live state. `chip:'dsp'` (SNES S-DSP) returns per-voice " +
|
|
292
|
+
"vol/pitch/adsr + `env` (internal envelope — 0 = silent regardless of vol) + `bufLastSamples` (nonzero " +
|
|
293
|
+
"proves the voice is producing audio) + `flg`; distinguishes 'never produced output' from 'muted by " +
|
|
294
|
+
"mixer.' GOTCHA: S-DSP FLG is $6C, KOFF is $5C (many refs swap them); power-on FLG=$E0 means your driver " +
|
|
295
|
+
"MUST clear bit 6. `chip:'psg'` (Genesis/SMS SN76489) returns 3 tone + 1 noise channel state. " +
|
|
296
|
+
"`chip:'ym2612'` (Genesis FM) returns a raw-blob snapshot (gpgx's struct isn't safely per-channel " +
|
|
297
|
+
"decodable) — useful for frame-to-frame diffing. Mirrors getCPUState({cpu}).",
|
|
298
|
+
{
|
|
299
|
+
chip: z.enum(["dsp", "psg", "ym2612"]).describe("Which sound chip: 'dsp' (SNES S-DSP), 'psg' (Genesis/SMS SN76489), 'ym2612' (Genesis FM)."),
|
|
300
|
+
},
|
|
301
|
+
safeTool(async ({ chip }) => jsonContent(readAudioChip(chip))),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
server.tool(
|
|
306
|
+
"inspectSprites",
|
|
307
|
+
"List the loaded ROM's active sprite table in a generic {slot,x,y,tile,palette,priority,flipH,flipV,size:{w,h},visible}[] shape. Supported: NES (64 sprites), SNES (128 sprites with hi-table X/size). Generic across platforms — each platform's adapter reads its native OAM and normalizes to this shape so cross-platform sprite debugging is one tool call. " +
|
|
308
|
+
"The sprite JSON is ALWAYS returned. On platforms that also render a sprite PNG (sms/gg, gb/gbc, atari2600/7800): DEFAULT writes the PNG to outputPath and returns {imagePath}; pass inline:true to get the image in the response (you must pass one or the other on those platforms). NES/SNES/Genesis/C64 are JSON-only — no path needed.",
|
|
309
|
+
{
|
|
310
|
+
platform: z.string().optional(),
|
|
311
|
+
outputPath: z.string().optional().describe("Absolute path to write the sprite PNG to (only platforms that produce one). Required on those platforms unless inline:true."),
|
|
312
|
+
inline: z.boolean().default(false).describe("If true, return the sprite image in the response instead of writing to disk (only platforms that produce one). Default false."),
|
|
313
|
+
},
|
|
314
|
+
safeTool(async ({ platform, outputPath, inline }) => {
|
|
315
|
+
const host = getHost(sessionKey);
|
|
316
|
+
const p = resolvePlatform(host, platform);
|
|
317
|
+
// Gate the PNG for platforms that render one. JSON is always returned.
|
|
318
|
+
const emitImage = async (pngBuf, structured) => {
|
|
319
|
+
requireImageTarget(outputPath, inline, "inspectSprites");
|
|
320
|
+
if (inline) {
|
|
321
|
+
return {
|
|
322
|
+
content: [
|
|
323
|
+
imageContent(pngBuf.toString("base64")),
|
|
324
|
+
{ type: "text", text: JSON.stringify(structured) },
|
|
325
|
+
],
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
await writeFile(outputPath, pngBuf);
|
|
329
|
+
const json = jsonContent({ ...structured, imagePath: outputPath });
|
|
330
|
+
json._observerImages = [{ kind: "image", mimeType: "image/png", base64: pngBuf.toString("base64") }];
|
|
331
|
+
return json;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
if (p === "nes") {
|
|
335
|
+
const oam = host.readMemory("nes_oam", 0, 256);
|
|
336
|
+
const sprites = [];
|
|
337
|
+
for (let i = 0; i < 64; i++) {
|
|
338
|
+
const o = i * 4;
|
|
339
|
+
const y = oam[o + 0];
|
|
340
|
+
const tile = oam[o + 1];
|
|
341
|
+
const attr = oam[o + 2];
|
|
342
|
+
const x = oam[o + 3];
|
|
343
|
+
sprites.push({
|
|
344
|
+
slot: i,
|
|
345
|
+
x, y, tile,
|
|
346
|
+
palette: attr & 0x3,
|
|
347
|
+
priority: (attr >> 5) & 0x1, // NES is 1-bit priority
|
|
348
|
+
flipH: !!((attr >> 6) & 0x1),
|
|
349
|
+
flipV: !!((attr >> 7) & 0x1),
|
|
350
|
+
size: { w: 8, h: 8 }, // NES sprites are 8x8 or 8x16 (PPUCTRL bit) — default to 8x8
|
|
351
|
+
visible: y < 0xF0,
|
|
352
|
+
raw: { byte0: y, byte1: tile, byte2: attr, byte3: x },
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return jsonContent({ platform: p, sprites });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (p === "snes") {
|
|
359
|
+
const oam = host.readMemory("snes_oam", 0, 544);
|
|
360
|
+
const fillram = host.readMemory("snes_fillram", 0, 0x8000);
|
|
361
|
+
const cgram = host.readMemory("snes_cgram", 0, 512);
|
|
362
|
+
const { decodeOAM, decodePpuRegs, ppuRegsPopulated, decodeCGRAM, checkObjPalettes } =
|
|
363
|
+
await import("../../platforms/snes/ppu.js");
|
|
364
|
+
// snes9x mirrors $2100-$213f into FillRAM (by full reg address), so we
|
|
365
|
+
// can read OBSEL and resolve real OBJ size + tile-base addressing.
|
|
366
|
+
const regsLive = ppuRegsPopulated(fillram);
|
|
367
|
+
const ppu = regsLive ? decodePpuRegs(fillram) : null;
|
|
368
|
+
const sprites = decodeOAM(oam, ppu ? {
|
|
369
|
+
smallSize: ppu.objSize.small,
|
|
370
|
+
largeSize: ppu.objSize.large,
|
|
371
|
+
objNameBaseByte: ppu.objNameBaseByte,
|
|
372
|
+
objGapByte: ppu.objGapByte,
|
|
373
|
+
} : {});
|
|
374
|
+
const colors = decodeCGRAM(cgram);
|
|
375
|
+
const { uninitializedPalettes, suspiciousPalettes, paletteReport, warnings } =
|
|
376
|
+
checkObjPalettes(sprites, colors);
|
|
377
|
+
const renderableCount = sprites.filter((s) => s.renderable).length;
|
|
378
|
+
const summary = [
|
|
379
|
+
`${renderableCount} of 128 OBJ slots are renderable on-screen` +
|
|
380
|
+
` (the other ${128 - renderableCount} are parked off-screen/hidden — not drawn).`,
|
|
381
|
+
regsLive
|
|
382
|
+
? `OBSEL=$${ppu.obsel.toString(16)}: OBJ size pair ${JSON.stringify(ppu.objSize.small)}/` +
|
|
383
|
+
`${JSON.stringify(ppu.objSize.large)}, OBJ tile base VRAM 0x${ppu.objNameBaseByte.toString(16)}, ` +
|
|
384
|
+
`OBJ layer ${ppu.mainScreen.obj ? "ENABLED" : "DISABLED"} on main screen (TM=$${ppu.tm.toString(16)}). ` +
|
|
385
|
+
`Each sprite's tileVramAddr + cgramPaletteRange are resolved from this.`
|
|
386
|
+
: `PPU registers not yet populated (step more frames before trusting OBJ size/base — ` +
|
|
387
|
+
`sizes assume the {8×8,16×16} default and tileVramAddr is null).`,
|
|
388
|
+
];
|
|
389
|
+
if (warnings.length) summary.push(...warnings);
|
|
390
|
+
return jsonContent({
|
|
391
|
+
platform: p,
|
|
392
|
+
sprites,
|
|
393
|
+
renderableCount,
|
|
394
|
+
ppuRegsLive: regsLive,
|
|
395
|
+
ppu: ppu && {
|
|
396
|
+
obsel: ppu.obsel, objSize: ppu.objSize, objNameBaseByte: ppu.objNameBaseByte,
|
|
397
|
+
mainScreenObjEnabled: ppu.mainScreen.obj, tm: ppu.tm, ts: ppu.ts,
|
|
398
|
+
},
|
|
399
|
+
uninitializedObjPalettes: uninitializedPalettes,
|
|
400
|
+
suspiciousObjPalettes: suspiciousPalettes,
|
|
401
|
+
objPaletteReport: paletteReport,
|
|
402
|
+
warnings,
|
|
403
|
+
summary,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (p === "genesis") {
|
|
408
|
+
const vram = host.readMemory("video_ram", 0, 65536);
|
|
409
|
+
const vdpRegs = host.readMemory("genesis_vdp_regs", 0, 32);
|
|
410
|
+
const { decodeGenesisSprites } = await import("../../host/gpgx-state.js");
|
|
411
|
+
const sprites = decodeGenesisSprites(vram, vdpRegs);
|
|
412
|
+
return jsonContent({ platform: p, sprites });
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (p === "sms" || p === "gg") {
|
|
416
|
+
const { snapshotSprites } = await import("../../platforms/sms/vdp.js");
|
|
417
|
+
const snap = snapshotSprites(host, p);
|
|
418
|
+
return emitImage(snap.png, {
|
|
419
|
+
platform: p,
|
|
420
|
+
sprites: snap.sprites,
|
|
421
|
+
vdp: snap.vdp,
|
|
422
|
+
spriteHeight: snap.spriteHeight,
|
|
423
|
+
width: snap.width,
|
|
424
|
+
height: snap.height,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (p === "gb" || p === "gbc") {
|
|
429
|
+
const { snapshotSprites } = await import("../../platforms/gb/ppu.js");
|
|
430
|
+
const snap = snapshotSprites(host, p);
|
|
431
|
+
return emitImage(snap.png, {
|
|
432
|
+
platform: p,
|
|
433
|
+
sprites: snap.sprites,
|
|
434
|
+
lcdc: snap.lcdc,
|
|
435
|
+
spriteHeight: snap.spriteHeight,
|
|
436
|
+
width: snap.width,
|
|
437
|
+
height: snap.height,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (p === "atari2600") {
|
|
442
|
+
// 2600 has no traditional "sprite list" — instead the TIA holds 5
|
|
443
|
+
// graphics objects (P0/P1/M0/M1/Ball) whose state we sample. The
|
|
444
|
+
// kernel re-positions them per-scanline; this is a snapshot.
|
|
445
|
+
const { snapshotTia, snapshotScanline } = await import("../../platforms/atari2600/tia.js");
|
|
446
|
+
const tia = snapshotTia(host);
|
|
447
|
+
const scan = snapshotScanline(host);
|
|
448
|
+
return emitImage(scan.png, {
|
|
449
|
+
platform: p,
|
|
450
|
+
note: scan.note,
|
|
451
|
+
sprites: [
|
|
452
|
+
{ name: "player0", ...tia.sprites.p0, color: tia.colors.p0 },
|
|
453
|
+
{ name: "player1", ...tia.sprites.p1, color: tia.colors.p1 },
|
|
454
|
+
{ name: "missile0", ...tia.sprites.missile0, color: tia.colors.p0 },
|
|
455
|
+
{ name: "missile1", ...tia.sprites.missile1, color: tia.colors.p1 },
|
|
456
|
+
{ name: "ball", ...tia.sprites.ball, color: tia.colors.pf },
|
|
457
|
+
],
|
|
458
|
+
playfield: tia.playfield,
|
|
459
|
+
ctrlpf: tia.ctrlpf,
|
|
460
|
+
nusiz0: tia.nusiz0,
|
|
461
|
+
nusiz1: tia.nusiz1,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (p === "atari7800") {
|
|
466
|
+
// 7800 sprites are driven by MARIA's display list, which lives in
|
|
467
|
+
// RAM at addresses chosen by the game — there's no fixed OAM. We
|
|
468
|
+
// return MARIA regs (background, 8 palettes, control) so the
|
|
469
|
+
// agent can locate the display list via DPP and parse from there.
|
|
470
|
+
const { snapshotPalette } = await import("../../platforms/atari7800/maria.js");
|
|
471
|
+
const { regs, png } = snapshotPalette(host);
|
|
472
|
+
const ram = host.readMemory("system_ram", 0x0080, 0x10);
|
|
473
|
+
const dpp = ram[0x04] | (ram[0x05] << 8); // DPPH/DPPL at $84/$85
|
|
474
|
+
return emitImage(png, {
|
|
475
|
+
platform: p,
|
|
476
|
+
note: "7800 has no fixed OAM. MARIA reads a display list from RAM (pointed at by DPP at $84/$85) each scanline — each entry describes one drawable. To enumerate sprites for the current frame, parse the DL starting at the dpp address. This snapshot shows MARIA's control regs + palette state.",
|
|
477
|
+
dpp: "0x" + dpp.toString(16).toUpperCase().padStart(4, "0"),
|
|
478
|
+
maria: regs,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (p === "c64") {
|
|
483
|
+
const { snapshotSprites } = await import("../../platforms/c64/vic.js");
|
|
484
|
+
const { sprites, vic } = snapshotSprites(host);
|
|
485
|
+
// Sprite pixel-data pointers live at screen[$3F8 + N] × 64. Read
|
|
486
|
+
// them from current screen RAM so the agent can locate sprite art.
|
|
487
|
+
const screenRamBase = parseInt(vic.memPointers.screenRamBaseInVicBank.replace("$", ""), 16);
|
|
488
|
+
const ram = host.readMemory("system_ram", screenRamBase + 0x3F8, 8);
|
|
489
|
+
const spriteDataPointers = Array.from(ram, (b, i) => ({
|
|
490
|
+
slot: i,
|
|
491
|
+
pointerByte: b,
|
|
492
|
+
dataAddr: "$" + (b * 64).toString(16).toUpperCase().padStart(4, "0"),
|
|
493
|
+
dataAddrDec: b * 64,
|
|
494
|
+
}));
|
|
495
|
+
return {
|
|
496
|
+
content: [
|
|
497
|
+
{ type: "text", text: JSON.stringify({
|
|
498
|
+
platform: p, sprites, vic, spriteDataPointers,
|
|
499
|
+
note: "VIC-II has 8 hardware sprites (MOBs). Sprite pixel data lives in main RAM at (screen[$3F8 + N] × 64). spriteDataPointers gives you the address for each.",
|
|
500
|
+
}) },
|
|
501
|
+
],
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
throw new Error(`inspectSprites not yet wired for platform '${p}'. Supported: nes, snes, genesis, sms, gg, gb, gbc, atari2600, atari7800, c64.`);
|
|
506
|
+
}),
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
server.tool(
|
|
510
|
+
"inspectBackgroundMap",
|
|
511
|
+
"Use this to see the loaded ROM's background tile map. NES returns raw CIRAM bytes (or `render:true` " +
|
|
512
|
+
"for a PNG); GB/GBC/SMS/GG/Genesis return a PNG composite of the full BG plane/nametable (scroll is " +
|
|
513
|
+
"shown but NOT applied). `which`/`window`/`plane` select the map. SNES needs you to pass the BG params " +
|
|
514
|
+
"(`tilemapBaseByte`/`tileBaseByte`/`bpp`/`mapWidth`/`mapHeight`) because snes9x doesn't expose PPU " +
|
|
515
|
+
"registers — they default to a Mode-1 BG1 best-guess. See param hints for the rest. " +
|
|
516
|
+
"For platforms/paths that render a PNG (NES render:true, GB/GBC/Genesis/SMS/GG/SNES): DEFAULT writes the PNG to outputPath and returns {imagePath}; pass inline:true to get the image in the response (you must pass one or the other). NES render:false returns raw bytes only — no path needed.",
|
|
517
|
+
{
|
|
518
|
+
platform: z.string().optional(),
|
|
519
|
+
outputPath: z.string().optional().describe("Absolute path to write the BG composite PNG to (image-producing paths only). Required on those paths unless inline:true."),
|
|
520
|
+
inline: z.boolean().default(false).describe("If true, return the BG image in the response instead of writing to disk (image-producing paths only). Default false."),
|
|
521
|
+
render: z.boolean().default(false).describe("NES: if true, return a rendered PNG composite instead of raw bytes. GB/GBC/Genesis: always renders a PNG; this flag is ignored."),
|
|
522
|
+
which: z.number().int().min(0).max(1).default(0).describe("NES: which 1KB nametable (0 = $2000, 1 = $2400). GB/GBC: 0 = $9800 (default), 1 = $9C00."),
|
|
523
|
+
window: z.boolean().default(false).describe("GB/GBC only: if true, render the Window tile map base (follows LCDC.6) instead of the BG map base."),
|
|
524
|
+
plane: z.enum(["A", "B"]).default("A").describe("Genesis only: which scroll plane to render — 'A' (default) or 'B'."),
|
|
525
|
+
tilemapBaseByte: z.number().int().min(0).default(0).describe("SNES only: byte offset into VRAM of the BG tilemap (BGxSC base). Default 0. snes9x doesn't expose PPU regs so this can't be auto-detected — pass your game's BG1 tilemap address."),
|
|
526
|
+
tileBaseByte: z.number().int().min(0).default(0).describe("SNES only: byte offset into VRAM of tile 0 (the BG character base / BGxNBA). Default 0."),
|
|
527
|
+
bpp: z.union([z.literal(2), z.literal(4), z.literal(8)]).default(4).describe("SNES only: tile bit-depth. Mode 1 BG1/BG2 = 4bpp (default), BG3 = 2bpp."),
|
|
528
|
+
mapWidth: z.union([z.literal(32), z.literal(64)]).default(32).describe("SNES only: tilemap width in tiles (32 or 64, per BGxSC size bits)."),
|
|
529
|
+
mapHeight: z.union([z.literal(32), z.literal(64)]).default(32).describe("SNES only: tilemap height in tiles (32 or 64)."),
|
|
530
|
+
},
|
|
531
|
+
safeTool(async ({ platform, render, which, window, plane, tilemapBaseByte, tileBaseByte, bpp, mapWidth, mapHeight, outputPath, inline }) => {
|
|
532
|
+
const host = getHost(sessionKey);
|
|
533
|
+
const p = resolvePlatform(host, platform);
|
|
534
|
+
// Gate the PNG; the textual note travels alongside it. Used by every
|
|
535
|
+
// image-producing path. NES render:false stays JSON-only (no image).
|
|
536
|
+
const emitImage = async (pngBuf, note) => {
|
|
537
|
+
requireImageTarget(outputPath, inline, "inspectBackgroundMap");
|
|
538
|
+
if (inline) {
|
|
539
|
+
return {
|
|
540
|
+
content: [
|
|
541
|
+
imageContent(pngBuf.toString("base64")),
|
|
542
|
+
{ type: "text", text: note },
|
|
543
|
+
],
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
await writeFile(outputPath, pngBuf);
|
|
547
|
+
const json = jsonContent({ platform: p, imagePath: outputPath, note });
|
|
548
|
+
json._observerImages = [{ kind: "image", mimeType: "image/png", base64: pngBuf.toString("base64") }];
|
|
549
|
+
return json;
|
|
550
|
+
};
|
|
551
|
+
if (p === "nes") {
|
|
552
|
+
if (render) {
|
|
553
|
+
const { snapshotNametable } = await import("../../platforms/nes/ppu.js");
|
|
554
|
+
const png = snapshotNametable(host, { which });
|
|
555
|
+
return emitImage(png, `Background composite (nametable ${which}, 256×240).`);
|
|
556
|
+
}
|
|
557
|
+
const nt = host.readMemory("nes_nametables", 0, 2048);
|
|
558
|
+
return jsonContent({
|
|
559
|
+
bytes: 2048,
|
|
560
|
+
hex: Array.from(nt, (b) => b.toString(16).padStart(2, "0")).join(""),
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
if (p === "gb" || p === "gbc") {
|
|
564
|
+
const { snapshotBackgroundMap } = await import("../../platforms/gb/ppu.js");
|
|
565
|
+
const snap = snapshotBackgroundMap(host, { which, window, platform: p });
|
|
566
|
+
const label = window ? "Window map" : "BG map";
|
|
567
|
+
return emitImage(snap.png, `${p.toUpperCase()} ${label} composite (${snap.width}×${snap.height}, base=${snap.mapBase}, mode=${snap.mode}, scroll=(${snap.scx},${snap.scy})). ${snap.note}`);
|
|
568
|
+
}
|
|
569
|
+
if (p === "genesis") {
|
|
570
|
+
const { snapshotPlaneMap } = await import("../../platforms/genesis/vdp.js");
|
|
571
|
+
const snap = snapshotPlaneMap(host, { plane });
|
|
572
|
+
return emitImage(snap.png, `Genesis ${snap.plane === "B" ? "Plane B" : "Plane A"} composite (${snap.width}×${snap.height}, base=${snap.baseAddr}, ${snap.wCells}×${snap.hCells} cells). ${snap.note}`);
|
|
573
|
+
}
|
|
574
|
+
if (p === "sms" || p === "gg") {
|
|
575
|
+
const { snapshotBackgroundMap } = await import("../../platforms/sms/vdp.js");
|
|
576
|
+
const snap = snapshotBackgroundMap(host, p);
|
|
577
|
+
return emitImage(snap.png, `${p.toUpperCase()} BG map composite (${snap.width}×${snap.height}, base=${snap.mapBase}, scroll=(${snap.scrollX},${snap.scrollY})). ${snap.note}`);
|
|
578
|
+
}
|
|
579
|
+
if (p === "snes") {
|
|
580
|
+
const { renderSnesTilemap, decodeCGRAM } = await import("../../platforms/snes/ppu.js");
|
|
581
|
+
const vram = host.readMemory("video_ram", 0, 0x10000);
|
|
582
|
+
const cgram = host.readMemory("snes_cgram", 0, 512);
|
|
583
|
+
const colors = decodeCGRAM(cgram);
|
|
584
|
+
const r = renderSnesTilemap(vram, colors, {
|
|
585
|
+
tilemapBaseByte, tileBaseByte, bpp, mapWidth, mapHeight,
|
|
586
|
+
});
|
|
587
|
+
return emitImage(r.png, `SNES BG map composite (${r.width}×${r.height}, ${r.mapWidth}×${r.mapHeight} tiles, ${r.bpp}bpp, tilemap@0x${tilemapBaseByte.toString(16)}, tiles@0x${tileBaseByte.toString(16)}). ${r.note}`);
|
|
588
|
+
}
|
|
589
|
+
throw new Error(`inspectBackgroundMap not yet implemented for platform '${p}'`);
|
|
590
|
+
}),
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
server.tool(
|
|
594
|
+
"convertImageToTiles",
|
|
595
|
+
"Use this to convert a PNG to a platform's native tile-byte format — raw tiles, no tilemap (use " +
|
|
596
|
+
"imageToTilemap for a full picture with screen/attribute data). Supported: nes, gb, gbc, sms, gg, " +
|
|
597
|
+
"snes, genesis, atari7800, c64 — each with its native bit-depth/layout; programmable-palette " +
|
|
598
|
+
"platforms also return a suggested palette. Image width/height must be multiples of 8. Good for " +
|
|
599
|
+
"demakes (rip art from one platform, re-encode for another) — combine with patchRom or your source. " +
|
|
600
|
+
"DEFAULT writes tiles.bin (+ palette.bin if a palette is produced) into outputDir and returns paths; pass " +
|
|
601
|
+
"inline:true to get tilesBase64/paletteHex in the response (you must pass one or the other).",
|
|
602
|
+
{
|
|
603
|
+
platform: z.string(),
|
|
604
|
+
pngBase64: z.string(),
|
|
605
|
+
maxTiles: z.number().int().min(1).max(8192).default(512),
|
|
606
|
+
outputDir: z.string().optional().describe("Directory to write tiles.bin (+ palette.bin). Required unless inline:true."),
|
|
607
|
+
inline: z.boolean().default(false).describe("If true, return tilesBase64/paletteBase64/paletteHex in the response instead of writing to disk. Default false — then outputDir is required."),
|
|
608
|
+
},
|
|
609
|
+
safeTool(async ({ platform, pngBase64, maxTiles, outputDir, inline }) => {
|
|
610
|
+
if (!inline && !outputDir) {
|
|
611
|
+
throw new Error("convertImageToTiles: pass outputDir (write tiles.bin/palette.bin to disk, returns paths) or inline:true (return base64 in the response).");
|
|
612
|
+
}
|
|
613
|
+
const { imageToTiles } = await import("../../platforms/common/image-to-tiles.js");
|
|
614
|
+
const png = Buffer.from(pngBase64, "base64");
|
|
615
|
+
const r = imageToTiles(platform, png, { maxTiles });
|
|
616
|
+
// Indexed-PNG / palette validation. Catches the most common
|
|
617
|
+
// newbie failure mode: paint in 24-bit RGB → silent color shift.
|
|
618
|
+
const warnings = await validateImagePalette(platform, png);
|
|
619
|
+
const out = {
|
|
620
|
+
platform: r.platform,
|
|
621
|
+
tilesAcross: r.tilesAcross,
|
|
622
|
+
tilesDown: r.tilesDown,
|
|
623
|
+
totalTiles: r.totalTiles,
|
|
624
|
+
tilesBytes: r.tiles.length,
|
|
625
|
+
};
|
|
626
|
+
if (inline) {
|
|
627
|
+
out.tilesBase64 = Buffer.from(r.tiles).toString("base64");
|
|
628
|
+
if (r.palette) {
|
|
629
|
+
out.paletteBase64 = Buffer.from(r.palette).toString("base64");
|
|
630
|
+
out.paletteBytes = r.palette.length;
|
|
631
|
+
out.paletteHex = Array.from(r.palette, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
632
|
+
}
|
|
633
|
+
} else {
|
|
634
|
+
await mkdir(outputDir, { recursive: true });
|
|
635
|
+
out.tilesPath = path.join(outputDir, "tiles.bin");
|
|
636
|
+
await writeFile(out.tilesPath, Buffer.from(r.tiles));
|
|
637
|
+
if (r.palette) {
|
|
638
|
+
out.palettePath = path.join(outputDir, "palette.bin");
|
|
639
|
+
await writeFile(out.palettePath, Buffer.from(r.palette));
|
|
640
|
+
out.paletteBytes = r.palette.length;
|
|
641
|
+
out.paletteHex = Array.from(r.palette, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (warnings.length) out.warnings = warnings;
|
|
645
|
+
if (platform === "nes") {
|
|
646
|
+
out.note = "Use patchRom to write the tile bytes (tilesPath / tilesBase64) to the CHR region of an iNES file (offset 16 + prgBanks*16384).";
|
|
647
|
+
} else if (platform === "gb" || platform === "gbc") {
|
|
648
|
+
out.note = "Game Boy uses fixed grayscale (DMG) or runtime palettes (CGB). Tiles are in 'interleaved' bitplane order. Inject into your VRAM via the rgbasm `INCBIN` directive or load via DMA at runtime.";
|
|
649
|
+
} else if (platform === "snes") {
|
|
650
|
+
out.note = "SNES 4bpp 'planar-pairs' layout (32 B/tile). `paletteHex` is a suggested 16-color sub-palette (BGR555 words you'd DMA into CGRAM). DMA the tile bytes to VRAM at your BG/OBJ char base.";
|
|
651
|
+
} else if (platform === "genesis") {
|
|
652
|
+
out.note = "Genesis 4bpp 'packed' layout (32 B/tile, high nibble = left pixel). DMA the tile bytes to VRAM; `paletteHex` is a suggested CRAM sub-palette (write to one of the 4 16-color banks).";
|
|
653
|
+
} else if (platform === "sms" || platform === "gg") {
|
|
654
|
+
out.note = "SMS/GG 4bpp 'interleaved' layout (32 B/tile, per-row [p0,p1,p2,p3]). Write tiles to VRAM tile data base (VDP reg 4); `paletteHex` is a suggested CRAM palette.";
|
|
655
|
+
} else if (platform === "c64") {
|
|
656
|
+
out.note = "C64 hi-res charset: each tile is one 8×8 char (8 B, 1bpp — bit set = foreground in the cell's Color-RAM color, clear = shared background). Load the tile bytes (tilesPath / tilesBase64) into your char base ($0800/$1000/etc.). For a full picture with per-cell colors + screen RAM, use imageToTilemap({platform:'c64'}) instead.";
|
|
657
|
+
}
|
|
658
|
+
return jsonContent(out);
|
|
659
|
+
}),
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
// ---- Background image conversion (platform-generic) -------------------
|
|
663
|
+
// Convention: caller already resized + dithered the image into the
|
|
664
|
+
// platform's native palette using the PNG returned by getPlatformPalettePng.
|
|
665
|
+
// The MCP tool then does the platform-specific tile/attribute encoding.
|
|
666
|
+
|
|
667
|
+
server.tool(
|
|
668
|
+
"getPlatformPalettePng",
|
|
669
|
+
"Return the target platform's master palette in one of three formats:\n" +
|
|
670
|
+
" - `png` (default): PNG swatch sheet — every distinct color the hardware can display.\n" +
|
|
671
|
+
" Use as the ImageMagick -remap target: `magick in.png -dither FloydSteinberg -remap palette.png out.png`.\n" +
|
|
672
|
+
" - `lospec`: Lospec JSON `{name, author, colors:[hex_no_hash]}` — drops straight into LibreSprite / lospec.com.\n" +
|
|
673
|
+
" - `hex`: text, one `#RRGGBB` per line — universal interchange.\n" +
|
|
674
|
+
"Pass `outputPath` to write the result to disk and skip the inline base64 / JSON.",
|
|
675
|
+
{
|
|
676
|
+
platform: z.string().describe("Target platform id (e.g. 'nes')."),
|
|
677
|
+
format: z.enum(["png", "lospec", "hex"]).default("png").describe("Output format. 'png' = swatch sheet for ImageMagick dithering (default). 'lospec' = Lospec-compatible JSON for LibreSprite import. 'hex' = one #RRGGBB per line."),
|
|
678
|
+
outputPath: z.string().optional().describe("If given, write the result to this absolute path. Skips inline payload in the response."),
|
|
679
|
+
},
|
|
680
|
+
safeTool(async ({ platform, format, outputPath }) => {
|
|
681
|
+
const { getPlatformPaletteRgb, rgbHex, rgbHexLospec } = await import("../../platforms/common/platform-palette.js");
|
|
682
|
+
if (format === "lospec") {
|
|
683
|
+
const colors = getPlatformPaletteRgb(platform).map(([r, g, b]) => rgbHexLospec(r, g, b));
|
|
684
|
+
const json = {
|
|
685
|
+
name: `${platform} master palette`,
|
|
686
|
+
author: "romdev",
|
|
687
|
+
colors,
|
|
688
|
+
};
|
|
689
|
+
if (outputPath) {
|
|
690
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
691
|
+
await writeFile(outputPath, JSON.stringify(json, null, 2));
|
|
692
|
+
return jsonContent({ platform, format, path: outputPath, colors: colors.length });
|
|
693
|
+
}
|
|
694
|
+
return jsonContent({ platform, format, json });
|
|
695
|
+
}
|
|
696
|
+
if (format === "hex") {
|
|
697
|
+
const lines = getPlatformPaletteRgb(platform).map(([r, g, b]) => rgbHex(r, g, b));
|
|
698
|
+
const text = lines.join("\n") + "\n";
|
|
699
|
+
if (outputPath) {
|
|
700
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
701
|
+
await writeFile(outputPath, text);
|
|
702
|
+
return jsonContent({ platform, format, path: outputPath, colors: lines.length });
|
|
703
|
+
}
|
|
704
|
+
return jsonContent({ platform, format, text });
|
|
705
|
+
}
|
|
706
|
+
// format === "png"
|
|
707
|
+
const png = await getPlatformPalettePng(platform);
|
|
708
|
+
if (outputPath) {
|
|
709
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
710
|
+
await writeFile(outputPath, png);
|
|
711
|
+
return jsonContent({
|
|
712
|
+
platform,
|
|
713
|
+
format: "png",
|
|
714
|
+
path: outputPath,
|
|
715
|
+
bytes: png.length,
|
|
716
|
+
note: "Use this PNG as the ImageMagick -remap target. The dithered output is what imageToTilemap expects.",
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
return jsonContent({
|
|
720
|
+
platform,
|
|
721
|
+
format: "png",
|
|
722
|
+
pngBase64: Buffer.from(png).toString("base64"),
|
|
723
|
+
note: "Save these bytes to a .png and pass it to ImageMagick as the -remap target. The resulting dithered image is what imageToTilemap expects. (Pass outputPath next time to skip the inline base64.)",
|
|
724
|
+
});
|
|
725
|
+
}),
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
server.tool(
|
|
729
|
+
"imageToTilemap",
|
|
730
|
+
"Use this to render a large PNG (title screen, cutscene, status panel, world map) from tiles: returns " +
|
|
731
|
+
"tile graphics + tilemap (NES nametable / SNES tilemap / GB BG map / C64 screen RAM) + per-cell " +
|
|
732
|
+
"palette/attribute + palette table, with tile dedup (h/v-flip aware). Supported: nes, snes, genesis, " +
|
|
733
|
+
"sms, gg, gb, gbc, c64. PREREQUISITE: the PNG must already be sized to the platform's native screen and " +
|
|
734
|
+
"quantized to its palette (see getPlatformPalettePng) — per-platform cell/bpp details are in the " +
|
|
735
|
+
"platform's MENTAL_MODEL.md. Pass `pngPath` (preferred) or `pngBase64`; pass `outputDir` to write " +
|
|
736
|
+
"chr/nametable/attr/palette/preview to disk instead of base64-inlining them.",
|
|
737
|
+
{
|
|
738
|
+
platform: z.string().describe("Target platform id."),
|
|
739
|
+
pngBase64: z.string().optional().describe("Base64-encoded PNG. Use `pngPath` instead when the image is already on disk to keep your context small."),
|
|
740
|
+
pngPath: z.string().optional().describe("Absolute path to a PNG file on disk. Preferred over pngBase64 — server reads the file directly."),
|
|
741
|
+
outputDir: z.string().optional().describe("Directory to write chr.bin, nametable.bin, attr.bin, palette.bin, preview.png into. When set, the response omits the base64 fields and returns paths instead. Created if it doesn't exist."),
|
|
742
|
+
maxTiles: z.number().int().min(1).max(4096).optional().describe("Cap on unique tiles (only used when dedup=true). Defaults to the platform's pattern-table limit (NES: 256)."),
|
|
743
|
+
backdrop: z.number().int().min(0).optional().describe("Force a specific master-palette index for the universal backdrop. If omitted, the most-common color is used."),
|
|
744
|
+
dedup: z.boolean().default(true).describe("If true (default), collapse identical tile bitmaps to one CHR entry."),
|
|
745
|
+
singlePalette: z.boolean().default(false).describe("If true, every attribute cell uses one identical palette. Limits the image to 4 total colors."),
|
|
746
|
+
},
|
|
747
|
+
safeTool(async ({ platform, pngBase64, pngPath, outputDir, maxTiles, backdrop, dedup, singlePalette }) => {
|
|
748
|
+
let pngBytes;
|
|
749
|
+
if (pngPath) {
|
|
750
|
+
pngBytes = await readFile(pngPath);
|
|
751
|
+
} else if (pngBase64) {
|
|
752
|
+
pngBytes = Buffer.from(pngBase64, "base64");
|
|
753
|
+
} else {
|
|
754
|
+
throw new Error("imageToTilemap: must provide either pngBase64 or pngPath");
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
const r = await imageToTilemap(platform, {
|
|
758
|
+
pngBytes,
|
|
759
|
+
maxTiles,
|
|
760
|
+
backdrop,
|
|
761
|
+
dedup,
|
|
762
|
+
singlePalette,
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
if (outputDir) {
|
|
766
|
+
await mkdir(outputDir, { recursive: true });
|
|
767
|
+
const chrPath = path.join(outputDir, "chr.bin");
|
|
768
|
+
const nametablePath = path.join(outputDir, "nametable.bin");
|
|
769
|
+
const attrPath = path.join(outputDir, "attr.bin");
|
|
770
|
+
const palettePath = path.join(outputDir, "palette.bin");
|
|
771
|
+
const previewPath = path.join(outputDir, "preview.png");
|
|
772
|
+
await writeFile(chrPath, r.chr);
|
|
773
|
+
await writeFile(nametablePath, r.nametable);
|
|
774
|
+
await writeFile(attrPath, r.attr);
|
|
775
|
+
await writeFile(palettePath, r.palette);
|
|
776
|
+
await writeFile(previewPath, r.previewPng);
|
|
777
|
+
return jsonContent({
|
|
778
|
+
platform,
|
|
779
|
+
chrPath,
|
|
780
|
+
chrBytes: r.chr.length,
|
|
781
|
+
nametablePath,
|
|
782
|
+
attrPath,
|
|
783
|
+
palettePath,
|
|
784
|
+
paletteHex: Array.from(r.palette, (b) => b.toString(16).padStart(2, "0")).join(""),
|
|
785
|
+
previewPath,
|
|
786
|
+
uniqueTilesBeforeMerge: r.uniqueTilesBeforeMerge,
|
|
787
|
+
uniqueTiles: r.uniqueTiles,
|
|
788
|
+
...(r._c64 ? { c64: r._c64 } : {}),
|
|
789
|
+
...(r._genesis ? { genesis: r._genesis } : {}),
|
|
790
|
+
note: platform === "c64"
|
|
791
|
+
? `C64 hi-res char mode: chr.bin = charset (${r.uniqueTiles} chars × 8B, load into your char base), ` +
|
|
792
|
+
`nametable.bin = screen RAM (1000 B of char codes → $0400), attr.bin = Color RAM (1000 B, low nibble = ` +
|
|
793
|
+
`per-cell fg color → $D800), palette.bin = 1 byte shared background color → $D021.` +
|
|
794
|
+
(r._c64?.warnings?.length ? " WARNINGS: " + r._c64.warnings.join(" ") : "")
|
|
795
|
+
: platform === "genesis"
|
|
796
|
+
? `Genesis VDP: chr.bin = ${r.uniqueTiles} deduped 4bpp tiles (32 B each, DMA to VRAM). ` +
|
|
797
|
+
`nametable.bin = ${40 * 28} 16-bit BE name-table entries (40×28 cells; tile idx + palette line + h/v flip). ` +
|
|
798
|
+
`palette.bin = 4 lines × 16 colors (128 B BE CRAM words; ${r._genesis?.paletteLines} line(s) used). ` +
|
|
799
|
+
`Set plane width to 64 cells and write the nametable to your Plane A base.` +
|
|
800
|
+
(r._genesis?.warnings?.length ? " WARNINGS: " + r._genesis.warnings.slice(0, 3).join(" ") : "")
|
|
801
|
+
: "Paths written. Pass them as binaryIncludePaths into buildSource.",
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
return jsonContent({
|
|
806
|
+
platform,
|
|
807
|
+
chrBase64: Buffer.from(r.chr).toString("base64"),
|
|
808
|
+
chrBytes: r.chr.length,
|
|
809
|
+
nametableBase64: Buffer.from(r.nametable).toString("base64"),
|
|
810
|
+
attrBase64: Buffer.from(r.attr).toString("base64"),
|
|
811
|
+
paletteBase64: Buffer.from(r.palette).toString("base64"),
|
|
812
|
+
paletteHex: Array.from(r.palette, (b) => b.toString(16).padStart(2, "0")).join(""),
|
|
813
|
+
uniqueTilesBeforeMerge: r.uniqueTilesBeforeMerge,
|
|
814
|
+
uniqueTiles: r.uniqueTiles,
|
|
815
|
+
previewPngBase64: Buffer.from(r.previewPng).toString("base64"),
|
|
816
|
+
...(r._c64 ? { c64: r._c64 } : {}),
|
|
817
|
+
...(r._genesis ? { genesis: r._genesis } : {}),
|
|
818
|
+
note: platform === "c64"
|
|
819
|
+
? `C64 hi-res char mode: chrBase64 = charset (${r.uniqueTiles} chars × 8B), nametableBase64 = screen RAM ` +
|
|
820
|
+
`(char codes → $0400), attrBase64 = Color RAM (low nibble = per-cell fg → $D800), paletteBase64 = ` +
|
|
821
|
+
`shared background color byte → $D021.` +
|
|
822
|
+
(r._c64?.warnings?.length ? " WARNINGS: " + r._c64.warnings.join(" ") : "")
|
|
823
|
+
: platform === "genesis"
|
|
824
|
+
? `Genesis VDP: chrBase64 = ${r.uniqueTiles} deduped 4bpp tiles (32 B each). nametableBase64 = 40×28 ` +
|
|
825
|
+
`16-bit BE entries (tile + palette line + flip). paletteBase64 = 4×16 CRAM words (${r._genesis?.paletteLines} used). ` +
|
|
826
|
+
`Pass outputDir to get .bin files instead of base64.` +
|
|
827
|
+
(r._genesis?.warnings?.length ? " WARNINGS: " + r._genesis.warnings.slice(0, 3).join(" ") : "")
|
|
828
|
+
: "Pass outputDir next call to skip inline base64 and get back paths instead.",
|
|
829
|
+
});
|
|
830
|
+
}),
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* Render a generic color list as a PNG swatch grid. Each color becomes
|
|
836
|
+
* a `swatchSize`-pixel square. `cols` controls grid width. Used by the
|
|
837
|
+
* generic inspectPalette path so SNES/Genesis/GB get the same visual.
|
|
838
|
+
*
|
|
839
|
+
* @param {Array<{ r: number, g: number, b: number }>} colors
|
|
840
|
+
* @param {number} [cols=16]
|
|
841
|
+
* @param {number} [swatchSize=12]
|
|
842
|
+
*/
|
|
843
|
+
function renderColorsAsPng(colors, cols = 16, swatchSize = 12) {
|
|
844
|
+
const rows = Math.ceil(colors.length / cols);
|
|
845
|
+
const width = cols * swatchSize;
|
|
846
|
+
const height = rows * swatchSize;
|
|
847
|
+
const png = new PNG({ width, height });
|
|
848
|
+
for (let cy = 0; cy < rows; cy++) {
|
|
849
|
+
for (let cx = 0; cx < cols; cx++) {
|
|
850
|
+
const idx = cy * cols + cx;
|
|
851
|
+
if (idx >= colors.length) break;
|
|
852
|
+
const { r, g, b } = colors[idx];
|
|
853
|
+
for (let py = 0; py < swatchSize; py++) {
|
|
854
|
+
for (let px = 0; px < swatchSize; px++) {
|
|
855
|
+
const x = cx * swatchSize + px;
|
|
856
|
+
const y = cy * swatchSize + py;
|
|
857
|
+
const o = (y * width + x) * 4;
|
|
858
|
+
png.data[o] = r;
|
|
859
|
+
png.data[o + 1] = g;
|
|
860
|
+
png.data[o + 2] = b;
|
|
861
|
+
png.data[o + 3] = 0xFF;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return PNG.sync.write(png);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Platform-generic dispatcher for background palette PNG. Adding a new
|
|
871
|
+
* platform means adding one branch here.
|
|
872
|
+
* @param {string} platform
|
|
873
|
+
*/
|
|
874
|
+
async function getPlatformPalettePng(platform) {
|
|
875
|
+
if (platform === "nes") {
|
|
876
|
+
const { nesPalettePng } = await import("../../platforms/nes/image-to-tilemap.js");
|
|
877
|
+
return nesPalettePng();
|
|
878
|
+
}
|
|
879
|
+
if (platform === "snes") {
|
|
880
|
+
const { snesPalettePng } = await import("../../platforms/snes/image-to-tilemap.js");
|
|
881
|
+
return snesPalettePng();
|
|
882
|
+
}
|
|
883
|
+
if (platform === "genesis") {
|
|
884
|
+
const { genesisPalettePng } = await import("../../platforms/genesis/image-to-tilemap.js");
|
|
885
|
+
return genesisPalettePng();
|
|
886
|
+
}
|
|
887
|
+
if (platform === "sms" || platform === "gg") {
|
|
888
|
+
const { smsPalettePng } = await import("../../platforms/sms/image-to-tilemap.js");
|
|
889
|
+
return smsPalettePng();
|
|
890
|
+
}
|
|
891
|
+
if (platform === "gb" || platform === "gbc") {
|
|
892
|
+
const { gbPalettePng } = await import("../../platforms/gb/image-to-tilemap.js");
|
|
893
|
+
return gbPalettePng();
|
|
894
|
+
}
|
|
895
|
+
if (platform === "atari2600" || platform === "a2600") {
|
|
896
|
+
const { renderNtscPalettePng } = await import("../../platforms/atari2600/tia.js");
|
|
897
|
+
return renderNtscPalettePng();
|
|
898
|
+
}
|
|
899
|
+
if (platform === "atari7800" || platform === "a7800") {
|
|
900
|
+
const { renderA78MasterPalettePng } = await import("../../platforms/atari7800/maria.js");
|
|
901
|
+
return renderA78MasterPalettePng();
|
|
902
|
+
}
|
|
903
|
+
if (platform === "c64") {
|
|
904
|
+
const { renderC64PalettePng } = await import("../../platforms/c64/vic.js");
|
|
905
|
+
return renderC64PalettePng();
|
|
906
|
+
}
|
|
907
|
+
throw new Error(`getPlatformPalettePng not implemented for '${platform}'. Currently supported: nes, snes, genesis, sms, gg, gb, gbc, atari2600, atari7800, c64.`);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Platform-generic dispatcher for image-to-tilemap conversion.
|
|
912
|
+
* @param {string} platform
|
|
913
|
+
* @param {{ pngBytes: Buffer | Uint8Array, maxTiles?: number, backdrop?: number, numPalettes?: number }} args
|
|
914
|
+
*/
|
|
915
|
+
async function imageToTilemap(platform, args) {
|
|
916
|
+
if (platform === "nes") {
|
|
917
|
+
const { nesImageToTilemap } = await import("../../platforms/nes/image-to-tilemap.js");
|
|
918
|
+
return nesImageToTilemap(args);
|
|
919
|
+
}
|
|
920
|
+
if (platform === "snes") {
|
|
921
|
+
const { snesImageToTilemap } = await import("../../platforms/snes/image-to-tilemap.js");
|
|
922
|
+
const r = snesImageToTilemap(args);
|
|
923
|
+
// Normalize return shape: SNES returns `tilemap` instead of `nametable`/`attr`.
|
|
924
|
+
return {
|
|
925
|
+
chr: r.chr,
|
|
926
|
+
nametable: r.tilemap, // SNES tilemap goes where NES nametable goes
|
|
927
|
+
attr: new Uint8Array(0), // SNES has no separate attr table (per-tile bits)
|
|
928
|
+
palette: r.palette,
|
|
929
|
+
uniqueTilesBeforeMerge: r.uniqueTiles,
|
|
930
|
+
uniqueTiles: r.uniqueTiles,
|
|
931
|
+
previewPng: r.previewPng,
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
if (platform === "sms" || platform === "gg") {
|
|
935
|
+
const { smsImageToTilemap } = await import("../../platforms/sms/image-to-tilemap.js");
|
|
936
|
+
return smsImageToTilemap(args);
|
|
937
|
+
}
|
|
938
|
+
if (platform === "genesis") {
|
|
939
|
+
const { genesisImageToTilemap } = await import("../../platforms/genesis/image-to-tilemap.js");
|
|
940
|
+
const r = genesisImageToTilemap(args);
|
|
941
|
+
return {
|
|
942
|
+
chr: r.chr,
|
|
943
|
+
nametable: r.nametable,
|
|
944
|
+
attr: r.attr,
|
|
945
|
+
palette: r.palette,
|
|
946
|
+
uniqueTilesBeforeMerge: r.uniqueTilesBeforeMerge,
|
|
947
|
+
uniqueTiles: r.uniqueTiles,
|
|
948
|
+
previewPng: r.previewPng,
|
|
949
|
+
_genesis: { paletteLines: r.paletteLines, imageColors: r.imageColors, warnings: r.warnings },
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
if (platform === "gb" || platform === "gbc") {
|
|
953
|
+
const { gbImageToTilemap } = await import("../../platforms/gb/image-to-tilemap.js");
|
|
954
|
+
return gbImageToTilemap(args);
|
|
955
|
+
}
|
|
956
|
+
if (platform === "c64") {
|
|
957
|
+
const { c64ImageToTilemap } = await import("../../platforms/c64/image-to-tilemap.js");
|
|
958
|
+
const r = c64ImageToTilemap(args);
|
|
959
|
+
// Normalize to the dispatcher's expected field names. C64 "chr" is the
|
|
960
|
+
// charset, "nametable" is screen RAM, "attr" is color RAM.
|
|
961
|
+
return {
|
|
962
|
+
chr: r.chr,
|
|
963
|
+
nametable: r.nametable,
|
|
964
|
+
attr: r.attr,
|
|
965
|
+
palette: r.palette,
|
|
966
|
+
uniqueTilesBeforeMerge: r.uniqueTilesBeforeMerge,
|
|
967
|
+
uniqueTiles: r.uniqueTiles,
|
|
968
|
+
previewPng: r.previewPng,
|
|
969
|
+
_c64: { backgroundColor: r.backgroundColor, imageColors: r.imageColors, warnings: r.warnings },
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
if (platform === "atari2600" || platform === "a2600") {
|
|
973
|
+
throw new Error(
|
|
974
|
+
`imageToTilemap[2600]: the 2600 has no tile/tilemap concept. The playfield ` +
|
|
975
|
+
`is 20 mirrored bits (PF0/PF1/PF2) that change every scanline, plus 5 ` +
|
|
976
|
+
`sprite objects. Pictures must be hand-authored as per-scanline byte ` +
|
|
977
|
+
`streams. There is no automated PNG → 2600 path.`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
if (platform === "atari7800" || platform === "a7800") {
|
|
981
|
+
throw new Error(
|
|
982
|
+
`imageToTilemap[7800]: MARIA reads "display lists" — variable-width sprite/ ` +
|
|
983
|
+
`character chunks at user-defined RAM addresses — instead of a fixed tilemap. ` +
|
|
984
|
+
`Converting an arbitrary PNG would require generating a per-zone display list ` +
|
|
985
|
+
`tuned to the cart, which is game-specific. Not auto-implemented.`
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
throw new Error(`imageToTilemap not implemented for '${platform}'. Currently supported: nes, snes, sms, gg, gb, gbc.`);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* Scan a PNG buffer against the platform's master palette and return
|
|
993
|
+
* an array of human-readable warnings (empty array = OK). Never throws.
|
|
994
|
+
* Indexed PNGs are validated via their PLTE chunk; truecolor PNGs are
|
|
995
|
+
* validated by scanning distinct RGB pixels (capped at 256 for cost).
|
|
996
|
+
*
|
|
997
|
+
* @param {string} platform
|
|
998
|
+
* @param {Buffer} pngBuf
|
|
999
|
+
* @returns {Promise<string[]>}
|
|
1000
|
+
*/
|
|
1001
|
+
async function validateImagePalette(platform, pngBuf) {
|
|
1002
|
+
const warnings = [];
|
|
1003
|
+
let pal;
|
|
1004
|
+
try {
|
|
1005
|
+
const { getPlatformPaletteRgb, paletteContains, rgbHex } =
|
|
1006
|
+
await import("../../platforms/common/platform-palette.js");
|
|
1007
|
+
pal = getPlatformPaletteRgb(platform);
|
|
1008
|
+
// Tolerance: 8 per channel covers LibreSprite sRGB drift. NES/Genesis
|
|
1009
|
+
// strict palettes still match within this.
|
|
1010
|
+
const TOL = 8;
|
|
1011
|
+
const decoded = PNG.sync.read(pngBuf);
|
|
1012
|
+
const plte = decoded.palette; // [[r,g,b,a],...] when PLTE present
|
|
1013
|
+
if (plte && plte.length) {
|
|
1014
|
+
const oob = [];
|
|
1015
|
+
for (let i = 0; i < plte.length; i++) {
|
|
1016
|
+
const [r, g, b] = plte[i];
|
|
1017
|
+
if (!paletteContains(pal, r, g, b, TOL)) {
|
|
1018
|
+
oob.push(rgbHex(r, g, b));
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
if (oob.length) {
|
|
1022
|
+
warnings.push(
|
|
1023
|
+
`PNG PLTE has ${oob.length}/${plte.length} colors outside the ${platform} palette` +
|
|
1024
|
+
` (tolerance ±${TOL}/channel): ` +
|
|
1025
|
+
oob.slice(0, 8).join(", ") + (oob.length > 8 ? `, ... (+${oob.length - 8} more)` : "") +
|
|
1026
|
+
`. Re-export from your editor using getPlatformPalettePng({platform:"${platform}", format:"hex"|"lospec"}) as the source palette.`
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
} else {
|
|
1030
|
+
// Truecolor — scan distinct RGB triples (cap at 256 for cost).
|
|
1031
|
+
const seen = new Map();
|
|
1032
|
+
const buf = decoded.data;
|
|
1033
|
+
const MAX_DISTINCT = 256;
|
|
1034
|
+
for (let i = 0; i < buf.length; i += 4) {
|
|
1035
|
+
const a = buf[i + 3];
|
|
1036
|
+
if (a === 0) continue; // skip fully transparent
|
|
1037
|
+
const key = (buf[i] << 16) | (buf[i + 1] << 8) | buf[i + 2];
|
|
1038
|
+
if (!seen.has(key)) {
|
|
1039
|
+
seen.set(key, [buf[i], buf[i + 1], buf[i + 2]]);
|
|
1040
|
+
if (seen.size > MAX_DISTINCT) break;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
const oob = [];
|
|
1044
|
+
for (const [r, g, b] of seen.values()) {
|
|
1045
|
+
if (!paletteContains(pal, r, g, b, TOL)) {
|
|
1046
|
+
oob.push(rgbHex(r, g, b));
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
if (oob.length) {
|
|
1050
|
+
warnings.push(
|
|
1051
|
+
`PNG has ${oob.length}/${seen.size} distinct colors outside the ${platform} palette` +
|
|
1052
|
+
` (tolerance ±${TOL}/channel): ` +
|
|
1053
|
+
oob.slice(0, 8).join(", ") + (oob.length > 8 ? `, ... (+${oob.length - 8} more)` : "") +
|
|
1054
|
+
`. Quantize to the platform palette first — call getPlatformPalettePng({platform:"${platform}"}) and use the PNG as ImageMagick's -remap target.`
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
} catch (e) {
|
|
1059
|
+
// Never block the build over a validator hiccup.
|
|
1060
|
+
warnings.push(`palette-validation skipped: ${e.message}`);
|
|
1061
|
+
}
|
|
1062
|
+
return warnings;
|
|
1063
|
+
}
|