@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.
Files changed (129) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +24 -0
  3. package/NOTICE.md +58 -0
  4. package/README.md +149 -2
  5. package/dist/assets/music.worklet-aD2x7RRM.js +466 -0
  6. package/dist/audio/cmfLoad.js +10 -0
  7. package/dist/audio/cmfPlayer.js +201 -0
  8. package/dist/audio/context.js +75 -0
  9. package/dist/audio/engine.js +173 -0
  10. package/dist/audio/mix.js +40 -0
  11. package/dist/audio/opl.js +245 -0
  12. package/dist/audio/output.js +40 -0
  13. package/dist/core/gameFiles.js +89 -0
  14. package/dist/engine/character.js +187 -0
  15. package/dist/engine/funcKeys.js +164 -0
  16. package/dist/engine/game.js +133 -0
  17. package/dist/engine/keys.js +68 -0
  18. package/dist/engine/machine.js +192 -0
  19. package/dist/engine/menus.js +135 -0
  20. package/dist/engine/monsters.js +259 -0
  21. package/dist/engine/playGain.js +10 -0
  22. package/dist/engine/playerLook.js +48 -0
  23. package/dist/engine/recorder.js +127 -0
  24. package/dist/engine/render.js +45 -0
  25. package/dist/engine/scene.js +324 -0
  26. package/dist/engine/scroll.js +79 -0
  27. package/dist/engine/showGraphic.js +107 -0
  28. package/dist/engine/slowPc.js +98 -0
  29. package/dist/engine/slowPcMusic.js +46 -0
  30. package/dist/engine/touch.js +61 -0
  31. package/dist/engine/world.js +205 -0
  32. package/dist/formats/binary.js +120 -0
  33. package/dist/formats/blocks.js +103 -0
  34. package/dist/formats/character.js +83 -0
  35. package/dist/formats/cmf.js +37 -0
  36. package/dist/formats/cmfEdit.js +154 -0
  37. package/dist/formats/cmfPreview.js +89 -0
  38. package/dist/formats/cmfSong.js +190 -0
  39. package/dist/formats/fli.js +340 -0
  40. package/dist/formats/fliFrames.js +34 -0
  41. package/dist/formats/fliLimits.js +54 -0
  42. package/dist/formats/game.js +198 -0
  43. package/dist/formats/gif.js +125 -0
  44. package/dist/formats/gifProgressive.js +99 -0
  45. package/dist/formats/graphicScripts.js +44 -0
  46. package/dist/formats/highscore.js +30 -0
  47. package/dist/formats/jpeg.js +359 -0
  48. package/dist/formats/map.js +38 -0
  49. package/dist/formats/monster.js +69 -0
  50. package/dist/formats/palette.js +58 -0
  51. package/dist/formats/recording.js +17 -0
  52. package/dist/formats/sound.js +44 -0
  53. package/dist/formats/voc.js +303 -0
  54. package/dist/gfx/colorVision.js +45 -0
  55. package/dist/gfx/cp437Glyphs.js +337 -0
  56. package/dist/gfx/font8x8.js +10 -0
  57. package/dist/gfx/screen.js +151 -0
  58. package/dist/index.js +15 -0
  59. package/dist/input/chords.js +46 -0
  60. package/dist/input/deskMouse.js +24 -0
  61. package/dist/input/keyboard.js +82 -0
  62. package/dist/input/scancodes.js +143 -0
  63. package/dist/player/fileExtensions.js +118 -0
  64. package/dist/player/patchRules.js +129 -0
  65. package/dist/player/patchTable.js +1753 -0
  66. package/dist/text/cp437.js +44 -0
  67. package/dist/types/audio/cmfLoad.d.ts +7 -0
  68. package/dist/types/audio/cmfPlayer.d.ts +69 -0
  69. package/dist/types/audio/context.d.ts +12 -0
  70. package/dist/types/audio/engine.d.ts +60 -0
  71. package/dist/types/audio/mix.d.ts +14 -0
  72. package/dist/types/audio/music.worklet.d.ts +22 -0
  73. package/dist/types/audio/opl.d.ts +37 -0
  74. package/dist/types/audio/output.d.ts +13 -0
  75. package/dist/types/core/gameFiles.d.ts +49 -0
  76. package/dist/types/engine/character.d.ts +30 -0
  77. package/dist/types/engine/funcKeys.d.ts +35 -0
  78. package/dist/types/engine/game.d.ts +57 -0
  79. package/dist/types/engine/keys.d.ts +17 -0
  80. package/dist/types/engine/machine.d.ts +103 -0
  81. package/dist/types/engine/menus.d.ts +46 -0
  82. package/dist/types/engine/monsters.d.ts +19 -0
  83. package/dist/types/engine/playGain.d.ts +11 -0
  84. package/dist/types/engine/playerLook.d.ts +44 -0
  85. package/dist/types/engine/recorder.d.ts +67 -0
  86. package/dist/types/engine/render.d.ts +8 -0
  87. package/dist/types/engine/scene.d.ts +188 -0
  88. package/dist/types/engine/scroll.d.ts +24 -0
  89. package/dist/types/engine/showGraphic.d.ts +39 -0
  90. package/dist/types/engine/slowPc.d.ts +124 -0
  91. package/dist/types/engine/slowPcMusic.d.ts +18 -0
  92. package/dist/types/engine/touch.d.ts +33 -0
  93. package/dist/types/engine/world.d.ts +237 -0
  94. package/dist/types/formats/binary.d.ts +44 -0
  95. package/dist/types/formats/blocks.d.ts +52 -0
  96. package/dist/types/formats/character.d.ts +65 -0
  97. package/dist/types/formats/cmf.d.ts +33 -0
  98. package/dist/types/formats/cmfEdit.d.ts +53 -0
  99. package/dist/types/formats/cmfPreview.d.ts +19 -0
  100. package/dist/types/formats/cmfSong.d.ts +74 -0
  101. package/dist/types/formats/fli.d.ts +56 -0
  102. package/dist/types/formats/fliFrames.d.ts +18 -0
  103. package/dist/types/formats/fliLimits.d.ts +13 -0
  104. package/dist/types/formats/game.d.ts +79 -0
  105. package/dist/types/formats/gif.d.ts +15 -0
  106. package/dist/types/formats/gifProgressive.d.ts +46 -0
  107. package/dist/types/formats/graphicScripts.d.ts +18 -0
  108. package/dist/types/formats/highscore.d.ts +10 -0
  109. package/dist/types/formats/jpeg.d.ts +20 -0
  110. package/dist/types/formats/map.d.ts +24 -0
  111. package/dist/types/formats/monster.d.ts +48 -0
  112. package/dist/types/formats/palette.d.ts +15 -0
  113. package/dist/types/formats/recording.d.ts +7 -0
  114. package/dist/types/formats/sound.d.ts +13 -0
  115. package/dist/types/formats/voc.d.ts +13 -0
  116. package/dist/types/gfx/colorVision.d.ts +26 -0
  117. package/dist/types/gfx/cp437Glyphs.d.ts +2 -0
  118. package/dist/types/gfx/font8x8.d.ts +2 -0
  119. package/dist/types/gfx/screen.d.ts +50 -0
  120. package/dist/types/index.d.ts +4 -0
  121. package/dist/types/input/chords.d.ts +22 -0
  122. package/dist/types/input/deskMouse.d.ts +14 -0
  123. package/dist/types/input/keyboard.d.ts +39 -0
  124. package/dist/types/input/scancodes.d.ts +3 -0
  125. package/dist/types/player/fileExtensions.d.ts +44 -0
  126. package/dist/types/player/patchRules.d.ts +24 -0
  127. package/dist/types/player/patchTable.d.ts +83 -0
  128. package/dist/types/text/cp437.d.ts +6 -0
  129. package/package.json +339 -4
