@lewismoten/gamemaker-sandbox-tools 0.0.0-stage → 3.1.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 (127) hide show
  1. package/LICENSE +24 -0
  2. package/NOTICE.md +19 -0
  3. package/README.md +76 -2
  4. package/dist/audio.js +140 -0
  5. package/dist/binary-D7wuaC5g.js +120 -0
  6. package/dist/drawing.js +871 -0
  7. package/dist/formats/blocks.js +103 -0
  8. package/dist/formats/character.js +83 -0
  9. package/dist/formats/cmf.js +37 -0
  10. package/dist/formats/fli.js +296 -0
  11. package/dist/formats/fliLimits.js +54 -0
  12. package/dist/formats/game.js +193 -0
  13. package/dist/formats/gif.js +125 -0
  14. package/dist/formats/graphicScripts.js +44 -0
  15. package/dist/formats/map.js +38 -0
  16. package/dist/formats/monster.js +69 -0
  17. package/dist/formats/palette.js +58 -0
  18. package/dist/formats/recording.js +17 -0
  19. package/dist/formats/sound.js +44 -0
  20. package/dist/formats/voc.js +303 -0
  21. package/dist/images.js +50 -0
  22. package/dist/pixels-DzfIIUOl.js +76 -0
  23. package/dist/simulation.js +2776 -0
  24. package/dist/types/games/kit/blit.d.ts +10 -0
  25. package/dist/types/games/kit/clips.d.ts +36 -0
  26. package/dist/types/games/kit/gameSim.d.ts +108 -0
  27. package/dist/types/games/kit/music.d.ts +1 -0
  28. package/dist/types/games/kit/palette.d.ts +16 -0
  29. package/dist/types/games/kit/pcText.d.ts +8 -0
  30. package/dist/types/games/kit/pixels.d.ts +26 -0
  31. package/dist/types/games/kit/reel.d.ts +34 -0
  32. package/dist/types/games/kit/sceneSim.d.ts +84 -0
  33. package/dist/types/games/kit/shading.d.ts +11 -0
  34. package/dist/types/games/kit/sound.d.ts +29 -0
  35. package/dist/types/games/kit/textBounds.d.ts +51 -0
  36. package/dist/types/games/kit/tune.d.ts +6 -0
  37. package/dist/types/web/packages/tools/src/audio.d.ts +3 -0
  38. package/dist/types/web/packages/tools/src/colors.d.ts +20 -0
  39. package/dist/types/web/packages/tools/src/drawing.d.ts +10 -0
  40. package/dist/types/web/packages/tools/src/images.d.ts +2 -0
  41. package/dist/types/web/packages/tools/src/microFont.d.ts +1 -0
  42. package/dist/types/web/packages/tools/src/simulation.d.ts +3 -0
  43. package/dist/types/web/packages/tools/src/text.d.ts +41 -0
  44. package/dist/types/web/scripts/cdGames.d.ts +103 -0
  45. package/dist/types/web/scripts/gameShots.d.ts +12 -0
  46. package/dist/types/web/scripts/ogImage.d.ts +21 -0
  47. package/dist/types/web/src/assistant/png.d.ts +10 -0
  48. package/dist/types/web/src/audio/cmfLoad.d.ts +7 -0
  49. package/dist/types/web/src/audio/cmfPlayer.d.ts +69 -0
  50. package/dist/types/web/src/audio/compose.d.ts +51 -0
  51. package/dist/types/web/src/audio/context.d.ts +12 -0
  52. package/dist/types/web/src/audio/engine.d.ts +39 -0
  53. package/dist/types/web/src/audio/music.worklet.d.ts +14 -0
  54. package/dist/types/web/src/audio/opl.d.ts +37 -0
  55. package/dist/types/web/src/audio/output.d.ts +13 -0
  56. package/dist/types/web/src/desk/boxes/boxFacts.d.ts +85 -0
  57. package/dist/types/web/src/dosPlayer/fileExtensions.d.ts +44 -0
  58. package/dist/types/web/src/dosPlayer/patchRules.d.ts +24 -0
  59. package/dist/types/web/src/dosPlayer/patchTable.d.ts +80 -0
  60. package/dist/types/web/src/edition.d.ts +6 -0
  61. package/dist/types/web/src/eggs/eggState.d.ts +26 -0
  62. package/dist/types/web/src/eggs/eggs.d.ts +31 -0
  63. package/dist/types/web/src/engine/character.d.ts +30 -0
  64. package/dist/types/web/src/engine/funcKeys.d.ts +33 -0
  65. package/dist/types/web/src/engine/game.d.ts +52 -0
  66. package/dist/types/web/src/engine/keys.d.ts +17 -0
  67. package/dist/types/web/src/engine/machine.d.ts +99 -0
  68. package/dist/types/web/src/engine/menus.d.ts +46 -0
  69. package/dist/types/web/src/engine/monsters.d.ts +19 -0
  70. package/dist/types/web/src/engine/playGain.d.ts +11 -0
  71. package/dist/types/web/src/engine/playerLook.d.ts +26 -0
  72. package/dist/types/web/src/engine/recorder.d.ts +60 -0
  73. package/dist/types/web/src/engine/render.d.ts +8 -0
  74. package/dist/types/web/src/engine/scene.d.ts +156 -0
  75. package/dist/types/web/src/engine/scroll.d.ts +16 -0
  76. package/dist/types/web/src/engine/showGraphic.d.ts +39 -0
  77. package/dist/types/web/src/engine/slowPc.d.ts +62 -0
  78. package/dist/types/web/src/engine/touch.d.ts +33 -0
  79. package/dist/types/web/src/engine/world.d.ts +215 -0
  80. package/dist/types/web/src/export/gameAbout.d.ts +15 -0
  81. package/dist/types/web/src/formats/binary.d.ts +44 -0
  82. package/dist/types/web/src/formats/blocks.d.ts +52 -0
  83. package/dist/types/web/src/formats/character.d.ts +65 -0
  84. package/dist/types/web/src/formats/cmf.d.ts +33 -0
  85. package/dist/types/web/src/formats/fli.d.ts +45 -0
  86. package/dist/types/web/src/formats/fliLimits.d.ts +13 -0
  87. package/dist/types/web/src/formats/game.d.ts +72 -0
  88. package/dist/types/web/src/formats/gif.d.ts +15 -0
  89. package/dist/types/web/src/formats/graphicScripts.d.ts +18 -0
  90. package/dist/types/web/src/formats/highscore.d.ts +10 -0
  91. package/dist/types/web/src/formats/map.d.ts +24 -0
  92. package/dist/types/web/src/formats/monster.d.ts +48 -0
  93. package/dist/types/web/src/formats/palette.d.ts +15 -0
  94. package/dist/types/web/src/formats/recording.d.ts +7 -0
  95. package/dist/types/web/src/formats/sound.d.ts +13 -0
  96. package/dist/types/web/src/formats/voc.d.ts +13 -0
  97. package/dist/types/web/src/gfx/cp437Glyphs.d.ts +2 -0
  98. package/dist/types/web/src/gfx/font8x8.d.ts +2 -0
  99. package/dist/types/web/src/gfx/levelPicture.d.ts +81 -0
  100. package/dist/types/web/src/gfx/screen.d.ts +46 -0
  101. package/dist/types/web/src/gfx/titlePicture.d.ts +21 -0
  102. package/dist/types/web/src/input/chords.d.ts +22 -0
  103. package/dist/types/web/src/input/deskMouse.d.ts +14 -0
  104. package/dist/types/web/src/input/keyboard.d.ts +39 -0
  105. package/dist/types/web/src/input/scancodes.d.ts +3 -0
  106. package/dist/types/web/src/manual/printables/types.d.ts +277 -0
  107. package/dist/types/web/src/project/bizarre.d.ts +28 -0
  108. package/dist/types/web/src/project/companion.d.ts +35 -0
  109. package/dist/types/web/src/project/diskFacts.d.ts +30 -0
  110. package/dist/types/web/src/project/files.d.ts +124 -0
  111. package/dist/types/web/src/project/gameFiles.d.ts +49 -0
  112. package/dist/types/web/src/project/gamePack.d.ts +17 -0
  113. package/dist/types/web/src/project/health.d.ts +30 -0
  114. package/dist/types/web/src/project/secretGames.d.ts +19 -0
  115. package/dist/types/web/src/project/storage.d.ts +46 -0
  116. package/dist/types/web/src/project/streamGame.d.ts +38 -0
  117. package/dist/types/web/src/project/zip.d.ts +33 -0
  118. package/dist/types/web/src/retro/dos/disks.d.ts +33 -0
  119. package/dist/types/web/src/retro/text/cp437.d.ts +4 -0
  120. package/dist/types/web/src/seededRandom.d.ts +6 -0
  121. package/dist/types/web/src/tinHearts/deskHearts.d.ts +33 -0
  122. package/dist/types/web/src/tinHearts/manifest.d.ts +30 -0
  123. package/dist/types/web/src/tinHearts/tinHearts.d.ts +84 -0
  124. package/dist/types/web/src/walkthrough/format.d.ts +92 -0
  125. package/dist/types/web/src/walkthrough/madeUpScores.d.ts +6 -0
  126. package/dist/types/web/src/walkthrough/runtime.d.ts +134 -0
  127. package/package.json +60 -4
