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,610 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: slope-collision
|
|
3
|
+
toolchain: oscar64
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [slope_collision]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D000, D001, D010, D011, D015, D018, D020, D021, D027, DC06, DC07, DC0F]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# Oscar64 Slope Collision: 45-degree and 1-in-2 hills and a drop-through platform
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
A sprite walks a character-map terrain under a scripted joystick byte:
|
|
19
|
+
flat ground, a 45-degree hill, a 1-in-2 hill (26.6 degrees) built from
|
|
20
|
+
two-cell halves, and a one-way platform it drops through with down + fire. Each
|
|
21
|
+
map cell is one attribute byte (ground, wall, drop-through, slope type in
|
|
22
|
+
bits 4 to 6), and a 64-byte height table gives the ground row inside a
|
|
23
|
+
cell for each of its eight pixel columns. The slope glyphs are generated
|
|
24
|
+
from the same table, so the picture and the collision cannot disagree.
|
|
25
|
+
Every grounded frame the program logs the foot row per foot column. At
|
|
26
|
+
the end it compares the log with a profile found a second way, by
|
|
27
|
+
scanning each map column from the top, and prints the largest error in
|
|
28
|
+
pixels, the sample counts and the CIA1 timer B cost of the update.
|
|
29
|
+
`$02FF` = `01` and a green border when the error is 0, every event was
|
|
30
|
+
seen and every phase ended at its scripted x; `02` and red otherwise.
|
|
31
|
+
This is the `slope_collision` technique in `docs/techniques/logic.md`;
|
|
32
|
+
the result-byte contract is `headless-verify.md`.
|
|
33
|
+
|
|
34
|
+
## Source
|
|
35
|
+
|
|
36
|
+
```c
|
|
37
|
+
// slope-collision.c
|
|
38
|
+
//
|
|
39
|
+
// Slope collision on a character map. Each map cell holds one attribute
|
|
40
|
+
// byte: ground, wall, drop-through and a slope type in bits 4-6. A
|
|
41
|
+
// height table gives the ground row inside the cell for each of its eight
|
|
42
|
+
// pixel columns. The terrain has flat ground, a 45-degree hill, a
|
|
43
|
+
// 1-in-2 hill built from two-cell halves and a drop-through
|
|
44
|
+
// platform, drawn with glyphs generated from the same table.
|
|
45
|
+
// One sprite walks right, then left, on a scripted joystick byte. It
|
|
46
|
+
// starts on the platform and drops through it with down + fire.
|
|
47
|
+
// Every grounded frame its foot row is logged per foot column; at the end
|
|
48
|
+
// the log is compared with a profile found by scanning each map column
|
|
49
|
+
// from the top, a second use of the tables by a different path.
|
|
50
|
+
// Row 0: foot x and y, slope type, state. Row 1: CIA1 timer B cycles of
|
|
51
|
+
// the update, worst and best frame. Row 2: samples per pass, largest
|
|
52
|
+
// error in pixels, result. $02FF = 01 and a green border on pass,
|
|
53
|
+
// 02 and red on fail.
|
|
54
|
+
// Build: oscar64 -tm=c64 -O2 -o=slope-collision.prg slope-collision.c
|
|
55
|
+
#include <c64/vic.h>
|
|
56
|
+
#include <c64/cia.h>
|
|
57
|
+
#include <c64/sprites.h>
|
|
58
|
+
#include <c64/memmap.h>
|
|
59
|
+
#include <string.h>
|
|
60
|
+
|
|
61
|
+
// Code and data below $3800; the charset copy sits at $3800-$3FFF.
|
|
62
|
+
#pragma region( main, 0x0a00, 0x3800, , , {code, data, bss, heap, stack} )
|
|
63
|
+
|
|
64
|
+
#define SCREEN ((char *)0x0400)
|
|
65
|
+
#define COLOUR ((char *)0xd800)
|
|
66
|
+
#define CHAR_ROM ((char *)0xd000)
|
|
67
|
+
#define FONT ((char *)0x3800) // $D018 = $1E: screen $0400, chars $3800
|
|
68
|
+
#define SPRDATA ((char *)0x0340) // sprite block 13, cassette buffer
|
|
69
|
+
#define RESULT (*(volatile char *)0x02ff)
|
|
70
|
+
|
|
71
|
+
#define CODE_PASS 0x01
|
|
72
|
+
#define CODE_FAIL 0x02
|
|
73
|
+
|
|
74
|
+
// --- the attribute byte ---------------------------------------------------
|
|
75
|
+
#define A_GROUND 0x01 // has a ground surface
|
|
76
|
+
#define A_WALL 0x02 // blocks a sideways move
|
|
77
|
+
#define A_DROP 0x04 // one-way: down + fire falls through
|
|
78
|
+
#define A_SLOPE 0x70 // slope type 0-7, bits 4-6
|
|
79
|
+
#define SLOPE(t) ((t) << 4)
|
|
80
|
+
|
|
81
|
+
// Ground row inside a cell for pixel column 0-7, per slope type. 0 is
|
|
82
|
+
// the cell's top row, 7 its bottom row. Types 3 and 4 are the lower and
|
|
83
|
+
// upper halves of one 1-in-2 rise across two cells; 6 and 5 the
|
|
84
|
+
// same falling. Type 7 is unused.
|
|
85
|
+
const char heights[64] = {
|
|
86
|
+
0, 0, 0, 0, 0, 0, 0, 0, // 0 flat
|
|
87
|
+
7, 6, 5, 4, 3, 2, 1, 0, // 1 up 45, rising to the right
|
|
88
|
+
0, 1, 2, 3, 4, 5, 6, 7, // 2 down 45
|
|
89
|
+
7, 7, 6, 6, 5, 5, 4, 4, // 3 up 1-in-2, lower cell
|
|
90
|
+
3, 3, 2, 2, 1, 1, 0, 0, // 4 up 1-in-2, upper cell
|
|
91
|
+
0, 0, 1, 1, 2, 2, 3, 3, // 5 down 1-in-2, upper cell
|
|
92
|
+
4, 4, 5, 5, 6, 6, 7, 7, // 6 down 1-in-2, lower cell
|
|
93
|
+
0, 0, 0, 0, 0, 0, 0, 0 // 7 unused
|
|
94
|
+
};
|
|
95
|
+
#define HIDX(a, x) ((((a) & A_SLOPE) >> 1) | ((x) & 7))
|
|
96
|
+
|
|
97
|
+
// Screen rows 3-24. '.' air, '#' ground, 'W' wall, '=' drop-through
|
|
98
|
+
// platform, '/' and '\' 45-degree cells, 'a' 'b' a 1-in-2 rise
|
|
99
|
+
// (lower, upper), 'c' 'd' a 1-in-2 fall (upper, lower).
|
|
100
|
+
#define MAP_ROW0 3
|
|
101
|
+
const char map_text[22][41] = {
|
|
102
|
+
"........................................", // 3
|
|
103
|
+
"........................................", // 4
|
|
104
|
+
"........................................", // 5
|
|
105
|
+
"........................................", // 6
|
|
106
|
+
"........................................", // 7
|
|
107
|
+
"WW...................................WWW", // 8
|
|
108
|
+
"WW...................................WWW", // 9
|
|
109
|
+
"WW...................................WWW", // 10
|
|
110
|
+
"WW...................................WWW", // 11
|
|
111
|
+
"WW...................................WWW", // 12
|
|
112
|
+
"WW...................................WWW", // 13
|
|
113
|
+
"WW...................................WWW", // 14
|
|
114
|
+
"WW...................................WWW", // 15
|
|
115
|
+
"WW========...........................WWW", // 16
|
|
116
|
+
"WW...................................WWW", // 17
|
|
117
|
+
"WW............/##\\...................WWW", // 18
|
|
118
|
+
"WW.........../####\\......ab#cd.......WWW", // 19
|
|
119
|
+
"WW........../######\\...ab#####cd.....WWW", // 20
|
|
120
|
+
"WW###################################WWW", // 21
|
|
121
|
+
"WW###################################WWW", // 22
|
|
122
|
+
"WW###################################WWW", // 23
|
|
123
|
+
"WW###################################WWW", // 24
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
char map[25 * 40]; // attribute bytes, screen layout
|
|
127
|
+
char *rowp[25];
|
|
128
|
+
|
|
129
|
+
// Glyphs: codes $80-$87 are the slope types, drawn from the height table;
|
|
130
|
+
// $88 is the wall and $89 the platform.
|
|
131
|
+
#define G_SLOPE 0x80
|
|
132
|
+
#define G_WALL 0x88
|
|
133
|
+
#define G_PLAT 0x89
|
|
134
|
+
|
|
135
|
+
// --- joystick bits (active low) and events ---------------------------------
|
|
136
|
+
#define JOY_UP 0x01
|
|
137
|
+
#define JOY_DOWN 0x02
|
|
138
|
+
#define JOY_LEFT 0x04
|
|
139
|
+
#define JOY_RIGHT 0x08
|
|
140
|
+
#define JOY_FIRE 0x10
|
|
141
|
+
#define JOY_MASK 0x1f
|
|
142
|
+
|
|
143
|
+
#define EV_DROP 0x01
|
|
144
|
+
#define EV_LAND 0x02
|
|
145
|
+
#define EV_WALLR 0x04
|
|
146
|
+
#define EV_WALLL 0x08
|
|
147
|
+
#define EV_ALL 0x0f
|
|
148
|
+
|
|
149
|
+
// --- the script ------------------------------------------------------------
|
|
150
|
+
struct Step { unsigned frames; char port; char pass; int exp_fx; };
|
|
151
|
+
const struct Step script[] = {
|
|
152
|
+
{ 10, 0xff, 0, 24 }, // stand on the platform
|
|
153
|
+
{ 16, 0xff ^ JOY_RIGHT, 0, 40 }, // walk along it
|
|
154
|
+
{ 1, 0xff ^ JOY_DOWN ^ JOY_FIRE, 0, 40 }, // down + fire: drop
|
|
155
|
+
{ 30, 0xff, 0, 40 }, // fall, land on the ground
|
|
156
|
+
{265, 0xff ^ JOY_RIGHT, 0, 293 }, // both hills, to the wall
|
|
157
|
+
{290, 0xff ^ JOY_LEFT, 1, 18 }, // back, under the platform
|
|
158
|
+
{ 20, 0xff, 1, 18 }, // stand; verdict
|
|
159
|
+
};
|
|
160
|
+
#define STEPS (sizeof(script) / sizeof(script[0]))
|
|
161
|
+
|
|
162
|
+
// --- the actor ---------------------------------------------------------------
|
|
163
|
+
// fx is the foot column in world pixels (the sprite's column 12); the
|
|
164
|
+
// foot row fy is the ground row under the feet, one below the sprite's
|
|
165
|
+
// last row. Body: sprite columns 10-14, rows 0-20.
|
|
166
|
+
#define FOOT_COL 12
|
|
167
|
+
#define BODY_HALF 2
|
|
168
|
+
#define BODY_H 21
|
|
169
|
+
#define GRAVITY 0x0040 // 8.8 pixels per frame per frame
|
|
170
|
+
#define MAX_FALL 0x0400 // 4 px a frame, under one cell
|
|
171
|
+
#define MAX_RISE 2 // steeper than this is a wall
|
|
172
|
+
#define MAX_SNAP 2 // deeper than this is a fall
|
|
173
|
+
|
|
174
|
+
int fx;
|
|
175
|
+
unsigned fy_fp; // 8.8
|
|
176
|
+
unsigned vy; // 8.8, down only
|
|
177
|
+
bool grounded;
|
|
178
|
+
char ground_attr; // attribute of the cell stood on
|
|
179
|
+
char events;
|
|
180
|
+
char state; // 0 stand, 1 walk, 2 fall, 3 wall
|
|
181
|
+
|
|
182
|
+
char logy[2][320]; // foot row per foot column, per pass
|
|
183
|
+
int drop_x;
|
|
184
|
+
|
|
185
|
+
// Ground row for foot column x, starting from the cell that holds the
|
|
186
|
+
// feet now (fy). One cell up if the cell above is also ground (walking
|
|
187
|
+
// up into the next slope cell), one cell down if the feet are in air
|
|
188
|
+
// (walking down). 0xff: no ground within a cell.
|
|
189
|
+
char surface_walk(int x, char fy)
|
|
190
|
+
{
|
|
191
|
+
char col = x >> 3, row = fy >> 3;
|
|
192
|
+
char a = rowp[row][col];
|
|
193
|
+
if (a & A_GROUND) {
|
|
194
|
+
char b = rowp[row - 1][col];
|
|
195
|
+
if (b & A_GROUND) {
|
|
196
|
+
a = b;
|
|
197
|
+
row--;
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
row++;
|
|
201
|
+
a = rowp[row][col];
|
|
202
|
+
if (!(a & A_GROUND))
|
|
203
|
+
return 0xff;
|
|
204
|
+
}
|
|
205
|
+
ground_attr = a;
|
|
206
|
+
return (row << 3) + heights[HIDX(a, x)];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// One frame. cur is the port byte, newp the lines that went low this frame.
|
|
210
|
+
void actor_update(char cur, char newp)
|
|
211
|
+
{
|
|
212
|
+
char fy = fy_fp >> 8;
|
|
213
|
+
|
|
214
|
+
if (grounded) {
|
|
215
|
+
// Drop-through: only from a one-way cell. Start one row below its
|
|
216
|
+
// surface so the landing test cannot catch it again.
|
|
217
|
+
if (!(cur & JOY_DOWN) && (newp & JOY_FIRE) && (ground_attr & A_DROP)) {
|
|
218
|
+
fy_fp += 0x100;
|
|
219
|
+
vy = 0;
|
|
220
|
+
grounded = false;
|
|
221
|
+
drop_x = fx;
|
|
222
|
+
events |= EV_DROP;
|
|
223
|
+
state = 2;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
state = 0;
|
|
227
|
+
signed char dx = 0;
|
|
228
|
+
if (!(cur & JOY_RIGHT)) dx = 1;
|
|
229
|
+
else if (!(cur & JOY_LEFT)) dx = -1;
|
|
230
|
+
if (!dx)
|
|
231
|
+
return;
|
|
232
|
+
int nx = fx + dx;
|
|
233
|
+
int edge = dx > 0 ? nx + BODY_HALF : nx - BODY_HALF;
|
|
234
|
+
char probe = rowp[(fy - 11) >> 3][edge >> 3];
|
|
235
|
+
char s = 0xff;
|
|
236
|
+
if (!(probe & A_WALL))
|
|
237
|
+
s = surface_walk(nx, fy);
|
|
238
|
+
if (probe & A_WALL || (s != 0xff && s < fy && fy - s > MAX_RISE)) {
|
|
239
|
+
events |= dx > 0 ? EV_WALLR : EV_WALLL;
|
|
240
|
+
state = 3;
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
fx = nx;
|
|
244
|
+
state = 1;
|
|
245
|
+
if (s != 0xff && (s <= fy || s - fy <= MAX_SNAP)) {
|
|
246
|
+
fy_fp = (unsigned)s << 8; // ground snap, up or down
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
grounded = false; // off an edge: fall from here
|
|
250
|
+
vy = 0;
|
|
251
|
+
state = 2;
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Airborne: fall, then look for a surface crossed on the way down, in
|
|
256
|
+
// the cell the feet left and the cell they reached.
|
|
257
|
+
vy += GRAVITY;
|
|
258
|
+
if (vy > MAX_FALL) vy = MAX_FALL;
|
|
259
|
+
fy_fp += vy;
|
|
260
|
+
char ny = fy_fp >> 8;
|
|
261
|
+
char col = fx >> 3;
|
|
262
|
+
for (char row = fy >> 3; row <= (ny >> 3); row++) {
|
|
263
|
+
char a = rowp[row][col];
|
|
264
|
+
if (a & A_GROUND) {
|
|
265
|
+
char s = (row << 3) + heights[HIDX(a, fx)];
|
|
266
|
+
if (s >= fy && s <= ny) {
|
|
267
|
+
fy_fp = (unsigned)s << 8;
|
|
268
|
+
vy = 0;
|
|
269
|
+
grounded = true;
|
|
270
|
+
ground_attr = a;
|
|
271
|
+
events |= EV_LAND;
|
|
272
|
+
state = 0;
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
state = 2;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Reference profile: scan the column from the top for the first ground
|
|
281
|
+
// cell that is not one-way, and read the table there.
|
|
282
|
+
char terrain(int x)
|
|
283
|
+
{
|
|
284
|
+
char col = x >> 3;
|
|
285
|
+
for (char row = MAP_ROW0; row < 25; row++) {
|
|
286
|
+
char a = rowp[row][col];
|
|
287
|
+
if ((a & A_GROUND) && !(a & A_DROP))
|
|
288
|
+
return (row << 3) + heights[HIDX(a, x)];
|
|
289
|
+
}
|
|
290
|
+
return 0xff;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// --- CIA1 timer B harness ---------------------------------------------------
|
|
294
|
+
static inline void timer_start(void)
|
|
295
|
+
{
|
|
296
|
+
cia1.crb = 0x00;
|
|
297
|
+
cia1.tb = 0xffff;
|
|
298
|
+
cia1.crb = 0x11;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static inline unsigned timer_stop(void)
|
|
302
|
+
{
|
|
303
|
+
cia1.crb = 0x00;
|
|
304
|
+
return 0xffff - cia1.tb;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// --- text helpers (screen codes) ---------------------------------------------
|
|
308
|
+
void put_str(char *p, const char *s)
|
|
309
|
+
{
|
|
310
|
+
while (*s)
|
|
311
|
+
*p++ = *s++;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
void put_dec(char *p, unsigned v, char digits)
|
|
315
|
+
{
|
|
316
|
+
for (char i = digits; i > 0; i--) {
|
|
317
|
+
p[i - 1] = 0x30 + v % 10;
|
|
318
|
+
v /= 10;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const char *state_name[4] = { s"stand", s"walk ", s"fall ", s"wall " };
|
|
323
|
+
|
|
324
|
+
int main(void)
|
|
325
|
+
{
|
|
326
|
+
__asm { sei }
|
|
327
|
+
mmap_set(MMAP_CHAR_ROM);
|
|
328
|
+
memcpy(FONT, CHAR_ROM, 2048);
|
|
329
|
+
mmap_set(MMAP_ROM);
|
|
330
|
+
|
|
331
|
+
// Slope glyphs from the height table: a pixel is set when its row is
|
|
332
|
+
// at or below the ground row of its column.
|
|
333
|
+
for (char t = 0; t < 8; t++) {
|
|
334
|
+
char *g = FONT + (G_SLOPE + t) * 8;
|
|
335
|
+
for (char r = 0; r < 8; r++) {
|
|
336
|
+
char bits = 0;
|
|
337
|
+
for (char x = 0; x < 8; x++)
|
|
338
|
+
if (r >= heights[t * 8 + x])
|
|
339
|
+
bits |= 0x80 >> x;
|
|
340
|
+
g[r] = bits;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
static const char wall[8] = { 0xff, 0x81, 0x81, 0xff, 0xff, 0x18, 0x18, 0xff };
|
|
344
|
+
for (char r = 0; r < 8; r++) {
|
|
345
|
+
FONT[G_WALL * 8 + r] = wall[r];
|
|
346
|
+
FONT[G_PLAT * 8 + r] = r < 3 ? 0xff : 0x00;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
vic.color_border = 0;
|
|
350
|
+
vic.color_back = 0;
|
|
351
|
+
vic.memptr = 0x1e;
|
|
352
|
+
memset(SCREEN, 0x20, 1000);
|
|
353
|
+
memset(COLOUR, VCOL_WHITE, 1000);
|
|
354
|
+
memset(map, 0, sizeof(map));
|
|
355
|
+
for (char r = 0; r < 25; r++)
|
|
356
|
+
rowp[r] = map + r * 40;
|
|
357
|
+
|
|
358
|
+
for (char y = 0; y < 22; y++) {
|
|
359
|
+
char row = MAP_ROW0 + y;
|
|
360
|
+
for (char x = 0; x < 40; x++) {
|
|
361
|
+
char c = map_text[y][x], a = 0, g = 0x20, k = VCOL_GREEN;
|
|
362
|
+
switch (c) {
|
|
363
|
+
case '#': a = A_GROUND; break;
|
|
364
|
+
case 'W': a = A_GROUND | A_WALL; g = G_WALL; k = VCOL_LT_GREY; break;
|
|
365
|
+
case '=': a = A_GROUND | A_DROP; g = G_PLAT; k = VCOL_YELLOW; break;
|
|
366
|
+
case '/': a = A_GROUND | SLOPE(1); break;
|
|
367
|
+
case '\\': a = A_GROUND | SLOPE(2); break;
|
|
368
|
+
case 'a': a = A_GROUND | SLOPE(3); break;
|
|
369
|
+
case 'b': a = A_GROUND | SLOPE(4); break;
|
|
370
|
+
case 'c': a = A_GROUND | SLOPE(5); break;
|
|
371
|
+
case 'd': a = A_GROUND | SLOPE(6); break;
|
|
372
|
+
}
|
|
373
|
+
if (a && g == 0x20)
|
|
374
|
+
g = G_SLOPE + ((a & A_SLOPE) >> 4);
|
|
375
|
+
rowp[row][x] = a;
|
|
376
|
+
SCREEN[row * 40 + x] = g;
|
|
377
|
+
COLOUR[row * 40 + x] = k;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Sprite 0: a bar 5 px wide (columns 10-14) and 21 tall.
|
|
382
|
+
for (char i = 0; i < 63; i++)
|
|
383
|
+
SPRDATA[i] = (i % 3 == 1) ? 0x3e : 0x00;
|
|
384
|
+
memset(logy, 0xff, sizeof(logy));
|
|
385
|
+
fx = 24;
|
|
386
|
+
fy_fp = (unsigned)(16 * 8) << 8; // on the platform
|
|
387
|
+
grounded = true;
|
|
388
|
+
ground_attr = A_GROUND | A_DROP;
|
|
389
|
+
spr_init(SCREEN);
|
|
390
|
+
spr_set(0, true, fx - FOOT_COL + 24, (fy_fp >> 8) - BODY_H + 50, 13, VCOL_WHITE, false, false, false);
|
|
391
|
+
|
|
392
|
+
put_str(SCREEN, s"x");
|
|
393
|
+
put_str(SCREEN + 6, s"y");
|
|
394
|
+
put_str(SCREEN + 12, s"slope");
|
|
395
|
+
put_str(SCREEN + 20, s"state");
|
|
396
|
+
put_str(SCREEN + 33, s"f");
|
|
397
|
+
put_str(SCREEN + 40, s"update max min");
|
|
398
|
+
put_str(SCREEN + 80, s"samples err result");
|
|
399
|
+
|
|
400
|
+
char prev = 0xff, step = 0, fault = 0;
|
|
401
|
+
unsigned left = script[0].frames, t_max = 0, t_min = 0xffff, frame = 0;
|
|
402
|
+
bool done = false;
|
|
403
|
+
|
|
404
|
+
for (;;) {
|
|
405
|
+
vic_waitFrame();
|
|
406
|
+
|
|
407
|
+
char cur = done ? 0xff : script[step].port;
|
|
408
|
+
char newp = (cur ^ prev) & prev & JOY_MASK; // low now, high last frame
|
|
409
|
+
prev = cur;
|
|
410
|
+
|
|
411
|
+
timer_start();
|
|
412
|
+
actor_update(cur, newp);
|
|
413
|
+
unsigned t = timer_stop();
|
|
414
|
+
if (t > t_max) t_max = t;
|
|
415
|
+
if (t < t_min) t_min = t;
|
|
416
|
+
|
|
417
|
+
char fy = fy_fp >> 8;
|
|
418
|
+
if (grounded && !done)
|
|
419
|
+
logy[script[step].pass][fx] = fy;
|
|
420
|
+
spr_move(0, fx - FOOT_COL + 24, fy - BODY_H + 50);
|
|
421
|
+
|
|
422
|
+
put_dec(SCREEN + 2, fx, 3);
|
|
423
|
+
put_dec(SCREEN + 8, fy, 3);
|
|
424
|
+
SCREEN[18] = grounded ? 0x30 + ((ground_attr & A_SLOPE) >> 4) : 0x2d;
|
|
425
|
+
put_str(SCREEN + 26, state_name[state]);
|
|
426
|
+
put_dec(SCREEN + 35, frame, 5);
|
|
427
|
+
frame++;
|
|
428
|
+
put_dec(SCREEN + 40 + 11, t_max, 5);
|
|
429
|
+
put_dec(SCREEN + 40 + 21, t_min, 5);
|
|
430
|
+
|
|
431
|
+
if (!done && --left == 0) {
|
|
432
|
+
if (script[step].exp_fx != fx && !fault)
|
|
433
|
+
fault = 1;
|
|
434
|
+
step++;
|
|
435
|
+
if (step < STEPS) {
|
|
436
|
+
left = script[step].frames;
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
done = true;
|
|
440
|
+
|
|
441
|
+
// Compare the log with the reference profile.
|
|
442
|
+
unsigned n0 = 0, n1 = 0;
|
|
443
|
+
char maxerr = 0;
|
|
444
|
+
for (int x = 0; x < 320; x++) {
|
|
445
|
+
for (char p = 0; p < 2; p++) {
|
|
446
|
+
char y = logy[p][x];
|
|
447
|
+
if (y == 0xff)
|
|
448
|
+
continue;
|
|
449
|
+
char e = (p == 0 && x < drop_x) ? 16 * 8 : terrain(x);
|
|
450
|
+
char d = y > e ? y - e : e - y;
|
|
451
|
+
if (d > maxerr) maxerr = d;
|
|
452
|
+
if (p) n1++; else n0++;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (maxerr && !fault) fault = 2;
|
|
456
|
+
if (events != EV_ALL && !fault) fault = 3;
|
|
457
|
+
if ((n0 != 270 || n1 != 275) && !fault) fault = 4;
|
|
458
|
+
|
|
459
|
+
put_dec(SCREEN + 80 + 8, n0, 3);
|
|
460
|
+
put_dec(SCREEN + 80 + 12, n1, 3);
|
|
461
|
+
put_dec(SCREEN + 80 + 20, maxerr, 3);
|
|
462
|
+
char code = fault ? CODE_FAIL : CODE_PASS;
|
|
463
|
+
RESULT = code;
|
|
464
|
+
vic.color_border = fault ? VCOL_RED : VCOL_GREEN;
|
|
465
|
+
SCREEN[80 + 31] = 0x30;
|
|
466
|
+
SCREEN[80 + 32] = 0x30 + code;
|
|
467
|
+
SCREEN[80 + 34] = 0x30 + fault;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return 0;
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## Build
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
oscar64 -tm=c64 -O2 -o=slope-collision.prg slope-collision.c
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Produces `slope-collision.prg`, 4,299 bytes (Oscar64 build 2026-05-19).
|
|
481
|
+
The `#pragma region` line keeps code and data below $3800, where the
|
|
482
|
+
program copies the character ROM and writes its glyphs; without it
|
|
483
|
+
nothing stops the code growing into the charset
|
|
484
|
+
(`charset_blit_overruns_grown_code`). The copy runs with `$01` = `$31`,
|
|
485
|
+
because the CPU sees the character ROM only while I/O is switched out
|
|
486
|
+
(`charset_under_io_invisible_to_cpu`). Then run headless in VICE (PAL):
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas x64sc -default -warp +sound \
|
|
490
|
+
+autostart-delay-random -autostartprgmode 1 -limitcycles 20000000 \
|
|
491
|
+
-exitscreenshot slope-collision.png -autostart slope-collision.prg
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Add `-model ntsc` for the NTSC picture. The script takes 632 frames; at
|
|
495
|
+
20,000,000 cycles the verdict is on screen on both models (frame counter
|
|
496
|
+
823 on PAL, 940 on NTSC).
|
|
497
|
+
|
|
498
|
+
## Expected output
|
|
499
|
+
|
|
500
|
+
Black background. Rows 0 to 2 are the HUD. Below them: a light grey
|
|
501
|
+
brick wall at columns 0 to 1 and 37 to 39 from row 8 down, a yellow
|
|
502
|
+
plank (the drop-through platform) on row 16 at columns 2 to 9, green
|
|
503
|
+
ground on rows 21 to 24, a green 45-degree hill on columns 12 to 19
|
|
504
|
+
(three cells up, a two-cell top, three cells down, top surface on row
|
|
505
|
+
18), and a green 1-in-2 hill on columns 23 to 31 (two two-cell
|
|
506
|
+
rises, a one-cell top on row 19, two two-cell falls). The sprite is a
|
|
507
|
+
white bar 5 pixels wide and 21 tall; its foot column is its middle.
|
|
508
|
+
|
|
509
|
+
The script, frame by frame:
|
|
510
|
+
|
|
511
|
+
| Frames | Port | What happens | Event |
|
|
512
|
+
|---|---|---|---|
|
|
513
|
+
| 0 to 9 | none | stands on the platform at foot x 24, foot row 128 | |
|
|
514
|
+
| 10 to 25 | right | walks along the platform to x 40 | |
|
|
515
|
+
| 26 | down + fire | drops through the platform | DROP |
|
|
516
|
+
| 27 to 56 | none | falls and lands on the ground, foot row 168 | LAND |
|
|
517
|
+
| 57 to 321 | right | over the 45-degree hill and the 1-in-2 hill; stopped by the right wall at x 293 for the last 12 frames | WALL R |
|
|
518
|
+
| 322 to 611 | left | back over both hills and under the platform; stopped by the left wall at x 18 for the last 15 frames | WALL L |
|
|
519
|
+
| 612 to 631 | none | stands; the verdict is posted | |
|
|
520
|
+
|
|
521
|
+
The verdict on both models (measured in VICE x64sc 3.10 at 20,000,000
|
|
522
|
+
cycles, HUD decoded against the character ROM): row 0 reads
|
|
523
|
+
`X 018 Y 168 SLOPE 0 STATE STAND F 00823` on PAL (`F 00940` on NTSC), row 1 `UPDATE MAX 00455 MIN 00087`,
|
|
524
|
+
row 2 `SAMPLES 270 275 ERR 000 RESULT 01 0`, and the border is palette
|
|
525
|
+
index 5, (98, 213, 50) on PAL and (114, 189, 103) on NTSC. The pass
|
|
526
|
+
covers foot x 24 to 293 going right (270 samples, 16 of them on the
|
|
527
|
+
platform) and 18 to 292 going left (275), and every sample matches the
|
|
528
|
+
reference profile exactly.
|
|
529
|
+
|
|
530
|
+
Screenshots at 20,000,000 cycles, both after the verdict:
|
|
531
|
+
`screenshots/slope-collision.png` (PAL) and
|
|
532
|
+
`screenshots/slope-collision-ntsc.png` (NTSC). Measured on the PNGs with
|
|
533
|
+
PIL, identically on both: the sprite is 105 white pixels, a 5 x 21 block
|
|
534
|
+
at world x 16 to 20 and y 147 to 167, so the foot column is 18 and its
|
|
535
|
+
bottom row is 167; the first pixel below it in that column is at y 168,
|
|
536
|
+
green, the flat ground on row 21. Text row 0 starts at PNG row 35 on PAL
|
|
537
|
+
and 23 on NTSC, which fixes world y 0. Scanning each column x 16 to 295
|
|
538
|
+
of both PNGs for the first green pixel reproduces the reference profile
|
|
539
|
+
in all 275 columns the sprite does not cover.
|
|
540
|
+
|
|
541
|
+
The two cycle figures are what `actor_update` costs for one actor: the
|
|
542
|
+
timer starts before the call and stops after it, with interrupts masked
|
|
543
|
+
for the whole program. The update runs just after `vic_waitFrame()`
|
|
544
|
+
returns at raster line 256, inside the vertical blank, so no badline
|
|
545
|
+
falls in it and the figures agree on the two models. A build that timed
|
|
546
|
+
each state separately (not the listing) put the worst frames at 455
|
|
547
|
+
cycles walking, 370 landing, 329 falling and 250 against a wall; standing
|
|
548
|
+
still costs 87.
|
|
549
|
+
|
|
550
|
+
## Why this works
|
|
551
|
+
|
|
552
|
+
The attribute byte is the whole collision model. Bit 0 says the cell
|
|
553
|
+
has a ground surface, bit 1 that it stops a sideways move, bit 2 that it
|
|
554
|
+
is one-way, and bits 4 to 6 pick a row of the height table. `(a & $70)
|
|
555
|
+
>> 1` is the slope type times 8, so `| (x & 7)` indexes the table with
|
|
556
|
+
no multiply. The filled cells under a hill are flat ground (type 0, full
|
|
557
|
+
glyph); only the surface cells carry a slope type.
|
|
558
|
+
|
|
559
|
+
The foot is one point, the middle column of the body, and the foot row
|
|
560
|
+
`fy` is the ground row under it, one below the sprite's last row. A
|
|
561
|
+
walking step looks only at the cell that holds `fy` and one neighbour.
|
|
562
|
+
If that cell is ground and the cell above is ground too, the feet have
|
|
563
|
+
walked into the fill under the next slope cell, so the surface is in the
|
|
564
|
+
cell above. If the cell is air, the feet have walked off the end of a
|
|
565
|
+
slope cell and the surface, if any, is in the cell below. The result is
|
|
566
|
+
the new foot row; the actor is put on it every step (ground snap), so
|
|
567
|
+
walking down a slope never leaves it floating. A rise of more than 2
|
|
568
|
+
pixels in one step is refused as a wall; a drop of more than 2 pixels
|
|
569
|
+
starts a fall. At 1 pixel a frame the steepest slope here, 45 degrees,
|
|
570
|
+
changes the foot row by 1, so neither limit trips on the hills. By the
|
|
571
|
+
same rule the 8-pixel step at the foot of a wall is refused even
|
|
572
|
+
without its wall bit (rung 3, read from the code, not run).
|
|
573
|
+
|
|
574
|
+
The 1-in-2 hill (8 pixels of rise over 16, 26.6 degrees) needs two
|
|
575
|
+
cell types per step of height: the lower cell's ground runs from row 7
|
|
576
|
+
to row 4, the upper cell's from 3 to 0, in steps of 1 every 2 pixels, so
|
|
577
|
+
a rise of 4 pixels per cell continues across the cell boundary without a
|
|
578
|
+
jump. Slope to flat and flat to slope
|
|
579
|
+
need no code: a 45-degree cell ends at row 0 or row 7, and the next cell
|
|
580
|
+
along, at the same height or one row up or down, starts one pixel away.
|
|
581
|
+
|
|
582
|
+
A fall looks at the cell the feet left and the cell they reached, and
|
|
583
|
+
lands on a surface that lies between the old and new foot rows. The
|
|
584
|
+
platform is one-way because a drop moves the feet one row below its
|
|
585
|
+
surface before the fall starts, so the platform's ground row is above
|
|
586
|
+
the old foot row on the first falling frame and is never caught; walking
|
|
587
|
+
under it later, the actor never tests it at all, because the foot cell
|
|
588
|
+
is on the ground below. That holds only while the platform is at least
|
|
589
|
+
two cells above the ground cell: `surface_walk` also reads the cell
|
|
590
|
+
directly above the foot cell, so a one-way cell there would be taken as
|
|
591
|
+
the next surface, a rise of 8 pixels, and refused as a wall (rung 3,
|
|
592
|
+
read from the code, not run). The recipe's platform is on row 16, five
|
|
593
|
+
cells above the ground on row 21. The fall speed is capped at 4 pixels a frame,
|
|
594
|
+
under a cell, so two cells are always enough.
|
|
595
|
+
|
|
596
|
+
The reference profile is built a different way: scan the column from
|
|
597
|
+
row 3 down to the first ground cell that is not one-way and read its
|
|
598
|
+
table entry. It shares the table with the walker but not the
|
|
599
|
+
neighbour rules, so a wrong rule shows as an error. Three edits of the
|
|
600
|
+
listing were run to prove the check can fail: without the cell-above
|
|
601
|
+
rule the largest error is 24 pixels; with the snap limit at 0 the
|
|
602
|
+
phases end at the wrong x (x 59 at the end, not 18); without the
|
|
603
|
+
one-row offset on the drop the error is 40 pixels, the platform's
|
|
604
|
+
height above the ground. Each posted `02`.
|
|
605
|
+
|
|
606
|
+
Verified: compiled with Oscar64 (build 2026-05-19), run headless in VICE
|
|
607
|
+
x64sc 3.10 with the pinned command on PAL and NTSC, each pinned run
|
|
608
|
+
twice with byte-identical PNGs; the HUD was decoded against the
|
|
609
|
+
character ROM and the sprite and the ground located by pixel colour with
|
|
610
|
+
PIL, not by eye.
|