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.
Files changed (970) hide show
  1. package/CHANGELOG.md +2082 -0
  2. package/LICENSE +29 -0
  3. package/README.md +559 -0
  4. package/VERSION +25 -0
  5. package/dist/cli/setup.js +66 -0
  6. package/dist/cli/setup.js.map +1 -0
  7. package/dist/cli-memorize-audit.js +97 -0
  8. package/dist/cli-memorize-audit.js.map +1 -0
  9. package/dist/cli.js +335 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.js +83 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/context.js +53 -0
  14. package/dist/context.js.map +1 -0
  15. package/dist/domain/budget-notes.js +104 -0
  16. package/dist/domain/budget-notes.js.map +1 -0
  17. package/dist/domain/budget.js +417 -0
  18. package/dist/domain/budget.js.map +1 -0
  19. package/dist/domain/game-design.js +77 -0
  20. package/dist/domain/game-design.js.map +1 -0
  21. package/dist/domain/timing.js +39 -0
  22. package/dist/domain/timing.js.map +1 -0
  23. package/dist/graph/apply.js +132 -0
  24. package/dist/graph/apply.js.map +1 -0
  25. package/dist/graph/claims.js +231 -0
  26. package/dist/graph/claims.js.map +1 -0
  27. package/dist/graph/extract/archetype.js +118 -0
  28. package/dist/graph/extract/archetype.js.map +1 -0
  29. package/dist/graph/extract/common.js +69 -0
  30. package/dist/graph/extract/common.js.map +1 -0
  31. package/dist/graph/extract/failure.js +37 -0
  32. package/dist/graph/extract/failure.js.map +1 -0
  33. package/dist/graph/extract/game-design.js +189 -0
  34. package/dist/graph/extract/game-design.js.map +1 -0
  35. package/dist/graph/extract/hardware.js +124 -0
  36. package/dist/graph/extract/hardware.js.map +1 -0
  37. package/dist/graph/extract/pitfall.js +62 -0
  38. package/dist/graph/extract/pitfall.js.map +1 -0
  39. package/dist/graph/extract/raster-band.js +56 -0
  40. package/dist/graph/extract/raster-band.js.map +1 -0
  41. package/dist/graph/extract/recipe.js +71 -0
  42. package/dist/graph/extract/recipe.js.map +1 -0
  43. package/dist/graph/extract/technique-entities.js +180 -0
  44. package/dist/graph/extract/technique-entities.js.map +1 -0
  45. package/dist/graph/extract/technique.js +179 -0
  46. package/dist/graph/extract/technique.js.map +1 -0
  47. package/dist/graph/extract/toolchain.js +67 -0
  48. package/dist/graph/extract/toolchain.js.map +1 -0
  49. package/dist/graph/extract/types.js +3 -0
  50. package/dist/graph/extract/types.js.map +1 -0
  51. package/dist/graph/extract/vocabulary.js +65 -0
  52. package/dist/graph/extract/vocabulary.js.map +1 -0
  53. package/dist/graph/extract.js +43 -0
  54. package/dist/graph/extract.js.map +1 -0
  55. package/dist/graph/kernal-clobbers.js +64 -0
  56. package/dist/graph/kernal-clobbers.js.map +1 -0
  57. package/dist/graph/machine-variants.js +208 -0
  58. package/dist/graph/machine-variants.js.map +1 -0
  59. package/dist/ingest/files.js +99 -0
  60. package/dist/ingest/files.js.map +1 -0
  61. package/dist/ingest/passes.js +104 -0
  62. package/dist/ingest/passes.js.map +1 -0
  63. package/dist/ingest/points.js +50 -0
  64. package/dist/ingest/points.js.map +1 -0
  65. package/dist/ingest/report.js +140 -0
  66. package/dist/ingest/report.js.map +1 -0
  67. package/dist/ingest/tally.js +81 -0
  68. package/dist/ingest/tally.js.map +1 -0
  69. package/dist/ingest/verified-on.js +43 -0
  70. package/dist/ingest/verified-on.js.map +1 -0
  71. package/dist/ingest.js +135 -0
  72. package/dist/ingest.js.map +1 -0
  73. package/dist/schemas/cost-basis.js +5 -0
  74. package/dist/schemas/cost-basis.js.map +1 -0
  75. package/dist/schemas/machine-variant.js +25 -0
  76. package/dist/schemas/machine-variant.js.map +1 -0
  77. package/dist/schemas/plan-budget.js +121 -0
  78. package/dist/schemas/plan-budget.js.map +1 -0
  79. package/dist/schemas/tool-outputs.js +526 -0
  80. package/dist/schemas/tool-outputs.js.map +1 -0
  81. package/dist/server/define-tool.js +52 -0
  82. package/dist/server/define-tool.js.map +1 -0
  83. package/dist/server/defined-only.js +9 -0
  84. package/dist/server/defined-only.js.map +1 -0
  85. package/dist/server/tools-briefings.js +70 -0
  86. package/dist/server/tools-briefings.js.map +1 -0
  87. package/dist/server/tools-lookup.js +180 -0
  88. package/dist/server/tools-lookup.js.map +1 -0
  89. package/dist/server/tools-maintenance.js +116 -0
  90. package/dist/server/tools-maintenance.js.map +1 -0
  91. package/dist/server/tools-pitfalls.js +89 -0
  92. package/dist/server/tools-pitfalls.js.map +1 -0
  93. package/dist/server/tools-recipes.js +296 -0
  94. package/dist/server/tools-recipes.js.map +1 -0
  95. package/dist/server/tools-runtime.js +48 -0
  96. package/dist/server/tools-runtime.js.map +1 -0
  97. package/dist/server/tools.js +43 -0
  98. package/dist/server/tools.js.map +1 -0
  99. package/dist/server.js +95 -0
  100. package/dist/server.js.map +1 -0
  101. package/dist/services/analytics/schema.js +78 -0
  102. package/dist/services/analytics/schema.js.map +1 -0
  103. package/dist/services/analytics/statements.js +99 -0
  104. package/dist/services/analytics/statements.js.map +1 -0
  105. package/dist/services/analytics.js +195 -0
  106. package/dist/services/analytics.js.map +1 -0
  107. package/dist/services/bm25.js +158 -0
  108. package/dist/services/bm25.js.map +1 -0
  109. package/dist/services/chunker.js +81 -0
  110. package/dist/services/chunker.js.map +1 -0
  111. package/dist/services/embeddings.js +58 -0
  112. package/dist/services/embeddings.js.map +1 -0
  113. package/dist/services/falkor/base.js +85 -0
  114. package/dist/services/falkor/base.js.map +1 -0
  115. package/dist/services/falkor/links.js +361 -0
  116. package/dist/services/falkor/links.js.map +1 -0
  117. package/dist/services/falkor/nodes.js +183 -0
  118. package/dist/services/falkor/nodes.js.map +1 -0
  119. package/dist/services/falkor/params.js +45 -0
  120. package/dist/services/falkor/params.js.map +1 -0
  121. package/dist/services/falkor/schema.js +77 -0
  122. package/dist/services/falkor/schema.js.map +1 -0
  123. package/dist/services/falkor.js +100 -0
  124. package/dist/services/falkor.js.map +1 -0
  125. package/dist/services/qdrant.js +238 -0
  126. package/dist/services/qdrant.js.map +1 -0
  127. package/dist/services/versions.js +73 -0
  128. package/dist/services/versions.js.map +1 -0
  129. package/dist/services/vice-bin.js +51 -0
  130. package/dist/services/vice-bin.js.map +1 -0
  131. package/dist/tools/briefings/archetype.js +174 -0
  132. package/dist/tools/briefings/archetype.js.map +1 -0
  133. package/dist/tools/briefings/budget.js +177 -0
  134. package/dist/tools/briefings/budget.js.map +1 -0
  135. package/dist/tools/briefings/build-order.js +135 -0
  136. package/dist/tools/briefings/build-order.js.map +1 -0
  137. package/dist/tools/briefings/build.js +185 -0
  138. package/dist/tools/briefings/build.js.map +1 -0
  139. package/dist/tools/briefings/discovery.js +290 -0
  140. package/dist/tools/briefings/discovery.js.map +1 -0
  141. package/dist/tools/briefings/plan-pitfalls.js +69 -0
  142. package/dist/tools/briefings/plan-pitfalls.js.map +1 -0
  143. package/dist/tools/briefings/render.js +151 -0
  144. package/dist/tools/briefings/render.js.map +1 -0
  145. package/dist/tools/briefings/rows.js +41 -0
  146. package/dist/tools/briefings/rows.js.map +1 -0
  147. package/dist/tools/briefings/toolchain.js +63 -0
  148. package/dist/tools/briefings/toolchain.js.map +1 -0
  149. package/dist/tools/briefings/why-proposed.js +69 -0
  150. package/dist/tools/briefings/why-proposed.js.map +1 -0
  151. package/dist/tools/briefings.js +44 -0
  152. package/dist/tools/briefings.js.map +1 -0
  153. package/dist/tools/feedback.js +97 -0
  154. package/dist/tools/feedback.js.map +1 -0
  155. package/dist/tools/hydrate.js +75 -0
  156. package/dist/tools/hydrate.js.map +1 -0
  157. package/dist/tools/intelligence.js +67 -0
  158. package/dist/tools/intelligence.js.map +1 -0
  159. package/dist/tools/lint/asm-decimal.js +86 -0
  160. package/dist/tools/lint/asm-decimal.js.map +1 -0
  161. package/dist/tools/lint/asm-rules.js +221 -0
  162. package/dist/tools/lint/asm-rules.js.map +1 -0
  163. package/dist/tools/lint/asm-shared.js +3 -0
  164. package/dist/tools/lint/asm-shared.js.map +1 -0
  165. package/dist/tools/lint/c-rules.js +215 -0
  166. package/dist/tools/lint/c-rules.js.map +1 -0
  167. package/dist/tools/lint/text.js +122 -0
  168. package/dist/tools/lint/text.js.map +1 -0
  169. package/dist/tools/lint/types.js +40 -0
  170. package/dist/tools/lint/types.js.map +1 -0
  171. package/dist/tools/lint.js +76 -0
  172. package/dist/tools/lint.js.map +1 -0
  173. package/dist/tools/memorization-mcp.js +111 -0
  174. package/dist/tools/memorization-mcp.js.map +1 -0
  175. package/dist/tools/pitfalls/bm25.js +53 -0
  176. package/dist/tools/pitfalls/bm25.js.map +1 -0
  177. package/dist/tools/pitfalls/format.js +58 -0
  178. package/dist/tools/pitfalls/format.js.map +1 -0
  179. package/dist/tools/pitfalls/graph.js +124 -0
  180. package/dist/tools/pitfalls/graph.js.map +1 -0
  181. package/dist/tools/pitfalls.js +134 -0
  182. package/dist/tools/pitfalls.js.map +1 -0
  183. package/dist/tools/prompts.js +81 -0
  184. package/dist/tools/prompts.js.map +1 -0
  185. package/dist/tools/query/compatibility/closure.js +62 -0
  186. package/dist/tools/query/compatibility/closure.js.map +1 -0
  187. package/dist/tools/query/compatibility/facts.js +28 -0
  188. package/dist/tools/query/compatibility/facts.js.map +1 -0
  189. package/dist/tools/query/compatibility/fetch.js +164 -0
  190. package/dist/tools/query/compatibility/fetch.js.map +1 -0
  191. package/dist/tools/query/compatibility/hard-rules.js +159 -0
  192. package/dist/tools/query/compatibility/hard-rules.js.map +1 -0
  193. package/dist/tools/query/compatibility/index.js +27 -0
  194. package/dist/tools/query/compatibility/index.js.map +1 -0
  195. package/dist/tools/query/compatibility/kernal-zp-rule.js +90 -0
  196. package/dist/tools/query/compatibility/kernal-zp-rule.js.map +1 -0
  197. package/dist/tools/query/compatibility/render.js +106 -0
  198. package/dist/tools/query/compatibility/render.js.map +1 -0
  199. package/dist/tools/query/compatibility/rules.js +337 -0
  200. package/dist/tools/query/compatibility/rules.js.map +1 -0
  201. package/dist/tools/query/compatibility/unit-rules.js +253 -0
  202. package/dist/tools/query/compatibility/unit-rules.js.map +1 -0
  203. package/dist/tools/query/game-design.js +83 -0
  204. package/dist/tools/query/game-design.js.map +1 -0
  205. package/dist/tools/query/lookups.js +220 -0
  206. package/dist/tools/query/lookups.js.map +1 -0
  207. package/dist/tools/query/plan-budget.js +266 -0
  208. package/dist/tools/query/plan-budget.js.map +1 -0
  209. package/dist/tools/query/recipes.js +214 -0
  210. package/dist/tools/query/recipes.js.map +1 -0
  211. package/dist/tools/query/retrieval.js +128 -0
  212. package/dist/tools/query/retrieval.js.map +1 -0
  213. package/dist/tools/query/shared.js +121 -0
  214. package/dist/tools/query/shared.js.map +1 -0
  215. package/dist/tools/query/techniques.js +331 -0
  216. package/dist/tools/query/techniques.js.map +1 -0
  217. package/dist/tools/query/timing.js +106 -0
  218. package/dist/tools/query/timing.js.map +1 -0
  219. package/dist/tools/query/types.js +11 -0
  220. package/dist/tools/query/types.js.map +1 -0
  221. package/dist/tools/query.js +21 -0
  222. package/dist/tools/query.js.map +1 -0
  223. package/dist/tools/resources.js +186 -0
  224. package/dist/tools/resources.js.map +1 -0
  225. package/dist/tools/run-game.js +249 -0
  226. package/dist/tools/run-game.js.map +1 -0
  227. package/dist/tools/selfimprovement.js +367 -0
  228. package/dist/tools/selfimprovement.js.map +1 -0
  229. package/docker-compose.yml +35 -0
  230. package/docs/ARCHITECTURE.md +164 -0
  231. package/docs/CONVENTIONS-archetypes.md +158 -0
  232. package/docs/CONVENTIONS-failures.md +46 -0
  233. package/docs/CONVENTIONS-game-designs.md +75 -0
  234. package/docs/CONVENTIONS-hardware-reference.md +184 -0
  235. package/docs/CONVENTIONS-pitfalls.md +91 -0
  236. package/docs/CONVENTIONS-recipes.md +106 -0
  237. package/docs/CONVENTIONS-techniques.md +309 -0
  238. package/docs/CONVENTIONS-toolchain-reference.md +89 -0
  239. package/docs/ONTOLOGY.md +655 -0
  240. package/docs/art/art-production-reference.md +157 -0
  241. package/docs/art/asset-pipelines.md +586 -0
  242. package/docs/c64-failure-patterns.md +693 -0
  243. package/docs/demo-design/demo-composition.md +349 -0
  244. package/docs/demo-design/demo-design-philosophy.md +320 -0
  245. package/docs/demo-design/intro-cracktro-patterns.md +435 -0
  246. package/docs/figures/ctm-spd-embed-probe.png +0 -0
  247. package/docs/figures/dot-flag-mid-5000000.png +0 -0
  248. package/docs/figures/dot-flag-no-erase-12000000.png +0 -0
  249. package/docs/figures/edges.json +1 -0
  250. package/docs/figures/fig6-architecture.png +0 -0
  251. package/docs/figures/fig7-ontology.png +0 -0
  252. package/docs/figures/screen-dissolve-mid-frame25.png +0 -0
  253. package/docs/figures/screen-dissolve-wipe-frame25.png +0 -0
  254. package/docs/figures/spindle-two-parts-part1.png +0 -0
  255. package/docs/figures/spindle-two-parts-part2.png +0 -0
  256. package/docs/figures/starters/action-puzzle.png +0 -0
  257. package/docs/figures/starters/adventure.png +0 -0
  258. package/docs/figures/starters/beat-em-up.png +0 -0
  259. package/docs/figures/starters/demo.png +0 -0
  260. package/docs/figures/starters/platformer.png +0 -0
  261. package/docs/figures/starters/shmup-vertical.png +0 -0
  262. package/docs/figures/tape-kernal-master-ntsc.png +0 -0
  263. package/docs/figures/tape-kernal-master-pal.png +0 -0
  264. package/docs/figures/tape-turbo-loader-ntsc.png +0 -0
  265. package/docs/figures/tape-turbo-loader-pal.png +0 -0
  266. package/docs/figures/tape-turbo-master-ntsc.png +0 -0
  267. package/docs/figures/tape-turbo-master-pal.png +0 -0
  268. package/docs/figures/tech-tech-pad2-12000000.png +0 -0
  269. package/docs/figures/tech-tech-pad4-12000000.png +0 -0
  270. package/docs/figures/tech-tech-seven-12000000.png +0 -0
  271. package/docs/figures/twister-mid-5000000.png +0 -0
  272. package/docs/figures/twister-straight-12000000.png +0 -0
  273. package/docs/figures/vector-balls-nosort-ntsc.png +0 -0
  274. package/docs/figures/vector-balls-nosort.png +0 -0
  275. package/docs/formats/c64-file-formats.md +1212 -0
  276. package/docs/formats/iec-disk-reference.md +754 -0
  277. package/docs/game-design/c64-game-archetypes.md +273 -0
  278. package/docs/game-design/designs/falling-blocks.md +54 -0
  279. package/docs/game-design/designs/platformer-scaffold.md +48 -0
  280. package/docs/game-design/designs/simple-shmup.md +27 -0
  281. package/docs/game-design/enemy-behaviour-and-difficulty.md +349 -0
  282. package/docs/game-design/game-design-patterns.md +1189 -0
  283. package/docs/game-design/game-structure.md +354 -0
  284. package/docs/game-design/production-planning.md +349 -0
  285. package/docs/game-design/reference-game-sources.md +90 -0
  286. package/docs/hardware/6502-illegal-opcodes.md +1353 -0
  287. package/docs/hardware/6510-cpu-reference.md +2112 -0
  288. package/docs/hardware/c64-memory-map.md +3184 -0
  289. package/docs/hardware/c64-registers-reference.md +996 -0
  290. package/docs/hardware/cia-reference.md +1281 -0
  291. package/docs/hardware/kernal-routines-reference.md +1836 -0
  292. package/docs/hardware/pal-ntsc-reference.md +813 -0
  293. package/docs/hardware/sid-reference.md +1137 -0
  294. package/docs/hardware/vic-ii-reference.md +1714 -0
  295. package/docs/music/music-production-reference.md +403 -0
  296. package/docs/pitfalls/banking.md +1067 -0
  297. package/docs/pitfalls/cia.md +1147 -0
  298. package/docs/pitfalls/cpu.md +874 -0
  299. package/docs/pitfalls/input.md +282 -0
  300. package/docs/pitfalls/kernal-and-io.md +1615 -0
  301. package/docs/pitfalls/loader.md +1191 -0
  302. package/docs/pitfalls/logic.md +94 -0
  303. package/docs/pitfalls/maths.md +187 -0
  304. package/docs/pitfalls/raster-and-badline.md +721 -0
  305. package/docs/pitfalls/region-timing.md +660 -0
  306. package/docs/pitfalls/scroll.md +207 -0
  307. package/docs/pitfalls/sid.md +738 -0
  308. package/docs/pitfalls/sprite.md +979 -0
  309. package/docs/pitfalls/text-mode-render.md +1172 -0
  310. package/docs/recipes/cc65/cartridge-8k.md +398 -0
  311. package/docs/recipes/cc65/hello-world-conio.md +76 -0
  312. package/docs/recipes/cc65/memory-layout.md +312 -0
  313. package/docs/recipes/cc65/screenshots/README.md +14 -0
  314. package/docs/recipes/cc65/screenshots/cartridge-8k-ntsc.png +0 -0
  315. package/docs/recipes/cc65/screenshots/cartridge-8k.png +0 -0
  316. package/docs/recipes/cc65/screenshots/hello-world-conio.png +0 -0
  317. package/docs/recipes/cc65/screenshots/memory-layout-ntsc.png +0 -0
  318. package/docs/recipes/cc65/screenshots/memory-layout.png +0 -0
  319. package/docs/recipes/kickassembler/basic-float-calls.md +578 -0
  320. package/docs/recipes/kickassembler/basic-wedge.md +398 -0
  321. package/docs/recipes/kickassembler/big-font-scroller.md +620 -0
  322. package/docs/recipes/kickassembler/charset-copy-rom-to-ram.md +623 -0
  323. package/docs/recipes/kickassembler/cia-revision-detect.md +366 -0
  324. package/docs/recipes/kickassembler/colour-cycling.md +343 -0
  325. package/docs/recipes/kickassembler/colour-fade.md +303 -0
  326. package/docs/recipes/kickassembler/compare-16bit-signed.md +1007 -0
  327. package/docs/recipes/kickassembler/cracktro-template.md +526 -0
  328. package/docs/recipes/kickassembler/crt-banked.md +276 -0
  329. package/docs/recipes/kickassembler/dos-error-codes.md +466 -0
  330. package/docs/recipes/kickassembler/dot-flag.md +576 -0
  331. package/docs/recipes/kickassembler/drive-job-queue.md +667 -0
  332. package/docs/recipes/kickassembler/drive-via-probe.md +690 -0
  333. package/docs/recipes/kickassembler/dycp-scroller.md +568 -0
  334. package/docs/recipes/kickassembler/dypp-sprite-scroller.md +681 -0
  335. package/docs/recipes/kickassembler/dysp.md +670 -0
  336. package/docs/recipes/kickassembler/easyflash-save.md +800 -0
  337. package/docs/recipes/kickassembler/eight-way-scroll.md +1484 -0
  338. package/docs/recipes/kickassembler/file-io-roundtrip.md +546 -0
  339. package/docs/recipes/kickassembler/fire-effect.md +420 -0
  340. package/docs/recipes/kickassembler/fld.md +414 -0
  341. package/docs/recipes/kickassembler/fli-image.md +336 -0
  342. package/docs/recipes/kickassembler/four-player-read.md +672 -0
  343. package/docs/recipes/kickassembler/headless-verify.md +228 -0
  344. package/docs/recipes/kickassembler/hello-world.md +98 -0
  345. package/docs/recipes/kickassembler/high-score-insert.md +660 -0
  346. package/docs/recipes/kickassembler/hires-plot-line.md +723 -0
  347. package/docs/recipes/kickassembler/irq-chain.md +316 -0
  348. package/docs/recipes/kickassembler/irq-owns-port.md +668 -0
  349. package/docs/recipes/kickassembler/isometric-room.md +1145 -0
  350. package/docs/recipes/kickassembler/light-pen-read.md +926 -0
  351. package/docs/recipes/kickassembler/logic-rate-decoupling.md +670 -0
  352. package/docs/recipes/kickassembler/mci-interlace.md +543 -0
  353. package/docs/recipes/kickassembler/memory-layout.md +277 -0
  354. package/docs/recipes/kickassembler/mouse-1351-read.md +801 -0
  355. package/docs/recipes/kickassembler/nmi-timer-tick.md +562 -0
  356. package/docs/recipes/kickassembler/own-keyscan.md +881 -0
  357. package/docs/recipes/kickassembler/paddle-read.md +751 -0
  358. package/docs/recipes/kickassembler/palette-cells.md +219 -0
  359. package/docs/recipes/kickassembler/pseudo-3d-road.md +930 -0
  360. package/docs/recipes/kickassembler/pwm-digi.md +463 -0
  361. package/docs/recipes/kickassembler/raster-bars.md +264 -0
  362. package/docs/recipes/kickassembler/reu-dma.md +1019 -0
  363. package/docs/recipes/kickassembler/runtime-relocation.md +743 -0
  364. package/docs/recipes/kickassembler/screen-dissolve.md +545 -0
  365. package/docs/recipes/kickassembler/screen-wipe.md +408 -0
  366. package/docs/recipes/kickassembler/screenshots/README.md +72 -0
  367. package/docs/recipes/kickassembler/screenshots/basic-float-calls-ntsc.png +0 -0
  368. package/docs/recipes/kickassembler/screenshots/basic-float-calls.png +0 -0
  369. package/docs/recipes/kickassembler/screenshots/basic-wedge-ntsc.png +0 -0
  370. package/docs/recipes/kickassembler/screenshots/basic-wedge.png +0 -0
  371. package/docs/recipes/kickassembler/screenshots/big-font-scroller-ntsc.png +0 -0
  372. package/docs/recipes/kickassembler/screenshots/big-font-scroller.png +0 -0
  373. package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram-ntsc.png +0 -0
  374. package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram.png +0 -0
  375. package/docs/recipes/kickassembler/screenshots/cia-revision-detect-ntsc.png +0 -0
  376. package/docs/recipes/kickassembler/screenshots/cia-revision-detect.png +0 -0
  377. package/docs/recipes/kickassembler/screenshots/colour-cycling-ntsc.png +0 -0
  378. package/docs/recipes/kickassembler/screenshots/colour-cycling.png +0 -0
  379. package/docs/recipes/kickassembler/screenshots/colour-fade-ntsc.png +0 -0
  380. package/docs/recipes/kickassembler/screenshots/colour-fade.png +0 -0
  381. package/docs/recipes/kickassembler/screenshots/compare-16bit-signed-ntsc.png +0 -0
  382. package/docs/recipes/kickassembler/screenshots/compare-16bit-signed.png +0 -0
  383. package/docs/recipes/kickassembler/screenshots/cracktro-template.png +0 -0
  384. package/docs/recipes/kickassembler/screenshots/crt-banked-ntsc.png +0 -0
  385. package/docs/recipes/kickassembler/screenshots/crt-banked.png +0 -0
  386. package/docs/recipes/kickassembler/screenshots/dos-error-codes-ntsc.png +0 -0
  387. package/docs/recipes/kickassembler/screenshots/dos-error-codes.png +0 -0
  388. package/docs/recipes/kickassembler/screenshots/dot-flag-ntsc.png +0 -0
  389. package/docs/recipes/kickassembler/screenshots/dot-flag.png +0 -0
  390. package/docs/recipes/kickassembler/screenshots/drive-job-queue-ntsc.png +0 -0
  391. package/docs/recipes/kickassembler/screenshots/drive-job-queue.png +0 -0
  392. package/docs/recipes/kickassembler/screenshots/drive-via-probe-ntsc.png +0 -0
  393. package/docs/recipes/kickassembler/screenshots/drive-via-probe.png +0 -0
  394. package/docs/recipes/kickassembler/screenshots/dycp-scroller-ntsc.png +0 -0
  395. package/docs/recipes/kickassembler/screenshots/dycp-scroller.png +0 -0
  396. package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller-ntsc.png +0 -0
  397. package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller.png +0 -0
  398. package/docs/recipes/kickassembler/screenshots/dysp-ntsc.png +0 -0
  399. package/docs/recipes/kickassembler/screenshots/dysp.png +0 -0
  400. package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc-run2.png +0 -0
  401. package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc.png +0 -0
  402. package/docs/recipes/kickassembler/screenshots/easyflash-save-run2.png +0 -0
  403. package/docs/recipes/kickassembler/screenshots/easyflash-save.png +0 -0
  404. package/docs/recipes/kickassembler/screenshots/eight-way-scroll-ntsc.png +0 -0
  405. package/docs/recipes/kickassembler/screenshots/eight-way-scroll.png +0 -0
  406. package/docs/recipes/kickassembler/screenshots/file-io-roundtrip-ntsc.png +0 -0
  407. package/docs/recipes/kickassembler/screenshots/file-io-roundtrip.png +0 -0
  408. package/docs/recipes/kickassembler/screenshots/fire-effect-ntsc.png +0 -0
  409. package/docs/recipes/kickassembler/screenshots/fire-effect.png +0 -0
  410. package/docs/recipes/kickassembler/screenshots/fld-ntsc.png +0 -0
  411. package/docs/recipes/kickassembler/screenshots/fld.png +0 -0
  412. package/docs/recipes/kickassembler/screenshots/fli-image.png +0 -0
  413. package/docs/recipes/kickassembler/screenshots/four-player-read-ntsc.png +0 -0
  414. package/docs/recipes/kickassembler/screenshots/four-player-read.png +0 -0
  415. package/docs/recipes/kickassembler/screenshots/headless-verify-ntsc.png +0 -0
  416. package/docs/recipes/kickassembler/screenshots/headless-verify.png +0 -0
  417. package/docs/recipes/kickassembler/screenshots/hello-world.png +0 -0
  418. package/docs/recipes/kickassembler/screenshots/high-score-insert-ntsc.png +0 -0
  419. package/docs/recipes/kickassembler/screenshots/high-score-insert.png +0 -0
  420. package/docs/recipes/kickassembler/screenshots/hires-plot-line-ntsc.png +0 -0
  421. package/docs/recipes/kickassembler/screenshots/hires-plot-line.png +0 -0
  422. package/docs/recipes/kickassembler/screenshots/irq-chain-ntsc.png +0 -0
  423. package/docs/recipes/kickassembler/screenshots/irq-chain.png +0 -0
  424. package/docs/recipes/kickassembler/screenshots/irq-owns-port-ntsc.png +0 -0
  425. package/docs/recipes/kickassembler/screenshots/irq-owns-port.png +0 -0
  426. package/docs/recipes/kickassembler/screenshots/isometric-room-ntsc.png +0 -0
  427. package/docs/recipes/kickassembler/screenshots/isometric-room.png +0 -0
  428. package/docs/recipes/kickassembler/screenshots/light-pen-read-ntsc.png +0 -0
  429. package/docs/recipes/kickassembler/screenshots/light-pen-read.png +0 -0
  430. package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling-ntsc.png +0 -0
  431. package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling.png +0 -0
  432. package/docs/recipes/kickassembler/screenshots/mci-interlace-average.png +0 -0
  433. package/docs/recipes/kickassembler/screenshots/mci-interlace-frame-b.png +0 -0
  434. package/docs/recipes/kickassembler/screenshots/mci-interlace-ntsc.png +0 -0
  435. package/docs/recipes/kickassembler/screenshots/mci-interlace.png +0 -0
  436. package/docs/recipes/kickassembler/screenshots/memory-layout-ntsc.png +0 -0
  437. package/docs/recipes/kickassembler/screenshots/memory-layout.png +0 -0
  438. package/docs/recipes/kickassembler/screenshots/mouse-1351-read-ntsc.png +0 -0
  439. package/docs/recipes/kickassembler/screenshots/mouse-1351-read.png +0 -0
  440. package/docs/recipes/kickassembler/screenshots/nmi-timer-tick-ntsc.png +0 -0
  441. package/docs/recipes/kickassembler/screenshots/nmi-timer-tick.png +0 -0
  442. package/docs/recipes/kickassembler/screenshots/own-keyscan-ntsc.png +0 -0
  443. package/docs/recipes/kickassembler/screenshots/own-keyscan.png +0 -0
  444. package/docs/recipes/kickassembler/screenshots/paddle-read-ntsc.png +0 -0
  445. package/docs/recipes/kickassembler/screenshots/paddle-read.png +0 -0
  446. package/docs/recipes/kickassembler/screenshots/palette-cells-ntsc.png +0 -0
  447. package/docs/recipes/kickassembler/screenshots/palette-cells.png +0 -0
  448. package/docs/recipes/kickassembler/screenshots/pseudo-3d-road-ntsc.png +0 -0
  449. package/docs/recipes/kickassembler/screenshots/pseudo-3d-road.png +0 -0
  450. package/docs/recipes/kickassembler/screenshots/pwm-digi-ntsc.png +0 -0
  451. package/docs/recipes/kickassembler/screenshots/pwm-digi.png +0 -0
  452. package/docs/recipes/kickassembler/screenshots/raster-bars.png +0 -0
  453. package/docs/recipes/kickassembler/screenshots/reu-dma-ntsc.png +0 -0
  454. package/docs/recipes/kickassembler/screenshots/reu-dma.png +0 -0
  455. package/docs/recipes/kickassembler/screenshots/runtime-relocation-ntsc.png +0 -0
  456. package/docs/recipes/kickassembler/screenshots/runtime-relocation.png +0 -0
  457. package/docs/recipes/kickassembler/screenshots/screen-dissolve-ntsc.png +0 -0
  458. package/docs/recipes/kickassembler/screenshots/screen-dissolve.png +0 -0
  459. package/docs/recipes/kickassembler/screenshots/screen-wipe-ntsc.png +0 -0
  460. package/docs/recipes/kickassembler/screenshots/screen-wipe.png +0 -0
  461. package/docs/recipes/kickassembler/screenshots/scroll-panel-split-ntsc.png +0 -0
  462. package/docs/recipes/kickassembler/screenshots/scroll-panel-split.png +0 -0
  463. package/docs/recipes/kickassembler/screenshots/sfx-in-player-ntsc.png +0 -0
  464. package/docs/recipes/kickassembler/screenshots/sfx-in-player.png +0 -0
  465. package/docs/recipes/kickassembler/screenshots/shadebobs-ntsc.png +0 -0
  466. package/docs/recipes/kickassembler/screenshots/shadebobs.png +0 -0
  467. package/docs/recipes/kickassembler/screenshots/sideborder-open.png +0 -0
  468. package/docs/recipes/kickassembler/screenshots/sine-scroller.png +0 -0
  469. package/docs/recipes/kickassembler/screenshots/sine-table-runtime-ntsc.png +0 -0
  470. package/docs/recipes/kickassembler/screenshots/sine-table-runtime.png +0 -0
  471. package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted-ntsc.png +0 -0
  472. package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted.png +0 -0
  473. package/docs/recipes/kickassembler/screenshots/speedcode-generator-ntsc.png +0 -0
  474. package/docs/recipes/kickassembler/screenshots/speedcode-generator.png +0 -0
  475. package/docs/recipes/kickassembler/screenshots/sprite-border-scroller-ntsc.png +0 -0
  476. package/docs/recipes/kickassembler/screenshots/sprite-border-scroller.png +0 -0
  477. package/docs/recipes/kickassembler/screenshots/sprite-cache-flip-ntsc.png +0 -0
  478. package/docs/recipes/kickassembler/screenshots/sprite-cache-flip.png +0 -0
  479. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-24.png +0 -0
  480. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game-ntsc.png +0 -0
  481. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game.png +0 -0
  482. package/docs/recipes/kickassembler/screenshots/sprite-priority-classes-ntsc.png +0 -0
  483. package/docs/recipes/kickassembler/screenshots/sprite-priority-classes.png +0 -0
  484. package/docs/recipes/kickassembler/screenshots/sprite-sine-chain-ntsc.png +0 -0
  485. package/docs/recipes/kickassembler/screenshots/sprite-sine-chain.png +0 -0
  486. package/docs/recipes/kickassembler/screenshots/sprite-stretcher-ntsc.png +0 -0
  487. package/docs/recipes/kickassembler/screenshots/sprite-stretcher.png +0 -0
  488. package/docs/recipes/kickassembler/screenshots/sprites-only-screen-ntsc.png +0 -0
  489. package/docs/recipes/kickassembler/screenshots/sprites-only-screen.png +0 -0
  490. package/docs/recipes/kickassembler/screenshots/sqrt-atan2-ntsc.png +0 -0
  491. package/docs/recipes/kickassembler/screenshots/sqrt-atan2.png +0 -0
  492. package/docs/recipes/kickassembler/screenshots/stable-raster-irq-control.png +0 -0
  493. package/docs/recipes/kickassembler/screenshots/stable-raster-irq.png +0 -0
  494. package/docs/recipes/kickassembler/screenshots/tech-tech-ntsc.png +0 -0
  495. package/docs/recipes/kickassembler/screenshots/tech-tech.png +0 -0
  496. package/docs/recipes/kickassembler/screenshots/tod-alarm-ntsc.png +0 -0
  497. package/docs/recipes/kickassembler/screenshots/tod-alarm.png +0 -0
  498. package/docs/recipes/kickassembler/screenshots/topbottom-border-open.png +0 -0
  499. package/docs/recipes/kickassembler/screenshots/twister-ntsc.png +0 -0
  500. package/docs/recipes/kickassembler/screenshots/twister.png +0 -0
  501. package/docs/recipes/kickassembler/screenshots/unit-test-driver-ntsc.png +0 -0
  502. package/docs/recipes/kickassembler/screenshots/unit-test-driver.png +0 -0
  503. package/docs/recipes/kickassembler/screenshots/vector-balls-ntsc.png +0 -0
  504. package/docs/recipes/kickassembler/screenshots/vector-balls.png +0 -0
  505. package/docs/recipes/kickassembler/screenshots/wireframe-ships-ntsc.png +0 -0
  506. package/docs/recipes/kickassembler/screenshots/wireframe-ships.png +0 -0
  507. package/docs/recipes/kickassembler/scroll-panel-split.md +381 -0
  508. package/docs/recipes/kickassembler/sfx-in-player.md +907 -0
  509. package/docs/recipes/kickassembler/shadebobs.md +522 -0
  510. package/docs/recipes/kickassembler/sideborder-open.md +338 -0
  511. package/docs/recipes/kickassembler/sine-scroller.md +321 -0
  512. package/docs/recipes/kickassembler/sine-table-runtime.md +815 -0
  513. package/docs/recipes/kickassembler/software-sprite-preshifted.md +725 -0
  514. package/docs/recipes/kickassembler/speedcode-generator.md +606 -0
  515. package/docs/recipes/kickassembler/sprite-border-scroller.md +696 -0
  516. package/docs/recipes/kickassembler/sprite-cache-flip.md +1071 -0
  517. package/docs/recipes/kickassembler/sprite-multiplex-24.md +326 -0
  518. package/docs/recipes/kickassembler/sprite-multiplex-game.md +986 -0
  519. package/docs/recipes/kickassembler/sprite-priority-classes.md +463 -0
  520. package/docs/recipes/kickassembler/sprite-sine-chain.md +338 -0
  521. package/docs/recipes/kickassembler/sprite-stretcher.md +501 -0
  522. package/docs/recipes/kickassembler/sprites-only-screen.md +550 -0
  523. package/docs/recipes/kickassembler/sqrt-atan2.md +1014 -0
  524. package/docs/recipes/kickassembler/stable-raster-irq.md +360 -0
  525. package/docs/recipes/kickassembler/tape-turbo-loader.md +875 -0
  526. package/docs/recipes/kickassembler/tech-tech.md +679 -0
  527. package/docs/recipes/kickassembler/tod-alarm.md +754 -0
  528. package/docs/recipes/kickassembler/topbottom-border-open.md +407 -0
  529. package/docs/recipes/kickassembler/twister.md +518 -0
  530. package/docs/recipes/kickassembler/unit-test-driver.md +314 -0
  531. package/docs/recipes/kickassembler/vector-balls.md +545 -0
  532. package/docs/recipes/kickassembler/wireframe-ships.md +2324 -0
  533. package/docs/recipes/oscar64/actor-activation-window.md +807 -0
  534. package/docs/recipes/oscar64/adventure-engine.md +1094 -0
  535. package/docs/recipes/oscar64/attract-replay.md +465 -0
  536. package/docs/recipes/oscar64/beat-em-up-lanes.md +563 -0
  537. package/docs/recipes/oscar64/bfs-distance-map.md +723 -0
  538. package/docs/recipes/oscar64/bitmap-koala-viewer.md +355 -0
  539. package/docs/recipes/oscar64/car-contact.md +950 -0
  540. package/docs/recipes/oscar64/cave-scan.md +609 -0
  541. package/docs/recipes/oscar64/char-bullets.md +477 -0
  542. package/docs/recipes/oscar64/charset-animation.md +383 -0
  543. package/docs/recipes/oscar64/charset-parallax.md +401 -0
  544. package/docs/recipes/oscar64/destructible-terrain.md +1099 -0
  545. package/docs/recipes/oscar64/difficulty-tables.md +654 -0
  546. package/docs/recipes/oscar64/dig-and-guards.md +975 -0
  547. package/docs/recipes/oscar64/directory-reader.md +535 -0
  548. package/docs/recipes/oscar64/divide-check.md +581 -0
  549. package/docs/recipes/oscar64/double-buffer-nomirror.md +205 -0
  550. package/docs/recipes/oscar64/double-buffer.md +255 -0
  551. package/docs/recipes/oscar64/falling-blocks.md +874 -0
  552. package/docs/recipes/oscar64/fixed-point-jump-velocity.md +289 -0
  553. package/docs/recipes/oscar64/fixed-point-jump.md +210 -0
  554. package/docs/recipes/oscar64/flip-screen-rooms.md +793 -0
  555. package/docs/recipes/oscar64/frame-sync-loop-overrun.md +214 -0
  556. package/docs/recipes/oscar64/frame-sync-loop.md +254 -0
  557. package/docs/recipes/oscar64/game-tree-search.md +743 -0
  558. package/docs/recipes/oscar64/ghost-targeting.md +867 -0
  559. package/docs/recipes/oscar64/headless-verify.md +345 -0
  560. package/docs/recipes/oscar64/hello-world.md +83 -0
  561. package/docs/recipes/oscar64/high-score-persist.md +772 -0
  562. package/docs/recipes/oscar64/iffl-kernal-skip.md +421 -0
  563. package/docs/recipes/oscar64/joystick-input.md +358 -0
  564. package/docs/recipes/oscar64/lane-pursuit.md +1028 -0
  565. package/docs/recipes/oscar64/level-rle-decoder.md +620 -0
  566. package/docs/recipes/oscar64/lfsr-random-seed2.md +338 -0
  567. package/docs/recipes/oscar64/lfsr-random.md +403 -0
  568. package/docs/recipes/oscar64/load-asset-runtime.md +492 -0
  569. package/docs/recipes/oscar64/memory-layout.md +232 -0
  570. package/docs/recipes/oscar64/mixed-fighters.md +781 -0
  571. package/docs/recipes/oscar64/multi-sprite-object.md +533 -0
  572. package/docs/recipes/oscar64/nav-area-pathfinding.md +881 -0
  573. package/docs/recipes/oscar64/object-pool.md +572 -0
  574. package/docs/recipes/oscar64/pal-ntsc-detect.md +257 -0
  575. package/docs/recipes/oscar64/password-state.md +532 -0
  576. package/docs/recipes/oscar64/per-frame-hitbox.md +651 -0
  577. package/docs/recipes/oscar64/petscii-screen-codes.md +428 -0
  578. package/docs/recipes/oscar64/platformer-scaffold.md +1467 -0
  579. package/docs/recipes/oscar64/print-number.md +367 -0
  580. package/docs/recipes/oscar64/raster-bars.md +239 -0
  581. package/docs/recipes/oscar64/raster-profile-bars.md +404 -0
  582. package/docs/recipes/oscar64/rel-side-sectors.md +391 -0
  583. package/docs/recipes/oscar64/relative-file-records.md +378 -0
  584. package/docs/recipes/oscar64/save-load-seq-file.md +365 -0
  585. package/docs/recipes/oscar64/screenshots/README.md +99 -0
  586. package/docs/recipes/oscar64/screenshots/actor-activation-window-ntsc.png +0 -0
  587. package/docs/recipes/oscar64/screenshots/actor-activation-window.png +0 -0
  588. package/docs/recipes/oscar64/screenshots/adventure-engine-ntsc.png +0 -0
  589. package/docs/recipes/oscar64/screenshots/adventure-engine.png +0 -0
  590. package/docs/recipes/oscar64/screenshots/attract-replay-ntsc.png +0 -0
  591. package/docs/recipes/oscar64/screenshots/attract-replay.png +0 -0
  592. package/docs/recipes/oscar64/screenshots/beat-em-up-lanes-ntsc.png +0 -0
  593. package/docs/recipes/oscar64/screenshots/beat-em-up-lanes.png +0 -0
  594. package/docs/recipes/oscar64/screenshots/bfs-distance-map-ntsc.png +0 -0
  595. package/docs/recipes/oscar64/screenshots/bfs-distance-map.png +0 -0
  596. package/docs/recipes/oscar64/screenshots/bitmap-koala-viewer.png +0 -0
  597. package/docs/recipes/oscar64/screenshots/car-contact-ntsc.png +0 -0
  598. package/docs/recipes/oscar64/screenshots/car-contact.png +0 -0
  599. package/docs/recipes/oscar64/screenshots/cave-scan-ntsc.png +0 -0
  600. package/docs/recipes/oscar64/screenshots/cave-scan.png +0 -0
  601. package/docs/recipes/oscar64/screenshots/char-bullets-ntsc.png +0 -0
  602. package/docs/recipes/oscar64/screenshots/char-bullets.png +0 -0
  603. package/docs/recipes/oscar64/screenshots/charset-animation-ntsc.png +0 -0
  604. package/docs/recipes/oscar64/screenshots/charset-animation.png +0 -0
  605. package/docs/recipes/oscar64/screenshots/charset-parallax-ntsc.png +0 -0
  606. package/docs/recipes/oscar64/screenshots/charset-parallax.png +0 -0
  607. package/docs/recipes/oscar64/screenshots/destructible-terrain-ntsc.png +0 -0
  608. package/docs/recipes/oscar64/screenshots/destructible-terrain.png +0 -0
  609. package/docs/recipes/oscar64/screenshots/difficulty-tables-ntsc.png +0 -0
  610. package/docs/recipes/oscar64/screenshots/difficulty-tables.png +0 -0
  611. package/docs/recipes/oscar64/screenshots/dig-and-guards-ntsc.png +0 -0
  612. package/docs/recipes/oscar64/screenshots/dig-and-guards.png +0 -0
  613. package/docs/recipes/oscar64/screenshots/directory-reader-ntsc.png +0 -0
  614. package/docs/recipes/oscar64/screenshots/directory-reader.png +0 -0
  615. package/docs/recipes/oscar64/screenshots/divide-check-ntsc.png +0 -0
  616. package/docs/recipes/oscar64/screenshots/divide-check.png +0 -0
  617. package/docs/recipes/oscar64/screenshots/double-buffer-nomirror.png +0 -0
  618. package/docs/recipes/oscar64/screenshots/double-buffer-ntsc.png +0 -0
  619. package/docs/recipes/oscar64/screenshots/double-buffer.png +0 -0
  620. package/docs/recipes/oscar64/screenshots/falling-blocks-ntsc.png +0 -0
  621. package/docs/recipes/oscar64/screenshots/falling-blocks.png +0 -0
  622. package/docs/recipes/oscar64/screenshots/fixed-point-jump-ntsc.png +0 -0
  623. package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity-ntsc.png +0 -0
  624. package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity.png +0 -0
  625. package/docs/recipes/oscar64/screenshots/fixed-point-jump.png +0 -0
  626. package/docs/recipes/oscar64/screenshots/flip-screen-rooms-ntsc.png +0 -0
  627. package/docs/recipes/oscar64/screenshots/flip-screen-rooms.png +0 -0
  628. package/docs/recipes/oscar64/screenshots/frame-sync-loop-ntsc.png +0 -0
  629. package/docs/recipes/oscar64/screenshots/frame-sync-loop-overrun.png +0 -0
  630. package/docs/recipes/oscar64/screenshots/frame-sync-loop.png +0 -0
  631. package/docs/recipes/oscar64/screenshots/game-tree-search-ntsc.png +0 -0
  632. package/docs/recipes/oscar64/screenshots/game-tree-search.png +0 -0
  633. package/docs/recipes/oscar64/screenshots/ghost-targeting-ntsc.png +0 -0
  634. package/docs/recipes/oscar64/screenshots/ghost-targeting.png +0 -0
  635. package/docs/recipes/oscar64/screenshots/headless-verify-ntsc.png +0 -0
  636. package/docs/recipes/oscar64/screenshots/headless-verify.png +0 -0
  637. package/docs/recipes/oscar64/screenshots/hello-world.png +0 -0
  638. package/docs/recipes/oscar64/screenshots/high-score-persist-ntsc.png +0 -0
  639. package/docs/recipes/oscar64/screenshots/high-score-persist.png +0 -0
  640. package/docs/recipes/oscar64/screenshots/iffl-kernal-skip-ntsc.png +0 -0
  641. package/docs/recipes/oscar64/screenshots/iffl-kernal-skip.png +0 -0
  642. package/docs/recipes/oscar64/screenshots/joystick-input-ntsc.png +0 -0
  643. package/docs/recipes/oscar64/screenshots/joystick-input.png +0 -0
  644. package/docs/recipes/oscar64/screenshots/lane-pursuit-ntsc.png +0 -0
  645. package/docs/recipes/oscar64/screenshots/lane-pursuit.png +0 -0
  646. package/docs/recipes/oscar64/screenshots/level-rle-decoder-ntsc.png +0 -0
  647. package/docs/recipes/oscar64/screenshots/level-rle-decoder.png +0 -0
  648. package/docs/recipes/oscar64/screenshots/lfsr-random-ntsc.png +0 -0
  649. package/docs/recipes/oscar64/screenshots/lfsr-random-seed2.png +0 -0
  650. package/docs/recipes/oscar64/screenshots/lfsr-random.png +0 -0
  651. package/docs/recipes/oscar64/screenshots/load-asset-runtime-ntsc.png +0 -0
  652. package/docs/recipes/oscar64/screenshots/load-asset-runtime.png +0 -0
  653. package/docs/recipes/oscar64/screenshots/memory-layout-ntsc.png +0 -0
  654. package/docs/recipes/oscar64/screenshots/memory-layout.png +0 -0
  655. package/docs/recipes/oscar64/screenshots/mixed-fighters-ntsc.png +0 -0
  656. package/docs/recipes/oscar64/screenshots/mixed-fighters.png +0 -0
  657. package/docs/recipes/oscar64/screenshots/multi-sprite-object-ntsc.png +0 -0
  658. package/docs/recipes/oscar64/screenshots/multi-sprite-object.png +0 -0
  659. package/docs/recipes/oscar64/screenshots/nav-area-pathfinding-ntsc.png +0 -0
  660. package/docs/recipes/oscar64/screenshots/nav-area-pathfinding.png +0 -0
  661. package/docs/recipes/oscar64/screenshots/object-pool-ntsc.png +0 -0
  662. package/docs/recipes/oscar64/screenshots/object-pool.png +0 -0
  663. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-ntsc.png +0 -0
  664. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-oldntsc.png +0 -0
  665. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-pal.png +0 -0
  666. package/docs/recipes/oscar64/screenshots/password-state-ntsc.png +0 -0
  667. package/docs/recipes/oscar64/screenshots/password-state.png +0 -0
  668. package/docs/recipes/oscar64/screenshots/per-frame-hitbox-ntsc.png +0 -0
  669. package/docs/recipes/oscar64/screenshots/per-frame-hitbox.png +0 -0
  670. package/docs/recipes/oscar64/screenshots/petscii-screen-codes-ntsc.png +0 -0
  671. package/docs/recipes/oscar64/screenshots/petscii-screen-codes.png +0 -0
  672. package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64-ntsc.png +0 -0
  673. package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64.png +0 -0
  674. package/docs/recipes/oscar64/screenshots/platformer-scaffold-ntsc.png +0 -0
  675. package/docs/recipes/oscar64/screenshots/platformer-scaffold.png +0 -0
  676. package/docs/recipes/oscar64/screenshots/print-number-ntsc.png +0 -0
  677. package/docs/recipes/oscar64/screenshots/print-number.png +0 -0
  678. package/docs/recipes/oscar64/screenshots/raster-bars.png +0 -0
  679. package/docs/recipes/oscar64/screenshots/raster-profile-bars-ntsc.png +0 -0
  680. package/docs/recipes/oscar64/screenshots/raster-profile-bars.png +0 -0
  681. package/docs/recipes/oscar64/screenshots/rel-side-sectors-ntsc.png +0 -0
  682. package/docs/recipes/oscar64/screenshots/rel-side-sectors.png +0 -0
  683. package/docs/recipes/oscar64/screenshots/relative-file-records-ntsc.png +0 -0
  684. package/docs/recipes/oscar64/screenshots/relative-file-records.png +0 -0
  685. package/docs/recipes/oscar64/screenshots/save-load-seq-file-ntsc.png +0 -0
  686. package/docs/recipes/oscar64/screenshots/save-load-seq-file.png +0 -0
  687. package/docs/recipes/oscar64/screenshots/seeded-level-fill-ntsc.png +0 -0
  688. package/docs/recipes/oscar64/screenshots/seeded-level-fill.png +0 -0
  689. package/docs/recipes/oscar64/screenshots/sfx-engine-ntsc.png +0 -0
  690. package/docs/recipes/oscar64/screenshots/sfx-engine.png +0 -0
  691. package/docs/recipes/oscar64/screenshots/sid-music-player.png +0 -0
  692. package/docs/recipes/oscar64/screenshots/simple-shmup.png +0 -0
  693. package/docs/recipes/oscar64/screenshots/slope-collision-ntsc.png +0 -0
  694. package/docs/recipes/oscar64/screenshots/slope-collision.png +0 -0
  695. package/docs/recipes/oscar64/screenshots/soft-scroll-h.png +0 -0
  696. package/docs/recipes/oscar64/screenshots/sprite-animation-table-ntsc.png +0 -0
  697. package/docs/recipes/oscar64/screenshots/sprite-animation-table.png +0 -0
  698. package/docs/recipes/oscar64/screenshots/sprite-multiplex-8.png +0 -0
  699. package/docs/recipes/oscar64/screenshots/stable-raster-irq.png +0 -0
  700. package/docs/recipes/oscar64/screenshots/text-input-ntsc.png +0 -0
  701. package/docs/recipes/oscar64/screenshots/text-input.png +0 -0
  702. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-gameover.png +0 -0
  703. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-notrail-control.png +0 -0
  704. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ntsc.png +0 -0
  705. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ungated-control.png +0 -0
  706. package/docs/recipes/oscar64/screenshots/text-overlay-playfield.png +0 -0
  707. package/docs/recipes/oscar64/screenshots/text-window-menu-ntsc.png +0 -0
  708. package/docs/recipes/oscar64/screenshots/text-window-menu.png +0 -0
  709. package/docs/recipes/oscar64/screenshots/tile-grid-collision-ntsc.png +0 -0
  710. package/docs/recipes/oscar64/screenshots/tile-grid-collision.png +0 -0
  711. package/docs/recipes/oscar64/screenshots/tile-map-render-ntsc.png +0 -0
  712. package/docs/recipes/oscar64/screenshots/tile-map-render.png +0 -0
  713. package/docs/recipes/oscar64/screenshots/two-player-ntsc.png +0 -0
  714. package/docs/recipes/oscar64/screenshots/two-player.png +0 -0
  715. package/docs/recipes/oscar64/screenshots/two-word-parser-ntsc.png +0 -0
  716. package/docs/recipes/oscar64/screenshots/two-word-parser.png +0 -0
  717. package/docs/recipes/oscar64/screenshots/vehicle-control-ntsc.png +0 -0
  718. package/docs/recipes/oscar64/screenshots/vehicle-control.png +0 -0
  719. package/docs/recipes/oscar64/screenshots/wave-director-ntsc.png +0 -0
  720. package/docs/recipes/oscar64/screenshots/wave-director.png +0 -0
  721. package/docs/recipes/oscar64/seeded-level-fill.md +364 -0
  722. package/docs/recipes/oscar64/sfx-engine.md +514 -0
  723. package/docs/recipes/oscar64/sid-music-player.md +441 -0
  724. package/docs/recipes/oscar64/simple-shmup.md +1000 -0
  725. package/docs/recipes/oscar64/slope-collision.md +610 -0
  726. package/docs/recipes/oscar64/soft-scroll-h.md +261 -0
  727. package/docs/recipes/oscar64/sprite-animation-table.md +671 -0
  728. package/docs/recipes/oscar64/sprite-multiplex-8.md +314 -0
  729. package/docs/recipes/oscar64/stable-raster-irq.md +236 -0
  730. package/docs/recipes/oscar64/text-input.md +274 -0
  731. package/docs/recipes/oscar64/text-overlay-playfield.md +617 -0
  732. package/docs/recipes/oscar64/text-window-menu.md +551 -0
  733. package/docs/recipes/oscar64/tile-grid-collision.md +563 -0
  734. package/docs/recipes/oscar64/tile-map-render.md +395 -0
  735. package/docs/recipes/oscar64/two-player.md +528 -0
  736. package/docs/recipes/oscar64/two-word-parser.md +510 -0
  737. package/docs/recipes/oscar64/vehicle-control.md +771 -0
  738. package/docs/recipes/oscar64/wave-director.md +787 -0
  739. package/docs/recipes/runs.json +1606 -0
  740. package/docs/runtime/sim6502-reference.md +466 -0
  741. package/docs/runtime/vice-mcp-reference.md +351 -0
  742. package/docs/runtime/vice-reference.md +1393 -0
  743. package/docs/techniques/bitmap-modes.md +685 -0
  744. package/docs/techniques/cpu-cycle-tricks.md +1570 -0
  745. package/docs/techniques/effects-vector-3d.md +1431 -0
  746. package/docs/techniques/file-io.md +1427 -0
  747. package/docs/techniques/input.md +1072 -0
  748. package/docs/techniques/loaders-packers.md +768 -0
  749. package/docs/techniques/logic.md +3091 -0
  750. package/docs/techniques/maths.md +1524 -0
  751. package/docs/techniques/memory-banking.md +1686 -0
  752. package/docs/techniques/music-sid.md +1144 -0
  753. package/docs/techniques/raster.md +1543 -0
  754. package/docs/techniques/scroll.md +1292 -0
  755. package/docs/techniques/sprite.md +2566 -0
  756. package/docs/techniques/text-mode-render.md +717 -0
  757. package/docs/techniques/text.md +1095 -0
  758. package/docs/techniques/transitions.md +405 -0
  759. package/docs/toolchains/cartconv-reference.md +262 -0
  760. package/docs/toolchains/cc1541-reference.md +316 -0
  761. package/docs/toolchains/cc65-reference.md +667 -0
  762. package/docs/toolchains/error-sources/cc65/README.md +1 -0
  763. package/docs/toolchains/error-sources/cc65/missing-setcpu.s +4 -0
  764. package/docs/toolchains/error-sources/cc65/range-error.s +4 -0
  765. package/docs/toolchains/error-sources/cc65/segment-overflow.c +6 -0
  766. package/docs/toolchains/error-sources/cc65/unresolved-external.c +6 -0
  767. package/docs/toolchains/error-sources/kickassembler/README.md +1 -0
  768. package/docs/toolchains/error-sources/kickassembler/branch-out-of-range.asm +4 -0
  769. package/docs/toolchains/error-sources/kickassembler/failed-assert.asm +3 -0
  770. package/docs/toolchains/error-sources/kickassembler/flat-lib.asm +4 -0
  771. package/docs/toolchains/error-sources/kickassembler/import-source-no-namespace.asm +5 -0
  772. package/docs/toolchains/error-sources/kickassembler/macro-without-parentheses.asm +6 -0
  773. package/docs/toolchains/error-sources/kickassembler/memory-block-overlap.asm +4 -0
  774. package/docs/toolchains/error-sources/kickassembler/symbol-clash-lib.asm +5 -0
  775. package/docs/toolchains/error-sources/kickassembler/symbol-clash-main.asm +6 -0
  776. package/docs/toolchains/error-sources/kickassembler/unknown-symbol.asm +4 -0
  777. package/docs/toolchains/error-sources/oscar64/README.md +1 -0
  778. package/docs/toolchains/error-sources/oscar64/asm-addressing-mode.c +7 -0
  779. package/docs/toolchains/error-sources/oscar64/region-overflow.c +6 -0
  780. package/docs/toolchains/error-sources/oscar64/undefined-extern-var.c +5 -0
  781. package/docs/toolchains/error-sources/oscar64/undefined-extern.c +6 -0
  782. package/docs/toolchains/error-sources/oscar64/unknown-vic-field.c +6 -0
  783. package/docs/toolchains/error-sources/oscar64/void-main.c +3 -0
  784. package/docs/toolchains/kickassembler-reference.md +1020 -0
  785. package/docs/toolchains/memory-layout-planning.md +362 -0
  786. package/docs/toolchains/oscar64-headers-reference.md +583 -0
  787. package/docs/toolchains/oscar64-reference.md +892 -0
  788. package/docs/toolchains/petcat-reference.md +290 -0
  789. package/docs/toolchains/png2prg.md +188 -0
  790. package/docs/toolchains/release-disk.md +314 -0
  791. package/docs/toolchains/sidreloc.md +236 -0
  792. package/docs/toolchains/spindle-reference.md +487 -0
  793. package/docs/toolchains/tape-mastering.md +592 -0
  794. package/docs/toolchains/unit-testing-6502.md +281 -0
  795. package/docs/workflow/agent-harness.md +478 -0
  796. package/package.json +105 -0
  797. package/templates/_harness/CLAUDE.md.template +91 -0
  798. package/templates/_harness/PLAN.md.template +72 -0
  799. package/templates/_harness/check.py +442 -0
  800. package/templates/_harness/claude/settings.json +17 -0
  801. package/templates/_harness/gen-asm-header.py +96 -0
  802. package/templates/_harness/harness.mk +273 -0
  803. package/templates/_harness/hooks/plan-gate.py +185 -0
  804. package/templates/_harness/meter/frame_meter.asm +311 -0
  805. package/templates/_harness/meter/frame_meter.c +155 -0
  806. package/templates/_harness/meter/frame_meter.h +80 -0
  807. package/templates/_harness/zp-used.py +104 -0
  808. package/templates/action-puzzle/.claude/settings.json +17 -0
  809. package/templates/action-puzzle/.mcp.json +10 -0
  810. package/templates/action-puzzle/CLAUDE.md +120 -0
  811. package/templates/action-puzzle/Makefile +125 -0
  812. package/templates/action-puzzle/PLAN.md +388 -0
  813. package/templates/action-puzzle/README.md +240 -0
  814. package/templates/action-puzzle/expect.json +25 -0
  815. package/templates/action-puzzle/src/cave.c +280 -0
  816. package/templates/action-puzzle/src/cave.h +80 -0
  817. package/templates/action-puzzle/src/gen_autopilot.h +20 -0
  818. package/templates/action-puzzle/src/gen_caves.h +59 -0
  819. package/templates/action-puzzle/src/gen_notes.h +16 -0
  820. package/templates/action-puzzle/src/hiscore.c +152 -0
  821. package/templates/action-puzzle/src/hiscore.h +41 -0
  822. package/templates/action-puzzle/src/level.c +64 -0
  823. package/templates/action-puzzle/src/level.h +24 -0
  824. package/templates/action-puzzle/src/main.c +599 -0
  825. package/templates/action-puzzle/src/render.c +239 -0
  826. package/templates/action-puzzle/src/render.h +31 -0
  827. package/templates/action-puzzle/src/sound.c +158 -0
  828. package/templates/action-puzzle/src/sound.h +22 -0
  829. package/templates/action-puzzle/tools/disk_check.py +77 -0
  830. package/templates/action-puzzle/tools/drive.py +106 -0
  831. package/templates/action-puzzle/tools/gen.py +454 -0
  832. package/templates/action-puzzle/tools/model_check.py +49 -0
  833. package/templates/action-puzzle/tools/verdict_codes.py +24 -0
  834. package/templates/adventure/.claude/settings.json +17 -0
  835. package/templates/adventure/.mcp.json +10 -0
  836. package/templates/adventure/CLAUDE.md +118 -0
  837. package/templates/adventure/Makefile +113 -0
  838. package/templates/adventure/PLAN.md +396 -0
  839. package/templates/adventure/README.md +277 -0
  840. package/templates/adventure/expect.json +25 -0
  841. package/templates/adventure/src/engine.c +543 -0
  842. package/templates/adventure/src/engine.h +48 -0
  843. package/templates/adventure/src/gen_script.h +141 -0
  844. package/templates/adventure/src/gen_world.h +511 -0
  845. package/templates/adventure/src/main.c +439 -0
  846. package/templates/adventure/src/picture.c +83 -0
  847. package/templates/adventure/src/picture.h +16 -0
  848. package/templates/adventure/src/save.c +159 -0
  849. package/templates/adventure/src/save.h +25 -0
  850. package/templates/adventure/src/sound.c +71 -0
  851. package/templates/adventure/src/sound.h +16 -0
  852. package/templates/adventure/src/text.c +349 -0
  853. package/templates/adventure/src/text.h +40 -0
  854. package/templates/adventure/tools/disk_check.py +128 -0
  855. package/templates/adventure/tools/drive.py +119 -0
  856. package/templates/adventure/tools/gen.py +1033 -0
  857. package/templates/adventure/tools/world.py +356 -0
  858. package/templates/beat-em-up/.claude/settings.json +17 -0
  859. package/templates/beat-em-up/.mcp.json +10 -0
  860. package/templates/beat-em-up/CLAUDE.md +136 -0
  861. package/templates/beat-em-up/Makefile +96 -0
  862. package/templates/beat-em-up/PLAN.md +502 -0
  863. package/templates/beat-em-up/README.md +315 -0
  864. package/templates/beat-em-up/expect-gameover.json +8 -0
  865. package/templates/beat-em-up/expect.json +29 -0
  866. package/templates/beat-em-up/src/anim.c +70 -0
  867. package/templates/beat-em-up/src/art.c +344 -0
  868. package/templates/beat-em-up/src/autopilot.h +154 -0
  869. package/templates/beat-em-up/src/brute.c +273 -0
  870. package/templates/beat-em-up/src/enemy.c +281 -0
  871. package/templates/beat-em-up/src/engine.asm +512 -0
  872. package/templates/beat-em-up/src/fighter.c +384 -0
  873. package/templates/beat-em-up/src/game.h +269 -0
  874. package/templates/beat-em-up/src/hud.c +135 -0
  875. package/templates/beat-em-up/src/main.c +341 -0
  876. package/templates/beat-em-up/src/sound.c +44 -0
  877. package/templates/beat-em-up/src/street.c +93 -0
  878. package/templates/beat-em-up/src/verdict.h +523 -0
  879. package/templates/beat-em-up/src/view.c +362 -0
  880. package/templates/beat-em-up/tools/drive.py +105 -0
  881. package/templates/beat-em-up/tools/flickercheck.py +273 -0
  882. package/templates/demo/.claude/settings.json +17 -0
  883. package/templates/demo/.mcp.json +10 -0
  884. package/templates/demo/CLAUDE.md +129 -0
  885. package/templates/demo/Makefile +66 -0
  886. package/templates/demo/PLAN.md +401 -0
  887. package/templates/demo/README.md +322 -0
  888. package/templates/demo/expect.json +945 -0
  889. package/templates/demo/src/config.asm +80 -0
  890. package/templates/demo/src/framework.asm +390 -0
  891. package/templates/demo/src/main.asm +139 -0
  892. package/templates/demo/src/music.asm +197 -0
  893. package/templates/demo/src/part_main.asm +279 -0
  894. package/templates/demo/src/part_title.asm +79 -0
  895. package/templates/demo/src/parts.asm +43 -0
  896. package/templates/demo/src/tables.asm +73 -0
  897. package/templates/demo/src/verdict.asm +179 -0
  898. package/templates/demo/tools/audio.py +80 -0
  899. package/templates/demo/tools/gen_expect.py +167 -0
  900. package/templates/demo/tools/probe.py +95 -0
  901. package/templates/hello/.claude/settings.json +17 -0
  902. package/templates/hello/.mcp.json +10 -0
  903. package/templates/hello/CLAUDE.md +100 -0
  904. package/templates/hello/Makefile +38 -0
  905. package/templates/hello/PLAN.md +200 -0
  906. package/templates/hello/expect.json +20 -0
  907. package/templates/hello/src/main.c +161 -0
  908. package/templates/hello/src/sprite.asm +27 -0
  909. package/templates/hello-kick/.claude/settings.json +17 -0
  910. package/templates/hello-kick/.mcp.json +10 -0
  911. package/templates/hello-kick/CLAUDE.md +100 -0
  912. package/templates/hello-kick/Makefile +17 -0
  913. package/templates/hello-kick/PLAN.md +199 -0
  914. package/templates/hello-kick/expect.json +20 -0
  915. package/templates/hello-kick/src/main.asm +233 -0
  916. package/templates/platformer/.claude/settings.json +17 -0
  917. package/templates/platformer/.mcp.json +10 -0
  918. package/templates/platformer/CLAUDE.md +125 -0
  919. package/templates/platformer/Makefile +86 -0
  920. package/templates/platformer/PLAN.md +360 -0
  921. package/templates/platformer/README.md +277 -0
  922. package/templates/platformer/expect.json +32 -0
  923. package/templates/platformer/src/actors.c +289 -0
  924. package/templates/platformer/src/anim.c +51 -0
  925. package/templates/platformer/src/art.c +212 -0
  926. package/templates/platformer/src/autopilot.h +30 -0
  927. package/templates/platformer/src/engine.asm +253 -0
  928. package/templates/platformer/src/game.h +248 -0
  929. package/templates/platformer/src/hud.c +90 -0
  930. package/templates/platformer/src/level.c +184 -0
  931. package/templates/platformer/src/main.c +306 -0
  932. package/templates/platformer/src/player.c +268 -0
  933. package/templates/platformer/src/sound.c +42 -0
  934. package/templates/platformer/src/verdict.h +206 -0
  935. package/templates/platformer/src/view.c +331 -0
  936. package/templates/platformer/stage-expect.json +6 -0
  937. package/templates/platformer/tools/drive.py +112 -0
  938. package/templates/platformer/tools/tearcheck.py +229 -0
  939. package/templates/shmup-vertical/.claude/settings.json +17 -0
  940. package/templates/shmup-vertical/.mcp.json +10 -0
  941. package/templates/shmup-vertical/CLAUDE.md +137 -0
  942. package/templates/shmup-vertical/Makefile +131 -0
  943. package/templates/shmup-vertical/PLAN.md +569 -0
  944. package/templates/shmup-vertical/README.md +189 -0
  945. package/templates/shmup-vertical/expect.json +38 -0
  946. package/templates/shmup-vertical/src/bullets.c +158 -0
  947. package/templates/shmup-vertical/src/bullets.h +35 -0
  948. package/templates/shmup-vertical/src/display.c +239 -0
  949. package/templates/shmup-vertical/src/display.h +40 -0
  950. package/templates/shmup-vertical/src/game.h +85 -0
  951. package/templates/shmup-vertical/src/glyph.asm +358 -0
  952. package/templates/shmup-vertical/src/hiscore.c +141 -0
  953. package/templates/shmup-vertical/src/hiscore.h +16 -0
  954. package/templates/shmup-vertical/src/hit.asm +180 -0
  955. package/templates/shmup-vertical/src/hitbox.c +59 -0
  956. package/templates/shmup-vertical/src/hitbox.h +25 -0
  957. package/templates/shmup-vertical/src/kernel.asm +330 -0
  958. package/templates/shmup-vertical/src/level.c +174 -0
  959. package/templates/shmup-vertical/src/level.h +27 -0
  960. package/templates/shmup-vertical/src/main.c +824 -0
  961. package/templates/shmup-vertical/src/mux.asm +321 -0
  962. package/templates/shmup-vertical/src/sound.asm +255 -0
  963. package/templates/shmup-vertical/src/step.asm +169 -0
  964. package/templates/shmup-vertical/src/waves.c +195 -0
  965. package/templates/shmup-vertical/src/waves.h +33 -0
  966. package/templates/shmup-vertical/stage-expect.json +6 -0
  967. package/templates/shmup-vertical/tools/drive.py +152 -0
  968. package/templates/shmup-vertical/tools/joytest.py +159 -0
  969. package/templates/shmup-vertical/tools/meter.py +15 -0
  970. package/templates/shmup-vertical/tools/phases.py +73 -0
