@lewismoten/gamemaker-sandbox-engine 0.0.0-stage → 3.3.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 +42 -0
- package/LICENSE +24 -0
- package/NOTICE.md +58 -0
- package/README.md +149 -2
- package/dist/assets/music.worklet-aD2x7RRM.js +466 -0
- package/dist/audio/cmfLoad.js +10 -0
- package/dist/audio/cmfPlayer.js +201 -0
- package/dist/audio/context.js +75 -0
- package/dist/audio/engine.js +173 -0
- package/dist/audio/mix.js +40 -0
- package/dist/audio/opl.js +245 -0
- package/dist/audio/output.js +40 -0
- package/dist/core/gameFiles.js +89 -0
- package/dist/engine/character.js +187 -0
- package/dist/engine/funcKeys.js +164 -0
- package/dist/engine/game.js +133 -0
- package/dist/engine/keys.js +68 -0
- package/dist/engine/machine.js +192 -0
- package/dist/engine/menus.js +135 -0
- package/dist/engine/monsters.js +259 -0
- package/dist/engine/playGain.js +10 -0
- package/dist/engine/playerLook.js +48 -0
- package/dist/engine/recorder.js +127 -0
- package/dist/engine/render.js +45 -0
- package/dist/engine/scene.js +324 -0
- package/dist/engine/scroll.js +79 -0
- package/dist/engine/showGraphic.js +107 -0
- package/dist/engine/slowPc.js +98 -0
- package/dist/engine/slowPcMusic.js +46 -0
- package/dist/engine/touch.js +61 -0
- package/dist/engine/world.js +205 -0
- package/dist/formats/binary.js +120 -0
- package/dist/formats/blocks.js +103 -0
- package/dist/formats/character.js +83 -0
- package/dist/formats/cmf.js +37 -0
- package/dist/formats/cmfEdit.js +154 -0
- package/dist/formats/cmfPreview.js +89 -0
- package/dist/formats/cmfSong.js +190 -0
- package/dist/formats/fli.js +340 -0
- package/dist/formats/fliFrames.js +34 -0
- package/dist/formats/fliLimits.js +54 -0
- package/dist/formats/game.js +198 -0
- package/dist/formats/gif.js +125 -0
- package/dist/formats/gifProgressive.js +99 -0
- package/dist/formats/graphicScripts.js +44 -0
- package/dist/formats/highscore.js +30 -0
- package/dist/formats/jpeg.js +359 -0
- package/dist/formats/map.js +38 -0
- package/dist/formats/monster.js +69 -0
- package/dist/formats/palette.js +58 -0
- package/dist/formats/recording.js +17 -0
- package/dist/formats/sound.js +44 -0
- package/dist/formats/voc.js +303 -0
- package/dist/gfx/colorVision.js +45 -0
- package/dist/gfx/cp437Glyphs.js +337 -0
- package/dist/gfx/font8x8.js +10 -0
- package/dist/gfx/screen.js +151 -0
- package/dist/index.js +15 -0
- package/dist/input/chords.js +46 -0
- package/dist/input/deskMouse.js +24 -0
- package/dist/input/keyboard.js +82 -0
- package/dist/input/scancodes.js +143 -0
- package/dist/player/fileExtensions.js +118 -0
- package/dist/player/patchRules.js +129 -0
- package/dist/player/patchTable.js +1753 -0
- package/dist/text/cp437.js +44 -0
- package/dist/types/audio/cmfLoad.d.ts +7 -0
- package/dist/types/audio/cmfPlayer.d.ts +69 -0
- package/dist/types/audio/context.d.ts +12 -0
- package/dist/types/audio/engine.d.ts +60 -0
- package/dist/types/audio/mix.d.ts +14 -0
- package/dist/types/audio/music.worklet.d.ts +22 -0
- package/dist/types/audio/opl.d.ts +37 -0
- package/dist/types/audio/output.d.ts +13 -0
- package/dist/types/core/gameFiles.d.ts +49 -0
- package/dist/types/engine/character.d.ts +30 -0
- package/dist/types/engine/funcKeys.d.ts +35 -0
- package/dist/types/engine/game.d.ts +57 -0
- package/dist/types/engine/keys.d.ts +17 -0
- package/dist/types/engine/machine.d.ts +103 -0
- package/dist/types/engine/menus.d.ts +46 -0
- package/dist/types/engine/monsters.d.ts +19 -0
- package/dist/types/engine/playGain.d.ts +11 -0
- package/dist/types/engine/playerLook.d.ts +44 -0
- package/dist/types/engine/recorder.d.ts +67 -0
- package/dist/types/engine/render.d.ts +8 -0
- package/dist/types/engine/scene.d.ts +188 -0
- package/dist/types/engine/scroll.d.ts +24 -0
- package/dist/types/engine/showGraphic.d.ts +39 -0
- package/dist/types/engine/slowPc.d.ts +124 -0
- package/dist/types/engine/slowPcMusic.d.ts +18 -0
- package/dist/types/engine/touch.d.ts +33 -0
- package/dist/types/engine/world.d.ts +237 -0
- package/dist/types/formats/binary.d.ts +44 -0
- package/dist/types/formats/blocks.d.ts +52 -0
- package/dist/types/formats/character.d.ts +65 -0
- package/dist/types/formats/cmf.d.ts +33 -0
- package/dist/types/formats/cmfEdit.d.ts +53 -0
- package/dist/types/formats/cmfPreview.d.ts +19 -0
- package/dist/types/formats/cmfSong.d.ts +74 -0
- package/dist/types/formats/fli.d.ts +56 -0
- package/dist/types/formats/fliFrames.d.ts +18 -0
- package/dist/types/formats/fliLimits.d.ts +13 -0
- package/dist/types/formats/game.d.ts +79 -0
- package/dist/types/formats/gif.d.ts +15 -0
- package/dist/types/formats/gifProgressive.d.ts +46 -0
- package/dist/types/formats/graphicScripts.d.ts +18 -0
- package/dist/types/formats/highscore.d.ts +10 -0
- package/dist/types/formats/jpeg.d.ts +20 -0
- package/dist/types/formats/map.d.ts +24 -0
- package/dist/types/formats/monster.d.ts +48 -0
- package/dist/types/formats/palette.d.ts +15 -0
- package/dist/types/formats/recording.d.ts +7 -0
- package/dist/types/formats/sound.d.ts +13 -0
- package/dist/types/formats/voc.d.ts +13 -0
- package/dist/types/gfx/colorVision.d.ts +26 -0
- package/dist/types/gfx/cp437Glyphs.d.ts +2 -0
- package/dist/types/gfx/font8x8.d.ts +2 -0
- package/dist/types/gfx/screen.d.ts +50 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/input/chords.d.ts +22 -0
- package/dist/types/input/deskMouse.d.ts +14 -0
- package/dist/types/input/keyboard.d.ts +39 -0
- package/dist/types/input/scancodes.d.ts +3 -0
- package/dist/types/player/fileExtensions.d.ts +44 -0
- package/dist/types/player/patchRules.d.ts +24 -0
- package/dist/types/player/patchTable.d.ts +83 -0
- package/dist/types/text/cp437.d.ts +6 -0
- package/package.json +339 -4
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const i = {
|
|
2
|
+
tickMs: 15,
|
|
3
|
+
monsterMs: 1.2,
|
|
4
|
+
scrollPassMs: 2.5,
|
|
5
|
+
stripMs: 1.5
|
|
6
|
+
};
|
|
7
|
+
class c {
|
|
8
|
+
constructor(t) {
|
|
9
|
+
this.interruptMs = t;
|
|
10
|
+
}
|
|
11
|
+
interruptMs;
|
|
12
|
+
/** Milliseconds of work still running. */
|
|
13
|
+
owed = 0;
|
|
14
|
+
/**
|
|
15
|
+
* Called once per NewTimer interrupt: true when the PC is still busy with earlier work
|
|
16
|
+
* and this interrupt's pass of the main loop (scroll step, game tick) is lost.
|
|
17
|
+
*/
|
|
18
|
+
busy() {
|
|
19
|
+
return this.owed >= this.interruptMs ? (this.owed -= this.interruptMs, !0) : (this.owed = 0, !1);
|
|
20
|
+
}
|
|
21
|
+
spend(t) {
|
|
22
|
+
this.owed += t;
|
|
23
|
+
}
|
|
24
|
+
reset() {
|
|
25
|
+
this.owed = 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function l(s, t, e = 0) {
|
|
29
|
+
return s.tickMs + s.monsterMs * t + (s.cellMs ?? 0) * Math.min(e, 170);
|
|
30
|
+
}
|
|
31
|
+
function u(s, t) {
|
|
32
|
+
return s.scrollPassMs + s.stripMs * t;
|
|
33
|
+
}
|
|
34
|
+
const v = ["today", "486", "386", "286", "ps1"], n = {
|
|
35
|
+
// 286 at 12 MHz, IDE disk about 400 KB/s, 30 ms to open a file; 20 monsters fill a tick
|
|
36
|
+
// (sourced range for a 286-era MFM or early IDE drive: about 220-550 KB/s, 30-75 ms an open)
|
|
37
|
+
286: { tickMs: 20, monsterMs: 1.8, scrollPassMs: 3.3, stripMs: 2, cellMs: 0.25, vocOpenMs: 30, vocBytesPerMs: 400, ...o(0.035, 0.033) },
|
|
38
|
+
// 386DX-33, disk about 800 KB/s, 18 ms to open
|
|
39
|
+
386: { tickMs: 9, monsterMs: 0.8, scrollPassMs: 1.5, stripMs: 0.8, cellMs: 0.12, vocOpenMs: 18, vocBytesPerMs: 800, ...o(0.016, 0.015) },
|
|
40
|
+
// 486DX2-66, disk about 1.5 MB/s, 12 ms to open
|
|
41
|
+
486: { tickMs: 4, monsterMs: 0.35, scrollPassMs: 0.7, stripMs: 0.4, cellMs: 0.05, vocOpenMs: 12, vocBytesPerMs: 1500, ...o(7e-3, 6e-3) },
|
|
42
|
+
// IBM PS/1 Model 2011: a 286 at 10 MHz (the 286-12's CPU costs times 1.2), 1 MB, a small slow hard disk
|
|
43
|
+
// (about 80 ms to find a file and about 150 KB/s after that), no disk cache, no EMS. PLAYGAME reads a
|
|
44
|
+
// .voc whole from the disk every time it plays one and keeps nothing between plays, so the cache a
|
|
45
|
+
// roomier PC might have added never helps here; the extra 384 KB above 640 KB is out of PLAYGAME's reach.
|
|
46
|
+
// The disk is the 2011's 30 MB WDL-330P (IBM PS/1 Technical Reference 57F1970, p. 8-26): 19 ms average
|
|
47
|
+
// access, 3600 rpm, 33 sectors a track at a 4:1 interleave, so at most about 247 KB/s; 80 ms and 150 KB/s
|
|
48
|
+
// are the slow end of what that gives with an uncached directory and fragmented files (range 30-90 ms,
|
|
49
|
+
// 145-245 KB/s). Estimates, not timed on a real PS/1 or in an emulator.
|
|
50
|
+
// DOS 4 lives in the PS/1's ROM, so only its data takes conventional memory (about 45 KB more for the
|
|
51
|
+
// game than a DOS loaded from disk): about 145 KB of the far heap is left once DOS's data, drivers and
|
|
52
|
+
// the game's own data have their share.
|
|
53
|
+
ps1: {
|
|
54
|
+
tickMs: 24,
|
|
55
|
+
monsterMs: 2.2,
|
|
56
|
+
scrollPassMs: 4,
|
|
57
|
+
stripMs: 2.4,
|
|
58
|
+
cellMs: 0.3,
|
|
59
|
+
vocOpenMs: 80,
|
|
60
|
+
vocBytesPerMs: 150,
|
|
61
|
+
vocHeapBytes: 145e3,
|
|
62
|
+
...o(0.042, 0.04)
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
function o(s, t) {
|
|
66
|
+
return { readHoldsMusic: !1, isrMs: s, fmEventMs: t, fmWriteMs: 0.03 };
|
|
67
|
+
}
|
|
68
|
+
function a(s) {
|
|
69
|
+
return s === "today" ? void 0 : n[s];
|
|
70
|
+
}
|
|
71
|
+
function d(s, t) {
|
|
72
|
+
return M(s, t) ? s.vocOpenMs ?? 0 : !s || s.vocOpenMs === void 0 || !s.vocBytesPerMs ? 0 : s.vocOpenMs + t / s.vocBytesPerMs;
|
|
73
|
+
}
|
|
74
|
+
function f(s, t) {
|
|
75
|
+
return s?.readHoldsMusic ? t : 0;
|
|
76
|
+
}
|
|
77
|
+
function M(s, t) {
|
|
78
|
+
return !!s && s.vocHeapBytes !== void 0 && t > s.vocHeapBytes;
|
|
79
|
+
}
|
|
80
|
+
function P(s, t) {
|
|
81
|
+
if (!s || s.vocOpenMs === void 0 || !s.vocBytesPerMs) return 0;
|
|
82
|
+
let e = 0;
|
|
83
|
+
for (const r of t) e += s.vocOpenMs + r / s.vocBytesPerMs;
|
|
84
|
+
return e;
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
v as SPEED_CHOICES,
|
|
88
|
+
n as SPEED_PRESETS,
|
|
89
|
+
c as SlowCpu,
|
|
90
|
+
i as TURBO_OFF,
|
|
91
|
+
a as costsFor,
|
|
92
|
+
f as musicHoldMs,
|
|
93
|
+
P as sceneLoadMs,
|
|
94
|
+
u as scrollCost,
|
|
95
|
+
l as tickCost,
|
|
96
|
+
d as vocStallMs,
|
|
97
|
+
M as vocWontFit
|
|
98
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { loadSong as v } from "../audio/cmfLoad.js";
|
|
2
|
+
import { TICK_RATE as p } from "../audio/cmfPlayer.js";
|
|
3
|
+
const o = { on: 4, off: 1, program: 11 };
|
|
4
|
+
function E(s) {
|
|
5
|
+
const e = v(s)?.music;
|
|
6
|
+
if (!e) return;
|
|
7
|
+
let n = 0;
|
|
8
|
+
const a = () => {
|
|
9
|
+
let t = 0, r;
|
|
10
|
+
do
|
|
11
|
+
r = e[n++] ?? 0, t = t * 128 + (r & 127);
|
|
12
|
+
while (r & 128 && n < e.length);
|
|
13
|
+
return t;
|
|
14
|
+
};
|
|
15
|
+
a();
|
|
16
|
+
const i = { interrupts: 0, events: 0, writes: 0, peakEvents: 0, peakWrites: 0 };
|
|
17
|
+
let l = 128, f = 0, u = 0;
|
|
18
|
+
const m = () => {
|
|
19
|
+
i.peakEvents = Math.max(i.peakEvents, f), i.peakWrites = Math.max(i.peakWrites, u), f = u = 0;
|
|
20
|
+
};
|
|
21
|
+
for (; n < e.length; ) {
|
|
22
|
+
e[n] & 128 && (l = e[n++]);
|
|
23
|
+
const t = l & 240;
|
|
24
|
+
let r = 0;
|
|
25
|
+
if (t === 144 ? r = e[n + 1] ? o.on : o.off : t === 128 ? r = o.off : t === 192 && (r = o.program), t === 128 || t === 144 || t === 160 || t === 176 || t === 224) n += 2;
|
|
26
|
+
else if (t === 192 || t === 208) n += 1;
|
|
27
|
+
else break;
|
|
28
|
+
r && (f++, u += r, i.events++, i.writes += r);
|
|
29
|
+
const M = a();
|
|
30
|
+
M && m(), i.interrupts += M;
|
|
31
|
+
}
|
|
32
|
+
return m(), i;
|
|
33
|
+
}
|
|
34
|
+
function g(s, e) {
|
|
35
|
+
return s?.isrMs ? !e || !e.interrupts ? s.isrMs : s.isrMs + (e.events * (s.fmEventMs ?? 0) + e.writes * (s.fmWriteMs ?? 0)) / e.interrupts : 0;
|
|
36
|
+
}
|
|
37
|
+
function h(s, e) {
|
|
38
|
+
return (s.isrMs ?? 0) + e.peakEvents * (s.fmEventMs ?? 0) + e.peakWrites * (s.fmWriteMs ?? 0);
|
|
39
|
+
}
|
|
40
|
+
const w = 1e3 / p;
|
|
41
|
+
export {
|
|
42
|
+
w as INTERRUPT_MS,
|
|
43
|
+
g as songIsrMs,
|
|
44
|
+
E as songLoad,
|
|
45
|
+
h as songPeakIsrMs
|
|
46
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { MAXSEQ as x, DIESEQ as E, INF_REPEAT as r, HURTSEQ as h } from "../formats/character.js";
|
|
2
|
+
import { pushKey as B } from "./keys.js";
|
|
3
|
+
import { i16 as S, u16 as N, mapBlock as U } from "./world.js";
|
|
4
|
+
import { BACKBL as l, BLEN as p } from "../formats/blocks.js";
|
|
5
|
+
import { LASTSND as O } from "../formats/sound.js";
|
|
6
|
+
import { MLEN as m, MWID as a } from "../formats/map.js";
|
|
7
|
+
const A = 0, X = 1, d = 2, P = 3, T = 4, q = 5, H = 6, L = 7, g = 8;
|
|
8
|
+
function i(t, e) {
|
|
9
|
+
return e >= 0 && e < O ? t.sound.play(e) : !1;
|
|
10
|
+
}
|
|
11
|
+
function R(t) {
|
|
12
|
+
return t.x >= 1 && t.y >= 1 && t.x <= 320 - p && t.y <= 200 - p;
|
|
13
|
+
}
|
|
14
|
+
function C(t, e, c, f) {
|
|
15
|
+
return f.x = e - t.mx, t.mx > e && (f.x += m), f.x = f.x * p - t.scroll.nx, f.y = c - t.my, t.my > c && (f.y += a), f.y = f.y * p - t.scroll.ny, R(f);
|
|
16
|
+
}
|
|
17
|
+
function I(t) {
|
|
18
|
+
const { chr: e, ci: c } = t, f = { blks: Array.from({ length: 6 }, () => [m, a]), blknum: new Array(6).fill(l) }, o = (u, D, y) => {
|
|
19
|
+
f.blks[u] = [D, y], f.blknum[u] = t.blkmap[U(t, D, y)] ?? l;
|
|
20
|
+
}, s = e.x[0], n = e.y[0];
|
|
21
|
+
if (c.topthere) {
|
|
22
|
+
const u = n - 1 < 0 ? n - 1 + a : n - 1;
|
|
23
|
+
o(0, s, u), e.x[1] > 0 && o(1, (s + 1) % m, u);
|
|
24
|
+
}
|
|
25
|
+
return o(2, s, n), e.x[1] > 0 && o(3, (s + 1) % m, n), e.y[1] > 0 && o(4, s, (n + 1) % a), e.x[1] > 0 && e.y[1] > 0 && o(5, (s + 1) % m, (n + 1) % a), f;
|
|
26
|
+
}
|
|
27
|
+
function _(t, e, c) {
|
|
28
|
+
for (let f = 0; f < x; f++) t.chr.sequences[f].bloc === e && (t.ci.seqon[f] = c);
|
|
29
|
+
}
|
|
30
|
+
function M(t, e) {
|
|
31
|
+
const { ci: c, chr: f } = t;
|
|
32
|
+
let o = !1;
|
|
33
|
+
if ((e.effect >= 20 || e.effect === 3) && c.meter[e.effect] + e.eamt <= 0) return 0;
|
|
34
|
+
if (f.cseq !== E && (e.chHitPt <= 0 ? c.hitpts = S(c.hitpts + e.chHitPt) : N(c.hitpts + e.chHitPt) < r ? c.hitpts = S(c.hitpts + e.chHitPt) : c.hitpts = r - 1, e.chHitPt > 0 ? o = i(t, A) : e.chHitPt < 0 && f.cseq !== h && (B(t), c.nextAni = t.clock, f.cseq = h, f.cframe = -1, t.curkey = 255, f.sequences[h].sound < O && f.sequences[h].sound >= 0 && (o = i(t, f.sequences[h].sound))), c.hitpts <= 0 && (c.nextAni = t.clock, f.cseq = E, f.cframe = -1, t.curkey = 0)), e.effect === 1 && (e.eamt > 0 && (o = i(t, T)), c.lives = S(c.lives + e.eamt)), e.effect > 2 && c.meter[e.effect] !== r && e.effect < c.meter.length) {
|
|
35
|
+
o || (e.effect === 3 ? e.eamt > 0 ? o = i(t, d) : e.eamt < 0 && (o = i(t, P)) : e.eamt > 0 ? o = i(t, L) : e.eamt < 0 && (o = i(t, g)));
|
|
36
|
+
const s = c.meter[e.effect];
|
|
37
|
+
N(s + e.eamt) < r ? s + e.eamt < -1 * (r - 128) ? c.meter[e.effect] = -1 * (r - 128) : c.meter[e.effect] = S(s + e.eamt) : c.meter[e.effect] = r - 1;
|
|
38
|
+
}
|
|
39
|
+
return c.score += e.scorePts, o || (e.scorePts > 0 ? o = i(t, q) : e.scorePts < 0 && (o = i(t, H))), o ? 2 : 1;
|
|
40
|
+
}
|
|
41
|
+
function F(t, e, c, f) {
|
|
42
|
+
if (e === m) return 1;
|
|
43
|
+
const o = t.bg[f] ?? t.bg[l];
|
|
44
|
+
return M(t, o) ? ((f !== o.touchBl || o.obj) && t.onTouched?.(e, c, f), f !== o.touchBl && C(t, e, c, { x: 0, y: 0 }) && (t.map[c * m + e] = o.touchBl), 1) : 2;
|
|
45
|
+
}
|
|
46
|
+
function z(t) {
|
|
47
|
+
const e = I(t);
|
|
48
|
+
for (let c = 0; c < 6; c++)
|
|
49
|
+
(t.bg[e.blknum[c]] ?? t.bg[l]).obj || F(t, e.blks[c][0], e.blks[c][1], e.blknum[c]);
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
X as KILLSOUND,
|
|
53
|
+
_ as checkSeqForTie,
|
|
54
|
+
z as checkTouch,
|
|
55
|
+
M as doBlockTouchChar,
|
|
56
|
+
i as doSound,
|
|
57
|
+
I as getTouchBlocks,
|
|
58
|
+
R as inScreenBounds,
|
|
59
|
+
C as onscrn,
|
|
60
|
+
F as reallyCheckTouch
|
|
61
|
+
};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { BACKBL as c, CHARBL as i, emptyBlock as u, MONBL as p } from "../formats/blocks.js";
|
|
2
|
+
import { BLEN as $ } from "../formats/blocks.js";
|
|
3
|
+
import { MAXSEQ as y, METERS as S, MAXINV as x } from "../formats/character.js";
|
|
4
|
+
import { INF_REPEAT as ot } from "../formats/character.js";
|
|
5
|
+
import { LASTMON as rt } from "../formats/monster.js";
|
|
6
|
+
import { LASTMM as a, MLEN as M } from "../formats/map.js";
|
|
7
|
+
import { MWID as ct } from "../formats/map.js";
|
|
8
|
+
import { LASTSND as st } from "../formats/sound.js";
|
|
9
|
+
const X = 320, I = 200, d = 20, f = 11, L = 16, w = 10, A = 1, P = 1, Y = 1, h = 8, g = 5, e = -100, k = 40, E = 40, b = 6, D = 50, K = 100, V = 4294967295, N = Object.freeze({
|
|
10
|
+
maxSpeed: f,
|
|
11
|
+
gravityCap: f * 4,
|
|
12
|
+
gravityTicks: A,
|
|
13
|
+
attackX: h,
|
|
14
|
+
attackY: g,
|
|
15
|
+
scrollSpeedX: k,
|
|
16
|
+
scrollSpeedY: E,
|
|
17
|
+
scrollSteps: b,
|
|
18
|
+
fadeSteps: 65
|
|
19
|
+
});
|
|
20
|
+
function C() {
|
|
21
|
+
return {
|
|
22
|
+
score: 0,
|
|
23
|
+
update: !1,
|
|
24
|
+
topthere: !1,
|
|
25
|
+
bottomthere: !1,
|
|
26
|
+
curtop: i,
|
|
27
|
+
curbottom: i,
|
|
28
|
+
nextx: e,
|
|
29
|
+
nexty: e,
|
|
30
|
+
scrx: e,
|
|
31
|
+
scry: e,
|
|
32
|
+
oldx: e,
|
|
33
|
+
oldy: e,
|
|
34
|
+
netx: 5,
|
|
35
|
+
nety: 0,
|
|
36
|
+
gravx: 0,
|
|
37
|
+
gravy: 0,
|
|
38
|
+
hitpts: -1,
|
|
39
|
+
lives: -1,
|
|
40
|
+
nextAni: 0,
|
|
41
|
+
inv: new Array(x).fill(c + 1),
|
|
42
|
+
meter: new Array(S).fill(-1),
|
|
43
|
+
seqon: new Array(y).fill(!1)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function O() {
|
|
47
|
+
return {
|
|
48
|
+
fromchar: 0,
|
|
49
|
+
delta: { x: 0, y: 0 },
|
|
50
|
+
curx: [0, 0],
|
|
51
|
+
cury: [0, 0],
|
|
52
|
+
target: { x: 0, y: 0 },
|
|
53
|
+
offl: -1,
|
|
54
|
+
offs: 0,
|
|
55
|
+
curMarch: 0,
|
|
56
|
+
curPic: -1,
|
|
57
|
+
orient: 0,
|
|
58
|
+
picDrawn: !1,
|
|
59
|
+
scrPos: { x: e, y: e },
|
|
60
|
+
oldPos: { x: e, y: e },
|
|
61
|
+
dest: 0,
|
|
62
|
+
nextAni: 0,
|
|
63
|
+
nextMove: 0,
|
|
64
|
+
birthTime: 0
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function R() {
|
|
68
|
+
return {
|
|
69
|
+
nx: 0,
|
|
70
|
+
ny: 0,
|
|
71
|
+
totalx: 0,
|
|
72
|
+
totaly: 0,
|
|
73
|
+
distx: 0,
|
|
74
|
+
disty: 0,
|
|
75
|
+
inMotion: 0,
|
|
76
|
+
maxX: 0,
|
|
77
|
+
maxY: 0,
|
|
78
|
+
minX: 0,
|
|
79
|
+
minY: 0,
|
|
80
|
+
leftStop: 0,
|
|
81
|
+
rightStop: 0,
|
|
82
|
+
upStop: 0,
|
|
83
|
+
downStop: 0,
|
|
84
|
+
movx: 0,
|
|
85
|
+
movy: 0,
|
|
86
|
+
littleShiftx: 0,
|
|
87
|
+
littleShifty: 0,
|
|
88
|
+
up: 0,
|
|
89
|
+
down: 0,
|
|
90
|
+
left: 0,
|
|
91
|
+
right: 0,
|
|
92
|
+
bx: { dscroll: 0, ctr: 0, iters: 0 },
|
|
93
|
+
by: { dscroll: 0, ctr: 0, iters: 0 }
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function s(t, o) {
|
|
97
|
+
const n = (t ?? []).slice(0, o);
|
|
98
|
+
for (; n.length < o + 1; ) n.push(u(n.length, !0));
|
|
99
|
+
return n;
|
|
100
|
+
}
|
|
101
|
+
function m(t, o) {
|
|
102
|
+
return o * M + t;
|
|
103
|
+
}
|
|
104
|
+
function U(t, o, n) {
|
|
105
|
+
return t.map[m(o, n)] ?? 0;
|
|
106
|
+
}
|
|
107
|
+
function W(t, o, n) {
|
|
108
|
+
const r = m(o, n);
|
|
109
|
+
return r >= 0 && r < t.mapMon.length ? t.mapMon[r] : a;
|
|
110
|
+
}
|
|
111
|
+
function j(t, o, n, r) {
|
|
112
|
+
const l = m(o, n);
|
|
113
|
+
l >= 0 && l < t.mapMon.length && (t.mapMon[l] = r);
|
|
114
|
+
}
|
|
115
|
+
function F(t, o) {
|
|
116
|
+
return t.bg[t.blkmap[o] ?? o] ?? t.bg[c];
|
|
117
|
+
}
|
|
118
|
+
function G(t, o) {
|
|
119
|
+
return t.bg[o] ?? t.bg[c];
|
|
120
|
+
}
|
|
121
|
+
function H(t, o, n = Math.random) {
|
|
122
|
+
return {
|
|
123
|
+
// 256 VGA colors x 3 (r, g, b), each 0..63.
|
|
124
|
+
palette: new Uint8Array(768),
|
|
125
|
+
map: t.blocks.slice(),
|
|
126
|
+
mapMon: t.mons.slice(),
|
|
127
|
+
bg: s(void 0, c),
|
|
128
|
+
mblk: s(void 0, p),
|
|
129
|
+
cblk: s(void 0, i),
|
|
130
|
+
mon: [],
|
|
131
|
+
chr: void 0,
|
|
132
|
+
noMons: !1,
|
|
133
|
+
ci: C(),
|
|
134
|
+
mi: Array.from({ length: a }, O),
|
|
135
|
+
mm: t.monsters.map((r) => ({ monnum: r.monnum, curx: r.curx, cury: r.cury })),
|
|
136
|
+
firstEmptyMM: 0,
|
|
137
|
+
monsolid: 0,
|
|
138
|
+
mmSolid: a,
|
|
139
|
+
blkMon: [],
|
|
140
|
+
birthFlag: new Uint8Array(c + 1),
|
|
141
|
+
nxtchg: new Array(c).fill(0),
|
|
142
|
+
blkmap: Uint8Array.from({ length: c }, (r, l) => l),
|
|
143
|
+
mx: 0,
|
|
144
|
+
my: 0,
|
|
145
|
+
scroll: R(),
|
|
146
|
+
clock: 1,
|
|
147
|
+
keydn: new Uint8Array(128),
|
|
148
|
+
keystack: Array.from({ length: d + 1 }, () => ({ key: 255, seq: 0, frame: 0 })),
|
|
149
|
+
keystkptr: 0,
|
|
150
|
+
curkey: 0,
|
|
151
|
+
gclk: 1,
|
|
152
|
+
joyOldTime: 1,
|
|
153
|
+
joyOldBut: 0,
|
|
154
|
+
sound: o,
|
|
155
|
+
rand: n,
|
|
156
|
+
jstickOn: !0,
|
|
157
|
+
tune: N
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const _ = (t, o) => Math.floor(t.rand() * o), q = (t) => t > 0 ? 1 : t < 0 ? -1 : 0, Z = (t) => t << 16 >> 16, z = (t) => t & 65535;
|
|
161
|
+
export {
|
|
162
|
+
h as ATTACKX,
|
|
163
|
+
g as ATTACKY,
|
|
164
|
+
c as BACKBL,
|
|
165
|
+
$ as BLEN,
|
|
166
|
+
i as CHARBL,
|
|
167
|
+
K as CHARPOWER,
|
|
168
|
+
A as GRAVSPEED,
|
|
169
|
+
ot as INF_REPEAT,
|
|
170
|
+
Y as JSTICKKEY,
|
|
171
|
+
a as LASTMM,
|
|
172
|
+
rt as LASTMON,
|
|
173
|
+
st as LASTSND,
|
|
174
|
+
f as MAXGRAV,
|
|
175
|
+
x as MAXINV,
|
|
176
|
+
d as MAXKEYS,
|
|
177
|
+
D as MAXMONSSHOWN,
|
|
178
|
+
y as MAXSEQ,
|
|
179
|
+
M as MLEN,
|
|
180
|
+
p as MONBL,
|
|
181
|
+
P as MONMOVESPEED,
|
|
182
|
+
ct as MWID,
|
|
183
|
+
V as NEVER,
|
|
184
|
+
e as OFFSCRN,
|
|
185
|
+
L as SCRNBLEN,
|
|
186
|
+
w as SCRNBWID,
|
|
187
|
+
b as SCROLLPERMOVE,
|
|
188
|
+
k as SCRSPDX,
|
|
189
|
+
E as SCRSPDY,
|
|
190
|
+
X as SIZEX,
|
|
191
|
+
I as SIZEY,
|
|
192
|
+
N as STOCK_TUNING,
|
|
193
|
+
G as bgBlock,
|
|
194
|
+
H as createWorld,
|
|
195
|
+
Z as i16,
|
|
196
|
+
U as mapBlock,
|
|
197
|
+
W as mapMonAt,
|
|
198
|
+
C as newCharInfo,
|
|
199
|
+
s as padBlocks,
|
|
200
|
+
_ as random,
|
|
201
|
+
j as setMapMon,
|
|
202
|
+
F as shownBlock,
|
|
203
|
+
q as sign,
|
|
204
|
+
z as u16
|
|
205
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const n = new TextDecoder("latin1");
|
|
2
|
+
class h {
|
|
3
|
+
bytes;
|
|
4
|
+
offset;
|
|
5
|
+
constructor(t, s = 0) {
|
|
6
|
+
this.bytes = t, this.offset = s;
|
|
7
|
+
}
|
|
8
|
+
get length() {
|
|
9
|
+
return this.bytes.length;
|
|
10
|
+
}
|
|
11
|
+
get eof() {
|
|
12
|
+
return this.offset >= this.bytes.length;
|
|
13
|
+
}
|
|
14
|
+
skip(t) {
|
|
15
|
+
return this.offset += t, this;
|
|
16
|
+
}
|
|
17
|
+
u8() {
|
|
18
|
+
const t = this.offset < this.bytes.length ? this.bytes[this.offset] : 0;
|
|
19
|
+
return this.offset++, t;
|
|
20
|
+
}
|
|
21
|
+
i8() {
|
|
22
|
+
const t = this.u8();
|
|
23
|
+
return t > 127 ? t - 256 : t;
|
|
24
|
+
}
|
|
25
|
+
u16() {
|
|
26
|
+
return this.u8() | this.u8() << 8;
|
|
27
|
+
}
|
|
28
|
+
i16() {
|
|
29
|
+
const t = this.u16();
|
|
30
|
+
return t > 32767 ? t - 65536 : t;
|
|
31
|
+
}
|
|
32
|
+
u32() {
|
|
33
|
+
return (this.u16() | this.u16() << 16) >>> 0;
|
|
34
|
+
}
|
|
35
|
+
i32() {
|
|
36
|
+
return this.u16() | this.u16() << 16;
|
|
37
|
+
}
|
|
38
|
+
/** Copies n bytes (zero padded when the source is short). */
|
|
39
|
+
bytesOf(t) {
|
|
40
|
+
const s = new Uint8Array(t), e = Math.max(0, Math.min(t, this.bytes.length - this.offset));
|
|
41
|
+
return e > 0 && s.set(this.bytes.subarray(this.offset, this.offset + e)), this.offset += t, s;
|
|
42
|
+
}
|
|
43
|
+
/** Reads a fixed size, NUL terminated string field. */
|
|
44
|
+
cstr(t) {
|
|
45
|
+
return u(this.bytesOf(t));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class f {
|
|
49
|
+
buf;
|
|
50
|
+
offset = 0;
|
|
51
|
+
constructor(t = 1024) {
|
|
52
|
+
this.buf = new Uint8Array(t);
|
|
53
|
+
}
|
|
54
|
+
ensure(t) {
|
|
55
|
+
if (this.offset + t <= this.buf.length) return;
|
|
56
|
+
let s = this.buf.length * 2;
|
|
57
|
+
for (; s < this.offset + t; ) s *= 2;
|
|
58
|
+
const e = new Uint8Array(s);
|
|
59
|
+
e.set(this.buf), this.buf = e;
|
|
60
|
+
}
|
|
61
|
+
u8(t) {
|
|
62
|
+
return this.ensure(1), this.buf[this.offset++] = t & 255, this;
|
|
63
|
+
}
|
|
64
|
+
// Signed writes store the same two's complement bytes as the unsigned ones.
|
|
65
|
+
i8(t) {
|
|
66
|
+
return this.u8(t);
|
|
67
|
+
}
|
|
68
|
+
u16(t) {
|
|
69
|
+
return this.u8(t).u8(t >> 8);
|
|
70
|
+
}
|
|
71
|
+
i16(t) {
|
|
72
|
+
return this.u16(t);
|
|
73
|
+
}
|
|
74
|
+
u32(t) {
|
|
75
|
+
return this.u16(t & 65535).u16(t >>> 16 & 65535);
|
|
76
|
+
}
|
|
77
|
+
i32(t) {
|
|
78
|
+
return this.u32(t >>> 0);
|
|
79
|
+
}
|
|
80
|
+
bytes(t, s = t.length) {
|
|
81
|
+
this.ensure(s);
|
|
82
|
+
for (let e = 0; e < s; e++) this.buf[this.offset++] = e < t.length ? t[e] & 255 : 0;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/** Writes a string into a fixed size NUL padded field (truncated to leave room for the NUL). */
|
|
86
|
+
cstr(t, s) {
|
|
87
|
+
const e = new Uint8Array(s);
|
|
88
|
+
for (let i = 0; i < Math.min(t.length, s - 1); i++) e[i] = t.charCodeAt(i) & 255;
|
|
89
|
+
return this.bytes(e);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Writes a fixed size string field. When the text is unchanged the original raw
|
|
93
|
+
* bytes (including any garbage after the NUL) are kept so files round-trip exactly.
|
|
94
|
+
*/
|
|
95
|
+
cstrOver(t, s, e) {
|
|
96
|
+
return s && s.length === e && u(s) === t ? this.bytes(s) : this.cstr(t, e);
|
|
97
|
+
}
|
|
98
|
+
toBytes() {
|
|
99
|
+
return this.buf.slice(0, this.offset);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function u(r) {
|
|
103
|
+
const t = r.indexOf(0);
|
|
104
|
+
return n.decode(t < 0 ? r : r.subarray(0, t));
|
|
105
|
+
}
|
|
106
|
+
function o(r) {
|
|
107
|
+
return n.decode(r);
|
|
108
|
+
}
|
|
109
|
+
function c(r) {
|
|
110
|
+
const t = new Uint8Array(r.length);
|
|
111
|
+
for (let s = 0; s < r.length; s++) t[s] = r.charCodeAt(s) & 255;
|
|
112
|
+
return t;
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
h as Reader,
|
|
116
|
+
f as Writer,
|
|
117
|
+
u as cString,
|
|
118
|
+
o as latin1Text,
|
|
119
|
+
c as textBytes
|
|
120
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Writer as r, Reader as u } from "./binary.js";
|
|
2
|
+
const c = 20, s = c * c, l = 420, a = 150, f = 100, B = 50, h = 255, S = 1, w = 2, T = 4, A = 8, m = { bbl: a, mbl: f, cbl: B };
|
|
3
|
+
function L(e, t = !1) {
|
|
4
|
+
return {
|
|
5
|
+
pixels: new Uint8Array(s).fill(t ? h : 0),
|
|
6
|
+
birthMon: 0,
|
|
7
|
+
birthTime: 0,
|
|
8
|
+
xtra: new Uint8Array(2),
|
|
9
|
+
solid: 0,
|
|
10
|
+
hitpt: 0,
|
|
11
|
+
scorePts: 0,
|
|
12
|
+
chHitPt: 0,
|
|
13
|
+
nextBl: e,
|
|
14
|
+
ntime: 0,
|
|
15
|
+
touchBl: e,
|
|
16
|
+
grav: 0,
|
|
17
|
+
obj: 0,
|
|
18
|
+
effect: 0,
|
|
19
|
+
eamt: 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function O(e) {
|
|
23
|
+
return {
|
|
24
|
+
pixels: e.bytesOf(s),
|
|
25
|
+
birthMon: e.u8(),
|
|
26
|
+
birthTime: e.i16(),
|
|
27
|
+
xtra: e.bytesOf(2),
|
|
28
|
+
solid: e.u8(),
|
|
29
|
+
hitpt: e.u8(),
|
|
30
|
+
scorePts: e.i16(),
|
|
31
|
+
chHitPt: e.i16(),
|
|
32
|
+
nextBl: e.u8(),
|
|
33
|
+
ntime: e.i16(),
|
|
34
|
+
touchBl: e.u8(),
|
|
35
|
+
grav: e.i8(),
|
|
36
|
+
obj: e.u8(),
|
|
37
|
+
effect: e.u8(),
|
|
38
|
+
eamt: e.i16()
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function p(e, t) {
|
|
42
|
+
e.bytes(t.pixels, s).u8(t.birthMon).i16(t.birthTime).bytes(t.xtra, 2).u8(t.solid).u8(t.hitpt).i16(t.scorePts).i16(t.chHitPt).u8(t.nextBl).i16(t.ntime).u8(t.touchBl).i8(t.grav).u8(t.obj).u8(t.effect).i16(t.eamt);
|
|
43
|
+
}
|
|
44
|
+
function b(e, t) {
|
|
45
|
+
const n = new u(e), o = [];
|
|
46
|
+
for (let i = 0; i < t; i++) o.push(O(n));
|
|
47
|
+
return o;
|
|
48
|
+
}
|
|
49
|
+
function C(e) {
|
|
50
|
+
const t = new r(e.length * l);
|
|
51
|
+
for (const n of e) p(t, n);
|
|
52
|
+
return t.toBytes();
|
|
53
|
+
}
|
|
54
|
+
function d(e) {
|
|
55
|
+
const t = e !== "bbl";
|
|
56
|
+
return Array.from({ length: m[e] }, (n, o) => L(o, t));
|
|
57
|
+
}
|
|
58
|
+
function g(e, t, n) {
|
|
59
|
+
const o = c - 1, i = e & 255;
|
|
60
|
+
switch (i > 7 ? 7 : i) {
|
|
61
|
+
case 1:
|
|
62
|
+
return (o - t) * c + n;
|
|
63
|
+
// p[L-j][k]
|
|
64
|
+
case 2:
|
|
65
|
+
return (o - n) * c + (o - t);
|
|
66
|
+
// p[L-k][L-j]
|
|
67
|
+
case 3:
|
|
68
|
+
return t * c + (o - n);
|
|
69
|
+
// p[j][L-k]
|
|
70
|
+
case 4:
|
|
71
|
+
return n * c + (o - t);
|
|
72
|
+
// p[k][L-j]
|
|
73
|
+
case 5:
|
|
74
|
+
return t * c + n;
|
|
75
|
+
// p[j][k]
|
|
76
|
+
case 6:
|
|
77
|
+
return (o - n) * c + t;
|
|
78
|
+
// p[L-k][j]
|
|
79
|
+
case 7:
|
|
80
|
+
return (o - t) * c + (o - n);
|
|
81
|
+
// p[L-j][L-k]
|
|
82
|
+
default:
|
|
83
|
+
return n * c + t;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
a as BACKBL,
|
|
88
|
+
c as BLEN,
|
|
89
|
+
m as BLOCK_COUNTS,
|
|
90
|
+
l as BLOCK_SIZE,
|
|
91
|
+
B as CHARBL,
|
|
92
|
+
f as MONBL,
|
|
93
|
+
T as SOLBOT,
|
|
94
|
+
A as SOLLEF,
|
|
95
|
+
w as SOLRIG,
|
|
96
|
+
S as SOLTOP,
|
|
97
|
+
h as TRANSPARENT,
|
|
98
|
+
L as emptyBlock,
|
|
99
|
+
d as newBlockSet,
|
|
100
|
+
g as orientIndex,
|
|
101
|
+
b as parseBlocks,
|
|
102
|
+
C as serializeBlocks
|
|
103
|
+
};
|