romdev-mcp 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +726 -0
- package/LICENSE +45 -0
- package/NOTICE +86 -0
- package/README.md +46 -0
- package/examples/README.md +36 -0
- package/examples/art-first-workflow/README.md +205 -0
- package/examples/atari2600/main.asm +143 -0
- package/examples/atari2600/templates/default.asm +183 -0
- package/examples/atari2600/templates/mini_invaders.asm +381 -0
- package/examples/atari2600/templates/music_demo.asm +322 -0
- package/examples/atari2600/templates/paddle.asm +345 -0
- package/examples/atari2600/templates/single_screen.asm +242 -0
- package/examples/atari7800/main.c +88 -0
- package/examples/atari7800/templates/default.c +183 -0
- package/examples/atari7800/templates/hello_sprite.c +141 -0
- package/examples/atari7800/templates/music_demo.c +123 -0
- package/examples/atari7800/templates/platformer.c +159 -0
- package/examples/atari7800/templates/puzzle.c +164 -0
- package/examples/atari7800/templates/racing.c +139 -0
- package/examples/atari7800/templates/shmup.c +148 -0
- package/examples/atari7800/templates/sports.c +207 -0
- package/examples/c64/main.c +63 -0
- package/examples/c64/templates/hello_sprite.c +117 -0
- package/examples/c64/templates/music_demo.c +131 -0
- package/examples/c64/templates/platformer.c +194 -0
- package/examples/c64/templates/puzzle.c +178 -0
- package/examples/c64/templates/racing.c +140 -0
- package/examples/c64/templates/shmup.c +201 -0
- package/examples/c64/templates/sports.c +109 -0
- package/examples/c64/templates/tile_engine.c +174 -0
- package/examples/gb/main.asm +106 -0
- package/examples/gb/main.c +49 -0
- package/examples/gb/templates/default.c +58 -0
- package/examples/gb/templates/hello_sprite.c +130 -0
- package/examples/gb/templates/music_demo.c +52 -0
- package/examples/gb/templates/platformer.c +178 -0
- package/examples/gb/templates/puzzle.c +217 -0
- package/examples/gb/templates/racing.c +158 -0
- package/examples/gb/templates/shmup.c +172 -0
- package/examples/gb/templates/sports.c +136 -0
- package/examples/gb/templates/tile_engine.c +280 -0
- package/examples/gba/templates/gba_hello.c +64 -0
- package/examples/gba/templates/maxmod_demo.c +105 -0
- package/examples/gba/templates/platformer.c +215 -0
- package/examples/gba/templates/puzzle.c +237 -0
- package/examples/gba/templates/racing.c +175 -0
- package/examples/gba/templates/shmup.c +197 -0
- package/examples/gba/templates/sports.c +177 -0
- package/examples/gba/templates/tonc_hello.c +72 -0
- package/examples/gba/templates/tonc_hello_sprite.c +109 -0
- package/examples/gbc/main.asm +123 -0
- package/examples/gbc/templates/default.c +61 -0
- package/examples/gbc/templates/hello_sprite.c +140 -0
- package/examples/gbc/templates/music_demo.c +63 -0
- package/examples/gbc/templates/platformer.c +181 -0
- package/examples/gbc/templates/puzzle.c +217 -0
- package/examples/gbc/templates/racing.c +164 -0
- package/examples/gbc/templates/shmup.c +188 -0
- package/examples/gbc/templates/sports.c +142 -0
- package/examples/gbc/templates/tile_engine.c +280 -0
- package/examples/genesis/main.s +161 -0
- package/examples/genesis/templates/hello_sprite.c +75 -0
- package/examples/genesis/templates/platformer.c +166 -0
- package/examples/genesis/templates/puzzle.c +240 -0
- package/examples/genesis/templates/racing.c +170 -0
- package/examples/genesis/templates/sgdk_hello.c +41 -0
- package/examples/genesis/templates/shmup.c +188 -0
- package/examples/genesis/templates/shmup_2p.c +244 -0
- package/examples/genesis/templates/sports.c +172 -0
- package/examples/genesis/templates/tile_engine.c +135 -0
- package/examples/genesis/templates/xgm2_demo.c +53 -0
- package/examples/genesis/templates/xgm2_demo_data.s +27 -0
- package/examples/gg/main.c +10 -0
- package/examples/gg/templates/default.c +156 -0
- package/examples/gg/templates/hello_sprite.c +90 -0
- package/examples/gg/templates/music_demo.c +156 -0
- package/examples/gg/templates/platformer.c +220 -0
- package/examples/gg/templates/puzzle.c +204 -0
- package/examples/gg/templates/racing.c +161 -0
- package/examples/gg/templates/shmup.c +188 -0
- package/examples/gg/templates/sports.c +137 -0
- package/examples/gg/templates/tile_engine.c +137 -0
- package/examples/lynx/main.c +4 -0
- package/examples/lynx/templates/default.c +41 -0
- package/examples/lynx/templates/hello_sprite.c +39 -0
- package/examples/lynx/templates/music_demo.c +37 -0
- package/examples/lynx/templates/platformer.c +72 -0
- package/examples/lynx/templates/puzzle.c +142 -0
- package/examples/lynx/templates/racing.c +94 -0
- package/examples/lynx/templates/shmup.c +132 -0
- package/examples/lynx/templates/sports.c +59 -0
- package/examples/nes/main.c +143 -0
- package/examples/nes/space-shooter/README.md +68 -0
- package/examples/nes/space-shooter/main.c +441 -0
- package/examples/nes/space-shooter/nes_runtime.c +347 -0
- package/examples/nes/space-shooter/nes_runtime.h +141 -0
- package/examples/nes/templates/default.c +41 -0
- package/examples/nes/templates/hello_sprite.c +104 -0
- package/examples/nes/templates/music_demo.c +80 -0
- package/examples/nes/templates/platformer.c +171 -0
- package/examples/nes/templates/puzzle.c +232 -0
- package/examples/nes/templates/racing.c +203 -0
- package/examples/nes/templates/shmup.c +228 -0
- package/examples/nes/templates/sports.c +205 -0
- package/examples/nes/templates/tile_engine.c +224 -0
- package/examples/porting-across-platforms/README.md +59 -0
- package/examples/sms/main.c +129 -0
- package/examples/sms/templates/default.c +110 -0
- package/examples/sms/templates/hello_sprite.c +90 -0
- package/examples/sms/templates/music_demo.c +151 -0
- package/examples/sms/templates/platformer.c +215 -0
- package/examples/sms/templates/puzzle.c +204 -0
- package/examples/sms/templates/racing.c +161 -0
- package/examples/sms/templates/shmup.c +167 -0
- package/examples/sms/templates/shmup_2p.c +219 -0
- package/examples/sms/templates/sports.c +147 -0
- package/examples/sms/templates/tile_engine.c +137 -0
- package/examples/snes/main.asm +70 -0
- package/examples/snes/templates/c-hello-data.asm +28 -0
- package/examples/snes/templates/c-hello.c +71 -0
- package/examples/snes/templates/default-data.asm +36 -0
- package/examples/snes/templates/default.c +74 -0
- package/examples/snes/templates/hello_sprite-data.asm +45 -0
- package/examples/snes/templates/hello_sprite.c +76 -0
- package/examples/snes/templates/music_demo-data.asm +20 -0
- package/examples/snes/templates/music_demo.c +83 -0
- package/examples/snes/templates/platformer-data.asm +27 -0
- package/examples/snes/templates/platformer.c +142 -0
- package/examples/snes/templates/puzzle-data.asm +14 -0
- package/examples/snes/templates/puzzle.c +199 -0
- package/examples/snes/templates/racing-data.asm +33 -0
- package/examples/snes/templates/racing.c +146 -0
- package/examples/snes/templates/shmup-data.asm +61 -0
- package/examples/snes/templates/shmup.c +199 -0
- package/examples/snes/templates/sports-data.asm +28 -0
- package/examples/snes/templates/sports.c +144 -0
- package/package.json +83 -0
- package/src/cli/smoke.js +283 -0
- package/src/cores/registry.js +95 -0
- package/src/host/LibretroHost.js +502 -0
- package/src/host/callbacks.js +444 -0
- package/src/host/chafa-render.js +170 -0
- package/src/host/coreLoader.js +57 -0
- package/src/host/cpu-state.js +422 -0
- package/src/host/dsp-state.js +188 -0
- package/src/host/framebuffer.js +115 -0
- package/src/host/gpgx-state.js +309 -0
- package/src/host/index.js +4 -0
- package/src/host/retroConstants.js +72 -0
- package/src/host/snes9x-state.js +35 -0
- package/src/host/types.js +280 -0
- package/src/mcp/disclosure.js +250 -0
- package/src/mcp/log.js +87 -0
- package/src/mcp/server.js +433 -0
- package/src/mcp/state.js +83 -0
- package/src/mcp/tools/address-to-symbol.js +151 -0
- package/src/mcp/tools/art-loaders.js +740 -0
- package/src/mcp/tools/assets.js +89 -0
- package/src/mcp/tools/audio.js +173 -0
- package/src/mcp/tools/cart-parts.js +649 -0
- package/src/mcp/tools/diff-roms.js +412 -0
- package/src/mcp/tools/disasm.js +980 -0
- package/src/mcp/tools/find-references.js +361 -0
- package/src/mcp/tools/font-map.js +353 -0
- package/src/mcp/tools/frame.js +249 -0
- package/src/mcp/tools/free-space.js +95 -0
- package/src/mcp/tools/index.js +351 -0
- package/src/mcp/tools/input-layout.js +215 -0
- package/src/mcp/tools/input.js +142 -0
- package/src/mcp/tools/lifecycle.js +110 -0
- package/src/mcp/tools/lospec.js +156 -0
- package/src/mcp/tools/memory.js +169 -0
- package/src/mcp/tools/metasprite-tools.js +261 -0
- package/src/mcp/tools/platform-docs.js +102 -0
- package/src/mcp/tools/platform-tools.js +1063 -0
- package/src/mcp/tools/platforms.js +86 -0
- package/src/mcp/tools/playtest.js +280 -0
- package/src/mcp/tools/preview-tile.js +360 -0
- package/src/mcp/tools/project.js +1885 -0
- package/src/mcp/tools/record.js +131 -0
- package/src/mcp/tools/rendering-context.js +700 -0
- package/src/mcp/tools/rom-id.js +256 -0
- package/src/mcp/tools/run-until.js +173 -0
- package/src/mcp/tools/snippets.js +235 -0
- package/src/mcp/tools/splice-chr.js +215 -0
- package/src/mcp/tools/sprite-pipeline.js +614 -0
- package/src/mcp/tools/state.js +99 -0
- package/src/mcp/tools/symbols.js +277 -0
- package/src/mcp/tools/tile-inspect.js +206 -0
- package/src/mcp/tools/toolchain.js +680 -0
- package/src/mcp/tools/watch-memory.js +212 -0
- package/src/mcp/tools/which-tiles.js +193 -0
- package/src/mcp/util.js +85 -0
- package/src/observer/bus.js +127 -0
- package/src/observer/livestream.html +589 -0
- package/src/observer/server.js +66 -0
- package/src/observer/tool-wrap.js +115 -0
- package/src/platforms/atari2600/MENTAL_MODEL.md +185 -0
- package/src/platforms/atari2600/TROUBLESHOOTING.md +155 -0
- package/src/platforms/atari2600/UPSTREAM_SOURCES.md +49 -0
- package/src/platforms/atari2600/lib/README.md +67 -0
- package/src/platforms/atari2600/lib/cc65-src/crt0.s +49 -0
- package/src/platforms/atari2600/lib/cc65-src/ctype.s +5 -0
- package/src/platforms/atari2600/lib/kernel_skeleton.asm +85 -0
- package/src/platforms/atari2600/lib/player_kernel.asm +87 -0
- package/src/platforms/atari2600/lib/playfield_kernel.asm +63 -0
- package/src/platforms/atari2600/lib/read_joystick.asm +76 -0
- package/src/platforms/atari2600/lib/score_kernel.asm +141 -0
- package/src/platforms/atari2600/lib/vcs_constants.h +97 -0
- package/src/platforms/atari2600/lib/vectors.asm +16 -0
- package/src/platforms/atari2600/tia.js +355 -0
- package/src/platforms/atari7800/MENTAL_MODEL.md +306 -0
- package/src/platforms/atari7800/TROUBLESHOOTING.md +195 -0
- package/src/platforms/atari7800/UPSTREAM_SOURCES.md +43 -0
- package/src/platforms/atari7800/lib/README.md +45 -0
- package/src/platforms/atari7800/lib/c/atari7800_music.c +215 -0
- package/src/platforms/atari7800/lib/c/atari7800_music.h +33 -0
- package/src/platforms/atari7800/lib/c/atari7800_sfx.c +74 -0
- package/src/platforms/atari7800/lib/c/atari7800_sfx.h +45 -0
- package/src/platforms/atari7800/lib/cc65-src/clock.s +69 -0
- package/src/platforms/atari7800/lib/cc65-src/clocks_per_sec.s +34 -0
- package/src/platforms/atari7800/lib/cc65-src/clrscr.s +27 -0
- package/src/platforms/atari7800/lib/cc65-src/conio.s +226 -0
- package/src/platforms/atari7800/lib/cc65-src/conio_font.s +278 -0
- package/src/platforms/atari7800/lib/cc65-src/cputc.s +139 -0
- package/src/platforms/atari7800/lib/cc65-src/crt0.s +71 -0
- package/src/platforms/atari7800/lib/cc65-src/ctype.s +5 -0
- package/src/platforms/atari7800/lib/cc65-src/exehdr.s +46 -0
- package/src/platforms/atari7800/lib/cc65-src/extra/mono.s +28 -0
- package/src/platforms/atari7800/lib/cc65-src/extzp.inc +15 -0
- package/src/platforms/atari7800/lib/cc65-src/extzp.s +15 -0
- package/src/platforms/atari7800/lib/cc65-src/get_tv.s +65 -0
- package/src/platforms/atari7800/lib/cc65-src/irq.s +36 -0
- package/src/platforms/atari7800/lib/cc65-src/joy/atari7800-stdjoy.s +197 -0
- package/src/platforms/atari7800/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/atari7800/lib/cc65-src/libref.s +8 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_clrscr.s +27 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_conio.s +231 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_cputc.s +102 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_font.s +2065 -0
- package/src/platforms/atari7800/lib/cc65-src/mono_setcursor.s +214 -0
- package/src/platforms/atari7800/lib/cc65-src/setcursor.s +214 -0
- package/src/platforms/atari7800/lib/cc65-src/textcolor.s +53 -0
- package/src/platforms/atari7800/lib/cc65-src/wherex.s +19 -0
- package/src/platforms/atari7800/lib/cc65-src/wherey.s +19 -0
- package/src/platforms/atari7800/lib/display_list.asm +53 -0
- package/src/platforms/atari7800/lib/maria_init.asm +48 -0
- package/src/platforms/atari7800/lib/maria_registers.h +61 -0
- package/src/platforms/atari7800/lib/palette_load.asm +53 -0
- package/src/platforms/atari7800/lib/read_pad.asm +57 -0
- package/src/platforms/atari7800/lib/vblank_wait.asm +16 -0
- package/src/platforms/atari7800/maria.js +220 -0
- package/src/platforms/c64/MENTAL_MODEL.md +175 -0
- package/src/platforms/c64/TROUBLESHOOTING.md +130 -0
- package/src/platforms/c64/UPSTREAM_SOURCES.md +35 -0
- package/src/platforms/c64/image-to-tilemap.js +190 -0
- package/src/platforms/c64/lib/README.md +52 -0
- package/src/platforms/c64/lib/basic_stub.s +25 -0
- package/src/platforms/c64/lib/c/c64_music.c +248 -0
- package/src/platforms/c64/lib/c/c64_music.h +36 -0
- package/src/platforms/c64/lib/c/c64_sfx.c +94 -0
- package/src/platforms/c64/lib/c/c64_sfx.h +37 -0
- package/src/platforms/c64/lib/c64_registers.h +108 -0
- package/src/platforms/c64/lib/cc65-src/_scrsize.s +12 -0
- package/src/platforms/c64/lib/cc65-src/acc_c128_speed.s +5 -0
- package/src/platforms/c64/lib/cc65-src/acc_c64dtv_speed.s +64 -0
- package/src/platforms/c64/lib/cc65-src/acc_c65_speed.s +69 -0
- package/src/platforms/c64/lib/cc65-src/acc_chameleon_speed.s +100 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_c128.s +33 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_c64dtv.s +44 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_c65.s +55 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_chameleon.s +39 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_scpu.s +34 -0
- package/src/platforms/c64/lib/cc65-src/acc_detect_turbomaster.s +45 -0
- package/src/platforms/c64/lib/cc65-src/acc_scpu_speed.s +59 -0
- package/src/platforms/c64/lib/cc65-src/acc_turbomaster_speed.s +56 -0
- package/src/platforms/c64/lib/cc65-src/bordercolor.s +17 -0
- package/src/platforms/c64/lib/cc65-src/break.s +108 -0
- package/src/platforms/c64/lib/cc65-src/cgetc.s +62 -0
- package/src/platforms/c64/lib/cc65-src/clrscr.s +11 -0
- package/src/platforms/c64/lib/cc65-src/color.s +24 -0
- package/src/platforms/c64/lib/cc65-src/conio.s +10 -0
- package/src/platforms/c64/lib/cc65-src/cputc.s +105 -0
- package/src/platforms/c64/lib/cc65-src/crt0.s +117 -0
- package/src/platforms/c64/lib/cc65-src/devnum.s +7 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-65816.s +377 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-c256k.s +508 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-dqbb.s +447 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-georam.s +355 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-isepic.s +276 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-kerberos.s +281 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-ram.s +270 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-ramcart.s +297 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-reu.s +286 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-rrr.s +363 -0
- package/src/platforms/c64/lib/cc65-src/emd/c64-vdc.s +405 -0
- package/src/platforms/c64/lib/cc65-src/emd/dtv-himem.s +251 -0
- package/src/platforms/c64/lib/cc65-src/extra/soft80.s +71 -0
- package/src/platforms/c64/lib/cc65-src/extra/soft80mono.s +74 -0
- package/src/platforms/c64/lib/cc65-src/extra/tgimousedata.s +21 -0
- package/src/platforms/c64/lib/cc65-src/get_ostype.s +43 -0
- package/src/platforms/c64/lib/cc65-src/get_tv.s +20 -0
- package/src/platforms/c64/lib/cc65-src/gettime.s +83 -0
- package/src/platforms/c64/lib/cc65-src/irq.s +49 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-hitjoy.s +218 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-numpad.s +155 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-ptvjoy.s +146 -0
- package/src/platforms/c64/lib/cc65-src/joy/c64-stdjoy.s +111 -0
- package/src/platforms/c64/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/joy_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/kbhit.s +23 -0
- package/src/platforms/c64/lib/cc65-src/kbrepeat.s +14 -0
- package/src/platforms/c64/lib/cc65-src/kernal.s +53 -0
- package/src/platforms/c64/lib/cc65-src/kplot.s +22 -0
- package/src/platforms/c64/lib/cc65-src/libref.s +16 -0
- package/src/platforms/c64/lib/cc65-src/mainargs.s +137 -0
- package/src/platforms/c64/lib/cc65-src/mcbdefault.s +146 -0
- package/src/platforms/c64/lib/cc65-src/mcbspritedata.s +4 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-1351.s +467 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-inkwell.s +446 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-joy.s +451 -0
- package/src/platforms/c64/lib/cc65-src/mou/c64-pot.s +409 -0
- package/src/platforms/c64/lib/cc65-src/mouse_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/mouse_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/mouseref.s +23 -0
- package/src/platforms/c64/lib/cc65-src/pencalib.c +94 -0
- package/src/platforms/c64/lib/cc65-src/randomize.s +18 -0
- package/src/platforms/c64/lib/cc65-src/revers.s +27 -0
- package/src/platforms/c64/lib/cc65-src/ser/c64-swlink.s +484 -0
- package/src/platforms/c64/lib/cc65-src/ser_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/ser_stddrv.s +13 -0
- package/src/platforms/c64/lib/cc65-src/settime.s +84 -0
- package/src/platforms/c64/lib/cc65-src/soft80.inc +46 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cgetc.s +85 -0
- package/src/platforms/c64/lib/cc65-src/soft80_charset.s +182 -0
- package/src/platforms/c64/lib/cc65-src/soft80_color.s +159 -0
- package/src/platforms/c64/lib/cc65-src/soft80_conio.s +157 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeekc.s +148 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeekcolor.s +19 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeekrevers.s +15 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cpeeks.s +71 -0
- package/src/platforms/c64/lib/cc65-src/soft80_cputc.s +521 -0
- package/src/platforms/c64/lib/cc65-src/soft80_kclrscr.s +76 -0
- package/src/platforms/c64/lib/cc65-src/soft80_kplot.s +63 -0
- package/src/platforms/c64/lib/cc65-src/soft80_scrsize.s +14 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_cgetc.s +67 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_color.s +65 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_conio.s +168 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_cpeekcolor.s +17 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_cputc.s +204 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_kclrscr.s +63 -0
- package/src/platforms/c64/lib/cc65-src/soft80mono_kplot.s +52 -0
- package/src/platforms/c64/lib/cc65-src/status.s +15 -0
- package/src/platforms/c64/lib/cc65-src/sysuname.s +37 -0
- package/src/platforms/c64/lib/cc65-src/tgi/c64-hi.s +881 -0
- package/src/platforms/c64/lib/cc65-src/tgi_stat_stddrv.s +14 -0
- package/src/platforms/c64/lib/cc65-src/tgi_stddrv.s +13 -0
- package/src/platforms/c64/lib/cc65-src/tmcommon.s +67 -0
- package/src/platforms/c64/lib/cc65-src/waitvsync.s +18 -0
- package/src/platforms/c64/lib/read_joystick.s +28 -0
- package/src/platforms/c64/lib/sid_play.s +48 -0
- package/src/platforms/c64/lib/sprite_table.s +73 -0
- package/src/platforms/c64/lib/vic_init.s +47 -0
- package/src/platforms/c64/sid.js +128 -0
- package/src/platforms/c64/vic.js +273 -0
- package/src/platforms/common/default-palette.js +139 -0
- package/src/platforms/common/image-to-tiles.js +407 -0
- package/src/platforms/common/intent.js +111 -0
- package/src/platforms/common/metasprite-adapters.js +279 -0
- package/src/platforms/common/metasprite-codegen.js +192 -0
- package/src/platforms/common/metasprite-core.js +201 -0
- package/src/platforms/common/metasprite.js +89 -0
- package/src/platforms/common/platform-palette.js +137 -0
- package/src/platforms/common/registers.js +329 -0
- package/src/platforms/common/render-tiles.js +86 -0
- package/src/platforms/common/screenshot-sprite.js +153 -0
- package/src/platforms/common/tile-decode.js +149 -0
- package/src/platforms/gb/MENTAL_MODEL.md +252 -0
- package/src/platforms/gb/TROUBLESHOOTING.md +221 -0
- package/src/platforms/gb/UPSTREAM_SOURCES.md +43 -0
- package/src/platforms/gb/image-to-tilemap.js +173 -0
- package/src/platforms/gb/lib/README.md +115 -0
- package/src/platforms/gb/lib/c/LICENSE-HUGEDRIVER +25 -0
- package/src/platforms/gb/lib/c/README.md +120 -0
- package/src/platforms/gb/lib/c/SDCC_GOTCHAS.md +189 -0
- package/src/platforms/gb/lib/c/gb_crt0.s +163 -0
- package/src/platforms/gb/lib/c/gb_hardware.h +113 -0
- package/src/platforms/gb/lib/c/gb_runtime.c +284 -0
- package/src/platforms/gb/lib/c/gb_runtime.h +145 -0
- package/src/platforms/gb/lib/c/hUGEDriver.c +191 -0
- package/src/platforms/gb/lib/c/hUGEDriver.h +95 -0
- package/src/platforms/gb/lib/c/hUGEDriver.upstream.asm +1908 -0
- package/src/platforms/gb/lib/c/lcd_init.c +19 -0
- package/src/platforms/gb/lib/c/patch-header.js +154 -0
- package/src/platforms/gb/lib/c/song_data.c +88 -0
- package/src/platforms/gb/lib/c/unroll.h +52 -0
- package/src/platforms/gb/lib/c/wait_vblank.c +14 -0
- package/src/platforms/gb/lib/dma_oam.asm +51 -0
- package/src/platforms/gb/lib/header.asm +56 -0
- package/src/platforms/gb/lib/joypad_read.asm +47 -0
- package/src/platforms/gb/lib/lcd_init.asm +44 -0
- package/src/platforms/gb/lib/load_palette.asm +25 -0
- package/src/platforms/gb/lib/load_tiles.asm +29 -0
- package/src/platforms/gb/lib/vblank_wait.asm +31 -0
- package/src/platforms/gb/ppu.js +574 -0
- package/src/platforms/gba/MENTAL_MODEL.md +203 -0
- package/src/platforms/gba/TROUBLESHOOTING.md +250 -0
- package/src/platforms/gba/UPSTREAM_SOURCES.md +41 -0
- package/src/platforms/gba/lib/arm-archives/libc.a +0 -0
- package/src/platforms/gba/lib/arm-archives/libgcc.a +0 -0
- package/src/platforms/gba/lib/arm-archives/libnosys.a +0 -0
- package/src/platforms/gba/lib/c/gba_sfx.c +81 -0
- package/src/platforms/gba/lib/c/gba_sfx.h +48 -0
- package/src/platforms/gba/lib/libgba/crtbegin.o +0 -0
- package/src/platforms/gba/lib/libgba/crtend.o +0 -0
- package/src/platforms/gba/lib/libgba/crti.o +0 -0
- package/src/platforms/gba/lib/libgba/crtn.o +0 -0
- package/src/platforms/gba/lib/libgba/gba_cart.ld +319 -0
- package/src/platforms/gba/lib/libgba/gba_crt0.s +258 -0
- package/src/platforms/gba/lib/libgba/include/BoyScout.h +128 -0
- package/src/platforms/gba/lib/libgba/include/disc.h +36 -0
- package/src/platforms/gba/lib/libgba/include/disc_io.h +64 -0
- package/src/platforms/gba/lib/libgba/include/dldi.h +112 -0
- package/src/platforms/gba/lib/libgba/include/erapi.h +195 -0
- package/src/platforms/gba/lib/libgba/include/fade.h +76 -0
- package/src/platforms/gba/lib/libgba/include/gba.h +47 -0
- package/src/platforms/gba/lib/libgba/include/gba_affine.h +83 -0
- package/src/platforms/gba/lib/libgba/include/gba_base.h +122 -0
- package/src/platforms/gba/lib/libgba/include/gba_compression.h +66 -0
- package/src/platforms/gba/lib/libgba/include/gba_console.h +55 -0
- package/src/platforms/gba/lib/libgba/include/gba_dma.h +100 -0
- package/src/platforms/gba/lib/libgba/include/gba_input.h +127 -0
- package/src/platforms/gba/lib/libgba/include/gba_interrupt.h +146 -0
- package/src/platforms/gba/lib/libgba/include/gba_multiboot.h +72 -0
- package/src/platforms/gba/lib/libgba/include/gba_sio.h +124 -0
- package/src/platforms/gba/lib/libgba/include/gba_sound.h +356 -0
- package/src/platforms/gba/lib/libgba/include/gba_sprites.h +195 -0
- package/src/platforms/gba/lib/libgba/include/gba_systemcalls.h +194 -0
- package/src/platforms/gba/lib/libgba/include/gba_timers.h +63 -0
- package/src/platforms/gba/lib/libgba/include/gba_types.h +60 -0
- package/src/platforms/gba/lib/libgba/include/gba_video.h +307 -0
- package/src/platforms/gba/lib/libgba/include/mappy.h +72 -0
- package/src/platforms/gba/lib/libgba/include/mbv2.h +90 -0
- package/src/platforms/gba/lib/libgba/include/xcomms.h +93 -0
- package/src/platforms/gba/lib/libgba/include/xcomms_cmd.h +53 -0
- package/src/platforms/gba/lib/libgba/libgba.seed.a +0 -0
- package/src/platforms/gba/lib/libgba/libgba.seed.hash +1 -0
- package/src/platforms/gba/lib/libgba/src/AffineSet.c +42 -0
- package/src/platforms/gba/lib/libgba/src/ArcTan.s +41 -0
- package/src/platforms/gba/lib/libgba/src/BoyScout/BoyScout.c +1242 -0
- package/src/platforms/gba/lib/libgba/src/BoyScout/GBASoundRegs.h +200 -0
- package/src/platforms/gba/lib/libgba/src/Compression.c +84 -0
- package/src/platforms/gba/lib/libgba/src/CpuSet.c +41 -0
- package/src/platforms/gba/lib/libgba/src/Div.s +58 -0
- package/src/platforms/gba/lib/libgba/src/DivArm.s +50 -0
- package/src/platforms/gba/lib/libgba/src/InterruptDispatcher.s +113 -0
- package/src/platforms/gba/lib/libgba/src/IntrWait.c +35 -0
- package/src/platforms/gba/lib/libgba/src/MultiBoot.s +33 -0
- package/src/platforms/gba/lib/libgba/src/Reset.s +49 -0
- package/src/platforms/gba/lib/libgba/src/Sound.s +48 -0
- package/src/platforms/gba/lib/libgba/src/Sqrt.s +34 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/disc.c +58 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/dldi.c +189 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/dldi_stub.s +78 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_cf_common.c +260 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_cf_common.h +72 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3_common.c +60 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3_common.h +48 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3cf.c +83 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3cf.h +45 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3sd.c +508 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_m3sd.h +45 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_mpcf.c +87 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_mpcf.h +42 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sc_common.c +47 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sc_common.h +43 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sccf.c +83 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sccf.h +45 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_scsd.c +385 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_scsd.h +48 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_scsd_s.s +139 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sd_common.c +203 -0
- package/src/platforms/gba/lib/libgba/src/disc_io/io_sd_common.h +108 -0
- package/src/platforms/gba/lib/libgba/src/fade.c +185 -0
- package/src/platforms/gba/lib/libgba/src/input.c +127 -0
- package/src/platforms/gba/lib/libgba/src/interrupt.c +116 -0
- package/src/platforms/gba/lib/libgba/src/mappy_print.c +74 -0
- package/src/platforms/gba/lib/libgba/src/mb2print.c +69 -0
- package/src/platforms/gba/lib/libgba/src/mbv2.c +230 -0
- package/src/platforms/gba/lib/libgba/src/mbv2.txt +119 -0
- package/src/platforms/gba/lib/libgba/src/xcomms.c +203 -0
- package/src/platforms/gba/lib/libgba/src/xcomms_print.c +56 -0
- package/src/platforms/gba/lib/libgba/sysinclude/_ansi.h +82 -0
- package/src/platforms/gba/lib/libgba/sysinclude/_newlib_version.h +11 -0
- package/src/platforms/gba/lib/libgba/sysinclude/_syslist.h +41 -0
- package/src/platforms/gba/lib/libgba/sysinclude/alloca.h +21 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ar.h +65 -0
- package/src/platforms/gba/lib/libgba/sysinclude/argz.h +33 -0
- package/src/platforms/gba/lib/libgba/sysinclude/assert.h +50 -0
- package/src/platforms/gba/lib/libgba/sysinclude/complex.h +150 -0
- package/src/platforms/gba/lib/libgba/sysinclude/cpio.h +30 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ctype.h +183 -0
- package/src/platforms/gba/lib/libgba/sysinclude/devctl.h +78 -0
- package/src/platforms/gba/lib/libgba/sysinclude/dirent.h +85 -0
- package/src/platforms/gba/lib/libgba/sysinclude/elf.h +3147 -0
- package/src/platforms/gba/lib/libgba/sysinclude/envlock.h +15 -0
- package/src/platforms/gba/lib/libgba/sysinclude/envz.h +16 -0
- package/src/platforms/gba/lib/libgba/sysinclude/errno.h +11 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fastmath.h +13 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fcntl.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fenv.h +42 -0
- package/src/platforms/gba/lib/libgba/sysinclude/float.h +631 -0
- package/src/platforms/gba/lib/libgba/sysinclude/fnmatch.h +55 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ftw.h +66 -0
- package/src/platforms/gba/lib/libgba/sysinclude/getopt.h +185 -0
- package/src/platforms/gba/lib/libgba/sysinclude/glob.h +90 -0
- package/src/platforms/gba/lib/libgba/sysinclude/grp.h +86 -0
- package/src/platforms/gba/lib/libgba/sysinclude/iconv.h +63 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ieeefp.h +295 -0
- package/src/platforms/gba/lib/libgba/sysinclude/inttypes.h +345 -0
- package/src/platforms/gba/lib/libgba/sysinclude/iso646.h +45 -0
- package/src/platforms/gba/lib/libgba/sysinclude/langinfo.h +332 -0
- package/src/platforms/gba/lib/libgba/sysinclude/libgen.h +37 -0
- package/src/platforms/gba/lib/libgba/sysinclude/limits.h +168 -0
- package/src/platforms/gba/lib/libgba/sysinclude/locale.h +96 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_arc4random.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_default_types.h +250 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_endian.h +39 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_time.h +3 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/_types.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/ansi.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/endian.h +69 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/fastmath.h +98 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/ieee.h +127 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/ieeefp.h +533 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/malloc.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/param.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/setjmp-dj.h +43 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/setjmp.h +524 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/stdlib.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/termios.h +1 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/time.h +15 -0
- package/src/platforms/gba/lib/libgba/sysinclude/machine/types.h +13 -0
- package/src/platforms/gba/lib/libgba/sysinclude/malloc.h +173 -0
- package/src/platforms/gba/lib/libgba/sysinclude/math.h +645 -0
- package/src/platforms/gba/lib/libgba/sysinclude/memory.h +4 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ndbm.h +91 -0
- package/src/platforms/gba/lib/libgba/sysinclude/newlib.h +427 -0
- package/src/platforms/gba/lib/libgba/sysinclude/paths.h +9 -0
- package/src/platforms/gba/lib/libgba/sysinclude/pthread.h +456 -0
- package/src/platforms/gba/lib/libgba/sysinclude/pwd.h +83 -0
- package/src/platforms/gba/lib/libgba/sysinclude/reent.h +190 -0
- package/src/platforms/gba/lib/libgba/sysinclude/regdef.h +7 -0
- package/src/platforms/gba/lib/libgba/sysinclude/regex.h +103 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sched.h +112 -0
- package/src/platforms/gba/lib/libgba/sysinclude/search.h +64 -0
- package/src/platforms/gba/lib/libgba/sysinclude/setjmp.h +25 -0
- package/src/platforms/gba/lib/libgba/sysinclude/signal.h +35 -0
- package/src/platforms/gba/lib/libgba/sysinclude/spawn.h +111 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/ssp.h +76 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/stdio.h +101 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/stdlib.h +30 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/string.h +115 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/strings.h +55 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/unistd.h +93 -0
- package/src/platforms/gba/lib/libgba/sysinclude/ssp/wchar.h +97 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdarg.h +135 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdatomic.h +409 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdbool.h +51 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stddef.h +463 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdint.h +466 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdio.h +807 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdio_ext.h +79 -0
- package/src/platforms/gba/lib/libgba/sysinclude/stdlib.h +345 -0
- package/src/platforms/gba/lib/libgba/sysinclude/string.h +183 -0
- package/src/platforms/gba/lib/libgba/sysinclude/strings.h +80 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_default_fcntl.h +241 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_intsup.h +199 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_locale.h +12 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_pthreadtypes.h +233 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_sigset.h +43 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_stdint.h +90 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_timespec.h +52 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_timeval.h +60 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_types.h +228 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/_tz_structs.h +24 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/cdefs.h +754 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/config.h +314 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/custom_file.h +2 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/dir.h +10 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/dirent.h +13 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/endian.h +207 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/errno.h +198 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/fcntl.h +12 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/features.h +551 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/fenv.h +90 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/file.h +2 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/iconvnls.h +77 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/iosupport.h +143 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/lock.h +75 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/param.h +35 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/queue.h +919 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/reent.h +913 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/resource.h +24 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/sched.h +69 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/select.h +94 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/signal.h +388 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/stat.h +179 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/statvfs.h +41 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/stdio.h +27 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/string.h +2 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/syslimits.h +61 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/time.h +448 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/timeb.h +40 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/times.h +32 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/timespec.h +63 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/tree.h +864 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/types.h +228 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/unistd.h +591 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/utime.h +22 -0
- package/src/platforms/gba/lib/libgba/sysinclude/sys/wait.h +44 -0
- package/src/platforms/gba/lib/libgba/sysinclude/tar.h +43 -0
- package/src/platforms/gba/lib/libgba/sysinclude/termios.h +7 -0
- package/src/platforms/gba/lib/libgba/sysinclude/tgmath.h +127 -0
- package/src/platforms/gba/lib/libgba/sysinclude/threads.h +93 -0
- package/src/platforms/gba/lib/libgba/sysinclude/time.h +313 -0
- package/src/platforms/gba/lib/libgba/sysinclude/unctrl.h +42 -0
- package/src/platforms/gba/lib/libgba/sysinclude/unistd.h +6 -0
- package/src/platforms/gba/lib/libgba/sysinclude/utime.h +12 -0
- package/src/platforms/gba/lib/libgba/sysinclude/utmp.h +8 -0
- package/src/platforms/gba/lib/libgba/sysinclude/varargs.h +7 -0
- package/src/platforms/gba/lib/libgba/sysinclude/wchar.h +339 -0
- package/src/platforms/gba/lib/libgba/sysinclude/wctype.h +74 -0
- package/src/platforms/gba/lib/libgba/sysinclude/wordexp.h +53 -0
- package/src/platforms/gba/lib/libtonc/crtbegin.o +0 -0
- package/src/platforms/gba/lib/libtonc/crtend.o +0 -0
- package/src/platforms/gba/lib/libtonc/crti.o +0 -0
- package/src/platforms/gba/lib/libtonc/crtn.o +0 -0
- package/src/platforms/gba/lib/libtonc/gba_cart.ld +319 -0
- package/src/platforms/gba/lib/libtonc/gba_crt0.s +258 -0
- package/src/platforms/gba/lib/libtonc/include/tonc.h +72 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_asminc.h +132 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_bios.h +555 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_core.h +573 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_input.h +184 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_irq.h +121 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_legacy.h +481 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_libgba.h +537 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_math.h +692 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_memdef.h +962 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_memmap.h +583 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_nocash.h +51 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_oam.h +186 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_surface.h +461 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_text.h +270 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_tte.h +748 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_types.h +376 -0
- package/src/platforms/gba/lib/libtonc/include/tonc_video.h +615 -0
- package/src/platforms/gba/lib/libtonc/libtonc.seed.a +0 -0
- package/src/platforms/gba/lib/libtonc/libtonc.seed.hash +1 -0
- package/src/platforms/gba/lib/libtonc/src/asm/clr_blend_fast.s +72 -0
- package/src/platforms/gba/lib/libtonc/src/asm/clr_fade_fast.s +74 -0
- package/src/platforms/gba/lib/libtonc/src/asm/div_lut.s +54 -0
- package/src/platforms/gba/lib/libtonc/src/asm/sin_lut.s +90 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_bios.s +289 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_bios_ex.s +97 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_isr_master.s +92 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_isr_nest.s +98 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_memcpy.s +126 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_memset.s +123 -0
- package/src/platforms/gba/lib/libtonc/src/asm/tonc_nocash.s +73 -0
- package/src/platforms/gba/lib/libtonc/src/font/sys8.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/sys8.s +46 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana10.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana10.s +293 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9.s +167 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9_b4.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9_b4.s +545 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9b.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9b.s +167 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9i.png +0 -0
- package/src/platforms/gba/lib/libtonc/src/font/verdana9i.s +167 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_bitmap.c +289 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text.c +81 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text_bm.c +244 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text_map.c +122 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/tonc_text_oam.c +113 -0
- package/src/platforms/gba/lib/libtonc/src/pre1.3/toncfont.s +43 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bg.c +61 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bg_affine.c +112 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bmp16.c +240 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_bmp8.c +314 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_color.c +368 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_core.c +237 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_input.c +118 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_irq.c +271 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_math.c +54 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_oam.c +76 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_obj_affine.c +146 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_sbmp16.c +369 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_sbmp8.c +405 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_schr4c.c +588 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_schr4r.c +462 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_surface.c +105 -0
- package/src/platforms/gba/lib/libtonc/src/tonc_video.c +33 -0
- package/src/platforms/gba/lib/libtonc/src/tte/ase_drawg.c +83 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp16_drawg.c +72 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp16_drawg_b1cs.c +92 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp8_drawg.c +71 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp8_drawg_b1cs.c +104 -0
- package/src/platforms/gba/lib/libtonc/src/tte/bmp8_drawg_b1cts_fast.s +115 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b1cts.c +76 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b1cts_fast.s +128 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b4cts.c +67 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4c_drawg_b4cts_fast.s +127 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4r_drawg_b1cts.c +80 -0
- package/src/platforms/gba/lib/libtonc/src/tte/chr4r_drawg_b1cts_fast.s +145 -0
- package/src/platforms/gba/lib/libtonc/src/tte/obj_drawg.c +61 -0
- package/src/platforms/gba/lib/libtonc/src/tte/se_drawg.c +110 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_ase.c +87 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_bmp.c +118 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_chr4c.c +86 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_chr4r.c +87 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_obj.c +84 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_init_se.c +96 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_iohook.c +264 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_main.c +756 -0
- package/src/platforms/gba/lib/libtonc/src/tte/tte_types.s +119 -0
- package/src/platforms/gba/lib/maxmod/LICENSE-MAXMOD +23 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_defs.inc +117 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_format_mas.inc +108 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_macros.inc +195 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mas.inc +40 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mas_structs.inc +189 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mixer_ds.inc +46 -0
- package/src/platforms/gba/lib/maxmod/asm_include/mp_mixer_gba.inc +42 -0
- package/src/platforms/gba/lib/maxmod/asm_include/swi_gba.inc +23 -0
- package/src/platforms/gba/lib/maxmod/include/maxmod.h +412 -0
- package/src/platforms/gba/lib/maxmod/include/mm_types.h +333 -0
- package/src/platforms/gba/lib/maxmod/maxmod.seed.a +0 -0
- package/src/platforms/gba/lib/maxmod/maxmod.seed.hash +1 -0
- package/src/platforms/gba/lib/maxmod/music/chiptune.xm +0 -0
- package/src/platforms/gba/lib/maxmod/music/chiptune_soundbank.bin +0 -0
- package/src/platforms/gba/lib/maxmod/music/chiptune_soundbank.h +4 -0
- package/src/platforms/gba/lib/maxmod/music/make_chiptune_xm.js +203 -0
- package/src/platforms/gba/lib/maxmod/source/mm_effect.s +767 -0
- package/src/platforms/gba/lib/maxmod/source/mm_main.s +115 -0
- package/src/platforms/gba/lib/maxmod/source/mm_mas.s +4990 -0
- package/src/platforms/gba/lib/maxmod/source/mm_mas_arm.s +612 -0
- package/src/platforms/gba/lib/maxmod/source_gba/mm_init_default.s +98 -0
- package/src/platforms/gba/lib/maxmod/source_gba/mm_main_gba.s +292 -0
- package/src/platforms/gba/lib/maxmod/source_gba/mm_mixer_gba.s +1367 -0
- package/src/platforms/gba/lib/sysbase/gba_iosupport.c +138 -0
- package/src/platforms/gbc/MENTAL_MODEL.md +165 -0
- package/src/platforms/gbc/TROUBLESHOOTING.md +142 -0
- package/src/platforms/gbc/UPSTREAM_SOURCES.md +60 -0
- package/src/platforms/gbc/lib/c/LICENSE-HUGEDRIVER +25 -0
- package/src/platforms/gbc/lib/c/README.md +120 -0
- package/src/platforms/gbc/lib/c/SDCC_GOTCHAS.md +189 -0
- package/src/platforms/gbc/lib/c/gb_crt0.s +163 -0
- package/src/platforms/gbc/lib/c/gb_hardware.h +113 -0
- package/src/platforms/gbc/lib/c/gb_runtime.c +284 -0
- package/src/platforms/gbc/lib/c/gb_runtime.h +145 -0
- package/src/platforms/gbc/lib/c/hUGEDriver.c +191 -0
- package/src/platforms/gbc/lib/c/hUGEDriver.h +95 -0
- package/src/platforms/gbc/lib/c/hUGEDriver.upstream.asm +1908 -0
- package/src/platforms/gbc/lib/c/lcd_init.c +19 -0
- package/src/platforms/gbc/lib/c/patch-header.js +154 -0
- package/src/platforms/gbc/lib/c/song_data.c +88 -0
- package/src/platforms/gbc/lib/c/unroll.h +52 -0
- package/src/platforms/gbc/lib/c/wait_vblank.c +14 -0
- package/src/platforms/genesis/MENTAL_MODEL.md +223 -0
- package/src/platforms/genesis/TROUBLESHOOTING.md +193 -0
- package/src/platforms/genesis/UPSTREAM_SOURCES.md +52 -0
- package/src/platforms/genesis/image-to-tilemap.js +333 -0
- package/src/platforms/genesis/lib/README.md +157 -0
- package/src/platforms/genesis/lib/c/crtbegin.o +0 -0
- package/src/platforms/genesis/lib/c/crtend.o +0 -0
- package/src/platforms/genesis/lib/c/genesis.ld +44 -0
- package/src/platforms/genesis/lib/c/genesis_sfx.c +51 -0
- package/src/platforms/genesis/lib/c/genesis_sfx.h +49 -0
- package/src/platforms/genesis/lib/c/libc.a +0 -0
- package/src/platforms/genesis/lib/c/libgcc.a +0 -0
- package/src/platforms/genesis/lib/c/libm.a +0 -0
- package/src/platforms/genesis/lib/c/sega.s +71 -0
- package/src/platforms/genesis/lib/header.s +96 -0
- package/src/platforms/genesis/lib/nmi_safe.s +79 -0
- package/src/platforms/genesis/lib/pad_read.s +104 -0
- package/src/platforms/genesis/lib/sgdk/COPYING.RUNTIME +73 -0
- package/src/platforms/genesis/lib/sgdk/LICENSE +12 -0
- package/src/platforms/genesis/lib/sgdk/include/asm.h +52 -0
- package/src/platforms/genesis/lib/sgdk/include/asm_mac.i +9 -0
- package/src/platforms/genesis/lib/sgdk/include/bmp.h +690 -0
- package/src/platforms/genesis/lib/sgdk/include/config.h +208 -0
- package/src/platforms/genesis/lib/sgdk/include/dma.h +542 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/console.h +387 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/everdrive.h +116 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/fat16.h +84 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/flash-save/flash.h +164 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/flash-save/saveman.h +177 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/link_cable.h +316 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/minimusic/minimus.h +29 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/16c550.h +221 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/comm.h +93 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/gamejolt.h +541 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/jsmn.h +471 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/json.h +122 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/lsd.h +172 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/megawifi.h +984 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/mw-msg.h +392 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/ssf_ed_pro.h +38 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/mw/ssf_ed_x7.h +73 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/serial/buffer.h +8 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/serial/serial.h +133 -0
- package/src/platforms/genesis/lib/sgdk/include/ext/stb/stb_sprintf.h +1864 -0
- package/src/platforms/genesis/lib/sgdk/include/genesis.h +92 -0
- package/src/platforms/genesis/lib/sgdk/include/joy.h +482 -0
- package/src/platforms/genesis/lib/sgdk/include/kdebug.h +21 -0
- package/src/platforms/genesis/lib/sgdk/include/map.h +409 -0
- package/src/platforms/genesis/lib/sgdk/include/mapper.h +186 -0
- package/src/platforms/genesis/lib/sgdk/include/maths.h +1071 -0
- package/src/platforms/genesis/lib/sgdk/include/maths3D.h +480 -0
- package/src/platforms/genesis/lib/sgdk/include/memory.h +346 -0
- package/src/platforms/genesis/lib/sgdk/include/memory_base.h +37 -0
- package/src/platforms/genesis/lib/sgdk/include/object.h +171 -0
- package/src/platforms/genesis/lib/sgdk/include/pal.h +500 -0
- package/src/platforms/genesis/lib/sgdk/include/pool.h +171 -0
- package/src/platforms/genesis/lib/sgdk/include/psg.h +153 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/snd_dpcm2.h +79 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/snd_pcm.h +98 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/snd_pcm4.h +125 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/pcm/tab_vol.h +6 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/smp_null.h +6 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/smp_null_dpcm.h +6 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/sound.h +70 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/xgm.h +399 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/xgm2.h +389 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/z80_def.i80 +41 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/z80_fct.i80 +83 -0
- package/src/platforms/genesis/lib/sgdk/include/snd/z80_mac.i80 +1476 -0
- package/src/platforms/genesis/lib/sgdk/include/sprite_eng.h +1095 -0
- package/src/platforms/genesis/lib/sgdk/include/sprite_eng_legacy.h +1030 -0
- package/src/platforms/genesis/lib/sgdk/include/sram.h +110 -0
- package/src/platforms/genesis/lib/sgdk/include/string.h +349 -0
- package/src/platforms/genesis/lib/sgdk/include/sys.h +511 -0
- package/src/platforms/genesis/lib/sgdk/include/tab_cnv.h +19 -0
- package/src/platforms/genesis/lib/sgdk/include/task.h +77 -0
- package/src/platforms/genesis/lib/sgdk/include/task_cst.h +33 -0
- package/src/platforms/genesis/lib/sgdk/include/timer.h +132 -0
- package/src/platforms/genesis/lib/sgdk/include/tools.h +450 -0
- package/src/platforms/genesis/lib/sgdk/include/types.h +320 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp.h +1150 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_bg.h +723 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_pal.h +101 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_spr.h +448 -0
- package/src/platforms/genesis/lib/sgdk/include/vdp_tile.h +1136 -0
- package/src/platforms/genesis/lib/sgdk/include/vram.h +270 -0
- package/src/platforms/genesis/lib/sgdk/include/ym2612.h +87 -0
- package/src/platforms/genesis/lib/sgdk/include/z80_ctrl.h +420 -0
- package/src/platforms/genesis/lib/sgdk/libmd.seed.a +0 -0
- package/src/platforms/genesis/lib/sgdk/libmd.seed.hash +1 -0
- package/src/platforms/genesis/lib/sgdk/md.ld +120 -0
- package/src/platforms/genesis/lib/sgdk/music/demo.vgm +0 -0
- package/src/platforms/genesis/lib/sgdk/music/demo.xgc +0 -0
- package/src/platforms/genesis/lib/sgdk/music/demo.xgm +0 -0
- package/src/platforms/genesis/lib/sgdk/res/image/font_default.png +0 -0
- package/src/platforms/genesis/lib/sgdk/res/image/sgdk_logo.png +0 -0
- package/src/platforms/genesis/lib/sgdk/res/libres.h +10 -0
- package/src/platforms/genesis/lib/sgdk/res/libres.res +5 -0
- package/src/platforms/genesis/lib/sgdk/res/libres.s +166 -0
- package/src/platforms/genesis/lib/sgdk/res/sound/stop_xgm.bin +0 -0
- package/src/platforms/genesis/lib/sgdk/rom_header.c +33 -0
- package/src/platforms/genesis/lib/sgdk/sega.preprocessed.s +364 -0
- package/src/platforms/genesis/lib/sgdk/sega.s +365 -0
- package/src/platforms/genesis/lib/sgdk/src/bmp.c +1539 -0
- package/src/platforms/genesis/lib/sgdk/src/bmp_a.s +3477 -0
- package/src/platforms/genesis/lib/sgdk/src/boot/rom_header.c +33 -0
- package/src/platforms/genesis/lib/sgdk/src/boot/sega.s +365 -0
- package/src/platforms/genesis/lib/sgdk/src/dma.c +782 -0
- package/src/platforms/genesis/lib/sgdk/src/dma_a.s +23 -0
- package/src/platforms/genesis/lib/sgdk/src/error_a.s +376 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/console.c +490 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/everdrive.c +285 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/fat16.c +610 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/flash-save/README.md +112 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/flash-save/flash.c +300 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/flash-save/saveman.c +641 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/link_cable.c +1758 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/CHANGELOG.md +31 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/LICENSE.txt +17 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/README.md +18 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/data.z80 +148 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/define.z80 +173 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/doc/api-c.md +80 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/doc/format.md +132 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/doc/teradrive.md +33 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/fm.z80 +363 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/main.z80 +433 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/minimus.c +129 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/minimus_drv.s80 +17 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/psg.z80 +231 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/track.z80 +398 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/minimusic/util.z80 +98 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/16c550.c +84 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/README.md +849 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/comm.c +141 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/gamejolt.c +758 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/json.c +153 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/lsd.c +364 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/megawifi.c +1501 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/ssf_ed_pro.c +98 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/mw/ssf_ed_x7.c +67 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/serial/buffer.c +69 -0
- package/src/platforms/genesis/lib/sgdk/src/ext/serial/serial.c +158 -0
- package/src/platforms/genesis/lib/sgdk/src/joy.c +1361 -0
- package/src/platforms/genesis/lib/sgdk/src/kdebug.s +109 -0
- package/src/platforms/genesis/lib/sgdk/src/map.c +1915 -0
- package/src/platforms/genesis/lib/sgdk/src/mapper.c +280 -0
- package/src/platforms/genesis/lib/sgdk/src/maths.c +878 -0
- package/src/platforms/genesis/lib/sgdk/src/maths3D.c +480 -0
- package/src/platforms/genesis/lib/sgdk/src/maths3D_a.s +205 -0
- package/src/platforms/genesis/lib/sgdk/src/memory.c +760 -0
- package/src/platforms/genesis/lib/sgdk/src/memory_a.s +306 -0
- package/src/platforms/genesis/lib/sgdk/src/object.c +111 -0
- package/src/platforms/genesis/lib/sgdk/src/pal.c +484 -0
- package/src/platforms/genesis/lib/sgdk/src/pool.c +234 -0
- package/src/platforms/genesis/lib/sgdk/src/psg.c +82 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/drv_null.s80 +27 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/drv_xgm.s80 +3037 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/drv_dpcm2.s80 +984 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/drv_pcm.s80 +592 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/drv_pcm4.s80 +699 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/snd_dpcm2.c +172 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/snd_pcm.c +152 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/snd_pcm4.c +213 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/pcm/tab_vol.c +277 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/smp_null.s +22 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/smp_null_dpcm.s +15 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/sound.c +33 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm.c +683 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2.s80 +993 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_fct.i80 +611 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_mac.i80 +133 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_pcm_fct.i80 +114 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_pcm_mac.i80 +1444 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_psg_fct.i80 +491 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_psg_mac.i80 +43 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_ym_fct.i80 +1664 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2/drv_xgm2_ym_mac.i80 +295 -0
- package/src/platforms/genesis/lib/sgdk/src/snd/xgm2.c +1083 -0
- package/src/platforms/genesis/lib/sgdk/src/sprite_eng.c +2256 -0
- package/src/platforms/genesis/lib/sgdk/src/sprite_eng_legacy.c +2309 -0
- package/src/platforms/genesis/lib/sgdk/src/sram.c +30 -0
- package/src/platforms/genesis/lib/sgdk/src/sram_a.s +41 -0
- package/src/platforms/genesis/lib/sgdk/src/string.c +720 -0
- package/src/platforms/genesis/lib/sgdk/src/sys.c +1053 -0
- package/src/platforms/genesis/lib/sgdk/src/sys_a.s +74 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_cnv.c +129 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_log10.c +8201 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_log2.c +8201 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_sin.c +2058 -0
- package/src/platforms/genesis/lib/sgdk/src/tab_sqrt.c +8201 -0
- package/src/platforms/genesis/lib/sgdk/src/task.s +148 -0
- package/src/platforms/genesis/lib/sgdk/src/timer.c +201 -0
- package/src/platforms/genesis/lib/sgdk/src/tools.c +1299 -0
- package/src/platforms/genesis/lib/sgdk/src/tools_a.s +979 -0
- package/src/platforms/genesis/lib/sgdk/src/types.c +18 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp.c +1060 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_bg.c +511 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_spr.c +322 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_tile.c +1011 -0
- package/src/platforms/genesis/lib/sgdk/src/vdp_tile_a.s +68 -0
- package/src/platforms/genesis/lib/sgdk/src/vram.c +273 -0
- package/src/platforms/genesis/lib/sgdk/src/ym2612.c +175 -0
- package/src/platforms/genesis/lib/sgdk/src/z80_ctrl.c +334 -0
- package/src/platforms/genesis/lib/sprite_table.s +129 -0
- package/src/platforms/genesis/lib/vblank_wait.s +73 -0
- package/src/platforms/genesis/lib/vdp_init.s +85 -0
- package/src/platforms/genesis/lib/wram.s +88 -0
- package/src/platforms/genesis/lib/z80_bootstrap.s +102 -0
- package/src/platforms/genesis/vdp.js +495 -0
- package/src/platforms/gg/MENTAL_MODEL.md +155 -0
- package/src/platforms/gg/TROUBLESHOOTING.md +91 -0
- package/src/platforms/gg/UPSTREAM_SOURCES.md +36 -0
- package/src/platforms/gg/lib/c/gg_crt0.s +112 -0
- package/src/platforms/gg/lib/c/gg_hw.h +62 -0
- package/src/platforms/gg/lib/c/gg_music.c +155 -0
- package/src/platforms/gg/lib/c/gg_music.h +89 -0
- package/src/platforms/gg/lib/c/gg_sfx.c +82 -0
- package/src/platforms/gg/lib/c/gg_sfx.h +40 -0
- package/src/platforms/gg/lib/c/joypad_read.c +22 -0
- package/src/platforms/gg/lib/c/load_palette.c +20 -0
- package/src/platforms/gg/lib/c/load_tiles.c +32 -0
- package/src/platforms/gg/lib/c/sprite_table.c +60 -0
- package/src/platforms/gg/lib/c/vblank_wait.c +10 -0
- package/src/platforms/gg/lib/c/vdp_init.c +58 -0
- package/src/platforms/index.js +7 -0
- package/src/platforms/lynx/MENTAL_MODEL.md +231 -0
- package/src/platforms/lynx/TROUBLESHOOTING.md +105 -0
- package/src/platforms/lynx/UPSTREAM_SOURCES.md +66 -0
- package/src/platforms/lynx/lib/c/lynx_music.c +63 -0
- package/src/platforms/lynx/lib/c/lynx_music.h +16 -0
- package/src/platforms/lynx/lib/c/lynx_sfx.c +147 -0
- package/src/platforms/lynx/lib/c/lynx_sfx.h +59 -0
- package/src/platforms/lynx/lib/cc65-src/bllhdr.s +18 -0
- package/src/platforms/lynx/lib/cc65-src/bootldr.s +195 -0
- package/src/platforms/lynx/lib/cc65-src/cgetc.s +69 -0
- package/src/platforms/lynx/lib/cc65-src/clock.s +87 -0
- package/src/platforms/lynx/lib/cc65-src/crt0.s +135 -0
- package/src/platforms/lynx/lib/cc65-src/defdir.s +29 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom.s +255 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom46.s +204 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom66.s +227 -0
- package/src/platforms/lynx/lib/cc65-src/eeprom86.s +236 -0
- package/src/platforms/lynx/lib/cc65-src/exec.s +34 -0
- package/src/platforms/lynx/lib/cc65-src/exehdr.s +27 -0
- package/src/platforms/lynx/lib/cc65-src/extzp.inc +23 -0
- package/src/platforms/lynx/lib/cc65-src/extzp.s +30 -0
- package/src/platforms/lynx/lib/cc65-src/irq.s +45 -0
- package/src/platforms/lynx/lib/cc65-src/joy/lynx-stdjoy.s +93 -0
- package/src/platforms/lynx/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/kbhit.s +56 -0
- package/src/platforms/lynx/lib/cc65-src/libref.s +9 -0
- package/src/platforms/lynx/lib/cc65-src/load.s +41 -0
- package/src/platforms/lynx/lib/cc65-src/lseek.s +58 -0
- package/src/platforms/lynx/lib/cc65-src/lynx-cart.s +98 -0
- package/src/platforms/lynx/lib/cc65-src/lynx-snd.s +1270 -0
- package/src/platforms/lynx/lib/cc65-src/mainargs.s +24 -0
- package/src/platforms/lynx/lib/cc65-src/open.s +136 -0
- package/src/platforms/lynx/lib/cc65-src/oserror.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/read.s +44 -0
- package/src/platforms/lynx/lib/cc65-src/ser/lynx-comlynx.s +404 -0
- package/src/platforms/lynx/lib/cc65-src/ser_stat_stddrv.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/sysuname.s +39 -0
- package/src/platforms/lynx/lib/cc65-src/tgi/lynx-160-102-16.s +1075 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_colors.s +9 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_irq.s +11 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_stat_stddrv.s +14 -0
- package/src/platforms/lynx/lib/cc65-src/tgi_stddrv.s +13 -0
- package/src/platforms/lynx/lib/cc65-src/uploader.s +81 -0
- package/src/platforms/nes/MENTAL_MODEL.md +301 -0
- package/src/platforms/nes/TROUBLESHOOTING.md +321 -0
- package/src/platforms/nes/UPSTREAM_SOURCES.md +31 -0
- package/src/platforms/nes/image-to-chr.js +195 -0
- package/src/platforms/nes/image-to-tilemap.js +415 -0
- package/src/platforms/nes/lib/README.md +40 -0
- package/src/platforms/nes/lib/asm/LICENSE-FAMITONE +40 -0
- package/src/platforms/nes/lib/asm/chr_ram_header.s +32 -0
- package/src/platforms/nes/lib/asm/famitone2.s +1258 -0
- package/src/platforms/nes/lib/asm/famitone_bridge.s +50 -0
- package/src/platforms/nes/lib/asm/music_data.s +238 -0
- package/src/platforms/nes/lib/c/chr_ram_runtime_hello_sprite.c +81 -0
- package/src/platforms/nes/lib/c/chr_ram_runtime_hud_row.c +101 -0
- package/src/platforms/nes/lib/c/nes_runtime.c +347 -0
- package/src/platforms/nes/lib/c/nes_runtime.h +153 -0
- package/src/platforms/nes/lib/c/nmi_handler.c +51 -0
- package/src/platforms/nes/lib/c/nmi_trampoline.s +25 -0
- package/src/platforms/nes/lib/cc65-src/Makefile.inc +9 -0
- package/src/platforms/nes/lib/cc65-src/_scrsize.s +24 -0
- package/src/platforms/nes/lib/cc65-src/cclear.s +29 -0
- package/src/platforms/nes/lib/cc65-src/chline.s +31 -0
- package/src/platforms/nes/lib/cc65-src/clock.s +31 -0
- package/src/platforms/nes/lib/cc65-src/clrscr.s +72 -0
- package/src/platforms/nes/lib/cc65-src/color.s +68 -0
- package/src/platforms/nes/lib/cc65-src/cpeekc.s +37 -0
- package/src/platforms/nes/lib/cc65-src/cpeekcolor.s +8 -0
- package/src/platforms/nes/lib/cc65-src/cpeekrevers.s +37 -0
- package/src/platforms/nes/lib/cc65-src/cputc.s +95 -0
- package/src/platforms/nes/lib/cc65-src/crt0.s +180 -0
- package/src/platforms/nes/lib/cc65-src/cvline.s +31 -0
- package/src/platforms/nes/lib/cc65-src/get_tv.s +37 -0
- package/src/platforms/nes/lib/cc65-src/gotox.s +21 -0
- package/src/platforms/nes/lib/cc65-src/gotoxy.s +22 -0
- package/src/platforms/nes/lib/cc65-src/gotoy.s +22 -0
- package/src/platforms/nes/lib/cc65-src/irq.s +19 -0
- package/src/platforms/nes/lib/cc65-src/joy/nes-stdjoy.s +102 -0
- package/src/platforms/nes/lib/cc65-src/joy_stat_stddrv.s +14 -0
- package/src/platforms/nes/lib/cc65-src/libref.s +9 -0
- package/src/platforms/nes/lib/cc65-src/mainargs.s +24 -0
- package/src/platforms/nes/lib/cc65-src/neschar.s +4616 -0
- package/src/platforms/nes/lib/cc65-src/ppu.s +158 -0
- package/src/platforms/nes/lib/cc65-src/ppubuf.s +117 -0
- package/src/platforms/nes/lib/cc65-src/randomize.s +18 -0
- package/src/platforms/nes/lib/cc65-src/revers.s +27 -0
- package/src/platforms/nes/lib/cc65-src/setcursor.s +37 -0
- package/src/platforms/nes/lib/cc65-src/sysuname.s +39 -0
- package/src/platforms/nes/lib/cc65-src/tgi/nes-64-56-2.s +480 -0
- package/src/platforms/nes/lib/cc65-src/tgi_stat_stddrv.s +14 -0
- package/src/platforms/nes/lib/cc65-src/tgi_stddrv.s +13 -0
- package/src/platforms/nes/lib/cc65-src/waitvsync.s +18 -0
- package/src/platforms/nes/lib/cc65-src/wherex.s +19 -0
- package/src/platforms/nes/lib/cc65-src/wherey.s +19 -0
- package/src/platforms/nes/lib/clear_nametable.s +38 -0
- package/src/platforms/nes/lib/clear_oam.s +18 -0
- package/src/platforms/nes/lib/load_palette.s +31 -0
- package/src/platforms/nes/lib/nmi_safe.s +65 -0
- package/src/platforms/nes/lib/oam_dma.s +16 -0
- package/src/platforms/nes/lib/read_pad.s +46 -0
- package/src/platforms/nes/lib/reset.s +46 -0
- package/src/platforms/nes/lib/sprite_table_populate.s +75 -0
- package/src/platforms/nes/lib/wait_vblank.s +12 -0
- package/src/platforms/nes/palette.js +39 -0
- package/src/platforms/nes/ppu.js +372 -0
- package/src/platforms/sms/MENTAL_MODEL.md +267 -0
- package/src/platforms/sms/TROUBLESHOOTING.md +124 -0
- package/src/platforms/sms/UPSTREAM_SOURCES.md +29 -0
- package/src/platforms/sms/image-to-tilemap.js +260 -0
- package/src/platforms/sms/lib/README.md +117 -0
- package/src/platforms/sms/lib/c/joypad_read.c +33 -0
- package/src/platforms/sms/lib/c/load_palette.c +24 -0
- package/src/platforms/sms/lib/c/load_tiles.c +32 -0
- package/src/platforms/sms/lib/c/sms_crt0.s +101 -0
- package/src/platforms/sms/lib/c/sms_hw.h +53 -0
- package/src/platforms/sms/lib/c/sms_music.c +178 -0
- package/src/platforms/sms/lib/c/sms_music.h +50 -0
- package/src/platforms/sms/lib/c/sms_sfx.c +82 -0
- package/src/platforms/sms/lib/c/sms_sfx.h +40 -0
- package/src/platforms/sms/lib/c/sprite_table.c +60 -0
- package/src/platforms/sms/lib/c/vblank_wait.c +10 -0
- package/src/platforms/sms/lib/c/vdp_init.c +58 -0
- package/src/platforms/sms/lib/header.s +33 -0
- package/src/platforms/sms/lib/joypad_read.s +40 -0
- package/src/platforms/sms/lib/load_palette.s +30 -0
- package/src/platforms/sms/lib/load_tiles.s +50 -0
- package/src/platforms/sms/lib/sprite_table.s +44 -0
- package/src/platforms/sms/lib/vblank_wait.s +36 -0
- package/src/platforms/sms/lib/vdp_init.s +47 -0
- package/src/platforms/sms/vdp.js +530 -0
- package/src/platforms/snes/MENTAL_MODEL.md +275 -0
- package/src/platforms/snes/TROUBLESHOOTING.md +208 -0
- package/src/platforms/snes/UPSTREAM_SOURCES.md +50 -0
- package/src/platforms/snes/brr.js +208 -0
- package/src/platforms/snes/image-to-tilemap.js +227 -0
- package/src/platforms/snes/lib/audio/apu_blob.asm +228 -0
- package/src/platforms/snes/lib/audio/apu_blob.bin +0 -0
- package/src/platforms/snes/lib/audio/explosion.brr +0 -0
- package/src/platforms/snes/lib/audio/sample_bank.bin +0 -0
- package/src/platforms/snes/lib/audio/shoot.brr +0 -0
- package/src/platforms/snes/lib/audio/spc_driver.asm +241 -0
- package/src/platforms/snes/lib/audio_pipeline.asm +62 -0
- package/src/platforms/snes/lib/c/crt0.asm +125 -0
- package/src/platforms/snes/lib/c/hdr.asm +50 -0
- package/src/platforms/snes/lib/c/snes_sfx.c +116 -0
- package/src/platforms/snes/lib/c/snes_sfx.h +96 -0
- package/src/platforms/snes/lib/c/snes_sfx_data.asm +25 -0
- package/src/platforms/snes/lib/cgram_upload.asm +43 -0
- package/src/platforms/snes/lib/lorom_header.asm +47 -0
- package/src/platforms/snes/lib/lorom_multibank.asm +66 -0
- package/src/platforms/snes/lib/nmi_safe.asm +77 -0
- package/src/platforms/snes/lib/oam_upload.asm +45 -0
- package/src/platforms/snes/lib/pad_read.asm +64 -0
- package/src/platforms/snes/lib/pvsneslib/LICENSE +21 -0
- package/src/platforms/snes/lib/pvsneslib/include/ctype.h +6 -0
- package/src/platforms/snes/lib/pvsneslib/include/float.h +4 -0
- package/src/platforms/snes/lib/pvsneslib/include/hdr.asm +47 -0
- package/src/platforms/snes/lib/pvsneslib/include/limits.h +13 -0
- package/src/platforms/snes/lib/pvsneslib/include/math.h +10 -0
- package/src/platforms/snes/lib/pvsneslib/include/setjmp.h +4 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/background.h +396 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/console.h +188 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/dma.h +381 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/input.h +289 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/interrupt.h +264 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/libversion.h +10 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/lzss.h +43 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/map.h +113 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/object.h +234 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/pixel.h +53 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/scores.h +66 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/snestypes.h +65 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/sound.h +245 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/sprite.h +456 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes/video.h +465 -0
- package/src/platforms/snes/lib/pvsneslib/include/snes.h +190 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdarg.h +28 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdbool.h +53 -0
- package/src/platforms/snes/lib/pvsneslib/include/stddef.h +27 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdint.h +7 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdio.h +9 -0
- package/src/platforms/snes/lib/pvsneslib/include/stdlib.h +13 -0
- package/src/platforms/snes/lib/pvsneslib/include/string.h +19 -0
- package/src/platforms/snes/lib/pvsneslib/include/strings.h +5 -0
- package/src/platforms/snes/lib/pvsneslib/source/Makefile +87 -0
- package/src/platforms/snes/lib/pvsneslib/source/backgrounds.asm +834 -0
- package/src/platforms/snes/lib/pvsneslib/source/consoles.asm +1028 -0
- package/src/platforms/snes/lib/pvsneslib/source/crt0_snes.asm +329 -0
- package/src/platforms/snes/lib/pvsneslib/source/dmas.asm +1275 -0
- package/src/platforms/snes/lib/pvsneslib/source/hdr.asm +56 -0
- package/src/platforms/snes/lib/pvsneslib/source/input.asm +445 -0
- package/src/platforms/snes/lib/pvsneslib/source/libc.asm +485 -0
- package/src/platforms/snes/lib/pvsneslib/source/libc_c.c +1214 -0
- package/src/platforms/snes/lib/pvsneslib/source/libm.asm +510 -0
- package/src/platforms/snes/lib/pvsneslib/source/libtcc.asm +374 -0
- package/src/platforms/snes/lib/pvsneslib/source/lzsss.asm +256 -0
- package/src/platforms/snes/lib/pvsneslib/source/maps.asm +1078 -0
- package/src/platforms/snes/lib/pvsneslib/source/objects.asm +2881 -0
- package/src/platforms/snes/lib/pvsneslib/source/scores.asm +226 -0
- package/src/platforms/snes/lib/pvsneslib/source/sm_spc.asm +187 -0
- package/src/platforms/snes/lib/pvsneslib/source/snesmodwla.asm +1186 -0
- package/src/platforms/snes/lib/pvsneslib/source/sounds.asm +273 -0
- package/src/platforms/snes/lib/pvsneslib/source/sprites.asm +3946 -0
- package/src/platforms/snes/lib/pvsneslib/source/vblank.asm +917 -0
- package/src/platforms/snes/lib/pvsneslib/source/videos.asm +1137 -0
- package/src/platforms/snes/lib/reset_init.asm +31 -0
- package/src/platforms/snes/lib/sprite_table_populate.asm +122 -0
- package/src/platforms/snes/lib/vram_dma_upload.asm +42 -0
- package/src/platforms/snes/ppu.js +606 -0
- package/src/playtest/playtest.js +612 -0
- package/src/rom-id/identifier.js +421 -0
- package/src/rom-id/patch.js +217 -0
- package/src/toolchains/_worker/pool.js +253 -0
- package/src/toolchains/_worker/run.js +78 -0
- package/src/toolchains/_worker/wasm-worker.js +233 -0
- package/src/toolchains/arm-none-eabi-gcc/gcc.js +208 -0
- package/src/toolchains/asar/asar.js +542 -0
- package/src/toolchains/assemble-snippet.js +256 -0
- package/src/toolchains/cc65/cc65.js +395 -0
- package/src/toolchains/cc65/da65.js +119 -0
- package/src/toolchains/cc65/dbgparse.js +274 -0
- package/src/toolchains/cc65/preset-resolver.js +59 -0
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +79 -0
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.crt0.s +178 -0
- package/src/toolchains/cc65/presets/nes/chr-ram.cfg +76 -0
- package/src/toolchains/cc65/presets/nes/chr-ram.crt0.s +106 -0
- package/src/toolchains/common/ar.js +121 -0
- package/src/toolchains/common/sdk-cache.js +116 -0
- package/src/toolchains/common/symbols.js +139 -0
- package/src/toolchains/dasm/dasm.js +96 -0
- package/src/toolchains/gba-c/gba-c.js +832 -0
- package/src/toolchains/genesis-c/README.md +61 -0
- package/src/toolchains/genesis-c/genesis-c.js +598 -0
- package/src/toolchains/index.js +727 -0
- package/src/toolchains/m68k-elf-gcc/gcc.js +220 -0
- package/src/toolchains/m68kdasm.js +438 -0
- package/src/toolchains/parse-errors.js +258 -0
- package/src/toolchains/registry.js +67 -0
- package/src/toolchains/rgbds/rgbds.js +144 -0
- package/src/toolchains/sdcc/preflight-lint.js +295 -0
- package/src/toolchains/sdcc/sdcc.js +519 -0
- package/src/toolchains/sjasm/sjasm.js +85 -0
- package/src/toolchains/sm83dasm.js +194 -0
- package/src/toolchains/snes-c/snes-c.js +409 -0
- package/src/toolchains/tcc816/tcc816.js +79 -0
- package/src/toolchains/vasm68k/vasm68k.js +138 -0
- package/src/toolchains/wladx/wladx.js +120 -0
- package/src/toolchains/z80dasm.js +303 -0
|
@@ -0,0 +1,1885 @@
|
|
|
1
|
+
// createProject — write a starter project directory the agent can iterate on.
|
|
2
|
+
//
|
|
3
|
+
// Policy (2026-05-25): no auto-injection at build time. createProject copies
|
|
4
|
+
// every file the template depends on (runtime, headers, crt0, linker .cfg)
|
|
5
|
+
// into the project directory. The project is then self-contained — any
|
|
6
|
+
// `buildSource` / `runSource` call points at the project's own files via
|
|
7
|
+
// sources/sourcesPaths/includePaths/crt0/linkerConfig args. If you take
|
|
8
|
+
// the project elsewhere and rebuild with cc65/sdcc directly, every byte
|
|
9
|
+
// that compiles is in the directory.
|
|
10
|
+
|
|
11
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
12
|
+
import { patchGbHeader } from "../../platforms/gb/lib/c/patch-header.js";
|
|
13
|
+
import { jsonContent, safeTool } from "../util.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Template manifest — each template lists:
|
|
17
|
+
* - main: path to the seed main.{c,s,asm} under examples/<platform>/
|
|
18
|
+
* - runtime: array of {src, dst} pairs to copy from src/platforms/<platform>/lib/
|
|
19
|
+
* - crt0: optional {src, dst} for a custom crt0 (asm)
|
|
20
|
+
* - linkerConfig: optional {src, dst} for the ld65 .cfg or similar
|
|
21
|
+
* - buildHint: string telling the agent what build args to use
|
|
22
|
+
*/
|
|
23
|
+
const TEMPLATES = {
|
|
24
|
+
nes: {
|
|
25
|
+
default: {
|
|
26
|
+
main: "templates/default.c",
|
|
27
|
+
runtime: [
|
|
28
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
29
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
30
|
+
],
|
|
31
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
32
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
33
|
+
lang: "C (cc65)",
|
|
34
|
+
ext: ".nes",
|
|
35
|
+
describe: "Minimal palette-cycle hello-world. Backdrop color flashes through 4 shades.",
|
|
36
|
+
},
|
|
37
|
+
hello_sprite: {
|
|
38
|
+
main: "templates/hello_sprite.c",
|
|
39
|
+
runtime: [
|
|
40
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
41
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
42
|
+
],
|
|
43
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
44
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
45
|
+
lang: "C (cc65)",
|
|
46
|
+
ext: ".nes",
|
|
47
|
+
describe: "Single sprite + d-pad movement. Boot order + palette + tile upload all explicit.",
|
|
48
|
+
},
|
|
49
|
+
tile_engine: {
|
|
50
|
+
main: "templates/tile_engine.c",
|
|
51
|
+
runtime: [
|
|
52
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
53
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
54
|
+
],
|
|
55
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
56
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
57
|
+
lang: "C (cc65)",
|
|
58
|
+
ext: ".nes",
|
|
59
|
+
describe: "32×30 tile map + room transitions. Walls, doors, collision, multi-screen.",
|
|
60
|
+
},
|
|
61
|
+
/* ── Genre scaffolds (R14, 2026-05-26) ── */
|
|
62
|
+
shmup: {
|
|
63
|
+
main: "templates/shmup.c",
|
|
64
|
+
runtime: [
|
|
65
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
66
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
67
|
+
],
|
|
68
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
69
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
70
|
+
lang: "C (cc65)",
|
|
71
|
+
ext: ".nes",
|
|
72
|
+
describe: "Vertical-scrolling shooter. Player + 4 bullets + 4 enemies, AABB collision, score counter, wave spawner.",
|
|
73
|
+
},
|
|
74
|
+
platformer: {
|
|
75
|
+
main: "templates/platformer.c",
|
|
76
|
+
runtime: [
|
|
77
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
78
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
79
|
+
],
|
|
80
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
81
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
82
|
+
lang: "C (cc65)",
|
|
83
|
+
ext: ".nes",
|
|
84
|
+
describe: "Single-screen platformer — also the starting point for a SIDE-SCROLLER (same genre here). Gravity + jump physics (fixed-point Y), 5 platforms, land-on-top collision, respawn on fall. This is the jump/gravity/collision core; it does NOT scroll as shipped. To make it scroll on NES you add a camera + world coords and write new nametable columns across the mirroring boundary as the camera advances (and usually a sprite-0/IRQ split for a fixed HUD) — see the NES MENTAL_MODEL.md scrolling section.",
|
|
85
|
+
},
|
|
86
|
+
puzzle: {
|
|
87
|
+
main: "templates/puzzle.c",
|
|
88
|
+
runtime: [
|
|
89
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
90
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
91
|
+
],
|
|
92
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
93
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
94
|
+
lang: "C (cc65)",
|
|
95
|
+
ext: ".nes",
|
|
96
|
+
describe: "Match-3 falling-block puzzle. 6×12 grid, 1×3 active piece (3 colors), rotate via A, soft-drop on DOWN, horizontal-triple clear.",
|
|
97
|
+
},
|
|
98
|
+
sports: {
|
|
99
|
+
main: "templates/sports.c",
|
|
100
|
+
runtime: [
|
|
101
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
102
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
103
|
+
],
|
|
104
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
105
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
106
|
+
lang: "C (cc65)",
|
|
107
|
+
ext: ".nes",
|
|
108
|
+
describe: "Two-player Pong. Port 0 = left paddle, port 1 = right paddle (AI fallback when no 2nd controller). Per-side score 0-9, ball bounces off paddles + walls. Designed for the playtest window with two USB controllers.",
|
|
109
|
+
},
|
|
110
|
+
racing: {
|
|
111
|
+
main: "templates/racing.c",
|
|
112
|
+
runtime: [
|
|
113
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
114
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
115
|
+
],
|
|
116
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
117
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
118
|
+
lang: "C (cc65)",
|
|
119
|
+
ext: ".nes",
|
|
120
|
+
describe: "Endless top-down lane racer. 3 lanes, 4 obstacle slots, LEFT/RIGHT switches lanes. Speed grows with score; collision triggers a 60-frame freeze then reset.",
|
|
121
|
+
},
|
|
122
|
+
/* R44 (2026-05-26): bundled-driver music demo. FamiTone2 engine +
|
|
123
|
+
* cc65 bridge + example track, all ship as source under lib/asm. */
|
|
124
|
+
music_demo: {
|
|
125
|
+
main: "templates/music_demo.c",
|
|
126
|
+
runtime: [
|
|
127
|
+
{ src: "lib/c/nes_runtime.h", dst: "nes_runtime.h" },
|
|
128
|
+
{ src: "lib/c/nes_runtime.c", dst: "nes_runtime.c" },
|
|
129
|
+
{ src: "lib/asm/famitone2.s", dst: "famitone2.s" },
|
|
130
|
+
{ src: "lib/asm/famitone_bridge.s", dst: "famitone_bridge.s" },
|
|
131
|
+
{ src: "lib/asm/music_data.s", dst: "music_data.s" },
|
|
132
|
+
{ src: "lib/asm/LICENSE-FAMITONE", dst: "LICENSE-FAMITONE" },
|
|
133
|
+
],
|
|
134
|
+
crt0: { presetSrc: "presets/nes/chr-ram-runtime.crt0.s", dst: "chr-ram-runtime.crt0.s" },
|
|
135
|
+
linkerConfig: { presetSrc: "presets/nes/chr-ram-runtime.cfg", dst: "chr-ram-runtime.cfg" },
|
|
136
|
+
lang: "C (cc65)",
|
|
137
|
+
ext: ".nes",
|
|
138
|
+
describe: "Continuous multi-channel music demo using bundled FamiTone2 (Shiru, public domain). Engine .s + bridge .s + example track .s ship as sources alongside main.c. Swap music_data.s for your own song (text2data converts FamiTracker .txt exports).",
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
gb: {
|
|
142
|
+
default: {
|
|
143
|
+
main: "templates/default.c",
|
|
144
|
+
runtime: [
|
|
145
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
146
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
147
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
148
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
149
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
150
|
+
],
|
|
151
|
+
lang: "C (SDCC sm83)",
|
|
152
|
+
ext: ".gb",
|
|
153
|
+
describe: "Minimal palette-cycle hello-world.",
|
|
154
|
+
},
|
|
155
|
+
hello_sprite: {
|
|
156
|
+
main: "templates/hello_sprite.c",
|
|
157
|
+
runtime: [
|
|
158
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
159
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
160
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
161
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
162
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
163
|
+
],
|
|
164
|
+
lang: "C (SDCC sm83)",
|
|
165
|
+
ext: ".gb",
|
|
166
|
+
describe: "Single sprite + d-pad movement.",
|
|
167
|
+
},
|
|
168
|
+
tile_engine: {
|
|
169
|
+
main: "templates/tile_engine.c",
|
|
170
|
+
runtime: [
|
|
171
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
172
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
173
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
174
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
175
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
176
|
+
],
|
|
177
|
+
lang: "C (SDCC sm83)",
|
|
178
|
+
ext: ".gb",
|
|
179
|
+
describe: "20×18 tile map + room transitions.",
|
|
180
|
+
},
|
|
181
|
+
shmup: {
|
|
182
|
+
main: "templates/shmup.c",
|
|
183
|
+
runtime: [
|
|
184
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
185
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
186
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
187
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
188
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
189
|
+
],
|
|
190
|
+
lang: "C (SDCC sm83)",
|
|
191
|
+
ext: ".gb",
|
|
192
|
+
describe: "Vertical-shmup scaffold for GB. Player ship + 4 bullets + 4 enemies, wave spawner, AABB collision, score (in WRAM). OAM slots 0/1-4/5-8 preallocated.",
|
|
193
|
+
},
|
|
194
|
+
platformer: {
|
|
195
|
+
main: "templates/platformer.c",
|
|
196
|
+
runtime: [
|
|
197
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
198
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
199
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
200
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
201
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
202
|
+
],
|
|
203
|
+
lang: "C (SDCC sm83)",
|
|
204
|
+
ext: ".gb",
|
|
205
|
+
describe: "SIDE-SCROLLING platformer for GB. Subpixel gravity + jump + land-on-top collision against a static platform list spread across a 256-px world (the full wrapping BG map). The camera follows the player and scrolls the BG via SCX each frame; the player sprite draws in screen space (worldX - camX). A=jump, d-pad=move. The world here is one BG map wide (no streaming) — for a wider world, stream a new tile column into the 32-wide BG map each time the camera crosses an 8px boundary (window for a fixed HUD). See the GB MENTAL_MODEL.md 'Horizontal scrolling'. Extend with enemies, goals, pickups.",
|
|
206
|
+
},
|
|
207
|
+
puzzle: {
|
|
208
|
+
main: "templates/puzzle.c",
|
|
209
|
+
runtime: [
|
|
210
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
211
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
212
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
213
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
214
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
215
|
+
],
|
|
216
|
+
lang: "C (SDCC sm83)",
|
|
217
|
+
ext: ".gb",
|
|
218
|
+
describe: "Match-3 falling-block puzzle scaffold for GB. 6×12 grid rendered via BG tilemap, 1×3 active piece (3 colours via 3 BG tile shapes), rotate via A, hard-drop on START, horizontal-triple clear.",
|
|
219
|
+
},
|
|
220
|
+
sports: {
|
|
221
|
+
main: "templates/sports.c",
|
|
222
|
+
runtime: [
|
|
223
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
224
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
225
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
226
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
227
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
228
|
+
],
|
|
229
|
+
lang: "C (SDCC sm83)",
|
|
230
|
+
ext: ".gb",
|
|
231
|
+
describe: "Player-vs-AI Pong. Game Boy hardware has only one controller port, so this is human vs chase-the-ball AI by design. Same gameplay shape as the 2P versions on platforms with two ports.",
|
|
232
|
+
},
|
|
233
|
+
racing: {
|
|
234
|
+
main: "templates/racing.c",
|
|
235
|
+
runtime: [
|
|
236
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
237
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
238
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
239
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
240
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
241
|
+
],
|
|
242
|
+
lang: "C (SDCC sm83)",
|
|
243
|
+
ext: ".gb",
|
|
244
|
+
describe: "Endless 3-lane top-down racer. LEFT/RIGHT switches lanes, obstacle speed grows with score, 60-frame freeze + auto-reset on collision.",
|
|
245
|
+
},
|
|
246
|
+
/* R45 — hUGEDriver music demo. Ships a compact SDCC-native music
|
|
247
|
+
* driver with the upstream hUGEDriver function surface plus a
|
|
248
|
+
* hand-authored sample song. Source-visible: the full upstream
|
|
249
|
+
* RGBDS asm is bundled alongside as hUGEDriver.upstream.asm. */
|
|
250
|
+
music_demo: {
|
|
251
|
+
main: "templates/music_demo.c",
|
|
252
|
+
runtime: [
|
|
253
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
254
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
255
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
256
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
257
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
258
|
+
{ src: "lib/c/hUGEDriver.h", dst: "hUGEDriver.h" },
|
|
259
|
+
{ src: "lib/c/hUGEDriver.c", dst: "hUGEDriver.c" },
|
|
260
|
+
{ src: "lib/c/song_data.c", dst: "song_data.c" },
|
|
261
|
+
{ src: "lib/c/hUGEDriver.upstream.asm",dst: "hUGEDriver.upstream.asm" },
|
|
262
|
+
{ src: "lib/c/LICENSE-HUGEDRIVER", dst: "LICENSE-HUGEDRIVER" },
|
|
263
|
+
],
|
|
264
|
+
lang: "C (SDCC sm83)",
|
|
265
|
+
ext: ".gb",
|
|
266
|
+
describe: "Music playback via hUGEDriver. Compact SDCC-native rewrite of the upstream hUGEDriver interface (public domain) + a 4-pattern, two-channel hand-authored sample song. Driver advances on every vblank via hUGE_dosound().",
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
// R37: GBC has its own scaffold tree at examples/gbc/templates/ +
|
|
271
|
+
// src/platforms/gbc/lib/c/. Same runtime files as GB (the APU + Z80 +
|
|
272
|
+
// most VRAM layout are identical) but the scaffolds add visible
|
|
273
|
+
// CGB-mode color via BCPS/BCPD palette writes. Output ext is .gbc so
|
|
274
|
+
// patchGbHeader flips $0143 = $80 → CGB-enhanced mode.
|
|
275
|
+
const GBC_RUNTIME = [
|
|
276
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
277
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
278
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
279
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
280
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
281
|
+
];
|
|
282
|
+
const GBC_LANG = "C (SDCC sm83, GBC color)";
|
|
283
|
+
TEMPLATES.gbc = {
|
|
284
|
+
default: {
|
|
285
|
+
main: "templates/default.c", runtime: GBC_RUNTIME,
|
|
286
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
287
|
+
describe: "Minimal GBC starter. Same shape as the GB default but ROM extension .gbc — patchGbHeader sets $0143=$80 so gambatte boots in CGB mode.",
|
|
288
|
+
},
|
|
289
|
+
hello_sprite: {
|
|
290
|
+
main: "templates/hello_sprite.c", runtime: GBC_RUNTIME,
|
|
291
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
292
|
+
describe: "Single sprite + d-pad on Game Boy Color. Sets a real CGB color palette via BCPS/BCPD (purple backdrop) so you can SEE that CGB mode is active.",
|
|
293
|
+
},
|
|
294
|
+
tile_engine: {
|
|
295
|
+
main: "templates/tile_engine.c", runtime: GBC_RUNTIME,
|
|
296
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
297
|
+
describe: "20×18 tile world on GBC. BG palette upload via BCPS/BCPD + sprite palette via OCPS/OCPD.",
|
|
298
|
+
},
|
|
299
|
+
shmup: {
|
|
300
|
+
main: "templates/shmup.c", runtime: GBC_RUNTIME,
|
|
301
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
302
|
+
describe: "Vertical-shmup for GBC. Colorful sprites (white ship, yellow bullets, red enemies) and a starfield BG palette via BCPS/BCPD. Same sfx wiring as GB (sound_play_tone/noise).",
|
|
303
|
+
},
|
|
304
|
+
platformer: {
|
|
305
|
+
main: "templates/platformer.c", runtime: GBC_RUNTIME,
|
|
306
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
307
|
+
describe: "SIDE-SCROLLING platformer for GBC. Full CGB color palette (BG + sprite via BCPS/OCPS) over the GB side-scroller core: subpixel gravity + jump + land-on-top collision against platforms across a 256-px world (the wrapping BG map). The camera follows the player and scrolls the BG via SCX; the player sprite draws in screen space. A=jump, d-pad=move. One BG map wide (no streaming) — for a wider world, stream a new BG-map column on each 8px camera step (window for a fixed HUD). See the GBC MENTAL_MODEL.md 'Horizontal scrolling'. Extend with enemies, goals, pickups.",
|
|
308
|
+
},
|
|
309
|
+
puzzle: {
|
|
310
|
+
main: "templates/puzzle.c", runtime: GBC_RUNTIME,
|
|
311
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
312
|
+
describe: "Match-3 puzzle for GBC. Three colored cells (BG palette via BCPS/BCPD), rotate + soft-drop + hard-drop + triple-clear chime.",
|
|
313
|
+
},
|
|
314
|
+
sports: {
|
|
315
|
+
main: "templates/sports.c", runtime: GBC_RUNTIME,
|
|
316
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
317
|
+
describe: "Pong for GBC. Player-vs-AI (one controller). Court green BG + colored paddles + paddle-hit sfx.",
|
|
318
|
+
},
|
|
319
|
+
racing: {
|
|
320
|
+
main: "templates/racing.c", runtime: GBC_RUNTIME,
|
|
321
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
322
|
+
describe: "3-lane racer for GBC. Asphalt BG palette + colored player/enemy cars + lane-switch + crash sfx.",
|
|
323
|
+
},
|
|
324
|
+
/* R45 — same hUGEDriver music_demo as GB, with BCPS/BCPD palette
|
|
325
|
+
* writes so it boots in CGB mode (gambatte flips on .gbc + $0143=$80).
|
|
326
|
+
* The APU is identical between DMG and CGB so the driver code is
|
|
327
|
+
* unchanged — only the visual palette path differs. */
|
|
328
|
+
music_demo: {
|
|
329
|
+
main: "templates/music_demo.c",
|
|
330
|
+
runtime: [
|
|
331
|
+
{ src: "lib/c/gb_hardware.h", dst: "gb_hardware.h" },
|
|
332
|
+
{ src: "lib/c/gb_runtime.h", dst: "gb_runtime.h" },
|
|
333
|
+
{ src: "lib/c/gb_runtime.c", dst: "gb_runtime.c" },
|
|
334
|
+
{ src: "lib/c/gb_crt0.s", dst: "gb_crt0.s" },
|
|
335
|
+
{ src: "lib/c/patch-header.js", dst: "patch-header.js" },
|
|
336
|
+
{ src: "lib/c/hUGEDriver.h", dst: "hUGEDriver.h" },
|
|
337
|
+
{ src: "lib/c/hUGEDriver.c", dst: "hUGEDriver.c" },
|
|
338
|
+
{ src: "lib/c/song_data.c", dst: "song_data.c" },
|
|
339
|
+
{ src: "lib/c/hUGEDriver.upstream.asm",dst: "hUGEDriver.upstream.asm" },
|
|
340
|
+
{ src: "lib/c/LICENSE-HUGEDRIVER", dst: "LICENSE-HUGEDRIVER" },
|
|
341
|
+
],
|
|
342
|
+
lang: GBC_LANG, ext: ".gbc",
|
|
343
|
+
describe: "Music playback on GBC. Compact SDCC-native rewrite of the upstream hUGEDriver interface (public domain) + bundled sample song. Background palette cycles via BCPS/BCPD to confirm CGB mode is active.",
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// ── SDCC z80 platforms (SMS / GG / MSX / Coleco) ─────────────────────
|
|
348
|
+
// They share the same hardware-port idiom (__sfr __at) but differ in
|
|
349
|
+
// register addresses / cart layout. SMS has a fleshed-out lib/c/sms_hw.h
|
|
350
|
+
// + working main.c we use directly; the other three reuse the same
|
|
351
|
+
// example main.c shape and get a minimal __sfr declaration sketch.
|
|
352
|
+
// R22: the modular SMS runtime under src/platforms/sms/lib/c/ is what
|
|
353
|
+
// hello_sprite + tile_engine + shmup + platformer + puzzle templates link
|
|
354
|
+
// against. Factored to a constant so adding a new template is a one-line
|
|
355
|
+
// change at the bottom.
|
|
356
|
+
const SMS_RUNTIME = [
|
|
357
|
+
{ src: "lib/c/sms_hw.h", dst: "sms_hw.h" },
|
|
358
|
+
{ src: "lib/c/vdp_init.c", dst: "vdp_init.c" },
|
|
359
|
+
{ src: "lib/c/load_palette.c", dst: "load_palette.c" },
|
|
360
|
+
{ src: "lib/c/load_tiles.c", dst: "load_tiles.c" },
|
|
361
|
+
{ src: "lib/c/vblank_wait.c", dst: "vblank_wait.c" },
|
|
362
|
+
{ src: "lib/c/joypad_read.c", dst: "joypad_read.c" },
|
|
363
|
+
{ src: "lib/c/sprite_table.c", dst: "sprite_table.c" },
|
|
364
|
+
// R35: PSG sound wrapper (SN76489 — same chip as Genesis PSG).
|
|
365
|
+
{ src: "lib/c/sms_sfx.h", dst: "sms_sfx.h" },
|
|
366
|
+
{ src: "lib/c/sms_sfx.c", dst: "sms_sfx.c" },
|
|
367
|
+
// R47: 3-voice tracker on top of the PSG (continuous music).
|
|
368
|
+
{ src: "lib/c/sms_music.h", dst: "sms_music.h" },
|
|
369
|
+
{ src: "lib/c/sms_music.c", dst: "sms_music.c" },
|
|
370
|
+
];
|
|
371
|
+
const SMS_LANG = "C (SDCC z80)";
|
|
372
|
+
|
|
373
|
+
TEMPLATES.sms = {
|
|
374
|
+
default: {
|
|
375
|
+
// Backward-compat: old `main.c` lives at the top of examples/sms/.
|
|
376
|
+
// New templates use the examples/sms/templates/ tree.
|
|
377
|
+
main: "main.c",
|
|
378
|
+
runtime: [
|
|
379
|
+
{ src: "lib/c/sms_hw.h", dst: "sms_hw.h" },
|
|
380
|
+
],
|
|
381
|
+
lang: SMS_LANG,
|
|
382
|
+
ext: ".sms",
|
|
383
|
+
describe: "Yellow 'H' tile on blue background. Press B1 to scroll BG by 1px/frame. Single-file project, inlines all VDP/joypad helpers.",
|
|
384
|
+
},
|
|
385
|
+
hello_sprite: {
|
|
386
|
+
main: "templates/hello_sprite.c",
|
|
387
|
+
runtime: SMS_RUNTIME,
|
|
388
|
+
lang: SMS_LANG,
|
|
389
|
+
ext: ".sms",
|
|
390
|
+
describe: "One sprite + d-pad. Uses bundled SMS runtime helpers (sms_vdp_init, sms_load_tiles, sms_sprite_*, sms_vblank_wait, sms_joypad_read). Multi-file project.",
|
|
391
|
+
},
|
|
392
|
+
tile_engine: {
|
|
393
|
+
main: "templates/tile_engine.c",
|
|
394
|
+
runtime: SMS_RUNTIME,
|
|
395
|
+
lang: SMS_LANG,
|
|
396
|
+
ext: ".sms",
|
|
397
|
+
describe: "32×24 tile world with walking player + AABB collision against solid tile indices. Demonstrates sms_set_tilemap_cell + the BG-plane name-table at $3800.",
|
|
398
|
+
},
|
|
399
|
+
shmup: {
|
|
400
|
+
main: "templates/shmup.c",
|
|
401
|
+
runtime: SMS_RUNTIME,
|
|
402
|
+
lang: SMS_LANG,
|
|
403
|
+
ext: ".sms",
|
|
404
|
+
describe: "Vertical-shmup scaffold for SMS. Player ship + 4 bullets + 4 enemies, wave spawner, AABB collisions, score (WRAM). Pre-allocated SAT slots 0/1-4/5-8.",
|
|
405
|
+
},
|
|
406
|
+
platformer: {
|
|
407
|
+
main: "templates/platformer.c",
|
|
408
|
+
runtime: SMS_RUNTIME,
|
|
409
|
+
lang: SMS_LANG,
|
|
410
|
+
ext: ".sms",
|
|
411
|
+
describe: "SIDE-SCROLLING platformer for SMS with COLUMN STREAMING. Subpixel gravity + jump + land-on-top collision against platforms across a 512-px world. The SMS name table is only 32 cells (256 px) and wraps, so the world is streamed: the camera follows the player, writes VDP R8 (-camX) for smooth pixel scroll, and each time camX crosses an 8-px boundary it rewrites the name-table column entering from the right (or left, on retreat) with the next world column. Player sprite draws in screen space. 1=jump, d-pad=move. For a fixed HUD, lock the top rows with VDP R0 bit 6. See the SMS MENTAL_MODEL.md 'Horizontal scrolling'. Extend with enemies, goals, pickups.",
|
|
412
|
+
},
|
|
413
|
+
puzzle: {
|
|
414
|
+
main: "templates/puzzle.c",
|
|
415
|
+
runtime: SMS_RUNTIME,
|
|
416
|
+
lang: SMS_LANG,
|
|
417
|
+
ext: ".sms",
|
|
418
|
+
describe: "Match-3 falling-block scaffold. 6×12 grid rendered via BG tilemap (three distinct tile shapes for R/G/B cells), 1×3 active piece, rotate via B1, hard-drop via B2.",
|
|
419
|
+
},
|
|
420
|
+
sports: {
|
|
421
|
+
main: "templates/sports.c",
|
|
422
|
+
runtime: SMS_RUNTIME,
|
|
423
|
+
lang: SMS_LANG,
|
|
424
|
+
ext: ".sms",
|
|
425
|
+
describe: "Two-player Pong on SMS. Both controller ports wired — sms_joypad_read for P1, sms_joypad_read_p2 for P2 (reassembles the awkward split-across-$DC/$DD bit layout). AI fallback when no second pad is plugged in.",
|
|
426
|
+
},
|
|
427
|
+
racing: {
|
|
428
|
+
main: "templates/racing.c",
|
|
429
|
+
runtime: SMS_RUNTIME,
|
|
430
|
+
lang: SMS_LANG,
|
|
431
|
+
ext: ".sms",
|
|
432
|
+
describe: "Endless 3-lane top-down racer. LEFT/RIGHT (edge-detected) switches lanes, obstacles slide down at speed = 2 + score/500 (capped at 4). 60-frame freeze + auto-reset on collision.",
|
|
433
|
+
},
|
|
434
|
+
shmup_2p: {
|
|
435
|
+
main: "templates/shmup_2p.c",
|
|
436
|
+
runtime: SMS_RUNTIME,
|
|
437
|
+
lang: SMS_LANG,
|
|
438
|
+
ext: ".sms",
|
|
439
|
+
describe: "Two-player competitive shmup on SMS via PORT_JOY_A + PORT_JOY_B (the new sms_joypad_read_p2 helper reassembles P2's split-port bits). Each player owns a 4-bullet pool + score; enemies are shared, first to hit scores.",
|
|
440
|
+
},
|
|
441
|
+
music_demo: {
|
|
442
|
+
main: "templates/music_demo.c",
|
|
443
|
+
runtime: SMS_RUNTIME,
|
|
444
|
+
lang: SMS_LANG,
|
|
445
|
+
ext: ".sms",
|
|
446
|
+
describe: "Continuous 3-voice music demo via sms_music.{h,c} — a tiny tracker on top of the SN76489 PSG. Voice 0 melody, voice 1 harmony, voice 2 bass. Noise channel stays free for game sfx. Source-visible: the parallel per-voice freq/length arrays in sms_music.c ARE the song.",
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
// R36: GG is tier-1 — full runtime + scaffolds + PSG sound, mirrors SMS.
|
|
450
|
+
// The genesis_plus_gx core handles GG natively. GG's visible viewport
|
|
451
|
+
// is 160×144 (centered in a 256×192 framebuffer); scaffolds render to
|
|
452
|
+
// the whole framebuffer but content positioning targets the center.
|
|
453
|
+
const GG_RUNTIME = [
|
|
454
|
+
{ src: "lib/c/gg_crt0.s", dst: "gg_crt0.s" },
|
|
455
|
+
{ src: "lib/c/gg_hw.h", dst: "gg_hw.h" },
|
|
456
|
+
{ src: "lib/c/vdp_init.c", dst: "vdp_init.c" },
|
|
457
|
+
{ src: "lib/c/load_palette.c", dst: "load_palette.c" },
|
|
458
|
+
{ src: "lib/c/load_tiles.c", dst: "load_tiles.c" },
|
|
459
|
+
{ src: "lib/c/vblank_wait.c", dst: "vblank_wait.c" },
|
|
460
|
+
{ src: "lib/c/joypad_read.c", dst: "joypad_read.c" },
|
|
461
|
+
{ src: "lib/c/sprite_table.c", dst: "sprite_table.c" },
|
|
462
|
+
{ src: "lib/c/gg_sfx.h", dst: "gg_sfx.h" },
|
|
463
|
+
{ src: "lib/c/gg_sfx.c", dst: "gg_sfx.c" },
|
|
464
|
+
{ src: "lib/c/gg_music.h", dst: "gg_music.h" },
|
|
465
|
+
{ src: "lib/c/gg_music.c", dst: "gg_music.c" },
|
|
466
|
+
];
|
|
467
|
+
/* For the single-file `default` template — it inlines its own VDP
|
|
468
|
+
* helpers, but it still needs gg_crt0.s for the boot vectors. SDCC's
|
|
469
|
+
* stock z80 crt0 traps rst $08 (used by its host runtime) which would
|
|
470
|
+
* halt any GG cartridge as soon as the VDP fires its first IRQ. */
|
|
471
|
+
const GG_DEFAULT_RUNTIME = [
|
|
472
|
+
{ src: "lib/c/gg_crt0.s", dst: "gg_crt0.s" },
|
|
473
|
+
];
|
|
474
|
+
const GG_LANG = "C (SDCC z80)";
|
|
475
|
+
|
|
476
|
+
TEMPLATES.gg = {
|
|
477
|
+
default: {
|
|
478
|
+
main: "templates/default.c",
|
|
479
|
+
runtime: GG_DEFAULT_RUNTIME,
|
|
480
|
+
lang: GG_LANG,
|
|
481
|
+
ext: ".gg",
|
|
482
|
+
describe: "Minimal GG starter: VDP init + yellow 'H' tile in the center of the 160×144 visible viewport + scroll-on-B1 input loop. Single source file (inlines VDP helpers) + the bundled gg_crt0.s. Use as the read-and-modify starting point when you're not sure what to build; switch to hello_sprite/tile_engine for multi-file projects.",
|
|
483
|
+
},
|
|
484
|
+
hello_sprite: {
|
|
485
|
+
main: "templates/hello_sprite.c",
|
|
486
|
+
runtime: GG_RUNTIME,
|
|
487
|
+
lang: GG_LANG,
|
|
488
|
+
ext: ".gg",
|
|
489
|
+
describe: "One sprite + d-pad. Uses bundled GG runtime helpers (gg_vdp_init, gg_load_tiles, gg_sprite_*, gg_vblank_wait, gg_joypad_read). Multi-file project. Boot chime via the bundled gg_sfx PSG wrapper.",
|
|
490
|
+
},
|
|
491
|
+
tile_engine: {
|
|
492
|
+
main: "templates/tile_engine.c",
|
|
493
|
+
runtime: GG_RUNTIME,
|
|
494
|
+
lang: GG_LANG,
|
|
495
|
+
ext: ".gg",
|
|
496
|
+
describe: "32×24 tile world with walking player + AABB collision against solid tile indices. BG name-table at $3800.",
|
|
497
|
+
},
|
|
498
|
+
shmup: {
|
|
499
|
+
main: "templates/shmup.c",
|
|
500
|
+
runtime: GG_RUNTIME,
|
|
501
|
+
lang: GG_LANG,
|
|
502
|
+
ext: ".gg",
|
|
503
|
+
describe: "Vertical-shmup scaffold for GG. Player ship + 4 bullets + 4 enemies, wave spawner, AABB collisions, score. Pew sfx on fire, boom on hit (PSG via gg_sfx).",
|
|
504
|
+
},
|
|
505
|
+
platformer: {
|
|
506
|
+
main: "templates/platformer.c",
|
|
507
|
+
runtime: GG_RUNTIME,
|
|
508
|
+
lang: GG_LANG,
|
|
509
|
+
ext: ".gg",
|
|
510
|
+
describe: "SIDE-SCROLLING platformer for GG with COLUMN STREAMING. Same Mode-4 VDP as the SMS — only the visible window differs (160 px wide). Subpixel gravity + jump + land-on-top collision across a 512-px world; the camera centers on the 160-px window, writes VDP R8 (-camX) for smooth pixel scroll, and streams the next world column into the wrapping 32-cell name table each time camX crosses an 8-px boundary. Player sprite draws in screen space. Jump boing via PSG sfx. 1=jump, d-pad=move. See the SMS/GG MENTAL_MODEL.md 'Horizontal scrolling'. Extend with enemies, goals, pickups.",
|
|
511
|
+
},
|
|
512
|
+
puzzle: {
|
|
513
|
+
main: "templates/puzzle.c",
|
|
514
|
+
runtime: GG_RUNTIME,
|
|
515
|
+
lang: GG_LANG,
|
|
516
|
+
ext: ".gg",
|
|
517
|
+
describe: "Match-3 falling-block scaffold. 6×12 grid, 1×3 piece, rotate via B1, hard-drop via B2. Rotate click + clear chime via PSG.",
|
|
518
|
+
},
|
|
519
|
+
sports: {
|
|
520
|
+
main: "templates/sports.c",
|
|
521
|
+
runtime: GG_RUNTIME,
|
|
522
|
+
lang: GG_LANG,
|
|
523
|
+
ext: ".gg",
|
|
524
|
+
describe: "Single-player Pong vs AI (GG has only one controller). Paddle hit + wall blip + score chime via PSG.",
|
|
525
|
+
},
|
|
526
|
+
racing: {
|
|
527
|
+
main: "templates/racing.c",
|
|
528
|
+
runtime: GG_RUNTIME,
|
|
529
|
+
lang: GG_LANG,
|
|
530
|
+
ext: ".gg",
|
|
531
|
+
describe: "Top-down 3-lane racer scaffold. L/R switches lanes, obstacles slide down + accelerate with score. Lane-switch beep + crash noise via PSG.",
|
|
532
|
+
},
|
|
533
|
+
music_demo: {
|
|
534
|
+
main: "templates/music_demo.c",
|
|
535
|
+
runtime: GG_RUNTIME,
|
|
536
|
+
lang: GG_LANG,
|
|
537
|
+
ext: ".gg",
|
|
538
|
+
describe: "Per-frame PSG music driver (gg_music) playing a hand-authored note table on PSG ch 2, with gg_sfx pew on ch 0. LEFT/RIGHT switches between three bundled songs, UP stops, DOWN restarts, B1 fires sfx. UI centered in the 160×144 visible viewport.",
|
|
539
|
+
},
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
// ── C64: cc65 + SID sound (R39 brings tier-1 parity) ────────────────────
|
|
543
|
+
const C64_RUNTIME = [
|
|
544
|
+
{ src: "lib/c64_registers.h", dst: "c64_registers.h" },
|
|
545
|
+
{ src: "lib/c/c64_sfx.h", dst: "c64_sfx.h" },
|
|
546
|
+
{ src: "lib/c/c64_sfx.c", dst: "c64_sfx.c" },
|
|
547
|
+
];
|
|
548
|
+
// R58b: ship cc65 C64 libsrc into project. Joystick driver,
|
|
549
|
+
// VIC-II / SID / CIA helpers, conio, header builder — all readable.
|
|
550
|
+
const C64_VENDOR_DIRS = [
|
|
551
|
+
{ src: "lib/cc65-src", dst: "vendor/cc65/libsrc/c64" },
|
|
552
|
+
];
|
|
553
|
+
// R49: music_demo gets its own 3-voice SID music driver instead of the
|
|
554
|
+
// one-shot sfx wrapper. Note table IS the song — open c64_music.c.
|
|
555
|
+
const C64_MUSIC_RUNTIME = [
|
|
556
|
+
{ src: "lib/c64_registers.h", dst: "c64_registers.h" },
|
|
557
|
+
{ src: "lib/c/c64_music.h", dst: "c64_music.h" },
|
|
558
|
+
{ src: "lib/c/c64_music.c", dst: "c64_music.c" },
|
|
559
|
+
];
|
|
560
|
+
const C64_LANG = "C (cc65)";
|
|
561
|
+
TEMPLATES.c64 = {
|
|
562
|
+
default: {
|
|
563
|
+
main: "main.c", runtime: [{ src: "lib/c64_registers.h", dst: "c64_registers.h" }], runtimeDirs: C64_VENDOR_DIRS,
|
|
564
|
+
lang: C64_LANG, ext: ".prg",
|
|
565
|
+
describe: "Minimal cc65 C64 program. Includes c64_registers.h (VIC-II + SID + CIA + kernel addrs).",
|
|
566
|
+
},
|
|
567
|
+
hello_sprite: {
|
|
568
|
+
main: "templates/hello_sprite.c", runtime: [{ src: "lib/c64_registers.h", dst: "c64_registers.h" }], runtimeDirs: C64_VENDOR_DIRS,
|
|
569
|
+
lang: C64_LANG, ext: ".prg",
|
|
570
|
+
describe: "One VIC-II hardware sprite driven by joystick port 2.",
|
|
571
|
+
},
|
|
572
|
+
tile_engine: {
|
|
573
|
+
main: "templates/tile_engine.c", runtime: [{ src: "lib/c64_registers.h", dst: "c64_registers.h" }], runtimeDirs: C64_VENDOR_DIRS,
|
|
574
|
+
lang: C64_LANG, ext: ".prg",
|
|
575
|
+
describe: "40×25 character-matrix world with a hardware sprite + AABB collision.",
|
|
576
|
+
},
|
|
577
|
+
shmup: {
|
|
578
|
+
main: "templates/shmup.c", runtime: C64_RUNTIME, runtimeDirs: C64_VENDOR_DIRS,
|
|
579
|
+
lang: C64_LANG, ext: ".prg",
|
|
580
|
+
describe: "Vertical-shmup. Player + 3 bullets + 4 enemies via VIC-II hardware sprites. SID sfx: pew + boom.",
|
|
581
|
+
},
|
|
582
|
+
platformer: {
|
|
583
|
+
main: "templates/platformer.c", runtime: C64_RUNTIME, runtimeDirs: C64_VENDOR_DIRS,
|
|
584
|
+
lang: C64_LANG, ext: ".prg",
|
|
585
|
+
describe: "SIDE-SCROLLING platformer for C64 — the fiddliest scroll of all the platforms, done for real. 80-col (640-px) world; the VIC-II only fine-scrolls 0-7 px in hardware ($D016 low 3 bits), so coarse motion re-renders the 40 visible columns of screen RAM ($0400) + color RAM ($D800) from a world map each time the camera crosses a char boundary. 38-column mode ($D016 bit 3 clear) masks the edge garbage column. The player is a VIC-II hardware sprite drawn in screen space (with the $D010 X-MSB handled); SID jump sfx. Joystick port 2, B1 jumps. See the C64 MENTAL_MODEL.md 'Horizontal scrolling'. Extend with enemies, goals, pickups.",
|
|
586
|
+
},
|
|
587
|
+
puzzle: {
|
|
588
|
+
main: "templates/puzzle.c", runtime: C64_RUNTIME, runtimeDirs: C64_VENDOR_DIRS,
|
|
589
|
+
lang: C64_LANG, ext: ".prg",
|
|
590
|
+
describe: "Match-3 falling-block puzzle. 6×12 grid in screen RAM (40×25 char matrix), C64 color codes. Rotate click + clear chime via SID.",
|
|
591
|
+
},
|
|
592
|
+
sports: {
|
|
593
|
+
main: "templates/sports.c", runtime: C64_RUNTIME, runtimeDirs: C64_VENDOR_DIRS,
|
|
594
|
+
lang: C64_LANG, ext: ".prg",
|
|
595
|
+
describe: "Pong with 3 hardware sprites. Joystick port 2 = P1; AI on the right paddle. SID paddle-hit + wall-bounce + score sfx.",
|
|
596
|
+
},
|
|
597
|
+
racing: {
|
|
598
|
+
main: "templates/racing.c", runtime: C64_RUNTIME, runtimeDirs: C64_VENDOR_DIRS,
|
|
599
|
+
lang: C64_LANG, ext: ".prg",
|
|
600
|
+
describe: "3-lane top-down racer. LEFT/RIGHT switches lanes. SID lane-switch beep + crash noise.",
|
|
601
|
+
},
|
|
602
|
+
music_demo: {
|
|
603
|
+
main: "templates/music_demo.c", runtime: C64_MUSIC_RUNTIME, runtimeDirs: C64_VENDOR_DIRS,
|
|
604
|
+
lang: C64_LANG, ext: ".prg",
|
|
605
|
+
describe: "Continuous 3-voice SID music demo. Per-frame note-table sequencer (c64_music.c IS the song — edit it). Melody / bass / harmony over an Am-F-C-G loop; FIRE on joy port 2 toggles playback.",
|
|
606
|
+
},
|
|
607
|
+
};
|
|
608
|
+
// R31: SNES audio assets shared by all C-mode genre scaffolds. The
|
|
609
|
+
// SPC700 driver source + sample BRR files are visible alongside the
|
|
610
|
+
// prebuilt apu_blob.bin (which gets .incbin'd into the ROM via
|
|
611
|
+
// snes_sfx_data.asm). User can rebuild apu_blob with asar — see
|
|
612
|
+
// src/platforms/snes/lib/audio/apu_blob.asm.
|
|
613
|
+
const SNES_SFX_RUNTIME = [
|
|
614
|
+
{ src: "lib/c/snes_sfx.h", dst: "snes_sfx.h" },
|
|
615
|
+
{ src: "lib/c/snes_sfx.c", dst: "snes_sfx.c" },
|
|
616
|
+
{ src: "lib/c/snes_sfx_data.asm", dst: "snes_sfx_data.asm" },
|
|
617
|
+
{ src: "lib/audio/apu_blob.bin", dst: "apu_blob.bin" },
|
|
618
|
+
{ src: "lib/audio/spc_driver.asm", dst: "spc_driver.asm" },
|
|
619
|
+
{ src: "lib/audio/apu_blob.asm", dst: "apu_blob.asm" },
|
|
620
|
+
{ src: "lib/audio/shoot.brr", dst: "shoot.brr" },
|
|
621
|
+
{ src: "lib/audio/explosion.brr", dst: "explosion.brr" },
|
|
622
|
+
{ src: "lib/audio/sample_bank.bin", dst: "sample_bank.bin" },
|
|
623
|
+
];
|
|
624
|
+
|
|
625
|
+
// R58b: ship the full PVSnesLib source tree into every SNES C
|
|
626
|
+
// project so the agent can grep snes/sound.h, consoleDrawText,
|
|
627
|
+
// setMode, padsCurrent, etc. instead of stabbing at the precompiled
|
|
628
|
+
// .obj. Same rationale as the Lynx cc65-src bundling — the agent
|
|
629
|
+
// debugs faster when they can read what the library actually does.
|
|
630
|
+
const SNES_PVSNESLIB_VENDOR_DIRS = [
|
|
631
|
+
{ src: "lib/pvsneslib/include", dst: "vendor/pvsneslib/include" },
|
|
632
|
+
{ src: "lib/pvsneslib/source", dst: "vendor/pvsneslib/source" },
|
|
633
|
+
];
|
|
634
|
+
|
|
635
|
+
TEMPLATES.snes = {
|
|
636
|
+
// C is the SNES default. PVSnesLib gives a clean C API (oamSet,
|
|
637
|
+
// padsCurrent, WaitForVBlank, etc.) instead of raw 65816 — same
|
|
638
|
+
// ergonomics as every other platform's C-mode default. Renders a
|
|
639
|
+
// movable sprite on a blue backdrop, no font dependency.
|
|
640
|
+
default: {
|
|
641
|
+
main: "templates/default.c",
|
|
642
|
+
extraSources: [
|
|
643
|
+
{ src: "templates/default-data.asm", dst: "data.asm" },
|
|
644
|
+
],
|
|
645
|
+
runtime: [],
|
|
646
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
647
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
648
|
+
ext: ".sfc",
|
|
649
|
+
describe: "Minimal SNES C starter: movable sprite + blue backdrop using PVSnesLib (oamSet, padsCurrent, WaitForVBlank). Two-file project: main.c + data.asm.",
|
|
650
|
+
},
|
|
651
|
+
// Raw 65816 path — kept for cycle-accurate work, IRQ-driven raster
|
|
652
|
+
// effects, etc. Same content as the pre-2026-05-27 `default`.
|
|
653
|
+
asm: {
|
|
654
|
+
main: "main.asm",
|
|
655
|
+
runtime: [
|
|
656
|
+
{ src: "lib/lorom_header.asm", dst: "lorom_header.asm" },
|
|
657
|
+
{ src: "lib/cgram_upload.asm", dst: "cgram_upload.asm" },
|
|
658
|
+
{ src: "lib/reset_init.asm", dst: "reset_init.asm" },
|
|
659
|
+
],
|
|
660
|
+
lang: "65816 assembly (asar)",
|
|
661
|
+
ext: ".sfc",
|
|
662
|
+
describe: "Raw 65816 asar starter: blue backdrop via CGRAM upload. Use when you need cycle-accurate control (raster splits, mid-frame DMA, etc.). For most game work prefer template:\"default\" (PVSnesLib C).",
|
|
663
|
+
},
|
|
664
|
+
// Text-mode console hello-world. Useful for status displays /
|
|
665
|
+
// debug overlays / tutorial-style text adventures.
|
|
666
|
+
c_hello: {
|
|
667
|
+
main: "templates/c-hello.c",
|
|
668
|
+
extraSources: [
|
|
669
|
+
{ src: "templates/c-hello-data.asm", dst: "data.asm" },
|
|
670
|
+
],
|
|
671
|
+
runtime: [],
|
|
672
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
673
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
674
|
+
ext: ".sfc",
|
|
675
|
+
describe: "PVSnesLib text-mode starter: consoleDrawText writes ASCII into a tile-mapped BG0. Stub font in data.asm — replace with .incbin of a real .pic/.pal for legible glyphs.",
|
|
676
|
+
},
|
|
677
|
+
// R21: parity templates with NES + Genesis. tcc-65816 is C89, so all
|
|
678
|
+
// declarations live at block top. Two-file projects (.c + .asm) because
|
|
679
|
+
// PVSnesLib's runtime expects tilfont/palfont symbols to be linkable;
|
|
680
|
+
// sprite templates also ship tilsprite + palsprite hand-authored bytes.
|
|
681
|
+
hello_sprite: {
|
|
682
|
+
main: "templates/hello_sprite.c",
|
|
683
|
+
extraSources: [
|
|
684
|
+
{ src: "templates/hello_sprite-data.asm", dst: "data.asm" },
|
|
685
|
+
],
|
|
686
|
+
runtime: [],
|
|
687
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
688
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
689
|
+
ext: ".sfc",
|
|
690
|
+
describe: "One 8×8 sprite + d-pad. oamSet/oamUpdate canonical loop, hand-authored sprite tile + palette in data.asm. Fork to add more sprites, animations, sound.",
|
|
691
|
+
},
|
|
692
|
+
shmup: {
|
|
693
|
+
main: "templates/shmup.c",
|
|
694
|
+
extraSources: [
|
|
695
|
+
{ src: "templates/shmup-data.asm", dst: "data.asm" },
|
|
696
|
+
],
|
|
697
|
+
runtime: SNES_SFX_RUNTIME,
|
|
698
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
699
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
700
|
+
ext: ".sfc",
|
|
701
|
+
describe: "Vertical-shmup scaffold for SNES. Player ship + 6 bullets + 6 enemies, wave spawner, AABB collisions, score. SFX (pew on fire, boom on hit) via the bundled SPC700 driver + sample bank.",
|
|
702
|
+
},
|
|
703
|
+
platformer: {
|
|
704
|
+
main: "templates/platformer.c",
|
|
705
|
+
extraSources: [
|
|
706
|
+
{ src: "templates/platformer-data.asm", dst: "data.asm" },
|
|
707
|
+
],
|
|
708
|
+
runtime: SNES_SFX_RUNTIME,
|
|
709
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
710
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
711
|
+
ext: ".sfc",
|
|
712
|
+
describe: "SIDE-SCROLLING platformer for SNES (PVSnesLib). Subpixel gravity + jump + land-on-top collision across a 512-px world. A camera follows the player; the BG scrolls in hardware via bgSetScroll(0, camX, 0) and the player sprite draws in screen space (worldX - camX), held screen-centered while the world moves under it. Jump SFX via the bundled SPC700 driver. NOTE: uses the PVSnesLib console (text) BG, so platforms are collision-only and the scroll shows as the on-BG text sliding — for visible tiled platform art across a wide world, build a tileset with gfx2snes + bgInitTileSet on a 64-wide map and stream tilemap columns into VRAM during vblank. See the SNES MENTAL_MODEL.md 'Horizontal scrolling'. BUILD: needs language:'c', snes_sfx_data.asm in sources, apu_blob.bin as a binary include, and snes_sfx.c/.h in includePaths (all scaffolded by createGame).",
|
|
713
|
+
},
|
|
714
|
+
puzzle: {
|
|
715
|
+
main: "templates/puzzle.c",
|
|
716
|
+
extraSources: [
|
|
717
|
+
{ src: "templates/puzzle-data.asm", dst: "data.asm" },
|
|
718
|
+
],
|
|
719
|
+
runtime: SNES_SFX_RUNTIME,
|
|
720
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
721
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
722
|
+
ext: ".sfc",
|
|
723
|
+
describe: "Match-3 falling-block puzzle for SNES. 6×12 grid (text mode), rotate/soft-drop/hard-drop, horizontal-triple clear. Rotate click + clear chime via bundled SPC700 sfx.",
|
|
724
|
+
},
|
|
725
|
+
sports: {
|
|
726
|
+
main: "templates/sports.c",
|
|
727
|
+
extraSources: [
|
|
728
|
+
{ src: "templates/sports-data.asm", dst: "data.asm" },
|
|
729
|
+
],
|
|
730
|
+
runtime: SNES_SFX_RUNTIME,
|
|
731
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
732
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
733
|
+
ext: ".sfc",
|
|
734
|
+
describe: "Two-player Pong on SNES. padsCurrent(0)/padsCurrent(1) wire both ports. Paddle-hit + score sfx via bundled SPC700 driver.",
|
|
735
|
+
},
|
|
736
|
+
racing: {
|
|
737
|
+
main: "templates/racing.c",
|
|
738
|
+
extraSources: [
|
|
739
|
+
{ src: "templates/racing-data.asm", dst: "data.asm" },
|
|
740
|
+
],
|
|
741
|
+
runtime: SNES_SFX_RUNTIME,
|
|
742
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
743
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
744
|
+
ext: ".sfc",
|
|
745
|
+
describe: "Endless 3-lane top-down racer for SNES. LEFT/RIGHT switches lanes, obstacles slide down at growing speed. Two sprite tiles (player + enemy), score in BG text overlay.",
|
|
746
|
+
},
|
|
747
|
+
// R46: continuous-music demo on the SPC700 driver. Showcases
|
|
748
|
+
// sfx_music_play / sfx_music_stop alongside the existing sfx_play
|
|
749
|
+
// path — the SPC walks a song table autonomously while the 65816
|
|
750
|
+
// just polls input.
|
|
751
|
+
music_demo: {
|
|
752
|
+
main: "templates/music_demo.c",
|
|
753
|
+
extraSources: [
|
|
754
|
+
{ src: "templates/music_demo-data.asm", dst: "data.asm" },
|
|
755
|
+
],
|
|
756
|
+
runtime: SNES_SFX_RUNTIME,
|
|
757
|
+
runtimeDirs: SNES_PVSNESLIB_VENDOR_DIRS,
|
|
758
|
+
lang: "C (tcc-65816 + PVSnesLib)",
|
|
759
|
+
ext: ".sfc",
|
|
760
|
+
describe: "Continuous SPC700 music + SFX demo. Auto-plays a looping arpeggio on voice 1; B = shoot sfx (voice 0), A = stop music, START = resume. Starting point for adding music to any SNES C scaffold.",
|
|
761
|
+
},
|
|
762
|
+
};
|
|
763
|
+
// All SGDK Genesis C templates share the same runtime bundle: crt0 (sega.s +
|
|
764
|
+
// cpp-expanded sega.preprocessed.s for the bare WASM `as`), linker script, ROM
|
|
765
|
+
// header source, MIT license, and the full include tree. SGDK itself is
|
|
766
|
+
// compiled from source by the build (its source is vendored via
|
|
767
|
+
// SGDK_RUNTIME_DIRS) — no prebuilt libmd.a is copied in.
|
|
768
|
+
const SGDK_RUNTIME = [
|
|
769
|
+
{ src: "lib/sgdk/sega.s", dst: "sega.s" },
|
|
770
|
+
{ src: "lib/sgdk/sega.preprocessed.s", dst: "sega.preprocessed.s" },
|
|
771
|
+
{ src: "lib/sgdk/rom_header.c", dst: "rom_header.c" },
|
|
772
|
+
{ src: "lib/sgdk/md.ld", dst: "md.ld" },
|
|
773
|
+
{ src: "lib/sgdk/LICENSE", dst: "LICENSE-SGDK" },
|
|
774
|
+
{ src: "lib/sgdk/COPYING.RUNTIME", dst: "COPYING-SGDK-RUNTIME" },
|
|
775
|
+
// R30: minimal PSG sound-effects wrapper. 3 functions matching the
|
|
776
|
+
// NES/GB/GBA scaffold sound shape.
|
|
777
|
+
{ src: "lib/c/genesis_sfx.h", dst: "genesis_sfx.h" },
|
|
778
|
+
{ src: "lib/c/genesis_sfx.c", dst: "genesis_sfx.c" },
|
|
779
|
+
];
|
|
780
|
+
const SGDK_RUNTIME_DIRS = [
|
|
781
|
+
{ src: "lib/sgdk/include", dst: "include" },
|
|
782
|
+
// R58b: ship the full SGDK src tree into the project. Agent can grep
|
|
783
|
+
// it directly instead of guessing what SPR_addSprite / VDP_drawText /
|
|
784
|
+
// JOY_readJoypad / XGM2_startPlay actually do. SGDK is compiled FROM this
|
|
785
|
+
// source by the build (no prebuilt libmd.a).
|
|
786
|
+
{ src: "lib/sgdk/src", dst: "vendor/sgdk/src" },
|
|
787
|
+
// res/: the generated libres (default font/logo) + its source (.res + PNGs)
|
|
788
|
+
// and the regen recipe — so the resource blobs are reproducible, not opaque.
|
|
789
|
+
{ src: "lib/sgdk/res", dst: "vendor/sgdk/res" },
|
|
790
|
+
];
|
|
791
|
+
const SGDK_LANG = "C (m68k-elf-gcc + SGDK)";
|
|
792
|
+
|
|
793
|
+
// R42: XGM2 music runtime — adds the demo .vgm source + compiled .xgc blob
|
|
794
|
+
// alongside the standard SGDK headers/libmd. .vgm is the human-editable
|
|
795
|
+
// chiptune (regen via scripts/build-genesis-demo-vgm.js + xgm2tool); .xgc
|
|
796
|
+
// is what gets .incbin'd into ROM via the data.s sibling.
|
|
797
|
+
const SGDK_XGM2_RUNTIME = [
|
|
798
|
+
...SGDK_RUNTIME,
|
|
799
|
+
{ src: "lib/sgdk/music/demo.vgm", dst: "demo.vgm" },
|
|
800
|
+
{ src: "lib/sgdk/music/demo.xgc", dst: "demo.xgc" },
|
|
801
|
+
];
|
|
802
|
+
|
|
803
|
+
TEMPLATES.genesis = {
|
|
804
|
+
// C via SGDK is the Genesis default. SGDK gives a clean C API
|
|
805
|
+
// (VDP_drawText, SYS_doVBlankProcess, SPR_addSprite, etc.) and
|
|
806
|
+
// builds in <2s. Same ergonomics as every other platform's C
|
|
807
|
+
// default — agent ships a game in one session, not 10.
|
|
808
|
+
default: {
|
|
809
|
+
main: "templates/sgdk_hello.c",
|
|
810
|
+
runtime: SGDK_RUNTIME,
|
|
811
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
812
|
+
lang: SGDK_LANG,
|
|
813
|
+
ext: ".bin",
|
|
814
|
+
describe: "Genesis C default using SGDK: VDP_drawText shows 'HELLO SEGA GENESIS'. #include <genesis.h>, SYS_doVBlankProcess, full SGDK API. For raw 68k asm see template:\"asm\".",
|
|
815
|
+
},
|
|
816
|
+
// Kept for cycle-accurate work / IRQ-driven raster effects.
|
|
817
|
+
asm: {
|
|
818
|
+
main: "main.s",
|
|
819
|
+
runtime: [
|
|
820
|
+
{ src: "lib/header.s", dst: "header.s" },
|
|
821
|
+
{ src: "lib/vdp_init.s", dst: "vdp_init.s" },
|
|
822
|
+
{ src: "lib/vblank_wait.s", dst: "vblank_wait.s" },
|
|
823
|
+
],
|
|
824
|
+
lang: "68k assembly (vasm68k)",
|
|
825
|
+
ext: ".bin",
|
|
826
|
+
describe: "Raw 68k Genesis starter (vasm68k): header + VDP init + vblank wait. Use when you need cycle-accurate control (raster splits, mid-frame DMA). For most game work prefer template:\"default\" (SGDK C).",
|
|
827
|
+
},
|
|
828
|
+
sgdk_hello: {
|
|
829
|
+
main: "templates/sgdk_hello.c",
|
|
830
|
+
runtime: SGDK_RUNTIME,
|
|
831
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
832
|
+
lang: SGDK_LANG,
|
|
833
|
+
ext: ".bin",
|
|
834
|
+
describe: "Alias of template:\"default\" (kept for backward-compat with earlier scripts that named it explicitly).",
|
|
835
|
+
},
|
|
836
|
+
// R42: XGM2 music playback — counterpart to the R30 PSG sfx wrapper.
|
|
837
|
+
// Two-file project (main.c + data.s sibling); data.s does the .incbin
|
|
838
|
+
// of demo.xgc, matching R31's snes_sfx_data.asm pattern. The compiled
|
|
839
|
+
// .xgc plus its source .vgm both ship in the project tree so users can
|
|
840
|
+
// regen with xgm2tool.
|
|
841
|
+
xgm2_demo: {
|
|
842
|
+
main: "templates/xgm2_demo.c",
|
|
843
|
+
extraSources: [
|
|
844
|
+
{ src: "templates/xgm2_demo_data.s", dst: "data.s" },
|
|
845
|
+
],
|
|
846
|
+
runtime: SGDK_XGM2_RUNTIME,
|
|
847
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
848
|
+
lang: SGDK_LANG,
|
|
849
|
+
ext: ".bin",
|
|
850
|
+
describe: "XGM2 music playback demo. XGM2_loadDriver + XGM2_play, music blob incbin'd via data.s sibling. Ships a tiny CC0 PSG arpeggio (demo.vgm source + demo.xgc compiled) — regen with SGDK's xgm2tool. SYS_doVBlankProcess drives the Z80 driver tick.",
|
|
851
|
+
},
|
|
852
|
+
hello_sprite: {
|
|
853
|
+
main: "templates/hello_sprite.c",
|
|
854
|
+
runtime: SGDK_RUNTIME,
|
|
855
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
856
|
+
lang: SGDK_LANG,
|
|
857
|
+
ext: ".bin",
|
|
858
|
+
describe: "Single sprite + d-pad. Uploads one 8×8 tile via VDP_loadTileData, places one VDP sprite, reads JOY_1 each frame, calls VDP_updateSprites + SYS_doVBlankProcess. The minimum-viable input-driven scaffold — fork from here to add more sprites, palettes, sound.",
|
|
859
|
+
},
|
|
860
|
+
tile_engine: {
|
|
861
|
+
main: "templates/tile_engine.c",
|
|
862
|
+
runtime: SGDK_RUNTIME,
|
|
863
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
864
|
+
lang: SGDK_LANG,
|
|
865
|
+
ext: ".bin",
|
|
866
|
+
describe: "40×28 tile world on plane B with a walking player + AABB collision against solid tile IDs. Demonstrates VDP_setTileMapXY / VDP_fillTileMapRect / two-plane composition. Single-screen — extend with VDP_setHorizontalScroll for scrolling worlds.",
|
|
867
|
+
},
|
|
868
|
+
shmup: {
|
|
869
|
+
main: "templates/shmup.c",
|
|
870
|
+
runtime: SGDK_RUNTIME,
|
|
871
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
872
|
+
lang: SGDK_LANG,
|
|
873
|
+
ext: ".bin",
|
|
874
|
+
describe: "Vertical-shmup genre scaffold. Player ship + 6 bullet slots + 6 enemy slots (object pools, no malloc), wave spawner, AABB collisions, score. Pre-allocated SAT slot ranges (0=player, 1-6=bullets, 7-12=enemies) so no flicker.",
|
|
875
|
+
},
|
|
876
|
+
platformer: {
|
|
877
|
+
main: "templates/platformer.c",
|
|
878
|
+
runtime: SGDK_RUNTIME,
|
|
879
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
880
|
+
lang: SGDK_LANG,
|
|
881
|
+
ext: ".bin",
|
|
882
|
+
describe: "SIDE-SCROLLING platformer for Genesis. Subpixel gravity + jump + land-on-top collision against a static platform list spread across a 512-px world. Camera follows the player; Plane A scrolls with the world via VDP_setHorizontalScroll, Plane B scrolls at half-rate for parallax. A=jump, d-pad=move. The world here is one 64-cell plane wide (no streaming) — for a wider world, stream the column entering view each 8-px camera step (see Genesis MENTAL_MODEL.md 'Horizontal scrolling'). Extend with enemies, goals, pickups.",
|
|
883
|
+
},
|
|
884
|
+
puzzle: {
|
|
885
|
+
main: "templates/puzzle.c",
|
|
886
|
+
runtime: SGDK_RUNTIME,
|
|
887
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
888
|
+
lang: SGDK_LANG,
|
|
889
|
+
ext: ".bin",
|
|
890
|
+
describe: "Match-3 falling-block puzzle genre scaffold. 6×12 grid, 1×3 active piece (3 colours), rotate via A, soft-drop on DOWN, hard-drop on START, horizontal-triple clear. xorshift RNG so cell colours actually vary.",
|
|
891
|
+
},
|
|
892
|
+
sports: {
|
|
893
|
+
main: "templates/sports.c",
|
|
894
|
+
runtime: SGDK_RUNTIME,
|
|
895
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
896
|
+
lang: SGDK_LANG,
|
|
897
|
+
ext: ".bin",
|
|
898
|
+
describe: "Two-player Pong via JOY_1 + JOY_2. AI fallback on port 2 when no second controller. Per-side score 0-9 rendered via VDP_drawText, ball bounces off paddles + court walls. Designed for the playtest window with hot-plugged controllers.",
|
|
899
|
+
},
|
|
900
|
+
racing: {
|
|
901
|
+
main: "templates/racing.c",
|
|
902
|
+
runtime: SGDK_RUNTIME,
|
|
903
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
904
|
+
lang: SGDK_LANG,
|
|
905
|
+
ext: ".bin",
|
|
906
|
+
describe: "Endless top-down 3-lane racer. LEFT/RIGHT switches lanes, obstacles slide down at increasing speed as score climbs. Game-over on collision with 60-frame freeze then auto-reset.",
|
|
907
|
+
},
|
|
908
|
+
shmup_2p: {
|
|
909
|
+
main: "templates/shmup_2p.c",
|
|
910
|
+
runtime: SGDK_RUNTIME,
|
|
911
|
+
runtimeDirs: SGDK_RUNTIME_DIRS,
|
|
912
|
+
lang: SGDK_LANG,
|
|
913
|
+
ext: ".bin",
|
|
914
|
+
describe: "Two-player competitive shmup via JOY_1 + JOY_2. Each player has their own ship + 4-bullet pool + score. Enemies shared — first to hit scores the 10 points. Designed for the romdev playtest window with two hot-plugged controllers.",
|
|
915
|
+
},
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
// Simpler one-file platforms — no runtime/template variants, just a seed source.
|
|
919
|
+
// These platforms don't yet have a per-platform lib/ runtime to bundle.
|
|
920
|
+
// Empty today; every supported platform now has a full TEMPLATES entry.
|
|
921
|
+
const SIMPLE_STARTERS = {};
|
|
922
|
+
|
|
923
|
+
// R38: Lynx tier-1 with full template set + MIKEY sound + tgi graphics.
|
|
924
|
+
// R43: music_demo template — cc65's lynx_snd_play streaming music engine.
|
|
925
|
+
// R58b: ship the cc65 Lynx libsrc INTO each project so the agent can
|
|
926
|
+
// grep the TGI driver / lynx_snd engine / joystick driver without
|
|
927
|
+
// leaving their project dir. The 1500-frame TGI wedge round
|
|
928
|
+
// (rounds 28-32) was caused entirely by the agent debugging a
|
|
929
|
+
// blackbox driver. R58 copy-into-install was the half-step;
|
|
930
|
+
// R58b shipping into the PROJECT closes the loop.
|
|
931
|
+
const LYNX_VENDOR_DIRS = [
|
|
932
|
+
{ src: "lib/cc65-src", dst: "vendor/cc65/libsrc/lynx" },
|
|
933
|
+
];
|
|
934
|
+
const LYNX_RUNTIME = [
|
|
935
|
+
{ src: "lib/c/lynx_sfx.h", dst: "lynx_sfx.h" },
|
|
936
|
+
{ src: "lib/c/lynx_sfx.c", dst: "lynx_sfx.c" },
|
|
937
|
+
];
|
|
938
|
+
const LYNX_MUSIC_RUNTIME = [
|
|
939
|
+
{ src: "lib/c/lynx_music.h", dst: "lynx_music.h" },
|
|
940
|
+
{ src: "lib/c/lynx_music.c", dst: "lynx_music.c" },
|
|
941
|
+
];
|
|
942
|
+
const LYNX_LANG = "C (cc65 + tgi)";
|
|
943
|
+
TEMPLATES.lynx = {
|
|
944
|
+
default: {
|
|
945
|
+
main: "templates/default.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
946
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
947
|
+
describe: "Minimal Lynx starter: TGI color-cycling square + 'HELLO LYNX' text. Smallest possible ROM that does something visible — use as starting point when you're not sure what to build. Project also includes vendor/cc65/libsrc/lynx/ — the FULL cc65 Lynx driver source (TGI, joystick, sound, conio) so you can grep it directly when debugging.",
|
|
948
|
+
},
|
|
949
|
+
hello_sprite: {
|
|
950
|
+
main: "templates/hello_sprite.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
951
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
952
|
+
describe: "Lynx hello + joystick movement. cc65 tgi graphics + lynx_sfx for sound. Boot chime confirms MIKEY audio is wired.",
|
|
953
|
+
},
|
|
954
|
+
music_demo: {
|
|
955
|
+
main: "templates/music_demo.c", runtime: LYNX_MUSIC_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
956
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
957
|
+
describe: "cc65's lynx_snd_play streaming music engine demo. Plays a short (note, length) sequence on channel 0 via the 240Hz timer IRQ. Hand-authored music bytestream in lynx_music.c — the byte array IS the source. Pairs with lynx_sfx (one-shot pokes) for full audio coverage.",
|
|
958
|
+
},
|
|
959
|
+
shmup: {
|
|
960
|
+
main: "templates/shmup.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
961
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
962
|
+
describe: "Vertical-shmup. Player + 4 bullets + 4 enemies (object pools), AABB collisions. MIKEY pew + boom sfx.",
|
|
963
|
+
},
|
|
964
|
+
platformer: {
|
|
965
|
+
main: "templates/platformer.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
966
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
967
|
+
describe: "Single-screen platformer. Subpixel gravity + jump + 5 platforms. MIKEY jump sfx.",
|
|
968
|
+
},
|
|
969
|
+
puzzle: {
|
|
970
|
+
main: "templates/puzzle.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
971
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
972
|
+
describe: "Match-3 puzzle. 6×12 grid via tgi_bar. Rotate click + clear chime via MIKEY.",
|
|
973
|
+
},
|
|
974
|
+
sports: {
|
|
975
|
+
main: "templates/sports.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
976
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
977
|
+
describe: "Pong vs AI (handheld = one controller). MIKEY paddle-hit + wall-bounce + score sfx.",
|
|
978
|
+
},
|
|
979
|
+
racing: {
|
|
980
|
+
main: "templates/racing.c", runtime: LYNX_RUNTIME, runtimeDirs: LYNX_VENDOR_DIRS,
|
|
981
|
+
lang: LYNX_LANG, ext: ".lnx",
|
|
982
|
+
describe: "3-lane top-down racer. MIKEY lane-switch beep + crash noise.",
|
|
983
|
+
},
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
// R24 + R28: Game Boy Advance C tier-1 via arm-none-eabi-gcc + EITHER
|
|
987
|
+
// libtonc (default, Tonc-tutorial-aligned) OR libgba (devkitPro
|
|
988
|
+
// official). Same self-containment policy as Genesis SGDK — the
|
|
989
|
+
// entire runtime bundle gets copied INTO the user's project so they
|
|
990
|
+
// can rebuild on any machine with devkitARM installed.
|
|
991
|
+
//
|
|
992
|
+
// Why libtonc is the default: the Tonc tutorial at gbadev.net/tonc is
|
|
993
|
+
// THE GBA C corpus the LLM has been trained on. Agent-generated code
|
|
994
|
+
// matches Tonc idioms naturally (tte_write, tonccpy, OBJ_ATTR, etc.).
|
|
995
|
+
// libgba stays available via `runtime:"libgba"` or `template:"gba_hello"`.
|
|
996
|
+
//
|
|
997
|
+
// One caveat shared by both runtimes: the libsysbase-backed iprintf
|
|
998
|
+
// bridge (tte_iohook in libtonc, console.c in libgba) is NOT bundled.
|
|
999
|
+
// Use tte_printf directly with libtonc — that's the Tonc-tutorial
|
|
1000
|
+
// pattern and works without the libsysbase header chain.
|
|
1001
|
+
const GBA_LIBTONC_RUNTIME = [
|
|
1002
|
+
// libtonc itself is compiled from source by the build (its source is vendored
|
|
1003
|
+
// via GBA_LIBTONC_RUNTIME_DIRS), so no prebuilt libtonc.a is copied in.
|
|
1004
|
+
{ src: "lib/libtonc/gba_crt0.s", dst: "gba_crt0.s" },
|
|
1005
|
+
{ src: "lib/libtonc/gba_cart.ld", dst: "gba_cart.ld" },
|
|
1006
|
+
{ src: "lib/libtonc/crti.o", dst: "crti.o" },
|
|
1007
|
+
{ src: "lib/libtonc/crtn.o", dst: "crtn.o" },
|
|
1008
|
+
{ src: "lib/libtonc/crtbegin.o", dst: "crtbegin.o" },
|
|
1009
|
+
{ src: "lib/libtonc/crtend.o", dst: "crtend.o" },
|
|
1010
|
+
// Minimal sfx wrapper around the GBA's DMG-compatible APU. Matches
|
|
1011
|
+
// the NES/GB scaffold sound shape — sfx_init + sfx_tone + sfx_noise.
|
|
1012
|
+
{ src: "lib/c/gba_sfx.h", dst: "gba_sfx.h" },
|
|
1013
|
+
{ src: "lib/c/gba_sfx.c", dst: "gba_sfx.c" },
|
|
1014
|
+
];
|
|
1015
|
+
const GBA_LIBTONC_RUNTIME_DIRS = [
|
|
1016
|
+
{ src: "lib/libtonc/include", dst: "include" },
|
|
1017
|
+
{ src: "lib/libgba/sysinclude", dst: "sysinclude" }, // shared with libgba
|
|
1018
|
+
// R58b: ship the FULL libtonc source tree INTO the project so the
|
|
1019
|
+
// agent can grep/read every implementation (TTE, OAM helpers, IRQ
|
|
1020
|
+
// setup, etc.) instead of stabbing in the dark against libtonc.a.
|
|
1021
|
+
// The 1500-frame Lynx wedge took 5 rounds partly because cc65 TGI
|
|
1022
|
+
// source wasn't in the project tree. Don't repeat that for libtonc.
|
|
1023
|
+
{ src: "lib/libtonc/src", dst: "vendor/libtonc/src" },
|
|
1024
|
+
{ src: "lib/maxmod", dst: "vendor/maxmod" },
|
|
1025
|
+
];
|
|
1026
|
+
const GBA_LIBGBA_RUNTIME = [
|
|
1027
|
+
// libgba is compiled from source by the build (source vendored via
|
|
1028
|
+
// GBA_LIBGBA_RUNTIME_DIRS); no prebuilt libgba.a copied in.
|
|
1029
|
+
{ src: "lib/libgba/gba_crt0.s", dst: "gba_crt0.s" },
|
|
1030
|
+
{ src: "lib/libgba/gba_cart.ld", dst: "gba_cart.ld" },
|
|
1031
|
+
{ src: "lib/libgba/crti.o", dst: "crti.o" },
|
|
1032
|
+
{ src: "lib/libgba/crtn.o", dst: "crtn.o" },
|
|
1033
|
+
{ src: "lib/libgba/crtbegin.o", dst: "crtbegin.o" },
|
|
1034
|
+
{ src: "lib/libgba/crtend.o", dst: "crtend.o" },
|
|
1035
|
+
];
|
|
1036
|
+
const GBA_LIBGBA_RUNTIME_DIRS = [
|
|
1037
|
+
{ src: "lib/libgba/include", dst: "include" },
|
|
1038
|
+
{ src: "lib/libgba/sysinclude", dst: "sysinclude" },
|
|
1039
|
+
// R58b: ship full libgba source so the agent can grep irqInit /
|
|
1040
|
+
// irqSet / VBlankIntrWait / GBA register defines directly.
|
|
1041
|
+
{ src: "lib/libgba/src", dst: "vendor/libgba/src" },
|
|
1042
|
+
];
|
|
1043
|
+
const GBA_TONC_LANG = "C (arm-none-eabi-gcc + libtonc)";
|
|
1044
|
+
const GBA_LIBGBA_LANG = "C (arm-none-eabi-gcc + libgba)";
|
|
1045
|
+
|
|
1046
|
+
TEMPLATES.gba = {
|
|
1047
|
+
// Tonc is the default — first key + canonical for new projects.
|
|
1048
|
+
tonc_hello: {
|
|
1049
|
+
main: "templates/tonc_hello.c",
|
|
1050
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1051
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1052
|
+
lang: GBA_TONC_LANG,
|
|
1053
|
+
ext: ".gba",
|
|
1054
|
+
describe: "Idiomatic Tonc-tutorial GBA C starter. #include <tonc.h>, TTE (Tonc Text Engine) draws 'Hello, Tonc!' on BG0 in MODE_0. Matches what every published GBA C tutorial at gbadev.net teaches. libtonc is compiled from its vendored source by the build (a fast prebuilt seed by default; pass rebuildSdk:true if you edit the SDK source) — the project gets the headers + gba_crt0 + linker script. Build with buildSource({platform:'gba', language:'c'}) — defaults to runtime:'libtonc'.",
|
|
1055
|
+
},
|
|
1056
|
+
tonc_hello_sprite: {
|
|
1057
|
+
main: "templates/tonc_hello_sprite.c",
|
|
1058
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1059
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1060
|
+
lang: GBA_TONC_LANG,
|
|
1061
|
+
ext: ".gba",
|
|
1062
|
+
describe: "One 8x8 sprite driven by the d-pad. Canonical Tonc sprite-chapter pattern: OBJ_ATTR shadow buffer + oam_copy DMA flush + key_poll/key_held input + 4bpp sprite tile + sprite palette setup. Forks well to multi-sprite scaffolds.",
|
|
1063
|
+
},
|
|
1064
|
+
shmup: {
|
|
1065
|
+
main: "templates/shmup.c",
|
|
1066
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1067
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1068
|
+
lang: GBA_TONC_LANG,
|
|
1069
|
+
ext: ".gba",
|
|
1070
|
+
describe: "Vertical shmup scaffold (Tonc). Player ship + 6 bullets + 6 enemies (fixed object pools), AABB collision, enemy wave spawner, TTE score readout. ~150 lines.",
|
|
1071
|
+
},
|
|
1072
|
+
platformer: {
|
|
1073
|
+
main: "templates/platformer.c",
|
|
1074
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1075
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1076
|
+
lang: GBA_TONC_LANG,
|
|
1077
|
+
ext: ".gba",
|
|
1078
|
+
describe: "SIDE-SCROLLING platformer for GBA (Tonc). Subpixel physics (1px = 16 subpixels), gravity + jump + land-on-top collision against platforms in a 512-px world. BG0 is a 64x32 map (whole world fits, no streaming); the camera follows the player via REG_BG0HOFS; the TTE HUD on BG1 stays fixed. For a world wider than 512 px, stream map columns as the camera advances (see GBA MENTAL_MODEL.md). Extend with enemies, goals, pickups.",
|
|
1079
|
+
},
|
|
1080
|
+
puzzle: {
|
|
1081
|
+
main: "templates/puzzle.c",
|
|
1082
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1083
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1084
|
+
lang: GBA_TONC_LANG,
|
|
1085
|
+
ext: ".gba",
|
|
1086
|
+
describe: "Match-3 falling-block scaffold (Tonc). 6x12 grid drawn as BG tiles, 1x3 active piece with LEFT/RIGHT shift, A rotate, DOWN soft-drop, START hard-drop. Horizontal triples clear + score.",
|
|
1087
|
+
},
|
|
1088
|
+
sports: {
|
|
1089
|
+
main: "templates/sports.c",
|
|
1090
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1091
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1092
|
+
lang: GBA_TONC_LANG,
|
|
1093
|
+
ext: ".gba",
|
|
1094
|
+
describe: "Pong scaffold (Tonc). Single-controller GBA → right paddle is AI ball-tracker. 24px paddles built from 3 stacked 8x8 sprites, ball collisions, score 0-9 via TTE. Real 2P on GBA needs link cable (out of scope).",
|
|
1095
|
+
},
|
|
1096
|
+
racing: {
|
|
1097
|
+
main: "templates/racing.c",
|
|
1098
|
+
runtime: GBA_LIBTONC_RUNTIME,
|
|
1099
|
+
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1100
|
+
lang: GBA_TONC_LANG,
|
|
1101
|
+
ext: ".gba",
|
|
1102
|
+
describe: "Top-down 3-lane racer scaffold (Tonc). Player car bottom, obstacles spawn from top + slide down, L/R switches lanes, AABB crash detection, 60-frame freeze + reset. Score is frames-since-crash.",
|
|
1103
|
+
},
|
|
1104
|
+
// Opt-in libgba path for users who prefer the devkitPro SDK or are
|
|
1105
|
+
// porting an existing libgba codebase.
|
|
1106
|
+
gba_hello: {
|
|
1107
|
+
main: "templates/gba_hello.c",
|
|
1108
|
+
runtime: GBA_LIBGBA_RUNTIME,
|
|
1109
|
+
runtimeDirs: GBA_LIBGBA_RUNTIME_DIRS,
|
|
1110
|
+
lang: GBA_LIBGBA_LANG,
|
|
1111
|
+
ext: ".gba",
|
|
1112
|
+
describe: "Alternate GBA C starter using devkitPro's libgba SDK. MODE_3 framebuffer + red pixel. Pass runtime:'libgba' to buildSource — or just use the Tonc path (gba_hello_tonc) which is better aligned with what published tutorials teach.",
|
|
1113
|
+
},
|
|
1114
|
+
// R34: maxmod music demo. Ships a hand-authored CC0 chiptune.xm +
|
|
1115
|
+
// its pre-built soundbank.bin. buildSource must be called with
|
|
1116
|
+
// `maxmod: true` AND binaryIncludes:{ "soundbank.bin": <bytes> } —
|
|
1117
|
+
// the buildGbaC layer auto-emits a `.incbin "soundbank.bin"` asm
|
|
1118
|
+
// stub exposing the soundbank under the global symbol soundbank_bin.
|
|
1119
|
+
// The .xm source ships alongside so users can regenerate the
|
|
1120
|
+
// soundbank with mmutil after editing the tune.
|
|
1121
|
+
maxmod_demo: {
|
|
1122
|
+
main: "templates/maxmod_demo.c",
|
|
1123
|
+
runtime: [
|
|
1124
|
+
...GBA_LIBTONC_RUNTIME,
|
|
1125
|
+
// maxmod compiled from source by the build — no prebuilt libmm.a.
|
|
1126
|
+
{ src: "lib/maxmod/music/chiptune.xm", dst: "chiptune.xm" },
|
|
1127
|
+
{ src: "lib/maxmod/music/chiptune_soundbank.bin", dst: "soundbank.bin" },
|
|
1128
|
+
{ src: "lib/maxmod/music/chiptune_soundbank.h", dst: "soundbank.h" },
|
|
1129
|
+
{ src: "lib/maxmod/music/make_chiptune_xm.js", dst: "make_chiptune_xm.js" },
|
|
1130
|
+
{ src: "lib/maxmod/LICENSE-MAXMOD", dst: "LICENSE-MAXMOD" },
|
|
1131
|
+
],
|
|
1132
|
+
runtimeDirs: [
|
|
1133
|
+
...GBA_LIBTONC_RUNTIME_DIRS,
|
|
1134
|
+
// Adds maxmod.h + mm_types.h next to the libtonc headers.
|
|
1135
|
+
{ src: "lib/maxmod/include", dst: "include" },
|
|
1136
|
+
],
|
|
1137
|
+
lang: GBA_TONC_LANG,
|
|
1138
|
+
ext: ".gba",
|
|
1139
|
+
maxmod: true,
|
|
1140
|
+
binaryIncludes: ["soundbank.bin"],
|
|
1141
|
+
describe: "Maxmod music demo (Tonc + libmm). Plays a CC0 chiptune.xm soundbank via mmInitDefault + mmStart + mmFrame, with START toggling pause. Pass `maxmod:true` AND `binaryIncludes:{\"soundbank.bin\": <bytes>}` to buildSource. The .xm source + generator script + pre-built soundbank.bin all ship in the project — edit and re-run mmutil to swap the tune.",
|
|
1142
|
+
},
|
|
1143
|
+
};
|
|
1144
|
+
|
|
1145
|
+
// R22: Atari 2600 promoted to multi-template platform. The 2600 has no
|
|
1146
|
+
// C compiler (asm only via dasm) and the genre-shmup/platformer/puzzle
|
|
1147
|
+
// scaffolds from other platforms don't map cleanly — its hardware
|
|
1148
|
+
// forces "race the beam" rendering. Three templates here that ARE
|
|
1149
|
+
// idiomatic 2600:
|
|
1150
|
+
// default — single sprite, blue background, joystick movement
|
|
1151
|
+
// paddle — Pong-style: two paddles + ball + walls
|
|
1152
|
+
// single_screen — dodge-the-falling-pixels using P0 + M0
|
|
1153
|
+
// music_demo — two-voice TIA chiptune
|
|
1154
|
+
// mini_invaders — gallery shooter via P0 cannon + P1/NUSIZ1 invaders + M0 shot
|
|
1155
|
+
TEMPLATES.atari2600 = {
|
|
1156
|
+
default: {
|
|
1157
|
+
main: "templates/default.asm",
|
|
1158
|
+
runtime: [],
|
|
1159
|
+
lang: "6507 assembly (dasm)",
|
|
1160
|
+
ext: ".a26",
|
|
1161
|
+
describe: "Hello, 2600. Blue background + white player sprite + joystick movement. Race-the-beam scanline-by-scanline rendering; demonstrates VSYNC/VBLANK/visible/overscan frame structure.",
|
|
1162
|
+
},
|
|
1163
|
+
paddle: {
|
|
1164
|
+
main: "templates/paddle.asm",
|
|
1165
|
+
runtime: [],
|
|
1166
|
+
lang: "6507 assembly (dasm)",
|
|
1167
|
+
ext: ".a26",
|
|
1168
|
+
describe: "Pong-style scaffold. Two 8-pixel paddles (P0 + P1), one 2-pixel ball (BL), top + bottom walls (PF). Left paddle on joystick, right paddle AI chases ball Y. Demonstrates multi-object positioning via RESP0/RESP1/RESBL.",
|
|
1169
|
+
},
|
|
1170
|
+
single_screen: {
|
|
1171
|
+
main: "templates/single_screen.asm",
|
|
1172
|
+
runtime: [],
|
|
1173
|
+
lang: "6507 assembly (dasm)",
|
|
1174
|
+
ext: ".a26",
|
|
1175
|
+
describe: "Dodge-the-falling-pixels scaffold. Player at bottom (P0), one falling rock (M0 missile). Demonstrates per-frame missile reset + survive-counter. Extend with multiple missiles, hit detection via TIA collision regs.",
|
|
1176
|
+
},
|
|
1177
|
+
music_demo: {
|
|
1178
|
+
main: "templates/music_demo.asm",
|
|
1179
|
+
runtime: [],
|
|
1180
|
+
lang: "6507 assembly (dasm)",
|
|
1181
|
+
ext: ".a26",
|
|
1182
|
+
describe: "Two-voice TIA chiptune scaffold. Voice 0 = 32-note melody, voice 1 = 16-note bass ostinato, both driven from hand-authored (AUDF, length_frames) note tables in ROM. AUDC0=AUDC1=$04 (pure tone). Music updates happen during VBLANK (never during visible scanlines). Display is minimal — blue BG + a centered playfield band — because the point IS the audio. The note tables ARE the song; edit them and you're writing chiptune.",
|
|
1183
|
+
},
|
|
1184
|
+
mini_invaders: {
|
|
1185
|
+
main: "templates/mini_invaders.asm",
|
|
1186
|
+
runtime: [],
|
|
1187
|
+
lang: "6507 assembly (dasm)",
|
|
1188
|
+
ext: ".a26",
|
|
1189
|
+
describe: "Gallery-shooter (Space-Invaders-shaped) done with the RIGHT TIA objects, not playfield 'barcode' bars: P0 = double-width cannon, P1 + NUSIZ1=%011 = a row of THREE hardware-replicated invaders (one GRP1 write draws all three), M0 = the player shot. Aliens march left/right and drop a step at the edges; fire with the joystick button. The honest 2600-idiomatic way to do this genre — extend by reusing P1 lower for shields or adding M1 as an alien bomb. Verified: marches + renders cannon/aliens/shot.",
|
|
1190
|
+
},
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
// R22: Atari 7800 promoted to multi-template platform. Each template is
|
|
1194
|
+
// a standalone .c file under examples/atari7800/templates/. The 7800's
|
|
1195
|
+
// MARIA architecture (display lists, no traditional tilemap) makes the
|
|
1196
|
+
// scaffolds work differently from the NES — see the comments in each
|
|
1197
|
+
// template for the per-object-DL vs framebuffer trade-off.
|
|
1198
|
+
// R40: TIA sound wrapper for 7800 scaffolds. 2 voices (no noise channel
|
|
1199
|
+
// per se — but distortion mode 8 = white noise). See atari7800_sfx.h.
|
|
1200
|
+
const ATARI7800_SFX_RUNTIME = [
|
|
1201
|
+
{ src: "lib/c/atari7800_sfx.h", dst: "atari7800_sfx.h" },
|
|
1202
|
+
{ src: "lib/c/atari7800_sfx.c", dst: "atari7800_sfx.c" },
|
|
1203
|
+
];
|
|
1204
|
+
// R44: TIA 2-voice music driver — separate runtime since music_demo
|
|
1205
|
+
// pulls in the song-player tables (atari7800_music.*) instead of the
|
|
1206
|
+
// one-shot sfx wrapper. Other scaffolds still use ATARI7800_SFX_RUNTIME.
|
|
1207
|
+
const ATARI7800_MUSIC_RUNTIME = [
|
|
1208
|
+
{ src: "lib/c/atari7800_music.h", dst: "atari7800_music.h" },
|
|
1209
|
+
{ src: "lib/c/atari7800_music.c", dst: "atari7800_music.c" },
|
|
1210
|
+
];
|
|
1211
|
+
|
|
1212
|
+
TEMPLATES.atari7800 = {
|
|
1213
|
+
default: {
|
|
1214
|
+
main: "templates/default.c",
|
|
1215
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1216
|
+
lang: "C (cc65)",
|
|
1217
|
+
ext: ".a78",
|
|
1218
|
+
describe: "Minimal MARIA bring-up: DLL + DL pointing at one 16-pixel sprite + palette + DMA enable. The 7800 has no tilemap — display is a list of objects placed at (zone, x).",
|
|
1219
|
+
},
|
|
1220
|
+
hello_sprite: {
|
|
1221
|
+
main: "templates/hello_sprite.c",
|
|
1222
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1223
|
+
lang: "C (cc65)",
|
|
1224
|
+
ext: ".a78",
|
|
1225
|
+
describe: "Single sprite driven by joystick port A. Vertical movement faked by stamping the sprite at different row offsets within a 24-row canvas — real 7800 games use multi-zone DLLs for Y movement.",
|
|
1226
|
+
},
|
|
1227
|
+
shmup: {
|
|
1228
|
+
main: "templates/shmup.c",
|
|
1229
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1230
|
+
lang: "C (cc65)",
|
|
1231
|
+
ext: ".a78",
|
|
1232
|
+
describe: "Per-object-DL shmup. Each game object (player, bullet, enemy) is one MARIA 5-byte DL header. 4 bullets + 4 enemies in one zone, with X mutated per frame. Demonstrates per-frame DL rebuild + how the 7800 differs from sprite-table consoles.",
|
|
1233
|
+
},
|
|
1234
|
+
platformer: {
|
|
1235
|
+
main: "templates/platformer.c",
|
|
1236
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1237
|
+
lang: "C (cc65)",
|
|
1238
|
+
ext: ".a78",
|
|
1239
|
+
describe: "Single-screen platformer in one zone. Subpixel gravity + jump + ground detection. Vertical movement faked via row-offset stamping into the player's 24-row canvas (Y is encoded by which row of the canvas the sprite starts at).",
|
|
1240
|
+
},
|
|
1241
|
+
puzzle: {
|
|
1242
|
+
main: "templates/puzzle.c",
|
|
1243
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1244
|
+
lang: "C (cc65)",
|
|
1245
|
+
ext: ".a78",
|
|
1246
|
+
describe: "Match-3 falling-block puzzle. 6×12 grid via per-cell MARIA DL entries (one 5-byte header per filled cell). Three palettes for R/G/B colours. Active piece is 3 extra DL entries.",
|
|
1247
|
+
},
|
|
1248
|
+
sports: {
|
|
1249
|
+
main: "templates/sports.c",
|
|
1250
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1251
|
+
lang: "C (cc65)",
|
|
1252
|
+
ext: ".a78",
|
|
1253
|
+
describe: "Two-player Pong on Atari 7800. Both joystick ports wired — SWCHA bits 4-7 = P1, bits 0-3 = P2. AI fallback when P2 isn't plugged in. Three per-object MARIA DL entries (paddles + ball) drawn into tall thin canvases that fit in the 7800's 4 KB RAM.",
|
|
1254
|
+
},
|
|
1255
|
+
racing: {
|
|
1256
|
+
main: "templates/racing.c",
|
|
1257
|
+
runtime: ATARI7800_SFX_RUNTIME,
|
|
1258
|
+
lang: "C (cc65)",
|
|
1259
|
+
ext: ".a78",
|
|
1260
|
+
describe: "Endless 3-lane top-down racer. Per-object MARIA DL pattern (same as the 7800 shmup) — each game object is one 5-byte DL header pointing at a static tile in ROM. LEFT/RIGHT switches lanes, obstacle speed grows with score.",
|
|
1261
|
+
},
|
|
1262
|
+
music_demo: {
|
|
1263
|
+
main: "templates/music_demo.c",
|
|
1264
|
+
runtime: ATARI7800_MUSIC_RUNTIME,
|
|
1265
|
+
lang: "C (cc65)",
|
|
1266
|
+
ext: ".a78",
|
|
1267
|
+
describe: "TIA 2-voice music demo. Hand-authored melody (voice 0, arpeggio + descending walk) and bass (voice 1, walking I-V-IV-V quarters) drive both TIA channels via parallel { distortion, freq, frames } note tables in atari7800_music.c — the tables ARE the song. TIA's 5-bit divider gives ~32 pitches, so the tune sounds primitive on purpose. Minimal pixel-art MUSIC banner on a blue background.",
|
|
1268
|
+
},
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
function pickRomExt(platform) {
|
|
1272
|
+
if (TEMPLATES[platform]) {
|
|
1273
|
+
if (platform === "gbc") return ".gbc";
|
|
1274
|
+
if (platform === "gb") return ".gb";
|
|
1275
|
+
if (platform === "nes") return ".nes";
|
|
1276
|
+
if (platform === "snes") return ".sfc";
|
|
1277
|
+
if (platform === "genesis") return ".bin";
|
|
1278
|
+
if (platform === "c64") return ".prg";
|
|
1279
|
+
if (platform === "sms") return ".sms";
|
|
1280
|
+
if (platform === "gg") return ".gg";
|
|
1281
|
+
if (platform === "atari7800") return ".a78";
|
|
1282
|
+
if (platform === "atari2600") return ".a26";
|
|
1283
|
+
if (platform === "gba") return ".gba";
|
|
1284
|
+
}
|
|
1285
|
+
return SIMPLE_STARTERS[platform]?.ext ?? ".bin";
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Recursively copy every file in `srcDir` to `dstDir`, creating
|
|
1290
|
+
* subdirectories on demand. Each written file's project-relative path
|
|
1291
|
+
* is appended to `writtenFiles` (prefixed with `dstPrefix`, the
|
|
1292
|
+
* relative location under the project root where this subtree lives).
|
|
1293
|
+
*
|
|
1294
|
+
* Used by `runtimeDirs` template entries — currently the SGDK Genesis
|
|
1295
|
+
* template, which ships ~270 header files from src/platforms/genesis/
|
|
1296
|
+
* lib/sgdk/include into the user's project as include/.
|
|
1297
|
+
*
|
|
1298
|
+
* Header files are utf-8; everything else is read as raw bytes so
|
|
1299
|
+
* binary blobs (resource .pic / .pal data, archives) round-trip
|
|
1300
|
+
* unchanged.
|
|
1301
|
+
*/
|
|
1302
|
+
async function copyDirRecursive(fs, path, srcDir, dstDir, writtenFiles, dstPrefix) {
|
|
1303
|
+
await fs.mkdir(dstDir, { recursive: true });
|
|
1304
|
+
const entries = await fs.readdir(srcDir, { withFileTypes: true });
|
|
1305
|
+
for (const ent of entries) {
|
|
1306
|
+
const srcPath = path.join(srcDir, ent.name);
|
|
1307
|
+
const dstPath = path.join(dstDir, ent.name);
|
|
1308
|
+
const relPath = dstPrefix ? `${dstPrefix}/${ent.name}` : ent.name;
|
|
1309
|
+
if (ent.isDirectory()) {
|
|
1310
|
+
await copyDirRecursive(fs, path, srcPath, dstPath, writtenFiles, relPath);
|
|
1311
|
+
} else if (ent.isFile()) {
|
|
1312
|
+
// Skip romdev-internal SDK build-cache artifacts — the .seed.a/.seed.hash
|
|
1313
|
+
// are how romdev's OWN build avoids recompiling the SDK; a user project
|
|
1314
|
+
// never builds the SDK itself, so shipping the prebuilt blob into the
|
|
1315
|
+
// project tree is just noise (and contradicts "everything here is source").
|
|
1316
|
+
if (/\.seed\.(a|hash)$/i.test(ent.name)) continue;
|
|
1317
|
+
const isText = /\.(h|c|s|asm|inc|ld|txt|md|cfg|json)$/i.test(ent.name);
|
|
1318
|
+
const contents = await fs.readFile(srcPath, isText ? "utf-8" : null);
|
|
1319
|
+
await fs.writeFile(dstPath, contents);
|
|
1320
|
+
writtenFiles.push(relPath);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Programmatic equivalent of the createProject MCP tool. Lifted to a
|
|
1327
|
+
* standalone function so createGame can reuse it without going through
|
|
1328
|
+
* the SDK's tool-call surface.
|
|
1329
|
+
*
|
|
1330
|
+
* @param {{platform: string, name: string, path: string, title?: string,
|
|
1331
|
+
* template?: string, overwrite?: boolean}} args
|
|
1332
|
+
* @returns {Promise<object>} the same JSON shape createProject's MCP
|
|
1333
|
+
* handler returns: {path, platform, template, files, sourceFile,
|
|
1334
|
+
* toolchain, nextStep}.
|
|
1335
|
+
*/
|
|
1336
|
+
export async function createProjectImpl({ platform, name, path: projPath, title, template, overwrite = false, withSnippets = false }) {
|
|
1337
|
+
const fs = await import("node:fs/promises");
|
|
1338
|
+
const path = await import("node:path");
|
|
1339
|
+
const { fileURLToPath } = await import("node:url");
|
|
1340
|
+
|
|
1341
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
1342
|
+
const __dirname = path.dirname(__filename);
|
|
1343
|
+
const REPO_ROOT = path.resolve(__dirname, "..", "..", "..");
|
|
1344
|
+
// R37 (revisited): gbc gets its own tree now — color-aware scaffolds,
|
|
1345
|
+
// GBC-specific docs, distinct examples/gbc/templates/ + src/platforms/
|
|
1346
|
+
// gbc/lib/c/. Same Z80 + APU + most VRAM layout as GB, but BCPS/BCPD
|
|
1347
|
+
// palette setup and visibly colorful tile art make the difference.
|
|
1348
|
+
const EXAMPLES_DIR = path.join(REPO_ROOT, "examples", platform);
|
|
1349
|
+
const PLATFORM_LIB_DIR = path.join(REPO_ROOT, "src", "platforms", platform);
|
|
1350
|
+
const CC65_PRESETS_DIR = path.join(REPO_ROOT, "src", "toolchains", "cc65");
|
|
1351
|
+
|
|
1352
|
+
const hasTemplates = !!TEMPLATES[platform];
|
|
1353
|
+
const isSimple = !!SIMPLE_STARTERS[platform];
|
|
1354
|
+
if (!hasTemplates && !isSimple) {
|
|
1355
|
+
throw new Error(`createProject doesn't yet support platform '${platform}'. Supported: ${[...Object.keys(TEMPLATES), ...Object.keys(SIMPLE_STARTERS)].sort().join(", ")}`);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
/** @type {any} */
|
|
1359
|
+
let tmpl = null;
|
|
1360
|
+
let mainFilename;
|
|
1361
|
+
let lang;
|
|
1362
|
+
if (hasTemplates) {
|
|
1363
|
+
const tname = template ?? "default";
|
|
1364
|
+
tmpl = TEMPLATES[platform][tname];
|
|
1365
|
+
if (!tmpl) {
|
|
1366
|
+
throw new Error(`Unknown template '${tname}' for platform '${platform}'. Available: ${Object.keys(TEMPLATES[platform]).join(", ")}`);
|
|
1367
|
+
}
|
|
1368
|
+
const mainExt = path.extname(tmpl.main);
|
|
1369
|
+
mainFilename = `main${mainExt}`;
|
|
1370
|
+
lang = tmpl.lang;
|
|
1371
|
+
} else {
|
|
1372
|
+
if (template) {
|
|
1373
|
+
throw new Error(`Platform '${platform}' has no template variants. Drop the template parameter.`);
|
|
1374
|
+
}
|
|
1375
|
+
mainFilename = SIMPLE_STARTERS[platform].filename;
|
|
1376
|
+
lang = SIMPLE_STARTERS[platform].lang;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
try {
|
|
1380
|
+
const entries = await fs.readdir(projPath);
|
|
1381
|
+
if (entries.length > 0 && !overwrite) {
|
|
1382
|
+
throw new Error(`destination '${projPath}' is not empty. Pass overwrite:true to write anyway.`);
|
|
1383
|
+
}
|
|
1384
|
+
} catch (e) {
|
|
1385
|
+
if (e.code !== "ENOENT") throw e;
|
|
1386
|
+
}
|
|
1387
|
+
await fs.mkdir(projPath, { recursive: true });
|
|
1388
|
+
|
|
1389
|
+
const writtenFiles = [];
|
|
1390
|
+
const mainSrcPath = path.join(EXAMPLES_DIR, hasTemplates ? tmpl.main : mainFilename);
|
|
1391
|
+
const mainContents = await fs.readFile(mainSrcPath, "utf-8");
|
|
1392
|
+
await fs.writeFile(path.join(projPath, mainFilename), mainContents, "utf-8");
|
|
1393
|
+
writtenFiles.push(mainFilename);
|
|
1394
|
+
|
|
1395
|
+
if (tmpl?.runtime) {
|
|
1396
|
+
for (const { src, dst } of tmpl.runtime) {
|
|
1397
|
+
// Detect binary archive files (.a, .o, .bin, .obj) — read as raw bytes,
|
|
1398
|
+
// not utf-8. SGDK's libmd.a is 2.6 MB of m68k object archive that
|
|
1399
|
+
// utf-8 would mangle on copy.
|
|
1400
|
+
const srcPath = path.join(PLATFORM_LIB_DIR, src);
|
|
1401
|
+
const isBinary = /\.(a|o|obj|bin|pic|pal|lib|xgc|xgm|vgm|brr)$/i.test(src);
|
|
1402
|
+
const contents = await fs.readFile(srcPath, isBinary ? null : "utf-8");
|
|
1403
|
+
await fs.writeFile(path.join(projPath, dst), contents);
|
|
1404
|
+
writtenFiles.push(dst);
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// R20 stage 3: runtimeDirs recursively copies a whole directory tree
|
|
1409
|
+
// (used by the SGDK Genesis template to ship the include/ header tree).
|
|
1410
|
+
if (tmpl?.runtimeDirs) {
|
|
1411
|
+
for (const { src, dst } of tmpl.runtimeDirs) {
|
|
1412
|
+
const srcDir = path.join(PLATFORM_LIB_DIR, src);
|
|
1413
|
+
const dstDir = path.join(projPath, dst);
|
|
1414
|
+
await copyDirRecursive(fs, path, srcDir, dstDir, writtenFiles, dst);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
// R58b: auto-vendor cc65 platform libsrc when present. Cheap blanket
|
|
1419
|
+
// policy — every cc65-using platform gets `vendor/cc65/libsrc/<p>/`
|
|
1420
|
+
// dropped into the project unless the template already wired it via
|
|
1421
|
+
// runtimeDirs. The TGI driver, joystick driver, conio, sound engine,
|
|
1422
|
+
// crt0 — all the things an agent would otherwise have to file a
|
|
1423
|
+
// feedback round to debug — now live in their project tree, greppable.
|
|
1424
|
+
// Lynx already wires this via LYNX_VENDOR_DIRS, so the skip-if-present
|
|
1425
|
+
// check below avoids double-copying for it.
|
|
1426
|
+
const cc65SrcDir = path.join(PLATFORM_LIB_DIR, "lib", "cc65-src");
|
|
1427
|
+
const cc65SrcDst = path.join(projPath, "vendor", "cc65", "libsrc", platform);
|
|
1428
|
+
try {
|
|
1429
|
+
await fs.stat(cc65SrcDir); // throws if missing — fine, skip
|
|
1430
|
+
try {
|
|
1431
|
+
await fs.stat(cc65SrcDst); // already copied by an explicit runtimeDir? skip
|
|
1432
|
+
} catch {
|
|
1433
|
+
await copyDirRecursive(fs, path, cc65SrcDir, cc65SrcDst, writtenFiles, `vendor/cc65/libsrc/${platform}`);
|
|
1434
|
+
}
|
|
1435
|
+
} catch {
|
|
1436
|
+
/* no cc65-src for this platform — fine */
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
// R19b: extraSources are additional files from EXAMPLES_DIR (typically
|
|
1440
|
+
// sibling .asm/.s files that the template's main.c references — like a
|
|
1441
|
+
// data.asm providing tilfont/palfont symbols for the SNES C starter).
|
|
1442
|
+
// Distinct from `runtime` (which sources from PLATFORM_LIB_DIR).
|
|
1443
|
+
if (tmpl?.extraSources) {
|
|
1444
|
+
for (const { src, dst } of tmpl.extraSources) {
|
|
1445
|
+
const contents = await fs.readFile(path.join(EXAMPLES_DIR, src), "utf-8");
|
|
1446
|
+
await fs.writeFile(path.join(projPath, dst), contents, "utf-8");
|
|
1447
|
+
writtenFiles.push(dst);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
if (tmpl?.crt0) {
|
|
1452
|
+
const srcPath = tmpl.crt0.presetSrc.startsWith("presets/")
|
|
1453
|
+
? path.join(CC65_PRESETS_DIR, tmpl.crt0.presetSrc)
|
|
1454
|
+
: path.join(PLATFORM_LIB_DIR, tmpl.crt0.presetSrc);
|
|
1455
|
+
const contents = await fs.readFile(srcPath, "utf-8");
|
|
1456
|
+
await fs.writeFile(path.join(projPath, tmpl.crt0.dst), contents, "utf-8");
|
|
1457
|
+
writtenFiles.push(tmpl.crt0.dst);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
if (tmpl?.linkerConfig) {
|
|
1461
|
+
const srcPath = path.join(CC65_PRESETS_DIR, tmpl.linkerConfig.presetSrc);
|
|
1462
|
+
const contents = await fs.readFile(srcPath, "utf-8");
|
|
1463
|
+
await fs.writeFile(path.join(projPath, tmpl.linkerConfig.dst), contents, "utf-8");
|
|
1464
|
+
writtenFiles.push(tmpl.linkerConfig.dst);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// R22: ship MENTAL_MODEL.md + TROUBLESHOOTING.md from src/platforms/
|
|
1468
|
+
// <LIB_PLATFORM>/ into the project tree when they exist. Without this
|
|
1469
|
+
// copy, template comments like "see TROUBLESHOOTING.md" point at a
|
|
1470
|
+
// file the user can't find — they'd have to call getPlatformDoc.
|
|
1471
|
+
// Putting the files alongside the source makes the project a true
|
|
1472
|
+
// self-contained build (you can grep MENTAL_MODEL right next to main.c).
|
|
1473
|
+
for (const docFile of ["MENTAL_MODEL.md", "TROUBLESHOOTING.md"]) {
|
|
1474
|
+
const srcDocPath = path.join(PLATFORM_LIB_DIR, docFile);
|
|
1475
|
+
try {
|
|
1476
|
+
const docContents = await fs.readFile(srcDocPath, "utf-8");
|
|
1477
|
+
await fs.writeFile(path.join(projPath, docFile), docContents, "utf-8");
|
|
1478
|
+
writtenFiles.push(docFile);
|
|
1479
|
+
} catch (e) {
|
|
1480
|
+
if (e.code !== "ENOENT") throw e;
|
|
1481
|
+
/* doc not shipped for this platform — skip */
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
// README + .gitignore generation lives in the MCP handler for now;
|
|
1486
|
+
// both create* tools want the README content, so we duplicate the
|
|
1487
|
+
// small string-building bit here. To keep the diff tight we replicate
|
|
1488
|
+
// it; if we add a third caller we'll factor it out further.
|
|
1489
|
+
const romExt = pickRomExt(platform);
|
|
1490
|
+
const isCc65 = lang.startsWith("C (cc65)") || lang.startsWith("C (cc65 ");
|
|
1491
|
+
const isSdccSm83 = platform === "gb" || platform === "gbc";
|
|
1492
|
+
const isSdccZ80 = platform === "sms" || platform === "gg";
|
|
1493
|
+
|
|
1494
|
+
const c89Note = (isCc65 || isSdccSm83 || isSdccZ80)
|
|
1495
|
+
? `## ⚠️ ${isCc65 ? "cc65" : "SDCC"} is C89
|
|
1496
|
+
|
|
1497
|
+
Compiles **C89**, not C99/C11. Stick to:
|
|
1498
|
+
- Declare loop variables at the top of blocks: \`uint8_t i; for (i = 0; ...) { ... }\`.
|
|
1499
|
+
- All declarations at the top of every block — no mixed declarations + code.
|
|
1500
|
+
- No designated initializers, no compound literals, no \`//\` line comments in some places.
|
|
1501
|
+
|
|
1502
|
+
`
|
|
1503
|
+
: "";
|
|
1504
|
+
const runtimeHeaders = (tmpl?.runtime ?? []).filter((r) => /\.h$/i.test(r.dst));
|
|
1505
|
+
const runtimeAsmIncludes = (tmpl?.runtime ?? []).filter((r) => /\.(s|asm)$/i.test(r.dst));
|
|
1506
|
+
|
|
1507
|
+
let buildBlock;
|
|
1508
|
+
if (tmpl?.linkerConfig) {
|
|
1509
|
+
// NES (cc65 / chr-ram-runtime preset). Build dynamic sourcesPaths so
|
|
1510
|
+
// templates that ship extra .s files (e.g. music_demo with FamiTone2)
|
|
1511
|
+
// get them listed too.
|
|
1512
|
+
const runtimeNonHeaders = (tmpl?.runtime ?? [])
|
|
1513
|
+
.filter((r) => /\.(c|s|asm)$/i.test(r.dst));
|
|
1514
|
+
const srcLines = [
|
|
1515
|
+
` "main.c": "${mainFilename}",`,
|
|
1516
|
+
...runtimeNonHeaders.map((r) => ` "${r.dst}": "${r.dst}",`),
|
|
1517
|
+
` "_preset_crt0.s": "${tmpl.crt0.dst}",`,
|
|
1518
|
+
].join("\n");
|
|
1519
|
+
const incLines = runtimeHeaders.length > 0
|
|
1520
|
+
? runtimeHeaders.map((h) => ` "${h.dst}": "${h.dst}",`).join("\n")
|
|
1521
|
+
: "";
|
|
1522
|
+
buildBlock = "```js\nrunSource({\n platform: \"" + platform + "\",\n sourcesPaths: {\n" + srcLines + "\n },\n" + (incLines ? " includePaths: {\n" + incLines + "\n },\n" : "") + " linkerConfig: /* contents of " + tmpl.linkerConfig.dst + " */,\n frames: 60,\n})\n```";
|
|
1523
|
+
} else if (isSdccSm83) {
|
|
1524
|
+
// GB / GBC (SDCC sm83). runSource BUILDS + RUNS + SCREENSHOTS in one
|
|
1525
|
+
// call AND auto-fixes the cartridge header (Nintendo logo, header +
|
|
1526
|
+
// global checksums, CGB flag on .gbc) — no manual patchGbHeader step.
|
|
1527
|
+
// Derive sources/includes from the template's runtime list so extra
|
|
1528
|
+
// .c files (e.g. music_demo's hUGEDriver) are listed too.
|
|
1529
|
+
const runtimeCs = (tmpl?.runtime ?? []).filter((r) => /\.c$/i.test(r.dst));
|
|
1530
|
+
const srcLines = [` "main.c": "${mainFilename}",`]
|
|
1531
|
+
.concat(runtimeCs.map((r) => ` "${r.dst}": "${r.dst}",`))
|
|
1532
|
+
.join("\n");
|
|
1533
|
+
const incLines = runtimeHeaders.length > 0
|
|
1534
|
+
? runtimeHeaders.map((h) => ` "${h.dst}": "${h.dst}",`).join("\n")
|
|
1535
|
+
: "";
|
|
1536
|
+
buildBlock =
|
|
1537
|
+
"```js\nrunSource({\n" +
|
|
1538
|
+
" platform: \"" + platform + "\",\n" +
|
|
1539
|
+
" sourcesPaths: {\n" + srcLines + "\n },\n" +
|
|
1540
|
+
(incLines ? " includePaths: {\n" + incLines + "\n },\n" : "") +
|
|
1541
|
+
" crt0Path: \"gb_crt0.s\",\n" +
|
|
1542
|
+
" codeLoc: 0x150,\n" +
|
|
1543
|
+
" frames: 60,\n" +
|
|
1544
|
+
"})\n```\n\n" +
|
|
1545
|
+
"`runSource` auto-fixes the GB/GBC cartridge header (logo, checksums, " +
|
|
1546
|
+
"CGB flag) — you do **not** call `patchGbHeader` for a freshly built " +
|
|
1547
|
+
"ROM. Use `patchGbHeader` only to fix up an existing/external ROM on " +
|
|
1548
|
+
"disk or to override header fields (title, cart type, ROM/RAM size).";
|
|
1549
|
+
} else if (isSdccZ80) {
|
|
1550
|
+
const inc = runtimeHeaders.length > 0
|
|
1551
|
+
? `\n includePaths: { ${runtimeHeaders.map((h) => `"${h.dst}": "${h.dst}"`).join(", ")} },`
|
|
1552
|
+
: "";
|
|
1553
|
+
buildBlock = "```js\nrunSource({\n platform: \"" + platform + "\",\n sourcePath: \"" + mainFilename + "\"," + inc + "\n frames: 60,\n})\n```";
|
|
1554
|
+
} else if (platform === "c64") {
|
|
1555
|
+
const inc = runtimeHeaders.length > 0
|
|
1556
|
+
? `\n includePaths: { ${runtimeHeaders.map((h) => `"${h.dst}": "${h.dst}"`).join(", ")} },`
|
|
1557
|
+
: "";
|
|
1558
|
+
buildBlock = "```js\nrunSource({\n platform: \"c64\",\n sourcePath: \"" + mainFilename + "\"," + inc + "\n frames: 60,\n})\n```";
|
|
1559
|
+
} else if (platform === "snes" && /\.c$/i.test(mainFilename)) {
|
|
1560
|
+
// R19b: SNES C-mode template (PVSnesLib runtime auto-linked). Multi-file
|
|
1561
|
+
// build with sibling .asm providing data symbols (tilfont/palfont).
|
|
1562
|
+
//
|
|
1563
|
+
// SFX-enabled scaffolds (shmup/platformer/puzzle/etc.) also ship the
|
|
1564
|
+
// SPC700 driver via SNES_SFX_RUNTIME. Those files split across THREE
|
|
1565
|
+
// build args, and getting the split wrong is the documented footgun:
|
|
1566
|
+
// - snes_sfx_data.asm → a SOURCE (it .incbin's the apu blob; the build
|
|
1567
|
+
// fails with unresolved `apu_blob_end` if it's missing)
|
|
1568
|
+
// - apu_blob.bin → a BINARY include (the .incbin'd payload)
|
|
1569
|
+
// - snes_sfx.h, snes_sfx.c → includePaths; main.c does
|
|
1570
|
+
// `#include "snes_sfx.c"`, so it is NOT a separately compiled source.
|
|
1571
|
+
// The remaining SNES_SFX_RUNTIME files (spc_driver.asm, apu_blob.asm,
|
|
1572
|
+
// *.brr, sample_bank.bin) are rebuild-only — not needed for the build.
|
|
1573
|
+
const rt = tmpl?.runtime ?? [];
|
|
1574
|
+
const has = (dst) => rt.some((r) => r.dst === dst);
|
|
1575
|
+
const sfxSourceAsm = has("snes_sfx_data.asm") ? ["snes_sfx_data.asm"] : [];
|
|
1576
|
+
const sfxIncludes = rt
|
|
1577
|
+
.filter((r) => r.dst === "snes_sfx.h" || r.dst === "snes_sfx.c")
|
|
1578
|
+
.map((r) => r.dst);
|
|
1579
|
+
const sfxBinary = has("apu_blob.bin") ? ["apu_blob.bin"] : [];
|
|
1580
|
+
|
|
1581
|
+
const sourceNames = [mainFilename]
|
|
1582
|
+
.concat((tmpl?.extraSources ?? []).map((e) => e.dst))
|
|
1583
|
+
.concat(sfxSourceAsm);
|
|
1584
|
+
const sourceLines = sourceNames
|
|
1585
|
+
.map((n) => ` "${n}": "${n}",`)
|
|
1586
|
+
.join("\n");
|
|
1587
|
+
const incLines = sfxIncludes
|
|
1588
|
+
.map((n) => ` "${n}": "${n}",`)
|
|
1589
|
+
.join("\n");
|
|
1590
|
+
const binLines = sfxBinary
|
|
1591
|
+
.map((n) => ` "${n}": "${n}",`)
|
|
1592
|
+
.join("\n");
|
|
1593
|
+
|
|
1594
|
+
buildBlock =
|
|
1595
|
+
"```js\nrunSource({\n" +
|
|
1596
|
+
" platform: \"snes\",\n" +
|
|
1597
|
+
" language: \"c\",\n" +
|
|
1598
|
+
" sourcesPaths: {\n" + sourceLines + "\n },\n" +
|
|
1599
|
+
(incLines ? " includePaths: {\n" + incLines + "\n },\n" : "") +
|
|
1600
|
+
(binLines ? " binaryIncludePaths: {\n" + binLines + "\n },\n" : "") +
|
|
1601
|
+
" frames: 120,\n" +
|
|
1602
|
+
"})\n```\n\n" +
|
|
1603
|
+
"PVSnesLib's runtime (crt0_snes, libm, libtcc, libc) is auto-linked. " +
|
|
1604
|
+
"`#include <snes.h>` works out of the box — consoleDrawText, setMode, " +
|
|
1605
|
+
"WaitForVBlank, etc." +
|
|
1606
|
+
(sfxSourceAsm.length
|
|
1607
|
+
? " The SPC700 sound files are split across the three args above on " +
|
|
1608
|
+
"purpose: `snes_sfx_data.asm` is a SOURCE, `apu_blob.bin` is a " +
|
|
1609
|
+
"binary include, and `snes_sfx.{h,c}` are includes (main.c does " +
|
|
1610
|
+
"`#include \"snes_sfx.c\"`). Omit any one and the build fails."
|
|
1611
|
+
: "");
|
|
1612
|
+
} else if (platform === "snes" || platform === "genesis") {
|
|
1613
|
+
// R30: Genesis SGDK templates ship genesis_sfx.{h,c} as runtime helpers.
|
|
1614
|
+
// If the template's runtime list includes .c files, emit a multi-file
|
|
1615
|
+
// sourcesPaths block; otherwise stick with the single-source form.
|
|
1616
|
+
const runtimeCs = (tmpl?.runtime ?? []).filter((r) => /\.c$/i.test(r.dst));
|
|
1617
|
+
if (runtimeCs.length > 0 && /\.c$/i.test(mainFilename)) {
|
|
1618
|
+
const runtimeHs = (tmpl?.runtime ?? []).filter((r) => /\.h$/i.test(r.dst));
|
|
1619
|
+
const srcLines = [` "${mainFilename}": "${mainFilename}",`]
|
|
1620
|
+
.concat(runtimeCs.map((r) => ` "${r.dst}": "${r.dst}",`))
|
|
1621
|
+
.join("\n");
|
|
1622
|
+
const incLine = runtimeHs.length > 0
|
|
1623
|
+
? `\n includePaths: {\n${runtimeHs.map((r) => ` "${r.dst}": "${r.dst}",`).join("\n")}\n },`
|
|
1624
|
+
: "";
|
|
1625
|
+
buildBlock = "```js\nrunSource({\n platform: \"" + platform + "\",\n language: \"c\",\n sourcesPaths: {\n" + srcLines + "\n }," + incLine + "\n frames: 60,\n})\n```";
|
|
1626
|
+
} else {
|
|
1627
|
+
const inc = runtimeAsmIncludes.length > 0
|
|
1628
|
+
? `\n includePaths: { ${runtimeAsmIncludes.map((r) => `"${r.dst}": "${r.dst}"`).join(", ")} },`
|
|
1629
|
+
: "";
|
|
1630
|
+
buildBlock = "```js\nrunSource({\n platform: \"" + platform + "\",\n sourcePath: \"" + mainFilename + "\"," + inc + "\n frames: 60,\n})\n```";
|
|
1631
|
+
}
|
|
1632
|
+
} else if (platform === "gba") {
|
|
1633
|
+
// GBA libtonc / libgba runtimes ship gba_sfx.{h,c} as a tiny DMG-APU
|
|
1634
|
+
// wrapper. Surface multi-file build: main.c + any runtime .c, with
|
|
1635
|
+
// runtime .h files in includePaths.
|
|
1636
|
+
const runtimeCs = (tmpl?.runtime ?? []).filter((r) => /\.c$/i.test(r.dst));
|
|
1637
|
+
const runtimeHs = (tmpl?.runtime ?? []).filter((r) => /\.h$/i.test(r.dst));
|
|
1638
|
+
if (runtimeCs.length > 0) {
|
|
1639
|
+
const srcLines = [` "${mainFilename}": "${mainFilename}",`]
|
|
1640
|
+
.concat(runtimeCs.map((r) => ` "${r.dst}": "${r.dst}",`))
|
|
1641
|
+
.join("\n");
|
|
1642
|
+
const incLine = runtimeHs.length > 0
|
|
1643
|
+
? `\n includePaths: {\n${runtimeHs.map((r) => ` "${r.dst}": "${r.dst}",`).join("\n")}\n },`
|
|
1644
|
+
: "";
|
|
1645
|
+
buildBlock = "```js\nrunSource({\n platform: \"gba\",\n language: \"c\",\n sourcesPaths: {\n" + srcLines + "\n }," + incLine + "\n frames: 60,\n})\n```";
|
|
1646
|
+
} else {
|
|
1647
|
+
buildBlock = "```js\nrunSource({ platform: \"gba\", language: \"c\", sourcePath: \"" + mainFilename + "\", frames: 60 })\n```";
|
|
1648
|
+
}
|
|
1649
|
+
} else {
|
|
1650
|
+
buildBlock = "```js\nrunSource({ platform: \"" + platform + "\", sourcePath: \"" + mainFilename + "\", frames: 60 })\n```";
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
let filesSection = `## Files\n\n- \`${mainFilename}\` — your game's entry point.\n`;
|
|
1654
|
+
if (tmpl?.runtime) {
|
|
1655
|
+
for (const { dst } of tmpl.runtime) {
|
|
1656
|
+
filesSection += `- \`${dst}\` — runtime helper. **You own this** — edit or replace at will.\n`;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
if (tmpl?.crt0) {
|
|
1660
|
+
filesSection += `- \`${tmpl.crt0.dst}\` — startup code (reset vector, NMI handler, hardware vectors). **You own this.**\n`;
|
|
1661
|
+
}
|
|
1662
|
+
if (tmpl?.linkerConfig) {
|
|
1663
|
+
filesSection += `- \`${tmpl.linkerConfig.dst}\` — ld65 linker config (memory layout, segment placement). **You own this.**\n`;
|
|
1664
|
+
}
|
|
1665
|
+
filesSection += `\nEvery byte that compiles into your ROM is in this directory. If you move the repo somewhere else, you don't need to install anything from romdev to rebuild it — the compiler binaries are the only external dependency.\n\n`;
|
|
1666
|
+
|
|
1667
|
+
const readme = `# ${title ?? name}\n\nA ${lang} project for ${platform}, scaffolded by romdev.\n\n${tmpl?.describe ? tmpl.describe + "\n\n" : ""}${filesSection}${c89Note}## Build + run with romdev\n\n${buildBlock}\n\n## Iterating\n\n- Edit \`${mainFilename}\` (or any of the runtime / crt0 / cfg files — they're yours).\n- Call \`runSource\` to see your changes. It builds + loads + runs + screenshots in one round trip.\n- Inspect at byte level: \`readMemory\`, \`inspectSprites\`, \`inspectPalette\`, \`inspectBackgroundMap({render:true})\`.\n- Open a playtest window for human eyes: \`loadCategory({category:"show"}); playtest({});\` — returns immediately, the window follows your rebuilds, and the emulator stays live for every other tool.\n`;
|
|
1668
|
+
await fs.writeFile(path.join(projPath, "README.md"), readme, "utf-8");
|
|
1669
|
+
writtenFiles.push("README.md");
|
|
1670
|
+
|
|
1671
|
+
const gitignore = `# Build outputs\n*${romExt}\n*.o\n*.rel\n*.ihx\n*.lst\n*.map\n*.sym\n*.dbg\n\n# Editor\n.vscode/\n.idea/\n*.swp\n.DS_Store\n`;
|
|
1672
|
+
await fs.writeFile(path.join(projPath, ".gitignore"), gitignore, "utf-8");
|
|
1673
|
+
writtenFiles.push(".gitignore");
|
|
1674
|
+
|
|
1675
|
+
// withSnippets: drop every vetted starter snippet for the platform
|
|
1676
|
+
// into the project dir alongside main.c. Replaces "createProject +
|
|
1677
|
+
// call getAllStarterSnippets + paste 11 files" with one shot.
|
|
1678
|
+
// Snippets that overlap with files we've already written (the
|
|
1679
|
+
// runtime tmpl.runtime list typically includes them) are skipped.
|
|
1680
|
+
const snippetFiles = [];
|
|
1681
|
+
if (withSnippets) {
|
|
1682
|
+
const { listSnippetsForPlatform } = await import("./snippets.js").catch(() => ({}));
|
|
1683
|
+
// Inline minimal duplicate of listSnippetsForPlatform since snippets.js
|
|
1684
|
+
// doesn't export it. Keep this in sync with snippets.js.
|
|
1685
|
+
const LIB_DIR = path.join(PLATFORM_LIB_DIR, "lib");
|
|
1686
|
+
let entries = [];
|
|
1687
|
+
try { entries = await fs.readdir(LIB_DIR); } catch { /* no lib/ */ }
|
|
1688
|
+
const written = new Set(writtenFiles);
|
|
1689
|
+
/** @type {Array<{srcPath: string, dst: string, language: string}>} */
|
|
1690
|
+
const candidates = [];
|
|
1691
|
+
for (const entry of entries.sort()) {
|
|
1692
|
+
if (entry.startsWith(".") || entry === "README.md") continue;
|
|
1693
|
+
const entryPath = path.join(LIB_DIR, entry);
|
|
1694
|
+
let s;
|
|
1695
|
+
try { s = await fs.stat(entryPath); } catch { continue; }
|
|
1696
|
+
if (s.isDirectory()) {
|
|
1697
|
+
const sub = await fs.readdir(entryPath).catch(() => []);
|
|
1698
|
+
for (const f of sub.sort()) {
|
|
1699
|
+
if (f.startsWith(".") || f === "README.md") continue;
|
|
1700
|
+
candidates.push({ srcPath: path.join(entryPath, f), dst: f, language: entry });
|
|
1701
|
+
}
|
|
1702
|
+
} else {
|
|
1703
|
+
const ext = path.extname(entry).toLowerCase();
|
|
1704
|
+
const lang = (ext === ".c" || ext === ".h") ? "c" : "asm";
|
|
1705
|
+
candidates.push({ srcPath: entryPath, dst: entry, language: lang });
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
// For platforms that have a `lang` like "C (SDCC z80)" filter to C
|
|
1709
|
+
// snippets; for asm-only platforms fall through and ship both.
|
|
1710
|
+
const wantsC = /\bC\b/i.test(lang);
|
|
1711
|
+
const wantsAsm = /\b(asm|sdcc|dasm)\b/i.test(lang); // best-effort
|
|
1712
|
+
const filtered = candidates.filter((c) => {
|
|
1713
|
+
if (c.language === "c") return wantsC || !wantsAsm;
|
|
1714
|
+
if (c.language === "asm") return wantsAsm || !wantsC;
|
|
1715
|
+
return true;
|
|
1716
|
+
});
|
|
1717
|
+
for (const c of filtered) {
|
|
1718
|
+
if (written.has(c.dst)) continue; // already written by tmpl.runtime
|
|
1719
|
+
// Binary detection — same heuristic as the runtime copy above.
|
|
1720
|
+
const isBinary = /\.(a|o|obj|bin|pic|pal|lib|xgc|xgm|vgm|brr)$/i.test(c.dst);
|
|
1721
|
+
const contents = await fs.readFile(c.srcPath, isBinary ? null : "utf-8");
|
|
1722
|
+
await fs.writeFile(path.join(projPath, c.dst), contents);
|
|
1723
|
+
writtenFiles.push(c.dst);
|
|
1724
|
+
snippetFiles.push(c.dst);
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
return {
|
|
1729
|
+
path: projPath,
|
|
1730
|
+
platform,
|
|
1731
|
+
template: hasTemplates ? (template ?? "default") : null,
|
|
1732
|
+
files: writtenFiles,
|
|
1733
|
+
snippetsCopied: withSnippets ? snippetFiles : null,
|
|
1734
|
+
sourceFile: path.join(projPath, mainFilename),
|
|
1735
|
+
toolchain: lang,
|
|
1736
|
+
nextStep: `Edit ${path.join(projPath, mainFilename)} and call runSource with sourcesPaths/includePaths pointing at the project's files. Everything you need is in the directory — nothing is hidden.`,
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
export function registerProjectTools(server, z) {
|
|
1741
|
+
server.tool(
|
|
1742
|
+
"createProject",
|
|
1743
|
+
"Use this to scaffold a new homebrew project directory: writes a starter main source + every runtime " +
|
|
1744
|
+
"file the template needs (headers, crt0, linker .cfg) + README + .gitignore. The result is " +
|
|
1745
|
+
"SELF-CONTAINED — every byte that compiles is in the dir, so it rebuilds with stock cc65/sdcc " +
|
|
1746
|
+
"elsewhere with nothing else. `template` defaults to the platform's smallest visible-and-runnable " +
|
|
1747
|
+
"program; most platforms also have hello_sprite/tile_engine + the genre templates (call listPlatforms " +
|
|
1748
|
+
"to see each platform's set). `withSnippets:true` also drops every vetted starter snippet alongside " +
|
|
1749
|
+
"main. (For a complete genre-shaped game baseline, prefer createGame.)",
|
|
1750
|
+
{
|
|
1751
|
+
platform: z.string().describe("Platform id: nes, c64, gb, gbc, sms, gg, atari2600, atari7800, lynx, snes, genesis, gba."),
|
|
1752
|
+
name: z.string().min(1).describe("Project name (used for output binary)."),
|
|
1753
|
+
path: z.string().describe("Absolute path where the project directory will be created."),
|
|
1754
|
+
title: z.string().optional().describe("Optional human-readable title shown in the README."),
|
|
1755
|
+
template: z.string().optional().describe("Template id. NES/GB/GBC: 'default' | 'hello_sprite' | 'tile_engine'. Other platforms with templates only have 'default' — omit this arg. Default is 'default'."),
|
|
1756
|
+
overwrite: z.boolean().default(false).describe("If true, allow writing into an existing non-empty directory."),
|
|
1757
|
+
withSnippets: z.boolean().default(false).describe("If true, also drop every vetted starter snippet for this platform into the project dir alongside main.c. Equivalent to calling copyStarterSnippets after createProject — saves a round trip when you want main.c + every helper without picking a genre template. Snippets that overlap with files the template's runtime already wrote are skipped."),
|
|
1758
|
+
},
|
|
1759
|
+
safeTool(async (args) => jsonContent(await createProjectImpl(args))),
|
|
1760
|
+
);
|
|
1761
|
+
|
|
1762
|
+
// ── createGame — v2 genre-shaped scaffold ─────────────────────────
|
|
1763
|
+
// Thin wrapper over createProjectImpl that takes a `genre` instead of
|
|
1764
|
+
// a `template`. Each genre maps to a corresponding template under
|
|
1765
|
+
// examples/<platform>/ and ships a known-good complete game baseline:
|
|
1766
|
+
// main loop, NMI, OAM init, gameplay slot, music driver wiring. The
|
|
1767
|
+
// agent fills in gameplay-specific logic on top.
|
|
1768
|
+
//
|
|
1769
|
+
// R21: NES + GB/GBC + SNES + Genesis with three genres each (shmup,
|
|
1770
|
+
// platformer, puzzle). Per-platform extension follows demand. Recipes
|
|
1771
|
+
// for other platforms can be added by registering an entry in the
|
|
1772
|
+
// GENRE_MAP below and shipping matching template files under
|
|
1773
|
+
// examples/<platform>/templates/.
|
|
1774
|
+
server.tool(
|
|
1775
|
+
"createGame",
|
|
1776
|
+
"Scaffold a genre-shaped game project. Higher-level than createProject — " +
|
|
1777
|
+
"picks the right template + runtime + crt0 + linker config for the genre. " +
|
|
1778
|
+
"Available genres on every supported platform: 'shmup' (vertical shooter), " +
|
|
1779
|
+
"'platformer' (side-scrolling + gravity, except NES which is single-screen), " +
|
|
1780
|
+
"'puzzle' (match-3 falling blocks), " +
|
|
1781
|
+
"'sports' (Pong — two controllers wired where the hardware supports it, " +
|
|
1782
|
+
"player-vs-AI on GB/GBC), 'racing' (3-lane top-down lane-switch dodge). " +
|
|
1783
|
+
"Supported platforms: nes, gb, gbc, snes, genesis, sms, gg, c64, gba, lynx, atari7800. " +
|
|
1784
|
+
"Each scaffolds a complete working ROM you can build + run + screenshot " +
|
|
1785
|
+
"in one round trip — fill in gameplay-specific logic on top of the " +
|
|
1786
|
+
"known-good baseline.",
|
|
1787
|
+
{
|
|
1788
|
+
platform: z.string().describe("Platform id. Today: 'nes' | 'gb' | 'gbc' | 'snes' | 'genesis' | 'sms' | 'gg' | 'c64' | 'gba' | 'lynx' | 'atari7800'."),
|
|
1789
|
+
genre: z.string().describe("Genre id: 'shmup' | 'platformer' | 'puzzle' | 'sports' | 'racing' — all five available on every supported platform."),
|
|
1790
|
+
name: z.string().min(1).describe("Project name (used for output binary)."),
|
|
1791
|
+
path: z.string().describe("Absolute path where the project directory will be created."),
|
|
1792
|
+
title: z.string().optional().describe("Optional human-readable title shown in the README."),
|
|
1793
|
+
overwrite: z.boolean().default(false).describe("If true, allow writing into an existing non-empty directory."),
|
|
1794
|
+
},
|
|
1795
|
+
safeTool(async ({ platform, genre, name, path: projPath, title, overwrite }) => {
|
|
1796
|
+
// The five canonical genres. A genre is available on a platform iff
|
|
1797
|
+
// TEMPLATES[platform] has a matching template entry — we DERIVE
|
|
1798
|
+
// availability from TEMPLATES rather than maintain a parallel table,
|
|
1799
|
+
// so createGame can never drift out of sync with the registered
|
|
1800
|
+
// templates (R61: the old hardcoded GENRE_MAP did exactly that — it
|
|
1801
|
+
// omitted c64/gba/lynx even though their genre templates were registered).
|
|
1802
|
+
//
|
|
1803
|
+
// R23 + R23e note: GB / GBC have no native 2P hardware (no second
|
|
1804
|
+
// controller port; the link cable would need custom serial code),
|
|
1805
|
+
// so their `sports` template is player-vs-AI. Everywhere else port 1
|
|
1806
|
+
// is a real second pad with AI fallback when none is plugged in.
|
|
1807
|
+
const CANONICAL_GENRES = ["shmup", "platformer", "puzzle", "sports", "racing"];
|
|
1808
|
+
const platformTemplates = TEMPLATES[platform];
|
|
1809
|
+
// Platforms that ship genre scaffolds = those whose TEMPLATES entry
|
|
1810
|
+
// has at least one canonical genre key.
|
|
1811
|
+
const genrePlatforms = Object.keys(TEMPLATES).filter((p) =>
|
|
1812
|
+
CANONICAL_GENRES.some((g) => TEMPLATES[p] && TEMPLATES[p][g])
|
|
1813
|
+
);
|
|
1814
|
+
const availableGenres = platformTemplates
|
|
1815
|
+
? CANONICAL_GENRES.filter((g) => platformTemplates[g])
|
|
1816
|
+
: [];
|
|
1817
|
+
if (availableGenres.length === 0) {
|
|
1818
|
+
throw new Error(
|
|
1819
|
+
`createGame: no genre scaffolds for platform '${platform}' yet. ` +
|
|
1820
|
+
`Supported platforms: ${genrePlatforms.join(", ") || "(none)"}. ` +
|
|
1821
|
+
`For other platforms, use createProject({platform, template:"default"}) and build up from there.`
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1824
|
+
if (!availableGenres.includes(genre)) {
|
|
1825
|
+
throw new Error(
|
|
1826
|
+
`createGame: genre '${genre}' not supported for platform '${platform}'. ` +
|
|
1827
|
+
`Available genres: ${availableGenres.join(", ")}.`
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
// Genre id IS the template id (they're 1:1 by construction).
|
|
1831
|
+
const templateId = genre;
|
|
1832
|
+
const result = await createProjectImpl({
|
|
1833
|
+
platform, template: templateId, name, path: projPath, title, overwrite,
|
|
1834
|
+
});
|
|
1835
|
+
return jsonContent({ ...result, genre, template: templateId });
|
|
1836
|
+
}),
|
|
1837
|
+
);
|
|
1838
|
+
|
|
1839
|
+
server.tool(
|
|
1840
|
+
"patchGbHeader",
|
|
1841
|
+
"Use this to write a complete, valid GB/GBC cartridge header into a ROM: Nintendo boot logo, EVERY " +
|
|
1842
|
+
"header byte ($0134-$014C — title, CGB flag, cart type, ROM/RAM size, etc.) with ROM-only defaults, " +
|
|
1843
|
+
"plus the header + global checksums. SDCC-path equivalent of `rgbfix -v -p 0`. Fills ALL bytes " +
|
|
1844
|
+
"deliberately: leaving the CGB flag as the linker's $FF pad makes gambatte enter CGB mode and ignore " +
|
|
1845
|
+
"DMG palette writes → white screen. Also shipped as `patch-header.js` in every GB/GBC project for use " +
|
|
1846
|
+
"outside MCP.",
|
|
1847
|
+
{
|
|
1848
|
+
path: z.string().describe("Absolute path to the .gb / .gbc ROM file. Patched in place unless outputPath is given."),
|
|
1849
|
+
outputPath: z.string().optional().describe("If given, write the patched ROM here instead of overwriting."),
|
|
1850
|
+
cgb: z.boolean().optional().describe("If true, sets the CGB flag at $0143 to $80 (CGB-aware + DMG-compatible). If omitted, auto-detects from .gbc extension; default for plain .gb is false (DMG-only)."),
|
|
1851
|
+
title: z.string().optional().describe("Cartridge title, up to 11 chars at $0134..$013E. Uppercased + zero-padded. Default = zero-fill."),
|
|
1852
|
+
cartType: z.number().int().min(0).max(0xFF).optional().describe("Cart-type byte at $0147. Default $00 (ROM-only). Common alternatives: $01=MBC1, $03=MBC1+RAM+BAT, $11=MBC3, $13=MBC3+RAM+BAT, $19=MBC5."),
|
|
1853
|
+
romSize: z.number().int().min(0).max(0xFF).optional().describe("ROM-size byte at $0148. Default $00 (32 KB / 2 banks). 1=64KB, 2=128KB, 3=256KB, 4=512KB, 5=1MB, 6=2MB, 7=4MB."),
|
|
1854
|
+
ramSize: z.number().int().min(0).max(0xFF).optional().describe("RAM-size byte at $0149. Default $00 (none). $02=8KB, $03=32KB. Only meaningful with battery-backed MBC."),
|
|
1855
|
+
destination: z.number().int().min(0).max(0xFF).optional().describe("Destination at $014A. Default $01 (non-Japan). $00 = Japan."),
|
|
1856
|
+
},
|
|
1857
|
+
safeTool(async ({ path: inPath, outputPath, cgb, title, cartType, romSize, ramSize, destination }) => {
|
|
1858
|
+
const rom = new Uint8Array(await readFile(inPath));
|
|
1859
|
+
const cgbFlag = cgb ?? (/\.gbc$/i.test(inPath) || (outputPath && /\.gbc$/i.test(outputPath)));
|
|
1860
|
+
patchGbHeader(rom, { cgb: cgbFlag, title, cartType, romSize, ramSize, destination });
|
|
1861
|
+
const outPath = outputPath ?? inPath;
|
|
1862
|
+
await writeFile(outPath, rom);
|
|
1863
|
+
return jsonContent({
|
|
1864
|
+
path: outPath,
|
|
1865
|
+
bytes: rom.length,
|
|
1866
|
+
cgb: !!cgbFlag,
|
|
1867
|
+
patched: [
|
|
1868
|
+
"nintendo_logo@$0104..$0133",
|
|
1869
|
+
"title@$0134..$013E",
|
|
1870
|
+
`cgb_flag@$0143=${cgbFlag ? "$80" : "$00"}`,
|
|
1871
|
+
"licensee@$0144..$0145=$00$00",
|
|
1872
|
+
"sgb_flag@$0146=$00",
|
|
1873
|
+
`cart_type@$0147=$${(cartType ?? 0).toString(16).padStart(2, "0").toUpperCase()}`,
|
|
1874
|
+
`rom_size@$0148=$${(romSize ?? 0).toString(16).padStart(2, "0").toUpperCase()}`,
|
|
1875
|
+
`ram_size@$0149=$${(ramSize ?? 0).toString(16).padStart(2, "0").toUpperCase()}`,
|
|
1876
|
+
`destination@$014A=$${(destination ?? 1).toString(16).padStart(2, "0").toUpperCase()}`,
|
|
1877
|
+
"old_licensee@$014B=$33",
|
|
1878
|
+
"rom_version@$014C=$00",
|
|
1879
|
+
"header_checksum@$014D",
|
|
1880
|
+
"global_checksum@$014E..$014F",
|
|
1881
|
+
],
|
|
1882
|
+
});
|
|
1883
|
+
}),
|
|
1884
|
+
);
|
|
1885
|
+
}
|