c64-kb 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2082 -0
- package/LICENSE +29 -0
- package/README.md +559 -0
- package/VERSION +25 -0
- package/dist/cli/setup.js +66 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli-memorize-audit.js +97 -0
- package/dist/cli-memorize-audit.js.map +1 -0
- package/dist/cli.js +335 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +53 -0
- package/dist/context.js.map +1 -0
- package/dist/domain/budget-notes.js +104 -0
- package/dist/domain/budget-notes.js.map +1 -0
- package/dist/domain/budget.js +417 -0
- package/dist/domain/budget.js.map +1 -0
- package/dist/domain/game-design.js +77 -0
- package/dist/domain/game-design.js.map +1 -0
- package/dist/domain/timing.js +39 -0
- package/dist/domain/timing.js.map +1 -0
- package/dist/graph/apply.js +132 -0
- package/dist/graph/apply.js.map +1 -0
- package/dist/graph/claims.js +231 -0
- package/dist/graph/claims.js.map +1 -0
- package/dist/graph/extract/archetype.js +118 -0
- package/dist/graph/extract/archetype.js.map +1 -0
- package/dist/graph/extract/common.js +69 -0
- package/dist/graph/extract/common.js.map +1 -0
- package/dist/graph/extract/failure.js +37 -0
- package/dist/graph/extract/failure.js.map +1 -0
- package/dist/graph/extract/game-design.js +189 -0
- package/dist/graph/extract/game-design.js.map +1 -0
- package/dist/graph/extract/hardware.js +124 -0
- package/dist/graph/extract/hardware.js.map +1 -0
- package/dist/graph/extract/pitfall.js +62 -0
- package/dist/graph/extract/pitfall.js.map +1 -0
- package/dist/graph/extract/raster-band.js +56 -0
- package/dist/graph/extract/raster-band.js.map +1 -0
- package/dist/graph/extract/recipe.js +71 -0
- package/dist/graph/extract/recipe.js.map +1 -0
- package/dist/graph/extract/technique-entities.js +180 -0
- package/dist/graph/extract/technique-entities.js.map +1 -0
- package/dist/graph/extract/technique.js +179 -0
- package/dist/graph/extract/technique.js.map +1 -0
- package/dist/graph/extract/toolchain.js +67 -0
- package/dist/graph/extract/toolchain.js.map +1 -0
- package/dist/graph/extract/types.js +3 -0
- package/dist/graph/extract/types.js.map +1 -0
- package/dist/graph/extract/vocabulary.js +65 -0
- package/dist/graph/extract/vocabulary.js.map +1 -0
- package/dist/graph/extract.js +43 -0
- package/dist/graph/extract.js.map +1 -0
- package/dist/graph/kernal-clobbers.js +64 -0
- package/dist/graph/kernal-clobbers.js.map +1 -0
- package/dist/graph/machine-variants.js +208 -0
- package/dist/graph/machine-variants.js.map +1 -0
- package/dist/ingest/files.js +99 -0
- package/dist/ingest/files.js.map +1 -0
- package/dist/ingest/passes.js +104 -0
- package/dist/ingest/passes.js.map +1 -0
- package/dist/ingest/points.js +50 -0
- package/dist/ingest/points.js.map +1 -0
- package/dist/ingest/report.js +140 -0
- package/dist/ingest/report.js.map +1 -0
- package/dist/ingest/tally.js +81 -0
- package/dist/ingest/tally.js.map +1 -0
- package/dist/ingest/verified-on.js +43 -0
- package/dist/ingest/verified-on.js.map +1 -0
- package/dist/ingest.js +135 -0
- package/dist/ingest.js.map +1 -0
- package/dist/schemas/cost-basis.js +5 -0
- package/dist/schemas/cost-basis.js.map +1 -0
- package/dist/schemas/machine-variant.js +25 -0
- package/dist/schemas/machine-variant.js.map +1 -0
- package/dist/schemas/plan-budget.js +121 -0
- package/dist/schemas/plan-budget.js.map +1 -0
- package/dist/schemas/tool-outputs.js +526 -0
- package/dist/schemas/tool-outputs.js.map +1 -0
- package/dist/server/define-tool.js +52 -0
- package/dist/server/define-tool.js.map +1 -0
- package/dist/server/defined-only.js +9 -0
- package/dist/server/defined-only.js.map +1 -0
- package/dist/server/tools-briefings.js +70 -0
- package/dist/server/tools-briefings.js.map +1 -0
- package/dist/server/tools-lookup.js +180 -0
- package/dist/server/tools-lookup.js.map +1 -0
- package/dist/server/tools-maintenance.js +116 -0
- package/dist/server/tools-maintenance.js.map +1 -0
- package/dist/server/tools-pitfalls.js +89 -0
- package/dist/server/tools-pitfalls.js.map +1 -0
- package/dist/server/tools-recipes.js +296 -0
- package/dist/server/tools-recipes.js.map +1 -0
- package/dist/server/tools-runtime.js +48 -0
- package/dist/server/tools-runtime.js.map +1 -0
- package/dist/server/tools.js +43 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/server.js +95 -0
- package/dist/server.js.map +1 -0
- package/dist/services/analytics/schema.js +78 -0
- package/dist/services/analytics/schema.js.map +1 -0
- package/dist/services/analytics/statements.js +99 -0
- package/dist/services/analytics/statements.js.map +1 -0
- package/dist/services/analytics.js +195 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/bm25.js +158 -0
- package/dist/services/bm25.js.map +1 -0
- package/dist/services/chunker.js +81 -0
- package/dist/services/chunker.js.map +1 -0
- package/dist/services/embeddings.js +58 -0
- package/dist/services/embeddings.js.map +1 -0
- package/dist/services/falkor/base.js +85 -0
- package/dist/services/falkor/base.js.map +1 -0
- package/dist/services/falkor/links.js +361 -0
- package/dist/services/falkor/links.js.map +1 -0
- package/dist/services/falkor/nodes.js +183 -0
- package/dist/services/falkor/nodes.js.map +1 -0
- package/dist/services/falkor/params.js +45 -0
- package/dist/services/falkor/params.js.map +1 -0
- package/dist/services/falkor/schema.js +77 -0
- package/dist/services/falkor/schema.js.map +1 -0
- package/dist/services/falkor.js +100 -0
- package/dist/services/falkor.js.map +1 -0
- package/dist/services/qdrant.js +238 -0
- package/dist/services/qdrant.js.map +1 -0
- package/dist/services/versions.js +73 -0
- package/dist/services/versions.js.map +1 -0
- package/dist/services/vice-bin.js +51 -0
- package/dist/services/vice-bin.js.map +1 -0
- package/dist/tools/briefings/archetype.js +174 -0
- package/dist/tools/briefings/archetype.js.map +1 -0
- package/dist/tools/briefings/budget.js +177 -0
- package/dist/tools/briefings/budget.js.map +1 -0
- package/dist/tools/briefings/build-order.js +135 -0
- package/dist/tools/briefings/build-order.js.map +1 -0
- package/dist/tools/briefings/build.js +185 -0
- package/dist/tools/briefings/build.js.map +1 -0
- package/dist/tools/briefings/discovery.js +290 -0
- package/dist/tools/briefings/discovery.js.map +1 -0
- package/dist/tools/briefings/plan-pitfalls.js +69 -0
- package/dist/tools/briefings/plan-pitfalls.js.map +1 -0
- package/dist/tools/briefings/render.js +151 -0
- package/dist/tools/briefings/render.js.map +1 -0
- package/dist/tools/briefings/rows.js +41 -0
- package/dist/tools/briefings/rows.js.map +1 -0
- package/dist/tools/briefings/toolchain.js +63 -0
- package/dist/tools/briefings/toolchain.js.map +1 -0
- package/dist/tools/briefings/why-proposed.js +69 -0
- package/dist/tools/briefings/why-proposed.js.map +1 -0
- package/dist/tools/briefings.js +44 -0
- package/dist/tools/briefings.js.map +1 -0
- package/dist/tools/feedback.js +97 -0
- package/dist/tools/feedback.js.map +1 -0
- package/dist/tools/hydrate.js +75 -0
- package/dist/tools/hydrate.js.map +1 -0
- package/dist/tools/intelligence.js +67 -0
- package/dist/tools/intelligence.js.map +1 -0
- package/dist/tools/lint/asm-decimal.js +86 -0
- package/dist/tools/lint/asm-decimal.js.map +1 -0
- package/dist/tools/lint/asm-rules.js +221 -0
- package/dist/tools/lint/asm-rules.js.map +1 -0
- package/dist/tools/lint/asm-shared.js +3 -0
- package/dist/tools/lint/asm-shared.js.map +1 -0
- package/dist/tools/lint/c-rules.js +215 -0
- package/dist/tools/lint/c-rules.js.map +1 -0
- package/dist/tools/lint/text.js +122 -0
- package/dist/tools/lint/text.js.map +1 -0
- package/dist/tools/lint/types.js +40 -0
- package/dist/tools/lint/types.js.map +1 -0
- package/dist/tools/lint.js +76 -0
- package/dist/tools/lint.js.map +1 -0
- package/dist/tools/memorization-mcp.js +111 -0
- package/dist/tools/memorization-mcp.js.map +1 -0
- package/dist/tools/pitfalls/bm25.js +53 -0
- package/dist/tools/pitfalls/bm25.js.map +1 -0
- package/dist/tools/pitfalls/format.js +58 -0
- package/dist/tools/pitfalls/format.js.map +1 -0
- package/dist/tools/pitfalls/graph.js +124 -0
- package/dist/tools/pitfalls/graph.js.map +1 -0
- package/dist/tools/pitfalls.js +134 -0
- package/dist/tools/pitfalls.js.map +1 -0
- package/dist/tools/prompts.js +81 -0
- package/dist/tools/prompts.js.map +1 -0
- package/dist/tools/query/compatibility/closure.js +62 -0
- package/dist/tools/query/compatibility/closure.js.map +1 -0
- package/dist/tools/query/compatibility/facts.js +28 -0
- package/dist/tools/query/compatibility/facts.js.map +1 -0
- package/dist/tools/query/compatibility/fetch.js +164 -0
- package/dist/tools/query/compatibility/fetch.js.map +1 -0
- package/dist/tools/query/compatibility/hard-rules.js +159 -0
- package/dist/tools/query/compatibility/hard-rules.js.map +1 -0
- package/dist/tools/query/compatibility/index.js +27 -0
- package/dist/tools/query/compatibility/index.js.map +1 -0
- package/dist/tools/query/compatibility/kernal-zp-rule.js +90 -0
- package/dist/tools/query/compatibility/kernal-zp-rule.js.map +1 -0
- package/dist/tools/query/compatibility/render.js +106 -0
- package/dist/tools/query/compatibility/render.js.map +1 -0
- package/dist/tools/query/compatibility/rules.js +337 -0
- package/dist/tools/query/compatibility/rules.js.map +1 -0
- package/dist/tools/query/compatibility/unit-rules.js +253 -0
- package/dist/tools/query/compatibility/unit-rules.js.map +1 -0
- package/dist/tools/query/game-design.js +83 -0
- package/dist/tools/query/game-design.js.map +1 -0
- package/dist/tools/query/lookups.js +220 -0
- package/dist/tools/query/lookups.js.map +1 -0
- package/dist/tools/query/plan-budget.js +266 -0
- package/dist/tools/query/plan-budget.js.map +1 -0
- package/dist/tools/query/recipes.js +214 -0
- package/dist/tools/query/recipes.js.map +1 -0
- package/dist/tools/query/retrieval.js +128 -0
- package/dist/tools/query/retrieval.js.map +1 -0
- package/dist/tools/query/shared.js +121 -0
- package/dist/tools/query/shared.js.map +1 -0
- package/dist/tools/query/techniques.js +331 -0
- package/dist/tools/query/techniques.js.map +1 -0
- package/dist/tools/query/timing.js +106 -0
- package/dist/tools/query/timing.js.map +1 -0
- package/dist/tools/query/types.js +11 -0
- package/dist/tools/query/types.js.map +1 -0
- package/dist/tools/query.js +21 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/resources.js +186 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/run-game.js +249 -0
- package/dist/tools/run-game.js.map +1 -0
- package/dist/tools/selfimprovement.js +367 -0
- package/dist/tools/selfimprovement.js.map +1 -0
- package/docker-compose.yml +35 -0
- package/docs/ARCHITECTURE.md +164 -0
- package/docs/CONVENTIONS-archetypes.md +158 -0
- package/docs/CONVENTIONS-failures.md +46 -0
- package/docs/CONVENTIONS-game-designs.md +75 -0
- package/docs/CONVENTIONS-hardware-reference.md +184 -0
- package/docs/CONVENTIONS-pitfalls.md +91 -0
- package/docs/CONVENTIONS-recipes.md +106 -0
- package/docs/CONVENTIONS-techniques.md +309 -0
- package/docs/CONVENTIONS-toolchain-reference.md +89 -0
- package/docs/ONTOLOGY.md +655 -0
- package/docs/art/art-production-reference.md +157 -0
- package/docs/art/asset-pipelines.md +586 -0
- package/docs/c64-failure-patterns.md +693 -0
- package/docs/demo-design/demo-composition.md +349 -0
- package/docs/demo-design/demo-design-philosophy.md +320 -0
- package/docs/demo-design/intro-cracktro-patterns.md +435 -0
- package/docs/figures/ctm-spd-embed-probe.png +0 -0
- package/docs/figures/dot-flag-mid-5000000.png +0 -0
- package/docs/figures/dot-flag-no-erase-12000000.png +0 -0
- package/docs/figures/edges.json +1 -0
- package/docs/figures/fig6-architecture.png +0 -0
- package/docs/figures/fig7-ontology.png +0 -0
- package/docs/figures/screen-dissolve-mid-frame25.png +0 -0
- package/docs/figures/screen-dissolve-wipe-frame25.png +0 -0
- package/docs/figures/spindle-two-parts-part1.png +0 -0
- package/docs/figures/spindle-two-parts-part2.png +0 -0
- package/docs/figures/starters/action-puzzle.png +0 -0
- package/docs/figures/starters/adventure.png +0 -0
- package/docs/figures/starters/beat-em-up.png +0 -0
- package/docs/figures/starters/demo.png +0 -0
- package/docs/figures/starters/platformer.png +0 -0
- package/docs/figures/starters/shmup-vertical.png +0 -0
- package/docs/figures/tape-kernal-master-ntsc.png +0 -0
- package/docs/figures/tape-kernal-master-pal.png +0 -0
- package/docs/figures/tape-turbo-loader-ntsc.png +0 -0
- package/docs/figures/tape-turbo-loader-pal.png +0 -0
- package/docs/figures/tape-turbo-master-ntsc.png +0 -0
- package/docs/figures/tape-turbo-master-pal.png +0 -0
- package/docs/figures/tech-tech-pad2-12000000.png +0 -0
- package/docs/figures/tech-tech-pad4-12000000.png +0 -0
- package/docs/figures/tech-tech-seven-12000000.png +0 -0
- package/docs/figures/twister-mid-5000000.png +0 -0
- package/docs/figures/twister-straight-12000000.png +0 -0
- package/docs/figures/vector-balls-nosort-ntsc.png +0 -0
- package/docs/figures/vector-balls-nosort.png +0 -0
- package/docs/formats/c64-file-formats.md +1212 -0
- package/docs/formats/iec-disk-reference.md +754 -0
- package/docs/game-design/c64-game-archetypes.md +273 -0
- package/docs/game-design/designs/falling-blocks.md +54 -0
- package/docs/game-design/designs/platformer-scaffold.md +48 -0
- package/docs/game-design/designs/simple-shmup.md +27 -0
- package/docs/game-design/enemy-behaviour-and-difficulty.md +349 -0
- package/docs/game-design/game-design-patterns.md +1189 -0
- package/docs/game-design/game-structure.md +354 -0
- package/docs/game-design/production-planning.md +349 -0
- package/docs/game-design/reference-game-sources.md +90 -0
- package/docs/hardware/6502-illegal-opcodes.md +1353 -0
- package/docs/hardware/6510-cpu-reference.md +2112 -0
- package/docs/hardware/c64-memory-map.md +3184 -0
- package/docs/hardware/c64-registers-reference.md +996 -0
- package/docs/hardware/cia-reference.md +1281 -0
- package/docs/hardware/kernal-routines-reference.md +1836 -0
- package/docs/hardware/pal-ntsc-reference.md +813 -0
- package/docs/hardware/sid-reference.md +1137 -0
- package/docs/hardware/vic-ii-reference.md +1714 -0
- package/docs/music/music-production-reference.md +403 -0
- package/docs/pitfalls/banking.md +1067 -0
- package/docs/pitfalls/cia.md +1147 -0
- package/docs/pitfalls/cpu.md +874 -0
- package/docs/pitfalls/input.md +282 -0
- package/docs/pitfalls/kernal-and-io.md +1615 -0
- package/docs/pitfalls/loader.md +1191 -0
- package/docs/pitfalls/logic.md +94 -0
- package/docs/pitfalls/maths.md +187 -0
- package/docs/pitfalls/raster-and-badline.md +721 -0
- package/docs/pitfalls/region-timing.md +660 -0
- package/docs/pitfalls/scroll.md +207 -0
- package/docs/pitfalls/sid.md +738 -0
- package/docs/pitfalls/sprite.md +979 -0
- package/docs/pitfalls/text-mode-render.md +1172 -0
- package/docs/recipes/cc65/cartridge-8k.md +398 -0
- package/docs/recipes/cc65/hello-world-conio.md +76 -0
- package/docs/recipes/cc65/memory-layout.md +312 -0
- package/docs/recipes/cc65/screenshots/README.md +14 -0
- package/docs/recipes/cc65/screenshots/cartridge-8k-ntsc.png +0 -0
- package/docs/recipes/cc65/screenshots/cartridge-8k.png +0 -0
- package/docs/recipes/cc65/screenshots/hello-world-conio.png +0 -0
- package/docs/recipes/cc65/screenshots/memory-layout-ntsc.png +0 -0
- package/docs/recipes/cc65/screenshots/memory-layout.png +0 -0
- package/docs/recipes/kickassembler/basic-float-calls.md +578 -0
- package/docs/recipes/kickassembler/basic-wedge.md +398 -0
- package/docs/recipes/kickassembler/big-font-scroller.md +620 -0
- package/docs/recipes/kickassembler/charset-copy-rom-to-ram.md +623 -0
- package/docs/recipes/kickassembler/cia-revision-detect.md +366 -0
- package/docs/recipes/kickassembler/colour-cycling.md +343 -0
- package/docs/recipes/kickassembler/colour-fade.md +303 -0
- package/docs/recipes/kickassembler/compare-16bit-signed.md +1007 -0
- package/docs/recipes/kickassembler/cracktro-template.md +526 -0
- package/docs/recipes/kickassembler/crt-banked.md +276 -0
- package/docs/recipes/kickassembler/dos-error-codes.md +466 -0
- package/docs/recipes/kickassembler/dot-flag.md +576 -0
- package/docs/recipes/kickassembler/drive-job-queue.md +667 -0
- package/docs/recipes/kickassembler/drive-via-probe.md +690 -0
- package/docs/recipes/kickassembler/dycp-scroller.md +568 -0
- package/docs/recipes/kickassembler/dypp-sprite-scroller.md +681 -0
- package/docs/recipes/kickassembler/dysp.md +670 -0
- package/docs/recipes/kickassembler/easyflash-save.md +800 -0
- package/docs/recipes/kickassembler/eight-way-scroll.md +1484 -0
- package/docs/recipes/kickassembler/file-io-roundtrip.md +546 -0
- package/docs/recipes/kickassembler/fire-effect.md +420 -0
- package/docs/recipes/kickassembler/fld.md +414 -0
- package/docs/recipes/kickassembler/fli-image.md +336 -0
- package/docs/recipes/kickassembler/four-player-read.md +672 -0
- package/docs/recipes/kickassembler/headless-verify.md +228 -0
- package/docs/recipes/kickassembler/hello-world.md +98 -0
- package/docs/recipes/kickassembler/high-score-insert.md +660 -0
- package/docs/recipes/kickassembler/hires-plot-line.md +723 -0
- package/docs/recipes/kickassembler/irq-chain.md +316 -0
- package/docs/recipes/kickassembler/irq-owns-port.md +668 -0
- package/docs/recipes/kickassembler/isometric-room.md +1145 -0
- package/docs/recipes/kickassembler/light-pen-read.md +926 -0
- package/docs/recipes/kickassembler/logic-rate-decoupling.md +670 -0
- package/docs/recipes/kickassembler/mci-interlace.md +543 -0
- package/docs/recipes/kickassembler/memory-layout.md +277 -0
- package/docs/recipes/kickassembler/mouse-1351-read.md +801 -0
- package/docs/recipes/kickassembler/nmi-timer-tick.md +562 -0
- package/docs/recipes/kickassembler/own-keyscan.md +881 -0
- package/docs/recipes/kickassembler/paddle-read.md +751 -0
- package/docs/recipes/kickassembler/palette-cells.md +219 -0
- package/docs/recipes/kickassembler/pseudo-3d-road.md +930 -0
- package/docs/recipes/kickassembler/pwm-digi.md +463 -0
- package/docs/recipes/kickassembler/raster-bars.md +264 -0
- package/docs/recipes/kickassembler/reu-dma.md +1019 -0
- package/docs/recipes/kickassembler/runtime-relocation.md +743 -0
- package/docs/recipes/kickassembler/screen-dissolve.md +545 -0
- package/docs/recipes/kickassembler/screen-wipe.md +408 -0
- package/docs/recipes/kickassembler/screenshots/README.md +72 -0
- package/docs/recipes/kickassembler/screenshots/basic-float-calls-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/basic-float-calls.png +0 -0
- package/docs/recipes/kickassembler/screenshots/basic-wedge-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/basic-wedge.png +0 -0
- package/docs/recipes/kickassembler/screenshots/big-font-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/big-font-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram.png +0 -0
- package/docs/recipes/kickassembler/screenshots/cia-revision-detect-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/cia-revision-detect.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-cycling-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-cycling.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-fade-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-fade.png +0 -0
- package/docs/recipes/kickassembler/screenshots/compare-16bit-signed-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/compare-16bit-signed.png +0 -0
- package/docs/recipes/kickassembler/screenshots/cracktro-template.png +0 -0
- package/docs/recipes/kickassembler/screenshots/crt-banked-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/crt-banked.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dos-error-codes-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dos-error-codes.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dot-flag-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dot-flag.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-job-queue-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-job-queue.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-via-probe-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-via-probe.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dycp-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dycp-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dysp-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dysp.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc-run2.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save-run2.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save.png +0 -0
- package/docs/recipes/kickassembler/screenshots/eight-way-scroll-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/eight-way-scroll.png +0 -0
- package/docs/recipes/kickassembler/screenshots/file-io-roundtrip-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/file-io-roundtrip.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fire-effect-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fire-effect.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fld-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fld.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fli-image.png +0 -0
- package/docs/recipes/kickassembler/screenshots/four-player-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/four-player-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/headless-verify-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/headless-verify.png +0 -0
- package/docs/recipes/kickassembler/screenshots/hello-world.png +0 -0
- package/docs/recipes/kickassembler/screenshots/high-score-insert-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/high-score-insert.png +0 -0
- package/docs/recipes/kickassembler/screenshots/hires-plot-line-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/hires-plot-line.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-chain-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-chain.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-owns-port-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-owns-port.png +0 -0
- package/docs/recipes/kickassembler/screenshots/isometric-room-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/isometric-room.png +0 -0
- package/docs/recipes/kickassembler/screenshots/light-pen-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/light-pen-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace-average.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace-frame-b.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace.png +0 -0
- package/docs/recipes/kickassembler/screenshots/memory-layout-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/memory-layout.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mouse-1351-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mouse-1351-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/nmi-timer-tick-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/nmi-timer-tick.png +0 -0
- package/docs/recipes/kickassembler/screenshots/own-keyscan-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/own-keyscan.png +0 -0
- package/docs/recipes/kickassembler/screenshots/paddle-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/paddle-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/palette-cells-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/palette-cells.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pseudo-3d-road-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pseudo-3d-road.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pwm-digi-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pwm-digi.png +0 -0
- package/docs/recipes/kickassembler/screenshots/raster-bars.png +0 -0
- package/docs/recipes/kickassembler/screenshots/reu-dma-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/reu-dma.png +0 -0
- package/docs/recipes/kickassembler/screenshots/runtime-relocation-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/runtime-relocation.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-dissolve-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-dissolve.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-wipe-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-wipe.png +0 -0
- package/docs/recipes/kickassembler/screenshots/scroll-panel-split-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/scroll-panel-split.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sfx-in-player-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sfx-in-player.png +0 -0
- package/docs/recipes/kickassembler/screenshots/shadebobs-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/shadebobs.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sideborder-open.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sine-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sine-table-runtime-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sine-table-runtime.png +0 -0
- package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted.png +0 -0
- package/docs/recipes/kickassembler/screenshots/speedcode-generator-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/speedcode-generator.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-border-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-border-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-cache-flip-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-cache-flip.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-multiplex-24.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-priority-classes-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-priority-classes.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-sine-chain-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-sine-chain.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-stretcher-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-stretcher.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprites-only-screen-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprites-only-screen.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sqrt-atan2-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sqrt-atan2.png +0 -0
- package/docs/recipes/kickassembler/screenshots/stable-raster-irq-control.png +0 -0
- package/docs/recipes/kickassembler/screenshots/stable-raster-irq.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tech-tech-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tech-tech.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tod-alarm-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tod-alarm.png +0 -0
- package/docs/recipes/kickassembler/screenshots/topbottom-border-open.png +0 -0
- package/docs/recipes/kickassembler/screenshots/twister-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/twister.png +0 -0
- package/docs/recipes/kickassembler/screenshots/unit-test-driver-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/unit-test-driver.png +0 -0
- package/docs/recipes/kickassembler/screenshots/vector-balls-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/vector-balls.png +0 -0
- package/docs/recipes/kickassembler/screenshots/wireframe-ships-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/wireframe-ships.png +0 -0
- package/docs/recipes/kickassembler/scroll-panel-split.md +381 -0
- package/docs/recipes/kickassembler/sfx-in-player.md +907 -0
- package/docs/recipes/kickassembler/shadebobs.md +522 -0
- package/docs/recipes/kickassembler/sideborder-open.md +338 -0
- package/docs/recipes/kickassembler/sine-scroller.md +321 -0
- package/docs/recipes/kickassembler/sine-table-runtime.md +815 -0
- package/docs/recipes/kickassembler/software-sprite-preshifted.md +725 -0
- package/docs/recipes/kickassembler/speedcode-generator.md +606 -0
- package/docs/recipes/kickassembler/sprite-border-scroller.md +696 -0
- package/docs/recipes/kickassembler/sprite-cache-flip.md +1071 -0
- package/docs/recipes/kickassembler/sprite-multiplex-24.md +326 -0
- package/docs/recipes/kickassembler/sprite-multiplex-game.md +986 -0
- package/docs/recipes/kickassembler/sprite-priority-classes.md +463 -0
- package/docs/recipes/kickassembler/sprite-sine-chain.md +338 -0
- package/docs/recipes/kickassembler/sprite-stretcher.md +501 -0
- package/docs/recipes/kickassembler/sprites-only-screen.md +550 -0
- package/docs/recipes/kickassembler/sqrt-atan2.md +1014 -0
- package/docs/recipes/kickassembler/stable-raster-irq.md +360 -0
- package/docs/recipes/kickassembler/tape-turbo-loader.md +875 -0
- package/docs/recipes/kickassembler/tech-tech.md +679 -0
- package/docs/recipes/kickassembler/tod-alarm.md +754 -0
- package/docs/recipes/kickassembler/topbottom-border-open.md +407 -0
- package/docs/recipes/kickassembler/twister.md +518 -0
- package/docs/recipes/kickassembler/unit-test-driver.md +314 -0
- package/docs/recipes/kickassembler/vector-balls.md +545 -0
- package/docs/recipes/kickassembler/wireframe-ships.md +2324 -0
- package/docs/recipes/oscar64/actor-activation-window.md +807 -0
- package/docs/recipes/oscar64/adventure-engine.md +1094 -0
- package/docs/recipes/oscar64/attract-replay.md +465 -0
- package/docs/recipes/oscar64/beat-em-up-lanes.md +563 -0
- package/docs/recipes/oscar64/bfs-distance-map.md +723 -0
- package/docs/recipes/oscar64/bitmap-koala-viewer.md +355 -0
- package/docs/recipes/oscar64/car-contact.md +950 -0
- package/docs/recipes/oscar64/cave-scan.md +609 -0
- package/docs/recipes/oscar64/char-bullets.md +477 -0
- package/docs/recipes/oscar64/charset-animation.md +383 -0
- package/docs/recipes/oscar64/charset-parallax.md +401 -0
- package/docs/recipes/oscar64/destructible-terrain.md +1099 -0
- package/docs/recipes/oscar64/difficulty-tables.md +654 -0
- package/docs/recipes/oscar64/dig-and-guards.md +975 -0
- package/docs/recipes/oscar64/directory-reader.md +535 -0
- package/docs/recipes/oscar64/divide-check.md +581 -0
- package/docs/recipes/oscar64/double-buffer-nomirror.md +205 -0
- package/docs/recipes/oscar64/double-buffer.md +255 -0
- package/docs/recipes/oscar64/falling-blocks.md +874 -0
- package/docs/recipes/oscar64/fixed-point-jump-velocity.md +289 -0
- package/docs/recipes/oscar64/fixed-point-jump.md +210 -0
- package/docs/recipes/oscar64/flip-screen-rooms.md +793 -0
- package/docs/recipes/oscar64/frame-sync-loop-overrun.md +214 -0
- package/docs/recipes/oscar64/frame-sync-loop.md +254 -0
- package/docs/recipes/oscar64/game-tree-search.md +743 -0
- package/docs/recipes/oscar64/ghost-targeting.md +867 -0
- package/docs/recipes/oscar64/headless-verify.md +345 -0
- package/docs/recipes/oscar64/hello-world.md +83 -0
- package/docs/recipes/oscar64/high-score-persist.md +772 -0
- package/docs/recipes/oscar64/iffl-kernal-skip.md +421 -0
- package/docs/recipes/oscar64/joystick-input.md +358 -0
- package/docs/recipes/oscar64/lane-pursuit.md +1028 -0
- package/docs/recipes/oscar64/level-rle-decoder.md +620 -0
- package/docs/recipes/oscar64/lfsr-random-seed2.md +338 -0
- package/docs/recipes/oscar64/lfsr-random.md +403 -0
- package/docs/recipes/oscar64/load-asset-runtime.md +492 -0
- package/docs/recipes/oscar64/memory-layout.md +232 -0
- package/docs/recipes/oscar64/mixed-fighters.md +781 -0
- package/docs/recipes/oscar64/multi-sprite-object.md +533 -0
- package/docs/recipes/oscar64/nav-area-pathfinding.md +881 -0
- package/docs/recipes/oscar64/object-pool.md +572 -0
- package/docs/recipes/oscar64/pal-ntsc-detect.md +257 -0
- package/docs/recipes/oscar64/password-state.md +532 -0
- package/docs/recipes/oscar64/per-frame-hitbox.md +651 -0
- package/docs/recipes/oscar64/petscii-screen-codes.md +428 -0
- package/docs/recipes/oscar64/platformer-scaffold.md +1467 -0
- package/docs/recipes/oscar64/print-number.md +367 -0
- package/docs/recipes/oscar64/raster-bars.md +239 -0
- package/docs/recipes/oscar64/raster-profile-bars.md +404 -0
- package/docs/recipes/oscar64/rel-side-sectors.md +391 -0
- package/docs/recipes/oscar64/relative-file-records.md +378 -0
- package/docs/recipes/oscar64/save-load-seq-file.md +365 -0
- package/docs/recipes/oscar64/screenshots/README.md +99 -0
- package/docs/recipes/oscar64/screenshots/actor-activation-window-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/actor-activation-window.png +0 -0
- package/docs/recipes/oscar64/screenshots/adventure-engine-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/adventure-engine.png +0 -0
- package/docs/recipes/oscar64/screenshots/attract-replay-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/attract-replay.png +0 -0
- package/docs/recipes/oscar64/screenshots/beat-em-up-lanes-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/beat-em-up-lanes.png +0 -0
- package/docs/recipes/oscar64/screenshots/bfs-distance-map-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/bfs-distance-map.png +0 -0
- package/docs/recipes/oscar64/screenshots/bitmap-koala-viewer.png +0 -0
- package/docs/recipes/oscar64/screenshots/car-contact-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/car-contact.png +0 -0
- package/docs/recipes/oscar64/screenshots/cave-scan-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/cave-scan.png +0 -0
- package/docs/recipes/oscar64/screenshots/char-bullets-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/char-bullets.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-animation-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-animation.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-parallax-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-parallax.png +0 -0
- package/docs/recipes/oscar64/screenshots/destructible-terrain-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/destructible-terrain.png +0 -0
- package/docs/recipes/oscar64/screenshots/difficulty-tables-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/difficulty-tables.png +0 -0
- package/docs/recipes/oscar64/screenshots/dig-and-guards-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/dig-and-guards.png +0 -0
- package/docs/recipes/oscar64/screenshots/directory-reader-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/directory-reader.png +0 -0
- package/docs/recipes/oscar64/screenshots/divide-check-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/divide-check.png +0 -0
- package/docs/recipes/oscar64/screenshots/double-buffer-nomirror.png +0 -0
- package/docs/recipes/oscar64/screenshots/double-buffer-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/double-buffer.png +0 -0
- package/docs/recipes/oscar64/screenshots/falling-blocks-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/falling-blocks.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump.png +0 -0
- package/docs/recipes/oscar64/screenshots/flip-screen-rooms-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/flip-screen-rooms.png +0 -0
- package/docs/recipes/oscar64/screenshots/frame-sync-loop-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/frame-sync-loop-overrun.png +0 -0
- package/docs/recipes/oscar64/screenshots/frame-sync-loop.png +0 -0
- package/docs/recipes/oscar64/screenshots/game-tree-search-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/game-tree-search.png +0 -0
- package/docs/recipes/oscar64/screenshots/ghost-targeting-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/ghost-targeting.png +0 -0
- package/docs/recipes/oscar64/screenshots/headless-verify-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/headless-verify.png +0 -0
- package/docs/recipes/oscar64/screenshots/hello-world.png +0 -0
- package/docs/recipes/oscar64/screenshots/high-score-persist-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/high-score-persist.png +0 -0
- package/docs/recipes/oscar64/screenshots/iffl-kernal-skip-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/iffl-kernal-skip.png +0 -0
- package/docs/recipes/oscar64/screenshots/joystick-input-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/joystick-input.png +0 -0
- package/docs/recipes/oscar64/screenshots/lane-pursuit-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/lane-pursuit.png +0 -0
- package/docs/recipes/oscar64/screenshots/level-rle-decoder-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/level-rle-decoder.png +0 -0
- package/docs/recipes/oscar64/screenshots/lfsr-random-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/lfsr-random-seed2.png +0 -0
- package/docs/recipes/oscar64/screenshots/lfsr-random.png +0 -0
- package/docs/recipes/oscar64/screenshots/load-asset-runtime-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/load-asset-runtime.png +0 -0
- package/docs/recipes/oscar64/screenshots/memory-layout-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/memory-layout.png +0 -0
- package/docs/recipes/oscar64/screenshots/mixed-fighters-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/mixed-fighters.png +0 -0
- package/docs/recipes/oscar64/screenshots/multi-sprite-object-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/multi-sprite-object.png +0 -0
- package/docs/recipes/oscar64/screenshots/nav-area-pathfinding-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/nav-area-pathfinding.png +0 -0
- package/docs/recipes/oscar64/screenshots/object-pool-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/object-pool.png +0 -0
- package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-oldntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-pal.png +0 -0
- package/docs/recipes/oscar64/screenshots/password-state-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/password-state.png +0 -0
- package/docs/recipes/oscar64/screenshots/per-frame-hitbox-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/per-frame-hitbox.png +0 -0
- package/docs/recipes/oscar64/screenshots/petscii-screen-codes-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/petscii-screen-codes.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold.png +0 -0
- package/docs/recipes/oscar64/screenshots/print-number-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/print-number.png +0 -0
- package/docs/recipes/oscar64/screenshots/raster-bars.png +0 -0
- package/docs/recipes/oscar64/screenshots/raster-profile-bars-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/raster-profile-bars.png +0 -0
- package/docs/recipes/oscar64/screenshots/rel-side-sectors-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/rel-side-sectors.png +0 -0
- package/docs/recipes/oscar64/screenshots/relative-file-records-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/relative-file-records.png +0 -0
- package/docs/recipes/oscar64/screenshots/save-load-seq-file-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/save-load-seq-file.png +0 -0
- package/docs/recipes/oscar64/screenshots/seeded-level-fill-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/seeded-level-fill.png +0 -0
- package/docs/recipes/oscar64/screenshots/sfx-engine-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/sfx-engine.png +0 -0
- package/docs/recipes/oscar64/screenshots/sid-music-player.png +0 -0
- package/docs/recipes/oscar64/screenshots/simple-shmup.png +0 -0
- package/docs/recipes/oscar64/screenshots/slope-collision-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/slope-collision.png +0 -0
- package/docs/recipes/oscar64/screenshots/soft-scroll-h.png +0 -0
- package/docs/recipes/oscar64/screenshots/sprite-animation-table-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/sprite-animation-table.png +0 -0
- package/docs/recipes/oscar64/screenshots/sprite-multiplex-8.png +0 -0
- package/docs/recipes/oscar64/screenshots/stable-raster-irq.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-input-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-input.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-gameover.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-notrail-control.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ungated-control.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-window-menu-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-window-menu.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-grid-collision-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-grid-collision.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-map-render-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-map-render.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-player-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-player.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-word-parser-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-word-parser.png +0 -0
- package/docs/recipes/oscar64/screenshots/vehicle-control-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/vehicle-control.png +0 -0
- package/docs/recipes/oscar64/screenshots/wave-director-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/wave-director.png +0 -0
- package/docs/recipes/oscar64/seeded-level-fill.md +364 -0
- package/docs/recipes/oscar64/sfx-engine.md +514 -0
- package/docs/recipes/oscar64/sid-music-player.md +441 -0
- package/docs/recipes/oscar64/simple-shmup.md +1000 -0
- package/docs/recipes/oscar64/slope-collision.md +610 -0
- package/docs/recipes/oscar64/soft-scroll-h.md +261 -0
- package/docs/recipes/oscar64/sprite-animation-table.md +671 -0
- package/docs/recipes/oscar64/sprite-multiplex-8.md +314 -0
- package/docs/recipes/oscar64/stable-raster-irq.md +236 -0
- package/docs/recipes/oscar64/text-input.md +274 -0
- package/docs/recipes/oscar64/text-overlay-playfield.md +617 -0
- package/docs/recipes/oscar64/text-window-menu.md +551 -0
- package/docs/recipes/oscar64/tile-grid-collision.md +563 -0
- package/docs/recipes/oscar64/tile-map-render.md +395 -0
- package/docs/recipes/oscar64/two-player.md +528 -0
- package/docs/recipes/oscar64/two-word-parser.md +510 -0
- package/docs/recipes/oscar64/vehicle-control.md +771 -0
- package/docs/recipes/oscar64/wave-director.md +787 -0
- package/docs/recipes/runs.json +1606 -0
- package/docs/runtime/sim6502-reference.md +466 -0
- package/docs/runtime/vice-mcp-reference.md +351 -0
- package/docs/runtime/vice-reference.md +1393 -0
- package/docs/techniques/bitmap-modes.md +685 -0
- package/docs/techniques/cpu-cycle-tricks.md +1570 -0
- package/docs/techniques/effects-vector-3d.md +1431 -0
- package/docs/techniques/file-io.md +1427 -0
- package/docs/techniques/input.md +1072 -0
- package/docs/techniques/loaders-packers.md +768 -0
- package/docs/techniques/logic.md +3091 -0
- package/docs/techniques/maths.md +1524 -0
- package/docs/techniques/memory-banking.md +1686 -0
- package/docs/techniques/music-sid.md +1144 -0
- package/docs/techniques/raster.md +1543 -0
- package/docs/techniques/scroll.md +1292 -0
- package/docs/techniques/sprite.md +2566 -0
- package/docs/techniques/text-mode-render.md +717 -0
- package/docs/techniques/text.md +1095 -0
- package/docs/techniques/transitions.md +405 -0
- package/docs/toolchains/cartconv-reference.md +262 -0
- package/docs/toolchains/cc1541-reference.md +316 -0
- package/docs/toolchains/cc65-reference.md +667 -0
- package/docs/toolchains/error-sources/cc65/README.md +1 -0
- package/docs/toolchains/error-sources/cc65/missing-setcpu.s +4 -0
- package/docs/toolchains/error-sources/cc65/range-error.s +4 -0
- package/docs/toolchains/error-sources/cc65/segment-overflow.c +6 -0
- package/docs/toolchains/error-sources/cc65/unresolved-external.c +6 -0
- package/docs/toolchains/error-sources/kickassembler/README.md +1 -0
- package/docs/toolchains/error-sources/kickassembler/branch-out-of-range.asm +4 -0
- package/docs/toolchains/error-sources/kickassembler/failed-assert.asm +3 -0
- package/docs/toolchains/error-sources/kickassembler/flat-lib.asm +4 -0
- package/docs/toolchains/error-sources/kickassembler/import-source-no-namespace.asm +5 -0
- package/docs/toolchains/error-sources/kickassembler/macro-without-parentheses.asm +6 -0
- package/docs/toolchains/error-sources/kickassembler/memory-block-overlap.asm +4 -0
- package/docs/toolchains/error-sources/kickassembler/symbol-clash-lib.asm +5 -0
- package/docs/toolchains/error-sources/kickassembler/symbol-clash-main.asm +6 -0
- package/docs/toolchains/error-sources/kickassembler/unknown-symbol.asm +4 -0
- package/docs/toolchains/error-sources/oscar64/README.md +1 -0
- package/docs/toolchains/error-sources/oscar64/asm-addressing-mode.c +7 -0
- package/docs/toolchains/error-sources/oscar64/region-overflow.c +6 -0
- package/docs/toolchains/error-sources/oscar64/undefined-extern-var.c +5 -0
- package/docs/toolchains/error-sources/oscar64/undefined-extern.c +6 -0
- package/docs/toolchains/error-sources/oscar64/unknown-vic-field.c +6 -0
- package/docs/toolchains/error-sources/oscar64/void-main.c +3 -0
- package/docs/toolchains/kickassembler-reference.md +1020 -0
- package/docs/toolchains/memory-layout-planning.md +362 -0
- package/docs/toolchains/oscar64-headers-reference.md +583 -0
- package/docs/toolchains/oscar64-reference.md +892 -0
- package/docs/toolchains/petcat-reference.md +290 -0
- package/docs/toolchains/png2prg.md +188 -0
- package/docs/toolchains/release-disk.md +314 -0
- package/docs/toolchains/sidreloc.md +236 -0
- package/docs/toolchains/spindle-reference.md +487 -0
- package/docs/toolchains/tape-mastering.md +592 -0
- package/docs/toolchains/unit-testing-6502.md +281 -0
- package/docs/workflow/agent-harness.md +478 -0
- package/package.json +105 -0
- package/templates/_harness/CLAUDE.md.template +91 -0
- package/templates/_harness/PLAN.md.template +72 -0
- package/templates/_harness/check.py +442 -0
- package/templates/_harness/claude/settings.json +17 -0
- package/templates/_harness/gen-asm-header.py +96 -0
- package/templates/_harness/harness.mk +273 -0
- package/templates/_harness/hooks/plan-gate.py +185 -0
- package/templates/_harness/meter/frame_meter.asm +311 -0
- package/templates/_harness/meter/frame_meter.c +155 -0
- package/templates/_harness/meter/frame_meter.h +80 -0
- package/templates/_harness/zp-used.py +104 -0
- package/templates/action-puzzle/.claude/settings.json +17 -0
- package/templates/action-puzzle/.mcp.json +10 -0
- package/templates/action-puzzle/CLAUDE.md +120 -0
- package/templates/action-puzzle/Makefile +125 -0
- package/templates/action-puzzle/PLAN.md +388 -0
- package/templates/action-puzzle/README.md +240 -0
- package/templates/action-puzzle/expect.json +25 -0
- package/templates/action-puzzle/src/cave.c +280 -0
- package/templates/action-puzzle/src/cave.h +80 -0
- package/templates/action-puzzle/src/gen_autopilot.h +20 -0
- package/templates/action-puzzle/src/gen_caves.h +59 -0
- package/templates/action-puzzle/src/gen_notes.h +16 -0
- package/templates/action-puzzle/src/hiscore.c +152 -0
- package/templates/action-puzzle/src/hiscore.h +41 -0
- package/templates/action-puzzle/src/level.c +64 -0
- package/templates/action-puzzle/src/level.h +24 -0
- package/templates/action-puzzle/src/main.c +599 -0
- package/templates/action-puzzle/src/render.c +239 -0
- package/templates/action-puzzle/src/render.h +31 -0
- package/templates/action-puzzle/src/sound.c +158 -0
- package/templates/action-puzzle/src/sound.h +22 -0
- package/templates/action-puzzle/tools/disk_check.py +77 -0
- package/templates/action-puzzle/tools/drive.py +106 -0
- package/templates/action-puzzle/tools/gen.py +454 -0
- package/templates/action-puzzle/tools/model_check.py +49 -0
- package/templates/action-puzzle/tools/verdict_codes.py +24 -0
- package/templates/adventure/.claude/settings.json +17 -0
- package/templates/adventure/.mcp.json +10 -0
- package/templates/adventure/CLAUDE.md +118 -0
- package/templates/adventure/Makefile +113 -0
- package/templates/adventure/PLAN.md +396 -0
- package/templates/adventure/README.md +277 -0
- package/templates/adventure/expect.json +25 -0
- package/templates/adventure/src/engine.c +543 -0
- package/templates/adventure/src/engine.h +48 -0
- package/templates/adventure/src/gen_script.h +141 -0
- package/templates/adventure/src/gen_world.h +511 -0
- package/templates/adventure/src/main.c +439 -0
- package/templates/adventure/src/picture.c +83 -0
- package/templates/adventure/src/picture.h +16 -0
- package/templates/adventure/src/save.c +159 -0
- package/templates/adventure/src/save.h +25 -0
- package/templates/adventure/src/sound.c +71 -0
- package/templates/adventure/src/sound.h +16 -0
- package/templates/adventure/src/text.c +349 -0
- package/templates/adventure/src/text.h +40 -0
- package/templates/adventure/tools/disk_check.py +128 -0
- package/templates/adventure/tools/drive.py +119 -0
- package/templates/adventure/tools/gen.py +1033 -0
- package/templates/adventure/tools/world.py +356 -0
- package/templates/beat-em-up/.claude/settings.json +17 -0
- package/templates/beat-em-up/.mcp.json +10 -0
- package/templates/beat-em-up/CLAUDE.md +136 -0
- package/templates/beat-em-up/Makefile +96 -0
- package/templates/beat-em-up/PLAN.md +502 -0
- package/templates/beat-em-up/README.md +315 -0
- package/templates/beat-em-up/expect-gameover.json +8 -0
- package/templates/beat-em-up/expect.json +29 -0
- package/templates/beat-em-up/src/anim.c +70 -0
- package/templates/beat-em-up/src/art.c +344 -0
- package/templates/beat-em-up/src/autopilot.h +154 -0
- package/templates/beat-em-up/src/brute.c +273 -0
- package/templates/beat-em-up/src/enemy.c +281 -0
- package/templates/beat-em-up/src/engine.asm +512 -0
- package/templates/beat-em-up/src/fighter.c +384 -0
- package/templates/beat-em-up/src/game.h +269 -0
- package/templates/beat-em-up/src/hud.c +135 -0
- package/templates/beat-em-up/src/main.c +341 -0
- package/templates/beat-em-up/src/sound.c +44 -0
- package/templates/beat-em-up/src/street.c +93 -0
- package/templates/beat-em-up/src/verdict.h +523 -0
- package/templates/beat-em-up/src/view.c +362 -0
- package/templates/beat-em-up/tools/drive.py +105 -0
- package/templates/beat-em-up/tools/flickercheck.py +273 -0
- package/templates/demo/.claude/settings.json +17 -0
- package/templates/demo/.mcp.json +10 -0
- package/templates/demo/CLAUDE.md +129 -0
- package/templates/demo/Makefile +66 -0
- package/templates/demo/PLAN.md +401 -0
- package/templates/demo/README.md +322 -0
- package/templates/demo/expect.json +945 -0
- package/templates/demo/src/config.asm +80 -0
- package/templates/demo/src/framework.asm +390 -0
- package/templates/demo/src/main.asm +139 -0
- package/templates/demo/src/music.asm +197 -0
- package/templates/demo/src/part_main.asm +279 -0
- package/templates/demo/src/part_title.asm +79 -0
- package/templates/demo/src/parts.asm +43 -0
- package/templates/demo/src/tables.asm +73 -0
- package/templates/demo/src/verdict.asm +179 -0
- package/templates/demo/tools/audio.py +80 -0
- package/templates/demo/tools/gen_expect.py +167 -0
- package/templates/demo/tools/probe.py +95 -0
- package/templates/hello/.claude/settings.json +17 -0
- package/templates/hello/.mcp.json +10 -0
- package/templates/hello/CLAUDE.md +100 -0
- package/templates/hello/Makefile +38 -0
- package/templates/hello/PLAN.md +200 -0
- package/templates/hello/expect.json +20 -0
- package/templates/hello/src/main.c +161 -0
- package/templates/hello/src/sprite.asm +27 -0
- package/templates/hello-kick/.claude/settings.json +17 -0
- package/templates/hello-kick/.mcp.json +10 -0
- package/templates/hello-kick/CLAUDE.md +100 -0
- package/templates/hello-kick/Makefile +17 -0
- package/templates/hello-kick/PLAN.md +199 -0
- package/templates/hello-kick/expect.json +20 -0
- package/templates/hello-kick/src/main.asm +233 -0
- package/templates/platformer/.claude/settings.json +17 -0
- package/templates/platformer/.mcp.json +10 -0
- package/templates/platformer/CLAUDE.md +125 -0
- package/templates/platformer/Makefile +86 -0
- package/templates/platformer/PLAN.md +360 -0
- package/templates/platformer/README.md +277 -0
- package/templates/platformer/expect.json +32 -0
- package/templates/platformer/src/actors.c +289 -0
- package/templates/platformer/src/anim.c +51 -0
- package/templates/platformer/src/art.c +212 -0
- package/templates/platformer/src/autopilot.h +30 -0
- package/templates/platformer/src/engine.asm +253 -0
- package/templates/platformer/src/game.h +248 -0
- package/templates/platformer/src/hud.c +90 -0
- package/templates/platformer/src/level.c +184 -0
- package/templates/platformer/src/main.c +306 -0
- package/templates/platformer/src/player.c +268 -0
- package/templates/platformer/src/sound.c +42 -0
- package/templates/platformer/src/verdict.h +206 -0
- package/templates/platformer/src/view.c +331 -0
- package/templates/platformer/stage-expect.json +6 -0
- package/templates/platformer/tools/drive.py +112 -0
- package/templates/platformer/tools/tearcheck.py +229 -0
- package/templates/shmup-vertical/.claude/settings.json +17 -0
- package/templates/shmup-vertical/.mcp.json +10 -0
- package/templates/shmup-vertical/CLAUDE.md +137 -0
- package/templates/shmup-vertical/Makefile +131 -0
- package/templates/shmup-vertical/PLAN.md +569 -0
- package/templates/shmup-vertical/README.md +189 -0
- package/templates/shmup-vertical/expect.json +38 -0
- package/templates/shmup-vertical/src/bullets.c +158 -0
- package/templates/shmup-vertical/src/bullets.h +35 -0
- package/templates/shmup-vertical/src/display.c +239 -0
- package/templates/shmup-vertical/src/display.h +40 -0
- package/templates/shmup-vertical/src/game.h +85 -0
- package/templates/shmup-vertical/src/glyph.asm +358 -0
- package/templates/shmup-vertical/src/hiscore.c +141 -0
- package/templates/shmup-vertical/src/hiscore.h +16 -0
- package/templates/shmup-vertical/src/hit.asm +180 -0
- package/templates/shmup-vertical/src/hitbox.c +59 -0
- package/templates/shmup-vertical/src/hitbox.h +25 -0
- package/templates/shmup-vertical/src/kernel.asm +330 -0
- package/templates/shmup-vertical/src/level.c +174 -0
- package/templates/shmup-vertical/src/level.h +27 -0
- package/templates/shmup-vertical/src/main.c +824 -0
- package/templates/shmup-vertical/src/mux.asm +321 -0
- package/templates/shmup-vertical/src/sound.asm +255 -0
- package/templates/shmup-vertical/src/step.asm +169 -0
- package/templates/shmup-vertical/src/waves.c +195 -0
- package/templates/shmup-vertical/src/waves.h +33 -0
- package/templates/shmup-vertical/stage-expect.json +6 -0
- package/templates/shmup-vertical/tools/drive.py +152 -0
- package/templates/shmup-vertical/tools/joytest.py +159 -0
- package/templates/shmup-vertical/tools/meter.py +15 -0
- package/templates/shmup-vertical/tools/phases.py +73 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# shmup-vertical
|
|
2
|
+
|
|
3
|
+
A vertically scrolling shoot-em-up for the stock C64, PAL and NTSC, built
|
|
4
|
+
to be copied and grown into a game. It plays: title, fire to start, three
|
|
5
|
+
lives, game over, back to the title.
|
|
6
|
+
|
|
7
|
+
- A river scrolls down one line a frame, through all eight YSCROLL phases,
|
|
8
|
+
above a fixed score panel.
|
|
9
|
+
- The ship is a multicolour sprite on joystick port 2. Its bolts are
|
|
10
|
+
characters.
|
|
11
|
+
- Enemies arrive in waves set off by how far the river has scrolled. Each
|
|
12
|
+
flies a small path program, which can fire: a dot, also a character,
|
|
13
|
+
falls towards where the ship was. With the ship, up to 13 sprites go
|
|
14
|
+
through a multiplexer onto the 8 hardware sprites.
|
|
15
|
+
- Hits are tested with a box per sprite frame.
|
|
16
|
+
- A three-voice tune plays; shot, explosion and ship-lost effects borrow
|
|
17
|
+
voice 3 and hand it back.
|
|
18
|
+
- The high score is saved to drive 8 and loaded at start; a fresh disk's
|
|
19
|
+
title shows HI 000000. With no drive, the game runs without saving. A
|
|
20
|
+
save that was cut off (a splat file) is scratched and written again.
|
|
21
|
+
|
|
22
|
+
Fire starts a game on the title only after it has been released: hold it
|
|
23
|
+
through GAME OVER and the title waits.
|
|
24
|
+
|
|
25
|
+
Make a project from it in c64-kb with
|
|
26
|
+
`npm run new-project -- shmup-vertical <dir>`, then `make run`.
|
|
27
|
+
|
|
28
|
+
## Files
|
|
29
|
+
|
|
30
|
+
| File | What it holds |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `src/main.c` | States (title, play, game over), the ship, the frame loop, the autopilot scripts and their verdict |
|
|
33
|
+
| `src/level.c` | The river map and the downward scroll through two screens |
|
|
34
|
+
| `src/waves.c` | The wave list, the path bytecode (MOVE, LOOP, FIRE, END), the pool of 12 enemies |
|
|
35
|
+
| `src/bullets.c` | The ship's bolts and the enemies' dots: firing and the rules |
|
|
36
|
+
| `src/hitbox.c` | The ship's box; the hits turned into events |
|
|
37
|
+
| `src/display.c` | Character set, sprite art (as text), the score panel |
|
|
38
|
+
| `src/hiscore.c` | The HISCORE file on drive 8 |
|
|
39
|
+
| `src/game.h` | Memory map, the kernel's variables as C names, shared state |
|
|
40
|
+
| `src/kernel.asm` | The raster IRQ chain, the panel split, the three-row copy (KickAssembler) |
|
|
41
|
+
| `src/mux.asm` | The sprite multiplexer: sort, build, zone IRQs |
|
|
42
|
+
| `src/sound.asm` | The music player with effects inside it, and the tune |
|
|
43
|
+
| `src/glyph.asm` | The character bullets: the bolts' and the dots' moves and draws, the list, the erase, the restore check |
|
|
44
|
+
| `src/hit.asm` | The dots against the ship; every enemy's box against the ship's and the bolts' |
|
|
45
|
+
| `src/step.asm` | The path bytecode run for every enemy, explosions, one path step for every flying enemy |
|
|
46
|
+
| `tools/phases.py` | `make phases`: the panel at every YSCROLL phase against the graded one |
|
|
47
|
+
| `tools/meter.py` | `make stage`: reads the meter off the staged run's shots |
|
|
48
|
+
| `tools/drive.py` | Plays the `make joy` build headless over VICE's binary monitor |
|
|
49
|
+
| `tools/joytest.py` | `make joytest`: games played on PAL and NTSC to GAME OVER, graded on lost frames, and a reboot that must show the saved HI; `make longplay`: long games with a ship that is never lost |
|
|
50
|
+
| `PLAN.md` | The plan, with the c64-kb tool output it was built from |
|
|
51
|
+
| `expect.json`, `stage-expect.json` | What the graded and the staged screenshots must show |
|
|
52
|
+
|
|
53
|
+
C does the game; KickAssembler does what needs exact cycles, no zero page,
|
|
54
|
+
or runs for every enemy or bullet every frame. The harness assembles
|
|
55
|
+
`kernel.asm` (which imports the other `.asm` files) to a blob at `$0880`
|
|
56
|
+
and writes `build/asm.h`, so C calls it as `ASM_<LABEL>`.
|
|
57
|
+
|
|
58
|
+
## How a frame runs
|
|
59
|
+
|
|
60
|
+
The frame IRQ on line 252 sets the playfield's registers, shows the first
|
|
61
|
+
eight sprites and tells C a frame began. C then restores the bullet cells,
|
|
62
|
+
checks them against the map (AUTOPILOT builds), and moves and draws the
|
|
63
|
+
bolts and dots before the beam reaches them. It tests hits, moves the ship,
|
|
64
|
+
runs the waves, hands the actors to the multiplexer, draws three rows of
|
|
65
|
+
the hidden screen and sets next frame's scroll. Zone IRQs reuse sprites down
|
|
66
|
+
the screen. The split IRQ on line 212 switches to the panel on line 215 and
|
|
67
|
+
plays the music.
|
|
68
|
+
|
|
69
|
+
## Measured
|
|
70
|
+
|
|
71
|
+
VICE x64sc 3.10, the harness meter. The graded script's 240 play frames:
|
|
72
|
+
|
|
73
|
+
| Model | Worst frame | Typical (median) | Frame |
|
|
74
|
+
|---|---|---|---|
|
|
75
|
+
| PAL | 11,681 cycles | 8,374 | 19,656 |
|
|
76
|
+
| NTSC | 11,875 cycles | 8,733 | 17,095 |
|
|
77
|
+
|
|
78
|
+
`make stage` plays a script that puts 12 enemies, bolts, dots and a kill in
|
|
79
|
+
the same frames, and meters play frames 150-399. The worst of a sweep of its
|
|
80
|
+
timing over 16 variants is the variant it runs:
|
|
81
|
+
|
|
82
|
+
| Model | `make stage` worst | Typical | Frame |
|
|
83
|
+
|---|---|---|---|
|
|
84
|
+
| PAL | 15,064 cycles | 9,280 | 19,656 |
|
|
85
|
+
| NTSC | 15,237 cycles | 9,967 | 17,095 |
|
|
86
|
+
|
|
87
|
+
The figures hold the C loop's frame and every IRQ, with badlines and sprite
|
|
88
|
+
DMA. They leave out the loop's head (the wait, the scroll hand-over, the
|
|
89
|
+
stick), the meter's own bookkeeping and about 45 cycles of entry and exit
|
|
90
|
+
per IRQ outside the C loop's bracket. So a frame can be lost below 17,095:
|
|
91
|
+
at 7974a7a the staged run lost one on NTSC with its worst at 16,122.
|
|
92
|
+
|
|
93
|
+
The staged worst was not the heaviest frame play reaches. With fire held
|
|
94
|
+
and the ship swept, NTSC play lost frames at 7974a7a: in the review's
|
|
95
|
+
drive, 6 of 15 games, at play frame 465 in 5 of them; in a build of it
|
|
96
|
+
with `-dWORKEND=1`, 4 of 4 games, at play frames 282-321 (the row-32 and
|
|
97
|
+
row-40 swoops) and 454-477 (the row-48 saucers and the row-56 darts on the
|
|
98
|
+
screen together), with bolts, dots and kills in the same frames. The staged
|
|
99
|
+
run stops recording at play frame 399, before the second stretch.
|
|
100
|
+
`-dWORKEND=1` reads the raster when a frame's work ends, in lines after the
|
|
101
|
+
frame IRQ's line 252: the staged run's latest end on NTSC is now line 249
|
|
102
|
+
of 263, and play's is 256, at play frames 464-472.
|
|
103
|
+
|
|
104
|
+
Cuts to the work brought play back inside the NTSC frame; PLAN.md lists
|
|
105
|
+
them with their figures. The largest: the bolts' loop, the paths and the
|
|
106
|
+
dots' test against the ship moved to KickAssembler; the enemy box scan
|
|
107
|
+
skips enemies whose lines miss every box and walks only the boxes that are
|
|
108
|
+
on; the multiplexer's build loop keeps its write place in a register.
|
|
109
|
+
`make joytest` now plays 16 games a model with fire held and a sweep, and
|
|
110
|
+
fails on any lost frame: 16 of 16 NTSC games lost none. `make longplay`
|
|
111
|
+
plays 4 games a model for 40 s of warp with a ship that is never lost
|
|
112
|
+
(about 44,000 play frames each on NTSC, through the level's later loops):
|
|
113
|
+
none lost a frame. The latest end over those runs was line 256 of 263 on
|
|
114
|
+
NTSC (7 lines, about 450 cycles, to spare) and 243 of 312 on PAL.
|
|
115
|
+
|
|
116
|
+
A frame far past the frame shows in the meter as about 65,524: CIA2 timer A
|
|
117
|
+
counts down from 65,535 and wraps. A reading that high is a wrap, not the
|
|
118
|
+
frame's size; count the lost frames instead (`OVERRUNS` in the verdict,
|
|
119
|
+
`LOST_FRAMES` at `$02FD` in any build).
|
|
120
|
+
|
|
121
|
+
The meter's readout is printed only after the freeze. Printed every frame,
|
|
122
|
+
it cost up to 3,404 cycles outside the bracket and made the autopilot build
|
|
123
|
+
drop frames that the game itself does not. The self-check of the bullet
|
|
124
|
+
cells (about 250 cycles, and the map code each draw notes for it) runs in
|
|
125
|
+
AUTOPILOT builds only and is inside the figures.
|
|
126
|
+
|
|
127
|
+
The bullet draw must end before the beam reaches the cells it changes. The
|
|
128
|
+
smallest margin measured (`-dDRAWEND=1`, NTSC) was 19 lines for a dot in
|
|
129
|
+
the graded run and 25 in the staged run; for the bolts, read after all of
|
|
130
|
+
them were drawn, 26 in both. On PAL the bolts were drawn before line 0 and
|
|
131
|
+
the dots had 69 lines or more.
|
|
132
|
+
|
|
133
|
+
`make phases` (part of `make check`) freezes the game on each of the eight
|
|
134
|
+
YSCROLL phases and wants the panel identical to the graded one on both
|
|
135
|
+
models: a bad entry in the split's delay table fails it. More in PLAN.md.
|
|
136
|
+
|
|
137
|
+
## Next steps
|
|
138
|
+
|
|
139
|
+
1. **A boss.** Several sprites at fixed offsets from one origin, moved as
|
|
140
|
+
one, entered as consecutive actors of the multiplexer. Technique
|
|
141
|
+
`multi_sprite_object`, recipe `oscar64-multi-sprite-object`.
|
|
142
|
+
2. **Difficulty.** Replace the spacing shift in `spawner()` with level
|
|
143
|
+
tables read from data: speeds, counts, spacing and fire per loop, held
|
|
144
|
+
at the last row. Technique `difficulty_ramp_tables`, recipe
|
|
145
|
+
`oscar64-difficulty-tables`.
|
|
146
|
+
3. **Power-ups.** A pickup is one more actor with its own box group against
|
|
147
|
+
the ship only: `hit.asm`'s `hit_scan` tests its boxes against enemies,
|
|
148
|
+
so give pickups their own loop beside `dot_scan` there. Technique
|
|
149
|
+
`per_frame_hitbox`, recipe `oscar64-per-frame-hitbox`.
|
|
150
|
+
|
|
151
|
+
The level is the `bank` table in `level.c` (river widths every 4 map rows)
|
|
152
|
+
and the `wave` table in `waves.c` (map row, path, type, count, spacing,
|
|
153
|
+
formation). Paths are the byte arrays above them; `P_FIRE` fires a dot when
|
|
154
|
+
the enemy is between sprite Y 72 and 140 (the window that keeps the draw
|
|
155
|
+
ahead of the beam). Re-run `make stage` after changing either.
|
|
156
|
+
|
|
157
|
+
## Left out on purpose
|
|
158
|
+
|
|
159
|
+
- Colour per map cell: colour RAM cannot be double-buffered, so every
|
|
160
|
+
playfield cell shares one colour RAM value and the map is 4 colours.
|
|
161
|
+
- Sprites below line 208: a sprite on line 214 breaks the panel split
|
|
162
|
+
(measured); 209-213 were clean, and MAX_SY keeps 5 lines of margin.
|
|
163
|
+
- Enemy fire from above sprite Y 72 or below 140; power-ups, a boss, a
|
|
164
|
+
high-score table with names.
|
|
165
|
+
- Keyboard and a second joystick; RESTORE does nothing.
|
|
166
|
+
|
|
167
|
+
## Checks
|
|
168
|
+
|
|
169
|
+
`make shot check` runs the autopilot on PAL and NTSC with a fresh copy of
|
|
170
|
+
the disk on drive 8. The script shoots darts and saucers, is hit by a dart's
|
|
171
|
+
dot, fires through a parade of ten enemies, then stops; the program freezes
|
|
172
|
+
on YSCROLL 3, saves and reloads the high score and grades 18 facts,
|
|
173
|
+
printing the number of the first that fails. `expect.json` then checks the
|
|
174
|
+
verdict, the text, the meter, the ship and all ten parade sprites, the
|
|
175
|
+
river's banks at 30 rows scrolled, the split and the panel. `make selftest`
|
|
176
|
+
starts the ship 16 pixels to the right and must fail. `make stage`, `make
|
|
177
|
+
joytest` and `make longplay` are this starter's proof targets
|
|
178
|
+
(VERIFY_TARGETS), which `npm run verify:templates -- --selftest` runs too. `make claims` checks
|
|
179
|
+
every store the program makes against what the Makefile declares. `make
|
|
180
|
+
joy` builds the normal game reading its stick from `$02FE`, for
|
|
181
|
+
`python3 tools/drive.py build/shmup-vertical-joy.prg "until:PUSH FIRE" tap:fire ...`
|
|
182
|
+
(it takes a free monitor port unless DRIVE_PORT names one).
|
|
183
|
+
|
|
184
|
+
Measuring switches, none in a release build: `-dPROFILE=1` (each step of the
|
|
185
|
+
heaviest frame), `-dDRAWEND=1` (the bullet draw's margin to the beam),
|
|
186
|
+
`-dWORKEND=1` (how late in the frame the work ended, at `$0370`; `=2` adds
|
|
187
|
+
each step), `-dEVENTLOG=1` (each kill, hit and lost frame with its frame),
|
|
188
|
+
`-dGOD=1` (the ship is never lost), `-dLOOP_TEST=1` (play to GAME OVER and
|
|
189
|
+
back), `-dFREEZE_Y=0..7` (freeze on another phase).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"checks": [
|
|
3
|
+
{ "name": "own verdict (border)", "type": "verdict" },
|
|
4
|
+
{ "name": "verdict line", "type": "text", "row": 9, "col": 1, "text": "RESULT 01 PASS" },
|
|
5
|
+
{ "name": "score, kills, lives", "type": "text", "row": 10, "col": 1, "text": "SCORE 000450 KILLS 05 LIVES 2" },
|
|
6
|
+
{ "name": "sprites shown, waves, ship, kills by type", "type": "text", "row": 11, "col": 1, "text": "SHOWN 11 WAVES 04 SHIP 060 176 K 1 4 0" },
|
|
7
|
+
{ "name": "enemy dots fired, dots that hit the ship, frames that overran", "type": "text", "row": 12, "col": 1, "text": "FIRED 10 HIT 1 OVERRUNS 00" },
|
|
8
|
+
{ "name": "frame meter, the script's 240 play frames", "type": "meter", "row": 13, "col": 10, "frames": 240 },
|
|
9
|
+
|
|
10
|
+
{ "name": "ship where the script leaves it (X 120, Y 176): its light blue", "type": "sprite", "colour": 14, "vic_x": 124, "line": 180, "width": 16, "height": 12 },
|
|
11
|
+
{ "name": "parade bug A1 (X 60, Y 72)", "type": "sprite", "colour": 4, "vic_x": 64, "line": 76, "width": 16, "height": 9 },
|
|
12
|
+
{ "name": "parade bug A2 (X 108, Y 72)", "type": "sprite", "colour": 4, "vic_x": 112, "line": 76, "width": 16, "height": 9 },
|
|
13
|
+
{ "name": "parade bug A3 (X 156, Y 72)", "type": "sprite", "colour": 4, "vic_x": 160, "line": 76, "width": 16, "height": 9 },
|
|
14
|
+
{ "name": "parade bug A4 (X 204, Y 72)", "type": "sprite", "colour": 4, "vic_x": 208, "line": 76, "width": 16, "height": 9 },
|
|
15
|
+
{ "name": "parade bug A5 (X 252, Y 72)", "type": "sprite", "colour": 4, "vic_x": 256, "line": 76, "width": 16, "height": 9 },
|
|
16
|
+
{ "name": "parade bug B1 (X 60, Y 102)", "type": "sprite", "colour": 4, "vic_x": 64, "line": 106, "width": 16, "height": 9 },
|
|
17
|
+
{ "name": "parade bug B2 (X 108, Y 102)", "type": "sprite", "colour": 4, "vic_x": 112, "line": 106, "width": 16, "height": 9 },
|
|
18
|
+
{ "name": "parade bug B3 (X 156, Y 102)", "type": "sprite", "colour": 4, "vic_x": 160, "line": 106, "width": 16, "height": 9 },
|
|
19
|
+
{ "name": "parade bug B4 (X 204, Y 102)", "type": "sprite", "colour": 4, "vic_x": 208, "line": 106, "width": 16, "height": 9 },
|
|
20
|
+
{ "name": "parade bug B5 (X 252, Y 102)", "type": "sprite", "colour": 4, "vic_x": 256, "line": 106, "width": 16, "height": 9 },
|
|
21
|
+
|
|
22
|
+
{ "name": "scrolled 30 rows: map row 36's right bank edge in screen row 14, column 25 (sand)", "type": "pixel", "vic_x": 226, "line": 163, "colour": 7 },
|
|
23
|
+
{ "name": "... water left of that edge", "type": "pixel", "vic_x": 224, "line": 163, "colour": 6 },
|
|
24
|
+
{ "name": "... earth right of it", "type": "pixel", "vic_x": 229, "line": 163, "colour": 9 },
|
|
25
|
+
{ "name": "... map row 35 in screen row 15 is water in that column", "type": "pixel", "vic_x": 226, "line": 171, "colour": 6 },
|
|
26
|
+
{ "name": "... map row 36's left bank edge in column 4 (sand)", "type": "pixel", "vic_x": 60, "line": 163, "colour": 7 },
|
|
27
|
+
|
|
28
|
+
{ "name": "split: line 214 is still playfield (water in column 25)", "type": "pixel", "vic_x": 224, "line": 214, "colour": 6 },
|
|
29
|
+
{ "name": "split: line 216 is the panel's grey", "type": "pixel", "vic_x": 224, "line": 216, "colour": 11 },
|
|
30
|
+
{ "name": "panel rule, light grey, 40 columns (lines 218-219)", "type": "rect", "colour": 15, "vic_x": 24, "line": 218, "width": 320, "height": 2 },
|
|
31
|
+
{ "name": "panel background, a blank row, 40 columns", "type": "rect", "colour": 11, "vic_x": 24, "line": 231, "width": 320, "height": 8 },
|
|
32
|
+
{ "name": "two lives left: two cyan ships", "type": "rect", "colour": 3, "vic_x": 88, "line": 243, "width": 16, "height": 1 },
|
|
33
|
+
{ "name": "no third life", "type": "rect", "colour": 11, "vic_x": 104, "line": 243, "width": 8, "height": 1 },
|
|
34
|
+
{ "name": "no sprite under the panel: the panel's lines match on both models", "type": "same", "area": { "vic_x": 24, "line": 215, "width": 320, "height": 36 } },
|
|
35
|
+
{ "name": "playfield rows 0-12 the same on both models", "type": "same", "cells": [0, 0, 12, 39] },
|
|
36
|
+
{ "name": "playfield rows 14-20 the same on both models", "type": "same", "cells": [14, 0, 20, 39] }
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// bullets.c: the ship's bolts and the enemies' bullets as characters, from
|
|
2
|
+
// c64-kb's oscar64/char-bullets recipe (technique char_bullets). Each bullet
|
|
3
|
+
// owns one reserved glyph. To draw it: save the screen code under it, copy
|
|
4
|
+
// that code's glyph into the reserved glyph, OR the shot into it, write the
|
|
5
|
+
// reserved code. Every bullet drawn in a frame goes on one list, bolts
|
|
6
|
+
// first; restoring walks the list backwards, so bullets sharing a cell
|
|
7
|
+
// unwind. The list, the moves and the draws are glyph.asm's (bb_run for the
|
|
8
|
+
// bolts, eb_run for the dots, cb_draw, cb_erase, cb_check); this file fires
|
|
9
|
+
// the bullets and holds the rules.
|
|
10
|
+
//
|
|
11
|
+
// Bolts: 1 pixel pair wide, rows 2-5 of their cell. A bolt moves up 7 lines
|
|
12
|
+
// a frame while the playfield moves down 1, so it stays on rows 2-5 of
|
|
13
|
+
// whatever cell it is in: b_line - 50 - YSCROLL = 8 * row every frame, the
|
|
14
|
+
// carry frame included (YSCROLL 7 to 0, same row). b_line is the raster line
|
|
15
|
+
// of the bolt's top row (row 2 of the cell, whose top is 48 + YSCROLL + 8 *
|
|
16
|
+
// row). A bolt never straddles two cells.
|
|
17
|
+
//
|
|
18
|
+
// Enemy bullets: a 2 x 2 dot that falls 2 lines a frame and drifts one
|
|
19
|
+
// pixel pair a frame towards where the ship was, snapped to an even glyph
|
|
20
|
+
// row so it never crosses a cell edge. An enemy fires only between sprite Y 72 and
|
|
21
|
+
// 140, so a bullet starts on line 84 or lower, in a cell that starts on line
|
|
22
|
+
// 77 or lower. Bolts are drawn first; the draw must end before the beam
|
|
23
|
+
// reaches the first cell it changes (the measured end is in PLAN.md).
|
|
24
|
+
//
|
|
25
|
+
// Colour: every playfield cell is multicolour with colour RAM $0F, so the
|
|
26
|
+
// shots' pairs %11 draw in yellow and colour RAM is never touched.
|
|
27
|
+
#include "bullets.h"
|
|
28
|
+
#include "level.h"
|
|
29
|
+
#include "display.h"
|
|
30
|
+
#include "hitbox.h"
|
|
31
|
+
|
|
32
|
+
#define EB_TOP 72 // enemies fire from sprite Y 72 ...
|
|
33
|
+
#define EB_BOTTOM 140 // ... to 140
|
|
34
|
+
#define eb_dx ((signed char *)ASM_EB_DX)
|
|
35
|
+
|
|
36
|
+
unsigned eb_fired;
|
|
37
|
+
|
|
38
|
+
#ifdef DRAWEND
|
|
39
|
+
// Measuring only (-dDRAWEND=1): the smallest number of lines between the
|
|
40
|
+
// raster just after a cell was written and the first line of that cell, at
|
|
41
|
+
// the word it is given ($0364 bolts, $0366 dots; starts at $7FFF when main
|
|
42
|
+
// sets it). Negative: the beam had reached the cell first. The raster is 0
|
|
43
|
+
// while it is still in the lower border or has not reached line 0.
|
|
44
|
+
char drawend_on; // main.c: 1 in a frame that starts on time
|
|
45
|
+
|
|
46
|
+
static void drawend_margin(unsigned at, char top)
|
|
47
|
+
{
|
|
48
|
+
if (!drawend_on)
|
|
49
|
+
return;
|
|
50
|
+
char l = vic.raster;
|
|
51
|
+
if ((vic.ctrl1 & 0x80) || l >= 250)
|
|
52
|
+
return; // not yet past line 0: no risk
|
|
53
|
+
int m = (int)top - l;
|
|
54
|
+
volatile int *d = (volatile int *)at;
|
|
55
|
+
if (m < *d)
|
|
56
|
+
*d = m;
|
|
57
|
+
}
|
|
58
|
+
#endif
|
|
59
|
+
|
|
60
|
+
void bullets_reset(void)
|
|
61
|
+
{
|
|
62
|
+
for (char i = 0; i < NB; i++) {
|
|
63
|
+
b_live[i] = 0;
|
|
64
|
+
box_off(BOX_SHOT + i);
|
|
65
|
+
}
|
|
66
|
+
for (char j = 0; j < NEB; j++)
|
|
67
|
+
eb_live[j] = 0;
|
|
68
|
+
__asm { jsr ASM_CB_BEGIN } // an empty draw list
|
|
69
|
+
K_BYTE(ASM_CB_KEEP) = AUTOPILOT; // bullets_restored needs the map's codes
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// The bolt starts in the cell row above the ship's nose, placed as if drawn
|
|
73
|
+
// this frame: the next frame's move keeps the invariant. Returns false when
|
|
74
|
+
// every bolt is in flight or the ship is too high.
|
|
75
|
+
bool bullet_fire(char hx, char ship_y)
|
|
76
|
+
{
|
|
77
|
+
if (ship_y < 52 + 16 + cur_y)
|
|
78
|
+
return false;
|
|
79
|
+
char r = ((char)(ship_y - 52 - cur_y) >> 3) - 1;
|
|
80
|
+
for (char i = 0; i < NB; i++) {
|
|
81
|
+
if (!b_live[i]) {
|
|
82
|
+
b_live[i] = 1;
|
|
83
|
+
b_hx[i] = hx;
|
|
84
|
+
b_line[i] = 50 + cur_y + 8 * r;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// A dot from the middle of an enemy sprite at (hx, sy), drifting towards
|
|
92
|
+
// target_hx. Outside the fire window, or with every slot in flight, nothing.
|
|
93
|
+
void enemy_bullet_fire(char hx, char sy, char target_hx)
|
|
94
|
+
{
|
|
95
|
+
if (sy < EB_TOP || sy > EB_BOTTOM)
|
|
96
|
+
return;
|
|
97
|
+
char x = hx + 6;
|
|
98
|
+
for (char j = 0; j < NEB; j++) {
|
|
99
|
+
if (!eb_live[j]) {
|
|
100
|
+
eb_live[j] = 1;
|
|
101
|
+
eb_hx[j] = x;
|
|
102
|
+
eb_line[j] = sy + 12;
|
|
103
|
+
eb_dx[j] = target_hx + 2 < x ? -1 : target_hx > x + 2 ? 1 : 0;
|
|
104
|
+
eb_fired++;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void bullet_kill(char i)
|
|
111
|
+
{
|
|
112
|
+
b_live[i] = 0;
|
|
113
|
+
box_off(BOX_SHOT + i);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void enemy_bullet_kill(char j)
|
|
117
|
+
{
|
|
118
|
+
eb_live[j] = 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
void bullets_erase(void)
|
|
122
|
+
{
|
|
123
|
+
__asm { jsr ASM_CB_ERASE }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Every cell the last draw changed holds the map's code again. Reads the
|
|
127
|
+
// screen back, so an erase that skipped a cell, or ran in the wrong order,
|
|
128
|
+
// leaves a reserved code there and fails.
|
|
129
|
+
bool bullets_restored(void)
|
|
130
|
+
{
|
|
131
|
+
__asm { jsr ASM_CB_CHECK }
|
|
132
|
+
return !K_BYTE(ASM_CB_FAULT);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
void bullets_move_draw(void)
|
|
136
|
+
{
|
|
137
|
+
K_BYTE(ASM_CB_FRONT) = cur_front;
|
|
138
|
+
K_BYTE(ASM_CB_TOP) = cur_row + 20;
|
|
139
|
+
K_BYTE(ASM_CB_Y) = cur_y; // the YSCROLL showing
|
|
140
|
+
__asm {
|
|
141
|
+
jsr ASM_CB_BEGIN
|
|
142
|
+
jsr ASM_BB_RUN // the bolts first
|
|
143
|
+
}
|
|
144
|
+
#ifdef DRAWEND
|
|
145
|
+
// Read after all the bolts (then all the dots), so a margin here is
|
|
146
|
+
// smaller than the one just after its own cell was written: a lower
|
|
147
|
+
// bound.
|
|
148
|
+
for (char i = 0; i < NB; i++)
|
|
149
|
+
if (b_live[i])
|
|
150
|
+
drawend_margin(0x0364, b_line[i] - 2); // the bolt's cell starts 2 lines up
|
|
151
|
+
#endif
|
|
152
|
+
__asm { jsr ASM_EB_RUN } // then the enemies' dots
|
|
153
|
+
#ifdef DRAWEND
|
|
154
|
+
for (char j = 0; j < NEB; j++)
|
|
155
|
+
if (eb_live[j])
|
|
156
|
+
drawend_margin(0x0366, eb_line[j] - ((char)(eb_line[j] - 48 - cur_y) & 7));
|
|
157
|
+
#endif
|
|
158
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// bullets.h: the ship's bolts and the enemies' bullets, all drawn as
|
|
2
|
+
// characters (char_bullets).
|
|
3
|
+
#ifndef BULLETS_H
|
|
4
|
+
#define BULLETS_H
|
|
5
|
+
|
|
6
|
+
#include "game.h"
|
|
7
|
+
|
|
8
|
+
// The ship's bolts, glyphs $F8-$FB. At most 3 fly at once: one shot per 7
|
|
9
|
+
// frames (P_COOL 6), and a bolt from the lowest ship (Y 180) lives 16 frames
|
|
10
|
+
// (arithmetic). The fourth is room for a faster gun.
|
|
11
|
+
#define NB 4
|
|
12
|
+
// The enemies' bullets, glyphs $F2-$F7.
|
|
13
|
+
#define NEB 6
|
|
14
|
+
|
|
15
|
+
// The bolts and the dots live in glyph.asm, which moves and draws them.
|
|
16
|
+
#define b_live ((char *)ASM_BB_LIVE)
|
|
17
|
+
#define b_hx ((char *)ASM_BB_HX) // half X of the bolt's pixel pair
|
|
18
|
+
#define b_line ((char *)ASM_BB_LINE) // raster line of the bolt's top row
|
|
19
|
+
#define eb_live ((char *)ASM_EB_LIVE)
|
|
20
|
+
#define eb_hx ((char *)ASM_EB_HX) // half X of the dot's pixel pair
|
|
21
|
+
#define eb_line ((char *)ASM_EB_LINE) // raster line of the dot's top row
|
|
22
|
+
extern unsigned eb_fired; // enemy bullets fired this game (play_enter clears it)
|
|
23
|
+
|
|
24
|
+
void bullets_reset(void);
|
|
25
|
+
bool bullet_fire(char hx, char ship_y); // from a ship whose sprite Y is ship_y
|
|
26
|
+
void enemy_bullet_fire(char hx, char sy, char target_hx); // from an enemy sprite
|
|
27
|
+
void bullets_erase(void); // restore every drawn cell, reverse order
|
|
28
|
+
void bullets_move_draw(void); // move, draw into the showing screen
|
|
29
|
+
void bullet_kill(char i);
|
|
30
|
+
void enemy_bullet_kill(char j);
|
|
31
|
+
bool bullets_restored(void); // after bullets_erase: every cell is the map's
|
|
32
|
+
|
|
33
|
+
#pragma compile("bullets.c")
|
|
34
|
+
|
|
35
|
+
#endif
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// display.c: the character set, sprite shapes, text and the score panel.
|
|
2
|
+
// All art is original. Glyphs and sprites are written as strings of
|
|
3
|
+
// multicolour pixel pairs, one digit per pair: 0 background, 1 $D022 or
|
|
4
|
+
// $D025, 2 $D023 or the sprite's own colour, 3 colour RAM or $D026.
|
|
5
|
+
#include "display.h"
|
|
6
|
+
#include <c64/memmap.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
// ---- playfield glyphs: 8 rows of 4 pairs each ------------------------------
|
|
10
|
+
static const char * const glyph_art[7] = {
|
|
11
|
+
"11111121111111112111111111121111", // G_LAND: earth, green specks
|
|
12
|
+
"22222212222222222122222222212222", // G_GRASS
|
|
13
|
+
"23323322223223222322222122112112", // G_TREE: canopy, trunk
|
|
14
|
+
"11111331331331311311111111111111", // G_ROCK
|
|
15
|
+
"11301130111311131130113013001130", // G_EDGE_L: land left, sand, water
|
|
16
|
+
"03110311311131110311031100310311", // G_EDGE_R: water, sand, land right
|
|
17
|
+
"00000000000000000000000300300000", // G_SPARKLE: light on the water
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
static const char life_glyph[8] = { 0x18, 0x3c, 0x3c, 0x7e, 0xff, 0xdb, 0x18, 0x00 };
|
|
21
|
+
static const char rule_glyph[8] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00 };
|
|
22
|
+
|
|
23
|
+
// ---- sprites: 21 rows of 12 pairs -----------------------------------------
|
|
24
|
+
static const char * const sprite_art[SPR_FRAMES][21] = {
|
|
25
|
+
{ // F_SHIP
|
|
26
|
+
"............", ".....33.....", ".....33.....", "....3223....",
|
|
27
|
+
"....2332....", "....2222....", "...122221...", "...122221...",
|
|
28
|
+
"..11222211..", ".1122332211.", "112223322211", "112222222211",
|
|
29
|
+
"11.222222.11", "1..122221..1", "...12..21...", "...3....3...",
|
|
30
|
+
"............", "............", "............", "............",
|
|
31
|
+
"............" },
|
|
32
|
+
{ // F_DART
|
|
33
|
+
"............", "..2......2..", "..22....22..", "..222..222..",
|
|
34
|
+
"...222222...", "...233332...", "....2332....", "....2112....",
|
|
35
|
+
".....22.....", ".....22.....", ".....11.....", "............",
|
|
36
|
+
"............", "............", "............", "............",
|
|
37
|
+
"............", "............", "............", "............",
|
|
38
|
+
"............" },
|
|
39
|
+
{ // F_SAUCER
|
|
40
|
+
"............", "....3333....", "...322223...", "..22222222..",
|
|
41
|
+
".2212121212.", "222222222222", ".1111111111.", "..1.1..1.1..",
|
|
42
|
+
"............", "............", "............", "............",
|
|
43
|
+
"............", "............", "............", "............",
|
|
44
|
+
"............", "............", "............", "............",
|
|
45
|
+
"............" },
|
|
46
|
+
{ // F_BUG
|
|
47
|
+
"............", "...1....1...", "....1..1....", "...222222...",
|
|
48
|
+
"..22322322..", "..22222222..", ".1222112221.", "1.22211222.1",
|
|
49
|
+
"..22222222..", ".1.222222.1.", "1...2222...1", ".....22.....",
|
|
50
|
+
"............", "............", "............", "............",
|
|
51
|
+
"............", "............", "............", "............",
|
|
52
|
+
"............" },
|
|
53
|
+
{ // F_BOOM1
|
|
54
|
+
"............", "............", ".....3......", "...3.2.3....",
|
|
55
|
+
"....222.....", "..32232223..", "....222.....", "...3.2.3....",
|
|
56
|
+
".....3......", "............", "............", "............",
|
|
57
|
+
"............", "............", "............", "............",
|
|
58
|
+
"............", "............", "............", "............",
|
|
59
|
+
"............" },
|
|
60
|
+
{ // F_BOOM2
|
|
61
|
+
"............", "..3...3...3.", "...2..2..2..", "....1.1.1...",
|
|
62
|
+
".3..22222..3", "..2.2.3.2.2.", "321.23332.12", "..2.2.3.2.2.",
|
|
63
|
+
".3..22222..3", "....1.1.1...", "...2..2..2..", "..3...3...3.",
|
|
64
|
+
"............", "............", "............", "............",
|
|
65
|
+
"............", "............", "............", "............",
|
|
66
|
+
"............" },
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Four pair digits to one byte.
|
|
70
|
+
static char pairs(const char *s)
|
|
71
|
+
{
|
|
72
|
+
char b = 0;
|
|
73
|
+
for (char i = 0; i < 4; i++) {
|
|
74
|
+
char d = s[i];
|
|
75
|
+
b = (b << 2) | (d == '.' ? 0 : d - '0');
|
|
76
|
+
}
|
|
77
|
+
return b;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static void make_charset(void)
|
|
81
|
+
{
|
|
82
|
+
__asm { sei }
|
|
83
|
+
mmap_set(MMAP_CHAR_ROM);
|
|
84
|
+
memcpy(CHARSET, (char *)0xd000, 64 * 8); // letters, digits, punctuation
|
|
85
|
+
mmap_set(MMAP_NO_ROM); // I/O back; the kernel keeps $01 = $35
|
|
86
|
+
memset(CHARSET + 64 * 8, 0, 2048 - 64 * 8);
|
|
87
|
+
for (char g = 0; g < 7; g++) {
|
|
88
|
+
char *d = CHARSET + (G_LAND + g) * 8;
|
|
89
|
+
for (char r = 0; r < 8; r++)
|
|
90
|
+
d[r] = pairs(glyph_art[g] + 4 * r);
|
|
91
|
+
}
|
|
92
|
+
memcpy(CHARSET + G_LIFE * 8, life_glyph, 8);
|
|
93
|
+
memcpy(CHARSET + G_RULE * 8, rule_glyph, 8);
|
|
94
|
+
// Shots over open water need no merge (glyph.asm): a dot in each pixel
|
|
95
|
+
// pair on each even row pair, a bolt in each pair on rows 2-5, in %11.
|
|
96
|
+
for (char p = 0; p < 4; p++) {
|
|
97
|
+
char m = 0xc0 >> (2 * p);
|
|
98
|
+
for (char r = 0; r < 4; r++) {
|
|
99
|
+
char *d = CHARSET + (G_DOTS + 4 * p + r) * 8;
|
|
100
|
+
d[2 * r] = d[2 * r + 1] = m;
|
|
101
|
+
}
|
|
102
|
+
char *b = CHARSET + (G_BOLTS + p) * 8;
|
|
103
|
+
b[2] = b[3] = b[4] = b[5] = m;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static void make_sprites(void)
|
|
108
|
+
{
|
|
109
|
+
for (char f = 0; f < SPR_FRAMES; f++) {
|
|
110
|
+
char *d = SPRITES + 64 * f;
|
|
111
|
+
for (char r = 0; r < 21; r++) {
|
|
112
|
+
const char *s = sprite_art[f][r];
|
|
113
|
+
d[0] = pairs(s);
|
|
114
|
+
d[1] = pairs(s + 4);
|
|
115
|
+
d[2] = pairs(s + 8);
|
|
116
|
+
d += 3;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
void display_init(void)
|
|
122
|
+
{
|
|
123
|
+
make_charset();
|
|
124
|
+
make_sprites();
|
|
125
|
+
cia2.pra = (cia2.pra & 0xfc) | 0x01; // VIC bank 2: $8000-$BFFF
|
|
126
|
+
vic.color_border = VCOL_BLACK;
|
|
127
|
+
vic.color_back = PF_BG_COL;
|
|
128
|
+
vic.color_back1 = PF_MC1;
|
|
129
|
+
vic.color_back2 = PF_MC2;
|
|
130
|
+
vic.spr_multi = 0xff;
|
|
131
|
+
vic.spr_expand_x = 0;
|
|
132
|
+
vic.spr_expand_y = 0;
|
|
133
|
+
vic.spr_priority = 0;
|
|
134
|
+
vic.spr_mcolor0 = VCOL_DARK_GREY;
|
|
135
|
+
vic.spr_mcolor1 = VCOL_WHITE;
|
|
136
|
+
memset(PF0, G_WATER, 1000);
|
|
137
|
+
memset(PF1, G_WATER, 1000);
|
|
138
|
+
memset(COLOUR, PF_CRAM, 21 * 40); // playfield rows 0-20
|
|
139
|
+
memset(COLOUR + 21 * 40, VCOL_WHITE, 4 * 40); // panel rows 21-24
|
|
140
|
+
panel_draw();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ASCII upper case, digits and punctuation to screen codes.
|
|
144
|
+
void put_text(char *screen, char row, char col, const char *s)
|
|
145
|
+
{
|
|
146
|
+
char *p = screen + 40 * row + col;
|
|
147
|
+
while (*s) {
|
|
148
|
+
char c = *s++;
|
|
149
|
+
*p++ = (c >= 'A' && c <= 'Z') ? c - 64 : c;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
void text_colour(char row, char col, char n, char colour)
|
|
154
|
+
{
|
|
155
|
+
memset(COLOUR + 40 * row + col, colour, n);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static const unsigned pow10[5] = { 1, 10, 100, 1000, 10000 };
|
|
159
|
+
|
|
160
|
+
// Digits by repeated subtraction: no 16-bit division, a few hundred cycles.
|
|
161
|
+
void put_dec(char *p, unsigned v, char digits)
|
|
162
|
+
{
|
|
163
|
+
for (char i = digits; i > 0; i--) {
|
|
164
|
+
unsigned q = pow10[i - 1];
|
|
165
|
+
char d = '0';
|
|
166
|
+
while (v >= q) {
|
|
167
|
+
v -= q;
|
|
168
|
+
d++;
|
|
169
|
+
}
|
|
170
|
+
*p++ = d;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---- the panel: rows 20-24 of the screen at $8800 ------------------------------
|
|
175
|
+
// Row 20 is a rule, drawn in colour RAM row 20's colour, which the playfield
|
|
176
|
+
// shares (pitfall-free only because the playfield's value, $0F, reads as
|
|
177
|
+
// light grey in hires). Rows 21-23 hold text; row 24 is cut by the border.
|
|
178
|
+
#define SCORE_AT (PANEL + 21 * 40 + 8) // five digits; the sixth is always 0
|
|
179
|
+
#define HI_AT (PANEL + 21 * 40 + 26)
|
|
180
|
+
static char shown_lives = 0xff;
|
|
181
|
+
// The score's digits change once a frame, in panel_update, however many
|
|
182
|
+
// kills the frame had: the frames with most kills are the heaviest.
|
|
183
|
+
static char score_due;
|
|
184
|
+
|
|
185
|
+
void panel_draw(void)
|
|
186
|
+
{
|
|
187
|
+
memset(PANEL, G_WATER, 1000);
|
|
188
|
+
memset(PANEL + 20 * 40, G_RULE, 40);
|
|
189
|
+
put_text(PANEL, 21, 2, "SCORE 000000 HI 000000");
|
|
190
|
+
put_text(PANEL, 23, 2, "LIVES");
|
|
191
|
+
put_dec(SCORE_AT, score, 5);
|
|
192
|
+
put_dec(HI_AT, hiscore, 5);
|
|
193
|
+
score_due = 0;
|
|
194
|
+
shown_lives = 0xff;
|
|
195
|
+
panel_update();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Adds to the score's digits on the panel one digit at a time, so a kill
|
|
199
|
+
// costs a few dozen cycles, not a 16-bit conversion. Call after score and
|
|
200
|
+
// hiscore have been updated.
|
|
201
|
+
static void add_digits(char tens)
|
|
202
|
+
{
|
|
203
|
+
char *p = SCORE_AT + 4;
|
|
204
|
+
char c = tens;
|
|
205
|
+
for (;;) {
|
|
206
|
+
char d = *p - '0' + c;
|
|
207
|
+
c = 0;
|
|
208
|
+
while (d >= 10) {
|
|
209
|
+
d -= 10;
|
|
210
|
+
c++;
|
|
211
|
+
}
|
|
212
|
+
*p = '0' + d;
|
|
213
|
+
if (!c || p == SCORE_AT)
|
|
214
|
+
break;
|
|
215
|
+
p--;
|
|
216
|
+
}
|
|
217
|
+
if (score == hiscore)
|
|
218
|
+
memcpy(HI_AT, SCORE_AT, 5);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
void panel_add(char tens)
|
|
222
|
+
{
|
|
223
|
+
score_due += tens;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
void panel_update(void)
|
|
227
|
+
{
|
|
228
|
+
if (score_due) {
|
|
229
|
+
add_digits(score_due);
|
|
230
|
+
score_due = 0;
|
|
231
|
+
}
|
|
232
|
+
if (lives != shown_lives) {
|
|
233
|
+
for (char i = 0; i < 5; i++) {
|
|
234
|
+
PANEL[23 * 40 + 8 + i] = i < lives ? G_LIFE : G_WATER;
|
|
235
|
+
COLOUR[23 * 40 + 8 + i] = VCOL_CYAN;
|
|
236
|
+
}
|
|
237
|
+
shown_lives = lives;
|
|
238
|
+
}
|
|
239
|
+
}
|