@lewismoten/gamemaker-sandbox-engine 3.1.0 → 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 (108) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/NOTICE.md +58 -753
  3. package/README.md +94 -10
  4. package/dist/assets/{music.worklet-NqOeNo6T.js → music.worklet-aD2x7RRM.js} +23 -21
  5. package/dist/audio/cmfLoad.js +10 -0
  6. package/dist/audio/cmfPlayer.js +201 -0
  7. package/dist/audio/context.js +75 -0
  8. package/dist/audio/engine.js +173 -0
  9. package/dist/audio/mix.js +40 -0
  10. package/dist/audio/opl.js +245 -0
  11. package/dist/audio/output.js +40 -0
  12. package/dist/core/gameFiles.js +89 -0
  13. package/dist/engine/character.js +187 -0
  14. package/dist/engine/funcKeys.js +164 -0
  15. package/dist/engine/game.js +133 -0
  16. package/dist/engine/keys.js +68 -0
  17. package/dist/engine/machine.js +192 -0
  18. package/dist/engine/menus.js +135 -0
  19. package/dist/engine/monsters.js +259 -0
  20. package/dist/engine/playGain.js +10 -0
  21. package/dist/engine/playerLook.js +48 -0
  22. package/dist/engine/recorder.js +127 -0
  23. package/dist/engine/render.js +45 -0
  24. package/dist/engine/scene.js +324 -0
  25. package/dist/engine/scroll.js +79 -0
  26. package/dist/engine/showGraphic.js +107 -0
  27. package/dist/engine/slowPc.js +98 -0
  28. package/dist/engine/slowPcMusic.js +46 -0
  29. package/dist/engine/touch.js +61 -0
  30. package/dist/engine/world.js +205 -0
  31. package/dist/formats/binary.js +120 -0
  32. package/dist/formats/blocks.js +103 -0
  33. package/dist/formats/character.js +83 -0
  34. package/dist/formats/cmf.js +37 -0
  35. package/dist/formats/cmfEdit.js +154 -0
  36. package/dist/formats/cmfPreview.js +89 -0
  37. package/dist/formats/cmfSong.js +190 -0
  38. package/dist/formats/fli.js +340 -0
  39. package/dist/formats/fliFrames.js +34 -0
  40. package/dist/formats/fliLimits.js +54 -0
  41. package/dist/formats/game.js +198 -0
  42. package/dist/formats/gif.js +125 -0
  43. package/dist/formats/gifProgressive.js +99 -0
  44. package/dist/formats/graphicScripts.js +44 -0
  45. package/dist/formats/highscore.js +30 -0
  46. package/dist/formats/jpeg.js +359 -0
  47. package/dist/formats/map.js +38 -0
  48. package/dist/formats/monster.js +69 -0
  49. package/dist/formats/palette.js +58 -0
  50. package/dist/formats/recording.js +17 -0
  51. package/dist/formats/sound.js +44 -0
  52. package/dist/formats/voc.js +303 -0
  53. package/dist/gfx/colorVision.js +45 -0
  54. package/dist/gfx/cp437Glyphs.js +337 -0
  55. package/dist/gfx/font8x8.js +10 -0
  56. package/dist/gfx/screen.js +151 -0
  57. package/dist/index.js +15 -0
  58. package/dist/input/chords.js +46 -0
  59. package/dist/input/deskMouse.js +24 -0
  60. package/dist/input/keyboard.js +82 -0
  61. package/dist/input/scancodes.js +143 -0
  62. package/dist/player/fileExtensions.js +118 -0
  63. package/dist/player/patchRules.js +129 -0
  64. package/dist/player/patchTable.js +1753 -0
  65. package/dist/text/cp437.js +44 -0
  66. package/dist/types/audio/cmfPlayer.d.ts +1 -1
  67. package/dist/types/audio/engine.d.ts +21 -0
  68. package/dist/types/audio/mix.d.ts +14 -0
  69. package/dist/types/audio/music.worklet.d.ts +8 -0
  70. package/dist/types/engine/character.d.ts +3 -3
  71. package/dist/types/engine/funcKeys.d.ts +8 -6
  72. package/dist/types/engine/game.d.ts +9 -4
  73. package/dist/types/engine/keys.d.ts +2 -2
  74. package/dist/types/engine/machine.d.ts +8 -4
  75. package/dist/types/engine/menus.d.ts +4 -4
  76. package/dist/types/engine/monsters.d.ts +1 -1
  77. package/dist/types/engine/playerLook.d.ts +20 -2
  78. package/dist/types/engine/recorder.d.ts +8 -1
  79. package/dist/types/engine/render.d.ts +2 -2
  80. package/dist/types/engine/scene.d.ts +41 -9
  81. package/dist/types/engine/scroll.d.ts +9 -1
  82. package/dist/types/engine/showGraphic.d.ts +2 -2
  83. package/dist/types/engine/slowPc.d.ts +64 -2
  84. package/dist/types/engine/slowPcMusic.d.ts +18 -0
  85. package/dist/types/engine/touch.d.ts +2 -2
  86. package/dist/types/engine/world.d.ts +28 -6
  87. package/dist/types/formats/cmfEdit.d.ts +53 -0
  88. package/dist/types/formats/cmfPreview.d.ts +19 -0
  89. package/dist/types/formats/cmfSong.d.ts +74 -0
  90. package/dist/types/formats/fli.d.ts +11 -0
  91. package/dist/types/formats/fliFrames.d.ts +18 -0
  92. package/dist/types/formats/fliLimits.d.ts +13 -0
  93. package/dist/types/formats/game.d.ts +7 -0
  94. package/dist/types/formats/gif.d.ts +1 -1
  95. package/dist/types/formats/gifProgressive.d.ts +46 -0
  96. package/dist/types/formats/jpeg.d.ts +20 -0
  97. package/dist/types/gfx/colorVision.d.ts +26 -0
  98. package/dist/types/gfx/screen.d.ts +4 -0
  99. package/dist/types/index.d.ts +4 -0
  100. package/dist/types/input/keyboard.d.ts +1 -1
  101. package/dist/types/{dosPlayer → player}/patchRules.d.ts +1 -1
  102. package/dist/types/{dosPlayer → player}/patchTable.d.ts +8 -5
  103. package/dist/types/text/cp437.d.ts +6 -0
  104. package/package.json +322 -9
  105. package/dist/engine.js +0 -5436
  106. package/dist/types/engine/package.d.ts +0 -4
  107. /package/dist/types/{project → core}/gameFiles.d.ts +0 -0
  108. /package/dist/types/{dosPlayer → player}/fileExtensions.d.ts +0 -0
