Skip to main content

gasm/
sys.rs

1//! Raw ABI. On wasm32 these are the real imports (see spec/ABI.md). On other
2//! targets they are backed by [`crate::native`], an in-process stub host used
3//! for native parity tests and benchmarks.
4//!
5//! GENERATED from spec/abi.json by scripts/gen-abi.mjs. Do not edit by hand.
6
7#![allow(clippy::missing_safety_doc)]
8
9#[cfg(target_arch = "wasm32")]
10mod imports {
11    #[link(wasm_import_module = "gasm")]
12    unsafe extern "C" {
13        /// Write a line to the runner's log.
14        pub fn log(msg: *const u8, msg_len: u32);
15        /// 1 if the runner provides an import module ("gasm:gfx") or a function in one ("gasm.asset_size64", "gasm:gfx.destroy"), else 0. Calling an import the runner lacks traps, so probe optional features first.
16        pub fn has(name: *const u8, name_len: u32) -> i32;
17        /// Monotonic time in milliseconds (virtual, frame-derived in headless runs).
18        pub fn time_ms() -> f64;
19        /// How many worker threads this run lets the game start at once (wasi-threads: thread-spawn); 0 when it allows none (headless runs, browsers), so a game sizes its thread pool from it instead of failing to spawn.
20        pub fn max_threads() -> u32;
21        /// The player's time zone now: minutes east of UTC, daylight saving included (120 for CEST, -300 for EST). 0 in headless runs. Local time is the WASI realtime clock plus this offset.
22        pub fn utc_offset_minutes() -> i32;
23        /// Rate (Hz) at which the runner calls gasm_frame(). Default 60; 1-1000.
24        pub fn set_frame_rate(hz: f64);
25        /// Present RGBA8 pixels (bytes R,G,B,A), stride bytes per row, w,h <= 4096. Copied before returning; letterboxed by the runner.
26        pub fn video_present(rgba: *const u8, width: u32, height: u32, stride: u32);
27        /// Show video_present frames at display aspect num:den (4:3 for 320x200 DOS games) instead of square pixels; 0:0 resets. Both 1..65535 with 1/8 <= num/den <= 8, else traps. Display and the pointer frame position only (not hashed). Newer than has: probe has("gasm.video_set_aspect") first.
28        pub fn video_set_aspect(num: u32, den: u32);
29        /// Format for audio_push: 8-192 kHz, 1 or 2 channels. Default 44100/2.
30        pub fn audio_config(sample_rate: u32, channels: u32);
31        /// Queue frames x channels interleaved f32 samples in [-1, 1]; the runner resamples.
32        pub fn audio_push(samples: *const f32, frames: u32);
33        /// Bitmask of GASM_BTN_* held on virtual pad player (0..3), stable within a frame.
34        pub fn input_pad(player: u32) -> u32;
35        /// UTF-8 text typed since the previous frame (backspace = \b, enter = \n), stable within a frame. Returns its length (copied only if length <= cap; cap = 0 queries), or -1 if the runner has no keyboard.
36        pub fn text_input(dst: *mut u8, cap: u32) -> i32;
37        /// GASM_INPUT_* flags: KEYS_RAW (the runner stops mapping the keyboard to pads; gamepads still map), POINTER_HIDDEN (hide the system cursor over the game), POINTER_LOCKED (capture the pointer for relative motion; best effort, the browser needs a click).
38        pub fn input_mode(flags: u32);
39        /// Held keys as a bitset indexed by GASM_KEY_* (bit k%8 of byte k/8), stable within a frame. Copies min(len, GASM_KEY_STATE_BYTES) bytes; returns GASM_KEY_STATE_BYTES, or -1 if the runner has no keyboard.
40        pub fn key_state(dst: *mut u8, len: u32) -> i32;
41        /// Key presses and releases since the previous frame, in order: 4 bytes each (u16 GASM_KEY_* code, u8 1 = down / 0 = up, u8 0). Returns the byte length (copied only if <= cap; cap = 0 queries), or -1 if the runner has no keyboard.
42        pub fn key_events(dst: *mut u8, cap: u32) -> i32;
43        /// Mouse/touch state for this frame as GASM_POINTER_BYTES bytes (see ABI.md: position in drawable and frame pixels, relative motion, wheel, buttons held/pressed/released, flags). Copied only if cap is large enough; returns GASM_POINTER_BYTES, or -1 if the runner has no pointer.
44        pub fn pointer(dst: *mut u8, cap: u32) -> i32;
45        /// Raw gamepad/joystick in slot 0-3 (connection order) as GASM_GAMEPAD_BYTES bytes: u32 flags (GASM_GAMEPAD_CONNECTED, GASM_GAMEPAD_STANDARD), u32 button count, u32 axis count, f32 buttons[32] (0-1), f32 axes[16] (-1..1). Standard mapping: W3C button and axis order. Copied only if cap is large enough; returns GASM_GAMEPAD_BYTES, or -1 if slot > 3 or the runner has no gamepad support.
46        pub fn gamepad(slot: u32, dst: *mut u8, cap: u32) -> i32;
47        /// Device name of the gamepad in slot: its length (copied only if <= cap), or -1 if the slot is empty.
48        pub fn gamepad_name(slot: u32, dst: *mut u8, cap: u32) -> i32;
49        /// Size in bytes of asset name, -1 if it does not exist, or -2 if it is 2 GiB or larger (use asset_size64).
50        pub fn asset_size(name: *const u8, name_len: u32) -> i32;
51        /// Size in bytes of asset name (any size), or -1 if it does not exist.
52        pub fn asset_size64(name: *const u8, name_len: u32) -> i64;
53        /// Copy up to cap bytes of asset name into dst. Bytes copied, or -1 if missing.
54        pub fn asset_read(name: *const u8, name_len: u32, dst: *mut u8, cap: u32) -> i32;
55        /// Copy up to len bytes of asset name starting at offset (streaming). Bytes copied (0 at the end), or -1 if missing.
56        pub fn asset_read_at(name: *const u8, name_len: u32, offset: u32, dst: *mut u8, len: u32) -> i32;
57        /// asset_read_at with a 64-bit offset, for assets of 4 GiB and more.
58        pub fn asset_read_at64(name: *const u8, name_len: u32, offset: u64, dst: *mut u8, len: u32) -> i32;
59        /// Number of assets.
60        pub fn asset_count() -> u32;
61        /// Name of asset index (0 .. asset_count-1, sorted by UTF-8 bytes; folder entries as named on disk). Its length (copied only if length <= cap; cap = 0 queries), or -1 if index is out of range.
62        pub fn asset_name(index: u32, dst: *mut u8, cap: u32) -> i32;
63        /// Version of asset name, -1 if it does not exist: 0 for assets given at launch, a new, larger number each time the embedder replaces it while the game runs (between frames). Poll it to notice new data; a read spanning frames should check it did not change.
64        pub fn asset_version(name: *const u8, name_len: u32) -> i32;
65        /// Launch parameter value length, or -1 if unset. Copied only if length <= cap (cap = 0 queries the length).
66        pub fn param(name: *const u8, name_len: u32, dst: *mut u8, cap: u32) -> i32;
67        /// Name the game's window or tab (the runner adds its own suffix). Control characters and bidi overrides are removed and the rest is cut to 256 bytes; empty resets to the default. Newer than has: probe has("gasm.set_title") first.
68        pub fn set_title(title: *const u8, title_len: u32);
69        /// Ask to show the game fullscreen (on = 1) or in its window (0), after this frame. Returns 1 if this runner can show it fullscreen (a window, the browser player), 0 if not (headless runs): what it got is is_fullscreen, a frame or more later. Going fullscreen needs a key press or click in the last 5 seconds (as browsers require); leaving never does. Newer than has: probe has("gasm.set_fullscreen") first.
70        pub fn set_fullscreen(on: u32) -> i32;
71        /// 1 while the game is shown fullscreen (set_fullscreen, or the player's own keys: F11, Alt+Enter), else 0; always 0 in headless runs. Newer than has: probe has("gasm.is_fullscreen") first.
72        pub fn is_fullscreen() -> u32;
73        /// End the frame inside gasm_run: the runner suspends the guest and resumes it at the start of the next frame. Traps outside gasm_run (and on runners without stack switching: probe has("gasm.yield_frame")).
74        pub fn yield_frame();
75    }
76
77    #[link(wasm_import_module = "gasm:gfx")]
78    unsafe extern "C" {
79        /// Current drawable width in pixels.
80        #[link_name = "width"]
81        pub fn gfx_width() -> u32;
82        /// Current drawable height in pixels.
83        #[link_name = "height"]
84        pub fn gfx_height() -> u32;
85        /// Compile WGSL source.
86        #[link_name = "create_shader"]
87        pub fn gfx_create_shader(wgsl: *const u8, wgsl_len: u32) -> u32;
88        /// size: non-zero multiple of 4; usage: GASM_BUF_* (WebGPU GPUBufferUsage bits; COPY_DST always added).
89        #[link_name = "create_buffer"]
90        pub fn gfx_create_buffer(size: u32, usage: u32) -> u32;
91        /// GPURenderPipelineDescriptor as JSON. layout: "auto" (default) or an array of bind group layout handles.
92        #[link_name = "create_pipeline"]
93        pub fn gfx_create_pipeline(json: *const u8, json_len: u32) -> u32;
94        /// {"layout":L,"entries":[...]} or {"pipeline":P,"group":G,"entries":[...]}; entries {"binding":B,"buffer":H,"offset":O,"size":S}, {"binding":B,"texture":T} or {"binding":B,"sampler":S}.
95        #[link_name = "create_bind_group"]
96        pub fn gfx_create_bind_group(json: *const u8, json_len: u32) -> u32;
97        /// GPUBindGroupLayoutDescriptor subset: {"entries":[{"binding":B,"visibility":GASM_STAGE_*,"buffer":{"type":"uniform"|"read-only-storage","hasDynamicOffset":bool,"minBindingSize":N} | "texture":{"sampleType":"float"|"unfilterable-float","viewDimension":"2d"} | "sampler":{"type":"filtering"|"non-filtering"}}]}.
98        #[link_name = "create_bind_group_layout"]
99        pub fn gfx_create_bind_group_layout(json: *const u8, json_len: u32) -> u32;
100        /// 2D texture: {"size":[w,h],"format":"rgba8unorm"|"rgba8unorm-srgb","mipLevelCount":n}, w,h 1-8192. Usage is TEXTURE_BINDING | COPY_DST.
101        #[link_name = "create_texture"]
102        pub fn gfx_create_texture(json: *const u8, json_len: u32) -> u32;
103        /// Upload a tightly packed RGBA8 region (len = width*height*4) of mip level mip at (x, y). Queued like write_buffer.
104        #[link_name = "write_texture"]
105        pub fn gfx_write_texture(texture: u32, mip: u32, x: u32, y: u32, width: u32, height: u32, data: *const u8, len: u32);
106        /// GPUSamplerDescriptor subset: addressModeU/V, magFilter, minFilter, mipmapFilter, lodMinClamp, lodMaxClamp, maxAnisotropy (1-16).
107        #[link_name = "create_sampler"]
108        pub fn gfx_create_sampler(json: *const u8, json_len: u32) -> u32;
109        /// Queue a write, applied before the frame's draws. offset/len: multiples of 4.
110        #[link_name = "write_buffer"]
111        pub fn gfx_write_buffer(buffer: u32, offset: u32, data: *const u8, len: u32);
112        /// Start the frame (clears color and depth). 1 = will be shown, 0 = discarded (the guest may skip draws).
113        #[link_name = "begin_frame"]
114        pub fn gfx_begin_frame(r: f32, g: f32, b: f32, a: f32) -> u32;
115        #[link_name = "set_pipeline"]
116        pub fn gfx_set_pipeline(pipeline: u32);
117        #[link_name = "set_bind_group"]
118        pub fn gfx_set_bind_group(index: u32, bind_group: u32);
119        /// set_bind_group with count dynamic offsets (multiples of 256), one per dynamic-offset entry of the layout, in binding order.
120        #[link_name = "set_bind_group_offsets"]
121        pub fn gfx_set_bind_group_offsets(index: u32, bind_group: u32, offsets: *const u32, count: u32);
122        /// Viewport in drawable pixels (clamped to the drawable), depth range 0-1. Reset to the whole drawable by begin_frame.
123        #[link_name = "set_viewport"]
124        pub fn gfx_set_viewport(x: f32, y: f32, width: f32, height: f32, min_depth: f32, max_depth: f32);
125        /// Scissor rectangle in drawable pixels (clamped to the drawable). Reset to the whole drawable by begin_frame.
126        #[link_name = "set_scissor_rect"]
127        pub fn gfx_set_scissor_rect(x: u32, y: u32, width: u32, height: u32);
128        /// slot 0-7; buffer with GASM_BUF_VERTEX; offset a multiple of 4, at most the buffer size.
129        #[link_name = "set_vertex_buffer"]
130        pub fn gfx_set_vertex_buffer(slot: u32, buffer: u32, offset: u32);
131        /// buffer with GASM_BUF_INDEX; format GASM_INDEX_U16 or GASM_INDEX_U32 (anything else traps); offset a multiple of the index size, at most the buffer size.
132        #[link_name = "set_index_buffer"]
133        pub fn gfx_set_index_buffer(buffer: u32, format: u32, offset: u32);
134        /// Needs a pipeline, and a vertex buffer in every slot the pipeline reads, large enough for the vertices and instances drawn (else traps).
135        #[link_name = "draw"]
136        pub fn gfx_draw(vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32);
137        /// Like draw, plus an index buffer holding first_index + index_count indices.
138        #[link_name = "draw_indexed"]
139        pub fn gfx_draw_indexed(index_count: u32, instance_count: u32, first_index: u32, base_vertex: i32, first_instance: u32);
140        /// Submit and present.
141        #[link_name = "end_frame"]
142        pub fn gfx_end_frame();
143        /// Release an object of any kind. The handle becomes invalid (later use, including another destroy, traps) and is never reused; objects created from it stay valid. GPU memory is freed once nothing in a submitted frame uses it.
144        #[link_name = "destroy"]
145        pub fn gfx_destroy(handle: u32);
146    }
147
148    #[link(wasm_import_module = "gasm:gl")]
149    unsafe extern "C" {
150        /// Drawable width in pixels (the default framebuffer follows it).
151        #[link_name = "width"]
152        pub fn gl_width() -> u32;
153        /// Drawable height in pixels.
154        #[link_name = "height"]
155        pub fn gl_height() -> u32;
156        /// 0 during catch-up frames (the runner runs several frames to catch up and shows only the last; the guest may skip drawing); 1 otherwise, headless included.
157        #[link_name = "frame_shown"]
158        pub fn gl_frame_shown() -> u32;
159        /// Show the default framebuffer now; otherwise the runner presents at the end of the frame.
160        #[link_name = "present"]
161        pub fn gl_present();
162        /// The oldest GL error flag (GL rules: a call with an error has no effect), or 0.
163        #[link_name = "get_error"]
164        pub fn gl_get_error() -> u32;
165        /// GL_VENDOR, GL_RENDERER, GL_VERSION, GL_SHADING_LANGUAGE_VERSION or GL_EXTENSIONS (space-separated): its length, copied if it fits; -1 for an invalid name (GL_INVALID_ENUM).
166        #[link_name = "get_string"]
167        pub fn gl_get_string(name: u32, dst: *mut u8, cap: u32) -> i32;
168        /// Turn on a WebGL extension listed in GL_EXTENSIONS (1), or 0 if it isn't there.
169        #[link_name = "enable_extension"]
170        pub fn gl_enable_extension(name: *const u8, name_len: u32) -> u32;
171        /// The parameter's values as i32s: how many it has (copied up to count), or -1 for an invalid pname (GL_INVALID_ENUM).
172        #[link_name = "get_integerv"]
173        pub fn gl_get_integerv(pname: u32, dst: *mut u8, count: u32) -> i32;
174        /// As get_integerv, as f32s.
175        #[link_name = "get_floatv"]
176        pub fn gl_get_floatv(pname: u32, dst: *mut u8, count: u32) -> i32;
177        /// As get_integerv, as i64s.
178        #[link_name = "get_integer64v"]
179        pub fn gl_get_integer64v(pname: u32, dst: *mut u8, count: u32) -> i32;
180        /// Indexed parameters (e.g. GL_UNIFORM_BUFFER_BINDING), as i32s.
181        #[link_name = "get_integeri_v"]
182        pub fn gl_get_integeri_v(target: u32, index: u32, dst: *mut u8, count: u32) -> i32;
183        /// GL_SAMPLES or GL_NUM_SAMPLE_COUNTS of a renderbuffer format.
184        #[link_name = "get_internalformativ"]
185        pub fn gl_get_internalformativ(target: u32, internalformat: u32, pname: u32, dst: *mut u8, count: u32) -> i32;
186        /// Writes 3 i32s: range min, range max, precision.
187        #[link_name = "get_shader_precision_format"]
188        pub fn gl_get_shader_precision_format(shadertype: u32, precisiontype: u32, dst: *mut u8);
189        #[link_name = "active_texture"]
190        pub fn gl_active_texture(texture: u32);
191        #[link_name = "blend_color"]
192        pub fn gl_blend_color(red: f32, green: f32, blue: f32, alpha: f32);
193        #[link_name = "blend_equation"]
194        pub fn gl_blend_equation(mode: u32);
195        #[link_name = "blend_equation_separate"]
196        pub fn gl_blend_equation_separate(mode_rgb: u32, mode_alpha: u32);
197        #[link_name = "blend_func"]
198        pub fn gl_blend_func(sfactor: u32, dfactor: u32);
199        #[link_name = "blend_func_separate"]
200        pub fn gl_blend_func_separate(src_rgb: u32, dst_rgb: u32, src_alpha: u32, dst_alpha: u32);
201        #[link_name = "clear"]
202        pub fn gl_clear(mask: u32);
203        #[link_name = "clear_color"]
204        pub fn gl_clear_color(red: f32, green: f32, blue: f32, alpha: f32);
205        #[link_name = "clear_depthf"]
206        pub fn gl_clear_depthf(depth: f32);
207        #[link_name = "clear_stencil"]
208        pub fn gl_clear_stencil(s: i32);
209        #[link_name = "color_mask"]
210        pub fn gl_color_mask(red: u32, green: u32, blue: u32, alpha: u32);
211        #[link_name = "cull_face"]
212        pub fn gl_cull_face(mode: u32);
213        #[link_name = "depth_func"]
214        pub fn gl_depth_func(func: u32);
215        #[link_name = "depth_mask"]
216        pub fn gl_depth_mask(flag: u32);
217        #[link_name = "depth_rangef"]
218        pub fn gl_depth_rangef(near: f32, far: f32);
219        #[link_name = "disable"]
220        pub fn gl_disable(cap: u32);
221        #[link_name = "enable"]
222        pub fn gl_enable(cap: u32);
223        #[link_name = "is_enabled"]
224        pub fn gl_is_enabled(cap: u32) -> u32;
225        #[link_name = "front_face"]
226        pub fn gl_front_face(mode: u32);
227        #[link_name = "hint"]
228        pub fn gl_hint(target: u32, mode: u32);
229        #[link_name = "line_width"]
230        pub fn gl_line_width(width: f32);
231        #[link_name = "pixel_storei"]
232        pub fn gl_pixel_storei(pname: u32, param: i32);
233        #[link_name = "polygon_offset"]
234        pub fn gl_polygon_offset(factor: f32, units: f32);
235        #[link_name = "sample_coverage"]
236        pub fn gl_sample_coverage(value: f32, invert: u32);
237        #[link_name = "scissor"]
238        pub fn gl_scissor(x: i32, y: i32, width: i32, height: i32);
239        #[link_name = "viewport"]
240        pub fn gl_viewport(x: i32, y: i32, width: i32, height: i32);
241        #[link_name = "stencil_func"]
242        pub fn gl_stencil_func(func: u32, r#ref: i32, mask: u32);
243        #[link_name = "stencil_func_separate"]
244        pub fn gl_stencil_func_separate(face: u32, func: u32, r#ref: i32, mask: u32);
245        #[link_name = "stencil_mask"]
246        pub fn gl_stencil_mask(mask: u32);
247        #[link_name = "stencil_mask_separate"]
248        pub fn gl_stencil_mask_separate(face: u32, mask: u32);
249        #[link_name = "stencil_op"]
250        pub fn gl_stencil_op(fail: u32, zfail: u32, zpass: u32);
251        #[link_name = "stencil_op_separate"]
252        pub fn gl_stencil_op_separate(face: u32, sfail: u32, dpfail: u32, dppass: u32);
253        #[link_name = "finish"]
254        pub fn gl_finish();
255        #[link_name = "flush"]
256        pub fn gl_flush();
257        /// A new buffer name (glGenBuffers).
258        #[link_name = "create_buffer"]
259        pub fn gl_create_buffer() -> u32;
260        #[link_name = "delete_buffer"]
261        pub fn gl_delete_buffer(buffer: u32);
262        #[link_name = "is_buffer"]
263        pub fn gl_is_buffer(buffer: u32) -> u32;
264        #[link_name = "bind_buffer"]
265        pub fn gl_bind_buffer(target: u32, buffer: u32);
266        #[link_name = "bind_buffer_base"]
267        pub fn gl_bind_buffer_base(target: u32, index: u32, buffer: u32);
268        #[link_name = "bind_buffer_range"]
269        pub fn gl_bind_buffer_range(target: u32, index: u32, buffer: u32, offset: u32, size: u32);
270        /// len bytes from data, or zeros if data is 0.
271        #[link_name = "buffer_data"]
272        pub fn gl_buffer_data(target: u32, data: *const u8, len: u32, usage: u32);
273        #[link_name = "buffer_sub_data"]
274        pub fn gl_buffer_sub_data(target: u32, offset: u32, data: *const u8, len: u32);
275        #[link_name = "copy_buffer_sub_data"]
276        pub fn gl_copy_buffer_sub_data(read_target: u32, write_target: u32, read_offset: u32, write_offset: u32, size: u32);
277        /// Read back len bytes (glMapBufferRange for reading).
278        #[link_name = "get_buffer_sub_data"]
279        pub fn gl_get_buffer_sub_data(target: u32, offset: u32, dst: *mut u8, len: u32);
280        #[link_name = "get_buffer_parameteriv"]
281        pub fn gl_get_buffer_parameteriv(target: u32, pname: u32) -> i32;
282        #[link_name = "create_vertex_array"]
283        pub fn gl_create_vertex_array() -> u32;
284        #[link_name = "delete_vertex_array"]
285        pub fn gl_delete_vertex_array(array: u32);
286        #[link_name = "is_vertex_array"]
287        pub fn gl_is_vertex_array(array: u32) -> u32;
288        #[link_name = "bind_vertex_array"]
289        pub fn gl_bind_vertex_array(array: u32);
290        #[link_name = "enable_vertex_attrib_array"]
291        pub fn gl_enable_vertex_attrib_array(index: u32);
292        #[link_name = "disable_vertex_attrib_array"]
293        pub fn gl_disable_vertex_attrib_array(index: u32);
294        /// offset into the bound GL_ARRAY_BUFFER (no client-side arrays).
295        #[link_name = "vertex_attrib_pointer"]
296        pub fn gl_vertex_attrib_pointer(index: u32, size: i32, r#type: u32, normalized: u32, stride: i32, offset: u32);
297        #[link_name = "vertex_attrib_ipointer"]
298        pub fn gl_vertex_attrib_ipointer(index: u32, size: i32, r#type: u32, stride: i32, offset: u32);
299        #[link_name = "vertex_attrib_divisor"]
300        pub fn gl_vertex_attrib_divisor(index: u32, divisor: u32);
301        #[link_name = "vertex_attrib4f"]
302        pub fn gl_vertex_attrib4f(index: u32, x: f32, y: f32, z: f32, w: f32);
303        #[link_name = "vertex_attribi4i"]
304        pub fn gl_vertex_attribi4i(index: u32, x: i32, y: i32, z: i32, w: i32);
305        #[link_name = "vertex_attribi4ui"]
306        pub fn gl_vertex_attribi4ui(index: u32, x: u32, y: u32, z: u32, w: u32);
307        #[link_name = "get_vertex_attribiv"]
308        pub fn gl_get_vertex_attribiv(index: u32, pname: u32) -> i32;
309        /// GL_CURRENT_VERTEX_ATTRIB: 4 f32s.
310        #[link_name = "get_vertex_attribfv"]
311        pub fn gl_get_vertex_attribfv(index: u32, pname: u32, dst: *mut u8, count: u32) -> i32;
312        #[link_name = "get_vertex_attrib_offset"]
313        pub fn gl_get_vertex_attrib_offset(index: u32, pname: u32) -> u32;
314        #[link_name = "draw_arrays"]
315        pub fn gl_draw_arrays(mode: u32, first: i32, count: i32);
316        /// Indices from the bound GL_ELEMENT_ARRAY_BUFFER at offset.
317        #[link_name = "draw_elements"]
318        pub fn gl_draw_elements(mode: u32, count: i32, r#type: u32, offset: u32);
319        #[link_name = "draw_arrays_instanced"]
320        pub fn gl_draw_arrays_instanced(mode: u32, first: i32, count: i32, instances: i32);
321        #[link_name = "draw_elements_instanced"]
322        pub fn gl_draw_elements_instanced(mode: u32, count: i32, r#type: u32, offset: u32, instances: i32);
323        #[link_name = "draw_range_elements"]
324        pub fn gl_draw_range_elements(mode: u32, start: u32, end: u32, count: i32, r#type: u32, offset: u32);
325        /// count GLenums.
326        #[link_name = "draw_buffers"]
327        pub fn gl_draw_buffers(bufs: *const u8, count: u32);
328        /// count i32s (4 for GL_COLOR, 1 for GL_STENCIL).
329        #[link_name = "clear_bufferiv"]
330        pub fn gl_clear_bufferiv(buffer: u32, drawbuffer: i32, value: *const u8, count: u32);
331        #[link_name = "clear_bufferuiv"]
332        pub fn gl_clear_bufferuiv(buffer: u32, drawbuffer: i32, value: *const u8, count: u32);
333        #[link_name = "clear_bufferfv"]
334        pub fn gl_clear_bufferfv(buffer: u32, drawbuffer: i32, value: *const u8, count: u32);
335        #[link_name = "clear_bufferfi"]
336        pub fn gl_clear_bufferfi(buffer: u32, drawbuffer: i32, depth: f32, stencil: i32);
337        #[link_name = "create_texture"]
338        pub fn gl_create_texture() -> u32;
339        #[link_name = "delete_texture"]
340        pub fn gl_delete_texture(texture: u32);
341        #[link_name = "is_texture"]
342        pub fn gl_is_texture(texture: u32) -> u32;
343        #[link_name = "bind_texture"]
344        pub fn gl_bind_texture(target: u32, texture: u32);
345        #[link_name = "tex_parameteri"]
346        pub fn gl_tex_parameteri(target: u32, pname: u32, param: i32);
347        #[link_name = "tex_parameterf"]
348        pub fn gl_tex_parameterf(target: u32, pname: u32, param: f32);
349        #[link_name = "get_tex_parameteriv"]
350        pub fn gl_get_tex_parameteriv(target: u32, pname: u32) -> i32;
351        #[link_name = "get_tex_parameterfv"]
352        pub fn gl_get_tex_parameterfv(target: u32, pname: u32) -> f32;
353        /// pixels 0: no data (or, with a bound GL_PIXEL_UNPACK_BUFFER, len is the offset into it); otherwise len must cover the image.
354        #[link_name = "tex_image_2d"]
355        pub fn gl_tex_image_2d(target: u32, level: i32, internalformat: i32, width: i32, height: i32, border: i32, format: u32, r#type: u32, pixels: *const u8, len: u32);
356        #[link_name = "tex_image_3d"]
357        pub fn gl_tex_image_3d(target: u32, level: i32, internalformat: i32, width: i32, height: i32, depth: i32, border: i32, format: u32, r#type: u32, pixels: *const u8, len: u32);
358        #[link_name = "tex_sub_image_2d"]
359        pub fn gl_tex_sub_image_2d(target: u32, level: i32, x: i32, y: i32, width: i32, height: i32, format: u32, r#type: u32, pixels: *const u8, len: u32);
360        #[link_name = "tex_sub_image_3d"]
361        pub fn gl_tex_sub_image_3d(target: u32, level: i32, x: i32, y: i32, z: i32, width: i32, height: i32, depth: i32, format: u32, r#type: u32, pixels: *const u8, len: u32);
362        #[link_name = "tex_storage_2d"]
363        pub fn gl_tex_storage_2d(target: u32, levels: i32, internalformat: u32, width: i32, height: i32);
364        #[link_name = "tex_storage_3d"]
365        pub fn gl_tex_storage_3d(target: u32, levels: i32, internalformat: u32, width: i32, height: i32, depth: i32);
366        #[link_name = "compressed_tex_image_2d"]
367        pub fn gl_compressed_tex_image_2d(target: u32, level: i32, internalformat: u32, width: i32, height: i32, border: i32, data: *const u8, len: u32);
368        #[link_name = "compressed_tex_image_3d"]
369        pub fn gl_compressed_tex_image_3d(target: u32, level: i32, internalformat: u32, width: i32, height: i32, depth: i32, border: i32, data: *const u8, len: u32);
370        #[link_name = "compressed_tex_sub_image_2d"]
371        pub fn gl_compressed_tex_sub_image_2d(target: u32, level: i32, x: i32, y: i32, width: i32, height: i32, format: u32, data: *const u8, len: u32);
372        #[link_name = "compressed_tex_sub_image_3d"]
373        pub fn gl_compressed_tex_sub_image_3d(target: u32, level: i32, x: i32, y: i32, z: i32, width: i32, height: i32, depth: i32, format: u32, data: *const u8, len: u32);
374        #[link_name = "copy_tex_image_2d"]
375        pub fn gl_copy_tex_image_2d(target: u32, level: i32, internalformat: u32, x: i32, y: i32, width: i32, height: i32, border: i32);
376        #[link_name = "copy_tex_sub_image_2d"]
377        pub fn gl_copy_tex_sub_image_2d(target: u32, level: i32, xoffset: i32, yoffset: i32, x: i32, y: i32, width: i32, height: i32);
378        #[link_name = "copy_tex_sub_image_3d"]
379        pub fn gl_copy_tex_sub_image_3d(target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, x: i32, y: i32, width: i32, height: i32);
380        /// Runners generate the levels (unlike gasm:gfx).
381        #[link_name = "generate_mipmap"]
382        pub fn gl_generate_mipmap(target: u32);
383        #[link_name = "create_sampler"]
384        pub fn gl_create_sampler() -> u32;
385        #[link_name = "delete_sampler"]
386        pub fn gl_delete_sampler(sampler: u32);
387        #[link_name = "is_sampler"]
388        pub fn gl_is_sampler(sampler: u32) -> u32;
389        #[link_name = "bind_sampler"]
390        pub fn gl_bind_sampler(unit: u32, sampler: u32);
391        #[link_name = "sampler_parameteri"]
392        pub fn gl_sampler_parameteri(sampler: u32, pname: u32, param: i32);
393        #[link_name = "sampler_parameterf"]
394        pub fn gl_sampler_parameterf(sampler: u32, pname: u32, param: f32);
395        #[link_name = "get_sampler_parameteriv"]
396        pub fn gl_get_sampler_parameteriv(sampler: u32, pname: u32) -> i32;
397        #[link_name = "get_sampler_parameterfv"]
398        pub fn gl_get_sampler_parameterfv(sampler: u32, pname: u32) -> f32;
399        #[link_name = "create_framebuffer"]
400        pub fn gl_create_framebuffer() -> u32;
401        #[link_name = "delete_framebuffer"]
402        pub fn gl_delete_framebuffer(framebuffer: u32);
403        #[link_name = "is_framebuffer"]
404        pub fn gl_is_framebuffer(framebuffer: u32) -> u32;
405        /// 0: the default framebuffer (the window).
406        #[link_name = "bind_framebuffer"]
407        pub fn gl_bind_framebuffer(target: u32, framebuffer: u32);
408        #[link_name = "check_framebuffer_status"]
409        pub fn gl_check_framebuffer_status(target: u32) -> u32;
410        #[link_name = "framebuffer_texture_2d"]
411        pub fn gl_framebuffer_texture_2d(target: u32, attachment: u32, textarget: u32, texture: u32, level: i32);
412        #[link_name = "framebuffer_texture_layer"]
413        pub fn gl_framebuffer_texture_layer(target: u32, attachment: u32, texture: u32, level: i32, layer: i32);
414        #[link_name = "framebuffer_renderbuffer"]
415        pub fn gl_framebuffer_renderbuffer(target: u32, attachment: u32, renderbuffertarget: u32, renderbuffer: u32);
416        #[link_name = "get_framebuffer_attachment_parameteriv"]
417        pub fn gl_get_framebuffer_attachment_parameteriv(target: u32, attachment: u32, pname: u32) -> i32;
418        #[link_name = "blit_framebuffer"]
419        pub fn gl_blit_framebuffer(src_x0: i32, src_y0: i32, src_x1: i32, src_y1: i32, dst_x0: i32, dst_y0: i32, dst_x1: i32, dst_y1: i32, mask: u32, filter: u32);
420        #[link_name = "invalidate_framebuffer"]
421        pub fn gl_invalidate_framebuffer(target: u32, attachments: *const u8, count: u32);
422        #[link_name = "invalidate_sub_framebuffer"]
423        pub fn gl_invalidate_sub_framebuffer(target: u32, attachments: *const u8, count: u32, x: i32, y: i32, width: i32, height: i32);
424        #[link_name = "read_buffer"]
425        pub fn gl_read_buffer(src: u32);
426        /// len must cover the rectangle; with a bound GL_PIXEL_PACK_BUFFER, dst is the offset into it.
427        #[link_name = "read_pixels"]
428        pub fn gl_read_pixels(x: i32, y: i32, width: i32, height: i32, format: u32, r#type: u32, dst: *mut u8, len: u32);
429        #[link_name = "create_renderbuffer"]
430        pub fn gl_create_renderbuffer() -> u32;
431        #[link_name = "delete_renderbuffer"]
432        pub fn gl_delete_renderbuffer(renderbuffer: u32);
433        #[link_name = "is_renderbuffer"]
434        pub fn gl_is_renderbuffer(renderbuffer: u32) -> u32;
435        #[link_name = "bind_renderbuffer"]
436        pub fn gl_bind_renderbuffer(target: u32, renderbuffer: u32);
437        #[link_name = "renderbuffer_storage"]
438        pub fn gl_renderbuffer_storage(target: u32, internalformat: u32, width: i32, height: i32);
439        #[link_name = "renderbuffer_storage_multisample"]
440        pub fn gl_renderbuffer_storage_multisample(target: u32, samples: i32, internalformat: u32, width: i32, height: i32);
441        #[link_name = "get_renderbuffer_parameteriv"]
442        pub fn gl_get_renderbuffer_parameteriv(target: u32, pname: u32) -> i32;
443        #[link_name = "create_shader"]
444        pub fn gl_create_shader(r#type: u32) -> u32;
445        #[link_name = "delete_shader"]
446        pub fn gl_delete_shader(shader: u32);
447        #[link_name = "is_shader"]
448        pub fn gl_is_shader(shader: u32) -> u32;
449        /// GLSL ES 3.00 (or 1.00).
450        #[link_name = "shader_source"]
451        pub fn gl_shader_source(shader: u32, source: *const u8, source_len: u32);
452        #[link_name = "compile_shader"]
453        pub fn gl_compile_shader(shader: u32);
454        #[link_name = "get_shaderiv"]
455        pub fn gl_get_shaderiv(shader: u32, pname: u32) -> i32;
456        #[link_name = "get_shader_info_log"]
457        pub fn gl_get_shader_info_log(shader: u32, dst: *mut u8, cap: u32) -> i32;
458        #[link_name = "get_shader_source"]
459        pub fn gl_get_shader_source(shader: u32, dst: *mut u8, cap: u32) -> i32;
460        #[link_name = "create_program"]
461        pub fn gl_create_program() -> u32;
462        #[link_name = "delete_program"]
463        pub fn gl_delete_program(program: u32);
464        #[link_name = "is_program"]
465        pub fn gl_is_program(program: u32) -> u32;
466        #[link_name = "attach_shader"]
467        pub fn gl_attach_shader(program: u32, shader: u32);
468        #[link_name = "detach_shader"]
469        pub fn gl_detach_shader(program: u32, shader: u32);
470        #[link_name = "link_program"]
471        pub fn gl_link_program(program: u32);
472        #[link_name = "use_program"]
473        pub fn gl_use_program(program: u32);
474        #[link_name = "validate_program"]
475        pub fn gl_validate_program(program: u32);
476        #[link_name = "get_programiv"]
477        pub fn gl_get_programiv(program: u32, pname: u32) -> i32;
478        #[link_name = "get_program_info_log"]
479        pub fn gl_get_program_info_log(program: u32, dst: *mut u8, cap: u32) -> i32;
480        /// Shader names (u32), copied up to count; returns how many.
481        #[link_name = "get_attached_shaders"]
482        pub fn gl_get_attached_shaders(program: u32, dst: *mut u8, count: u32) -> i32;
483        #[link_name = "bind_attrib_location"]
484        pub fn gl_bind_attrib_location(program: u32, index: u32, name: *const u8, name_len: u32);
485        #[link_name = "get_attrib_location"]
486        pub fn gl_get_attrib_location(program: u32, name: *const u8, name_len: u32) -> i32;
487        #[link_name = "get_frag_data_location"]
488        pub fn gl_get_frag_data_location(program: u32, name: *const u8, name_len: u32) -> i32;
489        /// info: 2 i32s (size, type). Returns the name's length (copied if it fits), or -1.
490        #[link_name = "get_active_attrib"]
491        pub fn gl_get_active_attrib(program: u32, index: u32, name: *mut u8, cap: u32, info: *mut u8) -> i32;
492        #[link_name = "get_active_uniform"]
493        pub fn gl_get_active_uniform(program: u32, index: u32, name: *mut u8, cap: u32, info: *mut u8) -> i32;
494        /// -1 if the program has no such uniform.
495        #[link_name = "get_uniform_location"]
496        pub fn gl_get_uniform_location(program: u32, name: *const u8, name_len: u32) -> i32;
497        /// glGetUniformIndices for one name (GL_INVALID_INDEX if none).
498        #[link_name = "get_uniform_index"]
499        pub fn gl_get_uniform_index(program: u32, name: *const u8, name_len: u32) -> u32;
500        /// count u32 indices in, count i32s out.
501        #[link_name = "get_active_uniformsiv"]
502        pub fn gl_get_active_uniformsiv(program: u32, indices: *const u8, count: u32, pname: u32, dst: *mut u8);
503        #[link_name = "get_uniform_block_index"]
504        pub fn gl_get_uniform_block_index(program: u32, name: *const u8, name_len: u32) -> u32;
505        #[link_name = "get_active_uniform_block_name"]
506        pub fn gl_get_active_uniform_block_name(program: u32, index: u32, dst: *mut u8, cap: u32) -> i32;
507        #[link_name = "get_active_uniform_blockiv"]
508        pub fn gl_get_active_uniform_blockiv(program: u32, index: u32, pname: u32, dst: *mut u8, count: u32) -> i32;
509        #[link_name = "uniform_block_binding"]
510        pub fn gl_uniform_block_binding(program: u32, index: u32, binding: u32);
511        #[link_name = "get_uniformfv"]
512        pub fn gl_get_uniformfv(program: u32, location: i32, dst: *mut u8, count: u32) -> i32;
513        #[link_name = "get_uniformiv"]
514        pub fn gl_get_uniformiv(program: u32, location: i32, dst: *mut u8, count: u32) -> i32;
515        #[link_name = "get_uniformuiv"]
516        pub fn gl_get_uniformuiv(program: u32, location: i32, dst: *mut u8, count: u32) -> i32;
517        /// count names, each NUL-terminated, in len bytes.
518        #[link_name = "transform_feedback_varyings"]
519        pub fn gl_transform_feedback_varyings(program: u32, names: *const u8, len: u32, count: u32, buffer_mode: u32);
520        #[link_name = "get_transform_feedback_varying"]
521        pub fn gl_get_transform_feedback_varying(program: u32, index: u32, name: *mut u8, cap: u32, info: *mut u8) -> i32;
522        #[link_name = "uniform1f"]
523        pub fn gl_uniform1f(location: i32, x: f32);
524        #[link_name = "uniform2f"]
525        pub fn gl_uniform2f(location: i32, x: f32, y: f32);
526        #[link_name = "uniform3f"]
527        pub fn gl_uniform3f(location: i32, x: f32, y: f32, z: f32);
528        #[link_name = "uniform4f"]
529        pub fn gl_uniform4f(location: i32, x: f32, y: f32, z: f32, w: f32);
530        #[link_name = "uniform1i"]
531        pub fn gl_uniform1i(location: i32, x: i32);
532        #[link_name = "uniform2i"]
533        pub fn gl_uniform2i(location: i32, x: i32, y: i32);
534        #[link_name = "uniform3i"]
535        pub fn gl_uniform3i(location: i32, x: i32, y: i32, z: i32);
536        #[link_name = "uniform4i"]
537        pub fn gl_uniform4i(location: i32, x: i32, y: i32, z: i32, w: i32);
538        #[link_name = "uniform1ui"]
539        pub fn gl_uniform1ui(location: i32, x: u32);
540        #[link_name = "uniform2ui"]
541        pub fn gl_uniform2ui(location: i32, x: u32, y: u32);
542        #[link_name = "uniform3ui"]
543        pub fn gl_uniform3ui(location: i32, x: u32, y: u32, z: u32);
544        #[link_name = "uniform4ui"]
545        pub fn gl_uniform4ui(location: i32, x: u32, y: u32, z: u32, w: u32);
546        /// count vectors (GL semantics).
547        #[link_name = "uniform1fv"]
548        pub fn gl_uniform1fv(location: i32, count: i32, value: *const u8);
549        #[link_name = "uniform2fv"]
550        pub fn gl_uniform2fv(location: i32, count: i32, value: *const u8);
551        #[link_name = "uniform3fv"]
552        pub fn gl_uniform3fv(location: i32, count: i32, value: *const u8);
553        #[link_name = "uniform4fv"]
554        pub fn gl_uniform4fv(location: i32, count: i32, value: *const u8);
555        #[link_name = "uniform1iv"]
556        pub fn gl_uniform1iv(location: i32, count: i32, value: *const u8);
557        #[link_name = "uniform2iv"]
558        pub fn gl_uniform2iv(location: i32, count: i32, value: *const u8);
559        #[link_name = "uniform3iv"]
560        pub fn gl_uniform3iv(location: i32, count: i32, value: *const u8);
561        #[link_name = "uniform4iv"]
562        pub fn gl_uniform4iv(location: i32, count: i32, value: *const u8);
563        #[link_name = "uniform1uiv"]
564        pub fn gl_uniform1uiv(location: i32, count: i32, value: *const u8);
565        #[link_name = "uniform2uiv"]
566        pub fn gl_uniform2uiv(location: i32, count: i32, value: *const u8);
567        #[link_name = "uniform3uiv"]
568        pub fn gl_uniform3uiv(location: i32, count: i32, value: *const u8);
569        #[link_name = "uniform4uiv"]
570        pub fn gl_uniform4uiv(location: i32, count: i32, value: *const u8);
571        #[link_name = "uniform_matrix2fv"]
572        pub fn gl_uniform_matrix2fv(location: i32, count: i32, transpose: u32, value: *const u8);
573        #[link_name = "uniform_matrix3fv"]
574        pub fn gl_uniform_matrix3fv(location: i32, count: i32, transpose: u32, value: *const u8);
575        #[link_name = "uniform_matrix4fv"]
576        pub fn gl_uniform_matrix4fv(location: i32, count: i32, transpose: u32, value: *const u8);
577        #[link_name = "uniform_matrix2x3fv"]
578        pub fn gl_uniform_matrix2x3fv(location: i32, count: i32, transpose: u32, value: *const u8);
579        #[link_name = "uniform_matrix3x2fv"]
580        pub fn gl_uniform_matrix3x2fv(location: i32, count: i32, transpose: u32, value: *const u8);
581        #[link_name = "uniform_matrix2x4fv"]
582        pub fn gl_uniform_matrix2x4fv(location: i32, count: i32, transpose: u32, value: *const u8);
583        #[link_name = "uniform_matrix4x2fv"]
584        pub fn gl_uniform_matrix4x2fv(location: i32, count: i32, transpose: u32, value: *const u8);
585        #[link_name = "uniform_matrix3x4fv"]
586        pub fn gl_uniform_matrix3x4fv(location: i32, count: i32, transpose: u32, value: *const u8);
587        #[link_name = "uniform_matrix4x3fv"]
588        pub fn gl_uniform_matrix4x3fv(location: i32, count: i32, transpose: u32, value: *const u8);
589        #[link_name = "create_query"]
590        pub fn gl_create_query() -> u32;
591        #[link_name = "delete_query"]
592        pub fn gl_delete_query(query: u32);
593        #[link_name = "is_query"]
594        pub fn gl_is_query(query: u32) -> u32;
595        #[link_name = "begin_query"]
596        pub fn gl_begin_query(target: u32, query: u32);
597        #[link_name = "end_query"]
598        pub fn gl_end_query(target: u32);
599        /// GL_CURRENT_QUERY: the active query's name.
600        #[link_name = "get_queryiv"]
601        pub fn gl_get_queryiv(target: u32, pname: u32) -> u32;
602        /// Results are available from the next frame on, on every runner.
603        #[link_name = "get_query_objectuiv"]
604        pub fn gl_get_query_objectuiv(query: u32, pname: u32) -> u32;
605        /// A sync name (not a pointer).
606        #[link_name = "fence_sync"]
607        pub fn gl_fence_sync(condition: u32, flags: u32) -> u32;
608        #[link_name = "is_sync"]
609        pub fn gl_is_sync(sync: u32) -> u32;
610        #[link_name = "delete_sync"]
611        pub fn gl_delete_sync(sync: u32);
612        /// Signaled from the next frame on; a timeout above 0 that isn't met gives GL_TIMEOUT_EXPIRED.
613        #[link_name = "client_wait_sync"]
614        pub fn gl_client_wait_sync(sync: u32, flags: u32, timeout: u64) -> u32;
615        #[link_name = "wait_sync"]
616        pub fn gl_wait_sync(sync: u32, flags: u32, timeout: u64);
617        #[link_name = "get_synciv"]
618        pub fn gl_get_synciv(sync: u32, pname: u32) -> i32;
619        #[link_name = "create_transform_feedback"]
620        pub fn gl_create_transform_feedback() -> u32;
621        #[link_name = "delete_transform_feedback"]
622        pub fn gl_delete_transform_feedback(tf: u32);
623        #[link_name = "is_transform_feedback"]
624        pub fn gl_is_transform_feedback(tf: u32) -> u32;
625        #[link_name = "bind_transform_feedback"]
626        pub fn gl_bind_transform_feedback(target: u32, tf: u32);
627        #[link_name = "begin_transform_feedback"]
628        pub fn gl_begin_transform_feedback(primitive_mode: u32);
629        #[link_name = "end_transform_feedback"]
630        pub fn gl_end_transform_feedback();
631        #[link_name = "pause_transform_feedback"]
632        pub fn gl_pause_transform_feedback();
633        #[link_name = "resume_transform_feedback"]
634        pub fn gl_resume_transform_feedback();
635    }
636
637    #[link(wasm_import_module = "gasm:net")]
638    unsafe extern "C" {
639        /// Open a ws:// or wss:// URL. Handle > 0, or -1 if denied/invalid.
640        #[link_name = "open"]
641        pub fn net_open(url: *const u8, url_len: u32) -> i32;
642        /// GASM_NET_CONNECTING / OPEN / CLOSED / ERROR.
643        #[link_name = "state"]
644        pub fn net_state(conn: i32) -> u32;
645        /// Send one message (len > 0). 0, or -1 if not open.
646        #[link_name = "send"]
647        pub fn net_send(conn: i32, data: *const u8, len: u32) -> i32;
648        /// Next message's length (copied only if <= cap, else it stays queued), 0 if none, -1 if closed and drained.
649        #[link_name = "recv"]
650        pub fn net_recv(conn: i32, dst: *mut u8, cap: u32) -> i32;
651        /// Close (flushing queued messages); closing again does nothing.
652        #[link_name = "close"]
653        pub fn net_close(conn: i32);
654    }
655
656    #[link(wasm_import_module = "gasm:fetch")]
657    unsafe extern "C" {
658        /// Start a request described by JSON {"method":"GET","url":"https://...","headers":{"name":"value"}}, with body_len bytes of body (0: none). Handle > 0, or -1 if denied, invalid or too many are open (16).
659        #[link_name = "request"]
660        pub fn fetch_request(desc: *const u8, desc_len: u32, body: *const u8, body_len: u32) -> i32;
661        /// GASM_FETCH_PENDING / HEADERS (status and headers are in) / DONE (the whole body arrived) / FAILED.
662        #[link_name = "state"]
663        pub fn fetch_state(req: i32) -> u32;
664        /// HTTP status of the final response (after redirects), 0 before the headers or after a failure.
665        #[link_name = "status"]
666        pub fn fetch_status(req: i32) -> i32;
667        /// Response headers as "name: value\n" lines (names lowercase). Length (copied only if <= cap; cap = 0 queries), -1 before GASM_FETCH_HEADERS.
668        #[link_name = "headers"]
669        pub fn fetch_headers(req: i32, dst: *mut u8, cap: u32) -> i32;
670        /// Copy up to cap bytes of body that have arrived; returns the count, 0 if none are waiting yet, -1 once the body is done and drained or the request failed.
671        #[link_name = "read"]
672        pub fn fetch_read(req: i32, dst: *mut u8, cap: u32) -> i32;
673        /// Cancel if still running and free the handle; closing again does nothing.
674        #[link_name = "close"]
675        pub fn fetch_close(req: i32);
676    }
677
678    #[link(wasm_import_module = "gasm:media")]
679    unsafe extern "C" {
680        /// A stream described by JSON {"url":"https://..."}, not playing yet. Handle > 0, or -1 if refused (no media permission, a private or loopback address that is not listed, not https, 4 streams already open, an invalid description): error(-1, ...) says why.
681        #[link_name = "open"]
682        pub fn media_open(desc: *const u8, desc_len: u32) -> i32;
683        /// Start or resume (connects on the first play). A live stream paused for long reconnects.
684        #[link_name = "play"]
685        pub fn media_play(h: i32);
686        /// Stop playing; the stream keeps its place (a live one may drop its connection meanwhile).
687        #[link_name = "pause"]
688        pub fn media_pause(h: i32);
689        /// Stop and free the handle; closing again does nothing.
690        #[link_name = "close"]
691        pub fn media_close(h: i32);
692        /// Volume 0 to 1 (outside that clamped, NaN is 0), applied smoothly. Where caps lacks GASM_MEDIA_CAN_VOLUME (iOS Safari) it is ignored.
693        #[link_name = "set_volume"]
694        pub fn media_set_volume(h: i32, gain: f32);
695        /// A low-pass filter at hz (20 to 20000, clamped), 0 = off. Ignored where caps lacks GASM_MEDIA_CAN_LOWPASS.
696        #[link_name = "set_lowpass"]
697        pub fn media_set_lowpass(h: i32, hz: f32);
698        /// GASM_MEDIA_CAN_* flags: what set_volume, set_lowpass and metadata can do for this stream. Final once the state is GASM_MEDIA_PLAYING (browsers: lowpass and metadata only where the stream sends CORS).
699        #[link_name = "caps"]
700        pub fn media_caps(h: i32) -> u32;
701        /// GASM_MEDIA_CONNECTING (also while the player is asked) / PLAYING / PAUSED / FAILED (error says why) / ENDED (a track played to its end). A closed handle is FAILED.
702        #[link_name = "state"]
703        pub fn media_state(h: i32) -> u32;
704        /// Why the stream failed (or, for h = -1, why the last open was refused), as text. Length (copied only if <= cap; cap = 0 queries), 0 if none.
705        #[link_name = "error"]
706        pub fn media_error(h: i32, dst: *mut u8, cap: u32) -> i32;
707        /// Seconds played so far (live streams: since play).
708        #[link_name = "position"]
709        pub fn media_position(h: i32) -> f64;
710        /// A track's length in seconds, -1 for live streams and while unknown.
711        #[link_name = "duration"]
712        pub fn media_duration(h: i32) -> f64;
713        /// JSON {"name","title","codec","bitrate"} (null where unknown; name and title from ICY: icy-name and StreamTitle). Length (copied only if <= cap; cap = 0 queries).
714        #[link_name = "metadata"]
715        pub fn media_metadata(h: i32, dst: *mut u8, cap: u32) -> i32;
716        /// Changes whenever metadata does (a new title): poll it each frame and read metadata only then.
717        #[link_name = "metadata_version"]
718        pub fn media_metadata_version(h: i32) -> u32;
719    }
720
721    #[link(wasm_import_module = "gasm:storage")]
722    unsafe extern "C" {
723        /// Value length, or -1 if missing. Copied only if length <= cap.
724        #[link_name = "get"]
725        pub fn storage_get(key: *const u8, key_len: u32, dst: *mut u8, cap: u32) -> i32;
726        /// 0, or a GASM_STORAGE_ERR_* code: invalid key, value too large, quota exceeded, I/O error.
727        #[link_name = "set"]
728        pub fn storage_set(key: *const u8, key_len: u32, data: *const u8, len: u32) -> i32;
729        /// 0 if deleted, -1 if it did not exist.
730        #[link_name = "delete"]
731        pub fn storage_delete(key: *const u8, key_len: u32) -> i32;
732        /// Number of keys in the namespace.
733        #[link_name = "count"]
734        pub fn storage_count() -> u32;
735        /// Key index (0 .. count-1, sorted): its length (copied only if <= cap; cap = 0 queries), or -1 if out of range.
736        #[link_name = "key"]
737        pub fn storage_key(index: u32, dst: *mut u8, cap: u32) -> i32;
738    }
739
740    #[link(wasm_import_module = "gasm:clipboard")]
741    unsafe extern "C" {
742        /// 0: the runner puts it on the clipboard after this frame; -1: refused (over 1 MiB, or no clipboard). Invalid UTF-8 traps.
743        #[link_name = "set_text"]
744        pub fn clipboard_set_text(text: *const u8, text_len: u32) -> i32;
745        /// The pasted text's length in bytes (copied only if <= cap; cap = 0 queries), or -1 outside a paste frame or with nothing to paste.
746        #[link_name = "get_text"]
747        pub fn clipboard_get_text(dst: *mut u8, cap: u32) -> i32;
748    }
749
750    #[link(wasm_import_module = "gasm:files")]
751    unsafe extern "C" {
752        /// A handle > 0 (the runner saves it after this frame), or -1: refused (saving is off, name empty or over 255 bytes, mime not type/subtype, over 256 MiB, or 16 saves still pending). name is a file name; the runner keeps only its last path component and makes it safe and unique. Invalid UTF-8 traps.
753        #[link_name = "save"]
754        pub fn files_save(name: *const u8, name_len: u32, mime: *const u8, mime_len: u32, data: *const u8, len: u32) -> i32;
755        /// GASM_FILES_PENDING (0), GASM_FILES_SAVED (1) or GASM_FILES_FAILED (2: cancelled or not written). A handle save never returned traps.
756        #[link_name = "state"]
757        pub fn files_state(handle: i32) -> i32;
758    }
759
760    #[link(wasm_import_module = "wasi_snapshot_preview1")]
761    unsafe extern "C" {
762        /// End the game; 0 is a normal exit.
763        pub fn proc_exit(code: i32) -> !;
764    }
765}
766
767#[cfg(target_arch = "wasm32")]
768pub use imports::*;
769
770#[cfg(not(target_arch = "wasm32"))]
771pub use crate::native::abi::*;
772
773/// Every import module and `module.function` of this ABI version (what `gasm::has` can report).
774pub const IMPORTS: [&str; 322] = [
775    "gasm", "gasm.log", "gasm.has", "gasm.time_ms",
776    "gasm.max_threads", "gasm.utc_offset_minutes", "gasm.set_frame_rate", "gasm.video_present",
777    "gasm.video_set_aspect", "gasm.audio_config", "gasm.audio_push", "gasm.input_pad",
778    "gasm.text_input", "gasm.input_mode", "gasm.key_state", "gasm.key_events",
779    "gasm.pointer", "gasm.gamepad", "gasm.gamepad_name", "gasm.asset_size",
780    "gasm.asset_size64", "gasm.asset_read", "gasm.asset_read_at", "gasm.asset_read_at64",
781    "gasm.asset_count", "gasm.asset_name", "gasm.asset_version", "gasm.param",
782    "gasm.set_title", "gasm.set_fullscreen", "gasm.is_fullscreen", "gasm.yield_frame",
783    "gasm:gfx", "gasm:gfx.width", "gasm:gfx.height", "gasm:gfx.create_shader",
784    "gasm:gfx.create_buffer", "gasm:gfx.create_pipeline", "gasm:gfx.create_bind_group", "gasm:gfx.create_bind_group_layout",
785    "gasm:gfx.create_texture", "gasm:gfx.write_texture", "gasm:gfx.create_sampler", "gasm:gfx.write_buffer",
786    "gasm:gfx.begin_frame", "gasm:gfx.set_pipeline", "gasm:gfx.set_bind_group", "gasm:gfx.set_bind_group_offsets",
787    "gasm:gfx.set_viewport", "gasm:gfx.set_scissor_rect", "gasm:gfx.set_vertex_buffer", "gasm:gfx.set_index_buffer",
788    "gasm:gfx.draw", "gasm:gfx.draw_indexed", "gasm:gfx.end_frame", "gasm:gfx.destroy",
789    "gasm:gl", "gasm:gl.width", "gasm:gl.height", "gasm:gl.frame_shown",
790    "gasm:gl.present", "gasm:gl.get_error", "gasm:gl.get_string", "gasm:gl.enable_extension",
791    "gasm:gl.get_integerv", "gasm:gl.get_floatv", "gasm:gl.get_integer64v", "gasm:gl.get_integeri_v",
792    "gasm:gl.get_internalformativ", "gasm:gl.get_shader_precision_format", "gasm:gl.active_texture", "gasm:gl.blend_color",
793    "gasm:gl.blend_equation", "gasm:gl.blend_equation_separate", "gasm:gl.blend_func", "gasm:gl.blend_func_separate",
794    "gasm:gl.clear", "gasm:gl.clear_color", "gasm:gl.clear_depthf", "gasm:gl.clear_stencil",
795    "gasm:gl.color_mask", "gasm:gl.cull_face", "gasm:gl.depth_func", "gasm:gl.depth_mask",
796    "gasm:gl.depth_rangef", "gasm:gl.disable", "gasm:gl.enable", "gasm:gl.is_enabled",
797    "gasm:gl.front_face", "gasm:gl.hint", "gasm:gl.line_width", "gasm:gl.pixel_storei",
798    "gasm:gl.polygon_offset", "gasm:gl.sample_coverage", "gasm:gl.scissor", "gasm:gl.viewport",
799    "gasm:gl.stencil_func", "gasm:gl.stencil_func_separate", "gasm:gl.stencil_mask", "gasm:gl.stencil_mask_separate",
800    "gasm:gl.stencil_op", "gasm:gl.stencil_op_separate", "gasm:gl.finish", "gasm:gl.flush",
801    "gasm:gl.create_buffer", "gasm:gl.delete_buffer", "gasm:gl.is_buffer", "gasm:gl.bind_buffer",
802    "gasm:gl.bind_buffer_base", "gasm:gl.bind_buffer_range", "gasm:gl.buffer_data", "gasm:gl.buffer_sub_data",
803    "gasm:gl.copy_buffer_sub_data", "gasm:gl.get_buffer_sub_data", "gasm:gl.get_buffer_parameteriv", "gasm:gl.create_vertex_array",
804    "gasm:gl.delete_vertex_array", "gasm:gl.is_vertex_array", "gasm:gl.bind_vertex_array", "gasm:gl.enable_vertex_attrib_array",
805    "gasm:gl.disable_vertex_attrib_array", "gasm:gl.vertex_attrib_pointer", "gasm:gl.vertex_attrib_ipointer", "gasm:gl.vertex_attrib_divisor",
806    "gasm:gl.vertex_attrib4f", "gasm:gl.vertex_attribi4i", "gasm:gl.vertex_attribi4ui", "gasm:gl.get_vertex_attribiv",
807    "gasm:gl.get_vertex_attribfv", "gasm:gl.get_vertex_attrib_offset", "gasm:gl.draw_arrays", "gasm:gl.draw_elements",
808    "gasm:gl.draw_arrays_instanced", "gasm:gl.draw_elements_instanced", "gasm:gl.draw_range_elements", "gasm:gl.draw_buffers",
809    "gasm:gl.clear_bufferiv", "gasm:gl.clear_bufferuiv", "gasm:gl.clear_bufferfv", "gasm:gl.clear_bufferfi",
810    "gasm:gl.create_texture", "gasm:gl.delete_texture", "gasm:gl.is_texture", "gasm:gl.bind_texture",
811    "gasm:gl.tex_parameteri", "gasm:gl.tex_parameterf", "gasm:gl.get_tex_parameteriv", "gasm:gl.get_tex_parameterfv",
812    "gasm:gl.tex_image_2d", "gasm:gl.tex_image_3d", "gasm:gl.tex_sub_image_2d", "gasm:gl.tex_sub_image_3d",
813    "gasm:gl.tex_storage_2d", "gasm:gl.tex_storage_3d", "gasm:gl.compressed_tex_image_2d", "gasm:gl.compressed_tex_image_3d",
814    "gasm:gl.compressed_tex_sub_image_2d", "gasm:gl.compressed_tex_sub_image_3d", "gasm:gl.copy_tex_image_2d", "gasm:gl.copy_tex_sub_image_2d",
815    "gasm:gl.copy_tex_sub_image_3d", "gasm:gl.generate_mipmap", "gasm:gl.create_sampler", "gasm:gl.delete_sampler",
816    "gasm:gl.is_sampler", "gasm:gl.bind_sampler", "gasm:gl.sampler_parameteri", "gasm:gl.sampler_parameterf",
817    "gasm:gl.get_sampler_parameteriv", "gasm:gl.get_sampler_parameterfv", "gasm:gl.create_framebuffer", "gasm:gl.delete_framebuffer",
818    "gasm:gl.is_framebuffer", "gasm:gl.bind_framebuffer", "gasm:gl.check_framebuffer_status", "gasm:gl.framebuffer_texture_2d",
819    "gasm:gl.framebuffer_texture_layer", "gasm:gl.framebuffer_renderbuffer", "gasm:gl.get_framebuffer_attachment_parameteriv", "gasm:gl.blit_framebuffer",
820    "gasm:gl.invalidate_framebuffer", "gasm:gl.invalidate_sub_framebuffer", "gasm:gl.read_buffer", "gasm:gl.read_pixels",
821    "gasm:gl.create_renderbuffer", "gasm:gl.delete_renderbuffer", "gasm:gl.is_renderbuffer", "gasm:gl.bind_renderbuffer",
822    "gasm:gl.renderbuffer_storage", "gasm:gl.renderbuffer_storage_multisample", "gasm:gl.get_renderbuffer_parameteriv", "gasm:gl.create_shader",
823    "gasm:gl.delete_shader", "gasm:gl.is_shader", "gasm:gl.shader_source", "gasm:gl.compile_shader",
824    "gasm:gl.get_shaderiv", "gasm:gl.get_shader_info_log", "gasm:gl.get_shader_source", "gasm:gl.create_program",
825    "gasm:gl.delete_program", "gasm:gl.is_program", "gasm:gl.attach_shader", "gasm:gl.detach_shader",
826    "gasm:gl.link_program", "gasm:gl.use_program", "gasm:gl.validate_program", "gasm:gl.get_programiv",
827    "gasm:gl.get_program_info_log", "gasm:gl.get_attached_shaders", "gasm:gl.bind_attrib_location", "gasm:gl.get_attrib_location",
828    "gasm:gl.get_frag_data_location", "gasm:gl.get_active_attrib", "gasm:gl.get_active_uniform", "gasm:gl.get_uniform_location",
829    "gasm:gl.get_uniform_index", "gasm:gl.get_active_uniformsiv", "gasm:gl.get_uniform_block_index", "gasm:gl.get_active_uniform_block_name",
830    "gasm:gl.get_active_uniform_blockiv", "gasm:gl.uniform_block_binding", "gasm:gl.get_uniformfv", "gasm:gl.get_uniformiv",
831    "gasm:gl.get_uniformuiv", "gasm:gl.transform_feedback_varyings", "gasm:gl.get_transform_feedback_varying", "gasm:gl.uniform1f",
832    "gasm:gl.uniform2f", "gasm:gl.uniform3f", "gasm:gl.uniform4f", "gasm:gl.uniform1i",
833    "gasm:gl.uniform2i", "gasm:gl.uniform3i", "gasm:gl.uniform4i", "gasm:gl.uniform1ui",
834    "gasm:gl.uniform2ui", "gasm:gl.uniform3ui", "gasm:gl.uniform4ui", "gasm:gl.uniform1fv",
835    "gasm:gl.uniform2fv", "gasm:gl.uniform3fv", "gasm:gl.uniform4fv", "gasm:gl.uniform1iv",
836    "gasm:gl.uniform2iv", "gasm:gl.uniform3iv", "gasm:gl.uniform4iv", "gasm:gl.uniform1uiv",
837    "gasm:gl.uniform2uiv", "gasm:gl.uniform3uiv", "gasm:gl.uniform4uiv", "gasm:gl.uniform_matrix2fv",
838    "gasm:gl.uniform_matrix3fv", "gasm:gl.uniform_matrix4fv", "gasm:gl.uniform_matrix2x3fv", "gasm:gl.uniform_matrix3x2fv",
839    "gasm:gl.uniform_matrix2x4fv", "gasm:gl.uniform_matrix4x2fv", "gasm:gl.uniform_matrix3x4fv", "gasm:gl.uniform_matrix4x3fv",
840    "gasm:gl.create_query", "gasm:gl.delete_query", "gasm:gl.is_query", "gasm:gl.begin_query",
841    "gasm:gl.end_query", "gasm:gl.get_queryiv", "gasm:gl.get_query_objectuiv", "gasm:gl.fence_sync",
842    "gasm:gl.is_sync", "gasm:gl.delete_sync", "gasm:gl.client_wait_sync", "gasm:gl.wait_sync",
843    "gasm:gl.get_synciv", "gasm:gl.create_transform_feedback", "gasm:gl.delete_transform_feedback", "gasm:gl.is_transform_feedback",
844    "gasm:gl.bind_transform_feedback", "gasm:gl.begin_transform_feedback", "gasm:gl.end_transform_feedback", "gasm:gl.pause_transform_feedback",
845    "gasm:gl.resume_transform_feedback", "gasm:net", "gasm:net.open", "gasm:net.state",
846    "gasm:net.send", "gasm:net.recv", "gasm:net.close", "gasm:fetch",
847    "gasm:fetch.request", "gasm:fetch.state", "gasm:fetch.status", "gasm:fetch.headers",
848    "gasm:fetch.read", "gasm:fetch.close", "gasm:media", "gasm:media.open",
849    "gasm:media.play", "gasm:media.pause", "gasm:media.close", "gasm:media.set_volume",
850    "gasm:media.set_lowpass", "gasm:media.caps", "gasm:media.state", "gasm:media.error",
851    "gasm:media.position", "gasm:media.duration", "gasm:media.metadata", "gasm:media.metadata_version",
852    "gasm:storage", "gasm:storage.get", "gasm:storage.set", "gasm:storage.delete",
853    "gasm:storage.count", "gasm:storage.key", "gasm:clipboard", "gasm:clipboard.set_text",
854    "gasm:clipboard.get_text", "gasm:files", "gasm:files.save", "gasm:files.state",
855    "wasi_snapshot_preview1", "wasi_snapshot_preview1.proc_exit",
856];
857
858// ---- buttons
859/// Virtual gamepad buttons (bit positions). Face buttons by position: East=A, South=B, North=X, West=Y.
860pub const GASM_BTN_A: u32 = 1 << 0;
861pub const GASM_BTN_B: u32 = 1 << 1;
862pub const GASM_BTN_X: u32 = 1 << 2;
863pub const GASM_BTN_Y: u32 = 1 << 3;
864pub const GASM_BTN_L: u32 = 1 << 4;
865pub const GASM_BTN_R: u32 = 1 << 5;
866pub const GASM_BTN_SELECT: u32 = 1 << 6;
867pub const GASM_BTN_START: u32 = 1 << 7;
868pub const GASM_BTN_UP: u32 = 1 << 8;
869pub const GASM_BTN_DOWN: u32 = 1 << 9;
870pub const GASM_BTN_LEFT: u32 = 1 << 10;
871pub const GASM_BTN_RIGHT: u32 = 1 << 11;
872
873// ---- buffer usage
874pub const GASM_BUF_COPY_DST: u32 = 0x08;
875pub const GASM_BUF_INDEX: u32 = 0x10;
876pub const GASM_BUF_VERTEX: u32 = 0x20;
877pub const GASM_BUF_UNIFORM: u32 = 0x40;
878pub const GASM_BUF_STORAGE: u32 = 0x80;
879
880// ---- shader stages
881/// Bind group layout entry visibility (WebGPU GPUShaderStage bits).
882pub const GASM_STAGE_VERTEX: u32 = 0x1;
883pub const GASM_STAGE_FRAGMENT: u32 = 0x2;
884
885// ---- index formats
886pub const GASM_INDEX_U16: u32 = 0;
887pub const GASM_INDEX_U32: u32 = 1;
888
889// ---- net states
890pub const GASM_NET_CONNECTING: u32 = 0;
891pub const GASM_NET_OPEN: u32 = 1;
892pub const GASM_NET_CLOSED: u32 = 2;
893pub const GASM_NET_ERROR: u32 = 3;
894
895// ---- fetch states
896pub const GASM_FETCH_PENDING: u32 = 0;
897pub const GASM_FETCH_HEADERS: u32 = 1;
898pub const GASM_FETCH_DONE: u32 = 2;
899pub const GASM_FETCH_FAILED: u32 = 3;
900
901// ---- media states
902pub const GASM_MEDIA_CONNECTING: u32 = 0;
903pub const GASM_MEDIA_PLAYING: u32 = 1;
904pub const GASM_MEDIA_PAUSED: u32 = 2;
905pub const GASM_MEDIA_FAILED: u32 = 3;
906pub const GASM_MEDIA_ENDED: u32 = 4;
907
908// ---- media caps
909pub const GASM_MEDIA_CAN_VOLUME: u32 = 1 << 0;
910pub const GASM_MEDIA_CAN_LOWPASS: u32 = 1 << 1;
911pub const GASM_MEDIA_CAN_METADATA: u32 = 1 << 2;
912
913// ---- input modes
914/// input_mode flags.
915pub const GASM_INPUT_KEYS_RAW: u32 = 1 << 0;
916pub const GASM_INPUT_POINTER_HIDDEN: u32 = 1 << 1;
917pub const GASM_INPUT_POINTER_LOCKED: u32 = 1 << 2;
918
919// ---- file save states
920/// gasm_files_state results.
921pub const GASM_FILES_PENDING: i32 = 0;
922pub const GASM_FILES_SAVED: i32 = 1;
923pub const GASM_FILES_FAILED: i32 = 2;
924
925// ---- storage errors
926/// gasm_storage_set results.
927pub const GASM_STORAGE_OK: i32 = 0;
928pub const GASM_STORAGE_ERR_KEY: i32 = -1;
929pub const GASM_STORAGE_ERR_SIZE: i32 = -2;
930pub const GASM_STORAGE_ERR_QUOTA: i32 = -3;
931pub const GASM_STORAGE_ERR_IO: i32 = -4;
932
933// ---- pointer
934/// pointer() layout and bits: little-endian fields at the GASM_POINTER_OFF_* byte offsets: f32 x, y (drawable px), fx, fy (frame px), dx, dy (relative motion), wheel_x, wheel_y (lines; y > 0 = down), u32 buttons, pressed, released, flags.
935pub const GASM_POINTER_BYTES: u32 = 48;
936pub const GASM_POINTER_OFF_X: u32 = 0;
937pub const GASM_POINTER_OFF_Y: u32 = 4;
938pub const GASM_POINTER_OFF_FX: u32 = 8;
939pub const GASM_POINTER_OFF_FY: u32 = 12;
940pub const GASM_POINTER_OFF_DX: u32 = 16;
941pub const GASM_POINTER_OFF_DY: u32 = 20;
942pub const GASM_POINTER_OFF_WHEEL_X: u32 = 24;
943pub const GASM_POINTER_OFF_WHEEL_Y: u32 = 28;
944pub const GASM_POINTER_OFF_BUTTONS: u32 = 32;
945pub const GASM_POINTER_OFF_PRESSED: u32 = 36;
946pub const GASM_POINTER_OFF_RELEASED: u32 = 40;
947pub const GASM_POINTER_OFF_FLAGS: u32 = 44;
948pub const GASM_MOUSE_LEFT: u32 = 1 << 0;
949pub const GASM_MOUSE_RIGHT: u32 = 1 << 1;
950pub const GASM_MOUSE_MIDDLE: u32 = 1 << 2;
951pub const GASM_MOUSE_BACK: u32 = 1 << 3;
952pub const GASM_MOUSE_FORWARD: u32 = 1 << 4;
953pub const GASM_POINTER_INSIDE: u32 = 1 << 0;
954pub const GASM_POINTER_IS_HIDDEN: u32 = 1 << 1;
955pub const GASM_POINTER_IS_LOCKED: u32 = 1 << 2;
956
957// ---- gamepad
958/// gamepad() layout: little-endian fields at the GASM_GAMEPAD_OFF_* byte offsets: u32 flags, u32 button count, u32 axis count, f32 button values (32), f32 axis values (16). Standard mapping (W3C): buttons 0 south, 1 east, 2 west, 3 north, 4/5 shoulders, 6/7 triggers, 8 select, 9 start, 10/11 stick clicks, 12-15 d-pad up/down/left/right, 16 home; axes 0/1 left stick x/y, 2/3 right stick x/y (y > 0 = down).
959pub const GASM_GAMEPAD_BYTES: u32 = 204;
960pub const GASM_GAMEPAD_BUTTONS: u32 = 32;
961pub const GASM_GAMEPAD_AXES: u32 = 16;
962pub const GASM_GAMEPAD_OFF_FLAGS: u32 = 0;
963pub const GASM_GAMEPAD_OFF_BUTTON_COUNT: u32 = 4;
964pub const GASM_GAMEPAD_OFF_AXIS_COUNT: u32 = 8;
965pub const GASM_GAMEPAD_OFF_BUTTONS: u32 = 12;
966pub const GASM_GAMEPAD_OFF_AXES: u32 = 140;
967pub const GASM_GAMEPAD_CONNECTED: u32 = 1 << 0;
968pub const GASM_GAMEPAD_STANDARD: u32 = 1 << 1;
969
970// ---- keyboard
971/// key_state() size, and the size of one key_events() record.
972pub const GASM_KEY_STATE_BYTES: u32 = 32;
973pub const GASM_KEY_EVENT_BYTES: u32 = 4;
974
975/// Physical keys (W3C KeyboardEvent.code names; layout-independent). The third column is the W3C name.
976pub mod keys {
977    pub const ESCAPE: u32 = 1;
978    pub const F1: u32 = 2;
979    pub const F2: u32 = 3;
980    pub const F3: u32 = 4;
981    pub const F4: u32 = 5;
982    pub const F5: u32 = 6;
983    pub const F6: u32 = 7;
984    pub const F7: u32 = 8;
985    pub const F8: u32 = 9;
986    pub const F9: u32 = 10;
987    pub const F10: u32 = 11;
988    pub const F11: u32 = 12;
989    pub const F12: u32 = 13;
990    pub const BACKQUOTE: u32 = 14;
991    pub const DIGIT0: u32 = 15;
992    pub const DIGIT1: u32 = 16;
993    pub const DIGIT2: u32 = 17;
994    pub const DIGIT3: u32 = 18;
995    pub const DIGIT4: u32 = 19;
996    pub const DIGIT5: u32 = 20;
997    pub const DIGIT6: u32 = 21;
998    pub const DIGIT7: u32 = 22;
999    pub const DIGIT8: u32 = 23;
1000    pub const DIGIT9: u32 = 24;
1001    pub const MINUS: u32 = 25;
1002    pub const EQUAL: u32 = 26;
1003    pub const BACKSPACE: u32 = 27;
1004    pub const TAB: u32 = 28;
1005    pub const KEY_A: u32 = 29;
1006    pub const KEY_B: u32 = 30;
1007    pub const KEY_C: u32 = 31;
1008    pub const KEY_D: u32 = 32;
1009    pub const KEY_E: u32 = 33;
1010    pub const KEY_F: u32 = 34;
1011    pub const KEY_G: u32 = 35;
1012    pub const KEY_H: u32 = 36;
1013    pub const KEY_I: u32 = 37;
1014    pub const KEY_J: u32 = 38;
1015    pub const KEY_K: u32 = 39;
1016    pub const KEY_L: u32 = 40;
1017    pub const KEY_M: u32 = 41;
1018    pub const KEY_N: u32 = 42;
1019    pub const KEY_O: u32 = 43;
1020    pub const KEY_P: u32 = 44;
1021    pub const KEY_Q: u32 = 45;
1022    pub const KEY_R: u32 = 46;
1023    pub const KEY_S: u32 = 47;
1024    pub const KEY_T: u32 = 48;
1025    pub const KEY_U: u32 = 49;
1026    pub const KEY_V: u32 = 50;
1027    pub const KEY_W: u32 = 51;
1028    pub const KEY_X: u32 = 52;
1029    pub const KEY_Y: u32 = 53;
1030    pub const KEY_Z: u32 = 54;
1031    pub const BRACKET_LEFT: u32 = 55;
1032    pub const BRACKET_RIGHT: u32 = 56;
1033    pub const BACKSLASH: u32 = 57;
1034    pub const CAPS_LOCK: u32 = 58;
1035    pub const SEMICOLON: u32 = 59;
1036    pub const QUOTE: u32 = 60;
1037    pub const ENTER: u32 = 61;
1038    pub const SHIFT_LEFT: u32 = 62;
1039    pub const INTL_BACKSLASH: u32 = 63;
1040    pub const COMMA: u32 = 64;
1041    pub const PERIOD: u32 = 65;
1042    pub const SLASH: u32 = 66;
1043    pub const SHIFT_RIGHT: u32 = 67;
1044    pub const CONTROL_LEFT: u32 = 68;
1045    pub const META_LEFT: u32 = 69;
1046    pub const ALT_LEFT: u32 = 70;
1047    pub const SPACE: u32 = 71;
1048    pub const ALT_RIGHT: u32 = 72;
1049    pub const META_RIGHT: u32 = 73;
1050    pub const CONTEXT_MENU: u32 = 74;
1051    pub const CONTROL_RIGHT: u32 = 75;
1052    pub const PRINT_SCREEN: u32 = 76;
1053    pub const SCROLL_LOCK: u32 = 77;
1054    pub const PAUSE: u32 = 78;
1055    pub const INSERT: u32 = 79;
1056    pub const HOME: u32 = 80;
1057    pub const PAGE_UP: u32 = 81;
1058    pub const DELETE: u32 = 82;
1059    pub const END: u32 = 83;
1060    pub const PAGE_DOWN: u32 = 84;
1061    pub const ARROW_UP: u32 = 85;
1062    pub const ARROW_LEFT: u32 = 86;
1063    pub const ARROW_DOWN: u32 = 87;
1064    pub const ARROW_RIGHT: u32 = 88;
1065    pub const NUM_LOCK: u32 = 89;
1066    pub const NUMPAD_DIVIDE: u32 = 90;
1067    pub const NUMPAD_MULTIPLY: u32 = 91;
1068    pub const NUMPAD_SUBTRACT: u32 = 92;
1069    pub const NUMPAD_ADD: u32 = 93;
1070    pub const NUMPAD_ENTER: u32 = 94;
1071    pub const NUMPAD_DECIMAL: u32 = 95;
1072    pub const NUMPAD0: u32 = 96;
1073    pub const NUMPAD1: u32 = 97;
1074    pub const NUMPAD2: u32 = 98;
1075    pub const NUMPAD3: u32 = 99;
1076    pub const NUMPAD4: u32 = 100;
1077    pub const NUMPAD5: u32 = 101;
1078    pub const NUMPAD6: u32 = 102;
1079    pub const NUMPAD7: u32 = 103;
1080    pub const NUMPAD8: u32 = 104;
1081    pub const NUMPAD9: u32 = 105;
1082    pub const NUMPAD_EQUAL: u32 = 106;
1083    pub const NUMPAD_COMMA: u32 = 107;
1084    pub const INTL_RO: u32 = 108;
1085    pub const INTL_YEN: u32 = 109;
1086    pub const F13: u32 = 110;
1087    pub const F14: u32 = 111;
1088    pub const F15: u32 = 112;
1089    pub const F16: u32 = 113;
1090    pub const F17: u32 = 114;
1091    pub const F18: u32 = 115;
1092    pub const F19: u32 = 116;
1093    pub const F20: u32 = 117;
1094    pub const F21: u32 = 118;
1095    pub const F22: u32 = 119;
1096    pub const F23: u32 = 120;
1097    pub const F24: u32 = 121;
1098    /// W3C names by code (index 0 is unused).
1099    pub const NAMES: [&str; 122] = [
1100        "", "Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backquote", "Digit0", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "Minus", "Equal", "Backspace", "Tab", "KeyA", "KeyB", "KeyC", "KeyD", "KeyE", "KeyF", "KeyG", "KeyH", "KeyI", "KeyJ", "KeyK", "KeyL", "KeyM", "KeyN", "KeyO", "KeyP", "KeyQ", "KeyR", "KeyS", "KeyT", "KeyU", "KeyV", "KeyW", "KeyX", "KeyY", "KeyZ", "BracketLeft", "BracketRight", "Backslash", "CapsLock", "Semicolon", "Quote", "Enter", "ShiftLeft", "IntlBackslash", "Comma", "Period", "Slash", "ShiftRight", "ControlLeft", "MetaLeft", "AltLeft", "Space", "AltRight", "MetaRight", "ContextMenu", "ControlRight", "PrintScreen", "ScrollLock", "Pause", "Insert", "Home", "PageUp", "Delete", "End", "PageDown", "ArrowUp", "ArrowLeft", "ArrowDown", "ArrowRight", "NumLock", "NumpadDivide", "NumpadMultiply", "NumpadSubtract", "NumpadAdd", "NumpadEnter", "NumpadDecimal", "Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9", "NumpadEqual", "NumpadComma", "IntlRo", "IntlYen", "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24",
1101    ];
1102}