@wasm-gaming/rsdkv4-wasm 0.1.5 → 0.2.1

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.
@@ -1,67 +1,184 @@
1
- // Engine-specific options for RSDKv4.
2
- //
3
- // This is the authoritative description of what `EngineConfig.options` accepts
4
- // for this engine. It provides both:
5
- // - `Rsdkv4Options` — the compile-time type (for TS hosts/launchers)
6
- // - `RSDKV4_OPTIONS_SCHEMA` — the JSON Schema mirrored into manifest.json's
7
- // `options` (for runtime host UI + validation)
8
- // - `DEFAULT_RSDKV4_OPTIONS` — defaults the SDK falls back to.
9
- //
10
- // At runtime these options are serialized into RSDKv4's `settings.ini` (see the
11
- // SDK's settings serializer) when the host does not pass an explicit `settings`
12
- // asset.
13
1
  /**
14
- * RSDKv4 reads 255 as "not set" for the starting stage/player (see Userdata.cpp:
15
- * anything else — **including 0** — makes Engine::Init skip the start-menu flow
16
- * and force InitStartingStage). So "boot normally" has to be 255, not 0.
2
+ * What this engine's four payloads accept, and the {@link RSDKV4_SPEC} that describes
3
+ * them to a host.
4
+ *
5
+ * ```ts
6
+ * import type { Rsdkv4Config, Rsdkv4Options } from '@wasm-gaming/rsdkv4-wasm/options';
7
+ * ```
8
+ *
9
+ * The contract's own module documents *how* the four payloads behave — they read as
10
+ * descriptors and write as patches, and `live` says whether a key reaches a running
11
+ * engine. This module is only the part that is RSDKv4's: which keys exist, what they
12
+ * mean here, and what the engine does with them.
13
+ *
14
+ * The split between the first two is the whole design:
15
+ *
16
+ * - {@link Rsdkv4Config} is **the engine**. It is serialized into RSDKv4's
17
+ * `settings.ini` and read once, at boot — so none of it is `live`.
18
+ * - {@link Rsdkv4Options} is **the session**: which character, which save slot, which
19
+ * stage. That is what a `restart()` reopens. It also carries the engine's own GAME
20
+ * OPTIONS rows, which *are* `live` — and which are not declared here at all, because
21
+ * they differ between Sonic 1 and Sonic 2 and are only knowable once the pack is
22
+ * loaded.
23
+ *
24
+ * @module
17
25
  */
