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,781 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: mixed-fighters
|
|
3
|
+
toolchain: oscar64
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [mixed_sprite_char_actors, mob_priority]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D000, D001, D002, D003, D004, D005, D006, D007, D010, D011, D015, D016, D017, D018, D01B, D01C, D01D, D020, D021, D022, D023, D025, D026, D027, D028, D029, D02A, DC06, DC07, DC0F]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# Oscar64 mixed fighters: one fighter in four sprites, one in pre-shifted character cells, crossing with $D01B priority
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Two fighters on a plain backdrop, drawn two different ways. Fighter A
|
|
19
|
+
is four multicolour hardware sprites in a 2 x 2 block, 48 x 42 pixels.
|
|
20
|
+
Fighter B is a 5 x 6 block of multicolour character cells whose 30
|
|
21
|
+
glyphs, codes 128 to 157, belong to B alone. B's picture is 16
|
|
22
|
+
multicolour pixels (32 screen pixels) by 48 rows, stored pre-shifted
|
|
23
|
+
at the four multicolour-pixel offsets inside a cell, so B moves in
|
|
24
|
+
2-pixel steps while its block of codes moves in whole cells. A script
|
|
25
|
+
runs on autopilot: the two walk in and overlap with A in front, A
|
|
26
|
+
strikes, they walk through each other with B in front (A's `$D01B`
|
|
27
|
+
bits set), come back and hold overlapped. At 17 checkpoint ticks the
|
|
28
|
+
program hashes the arena's 240 screen codes, B's 240 glyph bytes and
|
|
29
|
+
A's sprite registers and compares them with the table the Python
|
|
30
|
+
model below prints. CIA1 timer B times the actor update every tick
|
|
31
|
+
and each part of it once with the screen blank. `$02FF` = `01` and a
|
|
32
|
+
green border on a pass, `02` and red otherwise (`headless-verify.md`).
|
|
33
|
+
This is the `mixed_sprite_char_actors` technique from
|
|
34
|
+
`docs/techniques/sprite.md`, with `mob_priority` deciding who is in
|
|
35
|
+
front.
|
|
36
|
+
|
|
37
|
+
## Source
|
|
38
|
+
|
|
39
|
+
```c
|
|
40
|
+
// mixed-fighters.c
|
|
41
|
+
//
|
|
42
|
+
// Two fighters drawn two ways. Fighter A is four multicolour hardware
|
|
43
|
+
// sprites, 2 x 2, 48 x 42 pixels. Fighter B is a 5 x 6 block of
|
|
44
|
+
// multicolour character cells whose 30 glyphs (codes 128 to 157) are
|
|
45
|
+
// rewritten from a pre-shifted table, so B moves in 2-pixel steps
|
|
46
|
+
// although its cells move in 8-pixel steps. A scripted fight runs on
|
|
47
|
+
// autopilot: they walk in and overlap with A in front, A strikes, they
|
|
48
|
+
// cross with B in front ($D01B), come back and hold overlapped.
|
|
49
|
+
// At checkpoint ticks the program hashes the arena's screen codes, the
|
|
50
|
+
// 240 glyph bytes and the sprite registers and compares them with a
|
|
51
|
+
// table printed by the page's Python model. CIA1 timer B times the
|
|
52
|
+
// actor update each tick and each part of it once with the screen blank.
|
|
53
|
+
// $02FF = 01 and a green border on a pass, 02 and red if not.
|
|
54
|
+
//
|
|
55
|
+
#include <c64/vic.h>
|
|
56
|
+
#include <c64/cia.h>
|
|
57
|
+
|
|
58
|
+
#define Screen ((char *)0x0400)
|
|
59
|
+
#define Color ((char *)0xd800)
|
|
60
|
+
#define Chars ((char *)0x3000) // $D018 = $1C
|
|
61
|
+
#define SprData ((char *)0x3800) // blocks 224..231
|
|
62
|
+
#define SPR_BLK 224
|
|
63
|
+
#define VR ((volatile char *)0xd000)
|
|
64
|
+
#define PTR ((volatile char *)0x07f8)
|
|
65
|
+
#define PORT (*(volatile char *)0x0001)
|
|
66
|
+
#define RESULT (*(volatile char *)0x02ff)
|
|
67
|
+
|
|
68
|
+
#define ROW0 13 // top row of the arena
|
|
69
|
+
#define ROWS 6
|
|
70
|
+
#define BASE 128 // B's glyph range, 30 codes
|
|
71
|
+
#define SPACE 32
|
|
72
|
+
#define FLOOR 160
|
|
73
|
+
#define SPR_Y 154 // A's top sprite Y register
|
|
74
|
+
#define A_MASK 0x0f // A owns sprites 0 to 3
|
|
75
|
+
|
|
76
|
+
// --- art: rectangles in multicolour pixels (x0, y0, x1, y1, bit pair) ----
|
|
77
|
+
struct Rect { char x0, y0, x1, y1, v; };
|
|
78
|
+
|
|
79
|
+
const struct Rect char_body[5] = {
|
|
80
|
+
{6, 0, 9, 9, 2}, {4, 10, 11, 25, 3}, {4, 26, 11, 29, 1},
|
|
81
|
+
{4, 30, 6, 47, 3}, {9, 30, 11, 47, 3}};
|
|
82
|
+
const struct Rect char_arms[2][2] = {
|
|
83
|
+
{{2, 12, 3, 25, 2}, {12, 12, 13, 25, 2}},
|
|
84
|
+
{{1, 4, 3, 11, 2}, {12, 4, 14, 11, 2}}};
|
|
85
|
+
const struct Rect spr_body[5] = {
|
|
86
|
+
{10, 0, 13, 9, 1}, {8, 10, 15, 25, 2}, {8, 26, 15, 28, 3},
|
|
87
|
+
{8, 29, 10, 41, 2}, {13, 29, 15, 41, 2}};
|
|
88
|
+
const struct Rect spr_arms[2][2] = {
|
|
89
|
+
{{6, 12, 7, 25, 1}, {16, 12, 17, 25, 1}},
|
|
90
|
+
{{5, 4, 7, 11, 1}, {16, 4, 18, 11, 1}}};
|
|
91
|
+
|
|
92
|
+
// B's canvas, 16 multicolour pixels (4 bytes) by 48 rows, one pose
|
|
93
|
+
char bcanvas[48 * 4];
|
|
94
|
+
// the pre-shifted glyphs: pose * 4 + shift, 240 bytes each in glyph order
|
|
95
|
+
char preshift[8][240];
|
|
96
|
+
|
|
97
|
+
void canvas_rect(char *c, char stride, const struct Rect *r)
|
|
98
|
+
{
|
|
99
|
+
for (char y = r->y0; y <= r->y1; y++)
|
|
100
|
+
for (char x = r->x0; x <= r->x1; x++) {
|
|
101
|
+
char *p = c + y * stride + (x >> 2);
|
|
102
|
+
char sh = 6 - 2 * (x & 3);
|
|
103
|
+
*p = (*p & ~(3 << sh)) | (r->v << sh);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void build_char_fighter(void)
|
|
108
|
+
{
|
|
109
|
+
for (char pose = 0; pose < 2; pose++) {
|
|
110
|
+
for (char i = 0; i < 192; i++)
|
|
111
|
+
bcanvas[i] = 0;
|
|
112
|
+
for (char i = 0; i < 5; i++)
|
|
113
|
+
canvas_rect(bcanvas, 4, char_body + i);
|
|
114
|
+
for (char i = 0; i < 2; i++)
|
|
115
|
+
canvas_rect(bcanvas, 4, char_arms[pose] + i);
|
|
116
|
+
for (char s = 0; s < 4; s++) {
|
|
117
|
+
char *g = preshift[pose * 4 + s];
|
|
118
|
+
for (char r = 0; r < 48; r++) {
|
|
119
|
+
char w[5];
|
|
120
|
+
w[0] = bcanvas[r * 4]; w[1] = bcanvas[r * 4 + 1];
|
|
121
|
+
w[2] = bcanvas[r * 4 + 2]; w[3] = bcanvas[r * 4 + 3];
|
|
122
|
+
w[4] = 0;
|
|
123
|
+
for (char k = 0; k < 2 * s; k++) { // shift right 2s bits
|
|
124
|
+
char c = 0;
|
|
125
|
+
for (char j = 0; j < 5; j++) {
|
|
126
|
+
char n = w[j] & 1;
|
|
127
|
+
w[j] = (w[j] >> 1) | (c << 7);
|
|
128
|
+
c = n;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (char cx = 0; cx < 5; cx++)
|
|
132
|
+
g[((r >> 3) * 5 + cx) * 8 + (r & 7)] = w[cx];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// A's canvas is 24 x 42 multicolour pixels, cut into four sprites
|
|
139
|
+
char acanvas[42 * 6];
|
|
140
|
+
|
|
141
|
+
void build_sprite_fighter(void)
|
|
142
|
+
{
|
|
143
|
+
for (char pose = 0; pose < 2; pose++) {
|
|
144
|
+
for (char i = 0; i < 252; i++)
|
|
145
|
+
acanvas[i] = 0;
|
|
146
|
+
for (char i = 0; i < 5; i++)
|
|
147
|
+
canvas_rect(acanvas, 6, spr_body + i);
|
|
148
|
+
for (char i = 0; i < 2; i++)
|
|
149
|
+
canvas_rect(acanvas, 6, spr_arms[pose] + i);
|
|
150
|
+
for (char part = 0; part < 4; part++) {
|
|
151
|
+
char *d = SprData + (pose * 4 + part) * 64;
|
|
152
|
+
char y0 = (part >> 1) * 21, b0 = (part & 1) * 3;
|
|
153
|
+
for (char r = 0; r < 21; r++)
|
|
154
|
+
for (char b = 0; b < 3; b++)
|
|
155
|
+
d[r * 3 + b] = acanvas[(y0 + r) * 6 + b0 + b];
|
|
156
|
+
d[63] = 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// --- fighter state ------------------------------------------------------
|
|
162
|
+
int ax, bx; // screen pixels, left edges
|
|
163
|
+
char apose, bpose, afront;
|
|
164
|
+
char cur_pose = 0xff, cur_shift = 0xff, cur_col = 0xff;
|
|
165
|
+
char *const arow[ROWS] = {
|
|
166
|
+
Screen + (ROW0 + 0) * 40, Screen + (ROW0 + 1) * 40, Screen + (ROW0 + 2) * 40,
|
|
167
|
+
Screen + (ROW0 + 3) * 40, Screen + (ROW0 + 4) * 40, Screen + (ROW0 + 5) * 40};
|
|
168
|
+
const char *gsrc;
|
|
169
|
+
char mcol_old, mcol_new;
|
|
170
|
+
|
|
171
|
+
// --- the technique --------------------------------------------------------
|
|
172
|
+
// Rewrite B's 30 glyphs from the pre-shifted table: 240 bytes.
|
|
173
|
+
__noinline void glyph_copy(void)
|
|
174
|
+
{
|
|
175
|
+
char *d = Chars + BASE * 8;
|
|
176
|
+
for (char i = 0; i < 120; i++) {
|
|
177
|
+
d[i] = gsrc[i];
|
|
178
|
+
d[i + 120] = gsrc[i + 120];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Move B's 5 x 6 block of codes when its cell column changes.
|
|
183
|
+
__noinline void cells_move(void)
|
|
184
|
+
{
|
|
185
|
+
for (char r = 0; r < ROWS; r++) {
|
|
186
|
+
char *p = arow[r];
|
|
187
|
+
if (mcol_old != 0xff)
|
|
188
|
+
for (char x = 0; x < 5; x++)
|
|
189
|
+
p[mcol_old + x] = SPACE;
|
|
190
|
+
char c = BASE + r * 5;
|
|
191
|
+
for (char x = 0; x < 5; x++)
|
|
192
|
+
p[mcol_new + x] = c + x;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Place A's four sprites, merge the 9th X bits, set pointers and priority.
|
|
197
|
+
__noinline void sprite_update(void)
|
|
198
|
+
{
|
|
199
|
+
char msb = 0;
|
|
200
|
+
int x = ax + 24;
|
|
201
|
+
char f = SPR_BLK + apose * 4;
|
|
202
|
+
for (char i = 0; i < 4; i++) {
|
|
203
|
+
int xi = (i & 1) ? x + 24 : x;
|
|
204
|
+
VR[i * 2] = (char)xi;
|
|
205
|
+
VR[i * 2 + 1] = SPR_Y + (i >> 1) * 21;
|
|
206
|
+
if (xi & 0x100)
|
|
207
|
+
msb |= 1 << i;
|
|
208
|
+
PTR[i] = f + i;
|
|
209
|
+
}
|
|
210
|
+
VR[0x10] = (VR[0x10] & ~A_MASK) | msb;
|
|
211
|
+
VR[0x1b] = (VR[0x1b] & ~A_MASK) | (afront ? 0 : A_MASK);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
void actors_update(void)
|
|
215
|
+
{
|
|
216
|
+
char col = (char)(bx >> 3), sh = ((char)bx & 7) >> 1;
|
|
217
|
+
if (bpose != cur_pose || sh != cur_shift) {
|
|
218
|
+
gsrc = preshift[bpose * 4 + sh];
|
|
219
|
+
glyph_copy();
|
|
220
|
+
cur_pose = bpose;
|
|
221
|
+
cur_shift = sh;
|
|
222
|
+
}
|
|
223
|
+
if (col != cur_col) {
|
|
224
|
+
mcol_old = cur_col;
|
|
225
|
+
mcol_new = col;
|
|
226
|
+
cells_move();
|
|
227
|
+
cur_col = col;
|
|
228
|
+
}
|
|
229
|
+
sprite_update();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// --- the script (the Python model runs the same table) ---------------------
|
|
233
|
+
struct Seg { char n; signed char da, db; char pa, pb, afront; };
|
|
234
|
+
#define NSEG 5
|
|
235
|
+
const struct Seg script[NSEG] = {
|
|
236
|
+
{50, 2, -2, 0, 0, 1}, {16, 0, 0, 1, 0, 1}, {30, 2, -2, 0, 0, 0},
|
|
237
|
+
{25, -2, 2, 0, 1, 0}, {8, 0, 2, 0, 1, 0}};
|
|
238
|
+
char seg, segleft;
|
|
239
|
+
|
|
240
|
+
void script_step(void)
|
|
241
|
+
{
|
|
242
|
+
while (seg < NSEG && segleft == 0) {
|
|
243
|
+
seg++;
|
|
244
|
+
if (seg < NSEG)
|
|
245
|
+
segleft = script[seg].n;
|
|
246
|
+
}
|
|
247
|
+
if (seg >= NSEG)
|
|
248
|
+
return; // hold the last state
|
|
249
|
+
const struct Seg *s = script + seg;
|
|
250
|
+
ax += s->da;
|
|
251
|
+
bx += s->db;
|
|
252
|
+
apose = s->pa;
|
|
253
|
+
bpose = s->pb;
|
|
254
|
+
afront = s->afront;
|
|
255
|
+
segleft--;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// --- the check: hashes against the model's table --------------------------
|
|
259
|
+
#define NCHK 17
|
|
260
|
+
const unsigned check_tick[NCHK] = {1, 2, 3, 4, 5, 25, 50, 58, 66, 67, 80, 96, 110, 121, 125, 129, 150};
|
|
261
|
+
const unsigned check_scr[NCHK] = {0x5fb9, 0x5fb9, 0x5fb9, 0x5fb9, 0xbf72, 0xee57, 0x95fb, 0x95fb, 0x95fb, 0x95fb, 0xafdc, 0xfdca, 0x5fb9, 0x2bf7, 0x95fb, 0xcafd, 0xcafd};
|
|
262
|
+
const unsigned check_gly[NCHK] = {0x7e6f, 0xf9bd, 0xe6f7, 0x9bdf, 0x7e6f, 0x7e6f, 0xf9bd, 0xf9bd, 0xf9bd, 0xe6f7, 0x9bdf, 0x9bdf, 0x9823, 0x608e, 0x608e, 0x608e, 0x608e};
|
|
263
|
+
const unsigned check_spr[NCHK] = {0x7062, 0x8f62, 0xda62, 0xe962, 0xbc62, 0xf862, 0x3f78, 0x3f44, 0x3f44, 0x6a88, 0x6587, 0x3582, 0xcf87, 0x868a, 0x868a, 0x868a, 0x868a};
|
|
264
|
+
|
|
265
|
+
unsigned hash;
|
|
266
|
+
void rx(char v)
|
|
267
|
+
{
|
|
268
|
+
hash = (hash << 1) | (hash >> 15);
|
|
269
|
+
hash ^= v;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
char check(char k)
|
|
273
|
+
{
|
|
274
|
+
char bad = 0;
|
|
275
|
+
hash = 0;
|
|
276
|
+
for (char r = 0; r < ROWS; r++)
|
|
277
|
+
for (char x = 0; x < 40; x++)
|
|
278
|
+
rx(arow[r][x]);
|
|
279
|
+
if (hash != check_scr[k]) bad |= 1;
|
|
280
|
+
hash = 0;
|
|
281
|
+
for (char i = 0; i < 240; i++)
|
|
282
|
+
rx(Chars[BASE * 8 + i]);
|
|
283
|
+
if (hash != check_gly[k]) bad |= 2;
|
|
284
|
+
hash = 0;
|
|
285
|
+
for (char i = 0; i < 8; i++)
|
|
286
|
+
rx(VR[i]);
|
|
287
|
+
rx(VR[0x10] & A_MASK);
|
|
288
|
+
rx(VR[0x1b] & A_MASK);
|
|
289
|
+
for (char i = 0; i < 4; i++)
|
|
290
|
+
rx(PTR[i]);
|
|
291
|
+
if (hash != check_spr[k]) bad |= 4;
|
|
292
|
+
return bad;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// --- CIA1 timer B -------------------------------------------------------------
|
|
296
|
+
static inline void timer_start(void)
|
|
297
|
+
{
|
|
298
|
+
cia1.crb = 0x00;
|
|
299
|
+
cia1.tb = 0xffff;
|
|
300
|
+
cia1.crb = 0x11;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
static inline unsigned timer_stop(void)
|
|
304
|
+
{
|
|
305
|
+
cia1.crb = 0x00;
|
|
306
|
+
return 0xffff - cia1.tb;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
__noinline void nothing(void) { }
|
|
310
|
+
|
|
311
|
+
unsigned time1(void (*fn)(void))
|
|
312
|
+
{
|
|
313
|
+
__asm { sei }
|
|
314
|
+
timer_start();
|
|
315
|
+
fn();
|
|
316
|
+
unsigned t = timer_stop();
|
|
317
|
+
__asm { cli }
|
|
318
|
+
return t;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// --- text (screen codes) ----------------------------------------------------------
|
|
322
|
+
void put_str(char *p, const char *s)
|
|
323
|
+
{
|
|
324
|
+
while (*s)
|
|
325
|
+
*p++ = *s++;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
void put_dec(char *p, unsigned v, char digits)
|
|
329
|
+
{
|
|
330
|
+
for (char i = digits; i > 0; i--) {
|
|
331
|
+
p[i - 1] = 0x30 + v % 10;
|
|
332
|
+
v /= 10;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
#define VERDICT_TICK 160
|
|
337
|
+
|
|
338
|
+
int main(void)
|
|
339
|
+
{
|
|
340
|
+
// Copy the ROM font's first 64 glyphs (letters, digits) to $3000.
|
|
341
|
+
__asm { sei }
|
|
342
|
+
PORT = 0x33;
|
|
343
|
+
for (unsigned i = 0; i < 512; i++)
|
|
344
|
+
Chars[i] = ((volatile char *)0xd000)[i];
|
|
345
|
+
PORT = 0x37;
|
|
346
|
+
__asm { cli }
|
|
347
|
+
for (char i = 0; i < 8; i++) {
|
|
348
|
+
Chars[SPACE * 8 + i] = 0;
|
|
349
|
+
Chars[FLOOR * 8 + i] = (i & 1) ? 0xaa : 0xff;
|
|
350
|
+
}
|
|
351
|
+
build_char_fighter();
|
|
352
|
+
build_sprite_fighter();
|
|
353
|
+
|
|
354
|
+
vic.color_border = 0;
|
|
355
|
+
vic.color_back = 11; // 00: dark grey
|
|
356
|
+
vic.color_back1 = 14; // 01: light blue, B's belt
|
|
357
|
+
vic.color_back2 = 7; // 10: yellow, B's head and arms
|
|
358
|
+
vic.memptr = 0x1c;
|
|
359
|
+
vic.ctrl2 |= VIC_CTRL2_MCM;
|
|
360
|
+
for (unsigned i = 0; i < 1000; i++) {
|
|
361
|
+
Screen[i] = SPACE;
|
|
362
|
+
Color[i] = 1; // hires white text
|
|
363
|
+
}
|
|
364
|
+
for (char i = 0; i < ROWS * 40; i++)
|
|
365
|
+
Color[ROW0 * 40 + i] = 8 | 2; // 11: red, B's body
|
|
366
|
+
for (char i = 0; i < 40; i++) {
|
|
367
|
+
Screen[(ROW0 + ROWS) * 40 + i] = FLOOR;
|
|
368
|
+
Color[(ROW0 + ROWS) * 40 + i] = 4; // hires purple floor
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
vic.spr_mcolor0 = 15; // 01: light grey, A's head and arms
|
|
372
|
+
vic.spr_mcolor1 = 6; // 11: blue, A's belt
|
|
373
|
+
for (char i = 0; i < 4; i++)
|
|
374
|
+
VR[0x27 + i] = 5; // 10: green, A's body and legs
|
|
375
|
+
vic.spr_multi = A_MASK;
|
|
376
|
+
vic.spr_expand_x = 0;
|
|
377
|
+
vic.spr_expand_y = 0;
|
|
378
|
+
|
|
379
|
+
put_str(Screen + 0, s"mixed fighters tick");
|
|
380
|
+
put_str(Screen + 2 * 40, s"a x pose b x pose front");
|
|
381
|
+
put_str(Screen + 3 * 40, s"checks mismatches");
|
|
382
|
+
put_str(Screen + 4 * 40, s"update max min");
|
|
383
|
+
put_str(Screen + 5 * 40, s"glyphs cells sprites");
|
|
384
|
+
put_str(Screen + 6 * 40, s"overlap ticks front swaps");
|
|
385
|
+
|
|
386
|
+
// Cost of each part, screen blanked, less an empty call.
|
|
387
|
+
vic.ctrl1 &= ~VIC_CTRL1_DEN;
|
|
388
|
+
vic_waitFrame();
|
|
389
|
+
vic_waitFrame();
|
|
390
|
+
unsigned t_none = time1(nothing);
|
|
391
|
+
gsrc = preshift[0];
|
|
392
|
+
unsigned t_copy = time1(glyph_copy) - t_none;
|
|
393
|
+
mcol_old = 20; mcol_new = 21;
|
|
394
|
+
unsigned t_move = time1(cells_move) - t_none;
|
|
395
|
+
ax = 250; // two sprites past X 255
|
|
396
|
+
unsigned t_spr = time1(sprite_update) - t_none;
|
|
397
|
+
for (char r = 0; r < ROWS; r++)
|
|
398
|
+
for (char x = 0; x < 40; x++)
|
|
399
|
+
arow[r][x] = SPACE;
|
|
400
|
+
vic.ctrl1 |= VIC_CTRL1_DEN;
|
|
401
|
+
put_dec(Screen + 5 * 40 + 7, t_copy, 4);
|
|
402
|
+
put_dec(Screen + 5 * 40 + 19, t_move, 4);
|
|
403
|
+
put_dec(Screen + 5 * 40 + 33, t_spr, 4);
|
|
404
|
+
|
|
405
|
+
ax = 40; bx = 248;
|
|
406
|
+
seg = 0; segleft = script[0].n;
|
|
407
|
+
vic.spr_enable = A_MASK;
|
|
408
|
+
|
|
409
|
+
unsigned tick = 0, mism = 0, checks = 0, overlap = 0, swaps = 0;
|
|
410
|
+
unsigned u_max = 0, u_min = 0xffff;
|
|
411
|
+
char k = 0, fault = 0, done = 0, lastfront = 1;
|
|
412
|
+
|
|
413
|
+
for (;;) {
|
|
414
|
+
vic_waitFrame(); // raster line 256
|
|
415
|
+
script_step();
|
|
416
|
+
__asm { sei }
|
|
417
|
+
timer_start();
|
|
418
|
+
actors_update();
|
|
419
|
+
unsigned tu = timer_stop();
|
|
420
|
+
__asm { cli }
|
|
421
|
+
tick++;
|
|
422
|
+
if (tu > u_max) u_max = tu;
|
|
423
|
+
if (tu < u_min) u_min = tu;
|
|
424
|
+
if (afront != lastfront) swaps++;
|
|
425
|
+
lastfront = afront;
|
|
426
|
+
// The figures' pixel spans: A 48 wide, B's 32-pixel canvas.
|
|
427
|
+
if (ax < bx + 32 && bx < ax + 48) overlap++;
|
|
428
|
+
|
|
429
|
+
if (k < NCHK && tick == check_tick[k]) {
|
|
430
|
+
if (check(k)) mism++;
|
|
431
|
+
checks++;
|
|
432
|
+
k++;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
switch (tick & 3) { // one line of text a tick
|
|
436
|
+
case 0:
|
|
437
|
+
put_dec(Screen + 22, tick, 4);
|
|
438
|
+
put_dec(Screen + 2 * 40 + 4, ax, 3);
|
|
439
|
+
Screen[2 * 40 + 13] = 0x30 + apose;
|
|
440
|
+
put_dec(Screen + 2 * 40 + 19, bx, 3);
|
|
441
|
+
Screen[2 * 40 + 29] = 0x30 + bpose;
|
|
442
|
+
put_str(Screen + 2 * 40 + 37, afront ? s"a" : s"b");
|
|
443
|
+
break;
|
|
444
|
+
case 1:
|
|
445
|
+
put_dec(Screen + 3 * 40 + 7, checks, 3);
|
|
446
|
+
put_dec(Screen + 3 * 40 + 23, mism, 3);
|
|
447
|
+
break;
|
|
448
|
+
case 2:
|
|
449
|
+
put_dec(Screen + 4 * 40 + 11, u_max, 4);
|
|
450
|
+
put_dec(Screen + 4 * 40 + 21, u_min, 4);
|
|
451
|
+
break;
|
|
452
|
+
case 3:
|
|
453
|
+
put_dec(Screen + 6 * 40 + 14, overlap, 3);
|
|
454
|
+
put_dec(Screen + 6 * 40 + 30, swaps, 2);
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (!done && tick == VERDICT_TICK) {
|
|
459
|
+
done = 1;
|
|
460
|
+
if (checks != NCHK) fault = 2;
|
|
461
|
+
if (mism) fault = 1;
|
|
462
|
+
RESULT = fault ? 2 : 1;
|
|
463
|
+
vic.color_border = fault ? 2 : 5;
|
|
464
|
+
put_str(Screen + 40, fault ? s"result fail" : s"result pass");
|
|
465
|
+
Screen[40 + 12] = 0x30 + fault;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return 0;
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## Build
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
oscar64 -tm=c64 -O2 -o=mixed-fighters.prg mixed-fighters.c
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Produces `mixed-fighters.prg`, 3,743 bytes, with no warnings. The map
|
|
479
|
+
puts the end of BSS at `$20FC`; the font at `$3000` and the sprite
|
|
480
|
+
images at `$3800` (blocks 224 to 231) sit above it and are built at
|
|
481
|
+
run time. Code or data that grows past `$3000` would be overwritten by
|
|
482
|
+
the font copy, so check the map after a change.
|
|
483
|
+
|
|
484
|
+
The `check_*` tables in the listing come from this model (Python 3).
|
|
485
|
+
It draws both fighters from the same rectangles, runs the same script,
|
|
486
|
+
and hashes what the arena's codes, B's glyph range and A's registers
|
|
487
|
+
must hold after each checkpoint tick. It shares no code with the C.
|
|
488
|
+
|
|
489
|
+
```python
|
|
490
|
+
# model.py: the mixed-fighters model. What the screen block, the glyph range and the
|
|
491
|
+
# sprite registers must hold after each checkpoint tick.
|
|
492
|
+
ROW0, ROWS, BASE, SPACE, SPR_BLK, SPR_Y = 13, 6, 128, 32, 224, 154
|
|
493
|
+
|
|
494
|
+
# rectangles (x0, y0, x1, y1, bit pair), multicolour pixels, inclusive
|
|
495
|
+
CHAR_BODY = [(6, 0, 9, 9, 2), (4, 10, 11, 25, 3), (4, 26, 11, 29, 1),
|
|
496
|
+
(4, 30, 6, 47, 3), (9, 30, 11, 47, 3)]
|
|
497
|
+
CHAR_ARMS = [[(2, 12, 3, 25, 2), (12, 12, 13, 25, 2)],
|
|
498
|
+
[(1, 4, 3, 11, 2), (12, 4, 14, 11, 2)]]
|
|
499
|
+
SPR_BODY = [(10, 0, 13, 9, 1), (8, 10, 15, 25, 2), (8, 26, 15, 28, 3),
|
|
500
|
+
(8, 29, 10, 41, 2), (13, 29, 15, 41, 2)]
|
|
501
|
+
SPR_ARMS = [[(6, 12, 7, 25, 1), (16, 12, 17, 25, 1)],
|
|
502
|
+
[(5, 4, 7, 11, 1), (16, 4, 18, 11, 1)]]
|
|
503
|
+
|
|
504
|
+
# (ticks, da, db, pose a, pose b, sprite fighter in front); the last
|
|
505
|
+
# segment's poses hold after the script ends
|
|
506
|
+
SCRIPT = [(50, 2, -2, 0, 0, 1), (16, 0, 0, 1, 0, 1), (30, 2, -2, 0, 0, 0),
|
|
507
|
+
(25, -2, 2, 0, 1, 0), (8, 0, 2, 0, 1, 0)]
|
|
508
|
+
CHECKS = [1, 2, 3, 4, 5, 25, 50, 58, 66, 67, 80, 96, 110, 121, 125, 129, 150]
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def canvas(w, h, rects):
|
|
512
|
+
c = [[0] * w for _ in range(h)]
|
|
513
|
+
for x0, y0, x1, y1, v in rects:
|
|
514
|
+
for y in range(y0, y1 + 1):
|
|
515
|
+
for x in range(x0, x1 + 1):
|
|
516
|
+
c[y][x] = v
|
|
517
|
+
return c
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def glyphs(pose, shift):
|
|
521
|
+
c = canvas(16, 48, CHAR_BODY + CHAR_ARMS[pose])
|
|
522
|
+
g = [0] * 240
|
|
523
|
+
for r in range(48):
|
|
524
|
+
w = 0
|
|
525
|
+
for x in range(16):
|
|
526
|
+
w = (w << 2) | c[r][x]
|
|
527
|
+
w = (w << 8) >> (2 * shift) # 40 bits, five cells
|
|
528
|
+
for cx in range(5):
|
|
529
|
+
g[((r >> 3) * 5 + cx) * 8 + (r & 7)] = (w >> (8 * (4 - cx))) & 255
|
|
530
|
+
return g
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
def rotxor(bs):
|
|
534
|
+
h = 0
|
|
535
|
+
for v in bs:
|
|
536
|
+
h = (((h << 1) | (h >> 15)) & 0xFFFF) ^ v
|
|
537
|
+
return h
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
def state_after(t):
|
|
541
|
+
a, b, pa, pb, fr = 40, 248, 0, 0, 1
|
|
542
|
+
left = t
|
|
543
|
+
for n, da, db, qa, qb, f in SCRIPT:
|
|
544
|
+
k = min(n, left)
|
|
545
|
+
if k:
|
|
546
|
+
a += da * k
|
|
547
|
+
b += db * k
|
|
548
|
+
pa, pb, fr = qa, qb, f
|
|
549
|
+
left -= k
|
|
550
|
+
return a, b, pa, pb, fr
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def expect(t):
|
|
554
|
+
a, b, pa, pb, fr = state_after(t)
|
|
555
|
+
col = b >> 3
|
|
556
|
+
scr = []
|
|
557
|
+
for r in range(ROWS):
|
|
558
|
+
for x in range(40):
|
|
559
|
+
scr.append(BASE + r * 5 + (x - col) if col <= x < col + 5 else SPACE)
|
|
560
|
+
regs, msb = [], 0
|
|
561
|
+
for i in range(4):
|
|
562
|
+
x = a + 24 + (i & 1) * 24
|
|
563
|
+
regs += [x & 255, SPR_Y + (i >> 1) * 21]
|
|
564
|
+
if x & 256:
|
|
565
|
+
msb |= 1 << i
|
|
566
|
+
regs += [msb, 0 if fr else 15] + [SPR_BLK + pa * 4 + i for i in range(4)]
|
|
567
|
+
return rotxor(scr), rotxor(glyphs(pb, (b & 7) >> 1)), rotxor(regs), (a, b, pa, pb, fr)
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
if __name__ == "__main__":
|
|
571
|
+
rows = [expect(t) for t in CHECKS]
|
|
572
|
+
print("const unsigned check_tick[NCHK] = {%s};" % ", ".join(map(str, CHECKS)))
|
|
573
|
+
for k, name in enumerate(["check_scr", "check_gly", "check_spr"]):
|
|
574
|
+
print("const unsigned %s[NCHK] = {%s};" % (
|
|
575
|
+
name, ", ".join("0x%04x" % r[k] for r in rows)))
|
|
576
|
+
for t, r in zip(CHECKS, rows):
|
|
577
|
+
print("# tick %3d a %3d b %3d pose %d %d front %s" % (
|
|
578
|
+
t, *r[3][:4], "sprite" if r[3][4] else "char"))
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Then run headless in VICE (PAL):
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas x64sc -default -warp +sound \
|
|
585
|
+
+autostart-delay-random -autostartprgmode 1 -limitcycles 8000000 \
|
|
586
|
+
-exitscreenshot mixed-fighters.png -autostart mixed-fighters.prg
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
Add `-model ntsc` for the NTSC picture. The script is 129 ticks and the
|
|
590
|
+
verdict is posted at tick 160; at 8,000,000 cycles that has happened on
|
|
591
|
+
both models.
|
|
592
|
+
|
|
593
|
+
## Expected output
|
|
594
|
+
|
|
595
|
+
The script, one tick per loop pass. Positions are the left edges in
|
|
596
|
+
screen pixels: A's 48-pixel block, and B's 32-pixel picture.
|
|
597
|
+
|
|
598
|
+
| Ticks | A x | B x | A pose | B pose | In front |
|
|
599
|
+
|---|---|---|---|---|---|
|
|
600
|
+
| 1-50 | 42 to 140, +2 a tick | 246 to 148, -2 a tick | stand | stand | A |
|
|
601
|
+
| 51-66 | 140 | 148 | strike | stand | A |
|
|
602
|
+
| 67-96 | 142 to 200 | 146 to 88 | stand | stand | B |
|
|
603
|
+
| 97-121 | 198 to 150 | 90 to 138 | stand | arms up | B |
|
|
604
|
+
| 122-129 | 150 | 140 to 154 | stand | arms up | B |
|
|
605
|
+
| 130 on | 150 | 154 | stand | arms up | B |
|
|
606
|
+
|
|
607
|
+
Colours: A is green (5) from `$D027`-`$D02A`, light grey (15) from
|
|
608
|
+
`$D025` for the head and arms, blue (6) from `$D026` for the belt. B is
|
|
609
|
+
red (2) from colour RAM for body and legs, yellow (7) from `$D023` for
|
|
610
|
+
head and arms, light blue (14) from `$D022` for the belt. The backdrop
|
|
611
|
+
is dark grey (11) and the floor purple (4).
|
|
612
|
+
|
|
613
|
+
Measured in VICE x64sc 3.10 with the pinned command, text decoded
|
|
614
|
+
against the character ROM (rows 0 to 6, PAL):
|
|
615
|
+
|
|
616
|
+
```text
|
|
617
|
+
MIXED FIGHTERS TICK 0172
|
|
618
|
+
RESULT PASS 0
|
|
619
|
+
A X 150 POSE 0 B X 154 POSE 1 FRONT B
|
|
620
|
+
CHECKS 017 MISMATCHES 000
|
|
621
|
+
UPDATE MAX 6108 MIN 0508
|
|
622
|
+
GLYPHS 3323 CELLS 1899 SPRITES 0448
|
|
623
|
+
OVERLAP TICKS 090 FRONT SWAPS 01
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
NTSC reads the same except `TICK 0180`, `UPDATE MAX 6366` and `OVERLAP
|
|
627
|
+
TICKS 098`. The tick counter and the overlap count keep running in the
|
|
628
|
+
hold, so both depend on the cycle count; the NTSC run fits more ticks
|
|
629
|
+
into the same cycles. The tick is printed every fourth tick. The border
|
|
630
|
+
is palette index 5, (98, 213, 50) on PAL and (114, 189, 103) on NTSC.
|
|
631
|
+
|
|
632
|
+
What the numbers say:
|
|
633
|
+
|
|
634
|
+
- `CHECKS 017 MISMATCHES 000`: at every checkpoint the arena's screen
|
|
635
|
+
codes, B's glyph bytes and A's X, Y, `$D010`, `$D01B` bits and
|
|
636
|
+
pointers hashed to the model's values. The checkpoints include ticks
|
|
637
|
+
1 to 5, which step B through all four shifts, the strike, the tick the
|
|
638
|
+
priority swaps, and the hold.
|
|
639
|
+
- `UPDATE MAX 6108 MIN 0508`: the whole actor update, CIA1 timer B,
|
|
640
|
+
interrupts masked, started at raster line 256, worst and best tick of
|
|
641
|
+
the run. The worst tick is one that rewrites B's glyphs, moves B's
|
|
642
|
+
block of codes one cell and places A, which every walking tick on
|
|
643
|
+
which B crosses a cell boundary does: the three parts measured below
|
|
644
|
+
sum to 5,670 of the 6,108. The best is a hold tick, A's registers only. On NTSC the
|
|
645
|
+
worst is 6,366: the NTSC frame has 263 lines, so an update of about
|
|
646
|
+
94 lines from line 256 runs into the badlines at the top of the text
|
|
647
|
+
area; on PAL it ends by line 41, before the first badline at 51
|
|
648
|
+
(arithmetic from 63 and 65 cycles a line; the stall was not traced).
|
|
649
|
+
- `GLYPHS 3323 CELLS 1899 SPRITES 0448`: each part once, screen
|
|
650
|
+
blanked, less an empty call: the 240-byte glyph copy, the 5 x 6 block
|
|
651
|
+
cleared and rewritten one cell over (60 stores), and A's four sprites
|
|
652
|
+
placed with two of them past X 255. The rest of the worst tick, 438
|
|
653
|
+
cycles, is `actors_update` itself, the call and the timer.
|
|
654
|
+
- `FRONT SWAPS 01`: the one priority change, at tick 67.
|
|
655
|
+
|
|
656
|
+
The pictures: `screenshots/mixed-fighters.png` (PAL) and
|
|
657
|
+
`screenshots/mixed-fighters-ntsc.png` (NTSC), the hold at A x 150,
|
|
658
|
+
B x 154, B in front. The script below decodes the arena, raster lines
|
|
659
|
+
155 to 202 by 320 pixels, to palette indices and compares every pixel
|
|
660
|
+
with the model's picture of the two fighters under the `$D01B` rule.
|
|
661
|
+
|
|
662
|
+
| Shot | Pixels wrong | B over A | A through B's `$D022` belt | A only | B only |
|
|
663
|
+
|---|---|---|---|---|---|
|
|
664
|
+
| PAL, 8,000,000 cycles | 0 of 15,360 | 344 | 44 | 264 | 324 |
|
|
665
|
+
| NTSC, 8,000,000 cycles | 0 of 15,360 | 344 | 44 | 264 | 324 |
|
|
666
|
+
|
|
667
|
+
A's colours cover x 198 to 217 and B's x 188 to 215 in both shots,
|
|
668
|
+
A on rows 139 to 180 and B on 139 to 186 on PAL (127 to 168 and 127 to
|
|
669
|
+
174 on NTSC; line − 16 and − 28):
|
|
670
|
+
B's first line is raster 155, text row 13, and so is A's with sprite
|
|
671
|
+
Y register 154. Where B's red, yellow body covers A, B shows; where
|
|
672
|
+
B's light blue belt covers A, A shows, though A is behind. In
|
|
673
|
+
multicolour text mode bit pair 01 counts as background for sprite
|
|
674
|
+
priority, like 00 (measured here; Bauer's VIC-II article, section 3.8.2,
|
|
675
|
+
says the same: with MCM set, 00 and 01 are background and 10 and 11
|
|
676
|
+
foreground, http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt).
|
|
677
|
+
|
|
678
|
+
A probe at 5,450,000 cycles, not pinned, caught the strike (tick 60 on
|
|
679
|
+
PAL, 56 on NTSC; A x 140, B x 148, A in front). The same script found
|
|
680
|
+
0 of 15,360 pixels wrong on both models, with 540 pixels of A over B,
|
|
681
|
+
belt included. Each pinned shot run twice gives byte-identical PNGs.
|
|
682
|
+
|
|
683
|
+
```python
|
|
684
|
+
# measure.py: python3 measure.py shot.png pal|ntsc tick. Needs model.py
|
|
685
|
+
# (above) beside it and Pillow.
|
|
686
|
+
import sys
|
|
687
|
+
from PIL import Image
|
|
688
|
+
from model import canvas, CHAR_BODY, CHAR_ARMS, SPR_BODY, SPR_ARMS, state_after
|
|
689
|
+
|
|
690
|
+
PAL = {0: (0, 0, 0), 1: (255, 255, 255), 2: (175, 60, 88), 3: (126, 243, 214), 4: (170, 64, 245),
|
|
691
|
+
5: (98, 213, 50), 6: (44, 61, 236), 7: (255, 255, 70), 8: (183, 99, 30), 9: (119, 83, 0),
|
|
692
|
+
10: (238, 123, 149), 11: (98, 98, 98), 12: (148, 148, 148), 13: (183, 255, 134),
|
|
693
|
+
14: (115, 133, 255), 15: (205, 205, 205)}
|
|
694
|
+
NTSC = {0: (0, 0, 0), 1: (255, 255, 255), 2: (169, 71, 100), 3: (138, 230, 203), 4: (154, 88, 185),
|
|
695
|
+
5: (114, 189, 103), 6: (25, 73, 180), 7: (255, 248, 141), 8: (196, 98, 65), 9: (151, 64, 0),
|
|
696
|
+
10: (230, 134, 163), 11: (98, 98, 98), 12: (148, 148, 148), 13: (198, 255, 186),
|
|
697
|
+
14: (98, 145, 251), 15: (205, 205, 205)}
|
|
698
|
+
B_COL = {1: 14, 2: 7, 3: 2} # D022, D023, colour RAM
|
|
699
|
+
A_COL = {1: 15, 2: 5, 3: 6} # D025, D027, D026
|
|
700
|
+
|
|
701
|
+
path, model, tick = sys.argv[1], sys.argv[2], int(sys.argv[3])
|
|
702
|
+
pal, off = (PAL, 16) if model == 'pal' else (NTSC, 28)
|
|
703
|
+
inv = {v: k for k, v in pal.items()}
|
|
704
|
+
im = Image.open(path).convert('RGB')
|
|
705
|
+
a, b, pa, pb, afront = state_after(tick)
|
|
706
|
+
bc = canvas(16, 48, CHAR_BODY + CHAR_ARMS[pb])
|
|
707
|
+
ac = canvas(24, 42, SPR_BODY + SPR_ARMS[pa])
|
|
708
|
+
LINE0 = 51 + 13 * 8 # first raster line of the arena
|
|
709
|
+
stats = dict(bad=0, total=0, a_only=0, b_only=0, a_over_b=0, b_over_a=0, a_through_belt=0)
|
|
710
|
+
first_bad = None
|
|
711
|
+
for line in range(LINE0, LINE0 + 48):
|
|
712
|
+
for px in range(320):
|
|
713
|
+
r = line - LINE0
|
|
714
|
+
bv = bc[r][(px - b) // 2] if b <= px < b + 32 else 0
|
|
715
|
+
av = ac[r][(px - a) // 2] if a <= px < a + 48 and r < 42 else 0
|
|
716
|
+
if av and bv:
|
|
717
|
+
if afront or bv == 1:
|
|
718
|
+
want = A_COL[av]
|
|
719
|
+
stats['a_through_belt' if bv == 1 and not afront else 'a_over_b'] += 1
|
|
720
|
+
else:
|
|
721
|
+
want = B_COL[bv]
|
|
722
|
+
stats['b_over_a'] += 1
|
|
723
|
+
elif av:
|
|
724
|
+
want = A_COL[av]; stats['a_only'] += 1
|
|
725
|
+
elif bv:
|
|
726
|
+
want = B_COL[bv]; stats['b_only'] += 1
|
|
727
|
+
else:
|
|
728
|
+
want = 11
|
|
729
|
+
got = inv.get(im.getpixel((32 + px, line - off)), -1)
|
|
730
|
+
stats['total'] += 1
|
|
731
|
+
if got != want:
|
|
732
|
+
stats['bad'] += 1
|
|
733
|
+
if first_bad is None:
|
|
734
|
+
first_bad = (px, line, want, got)
|
|
735
|
+
print(path, model, 'tick', tick, 'a', a, 'b', b, 'poses', pa, pb, 'front', 'A' if afront else 'B')
|
|
736
|
+
print(stats, 'first mismatch', first_bad)
|
|
737
|
+
# bounding boxes of each fighter's own colours, screenshot coordinates
|
|
738
|
+
for name, cols in (('A', {15, 5, 6}), ('B', {14, 7, 2})):
|
|
739
|
+
xs, ys = [], []
|
|
740
|
+
for y in range(LINE0 - off, LINE0 - off + 48):
|
|
741
|
+
for x in range(32, 352):
|
|
742
|
+
if inv.get(im.getpixel((x, y)), -1) in cols:
|
|
743
|
+
xs.append(x); ys.append(y)
|
|
744
|
+
print(name, 'box x', min(xs), '-', max(xs), 'y', min(ys), '-', max(ys))
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
## Why this works
|
|
748
|
+
|
|
749
|
+
**B is a picture in its own glyphs.** Codes 128 to 157 are used by no
|
|
750
|
+
other cell, so rewriting their 240 bytes redraws B and nothing else.
|
|
751
|
+
The block of codes on screen is laid out once per cell position:
|
|
752
|
+
code `128 + row * 5 + column`. `glyph_copy` runs only when B's pose or
|
|
753
|
+
its shift inside the cell changes, and `cells_move` only when its cell
|
|
754
|
+
column changes. `cells_move` clears the old block before writing the
|
|
755
|
+
new one; without that the column B walked out of would keep its codes
|
|
756
|
+
and show a stale strip of B (`dirty_cell_skip_leaves_overlay_trail`;
|
|
757
|
+
from the mechanism, not run here).
|
|
758
|
+
|
|
759
|
+
**Pre-shifted by multicolour pixel.** A multicolour pixel is two screen
|
|
760
|
+
pixels wide, so four shifts cover every position inside a cell. Each
|
|
761
|
+
pose is stored four times, each copy 5 cells wide so the shifted
|
|
762
|
+
picture has room, 240 bytes each, 1,920 bytes for two poses (the
|
|
763
|
+
array's size in the map). A draw is then a straight copy at every
|
|
764
|
+
shift. Moving in whole cells would need no table and no copy on a
|
|
765
|
+
move, but B would step 8 pixels while A glides in 2.
|
|
766
|
+
|
|
767
|
+
**Priority is A's four `$D01B` bits.** With them clear A is in front of
|
|
768
|
+
everything B draws. With them set B's foreground pixels, bit pairs 10
|
|
769
|
+
and 11, cover A; pairs 00 and 01 do not. Sprite-to-sprite order does not
|
|
770
|
+
enter, as B is not a sprite. The script flips the bits in the same
|
|
771
|
+
update as the positions, before the raster reaches the fighters.
|
|
772
|
+
|
|
773
|
+
**The update runs in the vertical blank.** `vic_waitFrame` returns at
|
|
774
|
+
line 256. The worst update ends by line 41 on PAL and before line 91 on
|
|
775
|
+
NTSC (arithmetic from the measured cycles), both above B's first line,
|
|
776
|
+
155, so B's glyphs never change while the VIC is drawing them.
|
|
777
|
+
|
|
778
|
+
Verified: compiled with Oscar64, run headless in VICE x64sc 3.10 with the
|
|
779
|
+
pinned command on PAL and NTSC, each twice with byte-identical PNGs; the
|
|
780
|
+
text was decoded against the character ROM and every arena pixel
|
|
781
|
+
compared with the model's picture with PIL, not by eye.
|