@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.
- package/CHANGELOG.md +44 -0
- package/NOTICE.md +105 -3
- package/README.md +301 -15
- package/dist/audio-files.js +82 -0
- package/dist/audio.js +23 -138
- package/dist/block-merge.js +43 -0
- package/dist/color-reduce.js +44 -0
- package/dist/colors.js +87 -0
- package/dist/delta.js +75 -0
- package/dist/disk-diff.js +220 -0
- package/dist/drawing.js +83 -869
- package/dist/embroidery/compile.js +85 -0
- package/dist/embroidery/dst.js +79 -0
- package/dist/embroidery/exp.js +26 -0
- package/dist/embroidery/fill.js +49 -0
- package/dist/embroidery/geom.js +82 -0
- package/dist/embroidery/pes.js +79 -0
- package/dist/embroidery/satin.js +29 -0
- package/dist/embroidery/simulate.js +30 -0
- package/dist/embroidery/strokeFont.js +253 -0
- package/dist/embroidery/svg.js +24 -0
- package/dist/embroidery/types.js +13 -0
- package/dist/embroidery/units.js +26 -0
- package/dist/embroidery/validate.js +15 -0
- package/dist/formats/blocks.js +1 -103
- package/dist/formats/character.js +1 -83
- package/dist/formats/cmf.js +1 -37
- package/dist/formats/fli.js +1 -296
- package/dist/formats/fliLimits.js +1 -54
- package/dist/formats/game.js +1 -193
- package/dist/formats/gif.js +1 -125
- package/dist/formats/graphicScripts.js +1 -44
- package/dist/formats/map.js +1 -38
- package/dist/formats/monster.js +1 -69
- package/dist/formats/palette.js +1 -58
- package/dist/formats/recording.js +1 -17
- package/dist/formats/sound.js +1 -44
- package/dist/formats/voc.js +1 -303
- package/dist/gif-shrink.js +56 -0
- package/dist/image/png.js +42 -0
- package/dist/images.js +81 -43
- package/dist/kit/actors.js +19 -0
- package/dist/kit/align.js +204 -0
- package/dist/kit/blit.js +45 -0
- package/dist/kit/blockRoles.js +97 -0
- package/dist/kit/clips.js +40 -0
- package/dist/kit/coverPaint.js +18 -0
- package/dist/kit/disk.js +76 -0
- package/dist/kit/fadeOut.js +13 -0
- package/dist/kit/fliClips.js +133 -0
- package/dist/kit/fliShrink.js +277 -0
- package/dist/kit/gameSim.js +235 -0
- package/dist/kit/hopBot.js +142 -0
- package/dist/kit/levelGen.js +1423 -0
- package/dist/kit/levelGrid.js +33 -0
- package/dist/kit/levelPicture.js +27 -0
- package/dist/kit/menuVersion.js +19 -0
- package/dist/kit/microText.js +35 -0
- package/dist/kit/mumble.js +74 -0
- package/dist/kit/music.js +8 -0
- package/dist/kit/palRamps.js +32 -0
- package/dist/kit/palette.js +49 -0
- package/dist/kit/pcText.js +72 -0
- package/dist/kit/photo.js +150 -0
- package/dist/kit/pixels.js +79 -0
- package/dist/kit/png.js +40 -0
- package/dist/kit/quantize.js +72 -0
- package/dist/kit/raytrace.js +379 -0
- package/dist/kit/recordedDemo.js +10 -0
- package/dist/kit/reel.js +77 -0
- package/dist/kit/road3d.js +67 -0
- package/dist/kit/routeChecks.js +8 -0
- package/dist/kit/saveSlots.js +11 -0
- package/dist/kit/sceneInit.js +13 -0
- package/dist/kit/sceneSim.js +112 -0
- package/dist/kit/screenText.js +15 -0
- package/dist/kit/sdftext.js +237 -0
- package/dist/kit/shading.js +69 -0
- package/dist/kit/song.js +251 -0
- package/dist/kit/songFx.js +179 -0
- package/dist/kit/sound.js +52 -0
- package/dist/kit/synthParts.js +20 -0
- package/dist/kit/tar.js +53 -0
- package/dist/kit/textBounds.js +84 -0
- package/dist/kit/textfit.js +246 -0
- package/dist/kit/transforms.js +57 -0
- package/dist/kit/tune.js +21 -0
- package/dist/look-alike.js +50 -0
- package/dist/menu-version.js +4 -0
- package/dist/mesh/colorBodies.js +137 -0
- package/dist/mesh/decimate.js +207 -0
- package/dist/mesh/meshCheck.js +51 -0
- package/dist/mesh/overhang.js +41 -0
- package/dist/mesh/sampledField.js +12 -0
- package/dist/mesh/stl.js +36 -0
- package/dist/mesh/surfaceNets.js +79 -0
- package/dist/mesh/tetraMesh.js +62 -0
- package/dist/mesh/threeMf.js +58 -0
- package/dist/mesh/zipFile.js +52 -0
- package/dist/microFont.js +101 -0
- package/dist/music/compose.js +72 -0
- package/dist/pack/meshPack.js +198 -0
- package/dist/pack/threeMfPack.js +92 -0
- package/dist/palette-reserve.js +116 -0
- package/dist/palettes.js +138 -0
- package/dist/release-notes.js +40 -0
- package/dist/simulation.js +16 -2774
- package/dist/text.js +74 -0
- package/dist/types/audio.d.ts +4 -0
- package/dist/types/audioFiles.d.ts +22 -0
- package/dist/types/audioWav.d.ts +4 -0
- package/dist/types/blockMerge.d.ts +24 -0
- package/dist/types/colorReduce.d.ts +23 -0
- package/dist/types/{web/packages/tools/src/colors.d.ts → colors.d.ts} +6 -0
- package/dist/types/delta.d.ts +32 -0
- package/dist/types/diskDiff.d.ts +47 -0
- package/dist/types/drawing.d.ts +15 -0
- package/dist/types/embroidery/compile.d.ts +3 -0
- package/dist/types/embroidery/dst.d.ts +13 -0
- package/dist/types/embroidery/exp.d.ts +8 -0
- package/dist/types/embroidery/fill.d.ts +6 -0
- package/dist/types/embroidery/geom.d.ts +19 -0
- package/dist/types/embroidery/pes.d.ts +10 -0
- package/dist/types/embroidery/satin.d.ts +11 -0
- package/dist/types/embroidery/simulate.d.ts +19 -0
- package/dist/types/embroidery/strokeFont.d.ts +20 -0
- package/dist/types/embroidery/svg.d.ts +3 -0
- package/dist/types/embroidery/types.d.ts +70 -0
- package/dist/types/embroidery/units.d.ts +10 -0
- package/dist/types/embroidery/validate.d.ts +22 -0
- package/dist/types/formats/blocks.d.ts +1 -0
- package/dist/types/formats/character.d.ts +1 -0
- package/dist/types/formats/cmf.d.ts +1 -0
- package/dist/types/formats/fli.d.ts +1 -0
- package/dist/types/formats/fliLimits.d.ts +1 -0
- package/dist/types/formats/game.d.ts +1 -0
- package/dist/types/formats/gif.d.ts +1 -0
- package/dist/types/formats/graphicScripts.d.ts +1 -0
- package/dist/types/formats/map.d.ts +1 -0
- package/dist/types/formats/monster.d.ts +1 -0
- package/dist/types/formats/palette.d.ts +1 -0
- package/dist/types/formats/recording.d.ts +1 -0
- package/dist/types/formats/sound.d.ts +1 -0
- package/dist/types/formats/voc.d.ts +1 -0
- package/dist/types/gifShrink.d.ts +8 -0
- package/dist/types/image/animatedGif.d.ts +9 -0
- package/dist/types/image/surface.d.ts +26 -0
- package/dist/types/images.d.ts +13 -0
- package/dist/types/kit/actors.d.ts +7 -0
- package/dist/types/kit/align.d.ts +93 -0
- package/dist/types/kit/audioEvents.d.ts +26 -0
- package/dist/types/kit/blit.d.ts +20 -0
- package/dist/types/kit/blockRoles.d.ts +243 -0
- package/dist/types/{games/kit → kit}/clips.d.ts +1 -1
- package/dist/types/kit/coverPaint.d.ts +7 -0
- package/dist/types/kit/disk.d.ts +15 -0
- package/dist/types/kit/fadeOut.d.ts +12 -0
- package/dist/types/kit/fliClips.d.ts +32 -0
- package/dist/types/kit/fliShrink.d.ts +149 -0
- package/dist/types/{games/kit → kit}/gameSim.d.ts +9 -5
- package/dist/types/kit/hopBot.d.ts +72 -0
- package/dist/types/kit/laserClearance.d.ts +16 -0
- package/dist/types/kit/laserJoints.d.ts +39 -0
- package/dist/types/kit/laserLayout.d.ts +54 -0
- package/dist/types/kit/laserPixels.d.ts +52 -0
- package/dist/types/kit/laserPreview.d.ts +9 -0
- package/dist/types/kit/laserSvg.d.ts +35 -0
- package/dist/types/kit/levelGen/castle.d.ts +17 -0
- package/dist/types/kit/levelGen/dungeon.d.ts +11 -0
- package/dist/types/kit/levelGen/forest.d.ts +17 -0
- package/dist/types/kit/levelGen/furnish.d.ts +31 -0
- package/dist/types/kit/levelGen/grid.d.ts +46 -0
- package/dist/types/kit/levelGen/index.d.ts +138 -0
- package/dist/types/kit/levelGen/interior.d.ts +18 -0
- package/dist/types/kit/levelGen/jumpModel.d.ts +78 -0
- package/dist/types/kit/levelGen/needs.d.ts +44 -0
- package/dist/types/kit/levelGen/overworld.d.ts +21 -0
- package/dist/types/kit/levelGen/platform.d.ts +59 -0
- package/dist/types/kit/levelGen/platformCap.d.ts +13 -0
- package/dist/types/kit/levelGen/platformReach.d.ts +37 -0
- package/dist/types/kit/levelGen/props.d.ts +37 -0
- package/dist/types/kit/levelGen/town.d.ts +24 -0
- package/dist/types/kit/levelGrid.d.ts +16 -0
- package/dist/types/kit/levelPicture.d.ts +9 -0
- package/dist/types/kit/menuVersion.d.ts +7 -0
- package/dist/types/kit/microText.d.ts +18 -0
- package/dist/types/kit/mumble.d.ts +41 -0
- package/dist/types/kit/music.d.ts +1 -0
- package/dist/types/kit/palMerge.d.ts +10 -0
- package/dist/types/kit/palRamps.d.ts +28 -0
- package/dist/types/kit/pcText.d.ts +19 -0
- package/dist/types/kit/photo.d.ts +69 -0
- package/dist/types/kit/png.d.ts +7 -0
- package/dist/types/kit/quantize.d.ts +20 -0
- package/dist/types/kit/raytrace.d.ts +169 -0
- package/dist/types/kit/recordedDemo.d.ts +1 -0
- package/dist/types/kit/road3d.d.ts +71 -0
- package/dist/types/kit/routeChecks.d.ts +6 -0
- package/dist/types/kit/saveSlots.d.ts +17 -0
- package/dist/types/kit/sceneInit.d.ts +11 -0
- package/dist/types/{games/kit → kit}/sceneSim.d.ts +5 -5
- package/dist/types/kit/screenText.d.ts +3 -0
- package/dist/types/kit/sdftext.d.ts +34 -0
- package/dist/types/kit/shading.d.ts +23 -0
- package/dist/types/kit/shareBlocks.d.ts +20 -0
- package/dist/types/kit/song.d.ts +89 -0
- package/dist/types/kit/songFx.d.ts +99 -0
- package/dist/types/kit/synthParts.d.ts +7 -0
- package/dist/types/kit/tar.d.ts +13 -0
- package/dist/types/kit/textfit.d.ts +74 -0
- package/dist/types/kit/transforms.d.ts +8 -0
- package/dist/types/lookAlike.d.ts +31 -0
- package/dist/types/menuVersionEntry.d.ts +1 -0
- package/dist/types/mesh/colorBodies.d.ts +18 -0
- package/dist/types/mesh/decimate.d.ts +10 -0
- package/dist/types/mesh/fieldTrinket.d.ts +40 -0
- package/dist/types/mesh/figureShapes.d.ts +24 -0
- package/dist/types/mesh/mesh.d.ts +9 -0
- package/dist/types/mesh/meshCheck.d.ts +22 -0
- package/dist/types/mesh/overhang.d.ts +24 -0
- package/dist/types/mesh/pixelFigure.d.ts +41 -0
- package/dist/types/mesh/sampledField.d.ts +3 -0
- package/dist/types/mesh/sdfShapes.d.ts +20 -0
- package/dist/types/mesh/stl.d.ts +9 -0
- package/dist/types/mesh/strokeText.d.ts +8 -0
- package/dist/types/mesh/surfaceNets.d.ts +14 -0
- package/dist/types/mesh/tetraMesh.d.ts +4 -0
- package/dist/types/mesh/threeMf.d.ts +12 -0
- package/dist/types/mesh/trinketKinds.d.ts +72 -0
- package/dist/types/mesh/trinketTool.d.ts +26 -0
- package/dist/types/mesh/voxel.d.ts +10 -0
- package/dist/types/mesh/zipFile.d.ts +13 -0
- package/dist/types/microFont.d.ts +6 -0
- package/dist/types/pack/meshPack.d.ts +26 -0
- package/dist/types/pack/threeMfPack.d.ts +11 -0
- package/dist/types/palettePresetData.d.ts +4 -0
- package/dist/types/palettePresets.d.ts +12 -0
- package/dist/types/paletteReserve.d.ts +52 -0
- package/dist/types/palettes.d.ts +4 -0
- package/dist/types/releaseNotes.d.ts +3 -0
- package/dist/types/simulation.d.ts +6 -0
- package/dist/types/{web/packages/tools/src/text.d.ts → text.d.ts} +6 -6
- package/package.json +145 -15
- package/dist/binary-D7wuaC5g.js +0 -120
- package/dist/pixels-DzfIIUOl.js +0 -76
- package/dist/types/games/kit/blit.d.ts +0 -10
- package/dist/types/games/kit/music.d.ts +0 -1
- package/dist/types/games/kit/pcText.d.ts +0 -8
- package/dist/types/games/kit/shading.d.ts +0 -11
- package/dist/types/web/packages/tools/src/audio.d.ts +0 -3
- package/dist/types/web/packages/tools/src/drawing.d.ts +0 -10
- package/dist/types/web/packages/tools/src/images.d.ts +0 -2
- package/dist/types/web/packages/tools/src/microFont.d.ts +0 -1
- package/dist/types/web/packages/tools/src/simulation.d.ts +0 -3
- package/dist/types/web/scripts/cdGames.d.ts +0 -103
- package/dist/types/web/scripts/gameShots.d.ts +0 -12
- package/dist/types/web/scripts/ogImage.d.ts +0 -21
- package/dist/types/web/src/audio/cmfLoad.d.ts +0 -7
- package/dist/types/web/src/audio/cmfPlayer.d.ts +0 -69
- package/dist/types/web/src/audio/context.d.ts +0 -12
- package/dist/types/web/src/audio/engine.d.ts +0 -39
- package/dist/types/web/src/audio/music.worklet.d.ts +0 -14
- package/dist/types/web/src/audio/opl.d.ts +0 -37
- package/dist/types/web/src/audio/output.d.ts +0 -13
- package/dist/types/web/src/desk/boxes/boxFacts.d.ts +0 -85
- package/dist/types/web/src/dosPlayer/fileExtensions.d.ts +0 -44
- package/dist/types/web/src/dosPlayer/patchRules.d.ts +0 -24
- package/dist/types/web/src/dosPlayer/patchTable.d.ts +0 -80
- package/dist/types/web/src/edition.d.ts +0 -6
- package/dist/types/web/src/eggs/eggState.d.ts +0 -26
- package/dist/types/web/src/eggs/eggs.d.ts +0 -31
- package/dist/types/web/src/engine/character.d.ts +0 -30
- package/dist/types/web/src/engine/funcKeys.d.ts +0 -33
- package/dist/types/web/src/engine/game.d.ts +0 -52
- package/dist/types/web/src/engine/keys.d.ts +0 -17
- package/dist/types/web/src/engine/machine.d.ts +0 -99
- package/dist/types/web/src/engine/menus.d.ts +0 -46
- package/dist/types/web/src/engine/monsters.d.ts +0 -19
- package/dist/types/web/src/engine/playGain.d.ts +0 -11
- package/dist/types/web/src/engine/playerLook.d.ts +0 -26
- package/dist/types/web/src/engine/recorder.d.ts +0 -60
- package/dist/types/web/src/engine/render.d.ts +0 -8
- package/dist/types/web/src/engine/scene.d.ts +0 -156
- package/dist/types/web/src/engine/scroll.d.ts +0 -16
- package/dist/types/web/src/engine/showGraphic.d.ts +0 -39
- package/dist/types/web/src/engine/slowPc.d.ts +0 -62
- package/dist/types/web/src/engine/touch.d.ts +0 -33
- package/dist/types/web/src/engine/world.d.ts +0 -215
- package/dist/types/web/src/export/gameAbout.d.ts +0 -15
- package/dist/types/web/src/formats/binary.d.ts +0 -44
- package/dist/types/web/src/formats/blocks.d.ts +0 -52
- package/dist/types/web/src/formats/character.d.ts +0 -65
- package/dist/types/web/src/formats/cmf.d.ts +0 -33
- package/dist/types/web/src/formats/fli.d.ts +0 -45
- package/dist/types/web/src/formats/fliLimits.d.ts +0 -13
- package/dist/types/web/src/formats/game.d.ts +0 -72
- package/dist/types/web/src/formats/gif.d.ts +0 -15
- package/dist/types/web/src/formats/graphicScripts.d.ts +0 -18
- package/dist/types/web/src/formats/highscore.d.ts +0 -10
- package/dist/types/web/src/formats/map.d.ts +0 -24
- package/dist/types/web/src/formats/monster.d.ts +0 -48
- package/dist/types/web/src/formats/palette.d.ts +0 -15
- package/dist/types/web/src/formats/recording.d.ts +0 -7
- package/dist/types/web/src/formats/sound.d.ts +0 -13
- package/dist/types/web/src/formats/voc.d.ts +0 -13
- package/dist/types/web/src/gfx/cp437Glyphs.d.ts +0 -2
- package/dist/types/web/src/gfx/font8x8.d.ts +0 -2
- package/dist/types/web/src/gfx/levelPicture.d.ts +0 -81
- package/dist/types/web/src/gfx/screen.d.ts +0 -46
- package/dist/types/web/src/gfx/titlePicture.d.ts +0 -21
- package/dist/types/web/src/input/chords.d.ts +0 -22
- package/dist/types/web/src/input/deskMouse.d.ts +0 -14
- package/dist/types/web/src/input/keyboard.d.ts +0 -39
- package/dist/types/web/src/input/scancodes.d.ts +0 -3
- package/dist/types/web/src/manual/printables/types.d.ts +0 -277
- package/dist/types/web/src/project/bizarre.d.ts +0 -28
- package/dist/types/web/src/project/companion.d.ts +0 -35
- package/dist/types/web/src/project/diskFacts.d.ts +0 -30
- package/dist/types/web/src/project/files.d.ts +0 -124
- package/dist/types/web/src/project/gameFiles.d.ts +0 -49
- package/dist/types/web/src/project/gamePack.d.ts +0 -17
- package/dist/types/web/src/project/health.d.ts +0 -30
- package/dist/types/web/src/project/secretGames.d.ts +0 -19
- package/dist/types/web/src/project/storage.d.ts +0 -46
- package/dist/types/web/src/project/streamGame.d.ts +0 -38
- package/dist/types/web/src/project/zip.d.ts +0 -33
- package/dist/types/web/src/retro/dos/disks.d.ts +0 -33
- package/dist/types/web/src/retro/text/cp437.d.ts +0 -4
- package/dist/types/web/src/seededRandom.d.ts +0 -6
- package/dist/types/web/src/tinHearts/deskHearts.d.ts +0 -33
- package/dist/types/web/src/tinHearts/manifest.d.ts +0 -30
- package/dist/types/web/src/tinHearts/tinHearts.d.ts +0 -84
- package/dist/types/web/src/walkthrough/format.d.ts +0 -92
- package/dist/types/web/src/walkthrough/madeUpScores.d.ts +0 -6
- package/dist/types/web/src/walkthrough/runtime.d.ts +0 -134
- /package/dist/types/{web/src/assistant → image}/png.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/palette.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/pixels.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/reel.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/sound.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/textBounds.d.ts +0 -0
- /package/dist/types/{games/kit → kit}/tune.d.ts +0 -0
- /package/dist/types/{web/src/audio → music}/compose.d.ts +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { moveChars as f } from "@lewismoten/gamemaker-sandbox-engine/engine/character";
|
|
2
|
+
import { simKeyPress as u } from "@lewismoten/gamemaker-sandbox-engine/engine/keys";
|
|
3
|
+
import { blockBirthMonsters as k, moveAllMonsters as p } from "@lewismoten/gamemaker-sandbox-engine/engine/monsters";
|
|
4
|
+
import { updateCharDrawState as y } from "@lewismoten/gamemaker-sandbox-engine/engine/render";
|
|
5
|
+
import { startSceneInits as g, changeBlocks as w } from "@lewismoten/gamemaker-sandbox-engine/engine/scene";
|
|
6
|
+
import { initScroll as b, drawScroll as S, changeScroll as A } from "@lewismoten/gamemaker-sandbox-engine/engine/scroll";
|
|
7
|
+
import { getTouchBlocks as x } from "@lewismoten/gamemaker-sandbox-engine/engine/touch";
|
|
8
|
+
import { createWorld as M, padBlocks as a, BACKBL as B, CHARBL as _, newCharInfo as j, LASTMM as C } from "@lewismoten/gamemaker-sandbox-engine/engine/world";
|
|
9
|
+
import { MONBL as O } from "@lewismoten/gamemaker-sandbox-engine/formats/blocks";
|
|
10
|
+
function c(n) {
|
|
11
|
+
if (n === null || typeof n != "object") return n;
|
|
12
|
+
if (ArrayBuffer.isView(n)) return n.slice();
|
|
13
|
+
if (Array.isArray(n)) return n.map(c);
|
|
14
|
+
const t = {};
|
|
15
|
+
for (const s in n) t[s] = c(n[s]);
|
|
16
|
+
return t;
|
|
17
|
+
}
|
|
18
|
+
class P {
|
|
19
|
+
constructor(t, s, r = j(), e = 1, h = !0) {
|
|
20
|
+
this.scene = t, this.randA = e >>> 0;
|
|
21
|
+
const i = M(t.map, { play: (l) => (this.sounds.push(l), !0) }, () => this.rand());
|
|
22
|
+
i.bg = a(t.bbl, B), i.mblk = a(t.mbl, O), i.cblk = a(t.cbl, _), i.mon = t.mon ?? [], i.noMons = !t.mon, i.chr = structuredClone(t.chr), i.ci = r, i.clock = 1, this.w = i, g(i, s);
|
|
23
|
+
const o = h ? 255 : 0;
|
|
24
|
+
b(i, { up: o, down: o, left: o, right: o }), i.gclk = i.clock, i.joyOldTime = i.clock;
|
|
25
|
+
}
|
|
26
|
+
scene;
|
|
27
|
+
w;
|
|
28
|
+
held = /* @__PURE__ */ new Set();
|
|
29
|
+
doScroll = !1;
|
|
30
|
+
sounds = [];
|
|
31
|
+
/** Ticks played so far. */
|
|
32
|
+
ticks = 0;
|
|
33
|
+
/** Called with every key event (scan, bit 7 = released), e.g. to record a demo. */
|
|
34
|
+
onKey;
|
|
35
|
+
/** Link index reached (-1 = none yet). */
|
|
36
|
+
link = -1;
|
|
37
|
+
dead = !1;
|
|
38
|
+
/** kit/pixels.ts rng() (mulberry32), with its state out where a snapshot can keep it. */
|
|
39
|
+
randA;
|
|
40
|
+
rand() {
|
|
41
|
+
this.randA = this.randA + 1831565813 >>> 0;
|
|
42
|
+
let t = this.randA;
|
|
43
|
+
return t = Math.imul(t ^ t >>> 15, t | 1), t ^= t + Math.imul(t ^ t >>> 7, t | 61), ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
44
|
+
}
|
|
45
|
+
/** Everything that changes as the scene plays, to try a move and take it back with restore(). */
|
|
46
|
+
snapshot() {
|
|
47
|
+
const { sound: t, rand: s, joystick: r, bg: e, mblk: h, cblk: i, mon: o, palette: l, chr: d, ...m } = this.w;
|
|
48
|
+
return {
|
|
49
|
+
w: c(m),
|
|
50
|
+
chr: { ...d, x: [...d.x], y: [...d.y] },
|
|
51
|
+
randA: this.randA,
|
|
52
|
+
held: [...this.held],
|
|
53
|
+
pending: [...this.pending],
|
|
54
|
+
doScroll: this.doScroll,
|
|
55
|
+
sounds: this.sounds.length,
|
|
56
|
+
ticks: this.ticks,
|
|
57
|
+
link: this.link,
|
|
58
|
+
dead: this.dead
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
restore(t) {
|
|
62
|
+
const { ci: s, ...r } = c(t.w);
|
|
63
|
+
Object.assign(this.w, r, { chr: { ...t.chr, x: [...t.chr.x], y: [...t.chr.y] } }), Object.assign(this.w.ci, s), this.randA = t.randA, this.held = new Set(t.held), this.pending = [...t.pending], this.doScroll = t.doScroll, this.sounds.length = t.sounds, this.ticks = t.ticks, this.link = t.link, this.dead = t.dead;
|
|
64
|
+
}
|
|
65
|
+
press(t) {
|
|
66
|
+
this.held.has(t) || (this.held.add(t), this.event(t));
|
|
67
|
+
}
|
|
68
|
+
release(t) {
|
|
69
|
+
this.held.has(t) && (this.held.delete(t), this.event(t | 128));
|
|
70
|
+
}
|
|
71
|
+
pending = [];
|
|
72
|
+
event(t) {
|
|
73
|
+
this.pending.push(t), this.onKey?.(t);
|
|
74
|
+
}
|
|
75
|
+
/** One 18.2 Hz game tick (8 scroll steps + tick()). */
|
|
76
|
+
async tick() {
|
|
77
|
+
const t = this.w;
|
|
78
|
+
this.ticks++;
|
|
79
|
+
for (let e = 0; e < 8; e++) this.doScroll && S(t);
|
|
80
|
+
t.clock++, t.noMons || (k(t), p(t));
|
|
81
|
+
const s = t.chr;
|
|
82
|
+
if (this.pending.length && (!s.sequences[s.cseq].ground || s.cframe === 0))
|
|
83
|
+
for (const e of this.pending.splice(0)) u(t, e);
|
|
84
|
+
let r = 0;
|
|
85
|
+
do
|
|
86
|
+
await f(t, async () => -1) && (this.dead = !0);
|
|
87
|
+
while (t.chr.cframe === -1 && !this.dead && r++ < 50);
|
|
88
|
+
if (w(t), y(t), this.doScroll = A(t) !== 0, t.monsolid = 0, t.mmSolid = C, this.scene.links) {
|
|
89
|
+
const e = x(t);
|
|
90
|
+
this.scene.links.forEach((h, i) => {
|
|
91
|
+
this.link < 0 && e.blks.some(([o, l]) => o === h.from.x && l === h.from.y) && (this.link = i);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async run(t, s) {
|
|
96
|
+
for (let r = 0; r < t && (await this.tick(), !(s?.(r) === !0 || this.dead || this.link >= 0)); r++)
|
|
97
|
+
;
|
|
98
|
+
}
|
|
99
|
+
/** Live monsters called `name`, with their block positions. */
|
|
100
|
+
monsters(t) {
|
|
101
|
+
const s = this.scene.names?.indexOf(t) ?? -1;
|
|
102
|
+
return this.w.mm.flatMap((r, e) => r.monnum === s ? [{ x: this.w.mi[e].curx[0], y: this.w.mi[e].cury[0] }] : []);
|
|
103
|
+
}
|
|
104
|
+
/** Character position in pixels (x of its column, y of its bottom block). */
|
|
105
|
+
get pos() {
|
|
106
|
+
const t = this.w.chr;
|
|
107
|
+
return { x: t.x[0] * 20 + t.x[1], y: t.y[0] * 20 + t.y[1], bx: t.x[0], by: t.y[0] };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export {
|
|
111
|
+
P as Sim
|
|
112
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const e = (r, o = 1) => {
|
|
2
|
+
for (const t of r) if (t.length > 30) throw new Error(`Text line over 30 columns: "${t}"`);
|
|
3
|
+
if (r.length > 16 * o) throw new Error(`Text over ${o} page(s): "${r[0]}"`);
|
|
4
|
+
for (; r.length % 16; ) r.push("");
|
|
5
|
+
return r.join(`
|
|
6
|
+
`);
|
|
7
|
+
}, n = (r, o) => {
|
|
8
|
+
const t = r.get(o);
|
|
9
|
+
if (!t) throw new Error(`No sprite ${o}`);
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
e as page,
|
|
14
|
+
n as sprite
|
|
15
|
+
};
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
function u(m, t, n, a, r, s, i = 14) {
|
|
2
|
+
const h = [];
|
|
3
|
+
for (let o = 0; o <= i; o++) {
|
|
4
|
+
const c = (r + (s - r) * o / i) * Math.PI / 180;
|
|
5
|
+
h.push([m + Math.cos(c) * n, t + Math.sin(c) * a]);
|
|
6
|
+
}
|
|
7
|
+
return h;
|
|
8
|
+
}
|
|
9
|
+
const G = (m, t) => [[m, 0.88], [m + t - 0.19, 0.88], ...u(m + t - 0.19, 0.69, 0.19, 0.19, 90, -90, 10), [m, 0.5]], S = (m, t) => [[m, 0.5], [m + t - 0.19, 0.5], ...u(m + t - 0.19, 0.31, 0.19, 0.19, 90, -90, 10), [m, 0.12]], X = {
|
|
10
|
+
S: [[...u(0.33, 0.69, 0.22, 0.19, 15, 270), ...u(0.33, 0.31, 0.22, 0.19, 90, -165)]],
|
|
11
|
+
A: [
|
|
12
|
+
[
|
|
13
|
+
[0.1, 0.12],
|
|
14
|
+
[0.36, 0.88],
|
|
15
|
+
[0.62, 0.12]
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
[0.2, 0.38],
|
|
19
|
+
[0.52, 0.38]
|
|
20
|
+
]
|
|
21
|
+
],
|
|
22
|
+
N: [
|
|
23
|
+
[
|
|
24
|
+
[0.12, 0.12],
|
|
25
|
+
[0.12, 0.88],
|
|
26
|
+
[0.56, 0.12],
|
|
27
|
+
[0.56, 0.88]
|
|
28
|
+
]
|
|
29
|
+
],
|
|
30
|
+
D: [[[0.12, 0.12], [0.12, 0.88], [0.28, 0.88], ...u(0.28, 0.5, 0.3, 0.38, 90, -90), [0.12, 0.12]]],
|
|
31
|
+
B: [
|
|
32
|
+
[
|
|
33
|
+
[0.12, 0.12],
|
|
34
|
+
[0.12, 0.88]
|
|
35
|
+
],
|
|
36
|
+
G(0.12, 0.44),
|
|
37
|
+
S(0.12, 0.48)
|
|
38
|
+
],
|
|
39
|
+
O: [u(0.38, 0.5, 0.26, 0.38, 0, 360, 28)],
|
|
40
|
+
X: [
|
|
41
|
+
[
|
|
42
|
+
[0.12, 0.12],
|
|
43
|
+
[0.58, 0.88]
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
[0.12, 0.88],
|
|
47
|
+
[0.58, 0.12]
|
|
48
|
+
]
|
|
49
|
+
],
|
|
50
|
+
F: [
|
|
51
|
+
[
|
|
52
|
+
[0.12, 0.12],
|
|
53
|
+
[0.12, 0.88],
|
|
54
|
+
[0.54, 0.88]
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
[0.12, 0.52],
|
|
58
|
+
[0.44, 0.52]
|
|
59
|
+
]
|
|
60
|
+
],
|
|
61
|
+
T: [
|
|
62
|
+
[
|
|
63
|
+
[0.08, 0.88],
|
|
64
|
+
[0.58, 0.88]
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
[0.33, 0.88],
|
|
68
|
+
[0.33, 0.12]
|
|
69
|
+
]
|
|
70
|
+
],
|
|
71
|
+
W: [
|
|
72
|
+
[
|
|
73
|
+
[0.08, 0.88],
|
|
74
|
+
[0.24, 0.12],
|
|
75
|
+
[0.41, 0.62],
|
|
76
|
+
[0.58, 0.12],
|
|
77
|
+
[0.74, 0.88]
|
|
78
|
+
]
|
|
79
|
+
],
|
|
80
|
+
R: [
|
|
81
|
+
[
|
|
82
|
+
[0.12, 0.12],
|
|
83
|
+
[0.12, 0.88]
|
|
84
|
+
],
|
|
85
|
+
G(0.12, 0.46),
|
|
86
|
+
[
|
|
87
|
+
[0.3, 0.5],
|
|
88
|
+
[0.56, 0.12]
|
|
89
|
+
]
|
|
90
|
+
],
|
|
91
|
+
"-": [
|
|
92
|
+
[
|
|
93
|
+
[0.12, 0.5],
|
|
94
|
+
[0.5, 0.5]
|
|
95
|
+
]
|
|
96
|
+
],
|
|
97
|
+
"=": [
|
|
98
|
+
[
|
|
99
|
+
[0.12, 0.33],
|
|
100
|
+
[0.56, 0.33]
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
[0.12, 0.67],
|
|
104
|
+
[0.56, 0.67]
|
|
105
|
+
]
|
|
106
|
+
],
|
|
107
|
+
G: [[...u(0.38, 0.5, 0.26, 0.38, 40, 360, 26), [0.4, 0.5]]],
|
|
108
|
+
M: [
|
|
109
|
+
[
|
|
110
|
+
[0.12, 0.12],
|
|
111
|
+
[0.12, 0.88],
|
|
112
|
+
[0.4, 0.4],
|
|
113
|
+
[0.68, 0.88],
|
|
114
|
+
[0.68, 0.12]
|
|
115
|
+
]
|
|
116
|
+
],
|
|
117
|
+
K: [
|
|
118
|
+
[
|
|
119
|
+
[0.12, 0.12],
|
|
120
|
+
[0.12, 0.88]
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
[0.56, 0.88],
|
|
124
|
+
[0.14, 0.44]
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
[0.3, 0.56],
|
|
128
|
+
[0.58, 0.12]
|
|
129
|
+
]
|
|
130
|
+
],
|
|
131
|
+
E: [
|
|
132
|
+
[
|
|
133
|
+
[0.54, 0.88],
|
|
134
|
+
[0.12, 0.88],
|
|
135
|
+
[0.12, 0.12],
|
|
136
|
+
[0.54, 0.12]
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
[0.12, 0.5],
|
|
140
|
+
[0.44, 0.5]
|
|
141
|
+
]
|
|
142
|
+
]
|
|
143
|
+
};
|
|
144
|
+
function A(m, t, n, a = 0.1) {
|
|
145
|
+
const r = 0.12 * t, s = [];
|
|
146
|
+
let i = 0;
|
|
147
|
+
for (const o of m) {
|
|
148
|
+
const c = X[o];
|
|
149
|
+
if (!c) {
|
|
150
|
+
i += 0.5 * t;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const e = c.flat().map((f) => f[0]), x = Math.min(...e), M = Math.max(...e);
|
|
154
|
+
for (const f of c)
|
|
155
|
+
for (let l = 1; l < f.length; l++) {
|
|
156
|
+
const [B, T] = [f[l - 1], f[l]];
|
|
157
|
+
s.push([i + (B[0] - x + 0.12) * t, n + B[1] * t, i + (T[0] - x + 0.12) * t, n + T[1] * t, r]);
|
|
158
|
+
}
|
|
159
|
+
i += (M - x + 2 * 0.12 + a) * t;
|
|
160
|
+
}
|
|
161
|
+
const h = (i - a * t) / 2;
|
|
162
|
+
return s.map(([o, c, e, x, M]) => [o - h, c, e - h, x, M]);
|
|
163
|
+
}
|
|
164
|
+
class D {
|
|
165
|
+
constructor(t, n = 8e-3, a = 0.25) {
|
|
166
|
+
this.cell = n, this.cap = a;
|
|
167
|
+
const r = a + 0.05;
|
|
168
|
+
this.x0 = Math.min(...t.map((s) => Math.min(s[0], s[2]) - s[4])) - r, this.x1 = Math.max(...t.map((s) => Math.max(s[0], s[2]) + s[4])) + r, this.y0 = Math.min(...t.map((s) => Math.min(s[1], s[3]) - s[4])) - r, this.y1 = Math.max(...t.map((s) => Math.max(s[1], s[3]) + s[4])) + r, this.nx = Math.ceil((this.x1 - this.x0) / n) + 1, this.ny = Math.ceil((this.y1 - this.y0) / n) + 1, this.d = new Float32Array(this.nx * this.ny).fill(a);
|
|
169
|
+
for (const [s, i, h, o, c] of t) {
|
|
170
|
+
const e = c + a, x = Math.max(0, Math.floor((Math.min(s, h) - e - this.x0) / n)), M = Math.min(this.nx - 1, Math.ceil((Math.max(s, h) + e - this.x0) / n)), f = Math.max(0, Math.floor((Math.min(i, o) - e - this.y0) / n)), l = Math.min(this.ny - 1, Math.ceil((Math.max(i, o) + e - this.y0) / n)), B = h - s, T = o - i, d = B * B + T * T || 1e-9;
|
|
171
|
+
for (let y = f; y <= l; y++)
|
|
172
|
+
for (let p = x; p <= M; p++) {
|
|
173
|
+
const b = this.x0 + p * n - s, v = this.y0 + y * n - i, j = Math.max(0, Math.min(1, (b * B + v * T) / d)), w = Math.hypot(b - B * j, v - T * j) - c, k = y * this.nx + p;
|
|
174
|
+
w < this.d[k] && (this.d[k] = w);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
cell;
|
|
179
|
+
cap;
|
|
180
|
+
x0;
|
|
181
|
+
y0;
|
|
182
|
+
x1;
|
|
183
|
+
y1;
|
|
184
|
+
nx;
|
|
185
|
+
ny;
|
|
186
|
+
d;
|
|
187
|
+
/** The distance at (x, y), bilinear between cells; outside the grid, a safe lower bound. */
|
|
188
|
+
at(t, n) {
|
|
189
|
+
const a = (t - this.x0) / this.cell, r = (n - this.y0) / this.cell;
|
|
190
|
+
if (a < 0 || r < 0 || a >= this.nx - 1 || r >= this.ny - 1) {
|
|
191
|
+
const x = Math.max(this.x0 - t, 0, t - this.x1), M = Math.max(this.y0 - n, 0, n - this.y1);
|
|
192
|
+
return Math.hypot(x, M) + this.cap * 0.5;
|
|
193
|
+
}
|
|
194
|
+
const s = a | 0, i = r | 0, h = a - s, o = r - i, c = i * this.nx + s, e = this.d;
|
|
195
|
+
return (e[c] * (1 - h) + e[c + 1] * h) * (1 - o) + (e[c + this.nx] * (1 - h) + e[c + this.nx + 1] * h) * o;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
class E {
|
|
199
|
+
constructor(t, n, a) {
|
|
200
|
+
this.grid = t, this.bevel = a, this.half = n / 2;
|
|
201
|
+
}
|
|
202
|
+
grid;
|
|
203
|
+
bevel;
|
|
204
|
+
half;
|
|
205
|
+
sdf(t, n, a) {
|
|
206
|
+
const r = this.bevel, s = this.grid.at(t, n) + r, i = Math.abs(a) - this.half + r, h = Math.max(s, 0), o = Math.max(i, 0);
|
|
207
|
+
return Math.min(Math.max(s, i), 0) + Math.sqrt(h * h + o * o) - r;
|
|
208
|
+
}
|
|
209
|
+
/** Where a ray (object space, unit direction) first meets the letters, or -1. */
|
|
210
|
+
trace(t, n, a, r, s, i) {
|
|
211
|
+
const h = this.grid;
|
|
212
|
+
let o = 0, c = 1e9;
|
|
213
|
+
const e = (f, l, B, T) => {
|
|
214
|
+
if (Math.abs(l) < 1e-12) return f >= B && f <= T;
|
|
215
|
+
let d = (B - f) / l, y = (T - f) / l;
|
|
216
|
+
return d > y && ([d, y] = [y, d]), o = Math.max(o, d), c = Math.min(c, y), o <= c;
|
|
217
|
+
}, x = h.cap * 0.5;
|
|
218
|
+
if (!e(t, r, h.x0 + x, h.x1 - x) || !e(n, s, h.y0 + x, h.y1 - x) || !e(a, i, -this.half - 0.01, this.half + 0.01)) return -1;
|
|
219
|
+
let M = o;
|
|
220
|
+
for (let f = 0; f < 96 && M <= c; f++) {
|
|
221
|
+
const l = this.sdf(t + r * M, n + s * M, a + i * M);
|
|
222
|
+
if (l < 15e-4) return M;
|
|
223
|
+
M += l;
|
|
224
|
+
}
|
|
225
|
+
return -1;
|
|
226
|
+
}
|
|
227
|
+
/** The surface normal at a point (object space), from the field's gradient. */
|
|
228
|
+
normal(t, n, a) {
|
|
229
|
+
const s = this.sdf(t + 4e-3, n - 4e-3, a - 4e-3), i = this.sdf(t - 4e-3, n - 4e-3, a + 4e-3), h = this.sdf(t - 4e-3, n + 4e-3, a - 4e-3), o = this.sdf(t + 4e-3, n + 4e-3, a + 4e-3), c = s - i - h + o, e = -s - i + h + o, x = -s + i - h + o, M = Math.hypot(c, e, x) || 1;
|
|
230
|
+
return [c / M, e / M, x / M];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
export {
|
|
234
|
+
D as DistanceGrid,
|
|
235
|
+
E as ExtrudedText,
|
|
236
|
+
A as textStrokes
|
|
237
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { dither as d, rng as v } from "./pixels.js";
|
|
2
|
+
function g(o, n, r, h, a, t) {
|
|
3
|
+
const e = n + Math.max(0, Math.min(1, h)) * (r - n), f = Math.floor(e), M = d(a, t, e - f) ? f + 1 : f;
|
|
4
|
+
return o[Math.max(0, Math.min(o.length - 1, M))];
|
|
5
|
+
}
|
|
6
|
+
const k = [0, 4, 6, 2, 7, 3, 5, 1];
|
|
7
|
+
function z(o, n, r, h, a, t, e, f, M = !1) {
|
|
8
|
+
for (let l = r; l < r + a; l++) {
|
|
9
|
+
const i = (l - r) / Math.max(1, a - 1);
|
|
10
|
+
if (M) {
|
|
11
|
+
const c = e + Math.max(0, Math.min(1, i)) * (f - e), u = Math.floor(c), m = (c - u) * 8 > k[l & 7] ? u + 1 : u;
|
|
12
|
+
o.rect(n, l, h, 1, t[Math.max(0, Math.min(t.length - 1, m))]);
|
|
13
|
+
} else for (let c = n; c < n + h; c++) o.set(c, l, g(t, e, f, i, c, l));
|
|
14
|
+
}
|
|
15
|
+
return o;
|
|
16
|
+
}
|
|
17
|
+
function S(o, n, r, h, a, t, e = 0, f = t.length - 1, M = 1) {
|
|
18
|
+
for (let l = Math.floor(r - a); l <= r + a; l++)
|
|
19
|
+
for (let i = Math.floor(n - h); i <= n + h; i++) {
|
|
20
|
+
const c = (i + 0.5 - n) / h, u = (l + 0.5 - r) / a, m = c * c + u * u;
|
|
21
|
+
if (m > 1) continue;
|
|
22
|
+
const b = (0.62 * Math.sqrt(1 - m) - 0.42 * c - 0.52 * u) * M;
|
|
23
|
+
o.set(i, l, g(t, e, f, (b + 0.35) / 1.2, i, l));
|
|
24
|
+
}
|
|
25
|
+
return o;
|
|
26
|
+
}
|
|
27
|
+
function q(o, n, r, h, a, t, e, f = 1, M = [1, 1, -2, -2]) {
|
|
28
|
+
o.rect(n, r, h, a, t[e]);
|
|
29
|
+
const l = (s) => t[s >= 0 ? Math.min(t.length - 1, e + s) : Math.max(0, e + s)], [i, c, u, m] = M.map(l);
|
|
30
|
+
for (let s = 0; s < f; s++)
|
|
31
|
+
o.rect(n + s, r + s, h - 2 * s, 1, i).rect(n + s, r + s, 1, a - 2 * s, c), o.rect(n + s, r + a - 1 - s, h - 2 * s, 1, u).rect(n + h - 1 - s, r + s, 1, a - 2 * s, m);
|
|
32
|
+
return o;
|
|
33
|
+
}
|
|
34
|
+
function A(o, n, r, h, a, t, e, f, M, l = 0.25) {
|
|
35
|
+
const i = v(M);
|
|
36
|
+
for (let c = r; c < r + a; c++)
|
|
37
|
+
for (let u = n; u < n + h; u++) {
|
|
38
|
+
let m = e;
|
|
39
|
+
i() < l && (m += i() < 0.5 ? -f : f), o.set(u, c, t[Math.max(0, Math.min(t.length - 1, m))]);
|
|
40
|
+
}
|
|
41
|
+
return o;
|
|
42
|
+
}
|
|
43
|
+
function E(o, n, r, h) {
|
|
44
|
+
const a = /* @__PURE__ */ new Map();
|
|
45
|
+
for (const t of n) t.forEach((e, f) => a.set(e, t[Math.max(0, Math.min(t.length - 1, f + r))]));
|
|
46
|
+
for (let t = 0; t < o.h; t++)
|
|
47
|
+
for (let e = 0; e < o.w; e++) {
|
|
48
|
+
const f = a.get(o.get(e, t));
|
|
49
|
+
f !== void 0 && d(e, t, h(e, t)) && o.set(e, t, f);
|
|
50
|
+
}
|
|
51
|
+
return o;
|
|
52
|
+
}
|
|
53
|
+
function O(o, n, r, h, a, t, e, f) {
|
|
54
|
+
for (let M = Math.floor(r - a); M <= r + a; M++)
|
|
55
|
+
for (let l = Math.floor(n - h); l <= n + h; l++) {
|
|
56
|
+
const i = Math.hypot((l - n) / h, (M - r) / a);
|
|
57
|
+
i > 1 || o.set(l, M, g(t, e, f, 1 - i, l, M));
|
|
58
|
+
}
|
|
59
|
+
return o;
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
q as bevel,
|
|
63
|
+
S as blob,
|
|
64
|
+
z as gradient,
|
|
65
|
+
O as pool,
|
|
66
|
+
E as rampShift,
|
|
67
|
+
g as shadeAt,
|
|
68
|
+
A as speckle
|
|
69
|
+
};
|
package/dist/kit/song.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { encodeCmf as p } from "@lewismoten/gamemaker-sandbox-engine/formats/cmf";
|
|
2
|
+
import { sbi as i, INSTRUMENTS as M, midi as R } from "../music/compose.js";
|
|
3
|
+
const H = i({ modChar: 98, carChar: 97, modLevel: 29, carLevel: 0, modAD: 100, carAD: 117, modSR: 22, carSR: 23, feedback: 12 }), W = i({
|
|
4
|
+
modChar: 49,
|
|
5
|
+
carChar: 34,
|
|
6
|
+
modLevel: 30,
|
|
7
|
+
carLevel: 0,
|
|
8
|
+
modAD: 114,
|
|
9
|
+
carAD: 115,
|
|
10
|
+
modSR: 6,
|
|
11
|
+
carSR: 7,
|
|
12
|
+
modWave: 1,
|
|
13
|
+
feedback: 10
|
|
14
|
+
}), q = i({ modChar: 34, carChar: 33, modLevel: 74, carLevel: 5, modAD: 240, carAD: 240, modSR: 15, carSR: 15, feedback: 1 }), _ = i({ modChar: 97, carChar: 97, modLevel: 36, carLevel: 0, modAD: 84, carAD: 117, modSR: 6, carSR: 6, feedback: 14 }), K = i({
|
|
15
|
+
modChar: 3,
|
|
16
|
+
carChar: 1,
|
|
17
|
+
modLevel: 22,
|
|
18
|
+
carLevel: 0,
|
|
19
|
+
modAD: 246,
|
|
20
|
+
carAD: 244,
|
|
21
|
+
modSR: 68,
|
|
22
|
+
carSR: 69,
|
|
23
|
+
modWave: 2,
|
|
24
|
+
feedback: 12
|
|
25
|
+
}), j = i({
|
|
26
|
+
modChar: 5,
|
|
27
|
+
carChar: 1,
|
|
28
|
+
modLevel: 28,
|
|
29
|
+
carLevel: 0,
|
|
30
|
+
modAD: 246,
|
|
31
|
+
carAD: 244,
|
|
32
|
+
modSR: 52,
|
|
33
|
+
carSR: 37,
|
|
34
|
+
feedback: 6
|
|
35
|
+
}), y = i({ modChar: 1, carChar: 1, modLevel: 85, carLevel: 5, modAD: 242, carAD: 211, modSR: 99, carSR: 116, feedback: 8 }), w = i({ modChar: 1, carChar: 1, modLevel: 22, carLevel: 0, modAD: 244, carAD: 244, modSR: 38, carSR: 54, feedback: 10 }), g = i({ modChar: 1, carChar: 1, modLevel: 14, carLevel: 0, modAD: 248, carAD: 247, modSR: 119, carSR: 87, feedback: 8 }), O = i({ modChar: 2, carChar: 0, modLevel: 2, carLevel: 0, modAD: 247, carAD: 0, modSR: 7, carSR: 0, feedback: 0 }), $ = i({ modChar: 2, carChar: 0, modLevel: 4, carLevel: 0, modAD: 247, carAD: 0, modSR: 55, carSR: 0, feedback: 0 }), T = i({ modChar: 1, carChar: 0, modLevel: 8, carLevel: 0, modAD: 244, carAD: 0, modSR: 4, carSR: 0, feedback: 0 }), V = i({ modChar: 1, carChar: 0, modLevel: 6, carLevel: 0, modAD: 249, carAD: 0, modSR: 9, carSR: 0, feedback: 0 }), Y = (c, t, e = c.tune.length) => ({ chords: c.chords.slice(t, e), tune: c.tune.slice(t, e) }), z = (c, t) => ({ chords: c.chords, tune: [...c.tune.slice(0, -1), t] }), J = (c, t = "r w") => ({ chords: c, tune: c.map(() => t) }), L = { w: 4, h: 2, q: 1, e: 0.5, s: 0.25 }, E = (c) => c.split(",").map((t) => t.trim()).filter(Boolean);
|
|
36
|
+
function S(c) {
|
|
37
|
+
return E(c).map((t) => {
|
|
38
|
+
const e = /^(\S+)\s+([whqes])(\.?)$/.exec(t);
|
|
39
|
+
if (!e) throw new Error(`Bad note "${t}"`);
|
|
40
|
+
return [R(e[1]), L[e[2]] * (e[3] ? 1.5 : 1)];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const B = {
|
|
44
|
+
C: 0,
|
|
45
|
+
"C#": 1,
|
|
46
|
+
Db: 1,
|
|
47
|
+
D: 2,
|
|
48
|
+
"D#": 3,
|
|
49
|
+
Eb: 3,
|
|
50
|
+
E: 4,
|
|
51
|
+
F: 5,
|
|
52
|
+
"F#": 6,
|
|
53
|
+
Gb: 6,
|
|
54
|
+
G: 7,
|
|
55
|
+
"G#": 8,
|
|
56
|
+
Ab: 8,
|
|
57
|
+
A: 9,
|
|
58
|
+
"A#": 10,
|
|
59
|
+
Bb: 10,
|
|
60
|
+
B: 11
|
|
61
|
+
};
|
|
62
|
+
function D(c) {
|
|
63
|
+
const t = /^([A-G][#b]?)(m?)(7?)$/.exec(c);
|
|
64
|
+
if (!t) throw new Error(`Unknown chord ${c}`);
|
|
65
|
+
const e = t[2] ? 3 : 4;
|
|
66
|
+
return { pc: B[t[1]], iv: t[3] ? [0, e, 10] : [0, e, 7] };
|
|
67
|
+
}
|
|
68
|
+
const N = {
|
|
69
|
+
voicing: (c) => {
|
|
70
|
+
const { pc: t, iv: e } = D(c);
|
|
71
|
+
return e.map((o) => 55 + (t + o - 55 + 120) % 12).sort((o, r) => o - r);
|
|
72
|
+
},
|
|
73
|
+
root: (c) => 40 + (D(c).pc - 40 + 120) % 12
|
|
74
|
+
};
|
|
75
|
+
function Q(c, t) {
|
|
76
|
+
return {
|
|
77
|
+
voicing: (e) => {
|
|
78
|
+
if (!c[e]) throw new Error(`No voicing for ${e}`);
|
|
79
|
+
return c[e].map((o) => R(o));
|
|
80
|
+
},
|
|
81
|
+
root: (e) => t[e]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const P = { k: 11, s: 12, t: 13, c: 14, h: 15 }, G = { k: 36, s: 55, t: 48, c: 72, h: 55 }, I = {
|
|
85
|
+
rock: { k: "x...x.x.", s: "..X...X.", h: "xxxxxxxx" },
|
|
86
|
+
rock4: { k: "x...x.x.", s: "..X...X.", h: "x.x.x.x." },
|
|
87
|
+
rockFill: { k: "x...x...", s: "..X..xXX", t: "......xx", h: "xxxxx..." },
|
|
88
|
+
crash: { k: "x...x.x.", s: "..X...X.", c: "X.......", h: ".xxxxxxx" },
|
|
89
|
+
half: { k: "x.......", s: "....X...", h: "x.x.x.x." },
|
|
90
|
+
soft: { k: "x.......", h: "..x...x." },
|
|
91
|
+
shuffle: { k: "x..x..x.", s: "..X...X.", h: "x.xxx.xx" },
|
|
92
|
+
camel: { k: "x.....x.", t: "..x.x..x", s: "....X...", h: "x.x.x.x." },
|
|
93
|
+
ride: { k: "x...x...", s: "....x...", c: "x.x.x.x." },
|
|
94
|
+
gospel: { k: "x..x..x.", s: "..X...X.", h: "xxxxxxxx", t: "........" },
|
|
95
|
+
// a clap-along gospel two-step (snare on 2 and 4 with a ghost before 4), sixteenth hats
|
|
96
|
+
clap: { k: "x.......x.x.....", s: "....X.......X...", h: "x.x.x.x.x.x.x.x." },
|
|
97
|
+
clapFill: { k: "x.......x.......", s: "....X.....x.XxXX", t: "..............xx", h: "x.x.x.x.x.x....." },
|
|
98
|
+
// a hop: the kick bounces ahead of the beat
|
|
99
|
+
hop: { k: "x..x...xx..x....", s: "....X.......X...", h: "x.xxx.x.x.xxx.x." },
|
|
100
|
+
march: { k: "x...x...", s: "..x...x.", t: "x.....xx", h: "x.x.x.x." },
|
|
101
|
+
none: {}
|
|
102
|
+
};
|
|
103
|
+
class Z {
|
|
104
|
+
constructor(t, e = N) {
|
|
105
|
+
this.chords = e, this.tpb = Math.round(8760 / t), this.events.push({ tick: 0, data: [176, 103, 1] }), this.instruments[11] = g, this.instruments[12] = O, this.instruments[13] = $, this.instruments[14] = T, this.instruments[15] = V;
|
|
106
|
+
}
|
|
107
|
+
chords;
|
|
108
|
+
tpb;
|
|
109
|
+
events = [];
|
|
110
|
+
instruments = [];
|
|
111
|
+
bar = 0;
|
|
112
|
+
current = [];
|
|
113
|
+
tick(t) {
|
|
114
|
+
return Math.round(t * this.tpb);
|
|
115
|
+
}
|
|
116
|
+
/** A note from beat `at` lasting `len` beats; it lets go a little early so the next one retriggers. */
|
|
117
|
+
note(t, e, o, r, s, a = 0.9) {
|
|
118
|
+
const h = this.tick(e), n = Math.max(h + 1, Math.min(this.tick(e + o) - 1, h + Math.round(o * this.tpb * a)));
|
|
119
|
+
this.events.push({ tick: h, data: [144 | t, r, s] }), this.events.push({ tick: n, data: [128 | t, r, 0] });
|
|
120
|
+
}
|
|
121
|
+
/** Plays a note string from beat `at`; returns its length in beats. */
|
|
122
|
+
line(t, e, o, r, s = 0, a = 0.9) {
|
|
123
|
+
let h = e;
|
|
124
|
+
for (const [n, d] of S(o))
|
|
125
|
+
n !== null && this.note(t, h, d, n + s, r, a), h += d;
|
|
126
|
+
return h - e;
|
|
127
|
+
}
|
|
128
|
+
drums(t, e, o) {
|
|
129
|
+
for (const r of Object.keys(e)) {
|
|
130
|
+
const s = e[r], a = 4 / s.length;
|
|
131
|
+
[...s].forEach((h, n) => {
|
|
132
|
+
if (h === ".") return;
|
|
133
|
+
const d = Math.min(127, Math.round(o * (h === "X" ? 1.15 : r === "h" && n % 2 ? 0.8 : 1)));
|
|
134
|
+
this.note(P[r], t + n * a, Math.min(a, 0.5), G[r], d, 0.6);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** The bass for `beats` beats from `at` under one chord. */
|
|
139
|
+
bassLine(t, e, o, r) {
|
|
140
|
+
const s = this.chords.root(e) + (t.shift ?? 0), a = s + 7, h = {
|
|
141
|
+
whole: [[s, 4]],
|
|
142
|
+
half: [
|
|
143
|
+
[s, 2],
|
|
144
|
+
[a, 2]
|
|
145
|
+
],
|
|
146
|
+
pump: [
|
|
147
|
+
[s, 1],
|
|
148
|
+
[a, 1],
|
|
149
|
+
[s, 1],
|
|
150
|
+
[a, 1]
|
|
151
|
+
],
|
|
152
|
+
walk: [
|
|
153
|
+
[s, 1],
|
|
154
|
+
[s + (e.endsWith("m") ? 3 : 4), 1],
|
|
155
|
+
[a, 1],
|
|
156
|
+
[s + 12, 1]
|
|
157
|
+
],
|
|
158
|
+
eighths: [
|
|
159
|
+
[s, 0.5],
|
|
160
|
+
[s, 0.5],
|
|
161
|
+
[s + 12, 0.5],
|
|
162
|
+
[s, 0.5],
|
|
163
|
+
[a, 0.5],
|
|
164
|
+
[s, 0.5],
|
|
165
|
+
[s + 12, 0.5],
|
|
166
|
+
[a, 0.5]
|
|
167
|
+
]
|
|
168
|
+
};
|
|
169
|
+
let n = o;
|
|
170
|
+
for (const [d, u] of h[t.bass]) {
|
|
171
|
+
if (n >= o + r - 1e-6) break;
|
|
172
|
+
this.note(2, n, Math.min(u, o + r - n), d, t.bassVel ?? 105, 0.85), n += u;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** Writes a section's bars: tune, second voice, bass, three comping voices and drums. */
|
|
176
|
+
part(t) {
|
|
177
|
+
const e = t.section;
|
|
178
|
+
return this.patches(t), e.tune.forEach((o, r) => {
|
|
179
|
+
const s = (this.bar + r) * 4, a = S(o).reduce((x, [, m]) => x + m, 0);
|
|
180
|
+
if (Math.abs(a - 4) > 1e-6) throw new Error(`Bar ${r + 1} of a section has ${a} beats: ${o}`);
|
|
181
|
+
const h = t.shift ?? 0;
|
|
182
|
+
if (!t.noTune) {
|
|
183
|
+
const x = t.up ?? 0;
|
|
184
|
+
this.line(0, s, o, t.leadVel ?? 112, h + x), t.second === "double" && this.line(1, s, o, t.secondVel ?? 70, h + x - 12), t.second === "octave" && this.line(1, s, o, t.secondVel ?? 60, h + x + 12);
|
|
185
|
+
}
|
|
186
|
+
const n = e.chords[r].split(" "), d = 4 / n.length, u = (x) => n[Math.min(n.length - 1, Math.floor((x - s) / d + 1e-6))];
|
|
187
|
+
n.forEach((x, m) => this.bassLine(t, x, s + m * d, d));
|
|
188
|
+
let l = s;
|
|
189
|
+
for (const x of E(t.comp)) {
|
|
190
|
+
const m = /^([xr])\s+([whqes])(\.?)$/.exec(x);
|
|
191
|
+
if (!m) throw new Error(`Bad comp "${x}"`);
|
|
192
|
+
const k = L[m[2]] * (m[3] ? 1.5 : 1);
|
|
193
|
+
if (m[1] === "x" && n.length === 1) this.chords.voicing(n[0]).forEach((v, f) => this.note(3 + f, l, k, v + h, t.compVel ?? 70, 0.85));
|
|
194
|
+
else if (m[1] === "x") {
|
|
195
|
+
const v = u(l), f = Math.min(l + k, s + (n.indexOf(v) + 1) * d);
|
|
196
|
+
if (this.chords.voicing(v).forEach((A, b) => this.note(3 + b, l, f - l, A + h, t.compVel ?? 70, 0.85)), f < l + k) {
|
|
197
|
+
const A = u(f);
|
|
198
|
+
this.chords.voicing(A).forEach((b, X) => this.note(3 + X, f, l + k - f, b + h, t.compVel ?? 70, 0.85));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
l += k;
|
|
202
|
+
}
|
|
203
|
+
const C = I[t.drums[Math.min(r, t.drums.length - 1)]];
|
|
204
|
+
if (!C) throw new Error(`No groove ${t.drums[Math.min(r, t.drums.length - 1)]}`);
|
|
205
|
+
this.drums(s, C, t.drumVel ?? 100);
|
|
206
|
+
}), this.bar += e.tune.length, this;
|
|
207
|
+
}
|
|
208
|
+
/** Puts each melodic channel's patch in place for a part: the first part's are the file's instruments 0-5; later changes add an instrument and a program change. */
|
|
209
|
+
patches(t) {
|
|
210
|
+
const e = [
|
|
211
|
+
[0, t.lead],
|
|
212
|
+
[1, t.secondPatch ?? t.lead],
|
|
213
|
+
[2, t.bassPatch ?? w],
|
|
214
|
+
[3, t.compPatch],
|
|
215
|
+
[4, t.compPatch],
|
|
216
|
+
[5, t.compPatch]
|
|
217
|
+
];
|
|
218
|
+
for (const [o, r] of e)
|
|
219
|
+
if (this.current[o] !== r) {
|
|
220
|
+
if (this.current[o] === void 0) this.instruments[o] = r;
|
|
221
|
+
else {
|
|
222
|
+
let s = this.instruments.indexOf(r, 16);
|
|
223
|
+
s < 0 && (s = Math.max(16, this.instruments.length), this.instruments[s] = r), this.events.push({ tick: this.tick(this.bar * 4), data: [192 | o, s] });
|
|
224
|
+
}
|
|
225
|
+
this.current[o] = r;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/** The .CMF: ends exactly on the bar line, so PLAYGAME's restart keeps time. */
|
|
229
|
+
cmf() {
|
|
230
|
+
const t = this.tick(this.bar * 4);
|
|
231
|
+
for (let e = 0; e < 6; e++) this.current[e] !== this.instruments[e] && this.events.push({ tick: t, data: [192 | e, e] });
|
|
232
|
+
this.events.push({ tick: t, data: [176, 103, 1] });
|
|
233
|
+
for (let e = 0; e < 16; e++) this.instruments[e] ??= M.piano;
|
|
234
|
+
return p({ instruments: this.instruments, events: this.events, ticksPerBeat: this.tpb });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
export {
|
|
238
|
+
w as BASS,
|
|
239
|
+
j as CELESTA,
|
|
240
|
+
y as EPIANO,
|
|
241
|
+
_ as FLUTE,
|
|
242
|
+
q as ORGAN,
|
|
243
|
+
K as OUD,
|
|
244
|
+
W as REED,
|
|
245
|
+
H as VOICE,
|
|
246
|
+
Z as Writer,
|
|
247
|
+
Q as chordTable,
|
|
248
|
+
z as ending,
|
|
249
|
+
Y as slice,
|
|
250
|
+
J as vamp
|
|
251
|
+
};
|