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,671 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: sprite-animation-table
|
|
3
|
+
toolchain: oscar64
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [sprite_animation_table]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D000, D001, D010, D011, D015, D020, D021, D027, DC06, DC07, DC0F]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# Oscar64 Sprite Animation Tables: frames and durations in data, events on entry, priority on request
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Six actors animate from tables. An animation is a list of (frame,
|
|
19
|
+
duration) entries ending in an action: loop to entry N, hold the last
|
|
20
|
+
frame, or return to another animation. Bit 7 of a frame byte marks an
|
|
21
|
+
event fired when the entry is entered. Each actor keeps its animation,
|
|
22
|
+
its entry and a countdown, and a step is one decrement on most frames.
|
|
23
|
+
Facing adds 8 to the sprite block number. A script of requests runs
|
|
24
|
+
121 frames: a looping walk, an idle, a rise that plays entry 0 once and
|
|
25
|
+
loops from entry 1, an attack that fires on its third entry and returns
|
|
26
|
+
to idle, a hurt that cuts an attack off before it fires, a death that
|
|
27
|
+
holds its last frame, two requests refused by priority and two ignored
|
|
28
|
+
because the animation is already running. The engine logs every event
|
|
29
|
+
with its frame number. A second model walks the tables from each
|
|
30
|
+
animation's start instead of counting down; it computes the expected
|
|
31
|
+
log and the final sprite pointers, and the program compares both. The
|
|
32
|
+
screen shows the pointers read back from `$07F8` beside the model's, the
|
|
33
|
+
log, and CIA1 timer B cycles per step. `$02FF` = `01` and a green border
|
|
34
|
+
on a pass, `02` and red otherwise (`headless-verify.md`). This is the
|
|
35
|
+
`sprite_animation_table` technique from `docs/techniques/sprite.md`.
|
|
36
|
+
|
|
37
|
+
## Source
|
|
38
|
+
|
|
39
|
+
```c
|
|
40
|
+
// sprite-animation-table.c
|
|
41
|
+
//
|
|
42
|
+
// Sprite animation driven by tables. An animation is a list of
|
|
43
|
+
// (frame, duration) entries ending in an action: loop to entry N, hold
|
|
44
|
+
// the last frame, or return to another animation. Bit 7 of a frame byte
|
|
45
|
+
// marks an event that fires when the entry is entered. Each actor keeps
|
|
46
|
+
// its animation, its entry and a countdown; a step is one decrement on
|
|
47
|
+
// most frames. Facing is an offset of 8 into the sprite block numbers.
|
|
48
|
+
// Six actors run a script of requests, two of them refused by priority.
|
|
49
|
+
// The engine logs events with frame numbers; a second model, which walks
|
|
50
|
+
// the tables from the start of each animation instead of counting down,
|
|
51
|
+
// computes the expected log and the final sprite pointers.
|
|
52
|
+
// Rows 0-1: title and verdict. Rows 3-8: per actor, the animation, the
|
|
53
|
+
// pointer the VIC reads at $07F8 + n and the one the model predicts.
|
|
54
|
+
// Sprites 0-5 stand below them. Rows 13-15: events and CIA1 timer B
|
|
55
|
+
// cycles. Row 16 on: the event log. $02FF = 01 and a green border when
|
|
56
|
+
// the log and every pointer match; 02 and red otherwise.
|
|
57
|
+
//
|
|
58
|
+
#include <c64/vic.h>
|
|
59
|
+
#include <c64/cia.h>
|
|
60
|
+
|
|
61
|
+
#define Screen ((char *)0x0400)
|
|
62
|
+
#define SprPtr ((volatile char *)0x07f8) // screen + $3F8: the VIC's pointers
|
|
63
|
+
#define SprData ((char *)0x3000) // block 192 = $3000 / 64 in bank 0
|
|
64
|
+
#define SPR_BLK 192 // blocks 192-199 face right
|
|
65
|
+
#define FACE_L 8 // blocks 200-207 face left
|
|
66
|
+
#define RESULT (*(volatile char *)0x02ff)
|
|
67
|
+
|
|
68
|
+
// --- the tables ---------------------------------------------------------
|
|
69
|
+
// One flat pair of arrays holds every animation; anim_first[] is where
|
|
70
|
+
// each starts. A frame byte 0-7 is an image, | EV_FIRE marks an event.
|
|
71
|
+
// An end entry's frame byte is an action and its duration byte the
|
|
72
|
+
// argument: END_LOOP (entry index to loop to), END_HOLD (unused),
|
|
73
|
+
// END_RETURN (animation to return to).
|
|
74
|
+
#define EV_FIRE 0x80
|
|
75
|
+
#define END_LOOP 0xf0
|
|
76
|
+
#define END_HOLD 0xf1
|
|
77
|
+
#define END_RETURN 0xf2
|
|
78
|
+
|
|
79
|
+
#define AN_IDLE 0
|
|
80
|
+
#define AN_WALK 1
|
|
81
|
+
#define AN_ATTACK 2
|
|
82
|
+
#define AN_HURT 3
|
|
83
|
+
#define AN_DEATH 4
|
|
84
|
+
#define AN_RISE 5
|
|
85
|
+
#define AN_TFAST 6 // timing only: advances every step
|
|
86
|
+
#define AN_TSLOW 7 // timing only: never advances
|
|
87
|
+
#define ANIMS 8
|
|
88
|
+
#define AN_NONE 0xff
|
|
89
|
+
|
|
90
|
+
const char afrm[] = {
|
|
91
|
+
0, 1, END_LOOP, // 0 idle
|
|
92
|
+
2, 3, 4, 3, END_LOOP, // 3 walk
|
|
93
|
+
5, 6, 7 | EV_FIRE, 6, END_RETURN, // 8 attack: fires on entry 3
|
|
94
|
+
1, 0, 1, 0, END_RETURN, // 13 hurt
|
|
95
|
+
4, 5, 6, 7, END_HOLD, // 18 death: holds frame 7
|
|
96
|
+
0, 2, 3, END_LOOP, // 23 rise: entry 0 once
|
|
97
|
+
0, 1, END_LOOP, // 27 timing, fast
|
|
98
|
+
0, END_LOOP // 30 timing, slow
|
|
99
|
+
};
|
|
100
|
+
const char adur[] = {
|
|
101
|
+
20, 20, 0,
|
|
102
|
+
6, 6, 6, 6, 0,
|
|
103
|
+
4, 4, 8, 4, AN_IDLE,
|
|
104
|
+
3, 3, 3, 3, AN_IDLE,
|
|
105
|
+
5, 5, 5, 5, 0,
|
|
106
|
+
10, 8, 8, 1, // rise loops to entry 1
|
|
107
|
+
1, 1, 0,
|
|
108
|
+
255, 0
|
|
109
|
+
};
|
|
110
|
+
const char anim_first[ANIMS] = { 0, 3, 8, 13, 18, 23, 27, 30 };
|
|
111
|
+
// A request is refused while the running animation has a higher
|
|
112
|
+
// priority. Death holds forever at the top priority.
|
|
113
|
+
const char anim_prio[ANIMS] = { 0, 0, 1, 2, 3, 0, 0, 0 };
|
|
114
|
+
|
|
115
|
+
// --- per-actor state ----------------------------------------------------
|
|
116
|
+
#define ACTORS 6
|
|
117
|
+
char cur[ACTORS]; // running animation
|
|
118
|
+
char pos[ACTORS]; // entry, an index into afrm/adur
|
|
119
|
+
char count[ACTORS]; // frames left on this entry
|
|
120
|
+
char held[ACTORS]; // 1 after END_HOLD, or no animation
|
|
121
|
+
char base[ACTORS]; // SPR_BLK, + FACE_L when facing left
|
|
122
|
+
|
|
123
|
+
// --- the event log ------------------------------------------------------
|
|
124
|
+
#define LG_FIRE 1
|
|
125
|
+
#define LG_DONE 2
|
|
126
|
+
#define LG_REFUSED 3
|
|
127
|
+
#define MAXLOG 16
|
|
128
|
+
unsigned frame;
|
|
129
|
+
char nlog;
|
|
130
|
+
unsigned lf[MAXLOG];
|
|
131
|
+
char la[MAXLOG], le[MAXLOG];
|
|
132
|
+
|
|
133
|
+
void log_ev(char a, char ev)
|
|
134
|
+
{
|
|
135
|
+
if (nlog < MAXLOG) {
|
|
136
|
+
lf[nlog] = frame;
|
|
137
|
+
la[nlog] = a;
|
|
138
|
+
le[nlog] = ev;
|
|
139
|
+
}
|
|
140
|
+
nlog++;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Actor a has moved to entry pos[a]: run end actions until a real entry,
|
|
144
|
+
// load its countdown, fire its event, set the sprite pointer.
|
|
145
|
+
void enter(char a)
|
|
146
|
+
{
|
|
147
|
+
char p = pos[a];
|
|
148
|
+
char f = afrm[p];
|
|
149
|
+
while (f >= END_LOOP) {
|
|
150
|
+
if (f == END_LOOP)
|
|
151
|
+
p = anim_first[cur[a]] + adur[p];
|
|
152
|
+
else if (f == END_RETURN) {
|
|
153
|
+
log_ev(a, LG_DONE);
|
|
154
|
+
cur[a] = adur[p];
|
|
155
|
+
p = anim_first[cur[a]];
|
|
156
|
+
} else { // END_HOLD: stay on the last entry
|
|
157
|
+
log_ev(a, LG_DONE);
|
|
158
|
+
held[a] = 1;
|
|
159
|
+
pos[a] = p - 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
f = afrm[p];
|
|
163
|
+
}
|
|
164
|
+
pos[a] = p;
|
|
165
|
+
count[a] = adur[p];
|
|
166
|
+
if (f & EV_FIRE)
|
|
167
|
+
log_ev(a, LG_FIRE);
|
|
168
|
+
SprPtr[a] = base[a] + (f & 7);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// The per-frame step. On most frames it is one decrement.
|
|
172
|
+
void step(char a)
|
|
173
|
+
{
|
|
174
|
+
if (held[a])
|
|
175
|
+
return;
|
|
176
|
+
if (--count[a] == 0) {
|
|
177
|
+
pos[a]++;
|
|
178
|
+
enter(a);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// A request: the same animation again is ignored, not restarted; a lower
|
|
183
|
+
// priority than the running one is refused and logged.
|
|
184
|
+
void request(char a, char an)
|
|
185
|
+
{
|
|
186
|
+
if (an == cur[a])
|
|
187
|
+
return;
|
|
188
|
+
if (cur[a] != AN_NONE && anim_prio[an] < anim_prio[cur[a]]) {
|
|
189
|
+
log_ev(a, LG_REFUSED);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
cur[a] = an;
|
|
193
|
+
held[a] = 0;
|
|
194
|
+
pos[a] = anim_first[an];
|
|
195
|
+
enter(a);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Facing picks the other half of the block numbers; the entry is kept.
|
|
199
|
+
void set_face(char a, char left)
|
|
200
|
+
{
|
|
201
|
+
base[a] = left ? SPR_BLK + FACE_L : SPR_BLK;
|
|
202
|
+
if (cur[a] != AN_NONE)
|
|
203
|
+
SprPtr[a] = base[a] + (afrm[pos[a]] & 7);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// --- the script ---------------------------------------------------------
|
|
207
|
+
#define C_FACE_L 0x40
|
|
208
|
+
#define C_FACE_R 0x41
|
|
209
|
+
struct Cmd { char f, a, c; };
|
|
210
|
+
const struct Cmd script[] = {
|
|
211
|
+
{ 0, 0, AN_RISE }, { 0, 1, AN_WALK }, { 0, 1, C_FACE_L },
|
|
212
|
+
{ 0, 2, AN_IDLE }, { 0, 3, AN_IDLE }, { 0, 4, AN_IDLE },
|
|
213
|
+
{ 0, 5, AN_WALK },
|
|
214
|
+
{ 10, 2, AN_ATTACK }, // fires at 18, done at 30
|
|
215
|
+
{ 14, 2, AN_WALK }, // refused: attack outranks walk
|
|
216
|
+
{ 20, 3, AN_ATTACK },
|
|
217
|
+
{ 24, 3, AN_HURT }, // accepted: the fire at 28 never happens
|
|
218
|
+
{ 30, 4, AN_DEATH }, // done at 50, then held
|
|
219
|
+
{ 40, 2, AN_WALK }, // accepted: back to idle at 30
|
|
220
|
+
{ 50, 1, C_FACE_R },
|
|
221
|
+
{ 60, 4, AN_ATTACK }, // refused: dead
|
|
222
|
+
{ 70, 0, AN_RISE }, // ignored: already rising
|
|
223
|
+
{ 80, 5, AN_ATTACK }, // fires at 88, done at 100
|
|
224
|
+
{ 90, 5, AN_ATTACK }, // ignored: same animation
|
|
225
|
+
{ 99, 1, C_FACE_L },
|
|
226
|
+
{ 255, 0, 0 }
|
|
227
|
+
};
|
|
228
|
+
#define END_FRAME 120 // the scenario stops stepping here
|
|
229
|
+
|
|
230
|
+
char sp; // next script entry
|
|
231
|
+
|
|
232
|
+
void run_script(void)
|
|
233
|
+
{
|
|
234
|
+
while (script[sp].f == frame) {
|
|
235
|
+
char a = script[sp].a, c = script[sp].c;
|
|
236
|
+
if (c == C_FACE_L || c == C_FACE_R)
|
|
237
|
+
set_face(a, c == C_FACE_L);
|
|
238
|
+
else
|
|
239
|
+
request(a, c);
|
|
240
|
+
sp++;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// --- the model: walk the tables from the animation's start --------------
|
|
245
|
+
// Different arithmetic from the engine: no countdown, the elapsed time is
|
|
246
|
+
// spent entry by entry. w_* describe the state t frames after the start.
|
|
247
|
+
char w_anim, w_img, w_fire, w_done, w_held;
|
|
248
|
+
|
|
249
|
+
void walk(char an, unsigned t)
|
|
250
|
+
{
|
|
251
|
+
char p = anim_first[an];
|
|
252
|
+
w_done = 0;
|
|
253
|
+
w_held = 0;
|
|
254
|
+
for (;;) {
|
|
255
|
+
char f = afrm[p];
|
|
256
|
+
if (f == END_LOOP) {
|
|
257
|
+
p = anim_first[an] + adur[p];
|
|
258
|
+
} else if (f == END_RETURN) {
|
|
259
|
+
if (t == 0) w_done = 1;
|
|
260
|
+
an = adur[p];
|
|
261
|
+
p = anim_first[an];
|
|
262
|
+
} else if (f == END_HOLD) {
|
|
263
|
+
if (t == 0) w_done = 1;
|
|
264
|
+
w_held = 1;
|
|
265
|
+
p--;
|
|
266
|
+
break;
|
|
267
|
+
} else if (t < adur[p]) {
|
|
268
|
+
break;
|
|
269
|
+
} else {
|
|
270
|
+
t -= adur[p];
|
|
271
|
+
p++;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
w_anim = an;
|
|
275
|
+
w_img = afrm[p] & 7;
|
|
276
|
+
w_fire = !w_held && t == 0 && (afrm[p] & EV_FIRE);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
char ef_n;
|
|
280
|
+
unsigned ef[MAXLOG];
|
|
281
|
+
char ea[MAXLOG], ee[MAXLOG];
|
|
282
|
+
char m_anim[ACTORS], m_base[ACTORS], m_ptr[ACTORS];
|
|
283
|
+
unsigned m_start[ACTORS];
|
|
284
|
+
|
|
285
|
+
void expect(char a, char ev, unsigned f)
|
|
286
|
+
{
|
|
287
|
+
if (ef_n < MAXLOG) {
|
|
288
|
+
ef[ef_n] = f;
|
|
289
|
+
ea[ef_n] = a;
|
|
290
|
+
ee[ef_n] = ev;
|
|
291
|
+
}
|
|
292
|
+
ef_n++;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
void model(void)
|
|
296
|
+
{
|
|
297
|
+
char s = 0;
|
|
298
|
+
for (char a = 0; a < ACTORS; a++) {
|
|
299
|
+
m_anim[a] = AN_NONE;
|
|
300
|
+
m_base[a] = SPR_BLK;
|
|
301
|
+
}
|
|
302
|
+
for (unsigned f = 0; f <= END_FRAME; f++) {
|
|
303
|
+
// Steps first, as the engine does: an animation started at f
|
|
304
|
+
// shows its first entry from f on.
|
|
305
|
+
for (char a = 0; a < ACTORS; a++) {
|
|
306
|
+
if (m_anim[a] == AN_NONE)
|
|
307
|
+
continue;
|
|
308
|
+
walk(m_anim[a], f - m_start[a]);
|
|
309
|
+
if (w_done) expect(a, LG_DONE, f);
|
|
310
|
+
if (w_fire) expect(a, LG_FIRE, f);
|
|
311
|
+
}
|
|
312
|
+
while (script[s].f == f) {
|
|
313
|
+
char a = script[s].a, c = script[s].c;
|
|
314
|
+
s++;
|
|
315
|
+
if (c == C_FACE_L || c == C_FACE_R) {
|
|
316
|
+
m_base[a] = c == C_FACE_L ? SPR_BLK + FACE_L : SPR_BLK;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
char now = AN_NONE;
|
|
320
|
+
if (m_anim[a] != AN_NONE) {
|
|
321
|
+
walk(m_anim[a], f - m_start[a]);
|
|
322
|
+
now = w_anim; // after any return
|
|
323
|
+
}
|
|
324
|
+
if (c == now)
|
|
325
|
+
continue;
|
|
326
|
+
if (now != AN_NONE && anim_prio[c] < anim_prio[now]) {
|
|
327
|
+
expect(a, LG_REFUSED, f);
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
m_anim[a] = c;
|
|
331
|
+
m_start[a] = f;
|
|
332
|
+
walk(c, 0);
|
|
333
|
+
if (w_fire) expect(a, LG_FIRE, f);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
for (char a = 0; a < ACTORS; a++) {
|
|
337
|
+
walk(m_anim[a], END_FRAME - m_start[a]);
|
|
338
|
+
m_ptr[a] = m_base[a] + w_img;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// --- CIA1 timer B ---------------------------------------------------------
|
|
343
|
+
static inline void timer_start(void)
|
|
344
|
+
{
|
|
345
|
+
cia1.crb = 0x00;
|
|
346
|
+
cia1.tb = 0xffff;
|
|
347
|
+
cia1.crb = 0x11;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
static inline unsigned timer_stop(void)
|
|
351
|
+
{
|
|
352
|
+
cia1.crb = 0x00;
|
|
353
|
+
return 0xffff - cia1.tb;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// 100 steps of actor 0 on a given animation, less 100 empty calls.
|
|
357
|
+
__noinline void nothing(char a) { }
|
|
358
|
+
|
|
359
|
+
unsigned time100(void (*fn)(char))
|
|
360
|
+
{
|
|
361
|
+
__asm { sei }
|
|
362
|
+
timer_start();
|
|
363
|
+
for (char n = 0; n < 100; n++)
|
|
364
|
+
fn(0);
|
|
365
|
+
unsigned t = timer_stop();
|
|
366
|
+
__asm { cli }
|
|
367
|
+
return t;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// --- images: frame f is a bar 2f+3 rows tall, right or left half ---------
|
|
371
|
+
void make_images(void)
|
|
372
|
+
{
|
|
373
|
+
for (unsigned i = 0; i < 16 * 64; i++)
|
|
374
|
+
SprData[i] = 0;
|
|
375
|
+
for (char f = 0; f < 8; f++) {
|
|
376
|
+
char *r = SprData + f * 64; // right: pixels 12-23
|
|
377
|
+
char *l = SprData + (f + 8) * 64; // left: pixels 0-11
|
|
378
|
+
for (char y = 0; y < 2 * f + 3; y++) {
|
|
379
|
+
r[y * 3 + 1] = 0x0f;
|
|
380
|
+
r[y * 3 + 2] = 0xff;
|
|
381
|
+
l[y * 3 + 0] = 0xff;
|
|
382
|
+
l[y * 3 + 1] = 0xf0;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// --- text (screen codes) --------------------------------------------------
|
|
388
|
+
void put_str(char *p, const char *s)
|
|
389
|
+
{
|
|
390
|
+
while (*s)
|
|
391
|
+
*p++ = *s++;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
void put_dec(char *p, unsigned v, char digits)
|
|
395
|
+
{
|
|
396
|
+
for (char i = digits; i > 0; i--) {
|
|
397
|
+
p[i - 1] = 0x30 + v % 10;
|
|
398
|
+
v /= 10;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const char hexd[] = s"0123456789abcdef";
|
|
403
|
+
|
|
404
|
+
void put_hex2(char *p, char v)
|
|
405
|
+
{
|
|
406
|
+
p[0] = hexd[v >> 4];
|
|
407
|
+
p[1] = hexd[v & 15];
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const char *const an_name[ANIMS] = {
|
|
411
|
+
s"idle", s"walk", s"attack", s"hurt", s"death", s"rise", s"", s""
|
|
412
|
+
};
|
|
413
|
+
const char *const ev_name[4] = { s"", s"fire", s"done", s"refused" };
|
|
414
|
+
|
|
415
|
+
int main(void)
|
|
416
|
+
{
|
|
417
|
+
for (unsigned i = 0; i < 1000; i++)
|
|
418
|
+
Screen[i] = 0x20;
|
|
419
|
+
vic.color_border = 0;
|
|
420
|
+
vic.color_back = 6;
|
|
421
|
+
make_images();
|
|
422
|
+
model();
|
|
423
|
+
|
|
424
|
+
// Step cost, screen blanked so no badline steals a cycle: the
|
|
425
|
+
// countdown-only path, and the path that moves to the next entry
|
|
426
|
+
// and writes the pointer (an entry of duration 1, looping).
|
|
427
|
+
vic.ctrl1 &= ~VIC_CTRL1_DEN;
|
|
428
|
+
vic_waitFrame();
|
|
429
|
+
unsigned t0 = time100(nothing);
|
|
430
|
+
base[0] = SPR_BLK;
|
|
431
|
+
cur[0] = AN_TSLOW; pos[0] = anim_first[AN_TSLOW]; count[0] = 255; held[0] = 0;
|
|
432
|
+
unsigned c_count = (time100(step) - t0) / 100;
|
|
433
|
+
cur[0] = AN_TFAST; pos[0] = anim_first[AN_TFAST]; count[0] = 1;
|
|
434
|
+
unsigned c_adv = (time100(step) - t0) / 100;
|
|
435
|
+
vic.ctrl1 |= VIC_CTRL1_DEN;
|
|
436
|
+
|
|
437
|
+
for (char a = 0; a < ACTORS; a++) {
|
|
438
|
+
cur[a] = AN_NONE;
|
|
439
|
+
held[a] = 1;
|
|
440
|
+
base[a] = SPR_BLK;
|
|
441
|
+
SprPtr[a] = SPR_BLK;
|
|
442
|
+
vic.spr_pos[a].x = 40 + a * 40;
|
|
443
|
+
vic.spr_pos[a].y = 134;
|
|
444
|
+
vic.spr_color[a] = 7;
|
|
445
|
+
}
|
|
446
|
+
vic.spr_msbx = 0;
|
|
447
|
+
|
|
448
|
+
put_str(Screen + 0, s"sprite animation table frame");
|
|
449
|
+
put_str(Screen + 2 * 40, s"n anim entry ptr model");
|
|
450
|
+
put_str(Screen + 13 * 40, s"events got expected");
|
|
451
|
+
put_str(Screen + 14 * 40, s"step cycles: count advance");
|
|
452
|
+
put_str(Screen + 15 * 40, s"6 actors max at counting");
|
|
453
|
+
put_str(Screen + 16 * 40, s"log: frame actor event");
|
|
454
|
+
|
|
455
|
+
unsigned c_max = 0, c_max_f = 0, c_cnt = 0;
|
|
456
|
+
frame = 0;
|
|
457
|
+
vic_waitFrame();
|
|
458
|
+
vic.spr_enable = (1 << ACTORS) - 1;
|
|
459
|
+
|
|
460
|
+
for (;;) {
|
|
461
|
+
vic_waitFrame();
|
|
462
|
+
if (frame <= END_FRAME) {
|
|
463
|
+
__asm { sei }
|
|
464
|
+
timer_start();
|
|
465
|
+
for (char a = 0; a < ACTORS; a++)
|
|
466
|
+
step(a);
|
|
467
|
+
unsigned t = timer_stop();
|
|
468
|
+
__asm { cli }
|
|
469
|
+
run_script();
|
|
470
|
+
if (t > c_max) {
|
|
471
|
+
c_max = t;
|
|
472
|
+
c_max_f = frame;
|
|
473
|
+
}
|
|
474
|
+
if (frame == 5) // every actor only counts down
|
|
475
|
+
c_cnt = t;
|
|
476
|
+
if (frame == END_FRAME) {
|
|
477
|
+
char fault = 0;
|
|
478
|
+
if (nlog != ef_n) fault = 1;
|
|
479
|
+
for (char i = 0; i < nlog && i < MAXLOG; i++)
|
|
480
|
+
if (lf[i] != ef[i] || la[i] != ea[i] || le[i] != ee[i])
|
|
481
|
+
fault = 1;
|
|
482
|
+
for (char a = 0; a < ACTORS; a++) {
|
|
483
|
+
char *row = Screen + (3 + a) * 40;
|
|
484
|
+
put_dec(row, a, 1);
|
|
485
|
+
put_str(row + 2, an_name[cur[a]]);
|
|
486
|
+
put_dec(row + 10, pos[a] - anim_first[cur[a]], 1);
|
|
487
|
+
put_dec(row + 16, SprPtr[a], 3);
|
|
488
|
+
put_dec(row + 21, m_ptr[a], 3);
|
|
489
|
+
if (SprPtr[a] != m_ptr[a]) fault = 2;
|
|
490
|
+
}
|
|
491
|
+
put_dec(Screen + 13 * 40 + 11, nlog, 2);
|
|
492
|
+
put_dec(Screen + 13 * 40 + 23, ef_n, 2);
|
|
493
|
+
put_dec(Screen + 14 * 40 + 19, c_count, 3);
|
|
494
|
+
put_dec(Screen + 14 * 40 + 31, c_adv, 3);
|
|
495
|
+
put_dec(Screen + 15 * 40 + 13, c_max, 4);
|
|
496
|
+
put_dec(Screen + 15 * 40 + 21, c_max_f, 3);
|
|
497
|
+
put_dec(Screen + 15 * 40 + 34, c_cnt, 4);
|
|
498
|
+
for (char i = 0; i < nlog && i < 8; i++) {
|
|
499
|
+
char *row = Screen + (17 + i) * 40;
|
|
500
|
+
put_dec(row + 5, lf[i], 3);
|
|
501
|
+
put_dec(row + 11, la[i], 1);
|
|
502
|
+
put_str(row + 17, ev_name[le[i]]);
|
|
503
|
+
}
|
|
504
|
+
RESULT = fault ? 2 : 1;
|
|
505
|
+
vic.color_border = fault ? 2 : 5;
|
|
506
|
+
put_str(Screen + 40, fault ? s"result fail" : s"result pass");
|
|
507
|
+
}
|
|
508
|
+
put_dec(Screen + 31, frame, 3);
|
|
509
|
+
frame++;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return 0;
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
## Build
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
oscar64 -tm=c64 -O2 -o=sprite-animation-table.prg sprite-animation-table.c
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Produces `sprite-animation-table.prg`, 3,165 bytes. The sixteen sprite
|
|
523
|
+
images are built at run time at `$3000` to `$33FF`, blocks 192 to 207 of
|
|
524
|
+
VIC bank 0, above the program. Then run headless in VICE (PAL):
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas x64sc -default -warp +sound \
|
|
528
|
+
+autostart-delay-random -autostartprgmode 1 -limitcycles 8000000 \
|
|
529
|
+
-exitscreenshot sprite-animation-table.png -autostart sprite-animation-table.prg
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Add `-model ntsc` for the NTSC picture. The scenario stops stepping at
|
|
533
|
+
frame 120 and the screen holds, so any cycle count past the verdict
|
|
534
|
+
gives the same picture; 8,000,000 is pinned.
|
|
535
|
+
|
|
536
|
+
## Expected output
|
|
537
|
+
|
|
538
|
+
The tables, as the source states them (durations in frames):
|
|
539
|
+
|
|
540
|
+
| Animation | Entries (image, frames) | End | Priority |
|
|
541
|
+
|---|---|---|---|
|
|
542
|
+
| idle | (0, 20) (1, 20) | loop to entry 0 | 0 |
|
|
543
|
+
| walk | (2, 6) (3, 6) (4, 6) (3, 6) | loop to entry 0 | 0 |
|
|
544
|
+
| attack | (5, 4) (6, 4) (7 + fire, 8) (6, 4) | return to idle | 1 |
|
|
545
|
+
| hurt | (1, 3) (0, 3) (1, 3) (0, 3) | return to idle | 2 |
|
|
546
|
+
| death | (4, 5) (5, 5) (6, 5) (7, 5) | hold | 3 |
|
|
547
|
+
| rise | (0, 10) (2, 8) (3, 8) | loop to entry 1 | 0 |
|
|
548
|
+
|
|
549
|
+
Image `f` is a bar 2f + 3 rows tall, in the right half of the sprite
|
|
550
|
+
(pixels 12 to 23) in blocks 192 to 199 and the left half (pixels 0 to 11)
|
|
551
|
+
in blocks 200 to 207, so a screenshot shows which pointer each sprite
|
|
552
|
+
has.
|
|
553
|
+
|
|
554
|
+
Measured in VICE x64sc 3.10 with the pinned command, text decoded
|
|
555
|
+
against the character ROM with PIL (rows 0 to 8 and 13 to 24, PAL):
|
|
556
|
+
|
|
557
|
+
```text
|
|
558
|
+
SPRITE ANIMATION TABLE FRAME 120
|
|
559
|
+
RESULT PASS
|
|
560
|
+
N ANIM ENTRY PTR MODEL
|
|
561
|
+
0 RISE 2 195 195
|
|
562
|
+
1 WALK 0 202 202
|
|
563
|
+
2 WALK 1 195 195
|
|
564
|
+
3 IDLE 0 192 192
|
|
565
|
+
4 DEATH 3 199 199
|
|
566
|
+
5 IDLE 1 193 193
|
|
567
|
+
|
|
568
|
+
EVENTS GOT 08 EXPECTED 08
|
|
569
|
+
STEP CYCLES: COUNT 025 ADVANCE 124
|
|
570
|
+
6 ACTORS MAX 0799 AT 030 COUNTING 0357
|
|
571
|
+
LOG: FRAME ACTOR EVENT
|
|
572
|
+
014 2 REFUSED
|
|
573
|
+
018 2 FIRE
|
|
574
|
+
030 2 DONE
|
|
575
|
+
036 3 DONE
|
|
576
|
+
050 4 DONE
|
|
577
|
+
060 4 REFUSED
|
|
578
|
+
088 5 FIRE
|
|
579
|
+
100 5 DONE
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
NTSC reads the same, every row. The border is palette index 5, (98,
|
|
583
|
+
213, 50) on PAL and (114, 189, 103) on NTSC.
|
|
584
|
+
|
|
585
|
+
What the log says, against the script:
|
|
586
|
+
|
|
587
|
+
- Actor 2's attack starts at 10; its entries last 4 and 4, so the fire
|
|
588
|
+
entry is entered at 18 and the animation ends at 10 + 20 = 30 and
|
|
589
|
+
returns to idle. The walk requested at 14 is refused (priority 0
|
|
590
|
+
under 1); the walk requested at 40 is accepted, because idle runs by
|
|
591
|
+
then.
|
|
592
|
+
- Actor 3's attack starts at 20 and would fire at 28. The hurt at 24
|
|
593
|
+
outranks it (2 over 1), so the attack never fires; the hurt ends at
|
|
594
|
+
24 + 12 = 36.
|
|
595
|
+
- Actor 4 dies at 30, holds from 50 on, and refuses the attack at 60.
|
|
596
|
+
- Actor 5's second attack request at 90 is the running animation, so it
|
|
597
|
+
is ignored: no restart, no log entry. The attack fires at 88 and ends
|
|
598
|
+
at 100. Actor 0's rise request at 70 is ignored the same way.
|
|
599
|
+
- Actor 0's rise shows entry 0 for frames 0 to 9, then loops over
|
|
600
|
+
entries 1 and 2 (16 frames): at 120 it is 110 frames past entry 1's
|
|
601
|
+
first start, 6 loops and 14 frames, so entry 2, image 3.
|
|
602
|
+
- Actor 1 turned right at 50 and left again at 99, keeping its entry;
|
|
603
|
+
its pointer is 202, image 2 plus the facing offset of 8.
|
|
604
|
+
|
|
605
|
+
The sprites, measured with PIL on both pictures: each of the six yellow
|
|
606
|
+
sprites ((255, 255, 70) on PAL, (255, 248, 141) on NTSC) starts on line
|
|
607
|
+
135, one below its Y register of 134. Their heights are 9, 7, 9, 3, 17
|
|
608
|
+
and 5 rows, images 3, 2, 3, 0, 7 and 1; sprite 1's bar covers sprite
|
|
609
|
+
pixels 0 to 11 and the others 12 to 23. That gives pointers 195, 202,
|
|
610
|
+
195, 192, 199 and 193: the values printed, the model's, and the values
|
|
611
|
+
a separate Python model of the tables and script (scratch, not shipped)
|
|
612
|
+
predicts. Each model
|
|
613
|
+
run twice gives byte-identical PNGs:
|
|
614
|
+
`screenshots/sprite-animation-table.png` (PAL) and
|
|
615
|
+
`screenshots/sprite-animation-table-ntsc.png` (NTSC).
|
|
616
|
+
|
|
617
|
+
Cycle figures, CIA1 timer B, interrupts masked, the same on both models.
|
|
618
|
+
`COUNT` and `ADVANCE` are 100 calls of `step` through a function
|
|
619
|
+
pointer, less 100 empty calls, divided by 100, with the screen blanked.
|
|
620
|
+
`COUNT` runs an entry 255 frames long, so every call only decrements.
|
|
621
|
+
`ADVANCE` runs a two-entry loop with durations of 1, so every call moves
|
|
622
|
+
to the next entry, half of them through the loop action, and writes the
|
|
623
|
+
pointer. `MAX` is the worst frame of the scenario for all six actors,
|
|
624
|
+
the loop and calls included: frame 30, when actor 2 returns to idle with
|
|
625
|
+
a log entry and actors 1, 3 and 5 change entry. `COUNTING` is frame 5,
|
|
626
|
+
where every actor only decrements: 357 cycles, about 60 an actor with
|
|
627
|
+
the loop and call. These run straight after `vic_waitFrame()` returns at
|
|
628
|
+
line 256, before the next badline.
|
|
629
|
+
|
|
630
|
+
A negative run, with the engine's countdown loaded one frame too long
|
|
631
|
+
(`count[a] = adur[p] + 1`), prints `RESULT FAIL` with a red border: the
|
|
632
|
+
events move to 20, 34, 40, 54, 90 and 104, and four pointers differ from
|
|
633
|
+
the model's.
|
|
634
|
+
|
|
635
|
+
The program's own check compares the engine with the tables, not the
|
|
636
|
+
tables with intent. With rise's loop target changed from entry 1 to
|
|
637
|
+
entry 0 it still prints `RESULT PASS`, because the model reads the same
|
|
638
|
+
wrong table; sprite 0 then shows image 2 (pointer 194), and the pinned
|
|
639
|
+
PNG comparison is what catches it.
|
|
640
|
+
|
|
641
|
+
## Why this works
|
|
642
|
+
|
|
643
|
+
The animation is data, so the state code never picks a sprite block. It
|
|
644
|
+
asks for an animation; `request` refuses it when the running animation
|
|
645
|
+
has a higher priority, ignores it when it is the running one, and
|
|
646
|
+
otherwise points the actor at entry 0. `enter` resolves end actions
|
|
647
|
+
(loop, return, hold) until it reaches a real entry, loads the countdown,
|
|
648
|
+
fires the entry's event and writes the sprite pointer. `step` is the only
|
|
649
|
+
per-frame work: a decrement, and a call to `enter` when it reaches zero.
|
|
650
|
+
The pointer is written only when the entry changes.
|
|
651
|
+
|
|
652
|
+
Events belong to entries, not to time. The attack fires when its third
|
|
653
|
+
entry is entered, so changing a duration moves the shot with the
|
|
654
|
+
picture, and an animation cut off before that entry never fires. A game
|
|
655
|
+
reads the log (or a flag) after the steps and spawns the bullet there.
|
|
656
|
+
|
|
657
|
+
The check is honest because the model uses different arithmetic: it
|
|
658
|
+
spends the elapsed frames entry by entry from the animation's start, and
|
|
659
|
+
reports an event only when the time runs out exactly on an entry's
|
|
660
|
+
first frame. An off-by-one in the countdown moves every event, as the
|
|
661
|
+
negative run shows.
|
|
662
|
+
|
|
663
|
+
Pointers are block numbers in the VIC bank: `$3000` is block 192 of bank
|
|
664
|
+
0 and the pointers live at screen + `$3F8`. Moving the screen or the
|
|
665
|
+
bank moves both (`vic_bank_visibility_collision` in
|
|
666
|
+
`pitfalls/banking.md`).
|
|
667
|
+
|
|
668
|
+
Verified: compiled with Oscar64, run headless in VICE x64sc 3.10 with the
|
|
669
|
+
pinned command on PAL and NTSC, each twice with byte-identical PNGs; the
|
|
670
|
+
text was decoded against the character ROM and the sprite bars measured
|
|
671
|
+
with PIL, not by eye.
|