@lewismoten/gamemaker-sandbox-tools 3.1.0 → 3.4.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 (343) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/NOTICE.md +105 -3
  3. package/README.md +301 -15
  4. package/dist/audio-files.js +82 -0
  5. package/dist/audio.js +23 -138
  6. package/dist/block-merge.js +43 -0
  7. package/dist/color-reduce.js +44 -0
  8. package/dist/colors.js +87 -0
  9. package/dist/delta.js +75 -0
  10. package/dist/disk-diff.js +220 -0
  11. package/dist/drawing.js +83 -869
  12. package/dist/embroidery/compile.js +85 -0
  13. package/dist/embroidery/dst.js +79 -0
  14. package/dist/embroidery/exp.js +26 -0
  15. package/dist/embroidery/fill.js +49 -0
  16. package/dist/embroidery/geom.js +82 -0
  17. package/dist/embroidery/pes.js +79 -0
  18. package/dist/embroidery/satin.js +29 -0
  19. package/dist/embroidery/simulate.js +30 -0
  20. package/dist/embroidery/strokeFont.js +253 -0
  21. package/dist/embroidery/svg.js +24 -0
  22. package/dist/embroidery/types.js +13 -0
  23. package/dist/embroidery/units.js +26 -0
  24. package/dist/embroidery/validate.js +15 -0
  25. package/dist/formats/blocks.js +1 -103
  26. package/dist/formats/character.js +1 -83
  27. package/dist/formats/cmf.js +1 -37
  28. package/dist/formats/fli.js +1 -296
  29. package/dist/formats/fliLimits.js +1 -54
  30. package/dist/formats/game.js +1 -193
  31. package/dist/formats/gif.js +1 -125
  32. package/dist/formats/graphicScripts.js +1 -44
  33. package/dist/formats/map.js +1 -38
  34. package/dist/formats/monster.js +1 -69
  35. package/dist/formats/palette.js +1 -58
  36. package/dist/formats/recording.js +1 -17
  37. package/dist/formats/sound.js +1 -44
  38. package/dist/formats/voc.js +1 -303
  39. package/dist/gif-shrink.js +56 -0
  40. package/dist/image/png.js +42 -0
  41. package/dist/images.js +81 -43
  42. package/dist/kit/actors.js +19 -0
  43. package/dist/kit/align.js +204 -0
  44. package/dist/kit/blit.js +45 -0
  45. package/dist/kit/blockRoles.js +97 -0
  46. package/dist/kit/clips.js +40 -0
  47. package/dist/kit/coverPaint.js +18 -0
  48. package/dist/kit/disk.js +76 -0
  49. package/dist/kit/fadeOut.js +13 -0
  50. package/dist/kit/fliClips.js +133 -0
  51. package/dist/kit/fliShrink.js +277 -0
  52. package/dist/kit/gameSim.js +235 -0
  53. package/dist/kit/hopBot.js +142 -0
  54. package/dist/kit/levelGen.js +1423 -0
  55. package/dist/kit/levelGrid.js +33 -0
  56. package/dist/kit/levelPicture.js +27 -0
  57. package/dist/kit/menuVersion.js +19 -0
  58. package/dist/kit/microText.js +35 -0
  59. package/dist/kit/mumble.js +74 -0
  60. package/dist/kit/music.js +8 -0
  61. package/dist/kit/palRamps.js +32 -0
  62. package/dist/kit/palette.js +49 -0
  63. package/dist/kit/pcText.js +72 -0
  64. package/dist/kit/photo.js +150 -0
  65. package/dist/kit/pixels.js +79 -0
  66. package/dist/kit/png.js +40 -0
  67. package/dist/kit/quantize.js +72 -0
  68. package/dist/kit/raytrace.js +379 -0
  69. package/dist/kit/recordedDemo.js +10 -0
  70. package/dist/kit/reel.js +77 -0
  71. package/dist/kit/road3d.js +67 -0
  72. package/dist/kit/routeChecks.js +8 -0
  73. package/dist/kit/saveSlots.js +11 -0
  74. package/dist/kit/sceneInit.js +13 -0
  75. package/dist/kit/sceneSim.js +112 -0
  76. package/dist/kit/screenText.js +15 -0
  77. package/dist/kit/sdftext.js +237 -0
  78. package/dist/kit/shading.js +69 -0
  79. package/dist/kit/song.js +251 -0
  80. package/dist/kit/songFx.js +179 -0
  81. package/dist/kit/sound.js +52 -0
  82. package/dist/kit/synthParts.js +20 -0
  83. package/dist/kit/tar.js +53 -0
  84. package/dist/kit/textBounds.js +84 -0
  85. package/dist/kit/textfit.js +246 -0
  86. package/dist/kit/transforms.js +57 -0
  87. package/dist/kit/tune.js +21 -0
  88. package/dist/look-alike.js +50 -0
  89. package/dist/menu-version.js +4 -0
  90. package/dist/mesh/colorBodies.js +137 -0
  91. package/dist/mesh/decimate.js +207 -0
  92. package/dist/mesh/meshCheck.js +51 -0
  93. package/dist/mesh/overhang.js +41 -0
  94. package/dist/mesh/sampledField.js +12 -0
  95. package/dist/mesh/stl.js +36 -0
  96. package/dist/mesh/surfaceNets.js +79 -0
  97. package/dist/mesh/tetraMesh.js +62 -0
  98. package/dist/mesh/threeMf.js +58 -0
  99. package/dist/mesh/zipFile.js +52 -0
  100. package/dist/microFont.js +101 -0
  101. package/dist/music/compose.js +72 -0
  102. package/dist/pack/meshPack.js +198 -0
  103. package/dist/pack/threeMfPack.js +92 -0
  104. package/dist/palette-reserve.js +116 -0
  105. package/dist/palettes.js +138 -0
  106. package/dist/release-notes.js +40 -0
  107. package/dist/simulation.js +16 -2774
  108. package/dist/text.js +74 -0
  109. package/dist/types/audio.d.ts +4 -0
  110. package/dist/types/audioFiles.d.ts +22 -0
  111. package/dist/types/audioWav.d.ts +4 -0
  112. package/dist/types/blockMerge.d.ts +24 -0
  113. package/dist/types/colorReduce.d.ts +23 -0
  114. package/dist/types/{web/packages/tools/src/colors.d.ts → colors.d.ts} +6 -0
  115. package/dist/types/delta.d.ts +32 -0
  116. package/dist/types/diskDiff.d.ts +47 -0
  117. package/dist/types/drawing.d.ts +15 -0
  118. package/dist/types/embroidery/compile.d.ts +3 -0
  119. package/dist/types/embroidery/dst.d.ts +13 -0
  120. package/dist/types/embroidery/exp.d.ts +8 -0
  121. package/dist/types/embroidery/fill.d.ts +6 -0
  122. package/dist/types/embroidery/geom.d.ts +19 -0
  123. package/dist/types/embroidery/pes.d.ts +10 -0
  124. package/dist/types/embroidery/satin.d.ts +11 -0
  125. package/dist/types/embroidery/simulate.d.ts +19 -0
  126. package/dist/types/embroidery/strokeFont.d.ts +20 -0
  127. package/dist/types/embroidery/svg.d.ts +3 -0
  128. package/dist/types/embroidery/types.d.ts +70 -0
  129. package/dist/types/embroidery/units.d.ts +10 -0
  130. package/dist/types/embroidery/validate.d.ts +22 -0
  131. package/dist/types/formats/blocks.d.ts +1 -0
  132. package/dist/types/formats/character.d.ts +1 -0
  133. package/dist/types/formats/cmf.d.ts +1 -0
  134. package/dist/types/formats/fli.d.ts +1 -0
  135. package/dist/types/formats/fliLimits.d.ts +1 -0
  136. package/dist/types/formats/game.d.ts +1 -0
  137. package/dist/types/formats/gif.d.ts +1 -0
  138. package/dist/types/formats/graphicScripts.d.ts +1 -0
  139. package/dist/types/formats/map.d.ts +1 -0
  140. package/dist/types/formats/monster.d.ts +1 -0
  141. package/dist/types/formats/palette.d.ts +1 -0
  142. package/dist/types/formats/recording.d.ts +1 -0
  143. package/dist/types/formats/sound.d.ts +1 -0
  144. package/dist/types/formats/voc.d.ts +1 -0
  145. package/dist/types/gifShrink.d.ts +8 -0
  146. package/dist/types/image/animatedGif.d.ts +9 -0
  147. package/dist/types/image/surface.d.ts +26 -0
  148. package/dist/types/images.d.ts +13 -0
  149. package/dist/types/kit/actors.d.ts +7 -0
  150. package/dist/types/kit/align.d.ts +93 -0
  151. package/dist/types/kit/audioEvents.d.ts +26 -0
  152. package/dist/types/kit/blit.d.ts +20 -0
  153. package/dist/types/kit/blockRoles.d.ts +243 -0
  154. package/dist/types/{games/kit → kit}/clips.d.ts +1 -1
  155. package/dist/types/kit/coverPaint.d.ts +7 -0
  156. package/dist/types/kit/disk.d.ts +15 -0
  157. package/dist/types/kit/fadeOut.d.ts +12 -0
  158. package/dist/types/kit/fliClips.d.ts +32 -0
  159. package/dist/types/kit/fliShrink.d.ts +149 -0
  160. package/dist/types/{games/kit → kit}/gameSim.d.ts +9 -5
  161. package/dist/types/kit/hopBot.d.ts +72 -0
  162. package/dist/types/kit/laserClearance.d.ts +16 -0
  163. package/dist/types/kit/laserJoints.d.ts +39 -0
  164. package/dist/types/kit/laserLayout.d.ts +54 -0
  165. package/dist/types/kit/laserPixels.d.ts +52 -0
  166. package/dist/types/kit/laserPreview.d.ts +9 -0
  167. package/dist/types/kit/laserSvg.d.ts +35 -0
  168. package/dist/types/kit/levelGen/castle.d.ts +17 -0
  169. package/dist/types/kit/levelGen/dungeon.d.ts +11 -0
  170. package/dist/types/kit/levelGen/forest.d.ts +17 -0
  171. package/dist/types/kit/levelGen/furnish.d.ts +31 -0
  172. package/dist/types/kit/levelGen/grid.d.ts +46 -0
  173. package/dist/types/kit/levelGen/index.d.ts +138 -0
  174. package/dist/types/kit/levelGen/interior.d.ts +18 -0
  175. package/dist/types/kit/levelGen/jumpModel.d.ts +78 -0
  176. package/dist/types/kit/levelGen/needs.d.ts +44 -0
  177. package/dist/types/kit/levelGen/overworld.d.ts +21 -0
  178. package/dist/types/kit/levelGen/platform.d.ts +59 -0
  179. package/dist/types/kit/levelGen/platformCap.d.ts +13 -0
  180. package/dist/types/kit/levelGen/platformReach.d.ts +37 -0
  181. package/dist/types/kit/levelGen/props.d.ts +37 -0
  182. package/dist/types/kit/levelGen/town.d.ts +24 -0
  183. package/dist/types/kit/levelGrid.d.ts +16 -0
  184. package/dist/types/kit/levelPicture.d.ts +9 -0
  185. package/dist/types/kit/menuVersion.d.ts +7 -0
  186. package/dist/types/kit/microText.d.ts +18 -0
  187. package/dist/types/kit/mumble.d.ts +41 -0
  188. package/dist/types/kit/music.d.ts +1 -0
  189. package/dist/types/kit/palMerge.d.ts +10 -0
  190. package/dist/types/kit/palRamps.d.ts +28 -0
  191. package/dist/types/kit/pcText.d.ts +19 -0
  192. package/dist/types/kit/photo.d.ts +69 -0
  193. package/dist/types/kit/png.d.ts +7 -0
  194. package/dist/types/kit/quantize.d.ts +20 -0
  195. package/dist/types/kit/raytrace.d.ts +169 -0
  196. package/dist/types/kit/recordedDemo.d.ts +1 -0
  197. package/dist/types/kit/road3d.d.ts +71 -0
  198. package/dist/types/kit/routeChecks.d.ts +6 -0
  199. package/dist/types/kit/saveSlots.d.ts +17 -0
  200. package/dist/types/kit/sceneInit.d.ts +11 -0
  201. package/dist/types/{games/kit → kit}/sceneSim.d.ts +5 -5
  202. package/dist/types/kit/screenText.d.ts +3 -0
  203. package/dist/types/kit/sdftext.d.ts +34 -0
  204. package/dist/types/kit/shading.d.ts +23 -0
  205. package/dist/types/kit/shareBlocks.d.ts +20 -0
  206. package/dist/types/kit/song.d.ts +89 -0
  207. package/dist/types/kit/songFx.d.ts +99 -0
  208. package/dist/types/kit/synthParts.d.ts +7 -0
  209. package/dist/types/kit/tar.d.ts +13 -0
  210. package/dist/types/kit/textfit.d.ts +74 -0
  211. package/dist/types/kit/transforms.d.ts +8 -0
  212. package/dist/types/lookAlike.d.ts +31 -0
  213. package/dist/types/menuVersionEntry.d.ts +1 -0
  214. package/dist/types/mesh/colorBodies.d.ts +18 -0
  215. package/dist/types/mesh/decimate.d.ts +10 -0
  216. package/dist/types/mesh/fieldTrinket.d.ts +40 -0
  217. package/dist/types/mesh/figureShapes.d.ts +24 -0
  218. package/dist/types/mesh/mesh.d.ts +9 -0
  219. package/dist/types/mesh/meshCheck.d.ts +22 -0
  220. package/dist/types/mesh/overhang.d.ts +24 -0
  221. package/dist/types/mesh/pixelFigure.d.ts +41 -0
  222. package/dist/types/mesh/sampledField.d.ts +3 -0
  223. package/dist/types/mesh/sdfShapes.d.ts +20 -0
  224. package/dist/types/mesh/stl.d.ts +9 -0
  225. package/dist/types/mesh/strokeText.d.ts +8 -0
  226. package/dist/types/mesh/surfaceNets.d.ts +14 -0
  227. package/dist/types/mesh/tetraMesh.d.ts +4 -0
  228. package/dist/types/mesh/threeMf.d.ts +12 -0
  229. package/dist/types/mesh/trinketKinds.d.ts +72 -0
  230. package/dist/types/mesh/trinketTool.d.ts +26 -0
  231. package/dist/types/mesh/voxel.d.ts +10 -0
  232. package/dist/types/mesh/zipFile.d.ts +13 -0
  233. package/dist/types/microFont.d.ts +6 -0
  234. package/dist/types/pack/meshPack.d.ts +26 -0
  235. package/dist/types/pack/threeMfPack.d.ts +11 -0
  236. package/dist/types/palettePresetData.d.ts +4 -0
  237. package/dist/types/palettePresets.d.ts +12 -0
  238. package/dist/types/paletteReserve.d.ts +52 -0
  239. package/dist/types/palettes.d.ts +4 -0
  240. package/dist/types/releaseNotes.d.ts +3 -0
  241. package/dist/types/simulation.d.ts +6 -0
  242. package/dist/types/{web/packages/tools/src/text.d.ts → text.d.ts} +6 -6
  243. package/package.json +145 -15
  244. package/dist/binary-D7wuaC5g.js +0 -120
  245. package/dist/pixels-DzfIIUOl.js +0 -76
  246. package/dist/types/games/kit/blit.d.ts +0 -10
  247. package/dist/types/games/kit/music.d.ts +0 -1
  248. package/dist/types/games/kit/pcText.d.ts +0 -8
  249. package/dist/types/games/kit/shading.d.ts +0 -11
  250. package/dist/types/web/packages/tools/src/audio.d.ts +0 -3
  251. package/dist/types/web/packages/tools/src/drawing.d.ts +0 -10
  252. package/dist/types/web/packages/tools/src/images.d.ts +0 -2
  253. package/dist/types/web/packages/tools/src/microFont.d.ts +0 -1
  254. package/dist/types/web/packages/tools/src/simulation.d.ts +0 -3
  255. package/dist/types/web/scripts/cdGames.d.ts +0 -103
  256. package/dist/types/web/scripts/gameShots.d.ts +0 -12
  257. package/dist/types/web/scripts/ogImage.d.ts +0 -21
  258. package/dist/types/web/src/audio/cmfLoad.d.ts +0 -7
  259. package/dist/types/web/src/audio/cmfPlayer.d.ts +0 -69
  260. package/dist/types/web/src/audio/context.d.ts +0 -12
  261. package/dist/types/web/src/audio/engine.d.ts +0 -39
  262. package/dist/types/web/src/audio/music.worklet.d.ts +0 -14
  263. package/dist/types/web/src/audio/opl.d.ts +0 -37
  264. package/dist/types/web/src/audio/output.d.ts +0 -13
  265. package/dist/types/web/src/desk/boxes/boxFacts.d.ts +0 -85
  266. package/dist/types/web/src/dosPlayer/fileExtensions.d.ts +0 -44
  267. package/dist/types/web/src/dosPlayer/patchRules.d.ts +0 -24
  268. package/dist/types/web/src/dosPlayer/patchTable.d.ts +0 -80
  269. package/dist/types/web/src/edition.d.ts +0 -6
  270. package/dist/types/web/src/eggs/eggState.d.ts +0 -26
  271. package/dist/types/web/src/eggs/eggs.d.ts +0 -31
  272. package/dist/types/web/src/engine/character.d.ts +0 -30
  273. package/dist/types/web/src/engine/funcKeys.d.ts +0 -33
  274. package/dist/types/web/src/engine/game.d.ts +0 -52
  275. package/dist/types/web/src/engine/keys.d.ts +0 -17
  276. package/dist/types/web/src/engine/machine.d.ts +0 -99
  277. package/dist/types/web/src/engine/menus.d.ts +0 -46
  278. package/dist/types/web/src/engine/monsters.d.ts +0 -19
  279. package/dist/types/web/src/engine/playGain.d.ts +0 -11
  280. package/dist/types/web/src/engine/playerLook.d.ts +0 -26
  281. package/dist/types/web/src/engine/recorder.d.ts +0 -60
  282. package/dist/types/web/src/engine/render.d.ts +0 -8
  283. package/dist/types/web/src/engine/scene.d.ts +0 -156
  284. package/dist/types/web/src/engine/scroll.d.ts +0 -16
  285. package/dist/types/web/src/engine/showGraphic.d.ts +0 -39
  286. package/dist/types/web/src/engine/slowPc.d.ts +0 -62
  287. package/dist/types/web/src/engine/touch.d.ts +0 -33
  288. package/dist/types/web/src/engine/world.d.ts +0 -215
  289. package/dist/types/web/src/export/gameAbout.d.ts +0 -15
  290. package/dist/types/web/src/formats/binary.d.ts +0 -44
  291. package/dist/types/web/src/formats/blocks.d.ts +0 -52
  292. package/dist/types/web/src/formats/character.d.ts +0 -65
  293. package/dist/types/web/src/formats/cmf.d.ts +0 -33
  294. package/dist/types/web/src/formats/fli.d.ts +0 -45
  295. package/dist/types/web/src/formats/fliLimits.d.ts +0 -13
  296. package/dist/types/web/src/formats/game.d.ts +0 -72
  297. package/dist/types/web/src/formats/gif.d.ts +0 -15
  298. package/dist/types/web/src/formats/graphicScripts.d.ts +0 -18
  299. package/dist/types/web/src/formats/highscore.d.ts +0 -10
  300. package/dist/types/web/src/formats/map.d.ts +0 -24
  301. package/dist/types/web/src/formats/monster.d.ts +0 -48
  302. package/dist/types/web/src/formats/palette.d.ts +0 -15
  303. package/dist/types/web/src/formats/recording.d.ts +0 -7
  304. package/dist/types/web/src/formats/sound.d.ts +0 -13
  305. package/dist/types/web/src/formats/voc.d.ts +0 -13
  306. package/dist/types/web/src/gfx/cp437Glyphs.d.ts +0 -2
  307. package/dist/types/web/src/gfx/font8x8.d.ts +0 -2
  308. package/dist/types/web/src/gfx/levelPicture.d.ts +0 -81
  309. package/dist/types/web/src/gfx/screen.d.ts +0 -46
  310. package/dist/types/web/src/gfx/titlePicture.d.ts +0 -21
  311. package/dist/types/web/src/input/chords.d.ts +0 -22
  312. package/dist/types/web/src/input/deskMouse.d.ts +0 -14
  313. package/dist/types/web/src/input/keyboard.d.ts +0 -39
  314. package/dist/types/web/src/input/scancodes.d.ts +0 -3
  315. package/dist/types/web/src/manual/printables/types.d.ts +0 -277
  316. package/dist/types/web/src/project/bizarre.d.ts +0 -28
  317. package/dist/types/web/src/project/companion.d.ts +0 -35
  318. package/dist/types/web/src/project/diskFacts.d.ts +0 -30
  319. package/dist/types/web/src/project/files.d.ts +0 -124
  320. package/dist/types/web/src/project/gameFiles.d.ts +0 -49
  321. package/dist/types/web/src/project/gamePack.d.ts +0 -17
  322. package/dist/types/web/src/project/health.d.ts +0 -30
  323. package/dist/types/web/src/project/secretGames.d.ts +0 -19
  324. package/dist/types/web/src/project/storage.d.ts +0 -46
  325. package/dist/types/web/src/project/streamGame.d.ts +0 -38
  326. package/dist/types/web/src/project/zip.d.ts +0 -33
  327. package/dist/types/web/src/retro/dos/disks.d.ts +0 -33
  328. package/dist/types/web/src/retro/text/cp437.d.ts +0 -4
  329. package/dist/types/web/src/seededRandom.d.ts +0 -6
  330. package/dist/types/web/src/tinHearts/deskHearts.d.ts +0 -33
  331. package/dist/types/web/src/tinHearts/manifest.d.ts +0 -30
  332. package/dist/types/web/src/tinHearts/tinHearts.d.ts +0 -84
  333. package/dist/types/web/src/walkthrough/format.d.ts +0 -92
  334. package/dist/types/web/src/walkthrough/madeUpScores.d.ts +0 -6
  335. package/dist/types/web/src/walkthrough/runtime.d.ts +0 -134
  336. /package/dist/types/{web/src/assistant → image}/png.d.ts +0 -0
  337. /package/dist/types/{games/kit → kit}/palette.d.ts +0 -0
  338. /package/dist/types/{games/kit → kit}/pixels.d.ts +0 -0
  339. /package/dist/types/{games/kit → kit}/reel.d.ts +0 -0
  340. /package/dist/types/{games/kit → kit}/sound.d.ts +0 -0
  341. /package/dist/types/{games/kit → kit}/textBounds.d.ts +0 -0
  342. /package/dist/types/{games/kit → kit}/tune.d.ts +0 -0
  343. /package/dist/types/{web/src/audio → music}/compose.d.ts +0 -0
