@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,133 @@
|
|
|
1
|
+
import { encodeFli as b, parseFli as w, newFliCanvas as L, applyFliFrame as k } from "@lewismoten/gamemaker-sandbox-engine/formats/fli";
|
|
2
|
+
import { shrinkFrames as A, decodeFli as j, encodeFrames as v } from "./fliShrink.js";
|
|
3
|
+
import { parseSlideList as M, serializeSlideList as x } from "@lewismoten/gamemaker-sandbox-engine/formats/graphicScripts";
|
|
4
|
+
function I(t) {
|
|
5
|
+
const n = w(t);
|
|
6
|
+
return n.frameCount * n.speed / 70;
|
|
7
|
+
}
|
|
8
|
+
function O(t) {
|
|
9
|
+
const n = w(t);
|
|
10
|
+
if (n.frames.length <= n.frameCount) return t;
|
|
11
|
+
const e = t.slice(0, n.frames[n.frameCount]);
|
|
12
|
+
return new DataView(e.buffer).setUint32(0, e.length, !0), e;
|
|
13
|
+
}
|
|
14
|
+
function U(t) {
|
|
15
|
+
const n = w(t), e = L(n), c = [], o = [];
|
|
16
|
+
for (let r = 0; r < n.frameCount; r++)
|
|
17
|
+
k(n, r, e), c.push(Uint8Array.from(e.pixels)), o.push(Uint8Array.from(e.palette));
|
|
18
|
+
return { frames: c, palettes: o, w: n.width, h: n.height, speed: n.speed };
|
|
19
|
+
}
|
|
20
|
+
function d(t, n) {
|
|
21
|
+
if (t.length !== n.length) return !1;
|
|
22
|
+
for (let e = 0; e < t.length; e++) if (t[e] !== n[e]) return !1;
|
|
23
|
+
return !0;
|
|
24
|
+
}
|
|
25
|
+
function S(t, n, e) {
|
|
26
|
+
let c = d(n[e - 1], n[e]) ? 0 : 1e9;
|
|
27
|
+
const o = t[e - 1], r = t[e];
|
|
28
|
+
for (let f = 0; f < o.length; f++) o[f] !== r[f] && c++;
|
|
29
|
+
return c;
|
|
30
|
+
}
|
|
31
|
+
function W(t, n, e, c, o) {
|
|
32
|
+
const r = w(t), f = (s) => (s + 1 < r.frames.length ? r.frames[s + 1] : t.length) - r.frames[s], l = [], u = (s) => (l[s] === void 0 && (l[s] = s > 0 && d(n[s - 1], n[s]) && d(e[s - 1], e[s]) ? u(s - 1) : b([n[s]], e[s], { width: c, height: o, runs: !0, noLoopFrame: !0 }).length - 128), l[s]);
|
|
33
|
+
return (s) => d(e[s - 1], e[s]) ? u(s) - f(s) : 1e9;
|
|
34
|
+
}
|
|
35
|
+
function $(t, n, e) {
|
|
36
|
+
const c = t.length, o = [];
|
|
37
|
+
let r = 0;
|
|
38
|
+
for (; c - r > e; ) {
|
|
39
|
+
const f = Math.ceil((c - r) / e), l = r + Math.round((c - r) / f), u = Math.max(r + 1, l - Math.floor(e / 4), c - (f - 1) * e), s = Math.min(r + e, c - 1);
|
|
40
|
+
let i = s, a = 1 / 0;
|
|
41
|
+
for (let h = u; h <= s; h++) {
|
|
42
|
+
const m = S(t, n, h);
|
|
43
|
+
m < a && ([i, a] = [h, m]);
|
|
44
|
+
}
|
|
45
|
+
o.push(i), r = i;
|
|
46
|
+
}
|
|
47
|
+
return o;
|
|
48
|
+
}
|
|
49
|
+
function z(t, n, e, c) {
|
|
50
|
+
const o = [new Array(t + 1).fill(1 / 0)], r = [new Array(t + 1).fill(-1)];
|
|
51
|
+
o[0][0] = 0;
|
|
52
|
+
const f = /* @__PURE__ */ new Map(), l = (i) => f.get(i) ?? (f.set(i, c(i)), f.get(i));
|
|
53
|
+
let u;
|
|
54
|
+
for (let i = 0; i < e; i++) {
|
|
55
|
+
for (let a = 0; a < t; a++) o[i][a] < 1 / 0 && t - a <= n && (!u || o[i][a] < o[u[0]][u[1]]) && (u = [i, a]);
|
|
56
|
+
if (i + 1 === e) break;
|
|
57
|
+
o.push(new Array(t + 1).fill(1 / 0)), r.push(new Array(t + 1).fill(-1));
|
|
58
|
+
for (let a = 0; a < t; a++)
|
|
59
|
+
if (o[i][a] !== 1 / 0)
|
|
60
|
+
for (let h = a + 1; h <= Math.min(a + n, t - 1); h++) {
|
|
61
|
+
const m = o[i][a] + l(h);
|
|
62
|
+
m < o[i + 1][h] && ([o[i + 1][h], r[i + 1][h]] = [m, a]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const s = [];
|
|
66
|
+
for (let [i, a] = u; i > 0; a = r[i][a], i--) s.unshift(a);
|
|
67
|
+
return s;
|
|
68
|
+
}
|
|
69
|
+
function E(t, n) {
|
|
70
|
+
if (n === 0) return t;
|
|
71
|
+
const e = t.lastIndexOf(".");
|
|
72
|
+
return `${t.slice(0, e).slice(0, 7)}${n + 1}${t.slice(e)}`;
|
|
73
|
+
}
|
|
74
|
+
function P(t, n, e = 4, c = {}) {
|
|
75
|
+
let o = n, r;
|
|
76
|
+
const f = c.shrink?.length ? A(j(n), c.shrink) : [];
|
|
77
|
+
if (f.length) {
|
|
78
|
+
const p = f[f.length - 1];
|
|
79
|
+
f.some((y) => !y.lossless) && (o = v(p.frames)), r = p.encode.sparsePalettes;
|
|
80
|
+
}
|
|
81
|
+
if (I(o) <= e * 1.25) return { [t]: c.noLoopFrame ? O(o) : o };
|
|
82
|
+
const { frames: l, palettes: u, w: s, h: i, speed: a } = U(o), h = Math.max(1, Math.floor(e * 70 / Math.max(1, a))), m = $(l, u, h), g = [0, ...c.cheapCuts ? z(l.length, h, m.length + 1, W(o, l, u, s, i)) : m, l.length], C = {};
|
|
83
|
+
for (let p = 0; p + 1 < g.length; p++) {
|
|
84
|
+
const y = l.slice(g[p], g[p + 1]), F = u.slice(g[p], g[p + 1]);
|
|
85
|
+
C[E(t, p)] = b(y, F[0], {
|
|
86
|
+
width: s,
|
|
87
|
+
height: i,
|
|
88
|
+
speed: a,
|
|
89
|
+
palettes: F,
|
|
90
|
+
runs: !0,
|
|
91
|
+
noLoopFrame: c.noLoopFrame,
|
|
92
|
+
sparsePalettes: r
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return C;
|
|
96
|
+
}
|
|
97
|
+
function D(t, n) {
|
|
98
|
+
const e = Object.keys(t);
|
|
99
|
+
return e.map((c, o) => o < e.length - 1 ? { name: c, pause: 0 } : { name: c, pause: n });
|
|
100
|
+
}
|
|
101
|
+
function N(t, n, e = 4, c = {}) {
|
|
102
|
+
const o = /* @__PURE__ */ new Map();
|
|
103
|
+
for (const r of n)
|
|
104
|
+
for (const f of M(t.get(r) ?? new Uint8Array())) {
|
|
105
|
+
const l = f.name.toLowerCase(), u = t.get(l);
|
|
106
|
+
if (!l.endsWith(".fli") || !u || o.has(l)) continue;
|
|
107
|
+
const s = P(l, u, e, c);
|
|
108
|
+
Object.keys(s).length > 1 && o.set(l, s);
|
|
109
|
+
}
|
|
110
|
+
if (o.size) {
|
|
111
|
+
for (const r of o.values()) for (const [f, l] of Object.entries(r)) t.set(f, l);
|
|
112
|
+
for (const [r, f] of t) {
|
|
113
|
+
if (!r.endsWith(".lst")) continue;
|
|
114
|
+
const l = M(f), u = (s) => o.get(s.name.toLowerCase());
|
|
115
|
+
l.some(u) && t.set(r, x(l.flatMap((s) => u(s) ? D(u(s), s.pause) : [s])));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function H(t, n = 4, e = {}) {
|
|
120
|
+
N(
|
|
121
|
+
t,
|
|
122
|
+
[...t.keys()].filter((c) => c.endsWith(".lst")),
|
|
123
|
+
n,
|
|
124
|
+
e
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
D as clipEntries,
|
|
129
|
+
H as clipEveryList,
|
|
130
|
+
N as clipLists,
|
|
131
|
+
P as fliClips,
|
|
132
|
+
I as fliSeconds
|
|
133
|
+
};
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { parseFli as W, newFliCanvas as at, applyFliFrame as ot, encodeFli as rt } from "@lewismoten/gamemaker-sandbox-engine/formats/fli";
|
|
2
|
+
function ct(t) {
|
|
3
|
+
const s = W(t), f = at(s), e = [], n = [];
|
|
4
|
+
for (let o = 0; o < s.frameCount; o++)
|
|
5
|
+
ot(s, o, f), e.push(Uint8Array.from(f.pixels)), n.push(Uint8Array.from(f.palette));
|
|
6
|
+
return { frames: e, palettes: n, width: s.width, height: s.height, speed: s.speed };
|
|
7
|
+
}
|
|
8
|
+
function Q(t, s = {}) {
|
|
9
|
+
return rt(t.frames, t.palettes[0], {
|
|
10
|
+
width: t.width,
|
|
11
|
+
height: t.height,
|
|
12
|
+
speed: t.speed,
|
|
13
|
+
palettes: t.palettes,
|
|
14
|
+
runs: !0,
|
|
15
|
+
noLoopFrame: !0,
|
|
16
|
+
sparsePalettes: s.sparsePalettes
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const lt = { 4: "COLOR256", 7: "SS2", 11: "COLOR64", 12: "LC", 13: "BLACK", 15: "BRUN", 16: "COPY", 18: "PSTAMP" };
|
|
20
|
+
function wt(t) {
|
|
21
|
+
const s = W(t), f = ct(t), e = new DataView(t.buffer, t.byteOffset, t.byteLength), n = [], o = {};
|
|
22
|
+
for (let i = 0; i < s.frameCount; i++) {
|
|
23
|
+
const p = s.frames[i], u = { header: 16 };
|
|
24
|
+
let d = p + 16;
|
|
25
|
+
for (let x = 0, M = e.getUint16(p + 6, !0); x < M; x++) {
|
|
26
|
+
const P = e.getUint32(d, !0), S = lt[e.getUint16(d + 4, !0)] ?? String(e.getUint16(d + 4, !0));
|
|
27
|
+
u[S] = (u[S] ?? 0) + P, d += P;
|
|
28
|
+
}
|
|
29
|
+
let y = 0;
|
|
30
|
+
const b = f.frames[i - 1];
|
|
31
|
+
if (!b) y = f.frames[i].length;
|
|
32
|
+
else for (let x = 0; x < b.length; x++) b[x] !== f.frames[i][x] && y++;
|
|
33
|
+
for (const [x, M] of Object.entries(u)) o[x] = (o[x] ?? 0) + M;
|
|
34
|
+
n.push({ frame: i, bytes: e.getUint32(p, !0), chunks: u, changedPixels: y });
|
|
35
|
+
}
|
|
36
|
+
const c = [], h = t.length, r = [...n].sort((i, p) => p.bytes - i.bytes)[0];
|
|
37
|
+
r && r.bytes > h * 0.25 && c.push(
|
|
38
|
+
`Frame ${r.frame + 1} is ${Math.round(r.bytes / h * 100)}% of the file: a whole new picture. Dithered or speckled art costs the most there; flatter shading costs less.`
|
|
39
|
+
);
|
|
40
|
+
const l = o.COLOR64 ?? 0;
|
|
41
|
+
l > h * 0.04 && c.push(
|
|
42
|
+
`Palette changes take ${Math.round(l / h * 100)}%: fades resend colors a frame does not draw (sparse palettes, a smaller palette).`
|
|
43
|
+
);
|
|
44
|
+
const a = n.filter((i) => i.frame > 0 && i.changedPixels > 0 && i.bytes / i.changedPixels > 1.5 && i.changedPixels > 400);
|
|
45
|
+
a.length > n.length * 0.2 && c.push(
|
|
46
|
+
`${a.length} frames change many pixels by a little (noise or dither that moves): holding still areas still, or snapping near colors, cuts them.`
|
|
47
|
+
);
|
|
48
|
+
const m = n.filter((i) => i.frame > 0 && i.changedPixels === 0).length;
|
|
49
|
+
return m > n.length * 0.3 && c.push(`${m} frames repeat the one before: they cost their header only, but dropping frames and lengthening delays would save more.`), { totalBytes: h, frames: n, byChunk: o, findings: c };
|
|
50
|
+
}
|
|
51
|
+
const F = (t, s, f) => Math.round((t[s * 3 + f] & 63) * 255 / 63);
|
|
52
|
+
function Z(t, s, f = (e) => e) {
|
|
53
|
+
let e = 0, n = 0, o = 0, c = 0;
|
|
54
|
+
for (let h = 0; h < t.frames.length; h++) {
|
|
55
|
+
const r = t.frames[h], l = t.palettes[h], a = Math.min(s.frames.length - 1, f(h)), m = s.frames[a], i = s.palettes[a];
|
|
56
|
+
for (let p = 0; p < r.length; p++) {
|
|
57
|
+
if (c++, r[p] === m[p] && l === i) continue;
|
|
58
|
+
let u = 0;
|
|
59
|
+
for (let d = 0; d < 3; d++) u = Math.max(u, Math.abs(F(l, r[p], d) - F(i, m[p], d)));
|
|
60
|
+
u && o++, e += u, n = Math.max(n, u);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { mean: c ? e / c : 0, worst: n, changedShare: c ? o / c : 0 };
|
|
64
|
+
}
|
|
65
|
+
function C(t, s, f, e, n, o, c) {
|
|
66
|
+
const h = Q(f, o).length, r = Q(e, { ...o, ...n }).length;
|
|
67
|
+
return {
|
|
68
|
+
name: t,
|
|
69
|
+
lossless: s,
|
|
70
|
+
frames: e,
|
|
71
|
+
encode: { ...o, ...n },
|
|
72
|
+
bytesBefore: h,
|
|
73
|
+
bytesAfter: r,
|
|
74
|
+
savedBytes: h - r,
|
|
75
|
+
visibility: s ? { mean: 0, worst: 0, changedShare: 0 } : Z(f, e, c)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const N = (t, s, f) => Math.max(...[0, 1, 2].map((e) => Math.abs(F(t, s, e) - F(t, f, e))));
|
|
79
|
+
function X(t) {
|
|
80
|
+
const s = (f) => f.reduce((e, n) => e + n, 0);
|
|
81
|
+
return t.palettes.reduce((f, e) => s(e) > s(f) ? e : f);
|
|
82
|
+
}
|
|
83
|
+
function ft(t, s, f = {}) {
|
|
84
|
+
const { width: e, height: n } = t, o = X(t), c = t.frames.map((h) => {
|
|
85
|
+
const r = Uint8Array.from(h), l = (a, m, i) => {
|
|
86
|
+
r[m] === r[i] && r[a] !== r[m] && N(o, r[a], r[m]) <= s.tolerance && (r[a] = r[m]);
|
|
87
|
+
};
|
|
88
|
+
for (let a = 0; a < n; a++) for (let m = 1; m < e - 1; m++) l(a * e + m, a * e + m - 1, a * e + m + 1);
|
|
89
|
+
for (let a = 1; a < n - 1; a++) for (let m = 0; m < e; m++) l(a * e + m, (a - 1) * e + m, (a + 1) * e + m);
|
|
90
|
+
return r;
|
|
91
|
+
});
|
|
92
|
+
return C("flatten dithering", !1, t, { ...t, frames: c }, {}, f);
|
|
93
|
+
}
|
|
94
|
+
function ht(t, s = {}) {
|
|
95
|
+
return C("sparse palettes", !0, t, t, { sparsePalettes: !0 }, s);
|
|
96
|
+
}
|
|
97
|
+
function it(t, s, f = {}) {
|
|
98
|
+
const e = t.frames.map((n) => Uint8Array.from(n));
|
|
99
|
+
for (let n = 1; n < e.length; n++) {
|
|
100
|
+
if (t.palettes[n] !== t.palettes[n - 1] && t.palettes[n].some((r, l) => r !== t.palettes[n - 1][l])) continue;
|
|
101
|
+
const o = t.palettes[n], c = e[n - 1], h = e[n];
|
|
102
|
+
for (let r = 0; r < h.length; r++) h[r] !== c[r] && N(o, h[r], c[r]) <= s.tolerance && (h[r] = c[r]);
|
|
103
|
+
}
|
|
104
|
+
return C("hold still areas still", !1, t, { ...t, frames: e }, {}, f);
|
|
105
|
+
}
|
|
106
|
+
function pt(t, s, f) {
|
|
107
|
+
let e = f[0], n = 1 / 0;
|
|
108
|
+
for (const o of f) {
|
|
109
|
+
const c = [0, 1, 2].reduce((h, r) => h + (F(t, s, r) - F(t, o, r)) ** 2, 0);
|
|
110
|
+
c < n && ([e, n] = [o, c]);
|
|
111
|
+
}
|
|
112
|
+
return e;
|
|
113
|
+
}
|
|
114
|
+
function mt(t, s, f = {}) {
|
|
115
|
+
const e = X(t), n = new Array(256).fill(0);
|
|
116
|
+
for (const l of t.frames) for (let a = 0; a < l.length; a += 7) n[l[a]]++;
|
|
117
|
+
const o = n.map((l, a) => a).sort((l, a) => n[a] - n[l]), c = Array.from({ length: 256 }, (l, a) => a), h = [];
|
|
118
|
+
for (const l of o) {
|
|
119
|
+
if (!n[l]) continue;
|
|
120
|
+
const a = h.find((m) => N(e, l, m) <= s.tolerance);
|
|
121
|
+
a === void 0 ? h.push(l) : c[l] = a;
|
|
122
|
+
}
|
|
123
|
+
const r = t.frames.map((l) => l.map((a) => c[a]));
|
|
124
|
+
return C("snap near colors", !1, t, { ...t, frames: r }, {}, f);
|
|
125
|
+
}
|
|
126
|
+
function ut(t, s, f = {}) {
|
|
127
|
+
const e = X(t), n = new Array(256).fill(0);
|
|
128
|
+
for (const l of t.frames) for (let a = 0; a < l.length; a++) n[l[a]]++;
|
|
129
|
+
const o = n.map((l, a) => a).filter((l) => n[l]).sort((l, a) => n[a] - n[l]), c = o.slice(0, Math.max(1, s.colors)), h = Array.from({ length: 256 }, (l, a) => a);
|
|
130
|
+
for (const l of o.slice(c.length)) h[l] = pt(e, l, c);
|
|
131
|
+
const r = t.frames.map((l) => l.map((a) => h[a]));
|
|
132
|
+
return C("fewer colors", !1, t, { ...t, frames: r }, {}, f);
|
|
133
|
+
}
|
|
134
|
+
function dt(t, s = {}) {
|
|
135
|
+
const f = (o) => o % 2 === 0 || o === t.frames.length - 1, e = t.frames.map((o, c) => c).filter(f), n = { ...t, frames: e.map((o) => t.frames[o]), palettes: e.map((o) => t.palettes[o]), speed: Math.min(255, t.speed * 2) };
|
|
136
|
+
return C("drop every other frame", !1, t, n, {}, s, (o) => o >= t.frames.length - 1 ? e.length - 1 : o >> 1);
|
|
137
|
+
}
|
|
138
|
+
function At(t, s) {
|
|
139
|
+
const f = [];
|
|
140
|
+
let e = t, n = {};
|
|
141
|
+
for (const o of s) {
|
|
142
|
+
const c = o.step === "sparsePalettes" ? ht(e, n) : o.step === "holdStill" ? it(e, o, n) : o.step === "snapColors" ? mt(e, o, n) : o.step === "flattenDither" ? ft(e, o, n) : o.step === "maxColors" ? ut(e, o, n) : o.step === "onePalette" ? xt(e, o, n) : o.step === "frame" ? bt(e, o, n) : dt(e, n);
|
|
143
|
+
f.push(c), e = c.frames, n = c.encode;
|
|
144
|
+
}
|
|
145
|
+
return f;
|
|
146
|
+
}
|
|
147
|
+
function Ct(t, s) {
|
|
148
|
+
const f = t.frames.length, e = s.frames.length;
|
|
149
|
+
return Z(t, s, e === f ? (n) => n : (n) => n >= f - 1 ? e - 1 : n >> 1);
|
|
150
|
+
}
|
|
151
|
+
const K = (t, s) => (t[s * 3] & 63) << 12 | (t[s * 3 + 1] & 63) << 6 | t[s * 3 + 2] & 63;
|
|
152
|
+
function yt(t, s, f) {
|
|
153
|
+
const e = (c, h) => c >> 12 - 6 * h & 63, n = [t], o = (c) => {
|
|
154
|
+
let h = 0, r = 0;
|
|
155
|
+
for (let l = 0; l < 3; l++) {
|
|
156
|
+
const a = c.map((i) => e(i, l)), m = Math.max(...a) - Math.min(...a);
|
|
157
|
+
m > h && ([h, r] = [m, l]);
|
|
158
|
+
}
|
|
159
|
+
return { best: h, at: r };
|
|
160
|
+
};
|
|
161
|
+
for (; n.length < f; ) {
|
|
162
|
+
let c = -1, h = 0;
|
|
163
|
+
if (n.forEach((p, u) => {
|
|
164
|
+
if (p.length < 2) return;
|
|
165
|
+
const d = o(p).best * p.reduce((y, b) => y + s.get(b), 0);
|
|
166
|
+
d > h && ([c, h] = [u, d]);
|
|
167
|
+
}), c < 0) break;
|
|
168
|
+
const r = n[c], { at: l } = o(r);
|
|
169
|
+
r.sort((p, u) => e(p, l) - e(u, l));
|
|
170
|
+
const a = r.reduce((p, u) => p + s.get(u), 0) / 2;
|
|
171
|
+
let m = 0, i = 1;
|
|
172
|
+
for (let p = 0; p < r.length - 1 && (m += s.get(r[p]), i = p + 1, !(m >= a)); p++)
|
|
173
|
+
;
|
|
174
|
+
n.splice(c, 1, r.slice(0, i), r.slice(i));
|
|
175
|
+
}
|
|
176
|
+
return n.map((c) => {
|
|
177
|
+
const h = c.reduce((l, a) => l + s.get(a), 0) || 1, r = [0, 1, 2].map((l) => Math.round(c.reduce((a, m) => a + e(m, l) * s.get(m), 0) / h));
|
|
178
|
+
return r[0] << 12 | r[1] << 6 | r[2];
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function xt(t, s, f = {}) {
|
|
182
|
+
const e = Math.max(1, Math.min(256, Math.round(s.colors))), n = /* @__PURE__ */ new Map();
|
|
183
|
+
t.frames.forEach((i, p) => {
|
|
184
|
+
const u = t.palettes[p], d = new Uint32Array(256);
|
|
185
|
+
for (let y = 0; y < i.length; y++) d[i[y]]++;
|
|
186
|
+
for (let y = 0; y < 256; y++) d[y] && n.set(K(u, y), (n.get(K(u, y)) ?? 0) + d[y]);
|
|
187
|
+
});
|
|
188
|
+
const o = [...n.keys()], c = o.length <= e ? o : yt(o, n, e), h = new Uint8Array(768);
|
|
189
|
+
c.forEach((i, p) => {
|
|
190
|
+
h[p * 3] = i >> 12, h[p * 3 + 1] = i >> 6 & 63, h[p * 3 + 2] = i & 63;
|
|
191
|
+
});
|
|
192
|
+
const r = /* @__PURE__ */ new Map(), l = (i) => {
|
|
193
|
+
let p = r.get(i);
|
|
194
|
+
if (p !== void 0) return p;
|
|
195
|
+
let u = 1 / 0;
|
|
196
|
+
return p = 0, c.forEach((d, y) => {
|
|
197
|
+
const b = [12, 6, 0].reduce((x, M) => x + ((i >> M & 63) - (d >> M & 63)) ** 2, 0);
|
|
198
|
+
b < u && ([p, u] = [y, b]);
|
|
199
|
+
}), r.set(i, p), p;
|
|
200
|
+
}, a = t.frames.map((i, p) => {
|
|
201
|
+
const u = t.palettes[p], d = Uint8Array.from({ length: 256 }, (y, b) => l(K(u, b)));
|
|
202
|
+
return i.map((y) => d[y]);
|
|
203
|
+
}), m = { ...t, frames: a, palettes: a.map(() => h) };
|
|
204
|
+
return C("one palette", o.length <= e, t, m, {}, f);
|
|
205
|
+
}
|
|
206
|
+
function Mt(t) {
|
|
207
|
+
let s = 0, f = 1 / 0;
|
|
208
|
+
for (let e = 0; e < 256; e++) {
|
|
209
|
+
const n = (t[e * 3] & 63) + (t[e * 3 + 1] & 63) + (t[e * 3 + 2] & 63);
|
|
210
|
+
if (n < f && ([s, f] = [e, n]), e === 0 && n === 0) return 0;
|
|
211
|
+
}
|
|
212
|
+
return s;
|
|
213
|
+
}
|
|
214
|
+
function bt(t, s, f = {}) {
|
|
215
|
+
const { width: e, height: n } = t, o = (M, P) => Math.max(0, Math.min(P, Math.round(M) || 0)), c = o(s.left, e - 1), h = o(s.right, e - 1 - c), r = o(s.top, n - 1), l = o(s.bottom, n - 1 - r), a = Math.max(0.05, Math.min(8, s.zoom || 1));
|
|
216
|
+
if (!c && !h && !r && !l && a === 1 && !s.panX && !s.panY) return C("frame it", !0, t, t, {}, f);
|
|
217
|
+
const i = Mt(t.palettes[0]), p = e - c - h, u = n - r - l, d = a === 1 && !s.panX && !s.panY, y = d ? e / 2 : c + p / 2, b = d ? n / 2 : r + u / 2, x = t.frames.map((M, P) => {
|
|
218
|
+
const S = new Uint8Array(e * n).fill(i), tt = t.palettes[P], R = new Uint8Array(256);
|
|
219
|
+
for (let w = 0; w < M.length; w++) R[M[w]] = 1;
|
|
220
|
+
const et = [...R.keys()].filter((w) => R[w]), V = /* @__PURE__ */ new Map(), U = (w, k) => tt[w * 3 + k] & 63;
|
|
221
|
+
for (let w = 0; w < u; w++) {
|
|
222
|
+
const k = r + w, _ = n / 2 + s.panY + (k - b) / a, nt = _ + 1 / a;
|
|
223
|
+
for (let $ = 0; $ < p; $++) {
|
|
224
|
+
const B = c + $, D = e / 2 + s.panX + (B - y) / a, st = D + 1 / a;
|
|
225
|
+
if (a >= 1) {
|
|
226
|
+
const A = Math.floor(D + 0.5 / a), g = Math.floor(_ + 0.5 / a);
|
|
227
|
+
A >= 0 && A < e && g >= 0 && g < n && (S[k * e + B] = M[g * e + A]);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const I = Math.max(0, Math.floor(D)), q = Math.min(e - 1, Math.ceil(st) - 1), Y = Math.max(0, Math.floor(_)), H = Math.min(n - 1, Math.ceil(nt) - 1);
|
|
231
|
+
if (I > q || Y > H) continue;
|
|
232
|
+
const z = M[Y * e + I];
|
|
233
|
+
let T = !0, j = 0, G = 0, J = 0, E = 0;
|
|
234
|
+
for (let A = Y; A <= H; A++)
|
|
235
|
+
for (let g = I; g <= q; g++) {
|
|
236
|
+
const v = M[A * e + g];
|
|
237
|
+
v !== z && (T = !1), j += U(v, 0), G += U(v, 1), J += U(v, 2), E++;
|
|
238
|
+
}
|
|
239
|
+
if (T) {
|
|
240
|
+
S[k * e + B] = z;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const O = Math.round(j / E) << 12 | Math.round(G / E) << 6 | Math.round(J / E);
|
|
244
|
+
let L = V.get(O);
|
|
245
|
+
if (L === void 0) {
|
|
246
|
+
let A = 1 / 0;
|
|
247
|
+
L = z;
|
|
248
|
+
for (const g of et) {
|
|
249
|
+
const v = (U(g, 0) - (O >> 12)) ** 2 + (U(g, 1) - (O >> 6 & 63)) ** 2 + (U(g, 2) - (O & 63)) ** 2;
|
|
250
|
+
v < A && ([L, A] = [g, v]);
|
|
251
|
+
}
|
|
252
|
+
V.set(O, L);
|
|
253
|
+
}
|
|
254
|
+
S[k * e + B] = L;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return S;
|
|
258
|
+
});
|
|
259
|
+
return C("frame it", !1, t, { ...t, frames: x }, {}, f);
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
Mt as bandColor,
|
|
263
|
+
Ct as chainVisibility,
|
|
264
|
+
ct as decodeFli,
|
|
265
|
+
dt as dropFramesStep,
|
|
266
|
+
Q as encodeFrames,
|
|
267
|
+
ft as flattenDitherStep,
|
|
268
|
+
wt as fliReport,
|
|
269
|
+
bt as frameStep,
|
|
270
|
+
it as holdStillStep,
|
|
271
|
+
ut as maxColorsStep,
|
|
272
|
+
xt as onePaletteStep,
|
|
273
|
+
At as shrinkFrames,
|
|
274
|
+
mt as snapColorsStep,
|
|
275
|
+
ht as sparsePalettesStep,
|
|
276
|
+
Z as visibilityOf
|
|
277
|
+
};
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { readdirSync as A, readFileSync as M } from "node:fs";
|
|
2
|
+
import { join as b } from "node:path";
|
|
3
|
+
import { fileURLToPath as v } from "node:url";
|
|
4
|
+
import { moveChars as B } from "@lewismoten/gamemaker-sandbox-engine/engine/character";
|
|
5
|
+
import { simKeyPress as C } from "@lewismoten/gamemaker-sandbox-engine/engine/keys";
|
|
6
|
+
import { blockBirthMonsters as K, moveAllMonsters as L } from "@lewismoten/gamemaker-sandbox-engine/engine/monsters";
|
|
7
|
+
import { updateCharDrawState as x } from "@lewismoten/gamemaker-sandbox-engine/engine/render";
|
|
8
|
+
import { initScroll as N, drawScroll as E, changeScroll as j } from "@lewismoten/gamemaker-sandbox-engine/engine/scroll";
|
|
9
|
+
import { startSceneInits as I, changeBlocks as O } from "@lewismoten/gamemaker-sandbox-engine/engine/scene";
|
|
10
|
+
import { getTouchBlocks as R } from "@lewismoten/gamemaker-sandbox-engine/engine/touch";
|
|
11
|
+
import { BACKBL as D, newCharInfo as P, createWorld as W, padBlocks as f, LASTMM as q, MLEN as F, bgBlock as G } from "@lewismoten/gamemaker-sandbox-engine/engine/world";
|
|
12
|
+
import { parseBlocks as k, BACKBL as y, MONBL as w, CHARBL as S } from "@lewismoten/gamemaker-sandbox-engine/formats/blocks";
|
|
13
|
+
import { parseCharacter as H } from "@lewismoten/gamemaker-sandbox-engine/formats/character";
|
|
14
|
+
import { parseMonsters as U } from "@lewismoten/gamemaker-sandbox-engine/formats/monster";
|
|
15
|
+
import { parseMap as _ } from "@lewismoten/gamemaker-sandbox-engine/formats/map";
|
|
16
|
+
import { parseGame as $, MAXSCENELINKS as m, NOSCENE as V } from "@lewismoten/gamemaker-sandbox-engine/formats/game";
|
|
17
|
+
import { parseSoundSet as X, LASTSND as z } from "@lewismoten/gamemaker-sandbox-engine/formats/sound";
|
|
18
|
+
import { vocMs as J } from "./clips.js";
|
|
19
|
+
const Q = 18.2;
|
|
20
|
+
function Y(n) {
|
|
21
|
+
const t = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const e of A(n)) t.set(e.toLowerCase(), new Uint8Array(M(b(n, e))));
|
|
23
|
+
return t;
|
|
24
|
+
}
|
|
25
|
+
class p {
|
|
26
|
+
constructor(t) {
|
|
27
|
+
this.a = t;
|
|
28
|
+
}
|
|
29
|
+
a;
|
|
30
|
+
next = () => {
|
|
31
|
+
this.a = this.a + 1831565813 >>> 0;
|
|
32
|
+
let t = this.a;
|
|
33
|
+
return t = Math.imul(t ^ t >>> 15, t | 1), t ^= t + Math.imul(t ^ t >>> 7, t | 61), ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
class Z {
|
|
37
|
+
constructor(t, e = 1) {
|
|
38
|
+
this.files = t, this.seed = e, this.game = $(t.get([...t.keys()].find((o) => o.endsWith(".gam")))), this.ci.hitpts = -1, this.ci.lives = -1, this.ci.score = 0, this.ci.inv.fill(D + 1), this.ci.meter.fill(-1), this.enter(this.game.scenes[0].links[0].toScene, 0, 0);
|
|
39
|
+
}
|
|
40
|
+
files;
|
|
41
|
+
seed;
|
|
42
|
+
game;
|
|
43
|
+
ci = P();
|
|
44
|
+
w;
|
|
45
|
+
scene = 0;
|
|
46
|
+
prev = 0;
|
|
47
|
+
link = 0;
|
|
48
|
+
/** Scenes entered, in order (a death enters the same scene again). */
|
|
49
|
+
trail = [];
|
|
50
|
+
/** Game ticks since play entered the current scene (a segment's clock). */
|
|
51
|
+
ticks = 0;
|
|
52
|
+
/** Keys per scene entered (a scene entered again after a death keeps counting on). */
|
|
53
|
+
segments = [];
|
|
54
|
+
/** Ticks each finished segment ran. */
|
|
55
|
+
segmentTicks = [];
|
|
56
|
+
lastKeyTick = 0;
|
|
57
|
+
held = /* @__PURE__ */ new Set();
|
|
58
|
+
pending = [];
|
|
59
|
+
doScroll = !1;
|
|
60
|
+
/** TimerCounter: it runs on across scenes. */
|
|
61
|
+
clock = 1;
|
|
62
|
+
rand = new p(0);
|
|
63
|
+
ended;
|
|
64
|
+
deaths = 0;
|
|
65
|
+
/** The inventory slot the drop picker answers with once (set it before pressing the drop key; -1, the default, is Esc). */
|
|
66
|
+
dropSlot = -1;
|
|
67
|
+
/**
|
|
68
|
+
* The .VOC clip the Sound Blaster is playing (PlaySbVocFile: a new one cuts it off), with
|
|
69
|
+
* the game clock tick it ends on; a scene's exit or intro picture cuts it too (ShowGraphic).
|
|
70
|
+
*/
|
|
71
|
+
clip;
|
|
72
|
+
file(t, e) {
|
|
73
|
+
const o = this.game.scenes[t].files[e];
|
|
74
|
+
return o ? this.files.get(o) : void 0;
|
|
75
|
+
}
|
|
76
|
+
/** loadscene + StartSceneInits, as playScene does them. */
|
|
77
|
+
enter(t, e, o, a = !1) {
|
|
78
|
+
this.scene = t, this.prev = e, this.link = o, this.trail.push(t), a || (this.segments.length && this.segmentTicks.push(this.ticks), this.segments.push({ scene: t, keys: [] }), this.ticks = 0, this.lastKeyTick = 0);
|
|
79
|
+
const r = (c) => this.file(t, c);
|
|
80
|
+
this.rand = new p(this.seed), (this.game.scenes[e]?.files[10] || this.game.scenes[t].files[9]) && (this.clip = void 0);
|
|
81
|
+
const l = r(7) && X(r(7)), h = (c) => {
|
|
82
|
+
if (!l || c < 0 || c >= z) return !1;
|
|
83
|
+
const d = l.digital[c], g = d && d[0] !== " " ? this.files.get(`${d.toLowerCase()}.voc`) : void 0;
|
|
84
|
+
return g && (this.clip = { name: d, until: this.clock + Math.ceil(J(g) / 1e3 * Q) }), !0;
|
|
85
|
+
}, i = this.w, s = W(_(r(1)), { play: h }, this.rand.next);
|
|
86
|
+
s.bg = f(k(r(2), y), y), s.mblk = f(r(4) ? k(r(4), w) : void 0, w), s.cblk = r(6) || !i ? f(k(r(6), S), S) : i.cblk, s.mon = r(3) ? U(r(3)) : [], s.noMons = !r(3) || !r(4), s.chr = r(5) || !i ? H(r(5)) : i.chr, s.ci = this.ci, s.clock = this.clock, this.w = s, I(s, this.game.scenes[e].links[o].to), s.gclk = s.clock, s.joyOldTime = s.clock, N(s, this.game.scenes[t].scroll), this.doScroll = !1, this.held.clear(), this.pending = [];
|
|
87
|
+
}
|
|
88
|
+
press(t) {
|
|
89
|
+
this.held.has(t) || (this.held.add(t), this.event(t));
|
|
90
|
+
}
|
|
91
|
+
release(t) {
|
|
92
|
+
this.held.has(t) && (this.held.delete(t), this.event(t | 128));
|
|
93
|
+
}
|
|
94
|
+
releaseAll() {
|
|
95
|
+
for (const t of [...this.held]) this.release(t);
|
|
96
|
+
}
|
|
97
|
+
isHeld(t) {
|
|
98
|
+
return this.held.has(t);
|
|
99
|
+
}
|
|
100
|
+
event(t) {
|
|
101
|
+
this.ended || (this.pending.push(t), this.record(t));
|
|
102
|
+
}
|
|
103
|
+
/** Writes key `k` into the segment (without playing it in this sim): the drop picker's own keys, which the real engine reads. */
|
|
104
|
+
record(t) {
|
|
105
|
+
if (this.ended) return;
|
|
106
|
+
const e = this.ticks + 1;
|
|
107
|
+
this.segments[this.segments.length - 1].keys.push({ delta: e - this.lastKeyTick, key: t }), this.lastKeyTick = e;
|
|
108
|
+
}
|
|
109
|
+
/** One game tick; returns 'link' (into another scene), 'dead' or 'end'. */
|
|
110
|
+
async tick() {
|
|
111
|
+
if (this.ended) return "end";
|
|
112
|
+
const t = this.w;
|
|
113
|
+
this.ticks++, this.clock++;
|
|
114
|
+
for (let i = 0; i < 8; i++) this.doScroll && E(t);
|
|
115
|
+
t.clock = this.clock, t.noMons || (K(t), L(t));
|
|
116
|
+
const e = t.chr;
|
|
117
|
+
if (this.pending.length && (!e.sequences[e.cseq].ground || e.cframe === 0)) for (const i of this.pending.splice(0)) C(t, i);
|
|
118
|
+
let o = !1, a = 0;
|
|
119
|
+
do
|
|
120
|
+
await B(t, async () => {
|
|
121
|
+
const i = this.dropSlot;
|
|
122
|
+
if (this.dropSlot = -1, i >= 0) {
|
|
123
|
+
const s = [...new Array(i % 5).fill(77), ...i >= 5 ? [80] : [], 28];
|
|
124
|
+
for (const c of s)
|
|
125
|
+
this.record(c), this.record(c | 128);
|
|
126
|
+
}
|
|
127
|
+
return i;
|
|
128
|
+
}) && (o = !0);
|
|
129
|
+
while (t.chr.cframe === -1 && !o && a++ < 50);
|
|
130
|
+
O(t), x(t), this.doScroll = j(t) !== 0, t.monsolid = 0, t.mmSolid = q;
|
|
131
|
+
const r = R(t), l = this.game.scenes[this.scene].links;
|
|
132
|
+
let h = m;
|
|
133
|
+
for (let i = 0; i < m && h === m; i++) {
|
|
134
|
+
const s = l[i];
|
|
135
|
+
if (!(!s || s.toScene === V))
|
|
136
|
+
for (let c = 0; c < 6; c++) s.from.x === r.blks[c][0] && s.from.y === r.blks[c][1] && (h = i);
|
|
137
|
+
}
|
|
138
|
+
if (o)
|
|
139
|
+
return this.deaths++, this.ci.lives > 0 ? (this.ci.lives--, this.ci.hitpts = -1, this.enter(this.scene, this.prev, this.link, !0)) : this.ended = "lost", "dead";
|
|
140
|
+
if (h !== m) {
|
|
141
|
+
const i = l[h].toScene;
|
|
142
|
+
return i === 1 ? (this.ended = "won", "end") : (this.enter(i, this.scene, h), "link");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** Game ticks until the clip playing now ends (0 when none is). */
|
|
146
|
+
get clipTicksLeft() {
|
|
147
|
+
return this.clip ? Math.max(0, this.clip.until - this.clock) : 0;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Stands still until the clip playing now has played to the end, so the bot's next sound
|
|
151
|
+
* (a jump, a pickup) doesn't cut it off: a level's start clip, say. Returns what a tick
|
|
152
|
+
* returned if play left the scene meanwhile.
|
|
153
|
+
*/
|
|
154
|
+
async waitForClip() {
|
|
155
|
+
for (this.releaseAll(); this.clipTicksLeft > 0; ) {
|
|
156
|
+
const t = await this.tick();
|
|
157
|
+
if (t) return t;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** The character's block and the pixels past it. */
|
|
161
|
+
get pos() {
|
|
162
|
+
const t = this.w.chr;
|
|
163
|
+
return { x: t.x[0], y: t.y[0], sx: t.x[1], sy: t.y[1] };
|
|
164
|
+
}
|
|
165
|
+
meter(t) {
|
|
166
|
+
return this.ci.meter[t];
|
|
167
|
+
}
|
|
168
|
+
/** Money: Game-Maker's counter 3, which shows meter - 1. */
|
|
169
|
+
get money() {
|
|
170
|
+
return this.ci.meter[3] - 1;
|
|
171
|
+
}
|
|
172
|
+
/** The block number at (x, y) as it is now (a block taken or pushed is a new block number). */
|
|
173
|
+
blockAt(t, e) {
|
|
174
|
+
return this.w.map[e * F + t];
|
|
175
|
+
}
|
|
176
|
+
/** The block's attributes as shown now (timed blocks change by themselves). */
|
|
177
|
+
shown(t, e) {
|
|
178
|
+
return G(this.w, this.w.blkmap[this.blockAt(t, e)] ?? 0);
|
|
179
|
+
}
|
|
180
|
+
solidAt(t, e) {
|
|
181
|
+
return this.shown(t, e).solid !== 0;
|
|
182
|
+
}
|
|
183
|
+
snapshot() {
|
|
184
|
+
return {
|
|
185
|
+
w: T(this.w),
|
|
186
|
+
rand: this.rand.a,
|
|
187
|
+
scene: this.scene,
|
|
188
|
+
prev: this.prev,
|
|
189
|
+
link: this.link,
|
|
190
|
+
ticks: this.ticks,
|
|
191
|
+
clock: this.clock,
|
|
192
|
+
lastKeyTick: this.lastKeyTick,
|
|
193
|
+
held: [...this.held],
|
|
194
|
+
pending: [...this.pending],
|
|
195
|
+
doScroll: this.doScroll,
|
|
196
|
+
ended: this.ended,
|
|
197
|
+
deaths: this.deaths,
|
|
198
|
+
trail: [...this.trail],
|
|
199
|
+
segments: this.segments.map((t) => ({ scene: t.scene, keys: t.keys.slice() })),
|
|
200
|
+
segmentTicks: [...this.segmentTicks],
|
|
201
|
+
clip: this.clip && { ...this.clip }
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
restore(t) {
|
|
205
|
+
this.rand = new p(t.rand);
|
|
206
|
+
const e = T(t.w);
|
|
207
|
+
e.rand = this.rand.next, this.w = e, this.ci = e.ci, this.scene = t.scene, this.prev = t.prev, this.link = t.link, this.ticks = t.ticks, this.clock = t.clock, this.lastKeyTick = t.lastKeyTick, this.held = new Set(t.held), this.pending = [...t.pending], this.doScroll = t.doScroll, this.ended = t.ended, this.deaths = t.deaths, this.trail = [...t.trail], this.segments = t.segments.map((o) => ({ scene: o.scene, keys: o.keys.slice() })), this.segmentTicks = [...t.segmentTicks], this.clip = t.clip && { ...t.clip };
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function T(n) {
|
|
211
|
+
const { sound: t, rand: e, joystick: o, bg: a, mblk: r, cblk: l, mon: h, palette: i, chr: s, ...c } = n;
|
|
212
|
+
return { ...u(c), sound: t, rand: e, joystick: o, bg: a, mblk: r, cblk: l, mon: h, palette: i, chr: { ...s, x: [...s.x], y: [...s.y] } };
|
|
213
|
+
}
|
|
214
|
+
function u(n) {
|
|
215
|
+
if (n === null || typeof n != "object") return n;
|
|
216
|
+
if (ArrayBuffer.isView(n)) return n.slice();
|
|
217
|
+
if (Array.isArray(n)) return n.map(u);
|
|
218
|
+
const t = {};
|
|
219
|
+
for (const e in n) t[e] = u(n[e]);
|
|
220
|
+
return t;
|
|
221
|
+
}
|
|
222
|
+
function yt(n) {
|
|
223
|
+
const t = v(n);
|
|
224
|
+
return class extends Z {
|
|
225
|
+
constructor(e = Y(t), o = 1) {
|
|
226
|
+
super(e, o);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
export {
|
|
231
|
+
Z as GameSim,
|
|
232
|
+
Q as TICKS_PER_SECOND,
|
|
233
|
+
yt as diskSim,
|
|
234
|
+
Y as readDisk
|
|
235
|
+
};
|