18
- export const RSDKV4_UNSET = 255;
19
- export const DEFAULT_RSDKV4_OPTIONS = {
20
- devMenu: false,
21
- engineDebugMode: true,
22
- vsync: true,
23
- skipStartMenu: false,
24
- startingCategory: RSDKV4_UNSET,
25
- startingScene: RSDKV4_UNSET,
26
- startingPlayer: RSDKV4_UNSET,
26
+ /**
27
+ * RSDKv4's fourteen buttons, in the engine's own `InputButtons` order.
28
+ *
29
+ * The order is not cosmetic: it is the bit order of the mask the SDK hands the
30
+ * engine once per tick, so this array is the wire format and not merely a list.
31
+ *
32
+ * Sonic 1 and Sonic 2 read only the four directions, A, B, C and start. The other
33
+ * six exist in the engine and are free for a host to do as it likes with.
34
+ */
35
+ export const RSDKV4_BUTTONS = [
36
+ 'up',
37
+ 'down',
38
+ 'left',
39
+ 'right',
40
+ 'a',
41
+ 'b',
42
+ 'c',
43
+ 'x',
44
+ 'y',
45
+ 'z',
46
+ 'l',
47
+ 'r',
48
+ 'start',
49
+ 'select',
50
+ ];
51
+ /**
52
+ * The engine's own default bindings. See {@link Rsdkv4InputDefaults}.
53
+ *
54
+ * Directions are the arrow keys. This build's `ProcessInput()` also reads `KeyW`,
55
+ * `KeyA`, `KeyS` and `KeyD` as a second set of them, and takes those three scancodes
56
+ * off `x`, `y` and `z` to do it — so the table below is what a *claiming* host should
57
+ * bind, and the engine under SDL polling answers to both.
58
+ *
59
+ * This replaces the old `RSDKV4_KEYMAP`, which nothing read and which was wrong in
60
+ * three ways for want of ever being checked against the engine: it listed 9 of the
61
+ * 14 buttons, and bound `select` to `ShiftLeft` where the engine's default is `Tab`.
62
+ */
63
+ export const RSDKV4_INPUT = {
64
+ keyboard: {
65
+ up: 'ArrowUp',
66
+ down: 'ArrowDown',
67
+ left: 'ArrowLeft',
68
+ right: 'ArrowRight',
69
+ a: 'KeyZ',
70
+ b: 'KeyX',
71
+ c: 'KeyC',
72
+ x: 'KeyA',
73
+ y: 'KeyS',
74
+ z: 'KeyD',
75
+ l: 'KeyQ',
76
+ r: 'KeyE',
77
+ start: 'Enter',
78
+ select: 'Tab',
79
+ },
80
+ gamepad: {
81
+ up: 12,
82
+ down: 13,
83
+ left: 14,
84
+ right: 15,
85
+ a: 0,
86
+ b: 1,
87
+ c: 2,
88
+ x: 3,
89
+ y: 6,
90
+ z: 7,
91
+ l: 4,
92
+ r: 5,
93
+ start: 9,
94
+ select: null,
95
+ },
27
96
  };
28
- export const RSDKV4_OPTIONS_SCHEMA = {
29
- type: 'object',
30
- additionalProperties: false,
31
- properties: {
97
+ /**
98
+ * Everything the engine declares about its own properties, as data.
99
+ *
100
+ * `default` appears here and nowhere else: the contract's base class seeds the
101
+ * starting state from it, so there is no second table of defaults to drift out of
102
+ * agreement with this one — which is exactly what the old
103
+ * `DEFAULT_RSDKV4_OPTIONS`-alongside-a-JSON-Schema pair did.
104
+ *
105
+ * What is missing from `options` is deliberate: `player` and `stage` get their `enum`
106
+ * filled in from the loaded pack, and the GAME OPTIONS rows are added outright, when a
107
+ * running engine is asked to describe itself.
108
+ */
109
+ export const RSDKV4_SPEC = {
110
+ config: {
111
+ vsync: { default: true, live: false, description: 'VSync the engine window.' },
32
112
  devMenu: {
33
- type: 'boolean',
34
113
  default: false,
35
- description: "RSDKv4's native in-canvas Dev Menu. The launcher provides its own overlay via instance.devMenu, so keep this off.",
114
+ live: false,
115
+ description: "RSDKv4's native in-canvas Dev Menu. Hosts draw their own from play.devMenu.",
36
116
  },
37
117
  engineDebugMode: {
38
- type: 'boolean',
39
118
  default: true,
40
- description: 'Enables the web devmenu embind bridge (stage list / warp / pause).',
119
+ live: false,
120
+ description: "Gates the engine's log output. The embind bridges are installed either way.",
41
121
  },
42
- vsync: { type: 'boolean', default: true },
43
- skipStartMenu: {
44
- type: 'boolean',
45
- default: false,
46
- description: "Skip the engine's own save/character/options screens — set it when the host renders them from instance.game.",
122
+ startMenu: {
123
+ default: 'native',
124
+ enum: ['native', 'host'],
125
+ live: false,
126
+ description: "Who draws save/character/options: the engine's own menu, or the host from play.game.",
47
127
  },
48
- startingCategory: {
49
- type: 'integer',
50
- minimum: 0,
51
- default: RSDKV4_UNSET,
52
- description: '0-based stage-list category; 255 = unset (normal boot flow).',
128
+ jsUrl: { live: false, description: 'Emscripten glue URL. Defaults to ./rsdkv4.js.' },
129
+ wasmUrl: { live: false, description: 'WASM URL. Defaults to ./rsdkv4.wasm.' },
130
+ },
131
+ options: {
132
+ // No `default` on any of the three: absence is what "boot normally" means here,
133
+ // and a default would take that away.
134
+ player: {
135
+ live: false,
136
+ description: 'Character for a new game, by name. Choices arrive once the pack is loaded.',
137
+ },
138
+ slot: {
139
+ enum: [null, 0, 1, 2, 3],
140
+ live: false,
141
+ description: 'Save slot 0-3, or null to play without saving.',
142
+ },
143
+ stage: {
144
+ live: false,
145
+ description: 'Jump straight to a stage. Choices arrive once the pack is loaded.',
146
+ },
147
+ // No `default`, for the same reason as the three above: absence is what "the
148
+ // engine polls SDL as usual" means, and only `null` is a release.
149
+ //
150
+ // `live` because it is the one option that reaches a running engine directly
151
+ // rather than through a restart — and the description says the rest out loud,
152
+ // because the contract has no flag for "transient, do not paint, do not
153
+ // persist" and a host reading descriptors to build a settings screen would
154
+ // otherwise put fourteen booleans on it.
155
+ buttons: {
156
+ live: true,
157
+ description: 'Host-driven input: a live object of 14 booleans the engine reads once per tick, or null to hand input back. Transient — not a settings row, not persistable, and it always reads back as null.',
53
158
  },
54
- startingScene: {
55
- type: 'integer',
56
- minimum: 0,
57
- default: RSDKV4_UNSET,
58
- description: '0-based scene in the category; 255 = unset (normal boot flow).',
159
+ },
160
+ assets: {
161
+ data: {
162
+ allowedTypes: ['.rsdk'],
163
+ live: false,
164
+ description: 'The RSDKv4 game data pack. Selects the game; required to start.',
165
+ },
166
+ settings: {
167
+ allowedTypes: ['.ini'],
168
+ live: false,
169
+ description: 'A ready-made settings.ini. Omitted, one is generated from config.',
170
+ },
171
+ },
172
+ storage: {
173
+ namespace: {
174
+ default: 'default',
175
+ live: false,
176
+ description: "Folder for this game's pack, settings and save file.",
59
177
  },
60
- startingPlayer: {
61
- type: 'integer',
62
- minimum: 0,
63
- default: RSDKV4_UNSET,
64
- description: 'Player/character index; 255 = unset (normal boot flow).',
178
+ persist: {
179
+ enum: ['opfs', null],
180
+ live: false,
181
+ description: "'opfs' forces persistence, null keeps nothing, absent auto-detects.",
65
182
  },
66
183
  },
67
184
  };
@@ -1 +1 @@
1
- {"version":3,"file":"rsdkv4.options.js","sourceRoot":"","sources":["../../src/rsdkv4.options.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,qCAAqC;AACrC,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,iEAAiE;AACjE,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,SAAS;AA6BT;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAEhC,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,OAAO,EAAE,KAAK;IACd,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,IAAI;IACX,aAAa,EAAE,KAAK;IACpB,gBAAgB,EAAE,YAAY;IAC9B,aAAa,EAAE,YAAY;IAC3B,cAAc,EAAE,YAAY;CAC7B,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAe;IAC/C,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,WAAW,EACT,mHAAmH;SACtH;QACD,eAAe,EAAE;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,oEAAoE;SAClF;QACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;QACzC,aAAa,EAAE;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,WAAW,EACT,8GAA8G;SACjH;QACD,gBAAgB,EAAE;YAChB,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,8DAA8D;SAC5E;QACD,aAAa,EAAE;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,gEAAgE;SAC9E;QACD,cAAc,EAAE;YACd,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,yDAAyD;SACvE;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"rsdkv4.options.js","sourceRoot":"","sources":["../../src/rsdkv4.options.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,70 @@
1
- import type { EngineConfig, EngineInstance, AssetData } from '@wasm-gaming/engine-specs';
2
- import { manifest } from './rsdkv4.manifest.js';
3
- export { manifest };
4
- /** RSDKv4-specific bridge for the launcher's debug/stage-select UI. */
1
+ /**
2
+ * The engine package's entry point: an `EngineSDK` for RSDKv4.
3
+ *
4
+ * ```ts
5
+ * import Rsdkv4SDK from '@wasm-gaming/rsdkv4-wasm';
6
+ *
7
+ * const play = await new Rsdkv4SDK()
8
+ * .mount(document.querySelector('#stage'))
9
+ * .assets({ data: () => library.readBytes('Sonic2') })
10
+ * .storage({ namespace: 'rsdkv4/Sonic2' })
11
+ * .config({ startMenu: 'host' })
12
+ * .on('saves', ({ detail }) => paintSlots(detail))
13
+ * .start({ slot: 0 });
14
+ * ```
15
+ *
16
+ * Everything a host drives is the contract's, and documented there: the four payloads
17
+ * with their descriptors, `mount`, `on`/`off`, `start`, `restart`, `destroy`. What is
18
+ * this engine's own lives in two places — {@link Rsdkv4Config} and friends, which say
19
+ * what the payloads accept *here*, and the extra members of {@link Rsdkv4Play} below:
20
+ * {@link Rsdkv4Play.game} and {@link Rsdkv4Play.devMenu}, for a host that draws
21
+ * RSDKv4's start screens itself, owner-aware {@link Rsdkv4Play.pause}, and
22
+ * {@link Rsdkv4Play.input}, for a host that would rather drive the buttons than let
23
+ * the engine read the keyboard.
24
+ *
25
+ * One game-agnostic `rsdkv4.wasm` runs both Sonic 1 and Sonic 2 — the difference is
26
+ * only which `Data.rsdk` the host hands over in `assets.data`, written into the
27
+ * filesystem at runtime (not baked with `--preload-file`).
28
+ *
29
+ * Filesystem: built with `-sWASMFS`. The working dir is mounted on **OPFS** when the
30
+ * page is cross-origin isolated *and* the build can create the OPFS backend from the
31
+ * main thread (an Asyncify/JSPI build — today's is not, see `WebFS.cpp`); otherwise it
32
+ * falls back to the WASMFS in-memory backend, which boots fine but forgets everything.
33
+ * That fallback is why the SDK mirrors `SData.bin` into OPFS itself: see
34
+ * {@link Rsdkv4Storage.persist}.
35
+ *
36
+ * @module
37
+ * @see [The engine contract](https://wasm-gaming.github.io/engine-specs/api-docs/)
38
+ */
39
+ import { EnginePlayBase, EngineSDKBase, EventEmitter } from '@wasm-gaming/engine-specs';
40
+ import type { EngineInit, EngineSDKConstructor, EventsOf, PayloadKind, PromisePlay, PropertiesDefinition } from '@wasm-gaming/engine-specs';
41
+ import { type Rsdkv4Buttons, type Rsdkv4Options, type Rsdkv4Payloads, type RsdkSaveSlot } from './rsdkv4.options.js';
42
+ export type { Rsdkv4Asset, Rsdkv4AssetData, Rsdkv4Assets, Rsdkv4Button, Rsdkv4Buttons, Rsdkv4Config, Rsdkv4Events, Rsdkv4InputDefaults, Rsdkv4Options, Rsdkv4Payloads, Rsdkv4Stage, Rsdkv4Storage, RsdkSaveSlot, } from './rsdkv4.options.js';
43
+ export { RSDKV4_BUTTONS, RSDKV4_INPUT, RSDKV4_SPEC } from './rsdkv4.options.js';
44
+ /** The core events unioned with this engine's own — what `on`/`off` accept. */
45
+ export type Rsdkv4Events_ = EventsOf<Rsdkv4Payloads>;
46
+ /**
47
+ * The picture's native size, which is what the SDK scales to fit its mount.
48
+ *
49
+ * A module constant rather than a manifest field: `EngineManifest` left the contract
50
+ * in 0.3.0, and this was one of only two things the SDK ever read back out of it.
51
+ */
52
+ export declare const RSDKV4_VIDEO: {
53
+ readonly baseWidth: 424;
54
+ readonly baseHeight: 240;
55
+ readonly aspect: "16:9";
56
+ };
57
+ /**
58
+ * A screen of RSDKv4's own in-canvas Dev Menu (Debug.cpp), as {@link
59
+ * RsdkDevMenuBridge.open} names them.
60
+ *
61
+ * `'categories'` is the engine's `SELECT A STAGE LIST` — PRESENTATION / REGULAR /
62
+ * SPECIAL / BONUS — and `'stages'` the scene list under one of them. Those two are the
63
+ * only native way to reach the BONUS list: the packs' own menu scenes (Sonic 1 and 2's
64
+ * `LEVEL SELECT` and `STAGE MENU`) can load a regular stage and nothing else.
65
+ */
66
+ export type RsdkDevMenuScreen = 'main' | 'player' | 'categories' | 'stages';
67
+ /** RSDKv4-specific bridge for a host's debug/stage-select UI. */
5
68
  export interface RsdkDevMenuBridge {
6
69
  getStageList(): Array<{
7
70
  name: string;
@@ -11,24 +74,35 @@ export interface RsdkDevMenuBridge {
11
74
  }>;
12
75
  loadStage(categoryIdx: number, stageIdx: number): void;
13
76
  setPaused(paused: boolean): void;
77
+ /**
78
+ * Whether the loaded wasm carries {@link open}. False means an engine built before
79
+ * the bridge existed — a host should hide the button rather than offer a dead one.
80
+ */
81
+ readonly canOpen: boolean;
82
+ /**
83
+ * Open the engine's own Dev Menu at `screen`, with `category` selecting the stage
84
+ * list for `'categories'` (preselected) and `'stages'` (listed). Categories are the
85
+ * engine's own indices, the ones {@link getStageList} is ordered by — 2 is BONUS.
86
+ *
87
+ * This is what Escape does natively: the request is handed to the engine thread
88
+ * (`ENGINE_INITDEVMENU`) and the menu comes up on its next frame, so **the running
89
+ * stage is torn down** — `initDevMenu()` clears graphics and animation data. Save
90
+ * files are untouched; the current run is not.
91
+ *
92
+ * The menu is driven by the engine's own input and does not run while the SDK holds
93
+ * a pause, so resume before calling. Returns false when the engine cannot be reached
94
+ * or the wasm predates the bridge ({@link canOpen}).
95
+ */
96
+ open(screen?: RsdkDevMenuScreen, category?: number): boolean;
14
97
  }
15
- /** One of RSDKv4's four save slots, as the engine's own save-select screen sees it. */
16
- export interface RsdkSaveSlot {
17
- /** 0-3. */
18
- slot: number;
19
- /** No game stored here — starting it means picking a character first. */
20
- empty: boolean;
21
- /** Character index into `players()`: 0 Sonic, 1 Tails, 2 Knuckles, 3 Sonic & Tails. */
22
- character: number;
23
- lives: number;
24
- score: number;
25
- emeralds: number;
26
- /** Stage list the save resumes into (1 regular, 3 special), or -1 when empty. */
27
- list: number;
28
- /** 0-based scene within `list` — index it against `devMenu.getStageList()`. */
29
- zone: number;
30
- }
31
- /** A row of the engine's GAME OPTIONS screen (differs between Sonic 1 and 2). */
98
+ /**
99
+ * A row of the engine's GAME OPTIONS screen (differs between Sonic 1 and 2), as the
100
+ * engine reports it — with `value` as the raw number it stores.
101
+ *
102
+ * The same rows also come back through `play.options()` as descriptors, where a
103
+ * boolean row reads as a boolean and an enum row as one of its choice labels. This is
104
+ * the untranslated view, for a host that wants it.
105
+ */
32
106
  export interface RsdkGameOption {
33
107
  key: string;
34
108
  label: string;
@@ -39,8 +113,8 @@ export interface RsdkGameOption {
39
113
  }
40
114
  /**
41
115
  * The engine's Start Menu as data, so a host can render save-slot / character /
42
- * game-option screens itself. Everything here mirrors what RSDKv4's own in-canvas
43
- * menu does — see WebGame.cpp.
116
+ * game-option screens itself. Everything here mirrors what RSDKv4's own in-canvas menu
117
+ * does — see WebGame.cpp.
44
118
  */
45
119
  export interface RsdkGameBridge {
46
120
  /** 1 = Sonic 1, 2 = Sonic 2, 0 = unrecognised pack. */
@@ -49,9 +123,12 @@ export interface RsdkGameBridge {
49
123
  players(): string[];
50
124
  saveSlots(): RsdkSaveSlot[];
51
125
  /**
52
- * Start a game the way the native menu would: a slot with data continues it,
53
- * an empty slot starts a new game as `player`, and `slot: null` plays without
54
- * saving. Resumes the engine if the SDK had it paused.
126
+ * Start a game the way the native menu would: a slot with data continues it, an
127
+ * empty slot starts a new game as `player`, and `slot: null` plays without saving.
128
+ * Resumes the engine if the SDK had it paused.
129
+ *
130
+ * This is the index-taking form. `play.restart({ slot, player })` is the same thing
131
+ * through the contract, with the character named rather than numbered.
55
132
  */
56
133
  start(slot: number | null, player?: number): void;
57
134
  /** Wipe a slot back to "NEW GAME". */
@@ -60,48 +137,166 @@ export interface RsdkGameBridge {
60
137
  /** Set an option; written through to the engine and its save file, as the engine does. */
61
138
  setOption(key: string, value: number): void;
62
139
  }
63
- export type Rsdkv4Instance = Omit<EngineInstance, 'pause' | 'resume'> & {
140
+ /**
141
+ * Input ownership, named — the same thing as `options({ buttons })` and
142
+ * `options({ buttons: null })`, for a host that would rather say what it means.
143
+ *
144
+ * See {@link Rsdkv4Options.buttons} for what a claim costs the host: keyup on focus
145
+ * loss, the gamepad, and remembering to release.
146
+ */
147
+ export interface RsdkInputBridge {
64
148
  /**
65
- * Pause, on behalf of `owner` (default 'host'). The first caller to pause owns
66
- * it and only that owner's `resume()` lifts it, so a pause overlay can't
67
- * resume a game a start screen — or the host — had already frozen. Audio stops
68
- * with the engine.
149
+ * Take input over. The object is kept by reference and read once per tick — write
150
+ * to it, do not replace it.
151
+ *
152
+ * All fourteen keys of {@link Rsdkv4Buttons} must be present and nothing else may
153
+ * be: a missing key would read `false` for ever, and a misspelled one would be
154
+ * written to and never read. Both throw here instead.
69
155
  */
70
- pause(owner?: string): void;
71
- resume(owner?: string): void;
72
- devMenu: RsdkDevMenuBridge;
73
- game: RsdkGameBridge;
74
- /** True when the working dir is OPFS-backed (persistent) rather than in-memory. */
75
- persistent: boolean;
76
- /** Relative storage namespace used under /data (e.g. "sonic1", "sonic2"). */
77
- storageNamespace: string;
78
- /** Remove persisted game files for this namespace only. */
79
- purgeStorage(): {
80
- data: boolean;
81
- settings: boolean;
82
- };
83
- };
156
+ claim(buttons: Rsdkv4Buttons): PromisePlay<Rsdkv4Payloads>;
157
+ /** Hand input back; the engine polls SDL again from the next tick. */
158
+ release(): PromisePlay<Rsdkv4Payloads>;
159
+ /** Whether a claim is held. The `options()` descriptor deliberately will not say. */
160
+ readonly claimed: boolean;
161
+ /**
162
+ * What the engine has held **right now**, as the bitmask a claim writes: bit 0 is
163
+ * `up`, bit 13 is `select`, in {@link RSDKV4_BUTTONS} order.
164
+ *
165
+ * This is the read-back to the claim's write, and it answers the one question no
166
+ * amount of listening on the page can: *did the button reach the engine?* A key
167
+ * that fires `keydown` in the browser and never lights a bit here died between SDL
168
+ * and `ProcessInput()`; one that lights the bit and changes nothing on screen was
169
+ * received and the game chose not to act on it. Those two are otherwise the same
170
+ * silence, and telling them apart is the difference between a real input bug and
171
+ * Sonic simply refusing to roll while a direction is held.
172
+ *
173
+ * Works whether or not a claim is held — under SDL polling it is the keyboard and
174
+ * the pad as the engine read them. `0` when the engine is not up.
175
+ *
176
+ * Two things it is not. It is `hold`, not `press`: a button reads the same on the
177
+ * frame it goes down and on the hundredth frame it stays down. And it is the
178
+ * engine's view *after* the B→A fold, so in-stage the jump key `x` lights `a` and
179
+ * `b` never lights at all — which is the fold working, not a lost button.
180
+ */
181
+ readonly mask: number;
182
+ /**
183
+ * {@link mask}, spelled as the fourteen named booleans — the same shape a claim
184
+ * hands over, so a host can diff what it sent against what arrived.
185
+ *
186
+ * A fresh object on every read; it is a snapshot, not a live view.
187
+ */
188
+ readonly held: Rsdkv4Buttons;
189
+ }
84
190
  /**
85
- * Extra (engine-specific) config on top of the contract's EngineConfig: lazy asset
86
- * providers, invoked only on a cache miss — e.g. to skip a large Data.rsdk fetch
87
- * when it's already persisted in OPFS.
191
+ * What `start()` and `restart()` hand back: the contract's chainable promise, narrowed
192
+ * so that awaiting it gives this engine's {@link Rsdkv4Play} rather than the contract's
193
+ * `EnginePlay` — which is what puts {@link Rsdkv4Play.game} within reach without a cast.
194
+ *
195
+ * Chaining (`.mount(…)`, `.options(…)`) returns the contract's own `PromisePlay`, so
196
+ * put the `await` at the end of the chain to keep the narrowing.
88
197
  */
89
- export type Rsdkv4LoadConfig = EngineConfig & {
90
- dataProvider?: () => Promise<AssetData> | AssetData;
91
- settingsProvider?: () => Promise<AssetData> | AssetData;
198
+ export interface Rsdkv4Session extends PromisePlay<Rsdkv4Payloads> {
199
+ then<TResult1 = Rsdkv4Play, TResult2 = never>(onfulfilled?: ((value: Rsdkv4Play) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
200
+ }
201
+ /**
202
+ * The running engine.
203
+ *
204
+ * Most of it is the contract's, inherited: the four getter/setter pairs, the cumulative
205
+ * merge, the chainable promise, the event channel, and `destroy()`. What this class
206
+ * adds is the four hooks the base leaves to an engine — {@link open}, {@link close},
207
+ * {@link mounted}, {@link patched} — plus the members below, which have no contract
208
+ * equivalent and exist because RSDKv4 has a start menu worth drawing from HTML.
209
+ */
210
+ export declare class Rsdkv4Play extends EnginePlayBase<Rsdkv4Payloads> {
211
+ #private;
212
+ constructor(init?: EngineInit<Rsdkv4Payloads>, events?: EventEmitter<Rsdkv4Events_>);
92
213
  /**
93
- * Per-game storage folder under /data used for OPFS/WASMFS files.
94
- * Examples: "sonic1", "sonic2", "my-pack/v1".
214
+ * Open or reopen a session. The first call brings the wasm up; every call after that
215
+ * reuses it, because RSDKv4 cannot power-cycle in process and does not need to — a
216
+ * session is a save slot, a character and a stage, and all three are reachable on a
217
+ * running engine.
95
218
  */
96
- storageNamespace?: string;
97
- /** Deprecated alias for `canvasEl`, kept for hosts written against 0.0.x. */
98
- canvas?: HTMLCanvasElement;
99
- };
100
- /** Boot the RSDKv4 engine. */
101
- export declare function load(config: Rsdkv4LoadConfig): Promise<Rsdkv4Instance>;
102
- declare const _default: {
103
- manifest: import("@wasm-gaming/engine-specs").EngineManifest;
104
- load: typeof load;
105
- };
106
- export default _default;
219
+ protected open(options: Rsdkv4Options): Promise<void>;
220
+ /**
221
+ * Stop and release. The base emits `exit` once this resolves.
222
+ *
223
+ * There is no coming back: RSDKv4 cannot be restarted in process, so a later
224
+ * `start()` on the same factory reports that rather than quietly doing nothing.
225
+ */
226
+ protected close(): Promise<void>;
227
+ /**
228
+ * Where the picture goes. Called by the base before the first `open()`, which is what
229
+ * guarantees the canvas exists before Emscripten's SDL2 port goes looking for it.
230
+ *
231
+ * Hand over a `<canvas>` and it is used as-is, untouched apart from the id SDL needs;
232
+ * hand over any other element and the SDK creates a canvas inside it and keeps it
233
+ * scaled to fit. Reparenting a live engine is legal — the same canvas moves.
234
+ */
235
+ protected mounted(target: HTMLElement): Promise<void>;
236
+ /**
237
+ * A payload changed on a running engine. Only the GAME OPTIONS rows are `live` here —
238
+ * `config` is `settings.ini`, read once at boot, and `player`/`slot`/`stage` are what
239
+ * a `restart()` is for.
240
+ */
241
+ protected patched(kind: PayloadKind, patch: object): Promise<void>;
242
+ /**
243
+ * The session's descriptors, enriched with what only a loaded pack can say: the
244
+ * playable characters, the stage list, and the engine's own GAME OPTIONS rows.
245
+ *
246
+ * The base builds descriptors from a spec fixed at construction, which is right for
247
+ * every other payload and cannot work for this one — Sonic 1 and Sonic 2 do not offer
248
+ * the same characters or the same options, and neither is knowable before
249
+ * `Data.rsdk` is read. Before the engine is up this answers the static spec, which is
250
+ * still enough for a host to know the keys exist.
251
+ */
252
+ options(): Promise<PropertiesDefinition<Rsdkv4Options>>;
253
+ options(patch: Partial<Rsdkv4Options>): PromisePlay<Rsdkv4Payloads>;
254
+ restart(options?: Partial<Rsdkv4Options>): Rsdkv4Session;
255
+ /**
256
+ * Pause, on behalf of `owner`. The first caller to pause owns it and only that
257
+ * owner's `resume()` lifts it, so a pause overlay cannot resume a game a start
258
+ * screen — or the host — had already frozen. Audio stops with the engine.
259
+ *
260
+ * Emits the contract's `pause` event, whose detail carries the owner.
261
+ */
262
+ pause(owner?: string): void;
263
+ resume(owner?: string): void;
264
+ /** Who is holding the engine paused, or null. */
265
+ get pausedBy(): string | null;
266
+ /** True when the working dir is OPFS-backed rather than in-memory. */
267
+ get persistent(): boolean;
268
+ /** The normalised {@link Rsdkv4Storage.namespace} this session actually used. */
269
+ get namespace(): string;
270
+ /**
271
+ * Input ownership, named. `play.input.claim(buttons)` and `play.input.release()`
272
+ * are exactly `options({ buttons })` and `options({ buttons: null })` — same state,
273
+ * same survival across `restart()`, same everything.
274
+ */
275
+ get input(): RsdkInputBridge;
276
+ /** RSDKv4's Start Menu as data. Available once the engine is up. */
277
+ get game(): RsdkGameBridge;
278
+ /** The engine's stage list and loader. Available once the engine is up. */
279
+ get devMenu(): RsdkDevMenuBridge;
280
+ }
281
+ /**
282
+ * The factory a host imports: identity on the constructor, one live engine per
283
+ * instance, and a `start()` that brings the wasm up and opens a session.
284
+ *
285
+ * Everything on it is the contract's — see the module doc for the shape of a call.
286
+ */
287
+ export declare class Rsdkv4SDK extends EngineSDKBase<Rsdkv4Payloads> {
288
+ static readonly id = "rsdkv4";
289
+ /** Kept in step with package.json by `node scripts/sync-version.mjs`. */
290
+ static readonly version = "0.2.1";
291
+ static readonly name = "Retro Software Development Kit v4";
292
+ static readonly description = "RSDKv4 compiled to WebAssembly via Emscripten. One game-agnostic WASM binary runs both Sonic 1 and Sonic 2 \u2014 the difference is only which Data.rsdk the host supplies at runtime. Ships none of the game: the player provides their own Data.rsdk, and it never leaves their browser.";
293
+ protected createPlay(init: EngineInit<Rsdkv4Payloads>, events: EventEmitter<Rsdkv4Events_>): Rsdkv4Play;
294
+ start(options?: Partial<Rsdkv4Options>): Rsdkv4Session;
295
+ }
296
+ /**
297
+ * The line that puts the contract in CI: if this file stops satisfying
298
+ * `EngineSDKConstructor`, `make typecheck` says so.
299
+ */
300
+ export declare const RSDKV4_ENGINE: EngineSDKConstructor<Rsdkv4Payloads>;
301
+ export default Rsdkv4SDK;
107
302
  //# sourceMappingURL=rsdkv4.sdk.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rsdkv4.sdk.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.sdk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rsdkv4.sdk.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.sdk.ts"],"names":[],"mappings":"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"}