@@ -0,0 +1,189 @@
1
+ # shmup-vertical
2
+
3
+ A vertically scrolling shoot-em-up for the stock C64, PAL and NTSC, built
4
+ to be copied and grown into a game. It plays: title, fire to start, three
5
+ lives, game over, back to the title.
6
+
7
+ - A river scrolls down one line a frame, through all eight YSCROLL phases,
8
+ above a fixed score panel.
9
+ - The ship is a multicolour sprite on joystick port 2. Its bolts are
10
+ characters.
11
+ - Enemies arrive in waves set off by how far the river has scrolled. Each
12
+ flies a small path program, which can fire: a dot, also a character,
13
+ falls towards where the ship was. With the ship, up to 13 sprites go
14
+ through a multiplexer onto the 8 hardware sprites.
15
+ - Hits are tested with a box per sprite frame.
16
+ - A three-voice tune plays; shot, explosion and ship-lost effects borrow
17
+ voice 3 and hand it back.
18
+ - The high score is saved to drive 8 and loaded at start; a fresh disk's
19
+ title shows HI 000000. With no drive, the game runs without saving. A
20
+ save that was cut off (a splat file) is scratched and written again.
21
+
22
+ Fire starts a game on the title only after it has been released: hold it
23
+ through GAME OVER and the title waits.
24
+
25
+ Make a project from it in c64-kb with
26
+ `npm run new-project -- shmup-vertical <dir>`, then `make run`.
27
+
28
+ ## Files
29
+
30
+ | File | What it holds |
31
+ |---|---|
32
+ | `src/main.c` | States (title, play, game over), the ship, the frame loop, the autopilot scripts and their verdict |
33
+ | `src/level.c` | The river map and the downward scroll through two screens |
34
+ | `src/waves.c` | The wave list, the path bytecode (MOVE, LOOP, FIRE, END), the pool of 12 enemies |
35
+ | `src/bullets.c` | The ship's bolts and the enemies' dots: firing and the rules |
36
+ | `src/hitbox.c` | The ship's box; the hits turned into events |
37
+ | `src/display.c` | Character set, sprite art (as text), the score panel |
38
+ | `src/hiscore.c` | The HISCORE file on drive 8 |
39
+ | `src/game.h` | Memory map, the kernel's variables as C names, shared state |
40
+ | `src/kernel.asm` | The raster IRQ chain, the panel split, the three-row copy (KickAssembler) |
41
+ | `src/mux.asm` | The sprite multiplexer: sort, build, zone IRQs |
42
+ | `src/sound.asm` | The music player with effects inside it, and the tune |
43
+ | `src/glyph.asm` | The character bullets: the bolts' and the dots' moves and draws, the list, the erase, the restore check |
44
+ | `src/hit.asm` | The dots against the ship; every enemy's box against the ship's and the bolts' |
45
+ | `src/step.asm` | The path bytecode run for every enemy, explosions, one path step for every flying enemy |
46
+ | `tools/phases.py` | `make phases`: the panel at every YSCROLL phase against the graded one |
47
+ | `tools/meter.py` | `make stage`: reads the meter off the staged run's shots |
48
+ | `tools/drive.py` | Plays the `make joy` build headless over VICE's binary monitor |
49
+ | `tools/joytest.py` | `make joytest`: games played on PAL and NTSC to GAME OVER, graded on lost frames, and a reboot that must show the saved HI; `make longplay`: long games with a ship that is never lost |
50
+ | `PLAN.md` | The plan, with the c64-kb tool output it was built from |
51
+ | `expect.json`, `stage-expect.json` | What the graded and the staged screenshots must show |
52
+
53
+ C does the game; KickAssembler does what needs exact cycles, no zero page,
54
+ or runs for every enemy or bullet every frame. The harness assembles
55
+ `kernel.asm` (which imports the other `.asm` files) to a blob at `$0880`
56
+ and writes `build/asm.h`, so C calls it as `ASM_<LABEL>`.
57
+
58
+ ## How a frame runs
59
+
60
+ The frame IRQ on line 252 sets the playfield's registers, shows the first
61
+ eight sprites and tells C a frame began. C then restores the bullet cells,
62
+ checks them against the map (AUTOPILOT builds), and moves and draws the
63
+ bolts and dots before the beam reaches them. It tests hits, moves the ship,
64
+ runs the waves, hands the actors to the multiplexer, draws three rows of
65
+ the hidden screen and sets next frame's scroll. Zone IRQs reuse sprites down
66
+ the screen. The split IRQ on line 212 switches to the panel on line 215 and
67
+ plays the music.
68
+
69
+ ## Measured
70
+
71
+ VICE x64sc 3.10, the harness meter. The graded script's 240 play frames:
72
+
73
+ | Model | Worst frame | Typical (median) | Frame |
74
+ |---|---|---|---|
75
+ | PAL | 11,681 cycles | 8,374 | 19,656 |
76
+ | NTSC | 11,875 cycles | 8,733 | 17,095 |
77
+
78
+ `make stage` plays a script that puts 12 enemies, bolts, dots and a kill in
79
+ the same frames, and meters play frames 150-399. The worst of a sweep of its
80
+ timing over 16 variants is the variant it runs:
81
+
82
+ | Model | `make stage` worst | Typical | Frame |
83
+ |---|---|---|---|
84
+ | PAL | 15,064 cycles | 9,280 | 19,656 |
85
+ | NTSC | 15,237 cycles | 9,967 | 17,095 |
86
+
87
+ The figures hold the C loop's frame and every IRQ, with badlines and sprite
88
+ DMA. They leave out the loop's head (the wait, the scroll hand-over, the
89
+ stick), the meter's own bookkeeping and about 45 cycles of entry and exit
90
+ per IRQ outside the C loop's bracket. So a frame can be lost below 17,095:
91
+ at 7974a7a the staged run lost one on NTSC with its worst at 16,122.
92
+
93
+ The staged worst was not the heaviest frame play reaches. With fire held
94
+ and the ship swept, NTSC play lost frames at 7974a7a: in the review's
95
+ drive, 6 of 15 games, at play frame 465 in 5 of them; in a build of it
96
+ with `-dWORKEND=1`, 4 of 4 games, at play frames 282-321 (the row-32 and
97
+ row-40 swoops) and 454-477 (the row-48 saucers and the row-56 darts on the
98
+ screen together), with bolts, dots and kills in the same frames. The staged
99
+ run stops recording at play frame 399, before the second stretch.
100
+ `-dWORKEND=1` reads the raster when a frame's work ends, in lines after the
101
+ frame IRQ's line 252: the staged run's latest end on NTSC is now line 249
102
+ of 263, and play's is 256, at play frames 464-472.
103
+
104
+ Cuts to the work brought play back inside the NTSC frame; PLAN.md lists
105
+ them with their figures. The largest: the bolts' loop, the paths and the
106
+ dots' test against the ship moved to KickAssembler; the enemy box scan
107
+ skips enemies whose lines miss every box and walks only the boxes that are
108
+ on; the multiplexer's build loop keeps its write place in a register.
109
+ `make joytest` now plays 16 games a model with fire held and a sweep, and
110
+ fails on any lost frame: 16 of 16 NTSC games lost none. `make longplay`
111
+ plays 4 games a model for 40 s of warp with a ship that is never lost
112
+ (about 44,000 play frames each on NTSC, through the level's later loops):
113
+ none lost a frame. The latest end over those runs was line 256 of 263 on
114
+ NTSC (7 lines, about 450 cycles, to spare) and 243 of 312 on PAL.
115
+
116
+ A frame far past the frame shows in the meter as about 65,524: CIA2 timer A
117
+ counts down from 65,535 and wraps. A reading that high is a wrap, not the
118
+ frame's size; count the lost frames instead (`OVERRUNS` in the verdict,
119
+ `LOST_FRAMES` at `$02FD` in any build).
120
+
121
+ The meter's readout is printed only after the freeze. Printed every frame,
122
+ it cost up to 3,404 cycles outside the bracket and made the autopilot build
123
+ drop frames that the game itself does not. The self-check of the bullet
124
+ cells (about 250 cycles, and the map code each draw notes for it) runs in
125
+ AUTOPILOT builds only and is inside the figures.
126
+
127
+ The bullet draw must end before the beam reaches the cells it changes. The
128
+ smallest margin measured (`-dDRAWEND=1`, NTSC) was 19 lines for a dot in
129
+ the graded run and 25 in the staged run; for the bolts, read after all of
130
+ them were drawn, 26 in both. On PAL the bolts were drawn before line 0 and
131
+ the dots had 69 lines or more.
132
+
133
+ `make phases` (part of `make check`) freezes the game on each of the eight
134
+ YSCROLL phases and wants the panel identical to the graded one on both
135
+ models: a bad entry in the split's delay table fails it. More in PLAN.md.
136
+
137
+ ## Next steps
138
+
139
+ 1. **A boss.** Several sprites at fixed offsets from one origin, moved as
140
+ one, entered as consecutive actors of the multiplexer. Technique
141
+ `multi_sprite_object`, recipe `oscar64-multi-sprite-object`.
142
+ 2. **Difficulty.** Replace the spacing shift in `spawner()` with level
143
+ tables read from data: speeds, counts, spacing and fire per loop, held
144
+ at the last row. Technique `difficulty_ramp_tables`, recipe
145
+ `oscar64-difficulty-tables`.
146
+ 3. **Power-ups.** A pickup is one more actor with its own box group against
147
+ the ship only: `hit.asm`'s `hit_scan` tests its boxes against enemies,
148
+ so give pickups their own loop beside `dot_scan` there. Technique
149
+ `per_frame_hitbox`, recipe `oscar64-per-frame-hitbox`.
150
+
151
+ The level is the `bank` table in `level.c` (river widths every 4 map rows)
152
+ and the `wave` table in `waves.c` (map row, path, type, count, spacing,
153
+ formation). Paths are the byte arrays above them; `P_FIRE` fires a dot when
154
+ the enemy is between sprite Y 72 and 140 (the window that keeps the draw
155
+ ahead of the beam). Re-run `make stage` after changing either.
156
+
157
+ ## Left out on purpose
158
+
159
+ - Colour per map cell: colour RAM cannot be double-buffered, so every
160
+ playfield cell shares one colour RAM value and the map is 4 colours.
161
+ - Sprites below line 208: a sprite on line 214 breaks the panel split
162
+ (measured); 209-213 were clean, and MAX_SY keeps 5 lines of margin.
163
+ - Enemy fire from above sprite Y 72 or below 140; power-ups, a boss, a
164
+ high-score table with names.
165
+ - Keyboard and a second joystick; RESTORE does nothing.
166
+
167
+ ## Checks
168
+
169
+ `make shot check` runs the autopilot on PAL and NTSC with a fresh copy of
170
+ the disk on drive 8. The script shoots darts and saucers, is hit by a dart's
171
+ dot, fires through a parade of ten enemies, then stops; the program freezes
172
+ on YSCROLL 3, saves and reloads the high score and grades 18 facts,
173
+ printing the number of the first that fails. `expect.json` then checks the
174
+ verdict, the text, the meter, the ship and all ten parade sprites, the
175
+ river's banks at 30 rows scrolled, the split and the panel. `make selftest`
176
+ starts the ship 16 pixels to the right and must fail. `make stage`, `make
177
+ joytest` and `make longplay` are this starter's proof targets
178
+ (VERIFY_TARGETS), which `npm run verify:templates -- --selftest` runs too. `make claims` checks
179
+ every store the program makes against what the Makefile declares. `make
180
+ joy` builds the normal game reading its stick from `$02FE`, for
181
+ `python3 tools/drive.py build/shmup-vertical-joy.prg "until:PUSH FIRE" tap:fire ...`
182
+ (it takes a free monitor port unless DRIVE_PORT names one).
183
+
184
+ Measuring switches, none in a release build: `-dPROFILE=1` (each step of the
185
+ heaviest frame), `-dDRAWEND=1` (the bullet draw's margin to the beam),
186
+ `-dWORKEND=1` (how late in the frame the work ended, at `$0370`; `=2` adds
187
+ each step), `-dEVENTLOG=1` (each kill, hit and lost frame with its frame),
188
+ `-dGOD=1` (the ship is never lost), `-dLOOP_TEST=1` (play to GAME OVER and
189
+ back), `-dFREEZE_Y=0..7` (freeze on another phase).
@@ -0,0 +1,38 @@
1
+ {
2
+ "checks": [
3
+ { "name": "own verdict (border)", "type": "verdict" },
4
+ { "name": "verdict line", "type": "text", "row": 9, "col": 1, "text": "RESULT 01 PASS" },
5
+ { "name": "score, kills, lives", "type": "text", "row": 10, "col": 1, "text": "SCORE 000450 KILLS 05 LIVES 2" },
6
+ { "name": "sprites shown, waves, ship, kills by type", "type": "text", "row": 11, "col": 1, "text": "SHOWN 11 WAVES 04 SHIP 060 176 K 1 4 0" },
7
+ { "name": "enemy dots fired, dots that hit the ship, frames that overran", "type": "text", "row": 12, "col": 1, "text": "FIRED 10 HIT 1 OVERRUNS 00" },
8
+ { "name": "frame meter, the script's 240 play frames", "type": "meter", "row": 13, "col": 10, "frames": 240 },
9
+
10
+ { "name": "ship where the script leaves it (X 120, Y 176): its light blue", "type": "sprite", "colour": 14, "vic_x": 124, "line": 180, "width": 16, "height": 12 },
11
+ { "name": "parade bug A1 (X 60, Y 72)", "type": "sprite", "colour": 4, "vic_x": 64, "line": 76, "width": 16, "height": 9 },
12
+ { "name": "parade bug A2 (X 108, Y 72)", "type": "sprite", "colour": 4, "vic_x": 112, "line": 76, "width": 16, "height": 9 },
13
+ { "name": "parade bug A3 (X 156, Y 72)", "type": "sprite", "colour": 4, "vic_x": 160, "line": 76, "width": 16, "height": 9 },
14
+ { "name": "parade bug A4 (X 204, Y 72)", "type": "sprite", "colour": 4, "vic_x": 208, "line": 76, "width": 16, "height": 9 },
15
+ { "name": "parade bug A5 (X 252, Y 72)", "type": "sprite", "colour": 4, "vic_x": 256, "line": 76, "width": 16, "height": 9 },
16
+ { "name": "parade bug B1 (X 60, Y 102)", "type": "sprite", "colour": 4, "vic_x": 64, "line": 106, "width": 16, "height": 9 },
17
+ { "name": "parade bug B2 (X 108, Y 102)", "type": "sprite", "colour": 4, "vic_x": 112, "line": 106, "width": 16, "height": 9 },
18
+ { "name": "parade bug B3 (X 156, Y 102)", "type": "sprite", "colour": 4, "vic_x": 160, "line": 106, "width": 16, "height": 9 },
19
+ { "name": "parade bug B4 (X 204, Y 102)", "type": "sprite", "colour": 4, "vic_x": 208, "line": 106, "width": 16, "height": 9 },
20
+ { "name": "parade bug B5 (X 252, Y 102)", "type": "sprite", "colour": 4, "vic_x": 256, "line": 106, "width": 16, "height": 9 },
21
+
22
+ { "name": "scrolled 30 rows: map row 36's right bank edge in screen row 14, column 25 (sand)", "type": "pixel", "vic_x": 226, "line": 163, "colour": 7 },
23
+ { "name": "... water left of that edge", "type": "pixel", "vic_x": 224, "line": 163, "colour": 6 },
24
+ { "name": "... earth right of it", "type": "pixel", "vic_x": 229, "line": 163, "colour": 9 },
25
+ { "name": "... map row 35 in screen row 15 is water in that column", "type": "pixel", "vic_x": 226, "line": 171, "colour": 6 },
26
+ { "name": "... map row 36's left bank edge in column 4 (sand)", "type": "pixel", "vic_x": 60, "line": 163, "colour": 7 },
27
+
28
+ { "name": "split: line 214 is still playfield (water in column 25)", "type": "pixel", "vic_x": 224, "line": 214, "colour": 6 },
29
+ { "name": "split: line 216 is the panel's grey", "type": "pixel", "vic_x": 224, "line": 216, "colour": 11 },
30
+ { "name": "panel rule, light grey, 40 columns (lines 218-219)", "type": "rect", "colour": 15, "vic_x": 24, "line": 218, "width": 320, "height": 2 },
31
+ { "name": "panel background, a blank row, 40 columns", "type": "rect", "colour": 11, "vic_x": 24, "line": 231, "width": 320, "height": 8 },
32
+ { "name": "two lives left: two cyan ships", "type": "rect", "colour": 3, "vic_x": 88, "line": 243, "width": 16, "height": 1 },
33
+ { "name": "no third life", "type": "rect", "colour": 11, "vic_x": 104, "line": 243, "width": 8, "height": 1 },
34
+ { "name": "no sprite under the panel: the panel's lines match on both models", "type": "same", "area": { "vic_x": 24, "line": 215, "width": 320, "height": 36 } },
35
+ { "name": "playfield rows 0-12 the same on both models", "type": "same", "cells": [0, 0, 12, 39] },
36
+ { "name": "playfield rows 14-20 the same on both models", "type": "same", "cells": [14, 0, 20, 39] }
37
+ ]
38
+ }
@@ -0,0 +1,158 @@
1
+ // bullets.c: the ship's bolts and the enemies' bullets as characters, from
2
+ // c64-kb's oscar64/char-bullets recipe (technique char_bullets). Each bullet
3
+ // owns one reserved glyph. To draw it: save the screen code under it, copy
4
+ // that code's glyph into the reserved glyph, OR the shot into it, write the
5
+ // reserved code. Every bullet drawn in a frame goes on one list, bolts
6
+ // first; restoring walks the list backwards, so bullets sharing a cell
7
+ // unwind. The list, the moves and the draws are glyph.asm's (bb_run for the
8
+ // bolts, eb_run for the dots, cb_draw, cb_erase, cb_check); this file fires
9
+ // the bullets and holds the rules.
10
+ //
11
+ // Bolts: 1 pixel pair wide, rows 2-5 of their cell. A bolt moves up 7 lines
12
+ // a frame while the playfield moves down 1, so it stays on rows 2-5 of
13
+ // whatever cell it is in: b_line - 50 - YSCROLL = 8 * row every frame, the
14
+ // carry frame included (YSCROLL 7 to 0, same row). b_line is the raster line
15
+ // of the bolt's top row (row 2 of the cell, whose top is 48 + YSCROLL + 8 *
16
+ // row). A bolt never straddles two cells.
17
+ //
18
+ // Enemy bullets: a 2 x 2 dot that falls 2 lines a frame and drifts one
19
+ // pixel pair a frame towards where the ship was, snapped to an even glyph
20
+ // row so it never crosses a cell edge. An enemy fires only between sprite Y 72 and
21
+ // 140, so a bullet starts on line 84 or lower, in a cell that starts on line
22
+ // 77 or lower. Bolts are drawn first; the draw must end before the beam
23
+ // reaches the first cell it changes (the measured end is in PLAN.md).
24
+ //
25
+ // Colour: every playfield cell is multicolour with colour RAM $0F, so the
26
+ // shots' pairs %11 draw in yellow and colour RAM is never touched.
27
+ #include "bullets.h"
28
+ #include "level.h"
29
+ #include "display.h"
30
+ #include "hitbox.h"
31
+
32
+ #define EB_TOP 72 // enemies fire from sprite Y 72 ...
33
+ #define EB_BOTTOM 140 // ... to 140
34
+ #define eb_dx ((signed char *)ASM_EB_DX)
35
+
36
+ unsigned eb_fired;
37
+
38
+ #ifdef DRAWEND
39
+ // Measuring only (-dDRAWEND=1): the smallest number of lines between the
40
+ // raster just after a cell was written and the first line of that cell, at
41
+ // the word it is given ($0364 bolts, $0366 dots; starts at $7FFF when main
42
+ // sets it). Negative: the beam had reached the cell first. The raster is 0
43
+ // while it is still in the lower border or has not reached line 0.
44
+ char drawend_on; // main.c: 1 in a frame that starts on time
45
+
46
+ static void drawend_margin(unsigned at, char top)
47
+ {
48
+ if (!drawend_on)
49
+ return;
50
+ char l = vic.raster;
51
+ if ((vic.ctrl1 & 0x80) || l >= 250)
52
+ return; // not yet past line 0: no risk
53
+ int m = (int)top - l;
54
+ volatile int *d = (volatile int *)at;
55
+ if (m < *d)
56
+ *d = m;
57
+ }
58
+ #endif
59
+
60
+ void bullets_reset(void)
61
+ {
62
+ for (char i = 0; i < NB; i++) {
63
+ b_live[i] = 0;
64
+ box_off(BOX_SHOT + i);
65
+ }
66
+ for (char j = 0; j < NEB; j++)
67
+ eb_live[j] = 0;
68
+ __asm { jsr ASM_CB_BEGIN } // an empty draw list
69
+ K_BYTE(ASM_CB_KEEP) = AUTOPILOT; // bullets_restored needs the map's codes
70
+ }
71
+
72
+ // The bolt starts in the cell row above the ship's nose, placed as if drawn
73
+ // this frame: the next frame's move keeps the invariant. Returns false when
74
+ // every bolt is in flight or the ship is too high.
75
+ bool bullet_fire(char hx, char ship_y)
76
+ {
77
+ if (ship_y < 52 + 16 + cur_y)
78
+ return false;
79
+ char r = ((char)(ship_y - 52 - cur_y) >> 3) - 1;
80
+ for (char i = 0; i < NB; i++) {
81
+ if (!b_live[i]) {
82
+ b_live[i] = 1;
83
+ b_hx[i] = hx;
84
+ b_line[i] = 50 + cur_y + 8 * r;
85
+ return true;
86
+ }
87
+ }
88
+ return false;
89
+ }
90
+
91
+ // A dot from the middle of an enemy sprite at (hx, sy), drifting towards
92
+ // target_hx. Outside the fire window, or with every slot in flight, nothing.
93
+ void enemy_bullet_fire(char hx, char sy, char target_hx)
94
+ {
95
+ if (sy < EB_TOP || sy > EB_BOTTOM)
96
+ return;
97
+ char x = hx + 6;
98
+ for (char j = 0; j < NEB; j++) {
99
+ if (!eb_live[j]) {
100
+ eb_live[j] = 1;
101
+ eb_hx[j] = x;
102
+ eb_line[j] = sy + 12;
103
+ eb_dx[j] = target_hx + 2 < x ? -1 : target_hx > x + 2 ? 1 : 0;
104
+ eb_fired++;
105
+ return;
106
+ }
107
+ }
108
+ }
109
+
110
+ void bullet_kill(char i)
111
+ {
112
+ b_live[i] = 0;
113
+ box_off(BOX_SHOT + i);
114
+ }
115
+
116
+ void enemy_bullet_kill(char j)
117
+ {
118
+ eb_live[j] = 0;
119
+ }
120
+
121
+ void bullets_erase(void)
122
+ {
123
+ __asm { jsr ASM_CB_ERASE }
124
+ }
125
+
126
+ // Every cell the last draw changed holds the map's code again. Reads the
127
+ // screen back, so an erase that skipped a cell, or ran in the wrong order,
128
+ // leaves a reserved code there and fails.
129
+ bool bullets_restored(void)
130
+ {
131
+ __asm { jsr ASM_CB_CHECK }
132
+ return !K_BYTE(ASM_CB_FAULT);
133
+ }
134
+
135
+ void bullets_move_draw(void)
136
+ {
137
+ K_BYTE(ASM_CB_FRONT) = cur_front;
138
+ K_BYTE(ASM_CB_TOP) = cur_row + 20;
139
+ K_BYTE(ASM_CB_Y) = cur_y; // the YSCROLL showing
140
+ __asm {
141
+ jsr ASM_CB_BEGIN
142
+ jsr ASM_BB_RUN // the bolts first
143
+ }
144
+ #ifdef DRAWEND
145
+ // Read after all the bolts (then all the dots), so a margin here is
146
+ // smaller than the one just after its own cell was written: a lower
147
+ // bound.
148
+ for (char i = 0; i < NB; i++)
149
+ if (b_live[i])
150
+ drawend_margin(0x0364, b_line[i] - 2); // the bolt's cell starts 2 lines up
151
+ #endif
152
+ __asm { jsr ASM_EB_RUN } // then the enemies' dots
153
+ #ifdef DRAWEND
154
+ for (char j = 0; j < NEB; j++)
155
+ if (eb_live[j])
156
+ drawend_margin(0x0366, eb_line[j] - ((char)(eb_line[j] - 48 - cur_y) & 7));
157
+ #endif
158
+ }
@@ -0,0 +1,35 @@
1
+ // bullets.h: the ship's bolts and the enemies' bullets, all drawn as
2
+ // characters (char_bullets).
3
+ #ifndef BULLETS_H
4
+ #define BULLETS_H
5
+
6
+ #include "game.h"
7
+
8
+ // The ship's bolts, glyphs $F8-$FB. At most 3 fly at once: one shot per 7
9
+ // frames (P_COOL 6), and a bolt from the lowest ship (Y 180) lives 16 frames
10
+ // (arithmetic). The fourth is room for a faster gun.
11
+ #define NB 4
12
+ // The enemies' bullets, glyphs $F2-$F7.
13
+ #define NEB 6
14
+
15
+ // The bolts and the dots live in glyph.asm, which moves and draws them.
16
+ #define b_live ((char *)ASM_BB_LIVE)
17
+ #define b_hx ((char *)ASM_BB_HX) // half X of the bolt's pixel pair
18
+ #define b_line ((char *)ASM_BB_LINE) // raster line of the bolt's top row
19
+ #define eb_live ((char *)ASM_EB_LIVE)
20
+ #define eb_hx ((char *)ASM_EB_HX) // half X of the dot's pixel pair
21
+ #define eb_line ((char *)ASM_EB_LINE) // raster line of the dot's top row
22
+ extern unsigned eb_fired; // enemy bullets fired this game (play_enter clears it)
23
+
24
+ void bullets_reset(void);
25
+ bool bullet_fire(char hx, char ship_y); // from a ship whose sprite Y is ship_y
26
+ void enemy_bullet_fire(char hx, char sy, char target_hx); // from an enemy sprite
27
+ void bullets_erase(void); // restore every drawn cell, reverse order
28
+ void bullets_move_draw(void); // move, draw into the showing screen
29
+ void bullet_kill(char i);
30
+ void enemy_bullet_kill(char j);
31
+ bool bullets_restored(void); // after bullets_erase: every cell is the map's
32
+
33
+ #pragma compile("bullets.c")
34
+
35
+ #endif
@@ -0,0 +1,239 @@
1
+ // display.c: the character set, sprite shapes, text and the score panel.
2
+ // All art is original. Glyphs and sprites are written as strings of
3
+ // multicolour pixel pairs, one digit per pair: 0 background, 1 $D022 or
4
+ // $D025, 2 $D023 or the sprite's own colour, 3 colour RAM or $D026.
5
+ #include "display.h"
6
+ #include <c64/memmap.h>
7
+ #include <string.h>
8
+
9
+ // ---- playfield glyphs: 8 rows of 4 pairs each ------------------------------
10
+ static const char * const glyph_art[7] = {
11
+ "11111121111111112111111111121111", // G_LAND: earth, green specks
12
+ "22222212222222222122222222212222", // G_GRASS
13
+ "23323322223223222322222122112112", // G_TREE: canopy, trunk
14
+ "11111331331331311311111111111111", // G_ROCK
15
+ "11301130111311131130113013001130", // G_EDGE_L: land left, sand, water
16
+ "03110311311131110311031100310311", // G_EDGE_R: water, sand, land right
17
+ "00000000000000000000000300300000", // G_SPARKLE: light on the water
18
+ };
19
+
20
+ static const char life_glyph[8] = { 0x18, 0x3c, 0x3c, 0x7e, 0xff, 0xdb, 0x18, 0x00 };
21
+ static const char rule_glyph[8] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00 };
22
+
23
+ // ---- sprites: 21 rows of 12 pairs -----------------------------------------
24
+ static const char * const sprite_art[SPR_FRAMES][21] = {
25
+ { // F_SHIP
26
+ "............", ".....33.....", ".....33.....", "....3223....",
27
+ "....2332....", "....2222....", "...122221...", "...122221...",
28
+ "..11222211..", ".1122332211.", "112223322211", "112222222211",
29
+ "11.222222.11", "1..122221..1", "...12..21...", "...3....3...",
30
+ "............", "............", "............", "............",
31
+ "............" },
32
+ { // F_DART
33
+ "............", "..2......2..", "..22....22..", "..222..222..",
34
+ "...222222...", "...233332...", "....2332....", "....2112....",
35
+ ".....22.....", ".....22.....", ".....11.....", "............",
36
+ "............", "............", "............", "............",
37
+ "............", "............", "............", "............",
38
+ "............" },
39
+ { // F_SAUCER
40
+ "............", "....3333....", "...322223...", "..22222222..",
41
+ ".2212121212.", "222222222222", ".1111111111.", "..1.1..1.1..",
42
+ "............", "............", "............", "............",
43
+ "............", "............", "............", "............",
44
+ "............", "............", "............", "............",
45
+ "............" },
46
+ { // F_BUG
47
+ "............", "...1....1...", "....1..1....", "...222222...",
48
+ "..22322322..", "..22222222..", ".1222112221.", "1.22211222.1",
49
+ "..22222222..", ".1.222222.1.", "1...2222...1", ".....22.....",
50
+ "............", "............", "............", "............",
51
+ "............", "............", "............", "............",
52
+ "............" },
53
+ { // F_BOOM1
54
+ "............", "............", ".....3......", "...3.2.3....",
55
+ "....222.....", "..32232223..", "....222.....", "...3.2.3....",
56
+ ".....3......", "............", "............", "............",
57
+ "............", "............", "............", "............",
58
+ "............", "............", "............", "............",
59
+ "............" },
60
+ { // F_BOOM2
61
+ "............", "..3...3...3.", "...2..2..2..", "....1.1.1...",
62
+ ".3..22222..3", "..2.2.3.2.2.", "321.23332.12", "..2.2.3.2.2.",
63
+ ".3..22222..3", "....1.1.1...", "...2..2..2..", "..3...3...3.",
64
+ "............", "............", "............", "............",
65
+ "............", "............", "............", "............",
66
+ "............" },
67
+ };
68
+
69
+ // Four pair digits to one byte.
70
+ static char pairs(const char *s)
71
+ {
72
+ char b = 0;
73
+ for (char i = 0; i < 4; i++) {
74
+ char d = s[i];
75
+ b = (b << 2) | (d == '.' ? 0 : d - '0');
76
+ }
77
+ return b;
78
+ }
79
+
80
+ static void make_charset(void)
81
+ {
82
+ __asm { sei }
83
+ mmap_set(MMAP_CHAR_ROM);
84
+ memcpy(CHARSET, (char *)0xd000, 64 * 8); // letters, digits, punctuation
85
+ mmap_set(MMAP_NO_ROM); // I/O back; the kernel keeps $01 = $35
86
+ memset(CHARSET + 64 * 8, 0, 2048 - 64 * 8);
87
+ for (char g = 0; g < 7; g++) {
88
+ char *d = CHARSET + (G_LAND + g) * 8;
89
+ for (char r = 0; r < 8; r++)
90
+ d[r] = pairs(glyph_art[g] + 4 * r);
91
+ }
92
+ memcpy(CHARSET + G_LIFE * 8, life_glyph, 8);
93
+ memcpy(CHARSET + G_RULE * 8, rule_glyph, 8);
94
+ // Shots over open water need no merge (glyph.asm): a dot in each pixel
95
+ // pair on each even row pair, a bolt in each pair on rows 2-5, in %11.
96
+ for (char p = 0; p < 4; p++) {
97
+ char m = 0xc0 >> (2 * p);
98
+ for (char r = 0; r < 4; r++) {
99
+ char *d = CHARSET + (G_DOTS + 4 * p + r) * 8;
100
+ d[2 * r] = d[2 * r + 1] = m;
101
+ }
102
+ char *b = CHARSET + (G_BOLTS + p) * 8;
103
+ b[2] = b[3] = b[4] = b[5] = m;
104
+ }
105
+ }
106
+
107
+ static void make_sprites(void)
108
+ {
109
+ for (char f = 0; f < SPR_FRAMES; f++) {
110
+ char *d = SPRITES + 64 * f;
111
+ for (char r = 0; r < 21; r++) {
112
+ const char *s = sprite_art[f][r];
113
+ d[0] = pairs(s);
114
+ d[1] = pairs(s + 4);
115
+ d[2] = pairs(s + 8);
116
+ d += 3;
117
+ }
118
+ }
119
+ }
120
+
121
+ void display_init(void)
122
+ {
123
+ make_charset();
124
+ make_sprites();
125
+ cia2.pra = (cia2.pra & 0xfc) | 0x01; // VIC bank 2: $8000-$BFFF
126
+ vic.color_border = VCOL_BLACK;
127
+ vic.color_back = PF_BG_COL;
128
+ vic.color_back1 = PF_MC1;
129
+ vic.color_back2 = PF_MC2;
130
+ vic.spr_multi = 0xff;
131
+ vic.spr_expand_x = 0;
132
+ vic.spr_expand_y = 0;
133
+ vic.spr_priority = 0;
134
+ vic.spr_mcolor0 = VCOL_DARK_GREY;
135
+ vic.spr_mcolor1 = VCOL_WHITE;
136
+ memset(PF0, G_WATER, 1000);
137
+ memset(PF1, G_WATER, 1000);
138
+ memset(COLOUR, PF_CRAM, 21 * 40); // playfield rows 0-20
139
+ memset(COLOUR + 21 * 40, VCOL_WHITE, 4 * 40); // panel rows 21-24
140
+ panel_draw();
141
+ }
142
+
143
+ // ASCII upper case, digits and punctuation to screen codes.
144
+ void put_text(char *screen, char row, char col, const char *s)
145
+ {
146
+ char *p = screen + 40 * row + col;
147
+ while (*s) {
148
+ char c = *s++;
149
+ *p++ = (c >= 'A' && c <= 'Z') ? c - 64 : c;
150
+ }
151
+ }
152
+
153
+ void text_colour(char row, char col, char n, char colour)
154
+ {
155
+ memset(COLOUR + 40 * row + col, colour, n);
156
+ }
157
+
158
+ static const unsigned pow10[5] = { 1, 10, 100, 1000, 10000 };
159
+
160
+ // Digits by repeated subtraction: no 16-bit division, a few hundred cycles.
161
+ void put_dec(char *p, unsigned v, char digits)
162
+ {
163
+ for (char i = digits; i > 0; i--) {
164
+ unsigned q = pow10[i - 1];
165
+ char d = '0';
166
+ while (v >= q) {
167
+ v -= q;
168
+ d++;
169
+ }
170
+ *p++ = d;
171
+ }
172
+ }
173
+
174
+ // ---- the panel: rows 20-24 of the screen at $8800 ------------------------------
175
+ // Row 20 is a rule, drawn in colour RAM row 20's colour, which the playfield
176
+ // shares (pitfall-free only because the playfield's value, $0F, reads as
177
+ // light grey in hires). Rows 21-23 hold text; row 24 is cut by the border.
178
+ #define SCORE_AT (PANEL + 21 * 40 + 8) // five digits; the sixth is always 0
179
+ #define HI_AT (PANEL + 21 * 40 + 26)
180
+ static char shown_lives = 0xff;
181
+ // The score's digits change once a frame, in panel_update, however many
182
+ // kills the frame had: the frames with most kills are the heaviest.
183
+ static char score_due;
184
+
185
+ void panel_draw(void)
186
+ {
187
+ memset(PANEL, G_WATER, 1000);
188
+ memset(PANEL + 20 * 40, G_RULE, 40);
189
+ put_text(PANEL, 21, 2, "SCORE 000000 HI 000000");
190
+ put_text(PANEL, 23, 2, "LIVES");
191
+ put_dec(SCORE_AT, score, 5);
192
+ put_dec(HI_AT, hiscore, 5);
193
+ score_due = 0;
194
+ shown_lives = 0xff;
195
+ panel_update();
196
+ }
197
+
198
+ // Adds to the score's digits on the panel one digit at a time, so a kill
199
+ // costs a few dozen cycles, not a 16-bit conversion. Call after score and
200
+ // hiscore have been updated.
201
+ static void add_digits(char tens)
202
+ {
203
+ char *p = SCORE_AT + 4;
204
+ char c = tens;
205
+ for (;;) {
206
+ char d = *p - '0' + c;
207
+ c = 0;
208
+ while (d >= 10) {
209
+ d -= 10;
210
+ c++;
211
+ }
212
+ *p = '0' + d;
213
+ if (!c || p == SCORE_AT)
214
+ break;
215
+ p--;
216
+ }
217
+ if (score == hiscore)
218
+ memcpy(HI_AT, SCORE_AT, 5);
219
+ }
220
+
221
+ void panel_add(char tens)
222
+ {
223
+ score_due += tens;
224
+ }
225
+
226
+ void panel_update(void)
227
+ {
228
+ if (score_due) {
229
+ add_digits(score_due);
230
+ score_due = 0;
231
+ }
232
+ if (lives != shown_lives) {
233
+ for (char i = 0; i < 5; i++) {
234
+ PANEL[23 * 40 + 8 + i] = i < lives ? G_LIFE : G_WATER;
235
+ COLOUR[23 * 40 + 8 + i] = VCOL_CYAN;
236
+ }
237
+ shown_lives = lives;
238
+ }
239
+ }