@@ -0,0 +1,53 @@
1
+ import { type Ev, type Note, type CmfSong } from './cmfSong.js';
2
+ /** Notes on one channel, by start. */
3
+ export declare function channelNotes(song: CmfSong, ch: number): Note[];
4
+ export declare function addNote(song: CmfSong, ch: number, key: number, start: number, len: number, vel?: number): Note;
5
+ export declare const DEFAULT_VELOCITY = 100;
6
+ /** Clamps a velocity to what a note-on can carry (0 would turn the note off). */
7
+ export declare function clampVelocity(v: number): number;
8
+ /** Sets how loud notes play (1..127). Unchanged notes keep their bytes. */
9
+ export declare function setVelocity(notes: Iterable<Note>, v: number): void;
10
+ /** Scales velocities by a factor (and/or adds an offset), clamped to 1..127. */
11
+ export declare function scaleVelocities(notes: Iterable<Note>, factor: number, add?: number): number;
12
+ /**
13
+ * The carrier's total level (TL, 0 loudest .. 63 silent) SBFMDRV plays a note at, for the
14
+ * instrument's own TL: 63 - floor((velocity + 128) * (63 - TL) / 256). Velocity 127 keeps
15
+ * the level nearly as written; velocity 1 is about half as loud in TL steps.
16
+ */
17
+ export declare function velocityLevel(velocity: number, tl: number): number;
18
+ /** Moves and/or resizes a note (start, length in ticks, note number). */
19
+ export declare function setNote(song: CmfSong, n: Note, start: number, len: number, key: number): void;
20
+ export declare function deleteNotes(song: CmfSong, notes: Iterable<Note>): void;
21
+ /** The song end never comes before the last event. */
22
+ export declare function extendEnd(song: CmfSong): void;
23
+ export declare function lastEventTick(song: CmfSong): number;
24
+ /** Moves where the song repeats (never before the last event). */
25
+ export declare function setEnd(song: CmfSong, tick: number): void;
26
+ /** Mode in effect at the start (before any note). */
27
+ export declare function startMode(song: CmfSong): boolean;
28
+ export declare function modeChanges(song: CmfSong): Ev[];
29
+ /** Sets melody (false) or rhythm (true) mode from the start of the song. */
30
+ export declare function setStartMode(song: CmfSong, rhythm: boolean): void;
31
+ /** Instrument changes on a channel, by time. */
32
+ export declare function programChanges(song: CmfSong, ch: number): Ev[];
33
+ /** The instrument a channel starts with (its first note's instrument). */
34
+ export declare function startProgram(song: CmfSong, ch: number): number;
35
+ /** Picks the instrument a channel starts with. */
36
+ export declare function setStartProgram(song: CmfSong, ch: number, program: number): void;
37
+ /** Adds (or changes) an instrument change on a channel at a time. */
38
+ export declare function setProgramAt(song: CmfSong, ch: number, tick: number, program: number): Ev;
39
+ export declare function removeEvent(song: CmfSong, ev: Ev): void;
40
+ /** Channels that have notes or instrument changes. */
41
+ export declare function usedChannels(song: CmfSong): number[];
42
+ /** Removes a channel's notes and events (mode switches stay: they affect the whole song). */
43
+ export declare function removeChannel(song: CmfSong, ch: number): void;
44
+ /** Changes the speed: every time is multiplied by factor (the beat length too). */
45
+ export declare function scaleTime(song: CmfSong, factor: number): void;
46
+ /** Removes events PlayIt ignores (pitch bend, other controllers, stray note-offs...). */
47
+ export declare function stripIgnored(song: CmfSong): number;
48
+ export declare function ignoredCount(song: CmfSong): number;
49
+ /**
50
+ * Which FM voice a channel sounds on, given the mode: melody mode has voices 0..8 on
51
+ * channels 0..8; rhythm mode has 0..5 and drums on 11..15. Other channels are silent.
52
+ */
53
+ export declare function channelSounds(ch: number, rhythm: boolean): boolean;
@@ -0,0 +1,19 @@
1
+ import { type CmfSong } from './cmfSong.js';
2
+ export interface Preview {
3
+ bytes: Uint8Array;
4
+ /** Length of one pass of the preview in ticks. */
5
+ length: number;
6
+ /** Song tick (or -1 in a gap) for a tick since the preview started. */
7
+ songTick: (t: number) => number;
8
+ }
9
+ /**
10
+ * A copy of the song to listen to: some channels muted, starting from a point, or looping a
11
+ * region. Built from the same events, so it plays through the same PlayIt code.
12
+ */
13
+ export declare function buildPreview(song: CmfSong, opts?: {
14
+ muted?: Set<number>;
15
+ from?: number;
16
+ loop?: [number, number];
17
+ }): Preview;
18
+ /** A tiny song that plays one note with an instrument (for "try it"). */
19
+ export declare function auditionSong(song: CmfSong, ch: number, program: number, key: number, ticks?: number, vel?: number): Uint8Array;
@@ -0,0 +1,74 @@
1
+ type EvType = 'on' | 'off' | 'program' | 'mode' | 'raw';
2
+ /** One event of the stream. */
3
+ export interface Ev {
4
+ type: EvType;
5
+ tick: number;
6
+ /** Order among events at the same tick (original stream order; new events go around them). */
7
+ seq: number;
8
+ /** MIDI channel 0..15. */
9
+ ch: number;
10
+ /** on/off: note number; program: instrument number; mode: 0 = melody, otherwise rhythm. */
11
+ a: number;
12
+ /** on: velocity 1..127 (how loud; 0 would be a note off); off: the release byte (kept as read). */
13
+ b: number;
14
+ /** off: written as 0x8n (8) or as 0x9n with velocity 0 (9). */
15
+ fn?: 8 | 9;
16
+ /** notes: whether the original wrote a status byte (undefined for new events). */
17
+ status?: boolean;
18
+ /** A stray 0x8n/0x9n status byte written just before a non-note event. */
19
+ prefix?: number;
20
+ /** raw: the whole event. */
21
+ bytes?: number[];
22
+ /** The original encoding of the delta time before this event. */
23
+ delta?: number[];
24
+ }
25
+ export interface Note {
26
+ on: Ev;
27
+ /** No off event: the note sounds until it is cut or the song repeats. */
28
+ off?: Ev;
29
+ }
30
+ export interface CmfSong {
31
+ /** Everything before the instruments (header, title strings); fields are rewritten on save. */
32
+ header: Uint8Array;
33
+ ticksPerBeat: number;
34
+ clockTicks: number;
35
+ channelUsed: Uint8Array;
36
+ /** Which channels had events when read (to keep channelUsed as it was). */
37
+ hadEvents: boolean[];
38
+ /** 16-byte SBI records; instrument n starts on channel n. */
39
+ instruments: Uint8Array[];
40
+ /** Bytes between the instruments and the music (normally none). */
41
+ gap: Uint8Array;
42
+ /** Silence before the song starts again when it repeats (the first delta). */
43
+ leadIn: number;
44
+ leadInBytes?: number[];
45
+ notes: Note[];
46
+ /** program, mode, raw and stray off events. */
47
+ events: Ev[];
48
+ /** Where the song repeats. */
49
+ end: {
50
+ tick: number;
51
+ delta?: number[];
52
+ bytes: number[];
53
+ };
54
+ /** Counter for ordering new events. */
55
+ counter: number;
56
+ }
57
+ export declare const RHYTHM_CHANNELS: number[];
58
+ export declare const DRUM_NAMES: Record<number, string>;
59
+ export declare function noteEnd(song: CmfSong, n: Note): number;
60
+ /** Reads a CMF the way PlayIt() does. */
61
+ export declare function readSong(bytes: Uint8Array): CmfSong;
62
+ /** All events in stream order. */
63
+ export declare function streamEvents(song: CmfSong): Ev[];
64
+ /** Writes the song back to a CMF file. */
65
+ export declare function writeSong(song: CmfSong): Uint8Array;
66
+ /**
67
+ * The driver calls PlayIt() makes over `ticks` timer ticks, as "tick:call" strings
68
+ * (on/off/program/mode/restart). With `velocity`, note-ons end in "@velocity" (how loud
69
+ * SBFMDRV plays them). Two songs that give the same trace with velocities sound the same.
70
+ */
71
+ export declare function traceMusic(music: Uint8Array, ticks: number, velocity?: boolean): string[];
72
+ /** The music block of a CMF file. */
73
+ export declare function musicOf(bytes: Uint8Array): Uint8Array;
74
+ export {};
@@ -13,6 +13,8 @@ interface FliCanvas {
13
13
  /** 6-bit palette, 768 bytes. */
14
14
  palette: Uint8Array;
15
15
  }