@@ -0,0 +1,10 @@
1
+ import { Pixels } from './pixels.js';
2
+ export declare const CLEAR = 255;
3
+ /** Copies src over dst, skipping clear pixels. */
4
+ export declare function over(dst: Pixels, src: Pixels, x?: number, y?: number): Pixels;
5
+ /** Recolors every pixel through a lookup (palette swaps for variants and hurt flashes). */
6
+ export declare function recolor(src: Pixels, fn: (c: number) => number): Pixels;
7
+ /** Nearest-neighbor scaled copy (for big sprites on screens). */
8
+ export declare function scaleBlit(dst: Pixels, src: Pixels, x: number, y: number, s: number, flip?: boolean): void;
9
+ /** Adds a 1 pixel outline in `ink` around every opaque pixel. */
10
+ export declare function outline(src: Pixels, ink: number): Pixels;
@@ -0,0 +1,36 @@
1
+ import type { AudioEvent } from '../../web/src/walkthrough/runtime.js';
2
+ export interface ClipCut {
3
+ kind: 'end' | 'start';
4
+ /** The scene the clip started in. */
5
+ scene: number;
6
+ clip: string;
7
+ /** The clip's length and how much of it played, in ms. */
8
+ ms: number;
9
+ played: number;
10
+ /** What cut it: 'picture' (ShowGraphic or the end of the run) or the clip that played over it. */
11
+ by: string;
12
+ /** When it started, in ms of the walkthrough's clock. */
13
+ at: number;
14
+ /** A start clip: ms from the level's first frame. */
15
+ since?: number;
16
+ }
17
+ export interface ClipLog {
18
+ events: AudioEvent[];
19
+ /** When play entered each scene (before its intro picture). */
20
+ scenes: {
21
+ t: number;
22
+ n: number;
23
+ }[];
24
+ /** Each scene's first frame of play (after the intro and the fade in). */
25
+ starts: {
26
+ t: number;
27
+ n: number;
28
+ }[];
29
+ /** File names of the disk's clips, by their bytes. */
30
+ names: Map<Uint8Array, string>;
31
+ }
32
+ /** A .VOC clip's length in ms. */
33
+ export declare function vocMs(bytes: Uint8Array): number;
34
+ /** Every clip the run cut off at a scene's end or at a level's start. */
35
+ export declare function clipCuts(log: ClipLog): ClipCut[];
36
+ export declare function describeCut(c: ClipCut): string;
@@ -0,0 +1,108 @@
1
+ import { type CharInfo, type World } from '../../web/src/engine/world.js';
2
+ import { type Game } from '../../web/src/formats/game.js';
3
+ import type { RecordedKey } from '../../web/src/formats/recording.js';
4
+ /** PLAYGAME's game clock. */
5
+ export declare const TICKS_PER_SECOND = 18.2;
6
+ /** A built disk's files (in games/<id>/disk), by lower-case name. */
7
+ export declare function readDisk(diskDir: string): Map<string, Uint8Array>;
8
+ /** Keys pressed in one scene, timed from the tick play entered it. */
9
+ interface SceneKeys {
10
+ scene: number;
11
+ keys: RecordedKey[];
12
+ }
13
+ interface State {
14
+ w: World;
15
+ rand: number;
16
+ scene: number;
17
+ prev: number;
18
+ link: number;
19
+ ticks: number;
20
+ clock: number;
21
+ lastKeyTick: number;
22
+ held: number[];
23
+ pending: number[];
24
+ doScroll: boolean;
25
+ ended: GameSim['ended'];
26
+ deaths: number;
27
+ trail: number[];
28
+ segments: SceneKeys[];
29
+ segmentTicks: number[];
30
+ clip: GameSim['clip'];
31
+ }
32
+ export declare class GameSim {
33
+ readonly files: Map<string, Uint8Array>;
34
+ readonly seed: number;
35
+ readonly game: Game;
36
+ ci: CharInfo;
37
+ w: World;
38
+ scene: number;
39
+ prev: number;
40
+ link: number;
41
+ /** Scenes entered, in order (a death enters the same scene again). */
42
+ trail: number[];
43
+ /** Game ticks since play entered the current scene (a segment's clock). */
44
+ ticks: number;
45
+ /** Keys per scene entered (a scene entered again after a death keeps counting on). */
46
+ segments: SceneKeys[];
47
+ /** Ticks each finished segment ran. */
48
+ segmentTicks: number[];
49
+ private lastKeyTick;
50
+ private held;
51
+ private pending;
52
+ private doScroll;
53
+ /** TimerCounter: it runs on across scenes. */
54
+ private clock;
55
+ private rand;
56
+ ended: 'won' | 'lost' | undefined;
57
+ deaths: number;
58
+ /**
59
+ * The .VOC clip the Sound Blaster is playing (PlaySbVocFile: a new one cuts it off), with
60
+ * the game clock tick it ends on; a scene's exit or intro picture cuts it too (ShowGraphic).
61
+ */
62
+ clip: {
63
+ name: string;
64
+ until: number;
65
+ } | undefined;
66
+ constructor(files: Map<string, Uint8Array>, seed?: number);
67
+ private file;
68
+ /** loadscene + StartSceneInits, as playScene does them. */
69
+ private enter;
70
+ press(scan: number): void;
71
+ release(scan: number): void;
72
+ releaseAll(): void;
73
+ isHeld(scan: number): boolean;
74
+ private event;
75
+ /** One game tick; returns 'link' (into another scene), 'dead' or 'end'. */
76
+ tick(): Promise<'link' | 'dead' | 'end' | undefined>;
77
+ /** Game ticks until the clip playing now ends (0 when none is). */
78
+ get clipTicksLeft(): number;
79
+ /**
80
+ * Stands still until the clip playing now has played to the end, so the bot's next sound
81
+ * (a jump, a pickup) doesn't cut it off: a level's start clip, say. Returns what a tick
82
+ * returned if play left the scene meanwhile.
83
+ */
84
+ waitForClip(): Promise<'link' | 'dead' | 'end' | undefined>;
85
+ /** The character's block and the pixels past it. */
86
+ get pos(): {
87
+ x: number;
88
+ y: number;
89
+ sx: number;
90
+ sy: number;
91
+ };
92
+ meter(i: number): number;
93
+ /** Money: Game-Maker's counter 3, which shows meter - 1. */
94
+ get money(): number;
95
+ /** The block number at (x, y) as it is now (a block taken or pushed is a new block number). */
96
+ blockAt(x: number, y: number): number;
97
+ /** The block's attributes as shown now (timed blocks change by themselves). */
98
+ shown(x: number, y: number): import("../../web/src/formats/blocks.js").Block;
99
+ solidAt(x: number, y: number): boolean;
100
+ snapshot(): State;
101
+ restore(s: State): void;
102
+ }
103
+ /**
104
+ * A GameSim for one game's built disk: `diskSim(new URL('../disk', import.meta.url))` in the
105
+ * game's tools/sim.ts. It reads the disk when made without files; the seed defaults to 1.
106
+ */
107
+ export declare function diskSim(disk: URL): new (files?: Map<string, Uint8Array>, seed?: number) => GameSim;
108
+ export {};
@@ -0,0 +1 @@
1
+ export * from '../../web/src/audio/compose.js';
@@ -0,0 +1,16 @@
1
+ export declare class PaletteBuilder {
2
+ readonly pal: Uint8Array<ArrayBuffer>;
3
+ private next;
4
+ readonly ramps: Map<string, number[]>;
5
+ /** One color from 8-bit RGB; returns its index. */
6
+ color(r: number, g: number, b: number): number;
7
+ /** A ramp of n shades from dark to light (8-bit RGB stops); returns the indexes. */
8
+ ramp(name: string, n: number, from: readonly [number, number, number], to: readonly [number, number, number], mid?: readonly [number, number, number]): number[];
9
+ get(name: string): number[];
10
+ /**
11
+ * Game-Maker's designers look for these grays, reds, black and LCD green; keep them. Black
12
+ * comes first: PLAYGAME clears the screen to color 0 before the high score prompt.
13
+ */
14
+ designerColors(): void;
15
+ get used(): number;
16
+ }
@@ -0,0 +1,8 @@
1
+ import { Pixels } from './pixels.js';
2
+ /** Text in the PC font; returns the width drawn. */
3
+ export declare function text(p: Pixels, x: number, y: number, s: string, col: number, scale?: number): number;
4
+ export declare const textWidth: (s: string, scale?: number) => number;
5
+ /** Text with an outline (and an optional drop shadow). */
6
+ export declare function outlined(p: Pixels, x: number, y: number, s: string, col: number, edge: number, scale?: number, shadow?: number): void;
7
+ /** Centered text (outlined when `edge` is given). */
8
+ export declare function centered(p: Pixels, y: number, s: string, col: number, scale?: number, edge?: number, cx?: number, shadow?: number): void;
@@ -0,0 +1,26 @@
1
+ export declare class Pixels {
2
+ readonly w: number;
3
+ readonly h: number;
4
+ readonly px: Uint8Array;
5
+ constructor(w: number, h: number, fill?: number);
6
+ get(x: number, y: number): number;
7
+ set(x: number, y: number, c: number): this;
8
+ rect(x: number, y: number, w: number, h: number, c: number): this;
9
+ frame(x: number, y: number, w: number, h: number, c: number): this;
10
+ line(x0: number, y0: number, x1: number, y1: number, c: number): this;
11
+ disc(cx: number, cy: number, r: number, c: number): this;
12
+ ring(cx: number, cy: number, r: number, c: number): this;
13
+ /** Every pixel through fn(x, y, current) → new color (or the same). */
14
+ map(fn: (x: number, y: number, c: number) => number): this;
15
+ /** Copies another picture in, skipping `transparent` pixels. */
16
+ blit(src: Pixels, dx: number, dy: number, transparent?: number): this;
17
+ /** A sub-rectangle as a new picture (cutting a 20x20 block out of a big drawing). */
18
+ crop(x: number, y: number, w: number, h: number): Pixels;
19
+ flipX(): Pixels;
20
+ /** ASCII art: each character maps to a color through `key`; others are skipped. */
21
+ draw(x: number, y: number, rows: string[], key: Record<string, number>): this;
22
+ }
23
+ /** A seeded random number generator (mulberry32), so builds are reproducible. */
24
+ export declare function rng(seed: number): () => number;
25
+ /** 4x4 Bayer matrix ordered dither: true where a pixel at (x, y) should take the lighter color for level 0..1. */
26
+ export declare function dither(x: number, y: number, level: number): boolean;
@@ -0,0 +1,34 @@
1
+ import { Pixels } from './pixels.js';
2
+ /** The palette (6-bit VGA) faded toward black: light 0 is black, 1 is unchanged. */
3
+ export declare function dimmed(pal: Uint8Array, light: number): Uint8Array;
4
+ export declare class Reel {
5
+ /** The reel's palette (6-bit VGA, 768 bytes). */
6
+ readonly pal: Uint8Array;
7
+ readonly w: number;
8
+ readonly h: number;
9
+ readonly frames: Uint8Array[];
10
+ readonly palettes: Uint8Array[];
11
+ private last?;
12
+ constructor(
13
+ /** The reel's palette (6-bit VGA, 768 bytes). */
14
+ pal: Uint8Array, w?: number, h?: number);
15
+ /** Adds a picture for `hold` frames, its palette faded to `light`. */
16
+ add(p: Pixels, hold?: number, light?: number, pal?: Uint8Array<ArrayBufferLike>): this;
17
+ /** A picture drawn over a copy of `bg` (the actors over the scenery), for `hold` frames. */
18
+ frame(bg: Pixels, draw: (p: Pixels) => void, hold?: number, light?: number, pal?: Uint8Array<ArrayBufferLike>): this;
19
+ /** The picture fading in from black over `n` frames (the last at full light). */
20
+ fadeIn(p: Pixels, n: number, pal?: Uint8Array<ArrayBufferLike>): this;
21
+ /** The last picture fading out to black over `n` frames. */
22
+ fadeOut(n: number): this;
23
+ /**
24
+ * A cartoon's closing iris: black closes in on (cx, cy) over `n` frames from the last picture
25
+ * down to a circle `end` pixels across (round on a 4:3 screen: VGA's pixels are taller than
26
+ * wide), and holds there `hold` frames. Follow it with fadeOut. Gives an intro whose pictures
27
+ * are the title's art a last view that isn't the title.
28
+ */
29
+ irisOut(cx: number, cy: number, n: number, end?: number, hold?: number): this;
30
+ /** The .FLI: `speed` is the wait after each frame in 1/70 s (5 = 14 frames a second). */
31
+ fli(speed: number): Uint8Array;
32
+ /** How long it plays, in seconds. */
33
+ seconds(speed: number): number;
34
+ }
@@ -0,0 +1,84 @@
1
+ import { type CharInfo, type World } from '../../web/src/engine/world.js';
2
+ import { type Block } from '../../web/src/formats/blocks.js';
3
+ import type { Character } from '../../web/src/formats/character.js';
4
+ import type { GameMap } from '../../web/src/formats/map.js';
5
+ import type { Monster } from '../../web/src/formats/monster.js';
6
+ export interface SimScene {
7
+ map: GameMap;
8
+ bbl: Block[];
9
+ mbl?: Block[];
10
+ mon?: Monster[];
11
+ chr: Character;
12
+ cbl: Block[];
13
+ links?: {
14
+ from: {
15
+ x: number;
16
+ y: number;
17
+ };
18
+ to: {
19
+ x: number;
20
+ y: number;
21
+ };
22
+ }[];
23
+ /** Monster names by number (for bots that look for one). */
24
+ names?: string[];
25
+ }
26
+ /** What Sim.snapshot() keeps. */
27
+ interface SimState {
28
+ w: Omit<World, 'sound' | 'rand' | 'joystick' | 'bg' | 'mblk' | 'cblk' | 'mon' | 'palette' | 'chr'>;
29
+ chr: Character;
30
+ randA: number;
31
+ held: number[];
32
+ pending: number[];
33
+ doScroll: boolean;
34
+ sounds: number;
35
+ ticks: number;
36
+ link: number;
37
+ dead: boolean;
38
+ }
39
+ export declare class Sim {
40
+ readonly scene: SimScene;
41
+ readonly w: World;
42
+ private held;
43
+ private doScroll;
44
+ sounds: number[];
45
+ /** Ticks played so far. */
46
+ ticks: number;
47
+ /** Called with every key event (scan, bit 7 = released), e.g. to record a demo. */
48
+ onKey?: (key: number) => void;
49
+ /** Link index reached (-1 = none yet). */
50
+ link: number;
51
+ dead: boolean;
52
+ constructor(scene: SimScene, start: {
53
+ x: number;
54
+ y: number;
55
+ }, ci?: CharInfo, seed?: number,
56
+ /** False for games whose scenes never scroll (one screen each): the scroll window is shut. */
57
+ scroll?: boolean);
58
+ /** kit/pixels.ts rng() (mulberry32), with its state out where a snapshot can keep it. */
59
+ private randA;
60
+ private rand;
61
+ /** Everything that changes as the scene plays, to try a move and take it back with restore(). */
62
+ snapshot(): SimState;
63
+ restore(s: SimState): void;
64
+ press(scan: number): void;
65
+ release(scan: number): void;
66
+ private pending;
67
+ private event;
68
+ /** One 18.2 Hz game tick (8 scroll steps + tick()). */
69
+ tick(): Promise<void>;
70
+ run(ticks: number, each?: (t: number) => void | boolean): Promise<void>;
71
+ /** Live monsters called `name`, with their block positions. */
72
+ monsters(name: string): {
73
+ x: number;
74
+ y: number;
75
+ }[];
76
+ /** Character position in pixels (x of its column, y of its bottom block). */
77
+ get pos(): {
78
+ x: number;
79
+ y: number;
80
+ bx: number;
81
+ by: number;
82
+ };
83
+ }
84
+ export {};
@@ -0,0 +1,11 @@
1
+ import { Pixels } from './pixels.js';
2
+ /** A shade between ramp[lo] and ramp[hi] for level 0..1, ordered-dithered at (x, y). */
3
+ export declare function shadeAt(ramp: number[], lo: number, hi: number, level: number, x: number, y: number): number;
4
+ /** A vertical gradient across a rectangle. */
5
+ export declare function gradient(p: Pixels, x0: number, y0: number, w: number, h: number, ramp: number[], lo: number, hi: number): Pixels;
6
+ /** A lit ellipsoid lump, light from the upper left. */
7
+ export declare function blob(p: Pixels, cx: number, cy: number, rx: number, ry: number, ramp: number[], lo: number, hi: number, light?: number): Pixels;
8
+ /** A raised box: light top/left edge, dark bottom/right edge. */
9
+ export declare function bevel(p: Pixels, x: number, y: number, w: number, h: number, ramp: number[], face: number, depth?: number): Pixels;
10
+ /** Fills a rectangle with a speckled texture from ramp[lo..hi]. */
11
+ export declare function speckle(p: Pixels, x0: number, y0: number, w: number, h: number, ramp: number[], base: number, spread: number, seed: number, density?: number): Pixels;
@@ -0,0 +1,29 @@
1
+ /** A PC speaker sound from a function of step (0..35) → Hz (0 = silence). */
2
+ export declare function speaker(fn: (i: number, t: number) => number): Uint16Array;
3
+ export declare const SPEAKER: {
4
+ rise: (from?: number, to?: number) => Uint16Array<ArrayBufferLike>;
5
+ fall: (from?: number, to?: number) => Uint16Array<ArrayBufferLike>;
6
+ coin: () => Uint16Array<ArrayBufferLike>;
7
+ hurt: () => Uint16Array<ArrayBufferLike>;
8
+ zap: () => Uint16Array<ArrayBufferLike>;
9
+ chirp: () => Uint16Array<ArrayBufferLike>;
10
+ arpeggio: (notes?: number[]) => Uint16Array<ArrayBufferLike>;
11
+ noise: (seed?: number, low?: number, high?: number) => Uint16Array<ArrayBufferLike>;
12
+ warble: (base?: number, depth?: number, speed?: number) => Uint16Array<ArrayBufferLike>;
13
+ };
14
+ /** A synthesizer voice for samples: time (s) → -1..1. */
15
+ export type Synth = (t: number) => number;
16
+ export declare const osc: {
17
+ sine: (hz: number | ((t: number) => number)) => Synth;
18
+ square: (hz: number | ((t: number) => number)) => Synth;
19
+ noise: (seed?: number) => Synth;
20
+ };
21
+ /** Renders `seconds` of a synth through an envelope (attack, decay to 0) as a .VOC. */
22
+ export declare function sample(seconds: number, voice: Synth, opts?: {
23
+ rate?: number;
24
+ attack?: number;
25
+ gain?: number;
26
+ envelope?: (t: number) => number;
27
+ }): Uint8Array;
28
+ /** Mixes synths. */
29
+ export declare const mix: (...voices: [Synth, number][]) => Synth;
@@ -0,0 +1,51 @@
1
+ /** A rectangle as [x0, y0, x1, y1], x1 and y1 exclusive. */
2
+ type Box = [number, number, number, number];
3
+ /** One string that ran past its picture or clip area. */
4
+ export interface TextOverflow {
5
+ s: string;
6
+ /** The picture's size. */
7
+ w: number;
8
+ h: number;
9
+ /** Where the ink was, and the area it had to stay inside. */
10
+ ink: Box;
11
+ area: Box;
12
+ /** The drawing call's source: the game code that drew it, and the code that called that. */
13
+ at: string;
14
+ /** Every call from the game code down to the helper (an outline and its fill differ). */
15
+ via: string;
16
+ /** Characters the 8x8 font draws as an empty box (a curly quote, an accent), if any. */
17
+ missing?: string;
18
+ }
19
+ /** Collects one string's ink as a helper draws it; `end()` checks it against the area. */
20
+ declare class TextInk {
21
+ private readonly w;
22
+ private readonly h;
23
+ private readonly s;
24
+ private readonly area;
25
+ private readonly has;
26
+ private x0;
27
+ private y0;
28
+ private x1;
29
+ private y1;
30
+ constructor(w: number, h: number, s: string, area: Box, has: (ch: string) => boolean);
31
+ /** A lit rectangle of the string (a font pixel, scaled). */
32
+ add(x: number, y: number, w?: number, h?: number): void;
33
+ end(): void;
34
+ }
35
+ /**
36
+ * A recorder for one string drawn on picture `p`, or undefined when the audit is off. `clip`
37
+ * is an area inside the picture the text must keep to (a frame, a sign's face); `has` says
38
+ * which characters the font draws (the PC font's printable ASCII unless a helper says).
39
+ */
40
+ export declare function textInk(p: {
41
+ readonly w: number;
42
+ readonly h: number;
43
+ }, s: string, clip?: Box, has?: (ch: string) => boolean): TextInk | undefined;
44
+ /** One line about an overflow: the string, its ink box, the area and where it was drawn. */
45
+ export declare function describe(o: TextOverflow): string;
46
+ /** Reads a build's TEXT_BOUNDS file: the cut strings, and how many moved. */
47
+ export declare function readBounds(file: string): {
48
+ cut: TextOverflow[];
49
+ moving: TextOverflow[];
50
+ };
51
+ export {};
@@ -0,0 +1,6 @@
1
+ import { type Voice } from './music.js';
2
+ export declare const LEN: Record<string, number>;
3
+ export declare function tune(bpm: number, voices: Voice[]): Uint8Array;
4
+ export declare const v: (channel: number, instrument: Uint8Array, notes: string, velocity?: number, transpose?: number) => Voice;
5
+ export declare const join: (...parts: string[]) => string;
6
+ export declare const times: (n: number, s: string) => string;
@@ -0,0 +1,3 @@
1
+ export * from '../../../src/audio/compose.js';
2
+ export * from '../../../../games/kit/tune.js';
3
+ export * from '../../../../games/kit/sound.js';
@@ -0,0 +1,20 @@
1
+ export type RGB = readonly [number, number, number];
2
+ export type TimeOfDay = 'morning' | 'noon' | 'afternoon' | 'sunset' | 'night' | 'show';
3
+ export interface Lighting {
4
+ readonly mul: RGB;
5
+ readonly add: RGB;
6
+ }
7
+ /** Eight-bit RGB lighting presets; show is warm stage lighting. */
8
+ export declare const TIME_OF_DAY_LIGHT: Readonly<Record<TimeOfDay, Lighting>>;
9
+ /** Eight-bit sky ramp endpoints and optional middle stop, dark to light. */
10
+ export declare const TIME_OF_DAY_SKY: Readonly<Record<TimeOfDay, readonly [RGB, RGB, RGB?]>>;
11
+ /** Light one eight-bit RGB color, rounding and clamping each component. */
12
+ export declare function lightColor(color: RGB, lighting: TimeOfDay | Lighting): [number, number, number];
13
+ /** A pure eight-bit RGB ramp, including both endpoints; a middle stop falls at t=0.5. */
14
+ export declare function colorRamp(count: number, from: RGB, to: RGB, mid?: RGB): [number, number, number][];
15
+ /**
16
+ * Light a native 768-byte, six-bit VGA palette, without changing pixel indexes or the input.
17
+ * Indexes 0 (engine clear color) and 255 (transparent) are preserved by default. Supply
18
+ * your own list to protect glowing ramps, designer colors, or to adjust every entry ([]).
19
+ */
20
+ export declare function adjustPalette(palette: Uint8Array, lighting: TimeOfDay | Lighting, preserve?: readonly number[]): Uint8Array;
@@ -0,0 +1,10 @@
1
+ export * from '../../../../games/kit/pixels.js';
2
+ export * from '../../../../games/kit/palette.js';
3
+ export * from '../../../../games/kit/pcText.js';
4
+ export * from '../../../../games/kit/blit.js';
5
+ export * from '../../../../games/kit/shading.js';
6
+ export * from '../../../../games/kit/textBounds.js';
7
+ export * from '../../../../games/kit/reel.js';
8
+ export { FONT8X8 } from '../../../src/gfx/font8x8.js';
9
+ export * from './text.js';
10
+ export * from './colors.js';
@@ -0,0 +1,2 @@
1
+ export { encodePng, type IndexedPicture } from '../../../src/assistant/png.js';
2
+ export { crc32 } from '../../../src/project/zip.js';
@@ -0,0 +1 @@
1
+ export declare const MICRO_GLYPHS: Readonly<Record<string, string>>;
@@ -0,0 +1,3 @@
1
+ export { Sim, type SimScene } from '../../../../games/kit/sceneSim.js';
2
+ export { GameSim, readDisk, diskSim, TICKS_PER_SECOND } from '../../../../games/kit/gameSim.js';
3
+ export { newCharInfo, type CharInfo } from '../../../src/engine/world.js';
@@ -0,0 +1,41 @@
1
+ import { FONT_CP437 } from '../../../src/gfx/cp437Glyphs.js';
2
+ import { toCp437, fromCp437 } from '../../../src/retro/text/cp437.js';
3
+ import { Pixels } from '../../../../games/kit/pixels.js';
4
+ import { MICRO_GLYPHS } from './microFont.js';
5
+ export { FONT_CP437, toCp437, fromCp437, MICRO_GLYPHS };
6
+ export type TextFont = 'cp437' | 'micro';
7
+ /** Encode Unicode DOS symbols, including box drawing. Unsupported characters throw. */
8
+ export declare function encodeText(s: string): Uint8Array;
9
+ /** A fresh copy of a glyph's rows; bit 0 is the leftmost pixel. */
10
+ export declare function glyphRows(code: number, font?: TextFont): Uint8Array;
11
+ export interface TextOptions {
12
+ font?: TextFont;
13
+ /** Palette index, 0..254; 255 is reserved for transparent pixels. */
14
+ color?: number;
15
+ scale?: number;
16
+ /** A one-output-pixel outline, including diagonal neighbors. */
17
+ outline?: number;
18
+ /** Shadow offset in output pixels, independent of glyph scale. */
19
+ shadow?: {
20
+ color: number;
21
+ dx?: number;
22
+ dy?: number;
23
+ };
24
+ }
25
+ export interface TextImage {
26
+ width: number;
27
+ height: number;
28
+ /** Row-major palette indexes; transparent pixels are 255. */
29
+ pixels: Uint8Array;
30
+ /** Where the unadorned first text cell begins within the image. */
31
+ originX: number;
32
+ originY: number;
33
+ }
34
+ /** Same-size shadowed sprite; pixels beyond the source canvas are clipped. */
35
+ export declare function dropShadow(src: Pixels, ink: number, dx?: number, dy?: number): Pixels;
36
+ /**
37
+ * Render Unicode text (LF/CRLF separated lines) or raw CP437 bytes (one row, including
38
+ * control-code glyphs). Returns native indexed pixels, with enough padding for effects.
39
+ * CP437 cells are 8×8; micro cells are 3×5 plus a 1px gap, with no trailing gap.
40
+ */
41
+ export declare function renderText(text: string | Uint8Array, options?: TextOptions): TextImage;
@@ -0,0 +1,103 @@
1
+ import type { Plugin } from 'vite';
2
+ import type { PrintablesFile } from '../src/manual/printables/types.js';
3
+ import { type Issue } from '../src/project/health.js';
4
+ import { type BoxGame } from '../src/desk/boxes/boxFacts.js';
5
+ export interface CdCatalogEntry {
6
+ id: string;
7
+ title: string;
8
+ kind: 'gameware' | 'shareware';
9
+ /** Folder of the game's files, relative to the site root. */
10
+ path: string;
11
+ gam: string | null;
12
+ files: string[];
13
+ /** Size of each file in `files`, in bytes. */
14
+ sizes: number[];
15
+ /** Shareware: the author's notice (readme / order form), as text. */
16
+ notice?: string;
17
+ /** Shareware: CRC-32 of the .gam file, to recognize the game when imported. */
18
+ gamCrc?: number;
19
+ /** Total size of the game's files in bytes. */
20
+ bytes: number;
21
+ /** Shareware: the name of its DOS program (listed on the retro PC; never served). */
22
+ exe?: string;
23
+ /** A few lines from the game's own story or instruction screen. */
24
+ blurb?: string;
25
+ author?: string;
26
+ company?: string;
27
+ year?: number;
28
+ price?: string;
29
+ /** Original games (../games): the disk label, box art and manual, from about.json. */
30
+ original?: OriginalExtras;
31
+ /** Original games: about.json "series" ("bizarre": The Bard of Bizarre's games, src/project/bizarre.ts). */
32
+ series?: string;
33
+ /** games/catalog.json: the entry has a games/details/<id>.json (see slimCatalog). */
34
+ details?: boolean;
35
+ /** Original games: the site path of the game's walkthrough (../games/<id>/walkthrough.json, src/walkthrough). */
36
+ walkthrough?: string;
37
+ /** Original games: its DOS player look, ../games/<id>/player.json ({ base, patches }: src/dosPlayer/catalogPatches.ts). */
38
+ player?: unknown;
39
+ /** The build drew its pictures (games/shots/<id>-<cols>x<rows>.png, scripts/gameShots.ts). */
40
+ shots?: boolean;
41
+ /** …and its hero (games/shots/<id>-hero.png). */
42
+ heroShot?: boolean;
43
+ /** All its files in one gzipped file in its folder, named by a hash of them (packName, src/project/gamePack.ts). */
44
+ pack?: string;
45
+ /** Built sites: what the home page's quick check finds in it (src/editor/shell/gameHealth.ts), so the page need not fetch files to know. */
46
+ health?: Issue[];
47
+ /** Built sites: the size of its pack in bytes (what downloading it for offline use costs, src/offline). */
48
+ packBytes?: number;
49
+ /** Built sites, games with a box: what the box reads from the .gam (src/desk/boxes/boxFacts.ts). */
50
+ boxGame?: BoxGame;
51
+ }
52
+ /** What ../games/<id>/about.json and manual.json add for an original game. */
53
+ export interface OriginalExtras {
54
+ /** Printed disk label: background, band and text colors, and a small logo line. */
55
+ label?: {
56
+ background: string;
57
+ band: string;
58
+ ink: string;
59
+ logo?: string;
60
+ };
61
+ /** Box art: colors, tagline, back-cover copy, feature bullets and screenshot spots. */
62
+ box?: {
63
+ background: string;
64
+ accent: string;
65
+ ink: string;
66
+ tagline: string;
67
+ back: string;
68
+ features: string[];
69
+ /** Map views for screenshots: [map file, x, y] in blocks. */
70
+ shots?: [string, number, number][];
71
+ rating?: string;
72
+ };
73
+ /** The manual: pages of simple HTML, with <shot map="x.map" x="1" y="2"> screenshots. */
74
+ manual?: {
75
+ title: string;
76
+ pages: {
77
+ head: string;
78
+ html: string;
79
+ }[];
80
+ };
81
+ /** The paper extras in the box (games/<id>/printables.json, see src/manual/printables). */
82
+ printables?: PrintablesFile;
83
+ /** 'sb' games use the Sound Blaster; 'speaker' ones only the PC speaker. */
84
+ sound?: 'sb' | 'speaker';
85
+ }
86
+ export interface GmInstallEntry {
87
+ name: string;
88
+ size: number;
89
+ dir: boolean;
90
+ }
91
+ /**
92
+ * The catalog without what only some pages read (games/catalog.json): a shareware notice,
93
+ * an original game's manual and printables. Those are in games/details/<id>.json. The play
94
+ * page needs only this (and, for shareware, its game's details); games/index.json has it all.
95
+ */
96
+ export declare function slimCatalog(catalog: CdCatalogEntry[]): CdCatalogEntry[];
97
+ /** Every playable game on the CD and in ../games but the secret ones (what games/index.json lists, and every page, sitemap and picture the build makes). */
98
+ export declare function cdCatalog(cdRoot: string): CdCatalogEntry[];
99
+ /** The secret games (games/extra-<gate>.json): listed only once what reveals each is found. */
100
+ export declare function cdSecretCatalog(cdRoot: string): CdCatalogEntry[];
101
+ /** Where each game file the site serves (e.g. games/gameware/nebula/nebula.gam) is on disk. */
102
+ export declare function cdFiles(cdRoot: string): ReadonlyMap<string, string>;
103
+ export declare function cdGames(cdRoot: string): Plugin;
@@ -0,0 +1,12 @@
1
+ import { type HeroSpec, type LevelPicture } from '../src/gfx/levelPicture.js';
2
+ /**
3
+ * A palette PNG of only the colors the picture uses; rows unfiltered (flat pixel art packs best
4
+ * that way). With `transparent`, that palette index is see-through.
5
+ */
6
+ export declare function encodeIndexedPng(pic: LevelPicture, transparent?: number): Uint8Array;
7
+ /**
8
+ * A game's pictures, by site path: each size in BUILT_SHOTS, its title screen (titlePixels),
9
+ * an original game's box views (builtMapViews of its box's `shots`) and its hero (heroOf);
10
+ * none when it has no level to show. `disk` maps a game file's name (as listed) to where it is on disk.
11
+ */
12
+ export declare function gameShots(id: string, gam: string | null, disk: ReadonlyMap<string, string>, boxShots?: [string, number, number][], hero?: HeroSpec): Map<string, Uint8Array>;