@@ -0,0 +1,192 @@
1
+ import { Screen as d } from "../gfx/screen.js";
2
+ import { Keyboard as m } from "../input/keyboard.js";
3
+ import { listenDeskMouse as u, Mickeys as p } from "../input/deskMouse.js";
4
+ import { AudioEngine as y } from "../audio/engine.js";
5
+ import { PALETTE_SIZE as c } from "../formats/palette.js";
6
+ const w = 6;
7
+ class k extends Error {
8
+ constructor() {
9
+ super("Game aborted");
10
+ }
11
+ }
12
+ class E {
13
+ screen;
14
+ keyboard = new m();
15
+ audio;
16
+ files;
17
+ pointer = { x: 160, y: 100, clicks: 0 };
18
+ aborted = !1;
19
+ /** Observer only (the walkthrough player's item marks): a picture, cartoon, text page or slide list is about to be shown. Never changes timing. */
20
+ onItem;
21
+ frameWaiters = [];
22
+ raf = 0;
23
+ /** The ball mouse on the desk moves the pointer and clicks too. */
24
+ offDeskMouse;
25
+ /** The engine was made here (not passed in): it goes with the Machine. */
26
+ ownsAudio;
27
+ constructor(t, e, i, s = {}) {
28
+ if (this.screen = new d(t), this.files = e, this.ownsAudio = !i, this.audio = i ?? new y(), s.input === !1 ? (this.offDeskMouse = () => {
29
+ }, this.keyboard.attach = this.keyboard.detach = () => {
30
+ }) : this.listen(t), s.frames === "manual") return;
31
+ const o = () => {
32
+ this.presentFrame(), this.raf = requestAnimationFrame(o);
33
+ };
34
+ this.raf = requestAnimationFrame(o);
35
+ }
36
+ listen(t) {
37
+ t.addEventListener("pointerdown", this.onPointer), t.addEventListener("pointermove", this.onMove);
38
+ const e = new p();
39
+ let i = 0;
40
+ this.offDeskMouse = u((s, o, r) => {
41
+ const [h, a] = e.take(s, o);
42
+ this.pointer.x = Math.max(0, Math.min(319, this.pointer.x + h)), this.pointer.y = Math.max(0, Math.min(199, this.pointer.y + a)), r & ~i && (this.pointer.clicks++, this.audio.resume()), i = r;
43
+ });
44
+ }
45
+ /** The time in ms the game goes by (waits, fades, animations, the game clock). */
46
+ now() {
47
+ return performance.now();
48
+ }
49
+ /** One display frame: the screen is shown (unless `show` is false) and everything waiting for a frame goes on. */
50
+ presentFrame(t = !0) {
51
+ t && this.screen.present();
52
+ const e = this.frameWaiters;
53
+ this.frameWaiters = [], e.forEach((i) => i());
54
+ }
55
+ /** How many are waiting for the next frame (a stepped Machine's game is idle when one is). */
56
+ get frameWaiting() {
57
+ return this.frameWaiters.length;
58
+ }
59
+ toScreen(t) {
60
+ const e = this.screen.canvas.getBoundingClientRect();
61
+ this.pointer.x = Math.floor((t.clientX - e.left) / e.width * 320), this.pointer.y = Math.floor((t.clientY - e.top) / e.height * 200);
62
+ }
63
+ onPointer = (t) => {
64
+ this.toScreen(t), this.pointer.clicks++, this.audio.resume();
65
+ };
66
+ onMove = (t) => this.toScreen(t);
67
+ destroy() {
68
+ this.aborted = !0, this.raf && cancelAnimationFrame(this.raf), this.keyboard.detach(), this.ownsAudio ? this.audio.dispose() : this.audio.stopAll(), this.screen.canvas.removeEventListener("pointerdown", this.onPointer), this.screen.canvas.removeEventListener("pointermove", this.onMove), this.offDeskMouse();
69
+ const t = this.frameWaiters;
70
+ this.frameWaiters = [], t.forEach((e) => e());
71
+ }
72
+ /** Told when the game waits for files still on their way (true) and when they are in. */
73
+ onLoading;
74
+ /**
75
+ * Waits for game files still on their way from the site (a hosted game starts before
76
+ * all its files are in, project/streamGame.ts); a short wait shows no cue. Names the
77
+ * game doesn't have, or that are in already, return at once.
78
+ */
79
+ async need(...t) {
80
+ const e = this.files.stream?.need(t.filter((s) => !!s));
81
+ if (!e) return;
82
+ const i = setTimeout(() => this.onLoading?.(!0), 150);
83
+ try {
84
+ await e;
85
+ } finally {
86
+ clearTimeout(i), this.onLoading?.(!1);
87
+ }
88
+ this.polledAt = this.now(), this.checkAbort();
89
+ }
90
+ /** Fetches these game files next, if they are still on their way, without waiting. */
91
+ want(...t) {
92
+ this.files.stream?.want(t.filter((e) => !!e));
93
+ }
94
+ checkAbort() {
95
+ if (this.aborted) throw new k();
96
+ }
97
+ /** Waits for the next animation frame (the screen is presented every frame). */
98
+ frame() {
99
+ return this.checkAbort(), this.pollKeys(), new Promise((t) => this.frameWaiters.push(t)).then(() => this.checkAbort());
100
+ }
101
+ async sleep(t) {
102
+ const e = this.now() + t;
103
+ for (; this.now() < e; ) await this.frame();
104
+ }
105
+ takeClick() {
106
+ return this.pointer.clicks ? (this.pointer.clicks = 0, !0) : !1;
107
+ }
108
+ /**
109
+ * PauseTimeKey: waits up to `seconds` (forever if omitted) for a key or click.
110
+ * Returns the key, a pseudo key for a click (ascii 1, as the C returned 1 for a mouse
111
+ * button; scan 28 is Enter's), or undefined on time out (the C returned FALSE).
112
+ */
113
+ async pauseTimeKey(t = 1 / 0) {
114
+ const e = this.now() + t * 1e3;
115
+ return this.takeClick(), this.waiting(async () => {
116
+ for (; ; ) {
117
+ const i = this.keyboard.readKey();
118
+ if (i) return i;
119
+ if (this.takeClick()) return { scan: 28, ascii: 1, key: "" };
120
+ if (this.now() >= e) return;
121
+ await this.frame();
122
+ }
123
+ });
124
+ }
125
+ waitDepth = 0;
126
+ polledAt = 0;
127
+ /**
128
+ * Runs `fn` as PLAYGAME code that read keys through GetKey (key waits, pictures,
129
+ * animations, text pages): while it runs, each frame hands the demo recorder the polls
130
+ * the DOS PC would have made meanwhile (keyPoll). Gameplay itself stole the keyboard
131
+ * interrupt and never called GetKey, so it does not count.
132
+ */
133
+ async waiting(t) {
134
+ this.waitDepth++ === 0 && (this.polledAt = this.now());
135
+ try {
136
+ return await t();
137
+ } finally {
138
+ if (--this.waitDepth === 0 && this.keyPollEnd) for (const e of this.keyPollEnd()) this.keyboard.feed(e);
139
+ }
140
+ }
141
+ pollKeys() {
142
+ if (!this.keyPoll || this.waitDepth === 0) return;
143
+ const t = this.now(), e = Math.max(1, Math.round((t - this.polledAt) * w));
144
+ this.polledAt = t;
145
+ for (const i of this.keyPoll(e)) this.keyboard.feed(i);
146
+ }
147
+ /**
148
+ * Demo playback: called while a screen waits for a key with how many GetKey polls the
149
+ * DOS PC would have made meanwhile; returns recorded keys that become pending.
150
+ */
151
+ keyPoll;
152
+ /** Demo playback: a key-reading screen ended; returns recorded keys it must have taken. */
153
+ keyPollEnd;
154
+ /** Demo playback: one GetKey poll by a screen (tick-counted recordings); returns the recorded keys now due. */
155
+ keyPollOnce;
156
+ /** Clears keyboard input (while (GetKey(1)) GetKey(0)). */
157
+ flushKeys() {
158
+ this.keyboard.clear(), this.pointer.clicks = 0;
159
+ }
160
+ /**
161
+ * FadeTo: 65 retrace-synchronized steps from the current palette to `dest`. The C
162
+ * waited for one VGA vertical retrace (70 Hz in mode 13h) per step, hence steps/70 s;
163
+ * it stepped each channel Bresenham-style, which the truncated d*step/steps matches
164
+ * at every step.
165
+ */
166
+ async fadeTo(t, e = 65) {
167
+ if (e <= 0) {
168
+ this.screen.setPalette(t);
169
+ return;
170
+ }
171
+ const i = this.screen.palette.slice(), s = this.now(), o = e / 70 * 1e3;
172
+ for (; ; ) {
173
+ const r = Math.min(1, (this.now() - s) / o), h = Math.floor(r * e), a = new Uint8Array(c);
174
+ for (let n = 0; n < c; n++) {
175
+ const f = (t[n] ?? 0) - i[n];
176
+ a[n] = i[n] + Math.trunc(f * h / e);
177
+ }
178
+ if (this.screen.setPalette(a), r >= 1) break;
179
+ await this.frame();
180
+ }
181
+ this.screen.setPalette(t);
182
+ }
183
+ async fadeAllTo(t, e, i, s = 65) {
184
+ const o = new Uint8Array(c);
185
+ for (let r = 0; r < 256; r++) o.set([t, e, i], r * 3);
186
+ await this.fadeTo(o, s);
187
+ }
188
+ }
189
+ export {
190
+ k as GameAborted,
191
+ E as Machine
192
+ };
@@ -0,0 +1,135 @@
1
+ import { STOCK_LOOK as m } from "./playerLook.js";
2
+ import { placeFor as p, insertHighScore as b, serializeHighScores as M, parseHighScores as K } from "../formats/highscore.js";
3
+ import { PALETTE_SIZE as F } from "../formats/palette.js";
4
+ async function P(t, e, n, i, a, c, u = 1 / 0, r = 1, o = !0, f = 5) {
5
+ const s = (l) => n - 8 + l * i;
6
+ let w = t.screen.getCol(e, s(r));
7
+ o ? t.flushKeys() : t.takeClick();
8
+ let g = t.now();
9
+ for (; ; ) {
10
+ t.screen.boxFill(e, s(r), e + f, s(r) + 4, c);
11
+ const l = t.keyboard.readKey();
12
+ let h = 0;
13
+ if (t.takeClick()) {
14
+ const d = Math.floor((t.pointer.y - (n - 8) + i / 2) / i);
15
+ if (d >= 1 && d <= a)
16
+ return t.screen.boxFill(e, s(r), e + f, s(r) + 4, w), d;
17
+ }
18
+ if (l) {
19
+ if (g = t.now(), l.ascii === 13) return r;
20
+ if (l.ascii === 27) return 0;
21
+ l.scan === 72 && (h = -1), l.scan === 80 && (h = 1);
22
+ } else if (t.now() - g > u * 1e3) return a + 1;
23
+ h && (t.screen.boxFill(e, s(r), e + f, s(r) + 4, w), r += h, r < 1 && (r = a), r > a && (r = 1), w = t.screen.getCol(e, s(r))), await t.frame();
24
+ }
25
+ }
26
+ async function C(t, e, n, i, a, c, u) {
27
+ let r = c.slice(0, u);
28
+ t.screen.write(e, n, i, r), t.flushKeys();
29
+ const o = (f) => {
30
+ const s = r.length;
31
+ s < u ? t.screen.box(e + s * 8, n, e + (s + 1) * 8 - 2, n + 7, f) : t.screen.line(e + s * 8 - 1, n, e + s * 8 - 1, n + 7, f);
32
+ };
33
+ for (; ; ) {
34
+ const f = Math.floor(t.now() / 450) % 2 === 0;
35
+ o(f ? i : a);
36
+ const s = t.keyboard.readKey();
37
+ if (!s) {
38
+ await t.frame();
39
+ continue;
40
+ }
41
+ if (o(a), s.ascii === 27) return null;
42
+ if (s.ascii === 13) return r;
43
+ s.ascii === 8 || s.scan === 75 ? r.length && (r = r.slice(0, -1), t.screen.boxFill(e + r.length * 8, n, e + (r.length + 1) * 8 - 1, n + 7, a)) : s.ascii >= 32 && s.ascii < 256 && r.length < u && (r += String.fromCharCode(s.ascii), t.screen.write(e, n, i, r));
44
+ }
45
+ }
46
+ function H(t = Math.random) {
47
+ const e = new Uint8Array(F), n = 2;
48
+ let [i, a, c] = [0, 0, 0], [u, r, o] = [0, 0, 0];
49
+ const f = () => Math.floor(t() * 2);
50
+ for (let s = 0; s < 256; s++) {
51
+ if (s % (64 / n) === 0)
52
+ do
53
+ o === 0 && (o = f()), r === 0 && (r = f()), u === 0 && (u = f());
54
+ while (o === 0 && r === 0 && u === 0);
55
+ u === 1 && (i += n), r === 1 && (a += n), o === 1 && (c += n), u === 2 && (i -= n), r === 2 && (a -= n), o === 2 && (c -= n), i >= 63 && ([u, i] = [2, 63]), c >= 63 && ([o, c] = [2, 63]), a >= 63 && ([r, a] = [2, 63]), i < 0 && ([i, u] = [0, 0]), a < 0 && ([a, r] = [0, 0]), c < 0 && ([c, o] = [0, 0]), e.set([i, a, c], s * 3);
56
+ }
57
+ return e;
58
+ }
59
+ function Y(t, e, n = Math.random) {
60
+ t.screen.clear(), e.set(H(n)), t.screen.setPalette(e);
61
+ for (let i = 0; i <= 100; i++) t.screen.box(40 - Math.trunc(i * 4 / 10), 100 - i, 280 + Math.trunc(i * 4 / 10), 180 + Math.trunc(i * 2 / 10), i);
62
+ }
63
+ function y(t) {
64
+ return `${t}.his`;
65
+ }
66
+ function S(t, e) {
67
+ const n = t.files.get(y(e));
68
+ return n ? K(n) : Array.from({ length: 10 }, () => ({ score: 0, name: "" }));
69
+ }
70
+ function A(t, e, n, i) {
71
+ const a = e.color(n, "color.select.menu");
72
+ t.write(e.num("layout.menu.titleX"), e.num("layout.menu.titleY"), a, i);
73
+ for (const c of N) t.write(e.num(`layout.menu.${c}.x`), e.num(`layout.menu.${c}.y`), a, e.text(`str.menu.${c}`));
74
+ return a;
75
+ }
76
+ const N = ["play", "instructions", "storyline", "credits", "highScores", "quit"];
77
+ function R(t) {
78
+ return {
79
+ x: t.num("layout.menu.markerX"),
80
+ y: t.num("layout.menu.firstY"),
81
+ dy: t.num("layout.menu.spacing"),
82
+ idle: t.seconds("timing.menu.idleSeconds"),
83
+ width: t.num("border.marker.width")
84
+ };
85
+ }
86
+ function _(t, e, n, i) {
87
+ t.write(
88
+ e.num("layout.menu.noFile.x"),
89
+ e.num("layout.menu.noFile.y"),
90
+ e.color(n, "color.select.menuMessages"),
91
+ e.text(`str.menu.${i}`)
92
+ );
93
+ }
94
+ function $(t, e, n, i, a) {
95
+ const c = e.color(n, "color.select.hsTitle"), u = e.color(n, "color.select.hsRows");
96
+ t.write(e.num("layout.hiscore.title.x"), e.num("layout.hiscore.title.y"), c, e.text("str.hiscore.title"));
97
+ let r = e.num("layout.hiscore.rowSpacing"), o = e.num("layout.hiscore.firstRowY");
98
+ const f = e.num("layout.hiscore.rows");
99
+ for (let s = 0; s < f; s++)
100
+ i[s].score !== 0 && t.write(20, o, u, `${String(i[s].score).padStart(10)} ${i[s].name}`), o += r, s % 2 === 0 && r--, r--;
101
+ a > 0 && t.write(20, o, u, e.format("str.hiscore.latest", a)), t.write(e.num("layout.hiscore.anyKey.x"), e.num("layout.hiscore.anyKey.y"), c, e.text("str.hiscore.anyKey"));
102
+ }
103
+ async function v(t, e, n, i = -1, a = m) {
104
+ await t.need(y(e));
105
+ const c = S(t, e);
106
+ t.screen.setPalette(n), $(t.screen, a, n, c, i), await t.pauseTimeKey(a.seconds("timing.highScores"));
107
+ }
108
+ function x(t, e, n, i) {
109
+ const a = e.color(n, "color.select.hsPrompt"), c = e.color(n, "color.select.hsName");
110
+ return t.write(e.num("layout.hiscore.congrats.x"), e.num("layout.hiscore.congrats.y"), a, e.text("str.hiscore.congrats")), t.write(0, 100, c, e.format("str.hiscore.place", i)), t.write(e.num("layout.hiscore.enterName.x"), e.num("layout.hiscore.enterName.y"), a, e.text("str.hiscore.enterName")), c;
111
+ }
112
+ async function D(t, e, n, i, a = m) {
113
+ await t.need(y(e));
114
+ const c = S(t, e), u = p(c, i);
115
+ let r = 0, o = c;
116
+ if (u >= 0) {
117
+ const f = x(t.screen, a, n, u + 1), s = await C(t, 136, 120, f, 0, "", 22) ?? "";
118
+ o = b(c, u, { score: i, name: s }), r = u + 1;
119
+ }
120
+ return t.files.set(y(e), M(o)), r;
121
+ }
122
+ export {
123
+ D as checkHighScores,
124
+ Y as drawDefaultScreen,
125
+ $ as drawHighScores,
126
+ A as drawMenu,
127
+ x as drawNewHighScore,
128
+ _ as drawNoFile,
129
+ C as gGet,
130
+ P as gVertMenu,
131
+ y as highScoreFile,
132
+ R as menuMarker,
133
+ S as readHighScores,
134
+ v as showHighScores
135
+ };
@@ -0,0 +1,259 @@
1
+ import { BACKBL as tr, BLEN as i, MONBL as k, TRANSPARENT as p, CHARBL as Y, SOLRIG as C, SOLLEF as R, SOLBOT as F, SOLTOP as D } from "../formats/blocks.js";
2
+ import { LASTMON as N, LASTSL as O, ATTACKMOVEMENT as A, MAXMARCH as X, NORMALMOVEMENT as S } from "../formats/monster.js";
3
+ import { chrFrame as cr } from "./keys.js";
4
+ import { onscrn as or, doBlockTouchChar as nr, doSound as H, KILLSOUND as V } from "./touch.js";
5
+ import { SCRNBLEN as _, SCRNBWID as j, mapBlock as v, MONMOVESPEED as q, random as E, mapMonAt as J, setMapMon as Q, OFFSCRN as T, CHARPOWER as er, sign as m, shownBlock as fr } from "./world.js";
6
+ import { LASTMM as b, MWID as h, MLEN as d } from "../formats/map.js";
7
+ const sr = { x: 0, y: 0, pic: 0, orient: 0 };
8
+ function P(r, o, n) {
9
+ return n >= 0 ? r.march[o]?.[n] ?? sr : o === 1 ? r.march[0][X - 1] : { x: r.end, y: r.towards, pic: r.close[0], orient: r.close[1] };
10
+ }
11
+ function w(r) {
12
+ r.delta = { x: 0, y: 0 }, r.scrPos = { x: T, y: T }, r.oldPos = { ...r.scrPos }, r.picDrawn = !1, r.curx[1] = 0, r.cury[1] = 0, r.curPic = -1, r.offl = -1, r.offs = 0, r.curMarch = S, r.orient = 0, r.dest = 0;
13
+ }
14
+ function W(r, o) {
15
+ const n = r.mi[o];
16
+ if (n.curPic >= 0 && n.curPic < O) {
17
+ const f = r.mon[r.mm[o].monnum]?.pic[n.curPic][0] ?? k;
18
+ return f < k && f >= 0 ? f : k;
19
+ }
20
+ return k;
21
+ }
22
+ function ir(r, o) {
23
+ const n = or(r, o.curx[0], o.cury[0], o.scrPos);
24
+ return n && (o.scrPos.x += o.curx[1], o.scrPos.y += o.cury[1]), n;
25
+ }
26
+ function I(r, o, n) {
27
+ let c = o - r.curx[0], f = n - r.cury[0];
28
+ c > d / 2 && (c -= d), c < -d / 2 && (c += d), f > h / 2 && (f -= h), f < -h / 2 && (f += h), r.delta = { x: c * i, y: f * i };
29
+ }
30
+ function B(r, o) {
31
+ const n = { x: 0, y: 0 }, c = Math.abs(r.delta.x), f = Math.abs(r.delta.y);
32
+ if (c >= f)
33
+ for (let e = 0; e < o; e++) {
34
+ if (r.offl >= c) {
35
+ r.offl = -1;
36
+ break;
37
+ }
38
+ r.offl++, n.x += m(r.delta.x), r.offs += f, r.offs >= c && (r.offs -= c, n.y += m(r.delta.y));
39
+ }
40
+ else
41
+ for (let e = 0; e < o; e++) {
42
+ if (r.offl >= f) {
43
+ r.offl = -1;
44
+ break;
45
+ }
46
+ r.offl++, r.offs += c, n.y += m(r.delta.y), r.offs >= f && (r.offs -= f, n.x += m(r.delta.x));
47
+ }
48
+ return n;
49
+ }
50
+ function z(r) {
51
+ r.y < 0 ? r.y += h : r.y >= h && (r.y -= h), r.x < 0 ? r.x += d : r.x >= d && (r.x -= d);
52
+ }
53
+ const L = (r, o, n) => fr(r, v(r, o, n)).solid;
54
+ function Z(r, o, n, c) {
55
+ let f, e;
56
+ o.curx[1] + n.x < 0 ? (c.x--, f = C, e = 1) : (c.x++, f = R, e = 3), z(c);
57
+ let t = L(r, c.x, c.y);
58
+ return o.cury[1] + n.y > i / 4 && (t |= L(r, c.x, (c.y + 1) % h)), o.cury[1] + n.y < -i / 4 && (t |= L(r, c.x, (c.y - 1 + h) % h)), t & f ? (n.x = -o.curx[1], c.x += e === 1 ? 1 : -1, !0) : !1;
59
+ }
60
+ function $(r, o, n, c) {
61
+ let f, e;
62
+ o.cury[1] + n.y < 0 ? (c.y--, f = F, e = 1) : (c.y++, f = D, e = 3), z(c);
63
+ let t = L(r, c.x, c.y);
64
+ return o.curx[1] + n.x > i / 4 && (t |= L(r, (c.x + 1) % d, c.y)), o.curx[1] + n.x < -i / 4 && (t |= L(r, (c.x - 1 + d) % d, c.y)), t & f ? (n.y = -o.cury[1], c.y += e === 1 ? 1 : -1, !0) : !1;
65
+ }
66
+ function ur(r, o, n) {
67
+ const c = { x: o.curx[0], y: o.cury[0] };
68
+ let f = !1;
69
+ return Math.abs(n.x) > Math.abs(n.y) ? (f = Z(r, o, n, c) || f, n.y && (f = $(r, o, n, c) || f)) : (n.y && (f = $(r, o, n, c) || f), n.x && (f = Z(r, o, n, c) || f)), f;
70
+ }
71
+ function lr(r, o) {
72
+ const n = r.mi[o];
73
+ return Math.abs(n.curx[0] - r.chr.x[0]) < r.tune.attackX && Math.abs(n.cury[0] - r.chr.y[0]) < r.tune.attackY;
74
+ }
75
+ function G(r, o, n, c, f) {
76
+ if (o >= b) {
77
+ let e = r.firstEmptyMM;
78
+ for (let t = 0; t <= b; t++) {
79
+ if (e >= 0 && e < b && r.mm[e].monnum === N) {
80
+ o = e;
81
+ break;
82
+ }
83
+ e++, e >= b && (e = 0);
84
+ }
85
+ r.firstEmptyMM = Math.max(0, e);
86
+ }
87
+ if (o < b && o >= 0) {
88
+ r.mm[o].monnum = n & 255;
89
+ const e = r.mi[o];
90
+ return e.birthTime = r.clock, e.nextAni = r.clock, e.nextMove = r.clock, e.curx[0] = c, e.cury[0] = f, e.target = { x: c, y: f }, o;
91
+ }
92
+ return b;
93
+ }
94
+ function g(r, o) {
95
+ const n = r.mon[r.mm[o].monnum];
96
+ if (!n || n.end === -2) return !1;
97
+ if (n.newmon === N || n.newmon < 0)
98
+ return r.mm[o].monnum = N, o < r.firstEmptyMM && (r.firstEmptyMM = Math.max(0, o - 1)), !0;
99
+ const c = r.mi[o];
100
+ return G(r, o, n.newmon, c.curx[0], c.cury[0]), c.offl = -1, c.curMarch = S, c.dest = 0, c.curPic = 0, c.fromchar > 0 && c.fromchar++, !1;
101
+ }
102
+ function gr(r) {
103
+ r.birthFlag.fill(0);
104
+ for (const o of r.blkMon)
105
+ o.nexttime <= r.clock && (o.nexttime += r.bg[o.blnum].birthTime, r.birthFlag[o.blnum] = 1);
106
+ for (let o = r.mx - _ / 2; o < r.mx + _ * 3 / 2; o++)
107
+ for (let n = r.my - j / 2; n < r.my + j * 3 / 2; n++) {
108
+ const c = (o + d) % d, f = (n + h) % h, e = r.blkmap[v(r, c, f)] ?? tr;
109
+ if (!r.birthFlag[e]) continue;
110
+ const t = G(r, b, r.bg[e].birthMon, c, f);
111
+ t < b && (r.mi[t].fromchar = 0, w(r.mi[t]));
112
+ }
113
+ }
114
+ function Pr(r, o, n, c) {
115
+ const f = G(r, b, c, o, n);
116
+ if (f >= b) return;
117
+ const e = r.mi[f];
118
+ w(e), e.fromchar = 1, e.curx[1] = r.chr.x[1], e.cury[1] = r.chr.y[1], e.offl = -1;
119
+ const t = r.mon[c & 255];
120
+ if (t && t.towards < 64) {
121
+ const { netx: u, nety: x } = r.ci;
122
+ e.delta = { x: u * i, y: x * i }, Math.abs(u) - Math.abs(x) > 0 ? e.orient = u < 0 ? 4 : 0 : e.orient = x < 0 ? 3 : 1;
123
+ }
124
+ }
125
+ function ar(r, o, n) {
126
+ const c = r.mi[o], f = r.mon[n];
127
+ if (c.dest === X || P(f, c.curMarch, c.dest).pic === 0) {
128
+ if (f.end === -1 && c.curMarch === S && g(r, o)) return !0;
129
+ c.dest = 0, c.curMarch = S;
130
+ }
131
+ const e = P(f, c.curMarch, c.dest), t = { x: e.x + c.curx[0], y: e.y + c.cury[0] };
132
+ if (c.dest !== 0) {
133
+ const u = P(f, c.curMarch, c.dest - 1);
134
+ t.x -= u.x, t.y -= u.y;
135
+ }
136
+ return c.orient = e.orient, z(t), c.target = t, I(c, t.x, t.y), c.offl = 0, c.offs = 0, c.dest++, !1;
137
+ }
138
+ function K(r, o, n, c, f, e) {
139
+ const t = Math.abs(c - r), u = Math.abs(f - o);
140
+ if (c -= t, r -= t, f -= u, o -= u, t > i || u > i) return !1;
141
+ const x = (l) => l >= 0 && l < n.length ? n[l] : p, M = (l) => l >= 0 && l < e.length ? e[l] : p;
142
+ let s, a;
143
+ if (c >= r && f >= o) {
144
+ s = i * u, a = 0;
145
+ for (let l = 0; l < o + i - f; l++) {
146
+ s += t;
147
+ for (let y = 0; y < r + i - c; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
148
+ a += t;
149
+ }
150
+ return !1;
151
+ }
152
+ if (c >= r && f <= o) {
153
+ s = 0, a = u * i;
154
+ for (let l = 0; l < f + i - o; l++) {
155
+ s += t;
156
+ for (let y = 0; y < r + i - c; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
157
+ a += t;
158
+ }
159
+ return !1;
160
+ }
161
+ if (c <= r && f >= o) {
162
+ a = 0, s = u * i;
163
+ for (let l = 0; l < o + i - f; l++) {
164
+ a += t;
165
+ for (let y = 0; y < c + i - r; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
166
+ s += t;
167
+ }
168
+ return !1;
169
+ }
170
+ a = i * u, s = 0;
171
+ for (let l = 0; l < f + i - o; l++) {
172
+ a += t;
173
+ for (let y = 0; y < c + i - r; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
174
+ s += t;
175
+ }
176
+ return !1;
177
+ }
178
+ function xr(r, o) {
179
+ const n = r.mi[o], { ci: c } = r;
180
+ if (n.scrPos.x === T) return !1;
181
+ const f = Math.min(n.scrPos.x, c.scrx), e = Math.min(n.scrPos.y, c.scry), t = { x: c.scrx - f, y: c.scry - e }, u = { x: n.scrPos.x - f, y: n.scrPos.y - e }, x = { x: Math.max(t.x, u.x), y: Math.max(t.y, u.y) };
182
+ let M = !1;
183
+ if (u.x <= t.x + i && u.x + i >= t.x && u.y <= t.y + i && u.y + i * 2 >= t.y) {
184
+ let s = W(r, o);
185
+ if (s >= k) return !1;
186
+ const a = cr(r), l = r.mblk[s].pixels;
187
+ a.pic2 < Y && (M = K(t.x, t.y, r.cblk[a.pic2].pixels, u.x, u.y, l)), a.pic1 < Y && (M = K(t.x, t.y, r.cblk[a.pic1].pixels, u.x, u.y + i, l) || M), M && (s = r.mblk[s].solid, s > 0 && (x.x >= x.y ? r.monsolid |= t.x === 0 ? C & s : R & s : r.monsolid |= t.y === 0 ? F & s : D & s, r.mmSolid = o)), r.monsolid & C && r.monsolid & R && (r.monsolid |= t.y === 0 ? F & s : D & s), r.monsolid & F && r.monsolid & D && (r.monsolid |= t.x === 0 ? C & s : R & s);
188
+ }
189
+ return M;
190
+ }
191
+ function yr(r, o, n, c) {
192
+ const f = r.mm[o].monnum, e = r.mm[n].monnum;
193
+ if (f >= N || e >= N) return n;
194
+ const t = r.mon[f], u = r.mon[e];
195
+ if (t.power === u.power) return n;
196
+ const x = c & 1 ? i : 0, M = c & 2 ? i : 0, s = W(r, o);
197
+ if (s >= k) return n;
198
+ const a = W(r, n);
199
+ if (a >= k) return o;
200
+ const l = r.mi[o], y = r.mi[n];
201
+ return K(l.curx[1] + x, l.cury[1] + M, r.mblk[s].pixels, y.curx[1], y.cury[1], r.mblk[a].pixels) ? t.power < u.power ? (g(r, o), y.fromchar > 0 ? (r.ci.score += t.upscore, H(r, V), g(r, n), b) : n) : (g(r, n), l.fromchar > 0 ? (r.ci.score += u.upscore, H(r, V), g(r, o), b) : o) : n;
202
+ }
203
+ function Ar(r) {
204
+ const { clock: o, chr: n } = r;
205
+ for (let c = 0; c < b; c++) {
206
+ const f = r.mm[c].monnum;
207
+ if (f >= N) continue;
208
+ const e = r.mon[f], t = r.mi[c];
209
+ if (!e || (o >= t.nextAni && (t.curPic++, (t.curPic >= O || e.pic[t.curPic][0] >= k) && (t.curPic = e.pic[0][0] < k ? 0 : O), t.nextAni = t.curPic < O ? o + e.pic[t.curPic][1] : o + 1e5), o < t.nextMove)) continue;
210
+ const u = Math.trunc((o - t.nextMove + 1) / q);
211
+ t.nextMove = o + q, e.activate !== 0 && t.curMarch !== A && lr(r, c) && (t.curMarch = A, t.dest = 1);
212
+ let x;
213
+ if (t.curMarch === A && e.activate === 2) {
214
+ const l = P(e, A, t.dest);
215
+ t.target = { x: (l.x + n.x[0] + d) % d, y: (l.y + n.y[0] + h) % h }, I(t, t.target.x, t.target.y), t.offl = 0, x = B(t, l.pic * u), t.offl === -1 && (t.dest++, t.offs = 0, t.dest === X || P(e, A, t.dest).pic === 0 ? (t.curMarch = S, t.dest = 0) : t.orient = P(e, A, t.dest).orient);
216
+ } else if (e.towards === 0) {
217
+ if (t.offl === -1 && ar(r, c, f)) continue;
218
+ x = B(t, P(e, t.curMarch, t.dest - 1).pic * u);
219
+ } else e.towards < 64 ? (t.fromchar || (I(t, n.x[0], n.y[0]), t.delta.x += n.x[1] - t.curx[1], t.delta.y += n.y[1] - t.cury[1], e.towards < 0 && (t.delta = { x: -t.delta.x, y: -t.delta.y }), t.delta.x < 0 ? t.orient |= 4 : t.orient = 0), x = B(t, Math.abs(e.towards) * u)) : (t.curx[0] === t.target.x && t.cury[0] === t.target.y && (E(r, 2) ? t.target.x = (t.target.x + E(r, 7) + 5) % d : (t.target.x -= E(r, 7) + 5, t.target.x < 0 && (t.target.x += d)), E(r, 2) ? t.target.y = (t.target.y + E(r, 7) + 5) % h : (t.target.y -= E(r, 7) + 5, t.target.y < 0 && (t.target.y += h)), I(t, t.target.x, t.target.y), t.offl = 0, t.offs = 0), x = B(t, (e.towards >> 6) * u));
220
+ if (e.thru && ur(r, t, x) && t.fromchar > 0 && g(r, c)) continue;
221
+ for (x.x === 0 && x.y === 0 ? t.target = { x: t.curx[0], y: t.cury[0] } : (t.curx[1] += x.x, t.cury[1] += x.y), J(r, t.curx[0], t.cury[0]) === c && Q(r, t.curx[0], t.cury[0], b); t.curx[1] >= i; )
222
+ t.curx[1] -= i, t.curx[0]++;
223
+ for (; t.curx[1] < 0; )
224
+ t.curx[1] += i, t.curx[0]--;
225
+ for (; t.cury[1] >= i; )
226
+ t.cury[1] -= i, t.cury[0]++;
227
+ for (; t.cury[1] < 0; )
228
+ t.cury[1] += i, t.cury[0]--;
229
+ if (t.curx[0] < 0 && (t.curx[0] += d), t.cury[0] < 0 && (t.cury[0] += h), t.curx[0] >= d && (t.curx[0] -= d), t.cury[0] >= h && (t.cury[0] -= h), ir(r, t) || (t.scrPos = { x: T, y: T }), t.curPic >= 0 && t.curPic < O && xr(r, c) && t.fromchar !== 1) {
230
+ const l = W(r, c), y = nr(r, r.mblk[l]) - 1;
231
+ if (r.mon[r.mm[c].monnum]?.power < er && g(r, c)) {
232
+ y || H(r, V);
233
+ continue;
234
+ }
235
+ }
236
+ let M = c;
237
+ const s = t.curx[0], a = t.cury[0];
238
+ for (const [l, y, rr] of [
239
+ [0, 0, 0],
240
+ [1, 0, 1],
241
+ [1, 1, 3],
242
+ [0, 1, 2]
243
+ ]) {
244
+ const U = J(r, s + l, a + y);
245
+ U < b && (M = yr(r, U, c, rr));
246
+ }
247
+ M < b && Q(r, r.mi[M].curx[0], r.mi[M].cury[0], M), e.end > 0 && t.birthTime + e.end <= o && g(r, c);
248
+ }
249
+ }
250
+ export {
251
+ G as birthMon,
252
+ gr as blockBirthMonsters,
253
+ ir as calcDraw,
254
+ Pr as charBirthMon,
255
+ W as monPicNum,
256
+ Ar as moveAllMonsters,
257
+ K as picChkTouch,
258
+ w as resetMonInfo
259
+ };
@@ -0,0 +1,10 @@
1
+ const t = () => ({ banked: 0, base: 0 });
2
+ function b(a, n, e) {
3
+ a.banked += Math.max(0, n - a.base), a.base = e;
4
+ }
5
+ const s = (a, n) => a.banked + Math.max(0, n - a.base);
6
+ export {
7
+ s as gainAtEnd,
8
+ b as gainAtLoad,
9
+ t as newPlayGain
10
+ };
@@ -0,0 +1,48 @@
1
+ import { matchColor as p } from "../formats/palette.js";
2
+ import { PATCHES as i } from "../player/patchTable.js";
3
+ import { cleanPatches as l } from "../player/patchRules.js";
4
+ import { STOCK_TUNING as d } from "./world.js";
5
+ const m = new Map(i.map((o) => [o.id, o]));
6
+ function k(o, e) {
7
+ let c = 0;
8
+ return o.replace(/%([-0]*)(\d*)l?([ds])/g, (n, s, t, r) => {
9
+ const f = e[c++], a = String(r === "d" ? Math.trunc(Number(f)) : f), u = Number(t || 0);
10
+ return s.includes("-") ? a.padEnd(u) : s.includes("0") && r === "d" ? a.padStart(u, "0") : a.padStart(u);
11
+ });
12
+ }
13
+ function y(o, e) {
14
+ const c = l(o), n = (t) => {
15
+ const r = m.get(t);
16
+ if (!r) throw new Error(`No player patch ${t}`);
17
+ return c[t] ?? (r.kind === "fkey" ? "on" : r.stock);
18
+ }, s = (t) => n(t);
19
+ return {
20
+ text: (t) => n(t),
21
+ format: (t, ...r) => k(n(t), r),
22
+ color: (t, r) => {
23
+ const [f, a, u] = s(`color.rgb.${n(r)}`);
24
+ return p(t, f, a, u);
25
+ },
26
+ rgb: s,
27
+ frame: (t) => n(t),
28
+ num: (t) => n(t),
29
+ seconds: (t) => {
30
+ const r = n(t);
31
+ return r < 0 ? r & 65535 : r;
32
+ },
33
+ fkeyOn: (t) => !m.has(`table.fkeys.F${t}`) || n(`table.fkeys.F${t}`) !== "off",
34
+ ...e ? { about: e } : {}
35
+ };
36
+ }
37
+ function O(o) {
38
+ const e = {};
39
+ for (const c of Object.keys(d)) e[c] = o.num(`play.${c}`);
40
+ return e;
41
+ }
42
+ const N = y();
43
+ export {
44
+ N as STOCK_LOOK,
45
+ O as playTuning,
46
+ y as playerLook,
47
+ k as sprintf
48
+ };