@@ -0,0 +1,179 @@
1
+ import { midi as x } from "../music/compose.js";
2
+ const M = { kick: 11, snare: 12, tom: 13, cymbal: 14, hat: 15 }, A = { w: 4, h: 2, q: 1, e: 0.5, s: 0.25, t: 1 / 3, x: 1 / 6 };
3
+ function E(l) {
4
+ const t = [];
5
+ for (const r of l.split(",").map((n) => n.trim()).filter(Boolean)) {
6
+ const n = /^(~+)?(\S+)\s+([whqestx])(\.?)(\\+)?([!-]*)$/.exec(r);
7
+ if (!n) throw new Error(`Bad note "${r}"`);
8
+ const o = A[n[3]] * (n[4] ? 1.5 : 1), s = [...n[6]].reduce((i, h) => i + (h === "!" ? 14 : -18), 0);
9
+ if (n[2] === "_") {
10
+ const i = t[t.length - 1];
11
+ if (!i) throw new Error("A hold with nothing to hold");
12
+ t.push({ n: i.n, beats: o, scoop: 0, fall: n[5] ? n[5].length * 2 : 0, accent: 0, tie: !0 });
13
+ continue;
14
+ }
15
+ t.push({ n: x(n[2]), beats: o, scoop: n[1] ? n[1].length * 2 : 0, fall: n[5] ? n[5].length * 2 : 0, accent: s, tie: !1 });
16
+ }
17
+ return t;
18
+ }
19
+ function U(l, t) {
20
+ const r = Uint8Array.from(l);
21
+ return t.mod !== void 0 && (r[2] = r[2] & 192 | Math.max(0, Math.min(63, Math.round(t.mod)))), t.car !== void 0 && (r[3] = r[3] & 192 | Math.max(0, Math.min(63, Math.round(t.car)))), r;
22
+ }
23
+ function B(l) {
24
+ const t = Uint8Array.from(l);
25
+ return t[0] ^= 64, t[1] ^= 64, t;
26
+ }
27
+ function q(l, t, r) {
28
+ const n = Uint8Array.from(l);
29
+ return n[8] = t & 3, n[9] = r & 3, n;
30
+ }
31
+ function F(l, t, r, n) {
32
+ const o = (s, i, h) => s === void 0 || i === void 0 ? void 0 : s + (i - s) * h;
33
+ return Array.from({ length: t }, (s, i) => {
34
+ const h = t === 1 ? 1 : i / (t - 1);
35
+ return U(l, { mod: o(r.mod, n.mod, h), car: o(r.car, n.car, h) });
36
+ });
37
+ }
38
+ const v = (l, t, r) => Math.max(1, Math.min(127, Math.round(l + (t - l) * Math.max(0, Math.min(1, r)))));
39
+ class R {
40
+ constructor(t) {
41
+ this.w = t;
42
+ }
43
+ w;
44
+ /** The patch each channel has now (after its program changes). */
45
+ now = /* @__PURE__ */ new Map();
46
+ /** Where each section starts (beat), for the preview tools. */
47
+ sections = [];
48
+ tick(t) {
49
+ return Math.round(t * this.w.tpb);
50
+ }
51
+ /** The channel's opening patch (instrument n for channel n, loaded before the first note). */
52
+ open(t, r) {
53
+ return this.w.instruments[t] = r, this.now.set(t, r), this;
54
+ }
55
+ /** The instrument number of a patch: a channel's own opening patch, or one of the extra ones from 16 up (128 at most). */
56
+ patch(t) {
57
+ const r = this.w.instruments;
58
+ for (let o = 0; o < r.length; o++) if (r[o] && (r[o] === t || k(r[o], t))) return o;
59
+ const n = Math.max(16, r.length);
60
+ if (n >= 128) throw new Error("A CMF holds 128 instruments");
61
+ return r[n] = t, n;
62
+ }
63
+ /** A program change at beat `at` (nothing if the channel already has the patch). */
64
+ program(t, r, n) {
65
+ const o = this.now.get(t);
66
+ return o && (o === n || k(o, n)) ? this : (this.w.events.push({ tick: this.tick(r), data: [192 | t, this.patch(n)] }), this.now.set(t, n), this);
67
+ }
68
+ /** A section's start: a CMF marker (controller 0x66, value = its number) that PLAYGAME skips. */
69
+ marker(t, r) {
70
+ return this.sections.push({ at: t, name: r }), this.w.events.push({ tick: this.tick(t), data: [176, 102, Math.min(127, this.sections.length)] }), this;
71
+ }
72
+ /** One note, `len` beats from `at` (legato: the part of it held before letting go). */
73
+ note(t, r, n, o, s, i = 0.92) {
74
+ return this.w.note(t, r, n, o, Math.max(1, Math.min(127, Math.round(s))), i), this;
75
+ }
76
+ /**
77
+ * A phrase from beat `at` on one channel (see tones()): scoops slide up into their note in
78
+ * two-tick steps, falls slide away at the end, ties hold on. Returns its length in beats.
79
+ */
80
+ phrase(t, r, n, o, s = 0, i = 0.92) {
81
+ const h = E(n);
82
+ let e = r;
83
+ for (let c = 0; c < h.length; c++) {
84
+ const a = h[c];
85
+ if (a.n === null || a.tie) {
86
+ e += a.beats;
87
+ continue;
88
+ }
89
+ let p = a.beats, u = a.fall;
90
+ for (let d = c + 1; d < h.length && h[d].tie; d++)
91
+ p += h[d].beats, u = h[d].fall || u;
92
+ const f = a.n + s, w = o + a.accent;
93
+ let m = e;
94
+ a.scoop && (m = this.slide(t, e, f - a.scoop, f - 1, 2, w - 10));
95
+ const b = u ? u * 2 / this.w.tpb : 0, g = Math.max(1 / this.w.tpb, e + p * i - m - b);
96
+ u ? this.note(t, m, g + 1 / this.w.tpb, f, w, 1) : this.note(t, m, e + p - m, f, w, i), u && this.slide(t, m + g + 1 / this.w.tpb, f - 1, f - u, 2, w - 20), e += a.beats;
97
+ }
98
+ return e - r;
99
+ }
100
+ /** Semitone steps from `from` to `to`, `ticks` timer ticks each, on one channel; returns the beat it ends on. */
101
+ slide(t, r, n, o, s, i) {
102
+ const h = o >= n ? 1 : -1, e = s / this.w.tpb;
103
+ let c = r;
104
+ for (let a = n; h > 0 ? a <= o : a >= o; a += h)
105
+ this.note(t, c, e, a, i, 1), c += e;
106
+ return c;
107
+ }
108
+ /** The same notes on two channels at once, the second with the twin patch (a two-voice choir). */
109
+ choir(t, r, n, o, s, i = 0) {
110
+ return this.phrase(t, n, o, s, i), this.phrase(r, n, o, s - 8, i);
111
+ }
112
+ /** Program changes on `chs` stepping through `patches` evenly over `beats` from `at` (a swell or a filter sweep). */
113
+ swell(t, r, n, o) {
114
+ return o.forEach((s, i) => {
115
+ const h = r + (o.length === 1 ? 0 : n * i / (o.length - 1));
116
+ for (const e of t) this.program(e, h, s);
117
+ }), this;
118
+ }
119
+ /** A chord on one channel: its notes in turn, one every `every` beats, for `beats` ('up', 'down', 'updown'). */
120
+ arp(t, r, n, o, s, i, h = "up") {
121
+ const e = h === "up" ? o : h === "down" ? [...o].reverse() : [...o, ...o.slice(1, -1).reverse()], c = Math.round(n / s);
122
+ for (let a = 0; a < c; a++) this.note(t, r + a * s, s, e[a % e.length], i, 0.95);
123
+ return this;
124
+ }
125
+ /** A chord spread round several channels, a note every `every` beats; each rings on until its channel's next note (a harp). */
126
+ harp(t, r, n, o, s, i) {
127
+ const h = Math.round(n / s);
128
+ for (let e = 0; e < h; e++) {
129
+ const c = Math.min(h, e + t.length) * s, a = typeof i == "number" ? i : i(e);
130
+ this.note(t[e % t.length], r + e * s, c - e * s, o[e % o.length], a, 0.97);
131
+ }
132
+ return this;
133
+ }
134
+ /** The phrase again on `ch`, `delay` beats later, `times` times, each softer (an echo). */
135
+ echo(t, r, n, o, s, i = 1, h = 0.6, e = 0) {
136
+ for (let c = 1; c <= i; c++) this.phrase(t, r + s * c, n, o * h ** c, e, 0.7);
137
+ return this;
138
+ }
139
+ /** One note retriggered on its own channel `times` times, `gap` beats apart, each softer. */
140
+ stutter(t, r, n, o, s, i, h = 0.72) {
141
+ for (let e = 0; e < o; e++) this.note(t, r + e * s, s, n, i * h ** e, 0.8);
142
+ return this;
143
+ }
144
+ /** The bass drum as a pitched voice (its patch from boomPatch). */
145
+ boom(t, r, n, o) {
146
+ return this.note(M.kick, t, r, n, o, 0.9);
147
+ }
148
+ /** A drum hit every `every` beats for `beats`, velocity ramping (a roll); tuned drums (tom, kick) walk through `notes`. */
149
+ drumRoll(t, r, n, o, s, i, h = [t === M.tom ? 48 : t === M.cymbal ? 72 : 55]) {
150
+ const e = Math.round(n / o);
151
+ for (let c = 0; c < e; c++)
152
+ this.note(t, r + c * o, Math.min(o, 0.5), h[c % h.length], v(s, i, e === 1 ? 1 : c / (e - 1)), 0.6);
153
+ return this;
154
+ }
155
+ /** Puts every drum channel back on its opening patch and the song's length in bars, then writes the CMF. */
156
+ cmf(t) {
157
+ this.w.bar = t;
158
+ for (const r of [11, 12, 13, 14, 15]) {
159
+ const n = this.w.instruments[r];
160
+ n && this.program(r, t * 4, n);
161
+ }
162
+ return this.w.cmf();
163
+ }
164
+ }
165
+ const k = (l, t) => l.length === t.length && l.every((r, n) => r === t[n]);
166
+ function _(l = {}) {
167
+ const t = l.growl ?? 32;
168
+ return Uint8Array.from([33, 33, t, 0, 244, 240 | (l.decay ?? 3), 15, 16 | (l.release ?? 6), 0, 0, 4, 0, 0, 0, 0, 0]);
169
+ }
170
+ export {
171
+ M as DRUM,
172
+ R as Fx,
173
+ _ as boomPatch,
174
+ B as detuned,
175
+ U as leveled,
176
+ F as sweep,
177
+ E as tones,
178
+ q as waved
179
+ };
@@ -0,0 +1,52 @@
1
+ import { encodeVoc as M } from "@lewismoten/gamemaker-sandbox-engine/formats/voc";
2
+ import { NUMFREQ as u } from "@lewismoten/gamemaker-sandbox-engine/formats/sound";
3
+ import { rng as h } from "./pixels.js";
4
+ function a(t) {
5
+ return Uint16Array.from({ length: u }, (n, e) => Math.max(0, Math.min(8192, Math.round(t(e, e / (u - 1))))));
6
+ }
7
+ const k = {
8
+ rise: (t = 200, n = 2e3) => a((e, r) => t * (n / t) ** r),
9
+ fall: (t = 2e3, n = 150) => a((e, r) => t * (n / t) ** r),
10
+ coin: () => a((t) => t < 4 ? 988 : t < 18 ? 1319 : 0),
11
+ hurt: () => a((t) => (t % 2 ? 140 : 95) * (1 - t / 60)),
12
+ zap: () => a((t) => 3e3 - t * 75 + t % 3 * 300),
13
+ chirp: () => a((t) => t < 12 ? 1200 + t * 120 : 0),
14
+ arpeggio: (t = [523, 659, 784, 1047]) => a((n) => n < t.length * 6 ? t[Math.floor(n / 6)] : 0),
15
+ noise: (t = 1, n = 100, e = 2e3) => {
16
+ const r = h(t);
17
+ return a((o) => o < 30 ? n + r() * (e - n) : 0);
18
+ },
19
+ warble: (t = 600, n = 300, e = 1.3) => a((r) => t + Math.sin(r * e) * n)
20
+ }, f = {
21
+ sine: (t) => {
22
+ let n = 0, e = 0;
23
+ return (r) => {
24
+ const o = typeof t == "number" ? t : t(r);
25
+ return n += 2 * Math.PI * o * (r - e), e = r, Math.sin(n);
26
+ };
27
+ },
28
+ square: (t) => {
29
+ const n = f.sine(t);
30
+ return (e) => n(e) >= 0 ? 1 : -1;
31
+ },
32
+ noise: (t = 7) => {
33
+ const n = h(t);
34
+ return () => n() * 2 - 1;
35
+ }
36
+ };
37
+ function v(t, n, e = {}) {
38
+ const r = e.rate ?? 11025, o = Math.round(t * r), i = new Float32Array(o), l = e.attack ?? 5e-3;
39
+ for (let c = 0; c < o; c++) {
40
+ const s = c / r, m = e.envelope ? e.envelope(s / t) : Math.min(1, s / l) * (1 - s / t) ** 1.5;
41
+ i[c] = Math.max(-1, Math.min(1, n(s) * m * (e.gain ?? 0.9)));
42
+ }
43
+ return M(i, r);
44
+ }
45
+ const y = (...t) => (n) => t.reduce((e, [r, o]) => e + r(n) * o, 0);
46
+ export {
47
+ k as SPEAKER,
48
+ y as mix,
49
+ f as osc,
50
+ v as sample,
51
+ a as speaker
52
+ };
@@ -0,0 +1,20 @@
1
+ import { rng as s } from "./pixels.js";
2
+ function i(e, t) {
3
+ const n = s(e);
4
+ let r = 0;
5
+ return (a) => {
6
+ const o = typeof t == "number" ? t : t(a);
7
+ return r += o * (n() * 2 - 1 - r), r * (1.4 / Math.sqrt(Math.max(0.05, o)));
8
+ };
9
+ }
10
+ const c = (e, t, n) => (r) => r >= t && r < n ? e(r) : 0, h = (e, t) => (n) => Math.min(1, n / e) * Math.max(0, 1 - n) ** t;
11
+ function l(e, t) {
12
+ let n = 0;
13
+ return (r) => n += (e(r) - n) * t;
14
+ }
15
+ export {
16
+ h as env,
17
+ c as gate,
18
+ i as lowNoise,
19
+ l as lowpass
20
+ };
@@ -0,0 +1,53 @@
1
+ const h = new TextEncoder();
2
+ function s(e, r, t, n) {
3
+ const c = typeof n == "string" ? h.encode(n) : n;
4
+ if (c.length > t) throw new Error(`Tar field too long: ${typeof n == "string" ? n : c.length}`);
5
+ e.set(c, r);
6
+ }
7
+ const i = (e, r) => e.toString(8).padStart(r - 1, "0");
8
+ function y(e) {
9
+ if (h.encode(e).length <= 100) return [e, ""];
10
+ for (let r = e.lastIndexOf("/", e.length - 2); r > 0; r = e.lastIndexOf("/", r - 1)) {
11
+ const [t, n] = [e.slice(0, r), e.slice(r + 1)];
12
+ if (h.encode(n).length <= 100 && h.encode(t).length <= 155) return [n, t];
13
+ }
14
+ throw new Error(`Path too long for a tar archive: ${e}`);
15
+ }
16
+ function x(e, r) {
17
+ const t = new Uint8Array(512), n = e.path.endsWith("/"), [c, o] = y(e.path);
18
+ s(t, 0, 100, c), s(t, 100, 8, i(e.mode ?? (n ? 493 : 420), 8)), s(t, 108, 8, i(0, 8)), s(t, 116, 8, i(0, 8)), s(t, 124, 12, i(n ? 0 : e.data?.length ?? 0, 12)), s(t, 136, 12, i(r, 12)), t.fill(32, 148, 156), t[156] = n ? 53 : 48, s(t, 257, 6, "ustar\0"), s(t, 263, 2, "00"), s(t, 265, 32, "gamemaker"), s(t, 297, 32, "gamemaker"), s(t, 345, 155, o);
19
+ const a = t.reduce((f, d) => f + d, 0);
20
+ return s(t, 148, 8, `${i(a, 7)}\0`), t;
21
+ }
22
+ function T(e, r = /* @__PURE__ */ new Date()) {
23
+ const t = Math.floor(r.getTime() / 1e3), n = [];
24
+ for (const a of e)
25
+ n.push(x(a, t)), a.data && !a.path.endsWith("/") && (n.push(a.data), a.data.length % 512 && n.push(new Uint8Array(512 - a.data.length % 512)));
26
+ n.push(new Uint8Array(1024));
27
+ const c = new Uint8Array(n.reduce((a, f) => a + f.length, 0));
28
+ let o = 0;
29
+ for (const a of n)
30
+ c.set(a, o), o += a.length;
31
+ return c;
32
+ }
33
+ async function g(e, r) {
34
+ return new Uint8Array(await new Response(new Blob([e]).stream().pipeThrough(r)).arrayBuffer());
35
+ }
36
+ async function k(e, r) {
37
+ return g(T(e, r), new CompressionStream("gzip"));
38
+ }
39
+ async function A(e) {
40
+ const r = e[0] === 31 && e[1] === 139 ? await g(e, new DecompressionStream("gzip")) : e, t = new TextDecoder(), n = (o, a) => t.decode(r.subarray(o, o + a)).replace(/\0.*$/s, ""), c = [];
41
+ for (let o = 0; o + 512 <= r.length && !r.subarray(o, o + 512).every((u) => u === 0); ) {
42
+ const a = parseInt(n(o + 148, 8).trim(), 8), f = r.subarray(o, o + 512).reduce((u, w, p) => u + (p >= 148 && p < 156 ? 32 : w), 0);
43
+ if (a !== f) throw new Error("Bad tar header checksum.");
44
+ const d = n(o + 345, 155), m = (d ? `${d}/` : "") + n(o, 100), l = parseInt(n(o + 124, 12), 8);
45
+ c.push({ path: m, mode: parseInt(n(o + 100, 8), 8), data: r.slice(o + 512, o + 512 + l) }), o += 512 + Math.ceil(l / 512) * 512;
46
+ }
47
+ return c;
48
+ }
49
+ export {
50
+ T as createTar,
51
+ k as createTarGz,
52
+ A as readTar
53
+ };
@@ -0,0 +1,84 @@
1
+ const f = () => process.getBuiltinModule("node:fs"), x = (s) => /[\x20-\x7e\u25cf\u2022]/.test(s), u = typeof process < "u" ? process.env.TEXT_BOUNDS : void 0, p = [], o = /* @__PURE__ */ new Map(), d = (s, n, e, t) => `${s}x${n} ${e} ${t}`, m = /\/art\/(font|draw|canvas)\.ts|screens\/(draw|screen)\.ts/;
2
+ function w() {
3
+ const s = (new Error().stack ?? "").split(`
4
+ `).slice(1).map((t) => /\(?((?:\/|file:)[^():]+):(\d+):\d+\)?\s*$/.exec(t)).filter((t) => !!t).map((t) => ({ path: t[1].replace(/^file:\/\//, "").replace(/^.*\/games\//, ""), line: t[2] })).filter((t) => !/node_modules|kit\/textBounds\.ts/.test(t.path)).map((t) => ({ ...t, helper: m.test(t.path), name: `${t.path}:${t.line}` })), n = s.findIndex((t) => !t.helper);
5
+ return {
6
+ at: s.filter((t) => !t.helper).slice(0, 2).map((t) => t.name).join(" < "),
7
+ via: s.slice(0, n + 1).map((t) => t.name).join(" > ")
8
+ };
9
+ }
10
+ u && process.on("exit", () => {
11
+ const s = {
12
+ overflows: p,
13
+ shown: Object.fromEntries([...o].map(([n, e]) => [n, [...e].map((t) => t.split(",").map(Number))]))
14
+ };
15
+ f().writeFileSync(u, JSON.stringify(s));
16
+ });
17
+ class k {
18
+ constructor(n, e, t, i, r) {
19
+ this.w = n, this.h = e, this.s = t, this.area = i, this.has = r;
20
+ }
21
+ w;
22
+ h;
23
+ s;
24
+ area;
25
+ has;
26
+ x0 = 1 / 0;
27
+ y0 = 1 / 0;
28
+ x1 = -1 / 0;
29
+ y1 = -1 / 0;
30
+ /** A lit rectangle of the string (a font pixel, scaled). */
31
+ add(n, e, t = 1, i = 1) {
32
+ n < this.x0 && (this.x0 = n), e < this.y0 && (this.y0 = e), n + t > this.x1 && (this.x1 = n + t), e + i > this.y1 && (this.y1 = e + i);
33
+ }
34
+ end() {
35
+ if (this.x1 < this.x0) return;
36
+ const [n, e, t, i] = this.area, r = this.x0 < n - 0.5 || this.y0 < e - 0.5 || this.x1 > t + 0.5 || this.y1 > i + 0.5, { at: a, via: c } = w(), l = [...new Set(this.s)].filter((h) => !this.has(h)).join("");
37
+ if (l)
38
+ p.push({
39
+ s: this.s,
40
+ w: this.w,
41
+ h: this.h,
42
+ ink: [this.x0, this.y0, this.x1, this.y1].map((h) => Math.round(h)),
43
+ area: this.area,
44
+ at: a,
45
+ via: c,
46
+ missing: l
47
+ });
48
+ else if (r)
49
+ p.push({ s: this.s, w: this.w, h: this.h, ink: [this.x0, this.y0, this.x1, this.y1].map((h) => Math.round(h)), area: this.area, at: a, via: c });
50
+ else {
51
+ const h = d(this.w, this.h, c, this.s);
52
+ o.has(h) || o.set(h, /* @__PURE__ */ new Set()), o.get(h).add(`${Math.round(this.x0)},${Math.round(this.y0)}`);
53
+ }
54
+ }
55
+ }
56
+ function $(s, n, e, t = x) {
57
+ if (!(!u || !n.trim()))
58
+ return new k(s.w, s.h, n, e ?? [0, 0, s.w, s.h], t);
59
+ }
60
+ function y(s) {
61
+ const n = (i) => (s.shown[d(i.w, i.h, i.via, i.s)] ?? []).some(([r, a]) => Math.abs(r - i.ink[0]) > 2 || Math.abs(a - i.ink[1]) > 2), e = /* @__PURE__ */ new Map(), t = [];
62
+ for (const i of s.overflows) {
63
+ const r = d(i.w, i.h, i.via, i.s);
64
+ if (!i.missing && n(i)) {
65
+ t.push(i);
66
+ continue;
67
+ }
68
+ const a = e.get(r);
69
+ a ? a.ink = [Math.min(a.ink[0], i.ink[0]), Math.min(a.ink[1], i.ink[1]), Math.max(a.ink[2], i.ink[2]), Math.max(a.ink[3], i.ink[3])] : e.set(r, { ...i, ink: [...i.ink] });
70
+ }
71
+ return { cut: [...e.values()], moving: t };
72
+ }
73
+ function g(s) {
74
+ return s.missing ? `"${s.s}" has ${[...s.missing].map((n) => `U+${n.charCodeAt(0).toString(16).toUpperCase()}`).join(" ")}, a box in the PC font (${s.w}x${s.h}) at ${s.at}` : `"${s.s}" ink ${s.ink.join(",")} outside ${s.area.join(",")} (${s.w}x${s.h}) at ${s.at}`;
75
+ }
76
+ function M(s) {
77
+ if (!f().existsSync(s)) throw new Error(`${s}: the build wrote no text-bounds report`);
78
+ return y(JSON.parse(f().readFileSync(s, "utf8")));
79
+ }
80
+ export {
81
+ g as describe,
82
+ M as readBounds,
83
+ $ as textInk
84
+ };
@@ -0,0 +1,246 @@
1
+ import { readdirSync as O, readFileSync as j } from "node:fs";
2
+ import { join as G } from "node:path";
3
+ import { isGif as W, decodeGif as z } from "@lewismoten/gamemaker-sandbox-engine/formats/gif";
4
+ import { isFli as D, parseFli as H, newFliCanvas as _, applyFliFrame as B } from "@lewismoten/gamemaker-sandbox-engine/formats/fli";
5
+ import { parseBackdrop as Y, textLines as N, parseSlideList as Q } from "@lewismoten/gamemaker-sandbox-engine/formats/graphicScripts";
6
+ import { parseGame as R } from "@lewismoten/gamemaker-sandbox-engine/formats/game";
7
+ import { parsePalette as X, matchColor as Z } from "@lewismoten/gamemaker-sandbox-engine/formats/palette";
8
+ import { FONT8X8 as q } from "@lewismoten/gamemaker-sandbox-engine/gfx/font8x8";
9
+ const y = 320, w = 200, k = [63, 10, 10], C = [10, 10, 63], J = [63, 63, 0], v = 768, I = [50, 10, 50];
10
+ function ft(t) {
11
+ const e = /* @__PURE__ */ new Map();
12
+ for (const o of O(t)) e.set(o.toLowerCase(), new Uint8Array(j(G(t, o))));
13
+ return e;
14
+ }
15
+ const K = (t) => (/\.[^.]*$/.exec(t)?.[0] ?? "").toLowerCase(), b = (t, e) => Z(t, e[0], e[1], e[2]);
16
+ class $ {
17
+ pixels = new Uint8Array(y * w);
18
+ palette = new Uint8Array(v);
19
+ /** The `cols` a slide list hands from entry to entry (the last picture's palette). */
20
+ cols = new Uint8Array(v);
21
+ clone() {
22
+ const e = new $();
23
+ return e.pixels.set(this.pixels), e.palette.set(this.palette), e.cols.set(this.cols), e;
24
+ }
25
+ }
26
+ function A(t, e, o, n, c = 0, i = 0) {
27
+ for (let l = 0; l < n; l++) {
28
+ const m = l + i;
29
+ if (!(m < 0 || m >= w))
30
+ for (let r = 0; r < o; r++) {
31
+ const f = r + c;
32
+ f >= 0 && f < y && (t.pixels[m * y + f] = e[l * o + r]);
33
+ }
34
+ }
35
+ }
36
+ function F(t, e, o, n, c, i, l, m = I) {
37
+ const r = t.get(e.toLowerCase());
38
+ if (!r) return;
39
+ const f = K(e);
40
+ if (f === ".gif" || f === ".bkd") {
41
+ let s = e, a = 0, p = 0;
42
+ if (f === ".bkd") {
43
+ const u = Y(r);
44
+ [s, a, p] = [u.gif, u.x, u.y];
45
+ }
46
+ const x = t.get(s.toLowerCase());
47
+ if (!x || !W(x)) return;
48
+ const h = z(x);
49
+ A(o, h.pixels, h.width, h.height, a, p), o.cols.set(h.palette), o.palette.set(h.palette);
50
+ } else if (f === ".fli") {
51
+ if (!D(r)) return;
52
+ const s = H(r), a = _(s);
53
+ a.palette.set(o.palette), a.pixels.set(o.pixels.subarray(0, a.pixels.length));
54
+ for (let p = 0; p < s.frameCount; p++) B(s, p, a);
55
+ A(o, a.pixels, s.width, s.height), o.palette.set(a.palette), o.cols.set(a.palette);
56
+ } else if (f === ".txt") {
57
+ const s = b(l ?? n, m), a = b(n, k), p = N(r);
58
+ for (let x = 0; x * 16 < p.length; x++) {
59
+ const h = p.slice(x * 16, x * 16 + 16).map((u, d) => ({ x: 40, y: (5 + d) * 8, col: s, text: u }));
60
+ p.length > (x + 1) * 16 && h.push({ x: 224, y: 168, col: a, text: "MORE...", want: k }), c.push({ name: `${i}${e}${p.length > 16 ? ` p${x + 1}` : ""}`, kind: "page", pixels: o.pixels.slice(), palette: o.palette.slice(), texts: h });
61
+ }
62
+ } else if (f === ".lst")
63
+ for (const s of Q(r)) F(t, s.name, o, n, c, `${i}${e} > `, o.cols, m);
64
+ }
65
+ function M(t, e, o) {
66
+ const n = t.scenes[e]?.files[o];
67
+ return n ? n.toLowerCase() : void 0;
68
+ }
69
+ function S(t, e) {
70
+ const o = new $();
71
+ return F(t, e, o, o.palette, [], ""), o;
72
+ }
73
+ function pt(t, e = I) {
74
+ const o = [...t.keys()].find((f) => f.endsWith(".gam"));
75
+ if (!o) throw new Error("no .gam on the disk");
76
+ const n = R(t.get(o)), c = [], i = M(n, 0, 2), l = i ? S(t, i) : new $(), m = /* @__PURE__ */ new Set();
77
+ if (n.scenes.forEach((f, s) => {
78
+ const a = s === 0 ? [0, 4, 6, 7] : s === 1 ? [0, 2] : [9, 10];
79
+ let p = l.palette;
80
+ if (s > 1) {
81
+ const x = M(n, s, 0), h = x && t.get(x);
82
+ h && (p = X(h));
83
+ }
84
+ for (const x of a) {
85
+ const h = M(n, s, x);
86
+ if (!h || m.has(h)) continue;
87
+ m.add(h);
88
+ const u = s === 0 && x !== 0 ? l.clone() : new $();
89
+ F(t, h, u, p, c, "", void 0, e);
90
+ }
91
+ }), i) {
92
+ const f = b(l.palette, C), s = [{ x: 96, y: 104, col: f, text: n.scenes[0].desc }];
93
+ ["Play", "Read Instructions", "Read Storyline", "See Credits", "See Highest Scores", "Quit"].forEach((a, p) => {
94
+ s.push({ x: 80, y: (15 + p) * 8, col: f, text: a }), s.push({ x: 70, y: 113 + (p + 1) * 8, col: f, text: "", box: { w: 6, h: 5 } });
95
+ }), c.push({ name: `menu ${i}`, kind: "menu", pixels: l.pixels, palette: l.palette, texts: s });
96
+ }
97
+ const r = M(n, 0, 8);
98
+ if (r) {
99
+ const f = S(t, r), s = b(f.palette, k), a = b(f.palette, C), p = [{ x: 104, y: 0, col: s, text: "Top Ten Scores" }];
100
+ let x = 22, h = 27;
101
+ for (let u = 0; u < 10; u++)
102
+ p.push({ x: 20, y: h, col: a, text: `${String(1234567890 - u)} ${"M".repeat(22)}` }), h += x, u % 2 === 0 && x--, x--;
103
+ p.push({ x: 20, y: h, col: a, text: `${"1234".padStart(10)} Your Latest Score` }), p.push({ x: 116, y: 192, col: s, text: "Hit any key" }), c.push({ name: `scores ${r}`, kind: "scores", pixels: f.pixels, palette: f.palette, texts: p });
104
+ }
105
+ for (const [f, s] of [
106
+ [9, "load"],
107
+ [10, "save"]
108
+ ]) {
109
+ const a = M(n, 0, f);
110
+ if (!a) continue;
111
+ const p = S(t, a), x = b(p.palette, J), h = b(p.palette, k), u = b(p.palette, C), d = [];
112
+ for (let g = 0; g < 10; g++)
113
+ d.push({ x: 80, y: 40 + g * 14, col: x, text: "M".repeat(20) }), d.push({ x: 60, y: 27 + (g + 1) * 14, col: h, text: "", box: { w: 6, h: 5 } });
114
+ s === "load" ? d.push({ x: 40, y: 185, col: u, text: "This game has not been saved!" }) : d.push({ x: 112, y: 185, col: u, text: "Game Saved!" }), c.push({ name: `${s} ${a}`, kind: s, pixels: p.pixels, palette: p.palette, texts: d });
115
+ }
116
+ return c;
117
+ }
118
+ function T(t) {
119
+ const e = [];
120
+ if (t.box) {
121
+ for (let o = 0; o < t.box.h; o++) for (let n = 0; n < t.box.w; n++) e.push([t.x + n, t.y + o]);
122
+ return e;
123
+ }
124
+ for (let o = 0; o < t.text.length; o++) {
125
+ const n = (t.text.charCodeAt(o) & 255) * 8;
126
+ for (let c = 0; c < 8; c++) {
127
+ const i = q[n + c];
128
+ for (let l = 0; l < 8; l++) i & 1 << l && e.push([t.x + o * 8 + l, t.y + c]);
129
+ }
130
+ }
131
+ return e;
132
+ }
133
+ const E = (t, e) => [0, 1, 2].map((o) => t[e * 3 + o] << 2 | t[e * 3 + o] >> 4), L = (t) => {
134
+ const e = t / 255;
135
+ return e <= 0.03928 ? e / 12.92 : ((e + 0.055) / 1.055) ** 2.4;
136
+ }, P = (t) => 0.2126 * L(t[0]) + 0.7152 * L(t[1]) + 0.0722 * L(t[2]), V = (t, e) => {
137
+ const [o, n] = [P(t), P(e)].sort((c, i) => i - c);
138
+ return (o + 0.05) / (n + 0.05);
139
+ };
140
+ function U(t, e) {
141
+ const o = T(t);
142
+ if (!o.length) return;
143
+ let [n, c, i, l] = [1 / 0, 1 / 0, -1 / 0, -1 / 0];
144
+ for (const [m, r] of o) [n, c, i, l] = [Math.min(n, m), Math.min(c, r), Math.max(i, m), Math.max(l, r)];
145
+ return { x0: n - e, y0: c - e, x1: i + e, y1: l + e };
146
+ }
147
+ function tt(t, e) {
148
+ const o = [[], [], []];
149
+ for (const n of t.texts) {
150
+ const c = U(n, e);
151
+ if (c)
152
+ for (let i = Math.max(0, c.y0); i <= Math.min(w - 1, c.y1); i++)
153
+ for (let l = Math.max(0, c.x0); l <= Math.min(y - 1, c.x1); l++) {
154
+ const m = E(t.palette, t.pixels[i * y + l]);
155
+ for (let r = 0; r < 3; r++) o[r].push(m[r]);
156
+ }
157
+ }
158
+ return o.map((n) => (n.sort((c, i) => c - i), n[n.length >> 1] ?? 0));
159
+ }
160
+ function xt(t, e = {}, o) {
161
+ const n = e.margin ?? 2, c = e.artDistance ?? 72, i = e.allowArt ?? 0, l = e.minContrast ?? 3, m = [];
162
+ for (const r of t.texts) {
163
+ const f = U(r, n);
164
+ if (!f) continue;
165
+ const s = [];
166
+ (f.x0 + n < 0 || f.y0 + n < 0 || f.x1 - n >= y || f.y1 - n >= w) && s.push("off the screen");
167
+ const a = { ...t, texts: [r] }, p = tt(a, n);
168
+ let x = 0;
169
+ for (let u = Math.max(0, f.y0); u <= Math.min(w - 1, f.y1); u++)
170
+ for (let d = Math.max(0, f.x0); d <= Math.min(y - 1, f.x1); d++) {
171
+ const g = E(t.palette, t.pixels[u * y + d]);
172
+ Math.hypot(g[0] - p[0], g[1] - p[1], g[2] - p[2]) > c && (x++, o && (o[u * y + d] = 1));
173
+ }
174
+ x > i && s.push(`${x} art pixels within ${n}px`);
175
+ const h = V(E(t.palette, r.col), p);
176
+ if (h < l && s.push(`contrast ${h.toFixed(2)}`), r.want) {
177
+ const u = [0, 1, 2].map((d) => t.palette[r.col * 3 + d]);
178
+ Math.hypot(u[0] - r.want[0], u[1] - r.want[1], u[2] - r.want[2]) > 30 && s.push(`ink shows as rgb(${u.join(",")}), not rgb(${r.want.join(",")})`);
179
+ }
180
+ s.length && m.push({ screen: t.name, text: r.box ? "[marker]" : r.text, x: r.x, y: r.y, artPixels: x, contrast: h, problems: s });
181
+ }
182
+ return m;
183
+ }
184
+ function ht(t, e) {
185
+ const o = new Uint8Array(y * w * 3), n = t.pixels.slice();
186
+ for (const c of t.texts) for (const [i, l] of T(c)) i >= 0 && l >= 0 && i < y && l < w && (n[l * y + i] = c.col);
187
+ for (let c = 0; c < y * w; c++) {
188
+ let i = E(t.palette, n[c]);
189
+ e?.[c] && n[c] === t.pixels[c] && (i = [255, 0, 255]), o.set(i, c * 3);
190
+ }
191
+ return o;
192
+ }
193
+ function ut(t) {
194
+ const e = [...t.keys()].find((i) => i.endsWith(".gam"));
195
+ if (!e) throw new Error("no .gam on the disk");
196
+ const o = R(t.get(e)), n = [], c = /* @__PURE__ */ new Set();
197
+ return o.scenes.forEach((i, l) => {
198
+ if (!(l < 2))
199
+ for (const m of [9, 10]) {
200
+ const r = M(o, l, m);
201
+ if (!r || c.has(r) || !t.has(r)) continue;
202
+ c.add(r);
203
+ const f = S(t, r);
204
+ n.push({ name: `scene ${l} ${r}`, pixels: f.pixels, palette: f.palette });
205
+ }
206
+ }), n;
207
+ }
208
+ function mt(t) {
209
+ const e = (s, a) => t.pixels[a * y + s], o = e(24, 16);
210
+ let [n, c, i, l] = [24, 24, 16, 16];
211
+ for (; n > 0 && e(n - 1, 16) === o; ) n--;
212
+ for (; c < y - 1 && e(c + 1, 16) === o; ) c++;
213
+ for (let s = n + 2; s <= c - 2; s++) {
214
+ if (e(s, 16) !== o) continue;
215
+ let [a, p] = [16, 16];
216
+ for (; a > 0 && e(s, a - 1) === o; ) a--;
217
+ for (; p < w - 1 && e(s, p + 1) === o; ) p++;
218
+ i = Math.min(i, a), l = Math.max(l, p);
219
+ }
220
+ if (c - n < 100 || l - i < 30 || l - i > 90) return [];
221
+ const m = /* @__PURE__ */ new Set();
222
+ for (let s = Math.max(0, n - 6); s <= Math.min(y - 1, c + 6); s++) for (let a = Math.max(0, i - 6); a < i; a++) m.add(e(s, a));
223
+ for (let s = i; s <= Math.min(l, i + 6); s++) for (const a of [n - 1, n - 2, n - 3, c + 1, c + 2, c + 3]) m.add(e(a, s));
224
+ const r = /* @__PURE__ */ new Set();
225
+ for (let s = i; s <= l; s++) for (let a = n; a <= c; a++) e(a, s) !== o && !m.has(e(a, s)) && r.add(e(a, s));
226
+ const f = [];
227
+ for (const [s, a, p] of [
228
+ ["left", n - 14, n - 1],
229
+ ["right", c + 1, c + 14]
230
+ ]) {
231
+ let x = 0;
232
+ for (let h = i; h <= l; h++) for (let u = Math.max(0, a); u <= Math.min(y - 1, p); u++) r.has(e(u, h)) && x++;
233
+ x && f.push(`text runs past the ${s} edge of its box (${x} pixels outside it)`);
234
+ }
235
+ return f;
236
+ }
237
+ export {
238
+ w as H,
239
+ y as W,
240
+ mt as cardOverflow,
241
+ xt as checkTextScreen,
242
+ ut as levelCards,
243
+ ft as readDisk,
244
+ ht as renderRgb,
245
+ pt as textScreens
246
+ };