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,824 @@
|
|
|
1
|
+
// main.c: shmup-vertical, a vertically scrolling shoot-em-up starter.
|
|
2
|
+
//
|
|
3
|
+
// The river scrolls down through all eight YSCROLL phases above a fixed
|
|
4
|
+
// score panel. The ship is a sprite; up to twelve enemies and the ship go
|
|
5
|
+
// through a sprite multiplexer; waves start at map rows; bullets are
|
|
6
|
+
// characters; hits are boxes; effects play inside the tune; the high score
|
|
7
|
+
// is kept on drive 8.
|
|
8
|
+
//
|
|
9
|
+
// Files: main.c (states, the ship, the frame loop, the autopilot and its
|
|
10
|
+
// verdict), level.c (map and scroll), waves.c (waves, paths, enemy pool),
|
|
11
|
+
// bullets.c (character bullets), hitbox.c (collision), display.c (art, text,
|
|
12
|
+
// panel), hiscore.c (the file), kernel.asm + mux.asm + sound.asm (IRQ chain,
|
|
13
|
+
// panel split, multiplexer, music and effects, in KickAssembler).
|
|
14
|
+
//
|
|
15
|
+
// AUTOPILOT=1 replaces joystick port 2 with a script and grades the end
|
|
16
|
+
// state; FORCE_FAULT=1 starts the ship 16 pixels to the right, so its shots,
|
|
17
|
+
// its score and its end position all change.
|
|
18
|
+
#include "game.h"
|
|
19
|
+
#include "display.h"
|
|
20
|
+
#include "level.h"
|
|
21
|
+
#include "waves.h"
|
|
22
|
+
#include "bullets.h"
|
|
23
|
+
#include "hitbox.h"
|
|
24
|
+
#include "hiscore.h"
|
|
25
|
+
#include "frame_meter.h" // templates/_harness/meter
|
|
26
|
+
#include <string.h>
|
|
27
|
+
|
|
28
|
+
// ---- the kernel blob at its own address --------------------------------------
|
|
29
|
+
#pragma section( asmcode, 0 )
|
|
30
|
+
#pragma region( asmreg, ASM_ORG, 0x2000, , , { asmcode } )
|
|
31
|
+
#pragma region( main, 0x2000, 0x8000, , , { code, data, bss, heap, stack } )
|
|
32
|
+
#pragma data( asmcode )
|
|
33
|
+
__export const char asm_blob[] = {
|
|
34
|
+
#embed "asm.bin"
|
|
35
|
+
};
|
|
36
|
+
#pragma data( data )
|
|
37
|
+
|
|
38
|
+
char state;
|
|
39
|
+
char lives, deaths;
|
|
40
|
+
unsigned score, hiscore;
|
|
41
|
+
unsigned play_frames;
|
|
42
|
+
|
|
43
|
+
#define JOY_UP 0x01
|
|
44
|
+
#define JOY_DOWN 0x02
|
|
45
|
+
#define JOY_LEFT 0x04
|
|
46
|
+
#define JOY_RIGHT 0x08
|
|
47
|
+
#define JOY_FIRE 0x10
|
|
48
|
+
|
|
49
|
+
// ---- the ship ------------------------------------------------------------------
|
|
50
|
+
#define P_START_HX (84 + 8 * FORCE_FAULT) // half X: sprite X 168
|
|
51
|
+
#define P_START_Y 170
|
|
52
|
+
#define P_MIN_HX 12
|
|
53
|
+
#define P_MAX_HX 160
|
|
54
|
+
#define P_MIN_Y 110
|
|
55
|
+
#define P_MAX_Y 180 // below MAX_SY (187)
|
|
56
|
+
#define P_SAFE 100 // frames the ship is safe after a loss
|
|
57
|
+
#define P_COOL 6 // frames between shots
|
|
58
|
+
|
|
59
|
+
static char p_hx, p_y, p_safe, p_cool;
|
|
60
|
+
|
|
61
|
+
static void ship_reset(void)
|
|
62
|
+
{
|
|
63
|
+
p_hx = P_START_HX;
|
|
64
|
+
p_y = P_START_Y;
|
|
65
|
+
p_cool = 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static void ship_update(char joy)
|
|
69
|
+
{
|
|
70
|
+
if (!(joy & JOY_LEFT) && p_hx > P_MIN_HX) p_hx--;
|
|
71
|
+
if (!(joy & JOY_RIGHT) && p_hx < P_MAX_HX) p_hx++;
|
|
72
|
+
if (!(joy & JOY_UP) && p_y > P_MIN_Y) p_y -= 2;
|
|
73
|
+
if (!(joy & JOY_DOWN) && p_y < P_MAX_Y) p_y += 2;
|
|
74
|
+
if (p_cool)
|
|
75
|
+
p_cool--;
|
|
76
|
+
else if (!(joy & JOY_FIRE) && bullet_fire(p_hx + 6, p_y)) {
|
|
77
|
+
p_cool = P_COOL;
|
|
78
|
+
sfx(1);
|
|
79
|
+
}
|
|
80
|
+
if (p_safe)
|
|
81
|
+
p_safe--;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ---- hits (hitbox.c reports them) ---------------------------------------------------
|
|
85
|
+
#ifdef EVENTLOG
|
|
86
|
+
// Measuring only (-dEVENTLOG=1): each kill (1), ram (2) and shot (3) with its
|
|
87
|
+
// play frame, 4 bytes each from $C000 (kind, enemy or bullet, frame low, high).
|
|
88
|
+
static char ev_n;
|
|
89
|
+
static void ev_log(char kind, char who)
|
|
90
|
+
{
|
|
91
|
+
volatile char *q = (volatile char *)0xc000 + 4 * ev_n++;
|
|
92
|
+
q[0] = kind; q[1] = who; q[2] = (char)play_frames; q[3] = play_frames >> 8;
|
|
93
|
+
}
|
|
94
|
+
#define EV(k, w) ev_log(k, w)
|
|
95
|
+
#else
|
|
96
|
+
#define EV(k, w)
|
|
97
|
+
#endif
|
|
98
|
+
|
|
99
|
+
void on_enemy_shot(char e, char bullet)
|
|
100
|
+
{
|
|
101
|
+
EV(1, e);
|
|
102
|
+
bullet_kill(bullet);
|
|
103
|
+
add_score(enemy_points(e));
|
|
104
|
+
enemy_explode(e);
|
|
105
|
+
sfx(2);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static void ship_lost(void);
|
|
109
|
+
|
|
110
|
+
void on_player_hit(char e)
|
|
111
|
+
{
|
|
112
|
+
EV(2, e);
|
|
113
|
+
enemy_explode(e);
|
|
114
|
+
ship_lost();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static char ship_shots; // times an enemy dot hit the ship
|
|
118
|
+
|
|
119
|
+
void on_ship_shot(char j)
|
|
120
|
+
{
|
|
121
|
+
ship_shots++;
|
|
122
|
+
EV(3, j);
|
|
123
|
+
enemy_bullet_kill(j);
|
|
124
|
+
ship_lost();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
void on_enemy_fire(char e)
|
|
128
|
+
{
|
|
129
|
+
enemy_bullet_fire(e_hx[e], e_y[e], p_hx);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static void ship_lost(void)
|
|
133
|
+
{
|
|
134
|
+
box_off(BOX_PLAYER); // one loss a frame at most
|
|
135
|
+
#ifdef GOD
|
|
136
|
+
// Measuring only (-dGOD=1, make longplay): the ship is never lost, so a
|
|
137
|
+
// driven game runs through the level's later loops, where the waves come
|
|
138
|
+
// closer together. play_frame mirrors play_frames at $02FB.
|
|
139
|
+
return;
|
|
140
|
+
#endif
|
|
141
|
+
deaths++;
|
|
142
|
+
lives--;
|
|
143
|
+
sfx(3);
|
|
144
|
+
if (lives == 0) {
|
|
145
|
+
state = ST_OVER;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
ship_reset();
|
|
149
|
+
p_safe = P_SAFE;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
void add_score(char tens)
|
|
153
|
+
{
|
|
154
|
+
score += tens;
|
|
155
|
+
if (score > hiscore)
|
|
156
|
+
hiscore = score;
|
|
157
|
+
panel_add(tens);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static char sfx_arg, ntsc_arg; // globals: absolute addresses for __asm
|
|
161
|
+
|
|
162
|
+
void sfx(char n)
|
|
163
|
+
{
|
|
164
|
+
sfx_arg = n;
|
|
165
|
+
__asm {
|
|
166
|
+
php
|
|
167
|
+
sei
|
|
168
|
+
lda sfx_arg
|
|
169
|
+
jsr ASM_SFX_REQUEST
|
|
170
|
+
plp
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---- the multiplexer's actor table, and the boxes where they are drawn -----------------
|
|
175
|
+
// Actor 0 is the ship; actors 1-12 are the enemies, which waves.c writes in
|
|
176
|
+
// place. The ship's box is emitted here, where it is handed to the display;
|
|
177
|
+
// collide() reads the enemies' boxes from the same table next frame, so it
|
|
178
|
+
// tests what was on screen.
|
|
179
|
+
static void actors_draw(void)
|
|
180
|
+
{
|
|
181
|
+
bool ship = state == ST_PLAY || state == ST_FROZEN;
|
|
182
|
+
ACT_Y[0] = ship && !(p_safe & 4) ? p_y : OFF_Y; // blinks while safe
|
|
183
|
+
ACT_HX[0] = p_hx;
|
|
184
|
+
if (ship && !p_safe)
|
|
185
|
+
box_ship(p_hx, p_y);
|
|
186
|
+
else
|
|
187
|
+
box_off(BOX_PLAYER);
|
|
188
|
+
__asm {
|
|
189
|
+
jsr ASM_MUX_SORT
|
|
190
|
+
jsr ASM_MUX_BUILD
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
// ---- input: joystick port 2, or the autopilot's script ---------------------------------
|
|
196
|
+
#if AUTOPILOT
|
|
197
|
+
// { frames, port byte }, active low as $DC00 reads it. The title takes the
|
|
198
|
+
// first fire; the rest is play. See PLAN.md "Autopilot and checks".
|
|
199
|
+
#define PLAY_FRAMES 240
|
|
200
|
+
#ifdef LOOP_TEST
|
|
201
|
+
// Test only (-dLOOP_TEST=1): start, then hold fire without moving, so the
|
|
202
|
+
// game scores, runs to GAME OVER, saves the high score and returns to the
|
|
203
|
+
// title. It never freezes, so there is no verdict.
|
|
204
|
+
static const char script[][2] = {
|
|
205
|
+
{ 2, 0xff }, { 2, 0xef }, { 250, 0xef }, { 250, 0xef }, { 250, 0xef },
|
|
206
|
+
{ 250, 0xef }, { 250, 0xef }, { 250, 0xef }, { 250, 0xef }, { 250, 0xef }
|
|
207
|
+
};
|
|
208
|
+
#define FREEZE_Y 8
|
|
209
|
+
#elif defined(STAGE)
|
|
210
|
+
// Measuring only (-dSTAGE=1, make stage): the heaviest frame the game makes.
|
|
211
|
+
// Out of the darts' way, wait for the parade and the row-32 swoop (12
|
|
212
|
+
// enemies flying), then fire up a parade column, so bolts, a kill and every
|
|
213
|
+
// enemy share frames. The meter records play frames 150-399. Taken from the
|
|
214
|
+
// review of this starter.
|
|
215
|
+
// -dSD=n waits n frames longer, -dSX=n moves n frames left: the review swept
|
|
216
|
+
// both to find the worst frame.
|
|
217
|
+
#ifndef SD
|
|
218
|
+
#define SD 0
|
|
219
|
+
#endif
|
|
220
|
+
#ifndef SX
|
|
221
|
+
#define SX 16
|
|
222
|
+
#endif
|
|
223
|
+
static const char script[][2] = {
|
|
224
|
+
{ 2, 0xff }, { 2, 0xef },
|
|
225
|
+
{ 56, 0xf7 }, // right to hx 140
|
|
226
|
+
{ 190 + SD, 0xff }, // wait for the parade and the swoop
|
|
227
|
+
{ SX, 0xfb }, // left under a parade column
|
|
228
|
+
{ 250, 0xef }, // fire
|
|
229
|
+
};
|
|
230
|
+
#undef PLAY_FRAMES
|
|
231
|
+
#define PLAY_FRAMES 400
|
|
232
|
+
#define STAGE_FROM 150
|
|
233
|
+
#define METER_HOLD (PLAY_FRAMES - STAGE_FROM) // the meter's hold is a byte: 1-255
|
|
234
|
+
#else
|
|
235
|
+
static const char script[][2] = {
|
|
236
|
+
{ 2, 0xff }, { 2, 0xef }, // title: fire starts the game
|
|
237
|
+
{ 24, 0xeb }, { 10, 0xef }, // left and fire: shoot the darts there
|
|
238
|
+
{ 30, 0xf7 }, { 24, 0xff }, // right, past the start, hold fire: shot
|
|
239
|
+
{ 16, 0xeb }, { 32, 0xe7 }, { 16, 0xeb }, // fire and sweep left, right, back
|
|
240
|
+
{ 20, 0xff }, // hold fire: the parade comes down
|
|
241
|
+
{ 40, 0xef }, // fire through the gap between two columns
|
|
242
|
+
{ 24, 0xfb }, { 3, 0xfd }, // move left, then down
|
|
243
|
+
};
|
|
244
|
+
#endif
|
|
245
|
+
#define SCRIPT_LEN (sizeof(script) / 2)
|
|
246
|
+
static char ap_index, ap_used;
|
|
247
|
+
|
|
248
|
+
static char port_read(void)
|
|
249
|
+
{
|
|
250
|
+
char out = 0xff;
|
|
251
|
+
if (ap_index < SCRIPT_LEN) {
|
|
252
|
+
out = script[ap_index][1];
|
|
253
|
+
if (++ap_used == script[ap_index][0]) { ap_used = 0; ap_index++; }
|
|
254
|
+
}
|
|
255
|
+
return out;
|
|
256
|
+
}
|
|
257
|
+
#elif defined(JOY_SOURCE)
|
|
258
|
+
// Headless driving of the normal game (make joy, tools/drive.py): the port
|
|
259
|
+
// byte comes from RAM at JOY_SOURCE, which a VICE monitor writes; the
|
|
260
|
+
// windowless VICE's joyport commands do not reach $DC00.
|
|
261
|
+
#define PLAY_FRAMES 1
|
|
262
|
+
static char port_read(void)
|
|
263
|
+
{
|
|
264
|
+
return *(volatile char *)JOY_SOURCE;
|
|
265
|
+
}
|
|
266
|
+
#else
|
|
267
|
+
#define PLAY_FRAMES 1
|
|
268
|
+
static char port_read(void)
|
|
269
|
+
{
|
|
270
|
+
return cia1.pra;
|
|
271
|
+
}
|
|
272
|
+
#endif
|
|
273
|
+
|
|
274
|
+
#ifndef METER_HOLD
|
|
275
|
+
#define METER_HOLD PLAY_FRAMES
|
|
276
|
+
#endif
|
|
277
|
+
|
|
278
|
+
// ---- frames ------------------------------------------------------------------------
|
|
279
|
+
// A play frame whose work runs past the next frame IRQ (line 252) loses a
|
|
280
|
+
// frame: the scroll and the hidden screen then fall a frame out of step
|
|
281
|
+
// (level_frame takes values the screen does not show yet, and level_render
|
|
282
|
+
// can draw into the screen on display). Nothing guards that; it is counted
|
|
283
|
+
// and the verdict (and make joytest, which reads LOST_FRAMES) wants 0. Keep
|
|
284
|
+
// a frame's work under the frame.
|
|
285
|
+
//
|
|
286
|
+
// The count is taken here, before waiting: a frame flag already set means
|
|
287
|
+
// the work ended after the next frame IRQ. The first version counted only
|
|
288
|
+
// when the frame IRQ count moved by more than one at wake-up, which a single
|
|
289
|
+
// lost frame never does (the review's mutation M8a, one frame late by about
|
|
290
|
+
// 2,400 cycles, passed with 0). In a meter build the count stops with the
|
|
291
|
+
// recording: the frame after it spends several frames finding the median,
|
|
292
|
+
// harness work outside the brackets. The first two play frames are not
|
|
293
|
+
// counted either: play_enter draws both screens (and in a meter build holds
|
|
294
|
+
// IRQs off for its calibration), so play frame 0 starts mid-frame.
|
|
295
|
+
#define LOST_FRAMES (*(volatile char *)0x02fd) // lost play frames, saturating at 255
|
|
296
|
+
static char last_frame_cnt;
|
|
297
|
+
static unsigned overruns;
|
|
298
|
+
|
|
299
|
+
static void wait_frame(void)
|
|
300
|
+
{
|
|
301
|
+
char late = K_FRAME_FLAG; // set already: the work ran into the next frame
|
|
302
|
+
while (!K_FRAME_FLAG) ;
|
|
303
|
+
K_FRAME_FLAG = 0;
|
|
304
|
+
char f = K_FRAME_CNT;
|
|
305
|
+
char lost = (char)(f - last_frame_cnt) - (late ? 0 : 1);
|
|
306
|
+
last_frame_cnt = f;
|
|
307
|
+
bool counting = state == ST_PLAY && play_frames > 1;
|
|
308
|
+
#if FRAME_METER
|
|
309
|
+
counting = counting && play_frames < PLAY_FRAMES;
|
|
310
|
+
#endif
|
|
311
|
+
#ifdef STAGE_FROM
|
|
312
|
+
counting = counting && play_frames != STAGE_FROM + 1; // its meter_init holds IRQs off
|
|
313
|
+
#endif
|
|
314
|
+
if (counting && lost) {
|
|
315
|
+
#ifdef EVENTLOG
|
|
316
|
+
ev_log(4, lost); // a lost frame
|
|
317
|
+
#endif
|
|
318
|
+
overruns += lost;
|
|
319
|
+
unsigned t = LOST_FRAMES + lost;
|
|
320
|
+
LOST_FRAMES = t > 255 ? 255 : t;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
#if FRAME_METER
|
|
325
|
+
// The C main loop's bracket is timed by CIA2 timer A (the harness meter);
|
|
326
|
+
// IRQs outside it by timer B (kernel.asm). A frame's figure is the loop's
|
|
327
|
+
// bracket plus the IRQ time up to the next frame IRQ, so it is recorded one
|
|
328
|
+
// frame late, when that IRQ has handed its sum over.
|
|
329
|
+
static unsigned main_raw;
|
|
330
|
+
static char have_main;
|
|
331
|
+
|
|
332
|
+
// The split IRQ runs from its vector to its timer B start untimed, to keep
|
|
333
|
+
// the recipe's timing: 245-289 cycles on PAL and 246-296 on NTSC, from the
|
|
334
|
+
// IRQ sequence to the start write, measured under the VICE monitor over a
|
|
335
|
+
// whole autopilot run. The larger figure is added for every frame in which
|
|
336
|
+
// the split timed itself.
|
|
337
|
+
#define SPLIT_PRE_PAL 289
|
|
338
|
+
#define SPLIT_PRE_NTSC 296
|
|
339
|
+
|
|
340
|
+
static void meter_open(void)
|
|
341
|
+
{
|
|
342
|
+
__asm { sei }
|
|
343
|
+
unsigned irq = K_IRQ_CYC - K_IRQ_CNT * K_IRQ_CAL;
|
|
344
|
+
char split = K_SPLIT_PREV;
|
|
345
|
+
__asm { cli }
|
|
346
|
+
if (split)
|
|
347
|
+
irq += ntsc_arg ? SPLIT_PRE_NTSC : SPLIT_PRE_PAL;
|
|
348
|
+
if (have_main) {
|
|
349
|
+
meter_add(main_raw);
|
|
350
|
+
meter_add(irq + meter_zero);
|
|
351
|
+
meter_frame();
|
|
352
|
+
}
|
|
353
|
+
__asm { sei }
|
|
354
|
+
METER_START;
|
|
355
|
+
K_MTR_OPEN = 1;
|
|
356
|
+
__asm { cli }
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
static void meter_close(void)
|
|
360
|
+
{
|
|
361
|
+
__asm { sei }
|
|
362
|
+
main_raw = meter_read();
|
|
363
|
+
K_MTR_OPEN = 0;
|
|
364
|
+
__asm { cli }
|
|
365
|
+
have_main = 1;
|
|
366
|
+
}
|
|
367
|
+
#else
|
|
368
|
+
#define meter_open()
|
|
369
|
+
#define meter_close()
|
|
370
|
+
#endif
|
|
371
|
+
|
|
372
|
+
// ---- states -----------------------------------------------------------------------
|
|
373
|
+
static void title_enter(void)
|
|
374
|
+
{
|
|
375
|
+
state = ST_TITLE;
|
|
376
|
+
bullets_erase();
|
|
377
|
+
bullets_reset();
|
|
378
|
+
waves_reset();
|
|
379
|
+
level_show(0, 3);
|
|
380
|
+
memset(COLOUR, PF_CRAM, 21 * 40); // no text left from a game over
|
|
381
|
+
char *s = level_screen();
|
|
382
|
+
put_text(s, 6, 11, " DELTA PATROL ");
|
|
383
|
+
put_text(s, 9, 9, " PUSH FIRE TO START ");
|
|
384
|
+
put_text(s, 12, 11, " JOYSTICK PORT 2 ");
|
|
385
|
+
text_colour(6, 11, 15, VCOL_YELLOW);
|
|
386
|
+
text_colour(9, 9, 20, TEXT_CRAM);
|
|
387
|
+
text_colour(12, 11, 17, VCOL_LT_GREY);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
static void play_enter(void)
|
|
391
|
+
{
|
|
392
|
+
memset(COLOUR, PF_CRAM, 21 * 40); // every playfield cell multicolour
|
|
393
|
+
score = 0;
|
|
394
|
+
lives = START_LIVES;
|
|
395
|
+
deaths = 0;
|
|
396
|
+
ship_shots = 0;
|
|
397
|
+
play_frames = 0;
|
|
398
|
+
panel_draw();
|
|
399
|
+
p_safe = 0;
|
|
400
|
+
ship_reset();
|
|
401
|
+
bullets_reset();
|
|
402
|
+
eb_fired = 0;
|
|
403
|
+
waves_reset();
|
|
404
|
+
level_show(0, 0);
|
|
405
|
+
state = ST_PLAY;
|
|
406
|
+
#if FRAME_METER
|
|
407
|
+
meter_init((unsigned)SCRATCH, 13, 10, PF_CRAM, METER_HOLD);
|
|
408
|
+
#endif
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
static char over_timer;
|
|
412
|
+
|
|
413
|
+
static unsigned disk_hi; // the high score the file holds
|
|
414
|
+
|
|
415
|
+
// The raster chain stops during file I/O, so first set one screen that
|
|
416
|
+
// needs no IRQ: the playfield at YSCROLL 3, 25 rows, no sprites.
|
|
417
|
+
static void hold_screen(void)
|
|
418
|
+
{
|
|
419
|
+
__asm { sei }
|
|
420
|
+
vic.ctrl1 = 0x1b;
|
|
421
|
+
vic.memptr = cur_front ? D018_PF1 : D018_PF0; // the screen the text went to
|
|
422
|
+
vic.ctrl2 = 0xd8;
|
|
423
|
+
vic.spr_enable = 0;
|
|
424
|
+
vic.color_back = PF_BG_COL;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
static void over_enter(void)
|
|
428
|
+
{
|
|
429
|
+
char *s = level_screen();
|
|
430
|
+
put_text(s, 9, 14, " GAME OVER ");
|
|
431
|
+
text_colour(9, 14, 11, TEXT_CRAM);
|
|
432
|
+
if (disk_on && hiscore > disk_hi) {
|
|
433
|
+
put_text(s, 11, 12, " SAVING HI SCORE ");
|
|
434
|
+
text_colour(11, 12, 17, TEXT_CRAM);
|
|
435
|
+
hold_screen();
|
|
436
|
+
hiscore_save(); // a second or two; the chain restarts after
|
|
437
|
+
disk_hi = hiscore;
|
|
438
|
+
put_text(s, 11, 12, " ");
|
|
439
|
+
}
|
|
440
|
+
over_timer = 150;
|
|
441
|
+
state = ST_OVER;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
#ifdef WORKEND
|
|
445
|
+
// Measuring only (-dWORKEND=1): how far past the frame IRQ (line 252) a play
|
|
446
|
+
// frame's work ran, in raster lines (NTSC has 263, PAL 312: past that the
|
|
447
|
+
// frame is lost). At $0370, words: 0 the latest end over the run, 1 its play
|
|
448
|
+
// frame, 2 the frames whose work ended within 8 lines of the frame's end.
|
|
449
|
+
// Frames that woke late (after a lost one) are left out. -dWORKEND=2 also
|
|
450
|
+
// reads the line after each step: words 3-10 that frame's lines when it
|
|
451
|
+
// woke and after each of the 7 steps, 11-17 each step's most lines in any
|
|
452
|
+
// frame; the reads cost about 300 cycles a frame. Any build, the joy build
|
|
453
|
+
// too: nothing is held off, so the timing is the game's own.
|
|
454
|
+
#define WE ((volatile unsigned *)0x0370)
|
|
455
|
+
static unsigned we_step[8];
|
|
456
|
+
static unsigned we_line(void)
|
|
457
|
+
{
|
|
458
|
+
char hi, lo;
|
|
459
|
+
do { hi = vic.ctrl1; lo = vic.raster; } while (hi != vic.ctrl1);
|
|
460
|
+
unsigned l = lo + ((unsigned)(hi & 0x80) << 1);
|
|
461
|
+
unsigned n = ntsc_arg ? 263 : 312;
|
|
462
|
+
return l >= 252 ? l - 252 : l + n - 252;
|
|
463
|
+
}
|
|
464
|
+
#if WORKEND > 1
|
|
465
|
+
#define W1(k) we_step[k + 1] = we_line()
|
|
466
|
+
#else
|
|
467
|
+
#define W1(k) if (k == 6) we_step[7] = we_line()
|
|
468
|
+
#endif
|
|
469
|
+
#else
|
|
470
|
+
#define W1(k)
|
|
471
|
+
#endif
|
|
472
|
+
|
|
473
|
+
#ifdef PROFILE
|
|
474
|
+
// Debug only (-dPROFILE=1): CIA1 timer B times each step of play_frame with
|
|
475
|
+
// IRQs held off (badline and sprite DMA stay in). At $0340, words: 0-6 the
|
|
476
|
+
// steps of the frame whose steps summed largest, 7 the largest IRQ time of
|
|
477
|
+
// a frame, 8 that frame's number, 9 its sum, 10 the latest raster line the
|
|
478
|
+
// bullet draw ended on (0 when it ended above line 250).
|
|
479
|
+
#define PROF ((volatile unsigned *)0x0340)
|
|
480
|
+
static unsigned prof_step[7];
|
|
481
|
+
#define P0 { __asm { sei } cia1.crb = 0x00; cia1.tb = 0xffff; cia1.crb = 0x11; }
|
|
482
|
+
#define P1(k) { cia1.crb = 0; prof_step[k] = 0xffff - cia1.tb; __asm { cli } }
|
|
483
|
+
#else
|
|
484
|
+
#define P0
|
|
485
|
+
#define P1(k)
|
|
486
|
+
#endif
|
|
487
|
+
|
|
488
|
+
// One frame of play. The order matters: bullets first, drawn into the showing
|
|
489
|
+
// screen before the beam reaches the playfield; collisions next, on the
|
|
490
|
+
// boxes of what is on screen now; then the moves that show next frame.
|
|
491
|
+
#if AUTOPILOT
|
|
492
|
+
static char bullet_fault;
|
|
493
|
+
#endif
|
|
494
|
+
|
|
495
|
+
static void play_frame(char joy)
|
|
496
|
+
{
|
|
497
|
+
#ifdef DRAWEND
|
|
498
|
+
// Frames that start late for the harness's sake are left out: the first
|
|
499
|
+
// (after play_enter), the one after a meter_init (STAGE), and the ones
|
|
500
|
+
// from the end of the recording (the median is found there).
|
|
501
|
+
extern char drawend_on;
|
|
502
|
+
drawend_on = play_frames > 1 && play_frames < PLAY_FRAMES;
|
|
503
|
+
#ifdef STAGE_FROM
|
|
504
|
+
drawend_on = drawend_on && play_frames != STAGE_FROM + 1;
|
|
505
|
+
#endif
|
|
506
|
+
#endif
|
|
507
|
+
#ifdef WORKEND
|
|
508
|
+
we_step[0] = we_line();
|
|
509
|
+
#endif
|
|
510
|
+
P0; bullets_erase();
|
|
511
|
+
#if AUTOPILOT
|
|
512
|
+
if (!bullets_restored()) { // every cell the last draw changed is the map's again
|
|
513
|
+
bullet_fault = 1;
|
|
514
|
+
}
|
|
515
|
+
#endif
|
|
516
|
+
bullets_move_draw(); P1(0); W1(0);
|
|
517
|
+
#ifdef DRAWEND
|
|
518
|
+
// Measuring only (-dDRAWEND=1): the latest raster line the bullet draw
|
|
519
|
+
// ended on in a play frame, at $0360 (0 while still above line 250 or
|
|
520
|
+
// after the wrap below line 0... i.e. in the border before the display),
|
|
521
|
+
// and the play frame, at $0362. Not with PROFILE, whose timing is slower.
|
|
522
|
+
{
|
|
523
|
+
char l = vic.raster;
|
|
524
|
+
unsigned e = (vic.ctrl1 & 0x80) || l >= 250 ? 0 : l;
|
|
525
|
+
volatile unsigned *d = (volatile unsigned *)0x0360;
|
|
526
|
+
if (play_frames > 1 && play_frames < PLAY_FRAMES && e > d[0]) { d[0] = e; d[1] = play_frames; }
|
|
527
|
+
}
|
|
528
|
+
#endif
|
|
529
|
+
P0; collide(); P1(1); W1(1);
|
|
530
|
+
P0; ship_update(joy); P1(2); W1(2);
|
|
531
|
+
P0; waves_update(cur_row); P1(3); W1(3);
|
|
532
|
+
P0; actors_draw(); P1(4); W1(4);
|
|
533
|
+
P0; level_render(); P1(5); W1(5);
|
|
534
|
+
P0; level_advance(); panel_update(); P1(6); W1(6);
|
|
535
|
+
#ifdef WORKEND
|
|
536
|
+
if (play_frames > 1 && we_step[0] < 16) { // started on time
|
|
537
|
+
unsigned n = ntsc_arg ? 263 : 312;
|
|
538
|
+
if (we_step[7] > WE[0]) {
|
|
539
|
+
WE[0] = we_step[7];
|
|
540
|
+
WE[1] = play_frames;
|
|
541
|
+
#if WORKEND > 1
|
|
542
|
+
for (char k = 0; k < 8; k++)
|
|
543
|
+
WE[3 + k] = we_step[k];
|
|
544
|
+
#endif
|
|
545
|
+
}
|
|
546
|
+
if (we_step[7] + 8 >= n)
|
|
547
|
+
WE[2]++;
|
|
548
|
+
#if WORKEND > 1
|
|
549
|
+
for (char k = 0; k < 7; k++) {
|
|
550
|
+
unsigned d = we_step[k + 1] - we_step[k];
|
|
551
|
+
if (d < 200 && d > WE[11 + k])
|
|
552
|
+
WE[11 + k] = d;
|
|
553
|
+
}
|
|
554
|
+
#endif
|
|
555
|
+
}
|
|
556
|
+
#endif
|
|
557
|
+
#ifdef PROFILE
|
|
558
|
+
if (play_frames > 1) {
|
|
559
|
+
unsigned t = K_IRQ_CYC - K_IRQ_CNT * K_IRQ_CAL, sum = 0;
|
|
560
|
+
if (t > PROF[7]) PROF[7] = t;
|
|
561
|
+
for (char k = 0; k < 7; k++)
|
|
562
|
+
sum += prof_step[k];
|
|
563
|
+
if (sum > PROF[9]) {
|
|
564
|
+
for (char k = 0; k < 7; k++)
|
|
565
|
+
PROF[k] = prof_step[k];
|
|
566
|
+
PROF[8] = play_frames;
|
|
567
|
+
PROF[9] = sum;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
#endif
|
|
571
|
+
play_frames++;
|
|
572
|
+
#ifdef GOD
|
|
573
|
+
*(volatile unsigned *)0x02fb = play_frames;
|
|
574
|
+
#endif
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
#if AUTOPILOT
|
|
578
|
+
// The graded run freezes on YSCROLL 3, where playfield rows sit on the text
|
|
579
|
+
// grid check.py reads. -dFREEZE_Y=0..7 freezes on another phase (the verdict
|
|
580
|
+
// then fails check 8): the panel split was compared across all eight so.
|
|
581
|
+
#ifndef FREEZE_Y
|
|
582
|
+
#define FREEZE_Y 3
|
|
583
|
+
#endif
|
|
584
|
+
|
|
585
|
+
// ---- the verdict, after the script -------------------------------------------------
|
|
586
|
+
// What the script does, by play frame (frame 0 is the second fire frame on
|
|
587
|
+
// the title), from the -dEVENTLOG=1 build's log, the same on PAL and NTSC:
|
|
588
|
+
// 37 a dart shot (50) 71 the first dart's dot hits the ship, in a still
|
|
589
|
+
// segment 94, 113, 121, 128 saucers shot (100 each)
|
|
590
|
+
// 450 points, 5 kills, K 1 4 0; 10 dots fired: 5 darts at Y 72, 5 saucers at
|
|
591
|
+
// Y 88. Before enemy fire the review's Python model matched the same kills
|
|
592
|
+
// frame for frame, with a ram at 71 where the dot now hits. After the loss
|
|
593
|
+
// the ship respawns at the start and the script's last 27 frames move it 24
|
|
594
|
+
// left and 3 down.
|
|
595
|
+
#define EXPECT_DEATHS 1
|
|
596
|
+
#define EXPECT_SCORE 45 // 450 points: 1 dart, 4 saucers
|
|
597
|
+
#define EXPECT_KILLS 5
|
|
598
|
+
#define EXPECT_FIRED 10 // 5 darts at Y 72, 5 saucers at Y 88; none from the parade
|
|
599
|
+
#define EXPECT_SHOWN 11 // 10 parade bugs and the ship
|
|
600
|
+
#define END_HX (P_START_HX - 24) // after the loss: 24 frames left
|
|
601
|
+
#define END_Y (P_START_Y + 6) // and 3 frames down, 2 lines each
|
|
602
|
+
|
|
603
|
+
static char verdict_code;
|
|
604
|
+
|
|
605
|
+
static bool parade_in_place(void)
|
|
606
|
+
{
|
|
607
|
+
char n = 0;
|
|
608
|
+
for (char e = 0; e < NE; e++) {
|
|
609
|
+
if (e_state[e] != E_FLYING || e_ptr[e] != SPR_BLOCK + F_BUG)
|
|
610
|
+
continue;
|
|
611
|
+
char k = (e_hx[e] - 30) / 24;
|
|
612
|
+
if (e_hx[e] != 30 + 24 * k || k > 4 || (e_y[e] != 72 && e_y[e] != 102))
|
|
613
|
+
return false;
|
|
614
|
+
n++;
|
|
615
|
+
}
|
|
616
|
+
return n == 10;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// The number of the first check that fails, 0 when all pass. The number is
|
|
620
|
+
// printed after FAIL, so a red run says which fact was wrong.
|
|
621
|
+
#define CHECK(c) if (!(c)) return n; n++;
|
|
622
|
+
|
|
623
|
+
static char hw_d011, hw_d018; // read right after the frame IRQ, before the split
|
|
624
|
+
static bool disk_round_trip;
|
|
625
|
+
|
|
626
|
+
// Save the high score, clear it, load it back: drive 8 must answer 00 and
|
|
627
|
+
// return the same number. Runs before the checks; the screen holds still.
|
|
628
|
+
static void disk_test(void)
|
|
629
|
+
{
|
|
630
|
+
unsigned h = hiscore;
|
|
631
|
+
hiscore_save();
|
|
632
|
+
hiscore = 0;
|
|
633
|
+
hiscore_load();
|
|
634
|
+
disk_round_trip = disk_on && disk_code == 0 && hiscore == h && h == EXPECT_SCORE;
|
|
635
|
+
hiscore = h;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
static char first_fail(void)
|
|
639
|
+
{
|
|
640
|
+
char kills = kills_by_type[0] + kills_by_type[1] + kills_by_type[2];
|
|
641
|
+
unsigned sum = kills_by_type[0] * 5 + kills_by_type[1] * 10 + kills_by_type[2] * 15;
|
|
642
|
+
char n = 1;
|
|
643
|
+
#ifdef STAGE
|
|
644
|
+
// The staged run grades only what it is for: no play frame ran into the
|
|
645
|
+
// next, and every bullet cell was restored every frame. stage-expect.json
|
|
646
|
+
// adds the meter's worst inside a frame.
|
|
647
|
+
CHECK(overruns == 0) // 1
|
|
648
|
+
CHECK(!bullet_fault) // 2
|
|
649
|
+
return 0;
|
|
650
|
+
#endif
|
|
651
|
+
CHECK(level_intact()) // 1 bullets restored every cell
|
|
652
|
+
CHECK(deaths == EXPECT_DEATHS) // 2 the script's one ram
|
|
653
|
+
CHECK(lives == START_LIVES - EXPECT_DEATHS) // 3
|
|
654
|
+
CHECK(score == sum) // 4 score = points of what was shot
|
|
655
|
+
CHECK(score == EXPECT_SCORE) // 5
|
|
656
|
+
CHECK(kills == EXPECT_KILLS) // 6
|
|
657
|
+
CHECK(waves_started == waves_due(cur_pos)) // 7 every wave the scroll reached
|
|
658
|
+
CHECK((hw_d011 & 7) == 3 && cur_y == 3) // 8 the frame IRQ applied YSCROLL 3
|
|
659
|
+
CHECK((hw_d018 & 0xfe) == (cur_front ? D018_PF1 : D018_PF0)) // 9 ... and the screen (bit 0 reads 1)
|
|
660
|
+
CHECK(K_MUX_SHOWN == EXPECT_SHOWN) // 10 the multiplexer shows 11
|
|
661
|
+
CHECK(parade_in_place()) // 11 ten bugs where the paths end
|
|
662
|
+
CHECK(p_hx == END_HX && p_y == END_Y) // 12 the ship where the script ends
|
|
663
|
+
CHECK(K_SFX_TAKEN != 0) // 13 effects ran in the player
|
|
664
|
+
CHECK(disk_round_trip) // 14 HISCORE written and read back
|
|
665
|
+
CHECK(overruns == 0) // 15 no play frame ran into the next
|
|
666
|
+
CHECK(!bullet_fault) // 16 every bullet cell restored, every frame
|
|
667
|
+
CHECK(eb_fired == EXPECT_FIRED) // 17 the enemies' shots
|
|
668
|
+
CHECK(ship_shots == EXPECT_DEATHS) // 18 the loss was a dot, not a ram
|
|
669
|
+
return 0;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
static void verdict(void)
|
|
673
|
+
{
|
|
674
|
+
char fail = first_fail();
|
|
675
|
+
char ok = fail == 0;
|
|
676
|
+
verdict_code = ok ? 1 : 2;
|
|
677
|
+
RESULT = verdict_code;
|
|
678
|
+
vic.color_border = ok ? VCOL_GREEN : VCOL_RED;
|
|
679
|
+
char *s = level_screen();
|
|
680
|
+
char kills = kills_by_type[0] + kills_by_type[1] + kills_by_type[2];
|
|
681
|
+
put_text(s, 9, 1, ok ? "RESULT 01 PASS " : "RESULT 02 FAIL 00");
|
|
682
|
+
if (!ok)
|
|
683
|
+
put_dec(s + 9 * 40 + 16, fail, 2);
|
|
684
|
+
put_text(s, 10, 1, "SCORE 000000 KILLS 00 LIVES 0");
|
|
685
|
+
put_dec(s + 10 * 40 + 7, score, 5);
|
|
686
|
+
put_dec(s + 10 * 40 + 20, kills, 2);
|
|
687
|
+
put_dec(s + 10 * 40 + 29, lives, 1);
|
|
688
|
+
put_text(s, 11, 1, "SHOWN 00 WAVES 00 SHIP 000 000 K 0 0 0");
|
|
689
|
+
put_dec(s + 11 * 40 + 7, K_MUX_SHOWN, 2);
|
|
690
|
+
put_dec(s + 11 * 40 + 16, waves_started, 2);
|
|
691
|
+
put_dec(s + 11 * 40 + 24, p_hx, 3);
|
|
692
|
+
put_dec(s + 11 * 40 + 28, p_y, 3);
|
|
693
|
+
put_dec(s + 11 * 40 + 34, kills_by_type[0], 1); // darts, saucers, bugs
|
|
694
|
+
put_dec(s + 11 * 40 + 36, kills_by_type[1], 1);
|
|
695
|
+
put_dec(s + 11 * 40 + 38, kills_by_type[2], 1);
|
|
696
|
+
text_colour(9, 1, 17, TEXT_CRAM);
|
|
697
|
+
text_colour(10, 1, 29, TEXT_CRAM);
|
|
698
|
+
text_colour(11, 1, 38, TEXT_CRAM);
|
|
699
|
+
put_text(s, 12, 1, "FIRED 00 HIT 0 OVERRUNS 00");
|
|
700
|
+
put_dec(s + 12 * 40 + 7, eb_fired, 2);
|
|
701
|
+
put_dec(s + 12 * 40 + 14, ship_shots, 1);
|
|
702
|
+
put_dec(s + 12 * 40 + 25, overruns, 2);
|
|
703
|
+
text_colour(12, 1, 26, TEXT_CRAM);
|
|
704
|
+
text_colour(13, 10, 20, TEXT_CRAM);
|
|
705
|
+
}
|
|
706
|
+
#endif
|
|
707
|
+
|
|
708
|
+
// PAL has 312 lines, NTSC 263: the largest line past 255 tells them apart.
|
|
709
|
+
static char is_ntsc(void)
|
|
710
|
+
{
|
|
711
|
+
char top = 0;
|
|
712
|
+
for (unsigned i = 0; i < 20000; i++) {
|
|
713
|
+
if (vic.ctrl1 & 0x80) {
|
|
714
|
+
char l = vic.raster;
|
|
715
|
+
if (l > top) top = l;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return top < 0x20;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
int main(void)
|
|
722
|
+
{
|
|
723
|
+
__asm { sei }
|
|
724
|
+
ntsc_arg = is_ntsc();
|
|
725
|
+
cia1.pra = 0xff; // no keyboard column selected
|
|
726
|
+
level_init();
|
|
727
|
+
display_init();
|
|
728
|
+
ACT_PTR[0] = SPR_BLOCK + F_SHIP;
|
|
729
|
+
ACT_COL[0] = VCOL_LT_BLUE;
|
|
730
|
+
title_enter();
|
|
731
|
+
#if !AUTOPILOT && defined(JOY_SOURCE)
|
|
732
|
+
*(volatile char *)JOY_SOURCE = 0xff; // nothing pressed until the monitor says so
|
|
733
|
+
#endif
|
|
734
|
+
#ifdef DRAWEND
|
|
735
|
+
*(volatile int *)0x0364 = 0x7fff;
|
|
736
|
+
*(volatile int *)0x0366 = 0x7fff;
|
|
737
|
+
#endif
|
|
738
|
+
LOST_FRAMES = 0;
|
|
739
|
+
hold_screen(); // show the title while the disk works: the
|
|
740
|
+
// kernel sets the VIC only in kernel_init
|
|
741
|
+
#if AUTOPILOT
|
|
742
|
+
hiscore_forget(); // every graded run starts from no file
|
|
743
|
+
#endif
|
|
744
|
+
hiscore_load(); // banks the KERNAL in for the calls only
|
|
745
|
+
disk_hi = hiscore;
|
|
746
|
+
panel_draw();
|
|
747
|
+
#if FRAME_METER
|
|
748
|
+
// The readout goes to a scratch row until the verdict copies it onto the
|
|
749
|
+
// playfield; play_enter starts the recording again.
|
|
750
|
+
meter_init((unsigned)SCRATCH, 13, 10, PF_CRAM, METER_HOLD);
|
|
751
|
+
K_MTR_OPEN = 0; // IRQs time themselves (timer B)
|
|
752
|
+
K_BYTE(ASM_MTR_ON) = 1; // the frame IRQ hands their sum to C
|
|
753
|
+
#else
|
|
754
|
+
K_MTR_OPEN = 1; // no meter: IRQs never touch timer B
|
|
755
|
+
#endif
|
|
756
|
+
__asm {
|
|
757
|
+
lda ntsc_arg
|
|
758
|
+
jsr ASM_KERNEL_INIT
|
|
759
|
+
cli
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
char prev = 0xff;
|
|
763
|
+
for (;;) {
|
|
764
|
+
wait_frame();
|
|
765
|
+
level_frame();
|
|
766
|
+
char joy = port_read();
|
|
767
|
+
switch (state) {
|
|
768
|
+
case ST_TITLE:
|
|
769
|
+
actors_draw();
|
|
770
|
+
if (!(joy & JOY_FIRE) && (prev & JOY_FIRE))
|
|
771
|
+
play_enter();
|
|
772
|
+
break;
|
|
773
|
+
case ST_PLAY:
|
|
774
|
+
#if AUTOPILOT
|
|
775
|
+
if (play_frames > PLAY_FRAMES && cur_y == FREEZE_Y) {
|
|
776
|
+
bullets_erase(); // freeze on YSCROLL 3: nothing
|
|
777
|
+
bullets_reset(); // moves after this frame
|
|
778
|
+
state = ST_FROZEN;
|
|
779
|
+
break;
|
|
780
|
+
}
|
|
781
|
+
#endif
|
|
782
|
+
#if defined(STAGE) && FRAME_METER
|
|
783
|
+
if (play_frames == STAGE_FROM) { // record the heavy part only
|
|
784
|
+
meter_init((unsigned)SCRATCH, 13, 10, PF_CRAM, METER_HOLD);
|
|
785
|
+
have_main = 0;
|
|
786
|
+
}
|
|
787
|
+
#endif
|
|
788
|
+
meter_open();
|
|
789
|
+
play_frame(joy);
|
|
790
|
+
meter_close();
|
|
791
|
+
if (state == ST_OVER)
|
|
792
|
+
over_enter();
|
|
793
|
+
break;
|
|
794
|
+
case ST_OVER:
|
|
795
|
+
actors_draw();
|
|
796
|
+
if (--over_timer == 0)
|
|
797
|
+
title_enter();
|
|
798
|
+
break;
|
|
799
|
+
#if AUTOPILOT
|
|
800
|
+
case ST_FROZEN:
|
|
801
|
+
if (!verdict_code) {
|
|
802
|
+
hw_d011 = vic.ctrl1; // the playfield's values until line 212
|
|
803
|
+
hw_d018 = vic.memptr;
|
|
804
|
+
disk_test();
|
|
805
|
+
verdict();
|
|
806
|
+
#ifdef STAGE
|
|
807
|
+
for (char a = 0; a < N_ACTORS; a++)
|
|
808
|
+
ACT_Y[a] = OFF_Y; // no sprite over the meter's readout
|
|
809
|
+
#endif
|
|
810
|
+
}
|
|
811
|
+
actors_draw();
|
|
812
|
+
memcpy(level_screen() + 13 * 40 + 10, SCRATCH + 13 * 40 + 10, 20);
|
|
813
|
+
break;
|
|
814
|
+
#endif
|
|
815
|
+
}
|
|
816
|
+
prev = joy;
|
|
817
|
+
// The readout is read once, after the freeze. Printing it every play
|
|
818
|
+
// frame cost up to 3,404 cycles outside the bracket (the review) and
|
|
819
|
+
// made the autopilot build drop frames the game itself does not.
|
|
820
|
+
if (state != ST_PLAY)
|
|
821
|
+
meter_print();
|
|
822
|
+
}
|
|
823
|
+
return 0;
|
|
824
|
+
}
|