romdevtools 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1110 -0
- package/CHANGELOG.md +525 -0
- package/LICENSE +45 -0
- package/NOTICE +102 -0
- package/README.md +84 -0
- package/examples/README.md +36 -0
- package/examples/art-first-workflow/README.md +209 -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/msx/catch_game/README.md +75 -0
- package/examples/msx/catch_game/_verify.mjs +93 -0
- package/examples/msx/catch_game/main.c +249 -0
- package/examples/msx/catch_game/shot_after_left.png +0 -0
- package/examples/msx/catch_game/shot_after_right.png +0 -0
- package/examples/msx/catch_game/shot_before.png +0 -0
- package/examples/msx/catch_game/shot_scored.png +0 -0
- package/examples/msx/music_sfx/README.md +38 -0
- package/examples/msx/music_sfx/main.c +164 -0
- package/examples/msx/sprite_move/README.md +44 -0
- package/examples/msx/sprite_move/main.c +100 -0
- package/examples/nes/main.c +143 -0
- package/examples/nes/space-shooter/README.md +69 -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/pce/catch_game/README.md +8 -0
- package/examples/pce/catch_game/_verify.mjs +75 -0
- package/examples/pce/catch_game/main.c +327 -0
- package/examples/pce/catch_game/shot_after.png +0 -0
- package/examples/pce/catch_game/shot_before.png +0 -0
- package/examples/pce/main.c +37 -0
- package/examples/pce/music_sfx/README.md +8 -0
- package/examples/pce/music_sfx/main.c +154 -0
- package/examples/pce/sprite_move/README.md +19 -0
- package/examples/pce/sprite_move/main.c +155 -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 +97 -0
- package/src/cheats/gamegenie.js +506 -0
- package/src/cheats/lookup.js +262 -0
- package/src/cheats/parse-cht.js +92 -0
- package/src/cli/smoke.js +283 -0
- package/src/cores/registry.js +99 -0
- package/src/cores/wasm/bluemsx_libretro.js +2 -0
- package/src/cores/wasm/bluemsx_libretro.wasm +0 -0
- package/src/cores/wasm/fceumm_libretro.js +2 -0
- package/src/cores/wasm/fceumm_libretro.wasm +0 -0
- package/src/cores/wasm/gambatte_libretro.js +2 -0
- package/src/cores/wasm/gambatte_libretro.wasm +0 -0
- package/src/cores/wasm/geargrafx_libretro.js +2 -0
- package/src/cores/wasm/geargrafx_libretro.wasm +0 -0
- package/src/cores/wasm/genesis_plus_gx_libretro.js +2 -0
- package/src/cores/wasm/genesis_plus_gx_libretro.wasm +0 -0
- package/src/cores/wasm/handy_libretro.js +2 -0
- package/src/cores/wasm/handy_libretro.wasm +0 -0
- package/src/cores/wasm/mgba_libretro.js +2 -0
- package/src/cores/wasm/mgba_libretro.wasm +0 -0
- package/src/cores/wasm/prosystem_libretro.js +2 -0
- package/src/cores/wasm/prosystem_libretro.wasm +0 -0
- package/src/cores/wasm/snes9x_libretro.js +2 -0
- package/src/cores/wasm/snes9x_libretro.wasm +0 -0
- package/src/cores/wasm/stella2014_libretro.js +2 -0
- package/src/cores/wasm/stella2014_libretro.wasm +0 -0
- package/src/cores/wasm/vice_x64_libretro.js +2 -0
- package/src/cores/wasm/vice_x64_libretro.wasm +0 -0
- package/src/host/LibretroHost.js +1469 -0
- package/src/host/c64-sid-state.js +161 -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 +543 -0
- package/src/host/dsp-state.js +188 -0
- package/src/host/framebuffer.js +115 -0
- package/src/host/gb-apu-state.js +321 -0
- package/src/host/gba-video-state.js +215 -0
- package/src/host/gpgx-state.js +320 -0
- package/src/host/index.js +4 -0
- package/src/host/lynx-mikey-state.js +226 -0
- package/src/host/msx-ay-state.js +78 -0
- package/src/host/nes-apu-state.js +194 -0
- package/src/host/pce-psg-state.js +82 -0
- package/src/host/retroConstants.js +72 -0
- package/src/host/snes9x-state.js +35 -0
- package/src/host/types.js +332 -0
- package/src/http/routes.js +182 -0
- package/src/http/skill-doc.js +176 -0
- package/src/http/swagger.js +84 -0
- package/src/http/tool-registry.js +142 -0
- package/src/install/postinstall.mjs +81 -0
- package/src/mcp/disclosure.js +250 -0
- package/src/mcp/log.js +87 -0
- package/src/mcp/server.js +498 -0
- package/src/mcp/state.js +88 -0
- package/src/mcp/tool-manifest.js +92 -0
- package/src/mcp/tools/address-to-symbol.js +145 -0
- package/src/mcp/tools/art-loaders.js +743 -0
- package/src/mcp/tools/assets.js +87 -0
- package/src/mcp/tools/audio.js +562 -0
- package/src/mcp/tools/cart-parts.js +651 -0
- package/src/mcp/tools/cheats.js +343 -0
- package/src/mcp/tools/classify-region.js +107 -0
- package/src/mcp/tools/diff-cluster.js +32 -0
- package/src/mcp/tools/diff-roms.js +394 -0
- package/src/mcp/tools/disasm.js +1410 -0
- package/src/mcp/tools/find-references.js +375 -0
- package/src/mcp/tools/font-map.js +563 -0
- package/src/mcp/tools/frame.js +293 -0
- package/src/mcp/tools/free-space.js +71 -0
- package/src/mcp/tools/index.js +339 -0
- package/src/mcp/tools/input-layout.js +231 -0
- package/src/mcp/tools/input.js +227 -0
- package/src/mcp/tools/lifecycle.js +132 -0
- package/src/mcp/tools/lospec.js +187 -0
- package/src/mcp/tools/memory.js +472 -0
- package/src/mcp/tools/metasprite-tools.js +256 -0
- package/src/mcp/tools/platform-docs.js +113 -0
- package/src/mcp/tools/platform-tools.js +1300 -0
- package/src/mcp/tools/platforms.js +139 -0
- package/src/mcp/tools/playtest.js +360 -0
- package/src/mcp/tools/preview-tile.js +478 -0
- package/src/mcp/tools/project.js +1939 -0
- package/src/mcp/tools/record.js +180 -0
- package/src/mcp/tools/reinject.js +732 -0
- package/src/mcp/tools/rendering-context.js +838 -0
- package/src/mcp/tools/rom-id.js +308 -0
- package/src/mcp/tools/run-until.js +176 -0
- package/src/mcp/tools/snippets.js +209 -0
- package/src/mcp/tools/splice-chr.js +190 -0
- package/src/mcp/tools/sprite-pipeline.js +626 -0
- package/src/mcp/tools/state.js +198 -0
- package/src/mcp/tools/symbols.js +400 -0
- package/src/mcp/tools/tile-inspect.js +293 -0
- package/src/mcp/tools/toolchain.js +720 -0
- package/src/mcp/tools/trace-vram-source.js +81 -0
- package/src/mcp/tools/watch-memory.js +1036 -0
- package/src/mcp/tools/which-tiles.js +180 -0
- package/src/mcp/util.js +355 -0
- package/src/observer/bus.js +127 -0
- package/src/observer/livestream.html +594 -0
- package/src/observer/server.js +78 -0
- package/src/observer/tool-wrap.js +142 -0
- package/src/platforms/_guides/MUSIC_SOURCING.md +104 -0
- package/src/platforms/_guides/ROMHACKING_PLAYBOOK.md +245 -0
- package/src/platforms/atari2600/MENTAL_MODEL.md +194 -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 +324 -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/atari7800/song.js +232 -0
- package/src/platforms/c64/MENTAL_MODEL.md +188 -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/song.js +262 -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 +418 -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 +262 -0
- package/src/platforms/gb/TROUBLESHOOTING.md +218 -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 +122 -0
- package/src/platforms/gb/lib/c/SDCC_GOTCHAS.md +190 -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/gb/song.js +140 -0
- package/src/platforms/gba/MENTAL_MODEL.md +216 -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 +178 -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 +122 -0
- package/src/platforms/gbc/lib/c/SDCC_GOTCHAS.md +190 -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/gbc/song.js +3 -0
- package/src/platforms/genesis/MENTAL_MODEL.md +306 -0
- package/src/platforms/genesis/TROUBLESHOOTING.md +226 -0
- package/src/platforms/genesis/UPSTREAM_SOURCES.md +53 -0
- package/src/platforms/genesis/image-to-tilemap.js +351 -0
- package/src/platforms/genesis/lib/README.md +160 -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 +548 -0
- package/src/platforms/genesis/xgm2-pcm.js +165 -0
- package/src/platforms/gg/MENTAL_MODEL.md +174 -0
- package/src/platforms/gg/TROUBLESHOOTING.md +105 -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/gg/song.js +189 -0
- package/src/platforms/index.js +7 -0
- package/src/platforms/lynx/MENTAL_MODEL.md +248 -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/lynx/song.js +291 -0
- package/src/platforms/msx/MENTAL_MODEL.md +115 -0
- package/src/platforms/msx/TROUBLESHOOTING.md +62 -0
- package/src/platforms/msx/UPSTREAM_SOURCES.md +46 -0
- package/src/platforms/msx/image-to-tilemap.js +103 -0
- package/src/platforms/msx/lib/c/hello_msx.c +51 -0
- package/src/platforms/msx/lib/c/msx_crt0.s +74 -0
- package/src/platforms/msx/lib/c/msx_hw.h +92 -0
- package/src/platforms/msx/lib/c/msx_vdp.c +150 -0
- package/src/platforms/msx/tiles.js +99 -0
- package/src/platforms/msx/vdp.js +160 -0
- package/src/platforms/nes/MENTAL_MODEL.md +323 -0
- package/src/platforms/nes/TROUBLESHOOTING.md +319 -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 +448 -0
- package/src/platforms/pce/MENTAL_MODEL.md +98 -0
- package/src/platforms/pce/TROUBLESHOOTING.md +54 -0
- package/src/platforms/pce/UPSTREAM_SOURCES.md +38 -0
- package/src/platforms/pce/image-to-tilemap.js +123 -0
- package/src/platforms/pce/lib/c/hello_pce.c +37 -0
- package/src/platforms/pce/lib/c/pce_hw.h +130 -0
- package/src/platforms/pce/lib/c/pce_input.c +36 -0
- package/src/platforms/pce/lib/c/pce_sound.c +53 -0
- package/src/platforms/pce/lib/c/pce_video.c +113 -0
- package/src/platforms/pce/tiles.js +92 -0
- package/src/platforms/pce/vce.js +59 -0
- package/src/platforms/pce/vdc.js +52 -0
- package/src/platforms/sms/MENTAL_MODEL.md +286 -0
- package/src/platforms/sms/TROUBLESHOOTING.md +140 -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/song.js +217 -0
- package/src/platforms/sms/vdp.js +530 -0
- package/src/platforms/snes/MENTAL_MODEL.md +289 -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/platforms/snes/song.js +128 -0
- package/src/playtest/playtest.js +841 -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 +216 -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/reassemble.js +353 -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 +838 -0
- package/src/toolchains/genesis-c/README.md +61 -0
- package/src/toolchains/genesis-c/genesis-c.js +600 -0
- package/src/toolchains/gnu-ld-map.js +86 -0
- package/src/toolchains/index.js +862 -0
- package/src/toolchains/m68k-elf-gcc/gcc.js +230 -0
- package/src/toolchains/objdump.js +199 -0
- package/src/toolchains/parse-errors.js +338 -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 +540 -0
- package/src/toolchains/sjasm/sjasm.js +85 -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/z80/binutils.js +82 -0
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
// Playtest — open an SDL window, render the loaded ROM at native framerate,
|
|
2
|
+
// drive it with whatever gamepad is plugged in. Uses the same SDL API
|
|
3
|
+
// pattern as the working retroemu player.
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
RETRO_PIXEL_FORMAT_0RGB1555,
|
|
7
|
+
RETRO_PIXEL_FORMAT_RGB565,
|
|
8
|
+
RETRO_PIXEL_FORMAT_XRGB8888,
|
|
9
|
+
} from "../host/retroConstants.js";
|
|
10
|
+
import { log } from "../mcp/log.js";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { execFile } from "node:child_process";
|
|
14
|
+
import { promisify } from "node:util";
|
|
15
|
+
import { createRequire } from "node:module";
|
|
16
|
+
|
|
17
|
+
const execFileAsync = promisify(execFile);
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// One-pixel solid-black RGBA buffer; we stretch it across the letterbox
|
|
21
|
+
// bars each frame so they don't smear with leftover pixels.
|
|
22
|
+
const BLACK_PIXEL = Buffer.from([0, 0, 0, 0xFF]);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Choose a default window title from the loaded host. Prefers the loaded
|
|
26
|
+
* ROM/project basename (e.g. "asteroids.sfc" → "asteroids"); for in-memory
|
|
27
|
+
* builds (runSource) the path is a synthetic "<memory.sfc>" with no project
|
|
28
|
+
* name, so fall back to the platform, then the generic label.
|
|
29
|
+
* @param {import("../host/index.js").LibretroHost} host
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
32
|
+
export function deriveTitle(host) {
|
|
33
|
+
const mediaPath = host?.status?.mediaPath ?? "";
|
|
34
|
+
const platform = host?.status?.platform ?? null;
|
|
35
|
+
// Synthetic in-memory paths look like "<memory.sfc>" or "/rom.sfc" — no
|
|
36
|
+
// real project name. Treat those as nameless and fall back.
|
|
37
|
+
const real = mediaPath && !/^<memory|^\/rom\b|^\/rom\./.test(mediaPath);
|
|
38
|
+
if (real) {
|
|
39
|
+
const base = path.basename(mediaPath).replace(/\.[^.]+$/, "");
|
|
40
|
+
if (base) return platform ? `${base} (${platform})` : base;
|
|
41
|
+
}
|
|
42
|
+
return platform ? `romdev — ${platform}` : "romdev playtest";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Find the on-disk root directory of the @kmamal/sdl package. Its `exports`
|
|
47
|
+
* field doesn't expose `./package.json`, so we resolve the main entry and walk
|
|
48
|
+
* up to the nearest directory containing a package.json. Exported for tests.
|
|
49
|
+
* @returns {string | null}
|
|
50
|
+
*/
|
|
51
|
+
export function sdlPackageRoot() {
|
|
52
|
+
let entry;
|
|
53
|
+
try {
|
|
54
|
+
entry = require.resolve("@kmamal/sdl");
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
let dir = path.dirname(entry);
|
|
59
|
+
while (dir !== path.dirname(dir)) {
|
|
60
|
+
if (existsSync(path.join(dir, "package.json"))) return dir;
|
|
61
|
+
dir = path.dirname(dir);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @kmamal/sdl ships its native binary (`dist/sdl.node`) via an `install`
|
|
68
|
+
* lifecycle script — NOT in the npm tarball. When romdev is started with
|
|
69
|
+
* `npx romdev-mcp`, npm's transitive install path skips that script, so the
|
|
70
|
+
* binary is never fetched and `require('../../dist/sdl.node')` throws
|
|
71
|
+
* ERR_MODULE_NOT_FOUND. Worse, Node's ESM loader CACHES a failed dynamic import
|
|
72
|
+
* for the process lifetime — so once the first `import("@kmamal/sdl")` rejects,
|
|
73
|
+
* it can never recover, even after the binary appears on disk.
|
|
74
|
+
*
|
|
75
|
+
* So we must verify (and repair) the binary BEFORE the first import. This
|
|
76
|
+
* locates @kmamal/sdl, checks for dist/sdl.node, and if missing runs its own
|
|
77
|
+
* scripts/install.mjs to download the prebuilt binary, then imports once.
|
|
78
|
+
*
|
|
79
|
+
* On failure throws an Error tagged with `.sdlKind` ("missing-binary" |
|
|
80
|
+
* "install-failed" | "sdl-error") and, when actionable, `.fixCmd` — the tool
|
|
81
|
+
* layer branches on these for an accurate message (vs the old one that always
|
|
82
|
+
* blamed the desktop session).
|
|
83
|
+
* @returns {Promise<any>} the SDL module
|
|
84
|
+
*/
|
|
85
|
+
let _sdlModule = null;
|
|
86
|
+
async function getSdl() {
|
|
87
|
+
if (_sdlModule) return _sdlModule;
|
|
88
|
+
|
|
89
|
+
// Resolve the package root (works under npx, local install, or a monorepo
|
|
90
|
+
// symlink). Note: @kmamal/sdl's `exports` does NOT expose ./package.json, so
|
|
91
|
+
// resolve the main entry and walk up to the dir that contains package.json.
|
|
92
|
+
let sdlNode = null;
|
|
93
|
+
let installScript = null;
|
|
94
|
+
try {
|
|
95
|
+
const pkgDir = sdlPackageRoot();
|
|
96
|
+
if (pkgDir) {
|
|
97
|
+
sdlNode = path.join(pkgDir, "dist", "sdl.node");
|
|
98
|
+
installScript = path.join(pkgDir, "scripts", "install.mjs");
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
// @kmamal/sdl itself isn't installed at all — nothing we can repair.
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const tag = (err, kind, fixCmd) => {
|
|
105
|
+
err.sdlKind = kind;
|
|
106
|
+
if (fixCmd) err.fixCmd = fixCmd;
|
|
107
|
+
return err;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Self-heal: if the prebuilt binary is missing but the install script is
|
|
111
|
+
// present, run it (exactly what the skipped postinstall would have done).
|
|
112
|
+
// This MUST happen before the first import — Node's ESM loader caches a
|
|
113
|
+
// rejected dynamic import for the process lifetime, so a failed first import
|
|
114
|
+
// could never recover even after the binary lands on disk.
|
|
115
|
+
if (sdlNode && !existsSync(sdlNode) && installScript && existsSync(installScript)) {
|
|
116
|
+
log("playtest: @kmamal/sdl native binary missing — fetching prebuilt via its install script…");
|
|
117
|
+
try {
|
|
118
|
+
await execFileAsync(process.execPath, [installScript], {
|
|
119
|
+
timeout: 120000,
|
|
120
|
+
// Prebuilt-only — never fall through to a node-gyp/clang source build.
|
|
121
|
+
env: { ...process.env, npm_config_build_from_source: "false", npm_config_build_from_source_all: "false" },
|
|
122
|
+
});
|
|
123
|
+
} catch (e) {
|
|
124
|
+
throw tag(new Error(
|
|
125
|
+
`the @kmamal/sdl native binary isn't installed and the auto-install failed: ${e?.message ?? e}`,
|
|
126
|
+
), "install-failed", `node "${installScript}"`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Still missing after the heal attempt → fail with the exact fix, BEFORE the
|
|
131
|
+
// import (so we never cache a rejection).
|
|
132
|
+
if (sdlNode && !existsSync(sdlNode)) {
|
|
133
|
+
throw tag(new Error(
|
|
134
|
+
`the @kmamal/sdl native binary isn't installed (expected at ${sdlNode})`,
|
|
135
|
+
), "missing-binary", installScript ? `node "${installScript}"` : undefined);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Force nearest-neighbor scaling globally. SDL2 reads this env var at init;
|
|
139
|
+
// we already pass scaling:"nearest" per render, but this is belt-and-
|
|
140
|
+
// suspenders so a pixel-art ROM is NEVER blurred by bilinear filtering on any
|
|
141
|
+
// path. 0 = nearest, 1 = linear, 2 = best. MUST be set before SDL inits, i.e.
|
|
142
|
+
// before the import below.
|
|
143
|
+
if (!process.env.SDL_RENDER_SCALE_QUALITY) {
|
|
144
|
+
process.env.SDL_RENDER_SCALE_QUALITY = "0";
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Binary present (or path unresolvable — let import surface the real error).
|
|
148
|
+
try {
|
|
149
|
+
const ns = await import("@kmamal/sdl");
|
|
150
|
+
_sdlModule = ns.default || ns;
|
|
151
|
+
return _sdlModule;
|
|
152
|
+
} catch (e) {
|
|
153
|
+
const isModuleErr = e?.code === "ERR_MODULE_NOT_FOUND" ||
|
|
154
|
+
/sdl\.node|dist[\\/]/.test(e?.message || "");
|
|
155
|
+
throw tag(new Error(e?.message ?? String(e)),
|
|
156
|
+
isModuleErr ? "missing-binary" : "sdl-error",
|
|
157
|
+
isModuleErr && installScript ? `node "${installScript}"` : undefined);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Map SDL standard-controller button name → libretro JOYPAD bit.
|
|
162
|
+
// SDL names follow Xbox letter positions: A=bottom, B=right, X=left, Y=top.
|
|
163
|
+
// libretro RETRO_DEVICE_ID_JOYPAD also names by letter: B=0 (bottom-physical
|
|
164
|
+
// on a SNES/NES pad), A=8 (right), Y=1 (left), X=9 (top), SELECT=2, START=3,
|
|
165
|
+
// L=10, R=11, L2=12, R2=13, L3=14, R3=15.
|
|
166
|
+
//
|
|
167
|
+
// Both schemes share the "letter = physical position" convention, but Xbox
|
|
168
|
+
// swaps A/B vs SNES. We map by physical position so the bottom button is
|
|
169
|
+
// always "main action" (NES A / SNES B) and the right is "secondary"
|
|
170
|
+
// (NES B / SNES A) regardless of pad letters. That matches retroarch's
|
|
171
|
+
// default user mapping for an Xbox controller on a NES/SNES core.
|
|
172
|
+
const SDL_BUTTON_TO_LIBRETRO_BIT = {
|
|
173
|
+
dpadUp: 4,
|
|
174
|
+
dpadDown: 5,
|
|
175
|
+
dpadLeft: 6,
|
|
176
|
+
dpadRight: 7,
|
|
177
|
+
a: 0, // SDL bottom (Xbox A) → libretro B (NES A / SNES B) = main action
|
|
178
|
+
b: 8, // SDL right (Xbox B) → libretro A (NES B / SNES A) = secondary
|
|
179
|
+
x: 1, // SDL left (Xbox X) → libretro Y (SNES Y / unused on NES)
|
|
180
|
+
y: 9, // SDL top (Xbox Y) → libretro X (SNES X / unused on NES)
|
|
181
|
+
back: 2, // SELECT
|
|
182
|
+
guide: 2,
|
|
183
|
+
start: 3,
|
|
184
|
+
leftShoulder: 10,
|
|
185
|
+
rightShoulder: 11,
|
|
186
|
+
leftStick: 14,
|
|
187
|
+
rightStick: 15,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Analog stick → dpad direction (for games that only read dpad)
|
|
191
|
+
const STICK_DEADZONE = 8000;
|
|
192
|
+
|
|
193
|
+
// Keyboard fallback for users without a gamepad. Same physical-position
|
|
194
|
+
// convention as the controller map: Z = bottom (NES A / SNES B), X = right
|
|
195
|
+
// (NES B / SNES A), A = left (SNES Y), S = top (SNES X). Arrows for D-pad.
|
|
196
|
+
// Enter = Start, RShift = Select, Q/W = L/R shoulders. ESC closes the window.
|
|
197
|
+
//
|
|
198
|
+
// Key strings come straight from node-sdl keyDown/keyUp events.
|
|
199
|
+
const KEY_TO_LIBRETRO_BIT = {
|
|
200
|
+
up: 4, down: 5, left: 6, right: 7,
|
|
201
|
+
z: 0, // bottom face = B (NES A, SNES B) = main action
|
|
202
|
+
x: 8, // right face = A (NES B, SNES A)
|
|
203
|
+
a: 1, // left face = Y (SNES)
|
|
204
|
+
s: 9, // top face = X (SNES)
|
|
205
|
+
return: 3, // Enter = START
|
|
206
|
+
rshift: 2, // RShift = SELECT
|
|
207
|
+
backspace: 2, // also SELECT (laptop friendly)
|
|
208
|
+
q: 10, // L shoulder
|
|
209
|
+
w: 11, // R shoulder
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// Human-readable summary printed by --help and at playtest startup.
|
|
213
|
+
export const KEYBOARD_BINDINGS_HELP = `Keyboard:
|
|
214
|
+
Arrow keys D-pad
|
|
215
|
+
Z A / B (bottom face — main action; NES A, SNES B)
|
|
216
|
+
X B / A (right face)
|
|
217
|
+
A Y (SNES left face)
|
|
218
|
+
S X (SNES top face)
|
|
219
|
+
Q / W L / R shoulders
|
|
220
|
+
Enter START
|
|
221
|
+
RShift / Backspace SELECT
|
|
222
|
+
ESC Close playtest window
|
|
223
|
+
|
|
224
|
+
Emulator hotkeys (RetroArch defaults):
|
|
225
|
+
P / Space Pause / unpause emulation
|
|
226
|
+
K Frame advance (step one frame while paused)
|
|
227
|
+
R (hold) Rewind (up to 10 seconds)
|
|
228
|
+
F2 Save state (to slot)
|
|
229
|
+
F4 Load state (from slot)
|
|
230
|
+
|
|
231
|
+
Gamepad: any SDL-recognized controller works. Physical-position mapping —
|
|
232
|
+
the BOTTOM face button is always the main action, regardless of pad letter.
|
|
233
|
+
Select + Start (held together) Close playtest window`;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* "TV" aspect ratio per platform. For consoles displayed on CRT
|
|
237
|
+
* televisions, this is 4:3 — the actual physical screen shape, not
|
|
238
|
+
* the framebuffer geometry. (Genesis H40 ships a 320×224 framebuffer
|
|
239
|
+
* with displayAspect ≈ 10:7, but every actual Sega Mega Drive was
|
|
240
|
+
* plugged into a 4:3 TV that stretched it horizontally.) Handheld
|
|
241
|
+
* LCDs are their own aspect — GB is 10:9, GBA is 3:2.
|
|
242
|
+
*
|
|
243
|
+
* Fallback when platform unknown: use the core's reported displayAspect.
|
|
244
|
+
*
|
|
245
|
+
* @param {string | null} platform
|
|
246
|
+
* @param {number} displayAspect core-reported, used as fallback
|
|
247
|
+
*/
|
|
248
|
+
/**
|
|
249
|
+
* Largest rect of `targetAspect` that fits inside a winW×winH window, centered
|
|
250
|
+
* (letterbox/pillarbox). Pure + exported so the aspect-on-resize behavior is
|
|
251
|
+
* unit-testable without a display. The image is ALWAYS drawn at this rect, so
|
|
252
|
+
* resizing the window never stretches it off-aspect — it just grows the bars.
|
|
253
|
+
* @param {number} winW window backing-store width (px)
|
|
254
|
+
* @param {number} winH window backing-store height (px)
|
|
255
|
+
* @param {number} targetAspect desired width/height ratio
|
|
256
|
+
* @returns {{dstX:number, dstY:number, dstW:number, dstH:number}}
|
|
257
|
+
*/
|
|
258
|
+
export function letterbox(winW, winH, targetAspect) {
|
|
259
|
+
const winAspect = winW / winH;
|
|
260
|
+
let dstW, dstH;
|
|
261
|
+
if (winAspect > targetAspect) {
|
|
262
|
+
// Window wider than target → full height, pillarbox left/right.
|
|
263
|
+
dstH = winH;
|
|
264
|
+
dstW = Math.round(winH * targetAspect);
|
|
265
|
+
} else {
|
|
266
|
+
// Window taller than target → full width, letterbox top/bottom.
|
|
267
|
+
dstW = winW;
|
|
268
|
+
dstH = Math.round(winW / targetAspect);
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
dstX: Math.round((winW - dstW) / 2),
|
|
272
|
+
dstY: Math.round((winH - dstH) / 2),
|
|
273
|
+
dstW,
|
|
274
|
+
dstH,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function tvAspectFor(platform, displayAspect) {
|
|
279
|
+
switch (platform) {
|
|
280
|
+
case "nes":
|
|
281
|
+
case "snes":
|
|
282
|
+
case "genesis":
|
|
283
|
+
case "atari2600":
|
|
284
|
+
case "atari7800":
|
|
285
|
+
case "c64":
|
|
286
|
+
case "sms":
|
|
287
|
+
return 4 / 3;
|
|
288
|
+
case "gg": return 1.20; // Game Gear LCD 160×144 → ~10:9 but stretched
|
|
289
|
+
case "gb":
|
|
290
|
+
case "gbc": return 10 / 9; // GB LCD 160×144 native
|
|
291
|
+
case "gba": return 3 / 2; // GBA LCD 240×160 native
|
|
292
|
+
case "lynx": return 102 / 81; // Lynx LCD pixel aspect (4:3 displayed)
|
|
293
|
+
default: return displayAspect;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* @param {Object} args
|
|
299
|
+
* @param {import("../host/index.js").LibretroHost} args.host
|
|
300
|
+
* @param {number} [args.scale]
|
|
301
|
+
* @param {string} [args.title]
|
|
302
|
+
* @param {"fb" | "tv" | "core"} [args.aspect] "fb" (default) = raw
|
|
303
|
+
* framebuffer aspect; pixels are square in the window. "tv" = the
|
|
304
|
+
* physical CRT/LCD shape the platform was designed for — 4:3 for
|
|
305
|
+
* every console that hooked to a TV, native LCD aspect for
|
|
306
|
+
* handhelds. This is what you want for "looks like the real hardware
|
|
307
|
+
* on its actual display." "core" = honor the core's reported
|
|
308
|
+
* display_aspect_ratio, which is the framebuffer's geometric ratio
|
|
309
|
+
* (often non-4:3 — Genesis H40 reports ~10:7). Use "core" when you
|
|
310
|
+
* need pixel-accurate framebuffer dimensions; use "tv" when you
|
|
311
|
+
* want the user-visible shape that matches the real hardware.
|
|
312
|
+
*/
|
|
313
|
+
export async function playtest(args) {
|
|
314
|
+
const openHost = args.host;
|
|
315
|
+
if (!openHost) throw new Error("playtest requires a loaded host");
|
|
316
|
+
// Resolve the session's CURRENT host each frame so the window FOLLOWS a
|
|
317
|
+
// rebuild. `runSource`/`loadMedia` call resetHost(), which replaces the host
|
|
318
|
+
// object AND unloads the old one's media — a window pinned to the open-time
|
|
319
|
+
// host would then throw "no media loaded" mid-tick and die. Following the
|
|
320
|
+
// live host means the window shows the agent's latest build in place (the
|
|
321
|
+
// documented "runSource updates the live game" UX) and never crashes on
|
|
322
|
+
// rebuild. Falls back to the open-time host if the accessor is absent.
|
|
323
|
+
const getLiveHost = typeof args.getLiveHost === "function" ? args.getLiveHost : () => openHost;
|
|
324
|
+
const scale = args.scale ?? 3;
|
|
325
|
+
// Default the window title to the loaded ROM/project name so the human can
|
|
326
|
+
// tell which game they're looking at (instead of a generic "romdev
|
|
327
|
+
// playtest"). buildProject loads with a virtualName of the project dir, and
|
|
328
|
+
// file loads carry their own path — derive the basename from either. Falls
|
|
329
|
+
// back to the platform name, then the generic label. An explicit `title`
|
|
330
|
+
// arg always wins.
|
|
331
|
+
const title = args.title ?? deriveTitle(openHost);
|
|
332
|
+
// Default to "tv" — the 4:3 / native-LCD shape the game was authored for, so
|
|
333
|
+
// the window looks like the real hardware (matches retroemu, which honors the
|
|
334
|
+
// core's display aspect / 4:3 fallback). "fb" (raw square pixels) makes most
|
|
335
|
+
// consoles look squished — NES 256×240 renders ~8% too narrow, Genesis H32
|
|
336
|
+
// too tall, etc. Agents who want exact dev-time pixel geometry pass aspect:"fb".
|
|
337
|
+
const aspectMode = args.aspect ?? "tv";
|
|
338
|
+
|
|
339
|
+
const sdl = await getSdl();
|
|
340
|
+
|
|
341
|
+
// Window sizing + audio rate are fixed at open from the open-time host.
|
|
342
|
+
const host = openHost;
|
|
343
|
+
host.stepFrames(1);
|
|
344
|
+
const first = host.getFramebuffer();
|
|
345
|
+
const fbWidth = first.width;
|
|
346
|
+
const fbHeight = first.height;
|
|
347
|
+
|
|
348
|
+
// Decide initial window size. In "tv" / "core" modes, scale by height
|
|
349
|
+
// and let the chosen aspect dictate width — keeps vertical resolution
|
|
350
|
+
// honest (you can still count scanlines) while applying horizontal
|
|
351
|
+
// stretch.
|
|
352
|
+
let winInitW = fbWidth * scale;
|
|
353
|
+
let winInitH = fbHeight * scale;
|
|
354
|
+
if (aspectMode === "tv" || aspectMode === "core") {
|
|
355
|
+
const aspect = aspectMode === "tv"
|
|
356
|
+
? tvAspectFor(host.status.platform, host.status.displayAspect ?? fbWidth / fbHeight)
|
|
357
|
+
: (host.status.displayAspect ?? fbWidth / fbHeight);
|
|
358
|
+
winInitH = fbHeight * scale;
|
|
359
|
+
winInitW = Math.round(winInitH * aspect);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Open the window.
|
|
363
|
+
const window = sdl.video.createWindow({
|
|
364
|
+
title,
|
|
365
|
+
width: winInitW,
|
|
366
|
+
height: winInitH,
|
|
367
|
+
resizable: true,
|
|
368
|
+
accelerated: true,
|
|
369
|
+
vsync: false,
|
|
370
|
+
});
|
|
371
|
+
log.debug(`[playtest] window opened: ${winInitW}x${winInitH}, fb=${fbWidth}x${fbHeight}, aspect=${aspectMode}`);
|
|
372
|
+
|
|
373
|
+
// Open audio at the core's NATIVE sample rate, not a hardcoded one.
|
|
374
|
+
// snes9x emits at ~32040 Hz, fceumm at 48000, genesis-plus-gx at 44100.
|
|
375
|
+
// Mismatched rates produce choppy/sped-up/cracking playback because the
|
|
376
|
+
// SDL device consumes samples at the wrong rate, alternately starving
|
|
377
|
+
// (clicks) and overflowing.
|
|
378
|
+
let audio = null;
|
|
379
|
+
const coreSampleRate = Math.round(host.status.audioSampleRate ?? 48000);
|
|
380
|
+
try {
|
|
381
|
+
audio = sdl.audio.openDevice({ type: "playback" }, {
|
|
382
|
+
channels: 2,
|
|
383
|
+
frequency: coreSampleRate,
|
|
384
|
+
format: "s16",
|
|
385
|
+
});
|
|
386
|
+
audio.play();
|
|
387
|
+
log.debug(`[playtest] audio: ${coreSampleRate} Hz, stereo, s16`);
|
|
388
|
+
} catch (e) {
|
|
389
|
+
log.error("[playtest] audio init failed (continuing silent):", e.message);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Two-slot controller state with SDL hot-plug. Slot 0 = player 1,
|
|
393
|
+
// slot 1 = player 2. The first controller plugged in stays player 1
|
|
394
|
+
// even if it's unplugged and replugged later (we re-fill the lowest
|
|
395
|
+
// empty slot on add). A second controller plugged in mid-session lands
|
|
396
|
+
// in slot 1 without restarting the window — this matters for events
|
|
397
|
+
// where players come and go (Token Burn hackathon, friend wandering
|
|
398
|
+
// over to play a finished build, etc.).
|
|
399
|
+
/** @type {[any|null, any|null]} */
|
|
400
|
+
const controllers = [null, null];
|
|
401
|
+
|
|
402
|
+
function openInFreeSlot(device) {
|
|
403
|
+
// If this device is already in a slot (re-add after deviceRemove),
|
|
404
|
+
// don't open twice.
|
|
405
|
+
for (const slot of controllers) {
|
|
406
|
+
if (slot && slot._device === device) return;
|
|
407
|
+
}
|
|
408
|
+
// Find lowest empty slot.
|
|
409
|
+
const idx = controllers.findIndex((c) => c == null);
|
|
410
|
+
if (idx < 0) {
|
|
411
|
+
log.debug(`[playtest] controller plugged in but both slots full — ignoring: ${device.name}`);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
try {
|
|
415
|
+
const inst = sdl.controller.openDevice(device);
|
|
416
|
+
inst._device = device; // tag for deviceRemove matching
|
|
417
|
+
controllers[idx] = inst;
|
|
418
|
+
log.debug(`[playtest] controller slot ${idx + 1}: ${device.name}`);
|
|
419
|
+
} catch (e) {
|
|
420
|
+
log.error(`[playtest] controller open failed (slot ${idx + 1}):`, e.message);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function closeBySlotMatching(device) {
|
|
425
|
+
for (let i = 0; i < controllers.length; i++) {
|
|
426
|
+
const inst = controllers[i];
|
|
427
|
+
if (inst && inst._device === device) {
|
|
428
|
+
// SDL auto-closes the instance per its docs; just drop the ref.
|
|
429
|
+
controllers[i] = null;
|
|
430
|
+
log.debug(`[playtest] controller slot ${i + 1} disconnected: ${device.name}`);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Pre-open already-plugged controllers (up to slot 1).
|
|
437
|
+
if (sdl.controller.devices.length === 0) {
|
|
438
|
+
log.debug("[playtest] no controller detected (keyboard fallback active)");
|
|
439
|
+
} else {
|
|
440
|
+
for (const dev of sdl.controller.devices) {
|
|
441
|
+
openInFreeSlot(dev);
|
|
442
|
+
if (controllers.every((c) => c)) break;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Hot-plug: SDL emits 'deviceAdd' / 'deviceRemove' on sdl.controller.
|
|
447
|
+
// Subscribe so a controller plugged in (or yanked) mid-session updates
|
|
448
|
+
// our slot map. Important for hackathons + social play sessions where
|
|
449
|
+
// a second controller arrives long after playtest started.
|
|
450
|
+
const onDeviceAdd = (event) => openInFreeSlot(event.device);
|
|
451
|
+
const onDeviceRemove = (event) => closeBySlotMatching(event.device);
|
|
452
|
+
sdl.controller.on("deviceAdd", onDeviceAdd);
|
|
453
|
+
sdl.controller.on("deviceRemove", onDeviceRemove);
|
|
454
|
+
|
|
455
|
+
let running = true;
|
|
456
|
+
let frameCount = 0;
|
|
457
|
+
let closeResolver = null;
|
|
458
|
+
const closedPromise = new Promise((r) => { closeResolver = r; });
|
|
459
|
+
|
|
460
|
+
// Track pixel-size from resize events instead of polling window.width every
|
|
461
|
+
// tick — that's the retroemu pattern. window.pixelWidth/height is the real
|
|
462
|
+
// backing-store size (which is what dstRect cares about); on HiDPI it
|
|
463
|
+
// differs from window.width.
|
|
464
|
+
let winPixelW = window.pixelWidth;
|
|
465
|
+
let winPixelH = window.pixelHeight;
|
|
466
|
+
|
|
467
|
+
// Keyboard fallback state — tracked as a "currently pressed" set so we
|
|
468
|
+
// can OR it into the input mask each tick.
|
|
469
|
+
/** @type {Set<string>} */
|
|
470
|
+
const heldKeys = new Set();
|
|
471
|
+
|
|
472
|
+
// Rewind ring buffer — one serialized snapshot per frame, capped at 10 s.
|
|
473
|
+
const MAX_REWIND_FRAMES = 600;
|
|
474
|
+
/** @type {Uint8Array[]} */
|
|
475
|
+
const rewindBuffer = [];
|
|
476
|
+
|
|
477
|
+
window.on("close", () => { stop(); });
|
|
478
|
+
window.on("keyDown", (e) => {
|
|
479
|
+
if (e.key === "escape") { stop(); return; }
|
|
480
|
+
const key = e.key ? e.key.toLowerCase() : "";
|
|
481
|
+
// RetroArch-style emulator hotkeys — act on the live host, not game input.
|
|
482
|
+
if (key === "p" || key === "space") {
|
|
483
|
+
const h = getLiveHost();
|
|
484
|
+
if (h) { h.status.paused ? h.resume() : h.pause(); }
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (key === "f2") {
|
|
488
|
+
const h = getLiveHost();
|
|
489
|
+
if (h && h.status?.loaded) { try { h.saveState("hotkey"); } catch {} }
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
if (key === "f4") {
|
|
493
|
+
const h = getLiveHost();
|
|
494
|
+
if (h && h.status?.loaded) { try { h.loadState("hotkey"); } catch (err) {
|
|
495
|
+
log.debug("[playtest] load state failed (no save yet?):", err.message);
|
|
496
|
+
} }
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (key === "k") {
|
|
500
|
+
const h = getLiveHost();
|
|
501
|
+
if (h && h.status?.loaded && h.status.paused) {
|
|
502
|
+
h.resume();
|
|
503
|
+
h.stepFrames(1);
|
|
504
|
+
h.pause();
|
|
505
|
+
}
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (key) heldKeys.add(key);
|
|
509
|
+
});
|
|
510
|
+
window.on("keyUp", (e) => {
|
|
511
|
+
if (e.key) heldKeys.delete(e.key.toLowerCase());
|
|
512
|
+
});
|
|
513
|
+
window.on("resize", (e) => {
|
|
514
|
+
winPixelW = e.pixelWidth ?? window.pixelWidth;
|
|
515
|
+
winPixelH = e.pixelHeight ?? window.pixelHeight;
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
function stop() {
|
|
519
|
+
if (!running) return;
|
|
520
|
+
running = false;
|
|
521
|
+
if (interval) clearInterval(interval);
|
|
522
|
+
try { sdl.controller.off("deviceAdd", onDeviceAdd); } catch {}
|
|
523
|
+
try { sdl.controller.off("deviceRemove", onDeviceRemove); } catch {}
|
|
524
|
+
try { audio?.close(); } catch {}
|
|
525
|
+
try { if (!window.destroyed) window.destroy(); } catch {}
|
|
526
|
+
log.debug(`[playtest] closed after ${frameCount} frames`);
|
|
527
|
+
if (closeResolver) closeResolver();
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Tick = one emulated frame + render + audio drain. Driven by setInterval
|
|
531
|
+
// so the Node event loop stays free for MCP requests on the same host.
|
|
532
|
+
const frameMs = 1000 / 60;
|
|
533
|
+
|
|
534
|
+
function tick() {
|
|
535
|
+
if (!running || window.destroyed) { stop(); return; }
|
|
536
|
+
// Resolve the session's CURRENT host this frame. A `runSource`/`loadMedia`
|
|
537
|
+
// rebuild swapped it; we follow it so the window shows the latest build.
|
|
538
|
+
// If there's transiently no host or no media loaded (mid-swap), skip this
|
|
539
|
+
// frame — DON'T stop the window (that was the crash: the old host got its
|
|
540
|
+
// media unloaded and stepFrames threw).
|
|
541
|
+
const h = getLiveHost();
|
|
542
|
+
if (!h || !h.status?.loaded) return;
|
|
543
|
+
// While paused the window keeps RENDERING the frozen frame (so the human
|
|
544
|
+
// still sees it), but must NOT touch input or step the core: otherwise the
|
|
545
|
+
// per-tick setInput would clobber any input the AGENT set for an
|
|
546
|
+
// inspect-while-paused experiment. stepFrames already returns 0 when
|
|
547
|
+
// paused; skipping setInput too is what makes `pause` mean "stop fighting
|
|
548
|
+
// me". The render block below runs unconditionally.
|
|
549
|
+
// `paused` (the agent's pause) OR `_renderTickSuspended` (a breakpoint/watch
|
|
550
|
+
// tool is driving the core exclusively this instant) → render only, don't
|
|
551
|
+
// step. The latter prevents this 60fps tick from racing a runUntilPC loop and
|
|
552
|
+
// stepping the CPU past the breakpoint between its iterations.
|
|
553
|
+
const paused = !!h.status.paused || !!h._renderTickSuspended;
|
|
554
|
+
// Read controller state for each slot independently. Slot 0 = port 0
|
|
555
|
+
// (player 1), slot 1 = port 1 (player 2). Each slot's input is built
|
|
556
|
+
// into its own port object; the agent's setInput is overwritten each
|
|
557
|
+
// tick (matching prior behavior). Select+Start on any controller quits.
|
|
558
|
+
let quit = false;
|
|
559
|
+
function readControllerInto(port, inst) {
|
|
560
|
+
if (!inst) return;
|
|
561
|
+
const btn = inst.buttons || {};
|
|
562
|
+
if ((btn.back || btn.guide) && btn.start) {
|
|
563
|
+
quit = true;
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
for (const [sdlName, bit] of Object.entries(SDL_BUTTON_TO_LIBRETRO_BIT)) {
|
|
567
|
+
if (btn[sdlName]) port[bitToName(bit)] = true;
|
|
568
|
+
}
|
|
569
|
+
const axes = inst.axes || {};
|
|
570
|
+
const lx = axes.leftStickX ?? 0;
|
|
571
|
+
const ly = axes.leftStickY ?? 0;
|
|
572
|
+
if (lx > STICK_DEADZONE) port.right = true;
|
|
573
|
+
else if (lx < -STICK_DEADZONE) port.left = true;
|
|
574
|
+
if (ly > STICK_DEADZONE) port.down = true;
|
|
575
|
+
else if (ly < -STICK_DEADZONE) port.up = true;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const port0 = {};
|
|
579
|
+
const port1 = {};
|
|
580
|
+
readControllerInto(port0, controllers[0]);
|
|
581
|
+
readControllerInto(port1, controllers[1]);
|
|
582
|
+
if (quit) {
|
|
583
|
+
// Select+Start always closes — even while paused — so the human can
|
|
584
|
+
// dismiss a frozen window from the pad.
|
|
585
|
+
log.debug("[playtest] Select+Start pressed — closing");
|
|
586
|
+
stop();
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
// While paused: do NOTHING here — no input, no step, no rewind-capture.
|
|
590
|
+
// A paused window must truly freeze so it doesn't clobber input the AGENT
|
|
591
|
+
// set for an inspect-while-paused experiment (use the K hotkey to frame-
|
|
592
|
+
// advance, or release pause). The render block below still runs.
|
|
593
|
+
if (!paused) {
|
|
594
|
+
// Merge in keyboard state on port 0. ORed with controller state so a
|
|
595
|
+
// user can mix both (rare, but harmless). Keyboard never reaches
|
|
596
|
+
// port 1 — that's reserved for the second physical controller.
|
|
597
|
+
for (const [keyName, bit] of Object.entries(KEY_TO_LIBRETRO_BIT)) {
|
|
598
|
+
if (heldKeys.has(keyName)) port0[bitToName(bit)] = true;
|
|
599
|
+
}
|
|
600
|
+
const isRewinding = heldKeys.has("r") && rewindBuffer.length > 0;
|
|
601
|
+
if (isRewinding) {
|
|
602
|
+
// Restore the previous snapshot and run one frame to produce its visual.
|
|
603
|
+
const snap = rewindBuffer.pop();
|
|
604
|
+
try {
|
|
605
|
+
h.unserializeState(snap);
|
|
606
|
+
h.stepFrames(1);
|
|
607
|
+
frameCount++;
|
|
608
|
+
} catch (e) {
|
|
609
|
+
log.error("[playtest] rewind error:", e.message);
|
|
610
|
+
}
|
|
611
|
+
} else {
|
|
612
|
+
// Capture snapshot before stepping so it can be rewound to later.
|
|
613
|
+
if (h.status?.loaded) {
|
|
614
|
+
try {
|
|
615
|
+
const snap = h.serializeState();
|
|
616
|
+
rewindBuffer.push(snap);
|
|
617
|
+
if (rewindBuffer.length > MAX_REWIND_FRAMES) rewindBuffer.shift();
|
|
618
|
+
} catch {}
|
|
619
|
+
}
|
|
620
|
+
h.setInput({ ports: [port0, port1] });
|
|
621
|
+
let stepped = 0;
|
|
622
|
+
try {
|
|
623
|
+
stepped = h.stepFrames(1);
|
|
624
|
+
} catch (e) {
|
|
625
|
+
// A step error mid-swap (host being torn down/rebuilt) is transient —
|
|
626
|
+
// skip this frame and let the next tick pick up the new host. Don't kill
|
|
627
|
+
// the window. (A window-level failure is handled by the destroyed checks.)
|
|
628
|
+
log.error("[playtest] step error (skipping frame):", e.message);
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
if (stepped > 0) frameCount++;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
if (!window.destroyed) {
|
|
636
|
+
try {
|
|
637
|
+
const fb = h.getFramebuffer();
|
|
638
|
+
const rgba = framebufferToRgba(fb);
|
|
639
|
+
|
|
640
|
+
// Letterbox: compute the largest rect with the *target* aspect
|
|
641
|
+
// ratio that fits inside the (possibly-resized) window, centered.
|
|
642
|
+
// In "fb" mode the target is the raw framebuffer aspect; in "tv"
|
|
643
|
+
// mode it's the core-reported display aspect (so 160×210 Atari
|
|
644
|
+
// stays ~4:3 even after the user resizes).
|
|
645
|
+
// node-sdl's window.render with a dstRect handles bar regions for
|
|
646
|
+
// us — SDL clears the renderer each present, so we don't need to
|
|
647
|
+
// paint black bars ourselves. Matches retroemu's renderer pattern
|
|
648
|
+
// and avoids the multi-render flashing we hit before.
|
|
649
|
+
const fbW = fb.width;
|
|
650
|
+
const fbH = fb.height;
|
|
651
|
+
let targetAspect;
|
|
652
|
+
if (aspectMode === "tv") {
|
|
653
|
+
targetAspect = tvAspectFor(h.status.platform, h.status.displayAspect ?? fbW / fbH);
|
|
654
|
+
} else if (aspectMode === "core") {
|
|
655
|
+
targetAspect = h.status.displayAspect ?? fbW / fbH;
|
|
656
|
+
} else {
|
|
657
|
+
targetAspect = fbW / fbH;
|
|
658
|
+
}
|
|
659
|
+
// Read the window's CURRENT backing-store size fresh every frame rather
|
|
660
|
+
// than relying on the cached resize-event values. node-sdl can miss /
|
|
661
|
+
// mis-report a resize event (and during a live drag the cached value
|
|
662
|
+
// lags the actual window), which left the dstRect sized for the old
|
|
663
|
+
// window while SDL stretched the texture to fill the new one — i.e. the
|
|
664
|
+
// image stopped respecting the aspect ratio on resize. window.pixelWidth
|
|
665
|
+
// is always the true current backing size; fall back to the cached
|
|
666
|
+
// values only if the live read isn't available.
|
|
667
|
+
const curW = window.pixelWidth || winPixelW;
|
|
668
|
+
const curH = window.pixelHeight || winPixelH;
|
|
669
|
+
const { dstX, dstY, dstW, dstH } = letterbox(curW, curH, targetAspect);
|
|
670
|
+
|
|
671
|
+
window.render(fbW, fbH, fbW * 4, "rgba32", rgba, {
|
|
672
|
+
scaling: "nearest",
|
|
673
|
+
dstRect: { x: dstX, y: dstY, width: dstW, height: dstH },
|
|
674
|
+
});
|
|
675
|
+
} catch (e) {
|
|
676
|
+
// A render throw usually means the window went away under us (the
|
|
677
|
+
// SDL handle was freed without a 'close' event — compositor kill,
|
|
678
|
+
// session loss). If the window is no longer alive, stop the loop so
|
|
679
|
+
// we don't spin forever rendering into a corpse (the stale-status
|
|
680
|
+
// bug). Only a transient error on a still-live window is logged.
|
|
681
|
+
if (window.destroyed || e.message?.includes("destroyed")) { stop(); return; }
|
|
682
|
+
log.error("[playtest] render error:", e.message);
|
|
683
|
+
}
|
|
684
|
+
} else {
|
|
685
|
+
// Window vanished between the top-of-tick check and here.
|
|
686
|
+
stop();
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (running && audio && h.state.audioRing.length > 0) {
|
|
691
|
+
// SDL device tells us how many bytes are still queued (not yet played).
|
|
692
|
+
// If we get >200ms ahead, the player got a stutter and is now
|
|
693
|
+
// building latency — drop new samples until the queue drains back
|
|
694
|
+
// to ~50ms. This keeps audio synced to wall clock without underruns.
|
|
695
|
+
// Wrap the whole block in try/catch — stop() may have closed the
|
|
696
|
+
// audio device between the running check and the access below.
|
|
697
|
+
try {
|
|
698
|
+
const bytesPerSecond = coreSampleRate * 2 /* ch */ * 2 /* s16 */;
|
|
699
|
+
const queuedBytes = audio.queued ?? 0;
|
|
700
|
+
const queuedMs = (queuedBytes / bytesPerSecond) * 1000;
|
|
701
|
+
if (queuedMs < 200) {
|
|
702
|
+
let total = 0;
|
|
703
|
+
for (const buf of h.state.audioRing) total += buf.byteLength;
|
|
704
|
+
const merged = Buffer.alloc(total);
|
|
705
|
+
let off = 0;
|
|
706
|
+
for (const buf of h.state.audioRing) {
|
|
707
|
+
merged.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength), off);
|
|
708
|
+
off += buf.byteLength;
|
|
709
|
+
}
|
|
710
|
+
audio.enqueue(merged);
|
|
711
|
+
}
|
|
712
|
+
} catch (e) {
|
|
713
|
+
if (!e.message?.includes("closed")) {
|
|
714
|
+
log.error("[playtest] audio enqueue error:", e.message);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
// Always clear the ring — if we skipped enqueue we drop those samples.
|
|
718
|
+
h.state.audioRing.length = 0;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
const interval = setInterval(tick, frameMs);
|
|
723
|
+
|
|
724
|
+
// Return a handle the MCP layer can use to stop the session and to wait
|
|
725
|
+
// for natural close. The host stays usable by every other MCP tool while
|
|
726
|
+
// the window is open — screenshots, readMemory, saveState, etc. all act
|
|
727
|
+
// on the same emulator state the user is watching.
|
|
728
|
+
return {
|
|
729
|
+
stop,
|
|
730
|
+
closed: closedPromise,
|
|
731
|
+
get frameCount() { return frameCount; },
|
|
732
|
+
get running() { return running; },
|
|
733
|
+
// Truth-probe for the underlying SDL window. `running` is our own flag
|
|
734
|
+
// and can lag reality if the window dies without firing a 'close' event
|
|
735
|
+
// (compositor kill, X/Wayland session loss, invalid handle). Callers
|
|
736
|
+
// that need an honest answer (playtestStatus) check this and reconcile.
|
|
737
|
+
// Any throw from the SDL binding (handle freed under us) → treat as dead.
|
|
738
|
+
windowAlive() {
|
|
739
|
+
if (!running) return false;
|
|
740
|
+
try {
|
|
741
|
+
return !window.destroyed;
|
|
742
|
+
} catch {
|
|
743
|
+
return false;
|
|
744
|
+
}
|
|
745
|
+
},
|
|
746
|
+
// How many gamepads are currently mapped to player slots. Live (reflects
|
|
747
|
+
// hot-plug), so a caller can decide whether to surface the keyboard help.
|
|
748
|
+
// 0 → the user has no pad and is on the keyboard fallback.
|
|
749
|
+
get controllerCount() { return controllers.filter(Boolean).length; },
|
|
750
|
+
// The emulator host the window is CURRENTLY rendering. The window follows
|
|
751
|
+
// the session's live host (a `runSource`/`loadMedia` rebuild updates it in
|
|
752
|
+
// place), so this is whatever the human is looking at right now. Exposed so
|
|
753
|
+
// the agent can capture exactly that. See playtestFramebuffer.
|
|
754
|
+
get host() { return getLiveHost(); },
|
|
755
|
+
// Capture the framebuffer the human is currently looking at: PNG (base64) +
|
|
756
|
+
// dims + the host's media/frame metadata, straight off the live window host.
|
|
757
|
+
// Returns null if there's transiently no loaded host (mid-rebuild).
|
|
758
|
+
captureFrame() {
|
|
759
|
+
const h = getLiveHost();
|
|
760
|
+
if (!h || !h.status?.loaded) return null;
|
|
761
|
+
const shot = h.screenshot();
|
|
762
|
+
return {
|
|
763
|
+
pngBase64: shot.pngBase64,
|
|
764
|
+
width: shot.width,
|
|
765
|
+
height: shot.height,
|
|
766
|
+
loadedMediaPath: h.status?.mediaPath ?? null,
|
|
767
|
+
platform: h.status?.platform ?? null,
|
|
768
|
+
frameCount: h.status?.frameCount ?? frameCount,
|
|
769
|
+
};
|
|
770
|
+
},
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
function sleep(ms) {
|
|
775
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
function bitToName(bit) {
|
|
779
|
+
return ({
|
|
780
|
+
0: "b", 1: "y", 2: "select", 3: "start",
|
|
781
|
+
4: "up", 5: "down", 6: "left", 7: "right",
|
|
782
|
+
8: "a", 9: "x", 10: "l", 11: "r",
|
|
783
|
+
12: "l2", 13: "r2", 14: "l3", 15: "r3",
|
|
784
|
+
})[bit];
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/** Convert libretro framebuffer (any pixel format) to RGBA32. */
|
|
788
|
+
function framebufferToRgba(f) {
|
|
789
|
+
const out = Buffer.alloc(f.width * f.height * 4);
|
|
790
|
+
if (f.format === RETRO_PIXEL_FORMAT_XRGB8888) {
|
|
791
|
+
for (let y = 0; y < f.height; y++) {
|
|
792
|
+
const src = y * f.pitch;
|
|
793
|
+
const dst = y * f.width * 4;
|
|
794
|
+
for (let x = 0; x < f.width; x++) {
|
|
795
|
+
const s = src + x * 4;
|
|
796
|
+
const d = dst + x * 4;
|
|
797
|
+
out[d + 0] = f.pixels[s + 2];
|
|
798
|
+
out[d + 1] = f.pixels[s + 1];
|
|
799
|
+
out[d + 2] = f.pixels[s + 0];
|
|
800
|
+
out[d + 3] = 0xff;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
} else if (f.format === RETRO_PIXEL_FORMAT_RGB565) {
|
|
804
|
+
for (let y = 0; y < f.height; y++) {
|
|
805
|
+
const src = y * f.pitch;
|
|
806
|
+
const dst = y * f.width * 4;
|
|
807
|
+
for (let x = 0; x < f.width; x++) {
|
|
808
|
+
const s = src + x * 2;
|
|
809
|
+
const p = f.pixels[s] | (f.pixels[s + 1] << 8);
|
|
810
|
+
const r = (p >> 11) & 0x1f;
|
|
811
|
+
const g = (p >> 5) & 0x3f;
|
|
812
|
+
const b = p & 0x1f;
|
|
813
|
+
const d = dst + x * 4;
|
|
814
|
+
out[d + 0] = (r << 3) | (r >> 2);
|
|
815
|
+
out[d + 1] = (g << 2) | (g >> 4);
|
|
816
|
+
out[d + 2] = (b << 3) | (b >> 2);
|
|
817
|
+
out[d + 3] = 0xff;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
} else if (f.format === RETRO_PIXEL_FORMAT_0RGB1555) {
|
|
821
|
+
for (let y = 0; y < f.height; y++) {
|
|
822
|
+
const src = y * f.pitch;
|
|
823
|
+
const dst = y * f.width * 4;
|
|
824
|
+
for (let x = 0; x < f.width; x++) {
|
|
825
|
+
const s = src + x * 2;
|
|
826
|
+
const p = f.pixels[s] | (f.pixels[s + 1] << 8);
|
|
827
|
+
const r = (p >> 10) & 0x1f;
|
|
828
|
+
const g = (p >> 5) & 0x1f;
|
|
829
|
+
const b = p & 0x1f;
|
|
830
|
+
const d = dst + x * 4;
|
|
831
|
+
out[d + 0] = (r << 3) | (r >> 2);
|
|
832
|
+
out[d + 1] = (g << 3) | (g >> 2);
|
|
833
|
+
out[d + 2] = (b << 3) | (b >> 2);
|
|
834
|
+
out[d + 3] = 0xff;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
} else {
|
|
838
|
+
throw new Error(`Unsupported pixel format ${f.format}`);
|
|
839
|
+
}
|
|
840
|
+
return out;
|
|
841
|
+
}
|