16
+ /** A picture bigger than this (4096 x 4096) is a lie in the header, not an animation: refused before any canvas is made. */
17
+ export declare const FLI_MAX_PIXELS: number;
16
18
  export declare function isFli(bytes: Uint8Array): boolean;
17
19
  export declare function parseFli(bytes: Uint8Array): FliAnimation;
18
20
  export declare function newFliCanvas(anim: FliAnimation): FliCanvas;
@@ -34,6 +36,8 @@ export declare const FLI_CHUNK_MAX = 16000;
34
36
  * or as the lines that changed, the 6-bit palette in the first frame, and a closing "ring"
35
37
  * frame that leads back to the start. No chunk is bigger than FLI_CHUNK_MAX: a bigger frame
36
38
  * is split into bands of lines. `speed` is the delay after each frame in 1/70 s.
39
+ * `noLoopFrame` leaves the ring frame out: PLAYGAME's FLI::View (code/Image/FLI/FLI.CPP)
40
+ * plays only the header's frame count, so the ring frame is never shown there.
37
41
  */
38
42
  export declare function encodeFli(frames: Uint8Array[], palette: Uint8Array, opts?: {
39
43
  width?: number;
@@ -41,5 +45,12 @@ export declare function encodeFli(frames: Uint8Array[], palette: Uint8Array, opt
41
45
  speed?: number;
42
46
  /** A palette per frame (fades, flashes); changes are stored where they happen. */ palettes?: Uint8Array[];
43
47
  /** Code runs of a color inside changed spans as run packets too (smaller deltas for drawn art). */ runs?: boolean;
48
+ /** Leave out the closing ring frame (nothing that plays the file shows it). */ noLoopFrame?: boolean;
49
+ /**
50
+ * After the first frame, send a palette change only for the colors the frame draws (a fade
51
+ * of a picture that uses 90 colors sends 90, not 256); a color the player still holds
52
+ * stale goes out in the first frame that draws it. What shows is the same.
53
+ */
54
+ sparsePalettes?: boolean;
44
55
  }): Uint8Array;
45
56
  export {};
@@ -0,0 +1,18 @@
1
+ export interface FliFrame {
2
+ pixels: Uint8Array;
3
+ /** 6-bit palette, 768 bytes. */
4
+ palette: Uint8Array;
5
+ }
6
+ export interface FliFrames {
7
+ width: number;
8
+ height: number;
9
+ /** Delay after each frame in 1/70 s. */
10
+ speed: number;
11
+ frames: FliFrame[];
12
+ }
13
+ /** Plays the animation through, keeping a copy of every frame (not the closing ring frame). */
14
+ export declare function decodeFliFrames(bytes: Uint8Array): FliFrames;
15
+ /** Writes the frames as an .FLI; palette changes are stored on the frames where they happen. */
16
+ export declare function encodeFliFrames(a: FliFrames): Uint8Array;
17
+ /** Places a picture on a width x height frame: centered, cropped or padded with color 0. */
18
+ export declare function fitPicture(pixels: Uint8Array, pw: number, ph: number, width: number, height: number): Uint8Array;
@@ -0,0 +1,13 @@
1
+ type FliFaultKind = 'big' | 'packets' | 'black' | 'type';
2
+ interface FliFault {
3
+ kind: FliFaultKind;
4
+ /** The frame it is in (0 the first; the last is the ring frame back to the start). */
5
+ frame: number;
6
+ /** The chunk's size with its header ('big'), the packet count ('packets') or the chunk type ('type'). */
7
+ value: number;
8
+ }
9
+ /** Every fault in an .FLI, the first of each kind per frame. A file that isn't an FLI has none. */
10
+ export declare function fliFaults(bytes: Uint8Array): FliFault[];
11
+ /** A fault in words, for a finding or a health issue. */
12
+ export declare function describeFliFault(f: FliFault): string;
13
+ export {};
@@ -66,6 +66,13 @@ export declare function defaultHeader(): Uint8Array;
66
66
  export declare function newGame(title?: string): Game;
67
67
  export declare function parseGame(bytes: Uint8Array): Game;
68
68
  export declare function serializeGame(g: Game): Uint8Array;
69
+ /**
70
+ * The game's name for showing outside DOS: the start scene's description, which holds CP437
71
+ * byte codes (the menu draws them with the PC font), as the Unicode a PC showed, without the
72
+ * spaces and frame characters (box lines, blocks) authors put around it to center or box it.
73
+ * Empty when there is none.
74
+ */
75
+ export declare function gameTitle(game: Game): string;
69
76
  export declare function sceneKind(s: Scene): 'start' | 'end' | 'adventure' | 'unused';
70
77
  export declare function fileSlotsFor(s: Scene): readonly string[];
71
78
  export declare function slotExtensions(s: Scene): readonly string[];
@@ -1,4 +1,4 @@
1
- import { type Palette } from './palette';
1
+ import { type Palette } from './palette.js';
2
2
  export interface IndexedImage {
3
3
  width: number;
4
4
  height: number;
@@ -0,0 +1,46 @@
1
+ import { type IndexedImage } from './gif.js';
2
+ import { type Palette } from './palette.js';
3
+ /** A GIF read from as many of its bytes as there are so far. */
4
+ interface PartialGif {
5
+ width: number;
6
+ height: number;
7
+ /** 6-bit VGA values (the DAC), as decodeGif() gives them. */
8
+ palette: Palette;
9
+ /** How many colors the file's color table has. */
10
+ colors: number;
11
+ interlaced: boolean;
12
+ /** Indexes in file order: row by row as stored (interlaced files store their passes in turn). */
13
+ stored: Uint8Array;
14
+ /** How many pixels of `stored` have arrived. */
15
+ received: number;
16
+ /** All the pixels have arrived. */
17
+ complete: boolean;
18
+ /** Pixel width/height ratio from the GIF89a header (1 when not given). */
19
+ aspect: number;
20
+ }
21
+ /** The picture row each stored row is, and how many rows it covers until finer rows arrive. */
22
+ export declare function storedRows(height: number, interlaced: boolean): {
23
+ y: number;
24
+ span: number;
25
+ }[];
26
+ /**
27
+ * Reads the start of a GIF. Undefined until the header, color table and image descriptor
28
+ * have all arrived (a viewer can't draw anything before that).
29
+ */
30
+ export declare function decodePartialGif(bytes: Uint8Array): PartialGif | undefined;
31
+ /**
32
+ * The picture as far as it has arrived, rows in screen order. Rows not yet received are
33
+ * `blank`, or, in an interlaced file, a copy of the coarser row above them.
34
+ */
35
+ export declare function partialPixels(g: PartialGif, blank?: number): Uint8Array;
36
+ /**
37
+ * Encodes an image as GIF89a: interlaced if asked, with a color table just big enough for
38
+ * `colors` and an optional pixel aspect byte ((n + 15) / 64 = pixel width / height; 38 is
39
+ * the tall pixels of 320x200 and 640x400 on a 4:3 screen).
40
+ */
41
+ export declare function encodeGif89(img: IndexedImage, opts?: {
42
+ interlaced?: boolean;
43
+ colors?: number;
44
+ aspect?: number;
45
+ }): Uint8Array;
46
+ export {};
@@ -0,0 +1,20 @@
1
+ /** A JPEG decoded from as much of it as there is. */
2
+ export interface PartialJpeg {
3
+ width: number;
4
+ height: number;
5
+ /** 1 (grayscale) or 3 (RGB). */
6
+ channels: number;
7
+ /** width * height * channels bytes. */
8
+ pixels: Uint8Array;
9
+ /** Per pixel: 1 once that part of the picture has arrived (a progressive file: all of it after its first scan). */
10
+ shown: Uint8Array;
11
+ progressive: boolean;
12
+ /** Scans that have fully arrived. */
13
+ scans: number;
14
+ complete: boolean;
15
+ /** Pixel width / height from the JFIF header (1 when not given). */
16
+ aspect: number;
17
+ }
18
+ export declare function isJpeg(bytes: Uint8Array): boolean;
19
+ /** Decodes as much of a JPEG as there is; undefined until the frame header has arrived. */
20
+ export declare function decodePartialJpeg(data: Uint8Array): PartialJpeg | undefined;
@@ -0,0 +1,26 @@
1
+ export type Rgb = [number, number, number];
2
+ export type Vision = 'protan' | 'deutan' | 'tritan';
3
+ /** Machado et al. 2009, Table 1, severity 1.0 (rows give linear R, G, B out). */
4
+ export declare const MACHADO: {
5
+ readonly protan: readonly [0.152286, 1.052583, -0.204868, 0.114503, 0.786281, 0.099216, -0.003882, -0.048116, 1.051998];
6
+ readonly deutan: readonly [0.367322, 0.860646, -0.227968, 0.280085, 0.672501, 0.047413, -0.01182, 0.04294, 0.968881];
7
+ readonly tritan: readonly [1.255528, -0.076749, -0.178779, -0.078411, 0.930809, 0.147602, 0.004733, 0.691367, 0.3039];
8
+ };
9
+ /** An sRGB value (0..1) as linear light (0..1). */
10
+ export declare const srgbToLinear: (c: number) => number;
11
+ /** Linear light as an sRGB value (0..1), clamped first. */
12
+ export declare function linearToSrgb(l: number): number;
13
+ /** A linear RGB color as the given kind of color vision sees it, each channel clamped to 0..1. */
14
+ export declare function simulateLinear(rgb: Rgb, matrix: readonly number[]): Rgb;
15
+ /** Linear RGB to CIELAB (D65 white). */
16
+ export declare function lab([r, g, b]: Rgb): Rgb;
17
+ /** CIELAB back to linear RGB (unclamped). */
18
+ export declare function unlab([L, a, b]: Rgb): Rgb;
19
+ /** How far apart two CIELAB colors look (CIE76 delta E: about 2.3 is just noticeable side by side). */
20
+ export declare const deltaELab: (a: Rgb, b: Rgb) => number;
21
+ /** A color (0-255 per channel) as the given kind of color vision sees it. */
22
+ export declare function simulateBytes(c: Rgb, v: Vision): Rgb;
23
+ /** How far apart two colors (0-255 per channel) look: CIE76 delta E; about 2 is just noticeable, over 25 plainly different. */
24
+ export declare const deltaEBytes: (a: Rgb, b: Rgb) => number;
25
+ /** A whole VGA palette (768 bytes of 6-bit values) as the given kind of color vision sees it. */
26
+ export declare function simulatePalette(pal: Uint8Array, v: Vision): Uint8Array;
@@ -1,6 +1,10 @@
1
1
  export declare const SIZEX = 320;
2
2
  export declare const SIZEY = 200;
3
3
  export declare class Screen {
4
+ /** Observer metadata only: PLAYGAME's CropScreen is active (no effect on rendering). */
5
+ dosCropped: boolean;
6
+ /** Level number for screen captures; retained during function-key screens. */
7
+ sceneNumber: number;
4
8
  readonly pixels: Uint8Array<ArrayBuffer>;
5
9
  /** Palette currently shown by the "DAC" (6-bit components). */
6
10
  readonly palette: Uint8Array<ArrayBuffer>;
@@ -0,0 +1,4 @@
1
+ export { Machine, GameAborted } from './engine/machine.js';
2
+ export { runGame, loadGameFile, gameNameOf, type RunOptions } from './engine/game.js';
3
+ export { GameFiles, normalize, cdName, type FileStream } from './core/gameFiles.js';
4
+ export { AudioEngine } from './audio/engine.js';
@@ -1,4 +1,4 @@
1
- import { ArrowChords } from './chords';
1
+ import { ArrowChords } from './chords.js';
2
2
  export interface TypedKey {
3
3
  scan: number;
4
4
  /** ASCII code (0 for extended keys such as arrows). */
@@ -1,4 +1,4 @@
1
- import { type FramePatch, type PatchEntry } from './patchTable';
1
+ import { type FramePatch, type PatchEntry } from './patchTable.js';
2
2
  export type PatchValue = string | number | number[];
3
3
  /** A project's DOS player choices: patch id -> value (patchTable.ts says what each takes). */
4
4
  export type PlayerPatches = Record<string, PatchValue>;
@@ -1,7 +1,7 @@
1
1
  /** The editor panel's groups. */
2
- export type PatchGroup = 'words' | 'colors' | 'frames' | 'positions' | 'times' | 'keys';
3
- /** The screen a patch shows on, which the panel previews while it is edited. */
4
- export type PatchScreen = 'menu' | 'hiscores' | 'newHiscore' | 'status' | 'load' | 'save' | 'drop' | 'help' | 'text' | 'missing' | 'about' | 'play' | 'all';
2
+ export type PatchGroup = 'words' | 'colors' | 'frames' | 'positions' | 'times' | 'keys' | 'play';
3
+ /** The screen a patch shows on, which the panel previews while it is edited ('gameplay': every scene, no preview). */
4
+ export type PatchScreen = 'menu' | 'hiscores' | 'newHiscore' | 'status' | 'load' | 'save' | 'drop' | 'help' | 'text' | 'missing' | 'about' | 'play' | 'gameplay' | 'all';
5
5
  /**
6
6
  * The color targets RGBdata::Match looks for, by name, with the DGROUP offset of each object
7
7
  * (what a color selector's push imm16 names).
@@ -16,10 +16,12 @@ export declare const COLOR_TARGETS: {
16
16
  readonly hsGreen: 5632;
17
17
  };
18
18
  export type ColorName = keyof typeof COLOR_TARGETS;
19
- /** One immediate in the code: its file offset and size (1: push imm8, sign-extended; 2: imm16). */
19
+ /** One immediate in the code: its file offset and size (1: imm8, sign-extended; 2: imm16). */
20
20
  export interface ImmField {
21
21
  offset: number;
22
22
  size: number;
23
+ /** It holds the value's negative (the -MAXGRAV of `if (tx < -MAXGRAV) tx = -MAXGRAV`). */
24
+ negate?: true;
23
25
  }
24
26
  interface Base {
25
27
  id: string;
@@ -27,7 +29,8 @@ interface Base {
27
29
  screen: PatchScreen;
28
30
  label: string;
29
31
  note?: string;
30
- safety: 'safe' | 'caution';
32
+ /** experimental: changes how every scene plays (the `play` group); test it in DOSBox. */
33
+ safety: 'safe' | 'caution' | 'experimental';
31
34
  /** The web player shows it too (false: DOS only). */
32
35
  web: boolean;
33
36
  }
@@ -0,0 +1,6 @@
1
+ /** Converts a string written with Unicode symbols, accents and box characters to CP437 byte codes. */
2
+ export declare function toCp437(s: string): string;
3
+ /** Converts CP437 byte strings (including binary.ts's Latin-1 aliases), never Unicode prose. */
4
+ export declare function fromCp437(s: string): string;
5
+ /** A DOS text file as Unicode, retaining ASCII controls (CR/LF, TAB, NUL, ^Z) for its reader. */
6
+ export declare function cp437Text(bytes: Uint8Array): string;