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        /// 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.
20        pub fn utc_offset_minutes() -> i32;
21        /// Rate (Hz) at which the runner calls gasm_frame(). Default 60; 1-1000.
22        pub fn set_frame_rate(hz: f64);
23        /// Present RGBA8 pixels (bytes R,G,B,A), stride bytes per row, w,h <= 4096. Copied before returning; letterboxed by the runner.
24        pub fn video_present(rgba: *const u8, width: u32, height: u32, stride: u32);
25        /// 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.
26        pub fn video_set_aspect(num: u32, den: u32);
27        /// Format for audio_push: 8-192 kHz, 1 or 2 channels. Default 44100/2.
28        pub fn audio_config(sample_rate: u32, channels: u32);
29        /// Queue frames x channels interleaved f32 samples in [-1, 1]; the runner resamples.
30        pub fn audio_push(samples: *const f32, frames: u32);
31        /// Bitmask of GASM_BTN_* held on virtual pad player (0..3), stable within a frame.
32        pub fn input_pad(player: u32) -> u32;
33        /// 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.
34        pub fn text_input(dst: *mut u8, cap: u32) -> i32;
35        /// 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).
36        pub fn input_mode(flags: u32);
37        /// 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.
38        pub fn key_state(dst: *mut u8, len: u32) -> i32;
39        /// 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.
40        pub fn key_events(dst: *mut u8, cap: u32) -> i32;
41        /// 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.
42        pub fn pointer(dst: *mut u8, cap: u32) -> i32;
43        /// 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.
44        pub fn gamepad(slot: u32, dst: *mut u8, cap: u32) -> i32;
45        /// Device name of the gamepad in slot: its length (copied only if <= cap), or -1 if the slot is empty.
46        pub fn gamepad_name(slot: u32, dst: *mut u8, cap: u32) -> i32;
47        /// Size in bytes of asset name, -1 if it does not exist, or -2 if it is 2 GiB or larger (use asset_size64).
48        pub fn asset_size(name: *const u8, name_len: u32) -> i32;
49        /// Size in bytes of asset name (any size), or -1 if it does not exist.
50        pub fn asset_size64(name: *const u8, name_len: u32) -> i64;
51        /// Copy up to cap bytes of asset name into dst. Bytes copied, or -1 if missing.
52        pub fn asset_read(name: *const u8, name_len: u32, dst: *mut u8, cap: u32) -> i32;
53        /// Copy up to len bytes of asset name starting at offset (streaming). Bytes copied (0 at the end), or -1 if missing.
54        pub fn asset_read_at(name: *const u8, name_len: u32, offset: u32, dst: *mut u8, len: u32) -> i32;
55        /// asset_read_at with a 64-bit offset, for assets of 4 GiB and more.
56        pub fn asset_read_at64(name: *const u8, name_len: u32, offset: u64, dst: *mut u8, len: u32) -> i32;
57        /// Number of assets.
58        pub fn asset_count() -> u32;
59        /// 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.
60        pub fn asset_name(index: u32, dst: *mut u8, cap: u32) -> i32;
61        /// 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.
62        pub fn asset_version(name: *const u8, name_len: u32) -> i32;
63        /// Launch parameter value length, or -1 if unset. Copied only if length <= cap (cap = 0 queries the length).
64        pub fn param(name: *const u8, name_len: u32, dst: *mut u8, cap: u32) -> i32;
65        /// 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.
66        pub fn set_title(title: *const u8, title_len: u32);
67        /// 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")).
68        pub fn yield_frame();
69    }
70
71    #[link(wasm_import_module = "gasm:gfx")]
72    unsafe extern "C" {
73        /// Current drawable width in pixels.
74        #[link_name = "width"]
75        pub fn gfx_width() -> u32;
76        /// Current drawable height in pixels.
77        #[link_name = "height"]
78        pub fn gfx_height() -> u32;
79        /// Compile WGSL source.
80        #[link_name = "create_shader"]
81        pub fn gfx_create_shader(wgsl: *const u8, wgsl_len: u32) -> u32;
82        /// size: non-zero multiple of 4; usage: GASM_BUF_* (WebGPU GPUBufferUsage bits; COPY_DST always added).
83        #[link_name = "create_buffer"]
84        pub fn gfx_create_buffer(size: u32, usage: u32) -> u32;
85        /// GPURenderPipelineDescriptor as JSON. layout: "auto" (default) or an array of bind group layout handles.
86        #[link_name = "create_pipeline"]
87        pub fn gfx_create_pipeline(json: *const u8, json_len: u32) -> u32;
88        /// {"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}.
89        #[link_name = "create_bind_group"]
90        pub fn gfx_create_bind_group(json: *const u8, json_len: u32) -> u32;
91        /// 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"}}]}.
92        #[link_name = "create_bind_group_layout"]
93        pub fn gfx_create_bind_group_layout(json: *const u8, json_len: u32) -> u32;
94        /// 2D texture: {"size":[w,h],"format":"rgba8unorm"|"rgba8unorm-srgb","mipLevelCount":n}, w,h 1-8192. Usage is TEXTURE_BINDING | COPY_DST.
95        #[link_name = "create_texture"]
96        pub fn gfx_create_texture(json: *const u8, json_len: u32) -> u32;
97        /// Upload a tightly packed RGBA8 region (len = width*height*4) of mip level mip at (x, y). Queued like write_buffer.
98        #[link_name = "write_texture"]
99        pub fn gfx_write_texture(texture: u32, mip: u32, x: u32, y: u32, width: u32, height: u32, data: *const u8, len: u32);
100        /// GPUSamplerDescriptor subset: addressModeU/V, magFilter, minFilter, mipmapFilter, lodMinClamp, lodMaxClamp, maxAnisotropy (1-16).
101        #[link_name = "create_sampler"]
102        pub fn gfx_create_sampler(json: *const u8, json_len: u32) -> u32;
103        /// Queue a write, applied before the frame's draws. offset/len: multiples of 4.
104        #[link_name = "write_buffer"]
105        pub fn gfx_write_buffer(buffer: u32, offset: u32, data: *const u8, len: u32);
106        /// Start the frame (clears color and depth). 1 = will be shown, 0 = discarded (the guest may skip draws).
107        #[link_name = "begin_frame"]
108        pub fn gfx_begin_frame(r: f32, g: f32, b: f32, a: f32) -> u32;
109        #[link_name = "set_pipeline"]
110        pub fn gfx_set_pipeline(pipeline: u32);
111        #[link_name = "set_bind_group"]
112        pub fn gfx_set_bind_group(index: u32, bind_group: u32);
113        /// set_bind_group with count dynamic offsets (multiples of 256), one per dynamic-offset entry of the layout, in binding order.
114        #[link_name = "set_bind_group_offsets"]
115        pub fn gfx_set_bind_group_offsets(index: u32, bind_group: u32, offsets: *const u32, count: u32);
116        /// Viewport in drawable pixels (clamped to the drawable), depth range 0-1. Reset to the whole drawable by begin_frame.
117        #[link_name = "set_viewport"]
118        pub fn gfx_set_viewport(x: f32, y: f32, width: f32, height: f32, min_depth: f32, max_depth: f32);
119        /// Scissor rectangle in drawable pixels (clamped to the drawable). Reset to the whole drawable by begin_frame.
120        #[link_name = "set_scissor_rect"]
121        pub fn gfx_set_scissor_rect(x: u32, y: u32, width: u32, height: u32);
122        /// slot 0-7; buffer with GASM_BUF_VERTEX; offset a multiple of 4, at most the buffer size.
123        #[link_name = "set_vertex_buffer"]
124        pub fn gfx_set_vertex_buffer(slot: u32, buffer: u32, offset: u32);
125        /// 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.
126        #[link_name = "set_index_buffer"]
127        pub fn gfx_set_index_buffer(buffer: u32, format: u32, offset: u32);
128        /// Needs a pipeline, and a vertex buffer in every slot the pipeline reads, large enough for the vertices and instances drawn (else traps).
129        #[link_name = "draw"]
130        pub fn gfx_draw(vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32);
131        /// Like draw, plus an index buffer holding first_index + index_count indices.
132        #[link_name = "draw_indexed"]
133        pub fn gfx_draw_indexed(index_count: u32, instance_count: u32, first_index: u32, base_vertex: i32, first_instance: u32);
134        /// Submit and present.
135        #[link_name = "end_frame"]
136        pub fn gfx_end_frame();
137        /// 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.
138        #[link_name = "destroy"]
139        pub fn gfx_destroy(handle: u32);
140    }
141
142    #[link(wasm_import_module = "gasm:gl")]
143    unsafe extern "C" {
144        /// Drawable width in pixels (the default framebuffer follows it).
145        #[link_name = "width"]
146        pub fn gl_width() -> u32;
147        /// Drawable height in pixels.
148        #[link_name = "height"]
149        pub fn gl_height() -> u32;
150        /// 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.
151        #[link_name = "frame_shown"]
152        pub fn gl_frame_shown() -> u32;
153        /// Show the default framebuffer now; otherwise the runner presents at the end of the frame.
154        #[link_name = "present"]
155        pub fn gl_present();
156        /// The oldest GL error flag (GL rules: a call with an error has no effect), or 0.
157        #[link_name = "get_error"]
158        pub fn gl_get_error() -> u32;
159        /// 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).
160        #[link_name = "get_string"]
161        pub fn gl_get_string(name: u32, dst: *mut u8, cap: u32) -> i32;
162        /// Turn on a WebGL extension listed in GL_EXTENSIONS (1), or 0 if it isn't there.
163        #[link_name = "enable_extension"]
164        pub fn gl_enable_extension(name: *const u8, name_len: u32) -> u32;
165        /// The parameter's values as i32s: how many it has (copied up to count), or -1 for an invalid pname (GL_INVALID_ENUM).
166        #[link_name = "get_integerv"]
167        pub fn gl_get_integerv(pname: u32, dst: *mut u8, count: u32) -> i32;
168        /// As get_integerv, as f32s.
169        #[link_name = "get_floatv"]
170        pub fn gl_get_floatv(pname: u32, dst: *mut u8, count: u32) -> i32;
171        /// As get_integerv, as i64s.
172        #[link_name = "get_integer64v"]
173        pub fn gl_get_integer64v(pname: u32, dst: *mut u8, count: u32) -> i32;
174        /// Indexed parameters (e.g. GL_UNIFORM_BUFFER_BINDING), as i32s.
175        #[link_name = "get_integeri_v"]
176        pub fn gl_get_integeri_v(target: u32, index: u32, dst: *mut u8, count: u32) -> i32;
177        /// GL_SAMPLES or GL_NUM_SAMPLE_COUNTS of a renderbuffer format.
178        #[link_name = "get_internalformativ"]
179        pub fn gl_get_internalformativ(target: u32, internalformat: u32, pname: u32, dst: *mut u8, count: u32) -> i32;
180        /// Writes 3 i32s: range min, range max, precision.
181        #[link_name = "get_shader_precision_format"]
182        pub fn gl_get_shader_precision_format(shadertype: u32, precisiontype: u32, dst: *mut u8);
183        #[link_name = "active_texture"]
184        pub fn gl_active_texture(texture: u32);
185        #[link_name = "blend_color"]
186        pub fn gl_blend_color(red: f32, green: f32, blue: f32, alpha: f32);
187        #[link_name = "blend_equation"]
188        pub fn gl_blend_equation(mode: u32);
189        #[link_name = "blend_equation_separate"]
190        pub fn gl_blend_equation_separate(mode_rgb: u32, mode_alpha: u32);
191        #[link_name = "blend_func"]
192        pub fn gl_blend_func(sfactor: u32, dfactor: u32);
193        #[link_name = "blend_func_separate"]
194        pub fn gl_blend_func_separate(src_rgb: u32, dst_rgb: u32, src_alpha: u32, dst_alpha: u32);
195        #[link_name = "clear"]
196        pub fn gl_clear(mask: u32);
197        #[link_name = "clear_color"]
198        pub fn gl_clear_color(red: f32, green: f32, blue: f32, alpha: f32);
199        #[link_name = "clear_depthf"]
200        pub fn gl_clear_depthf(depth: f32);
201        #[link_name = "clear_stencil"]
202        pub fn gl_clear_stencil(s: i32);
203        #[link_name = "color_mask"]
204        pub fn gl_color_mask(red: u32, green: u32, blue: u32, alpha: u32);
205        #[link_name = "cull_face"]
206        pub fn gl_cull_face(mode: u32);
207        #[link_name = "depth_func"]
208        pub fn gl_depth_func(func: u32);
209        #[link_name = "depth_mask"]
210        pub fn gl_depth_mask(flag: u32);
211        #[link_name = "depth_rangef"]
212        pub fn gl_depth_rangef(near: f32, far: f32);
213        #[link_name = "disable"]
214        pub fn gl_disable(cap: u32);
215        #[link_name = "enable"]
216        pub fn gl_enable(cap: u32);
217        #[link_name = "is_enabled"]
218        pub fn gl_is_enabled(cap: u32) -> u32;
219        #[link_name = "front_face"]
220        pub fn gl_front_face(mode: u32);
221        #[link_name = "hint"]
222        pub fn gl_hint(target: u32, mode: u32);
223        #[link_name = "line_width"]
224        pub fn gl_line_width(width: f32);
225        #[link_name = "pixel_storei"]
226        pub fn gl_pixel_storei(pname: u32, param: i32);
227        #[link_name = "polygon_offset"]
228        pub fn gl_polygon_offset(factor: f32, units: f32);
229        #[link_name = "sample_coverage"]
230        pub fn gl_sample_coverage(value: f32, invert: u32);
231        #[link_name = "scissor"]
232        pub fn gl_scissor(x: i32, y: i32, width: i32, height: i32);
233        #[link_name = "viewport"]
234        pub fn gl_viewport(x: i32, y: i32, width: i32, height: i32);
235        #[link_name = "stencil_func"]
236        pub fn gl_stencil_func(func: u32, r#ref: i32, mask: u32);
237        #[link_name = "stencil_func_separate"]
238        pub fn gl_stencil_func_separate(face: u32, func: u32, r#ref: i32, mask: u32);
239        #[link_name = "stencil_mask"]
240        pub fn gl_stencil_mask(mask: u32);
241        #[link_name = "stencil_mask_separate"]
242        pub fn gl_stencil_mask_separate(face: u32, mask: u32);
243        #[link_name = "stencil_op"]
244        pub fn gl_stencil_op(fail: u32, zfail: u32, zpass: u32);
245        #[link_name = "stencil_op_separate"]
246        pub fn gl_stencil_op_separate(face: u32, sfail: u32, dpfail: u32, dppass: u32);
247        #[link_name = "finish"]
248        pub fn gl_finish();
249        #[link_name = "flush"]
250        pub fn gl_flush();
251        /// A new buffer name (glGenBuffers).
252        #[link_name = "create_buffer"]
253        pub fn gl_create_buffer() -> u32;
254        #[link_name = "delete_buffer"]
255        pub fn gl_delete_buffer(buffer: u32);
256        #[link_name = "is_buffer"]
257        pub fn gl_is_buffer(buffer: u32) -> u32;
258        #[link_name = "bind_buffer"]
259        pub fn gl_bind_buffer(target: u32, buffer: u32);
260        #[link_name = "bind_buffer_base"]
261        pub fn gl_bind_buffer_base(target: u32, index: u32, buffer: u32);
262        #[link_name = "bind_buffer_range"]
263        pub fn gl_bind_buffer_range(target: u32, index: u32, buffer: u32, offset: u32, size: u32);
264        /// len bytes from data, or zeros if data is 0.
265        #[link_name = "buffer_data"]
266        pub fn gl_buffer_data(target: u32, data: *const u8, len: u32, usage: u32);
267        #[link_name = "buffer_sub_data"]
268        pub fn gl_buffer_sub_data(target: u32, offset: u32, data: *const u8, len: u32);
269        #[link_name = "copy_buffer_sub_data"]
270        pub fn gl_copy_buffer_sub_data(read_target: u32, write_target: u32, read_offset: u32, write_offset: u32, size: u32);
271        /// Read back len bytes (glMapBufferRange for reading).
272        #[link_name = "get_buffer_sub_data"]
273        pub fn gl_get_buffer_sub_data(target: u32, offset: u32, dst: *mut u8, len: u32);
274        #[link_name = "get_buffer_parameteriv"]
275        pub fn gl_get_buffer_parameteriv(target: u32, pname: u32) -> i32;
276        #[link_name = "create_vertex_array"]
277        pub fn gl_create_vertex_array() -> u32;
278        #[link_name = "delete_vertex_array"]
279        pub fn gl_delete_vertex_array(array: u32);
280        #[link_name = "is_vertex_array"]
281        pub fn gl_is_vertex_array(array: u32) -> u32;
282        #[link_name = "bind_vertex_array"]
283        pub fn gl_bind_vertex_array(array: u32);
284        #[link_name = "enable_vertex_attrib_array"]
285        pub fn gl_enable_vertex_attrib_array(index: u32);
286        #[link_name = "disable_vertex_attrib_array"]
287        pub fn gl_disable_vertex_attrib_array(index: u32);
288        /// offset into the bound GL_ARRAY_BUFFER (no client-side arrays).
289        #[link_name = "vertex_attrib_pointer"]
290        pub fn gl_vertex_attrib_pointer(index: u32, size: i32, r#type: u32, normalized: u32, stride: i32, offset: u32);
291        #[link_name = "vertex_attrib_ipointer"]
292        pub fn gl_vertex_attrib_ipointer(index: u32, size: i32, r#type: u32, stride: i32, offset: u32);
293        #[link_name = "vertex_attrib_divisor"]
294        pub fn gl_vertex_attrib_divisor(index: u32, divisor: u32);
295        #[link_name = "vertex_attrib4f"]
296        pub fn gl_vertex_attrib4f(index: u32, x: f32, y: f32, z: f32, w: f32);
297        #[link_name = "vertex_attribi4i"]
298        pub fn gl_vertex_attribi4i(index: u32, x: i32, y: i32, z: i32, w: i32);
299        #[link_name = "vertex_attribi4ui"]
300        pub fn gl_vertex_attribi4ui(index: u32, x: u32, y: u32, z: u32, w: u32);
301        #[link_name = "get_vertex_attribiv"]
302        pub fn gl_get_vertex_attribiv(index: u32, pname: u32) -> i32;
303        /// GL_CURRENT_VERTEX_ATTRIB: 4 f32s.
304        #[link_name = "get_vertex_attribfv"]
305        pub fn gl_get_vertex_attribfv(index: u32, pname: u32, dst: *mut u8, count: u32) -> i32;
306        #[link_name = "get_vertex_attrib_offset"]
307        pub fn gl_get_vertex_attrib_offset(index: u32, pname: u32) -> u32;
308        #[link_name = "draw_arrays"]
309        pub fn gl_draw_arrays(mode: u32, first: i32, count: i32);
310        /// Indices from the bound GL_ELEMENT_ARRAY_BUFFER at offset.
311        #[link_name = "draw_elements"]
312        pub fn gl_draw_elements(mode: u32, count: i32, r#type: u32, offset: u32);
313        #[link_name = "draw_arrays_instanced"]
314        pub fn gl_draw_arrays_instanced(mode: u32, first: i32, count: i32, instances: i32);
315        #[link_name = "draw_elements_instanced"]
316        pub fn gl_draw_elements_instanced(mode: u32, count: i32, r#type: u32, offset: u32, instances: i32);
317        #[link_name = "draw_range_elements"]
318        pub fn gl_draw_range_elements(mode: u32, start: u32, end: u32, count: i32, r#type: u32, offset: u32);
319        /// count GLenums.
320        #[link_name = "draw_buffers"]
321        pub fn gl_draw_buffers(bufs: *const u8, count: u32);
322        /// count i32s (4 for GL_COLOR, 1 for GL_STENCIL).
323        #[link_name = "clear_bufferiv"]
324        pub fn gl_clear_bufferiv(buffer: u32, drawbuffer: i32, value: *const u8, count: u32);
325        #[link_name = "clear_bufferuiv"]
326        pub fn gl_clear_bufferuiv(buffer: u32, drawbuffer: i32, value: *const u8, count: u32);
327        #[link_name = "clear_bufferfv"]
328        pub fn gl_clear_bufferfv(buffer: u32, drawbuffer: i32, value: *const u8, count: u32);
329        #[link_name = "clear_bufferfi"]
330        pub fn gl_clear_bufferfi(buffer: u32, drawbuffer: i32, depth: f32, stencil: i32);
331        #[link_name = "create_texture"]
332        pub fn gl_create_texture() -> u32;
333        #[link_name = "delete_texture"]
334        pub fn gl_delete_texture(texture: u32);
335        #[link_name = "is_texture"]
336        pub fn gl_is_texture(texture: u32) -> u32;
337        #[link_name = "bind_texture"]
338        pub fn gl_bind_texture(target: u32, texture: u32);
339        #[link_name = "tex_parameteri"]
340        pub fn gl_tex_parameteri(target: u32, pname: u32, param: i32);
341        #[link_name = "tex_parameterf"]
342        pub fn gl_tex_parameterf(target: u32, pname: u32, param: f32);
343        #[link_name = "get_tex_parameteriv"]
344        pub fn gl_get_tex_parameteriv(target: u32, pname: u32) -> i32;
345        #[link_name = "get_tex_parameterfv"]
346        pub fn gl_get_tex_parameterfv(target: u32, pname: u32) -> f32;
347        /// pixels 0: no data (or, with a bound GL_PIXEL_UNPACK_BUFFER, len is the offset into it); otherwise len must cover the image.
348        #[link_name = "tex_image_2d"]
349        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);
350        #[link_name = "tex_image_3d"]
351        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);
352        #[link_name = "tex_sub_image_2d"]
353        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);
354        #[link_name = "tex_sub_image_3d"]
355        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);
356        #[link_name = "tex_storage_2d"]
357        pub fn gl_tex_storage_2d(target: u32, levels: i32, internalformat: u32, width: i32, height: i32);
358        #[link_name = "tex_storage_3d"]
359        pub fn gl_tex_storage_3d(target: u32, levels: i32, internalformat: u32, width: i32, height: i32, depth: i32);
360        #[link_name = "compressed_tex_image_2d"]
361        pub fn gl_compressed_tex_image_2d(target: u32, level: i32, internalformat: u32, width: i32, height: i32, border: i32, data: *const u8, len: u32);
362        #[link_name = "compressed_tex_image_3d"]
363        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);
364        #[link_name = "compressed_tex_sub_image_2d"]
365        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);
366        #[link_name = "compressed_tex_sub_image_3d"]
367        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);
368        #[link_name = "copy_tex_image_2d"]
369        pub fn gl_copy_tex_image_2d(target: u32, level: i32, internalformat: u32, x: i32, y: i32, width: i32, height: i32, border: i32);
370        #[link_name = "copy_tex_sub_image_2d"]
371        pub fn gl_copy_tex_sub_image_2d(target: u32, level: i32, xoffset: i32, yoffset: i32, x: i32, y: i32, width: i32, height: i32);
372        #[link_name = "copy_tex_sub_image_3d"]
373        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);
374        /// Runners generate the levels (unlike gasm:gfx).
375        #[link_name = "generate_mipmap"]
376        pub fn gl_generate_mipmap(target: u32);
377        #[link_name = "create_sampler"]
378        pub fn gl_create_sampler() -> u32;
379        #[link_name = "delete_sampler"]
380        pub fn gl_delete_sampler(sampler: u32);
381        #[link_name = "is_sampler"]
382        pub fn gl_is_sampler(sampler: u32) -> u32;
383        #[link_name = "bind_sampler"]
384        pub fn gl_bind_sampler(unit: u32, sampler: u32);
385        #[link_name = "sampler_parameteri"]
386        pub fn gl_sampler_parameteri(sampler: u32, pname: u32, param: i32);
387        #[link_name = "sampler_parameterf"]
388        pub fn gl_sampler_parameterf(sampler: u32, pname: u32, param: f32);
389        #[link_name = "get_sampler_parameteriv"]
390        pub fn gl_get_sampler_parameteriv(sampler: u32, pname: u32) -> i32;
391        #[link_name = "get_sampler_parameterfv"]
392        pub fn gl_get_sampler_parameterfv(sampler: u32, pname: u32) -> f32;
393        #[link_name = "create_framebuffer"]
394        pub fn gl_create_framebuffer() -> u32;
395        #[link_name = "delete_framebuffer"]
396        pub fn gl_delete_framebuffer(framebuffer: u32);
397        #[link_name = "is_framebuffer"]
398        pub fn gl_is_framebuffer(framebuffer: u32) -> u32;
399        /// 0: the default framebuffer (the window).
400        #[link_name = "bind_framebuffer"]
401        pub fn gl_bind_framebuffer(target: u32, framebuffer: u32);
402        #[link_name = "check_framebuffer_status"]
403        pub fn gl_check_framebuffer_status(target: u32) -> u32;
404        #[link_name = "framebuffer_texture_2d"]
405        pub fn gl_framebuffer_texture_2d(target: u32, attachment: u32, textarget: u32, texture: u32, level: i32);
406        #[link_name = "framebuffer_texture_layer"]
407        pub fn gl_framebuffer_texture_layer(target: u32, attachment: u32, texture: u32, level: i32, layer: i32);
408        #[link_name = "framebuffer_renderbuffer"]
409        pub fn gl_framebuffer_renderbuffer(target: u32, attachment: u32, renderbuffertarget: u32, renderbuffer: u32);
410        #[link_name = "get_framebuffer_attachment_parameteriv"]
411        pub fn gl_get_framebuffer_attachment_parameteriv(target: u32, attachment: u32, pname: u32) -> i32;
412        #[link_name = "blit_framebuffer"]
413        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);
414        #[link_name = "invalidate_framebuffer"]
415        pub fn gl_invalidate_framebuffer(target: u32, attachments: *const u8, count: u32);
416        #[link_name = "invalidate_sub_framebuffer"]
417        pub fn gl_invalidate_sub_framebuffer(target: u32, attachments: *const u8, count: u32, x: i32, y: i32, width: i32, height: i32);
418        #[link_name = "read_buffer"]
419        pub fn gl_read_buffer(src: u32);
420        /// len must cover the rectangle; with a bound GL_PIXEL_PACK_BUFFER, dst is the offset into it.
421        #[link_name = "read_pixels"]
422        pub fn gl_read_pixels(x: i32, y: i32, width: i32, height: i32, format: u32, r#type: u32, dst: *mut u8, len: u32);
423        #[link_name = "create_renderbuffer"]
424        pub fn gl_create_renderbuffer() -> u32;
425        #[link_name = "delete_renderbuffer"]
426        pub fn gl_delete_renderbuffer(renderbuffer: u32);
427        #[link_name = "is_renderbuffer"]
428        pub fn gl_is_renderbuffer(renderbuffer: u32) -> u32;
429        #[link_name = "bind_renderbuffer"]
430        pub fn gl_bind_renderbuffer(target: u32, renderbuffer: u32);
431        #[link_name = "renderbuffer_storage"]
432        pub fn gl_renderbuffer_storage(target: u32, internalformat: u32, width: i32, height: i32);
433        #[link_name = "renderbuffer_storage_multisample"]
434        pub fn gl_renderbuffer_storage_multisample(target: u32, samples: i32, internalformat: u32, width: i32, height: i32);
435        #[link_name = "get_renderbuffer_parameteriv"]
436        pub fn gl_get_renderbuffer_parameteriv(target: u32, pname: u32) -> i32;
437        #[link_name = "create_shader"]
438        pub fn gl_create_shader(r#type: u32) -> u32;
439        #[link_name = "delete_shader"]
440        pub fn gl_delete_shader(shader: u32);
441        #[link_name = "is_shader"]
442        pub fn gl_is_shader(shader: u32) -> u32;
443        /// GLSL ES 3.00 (or 1.00).
444        #[link_name = "shader_source"]
445        pub fn gl_shader_source(shader: u32, source: *const u8, source_len: u32);
446        #[link_name = "compile_shader"]
447        pub fn gl_compile_shader(shader: u32);
448        #[link_name = "get_shaderiv"]
449        pub fn gl_get_shaderiv(shader: u32, pname: u32) -> i32;
450        #[link_name = "get_shader_info_log"]
451        pub fn gl_get_shader_info_log(shader: u32, dst: *mut u8, cap: u32) -> i32;
452        #[link_name = "get_shader_source"]
453        pub fn gl_get_shader_source(shader: u32, dst: *mut u8, cap: u32) -> i32;
454        #[link_name = "create_program"]
455        pub fn gl_create_program() -> u32;
456        #[link_name = "delete_program"]
457        pub fn gl_delete_program(program: u32);
458        #[link_name = "is_program"]
459        pub fn gl_is_program(program: u32) -> u32;
460        #[link_name = "attach_shader"]
461        pub fn gl_attach_shader(program: u32, shader: u32);
462        #[link_name = "detach_shader"]
463        pub fn gl_detach_shader(program: u32, shader: u32);
464        #[link_name = "link_program"]
465        pub fn gl_link_program(program: u32);
466        #[link_name = "use_program"]
467        pub fn gl_use_program(program: u32);
468        #[link_name = "validate_program"]
469        pub fn gl_validate_program(program: u32);
470        #[link_name = "get_programiv"]
471        pub fn gl_get_programiv(program: u32, pname: u32) -> i32;
472        #[link_name = "get_program_info_log"]
473        pub fn gl_get_program_info_log(program: u32, dst: *mut u8, cap: u32) -> i32;
474        /// Shader names (u32), copied up to count; returns how many.
475        #[link_name = "get_attached_shaders"]
476        pub fn gl_get_attached_shaders(program: u32, dst: *mut u8, count: u32) -> i32;
477        #[link_name = "bind_attrib_location"]
478        pub fn gl_bind_attrib_location(program: u32, index: u32, name: *const u8, name_len: u32);
479        #[link_name = "get_attrib_location"]
480        pub fn gl_get_attrib_location(program: u32, name: *const u8, name_len: u32) -> i32;
481        #[link_name = "get_frag_data_location"]
482        pub fn gl_get_frag_data_location(program: u32, name: *const u8, name_len: u32) -> i32;
483        /// info: 2 i32s (size, type). Returns the name's length (copied if it fits), or -1.
484        #[link_name = "get_active_attrib"]
485        pub fn gl_get_active_attrib(program: u32, index: u32, name: *mut u8, cap: u32, info: *mut u8) -> i32;
486        #[link_name = "get_active_uniform"]
487        pub fn gl_get_active_uniform(program: u32, index: u32, name: *mut u8, cap: u32, info: *mut u8) -> i32;
488        /// -1 if the program has no such uniform.
489        #[link_name = "get_uniform_location"]
490        pub fn gl_get_uniform_location(program: u32, name: *const u8, name_len: u32) -> i32;
491        /// glGetUniformIndices for one name (GL_INVALID_INDEX if none).
492        #[link_name = "get_uniform_index"]
493        pub fn gl_get_uniform_index(program: u32, name: *const u8, name_len: u32) -> u32;
494        /// count u32 indices in, count i32s out.
495        #[link_name = "get_active_uniformsiv"]
496        pub fn gl_get_active_uniformsiv(program: u32, indices: *const u8, count: u32, pname: u32, dst: *mut u8);
497        #[link_name = "get_uniform_block_index"]
498        pub fn gl_get_uniform_block_index(program: u32, name: *const u8, name_len: u32) -> u32;
499        #[link_name = "get_active_uniform_block_name"]
500        pub fn gl_get_active_uniform_block_name(program: u32, index: u32, dst: *mut u8, cap: u32) -> i32;
501        #[link_name = "get_active_uniform_blockiv"]
502        pub fn gl_get_active_uniform_blockiv(program: u32, index: u32, pname: u32, dst: *mut u8, count: u32) -> i32;
503        #[link_name = "uniform_block_binding"]
504        pub fn gl_uniform_block_binding(program: u32, index: u32, binding: u32);
505        #[link_name = "get_uniformfv"]
506        pub fn gl_get_uniformfv(program: u32, location: i32, dst: *mut u8, count: u32) -> i32;
507        #[link_name = "get_uniformiv"]
508        pub fn gl_get_uniformiv(program: u32, location: i32, dst: *mut u8, count: u32) -> i32;
509        #[link_name = "get_uniformuiv"]
510        pub fn gl_get_uniformuiv(program: u32, location: i32, dst: *mut u8, count: u32) -> i32;
511        /// count names, each NUL-terminated, in len bytes.
512        #[link_name = "transform_feedback_varyings"]
513        pub fn gl_transform_feedback_varyings(program: u32, names: *const u8, len: u32, count: u32, buffer_mode: u32);
514        #[link_name = "get_transform_feedback_varying"]
515        pub fn gl_get_transform_feedback_varying(program: u32, index: u32, name: *mut u8, cap: u32, info: *mut u8) -> i32;
516        #[link_name = "uniform1f"]
517        pub fn gl_uniform1f(location: i32, x: f32);
518        #[link_name = "uniform2f"]
519        pub fn gl_uniform2f(location: i32, x: f32, y: f32);
520        #[link_name = "uniform3f"]
521        pub fn gl_uniform3f(location: i32, x: f32, y: f32, z: f32);
522        #[link_name = "uniform4f"]
523        pub fn gl_uniform4f(location: i32, x: f32, y: f32, z: f32, w: f32);
524        #[link_name = "uniform1i"]
525        pub fn gl_uniform1i(location: i32, x: i32);
526        #[link_name = "uniform2i"]
527        pub fn gl_uniform2i(location: i32, x: i32, y: i32);
528        #[link_name = "uniform3i"]
529        pub fn gl_uniform3i(location: i32, x: i32, y: i32, z: i32);
530        #[link_name = "uniform4i"]
531        pub fn gl_uniform4i(location: i32, x: i32, y: i32, z: i32, w: i32);
532        #[link_name = "uniform1ui"]
533        pub fn gl_uniform1ui(location: i32, x: u32);
534        #[link_name = "uniform2ui"]
535        pub fn gl_uniform2ui(location: i32, x: u32, y: u32);
536        #[link_name = "uniform3ui"]
537        pub fn gl_uniform3ui(location: i32, x: u32, y: u32, z: u32);
538        #[link_name = "uniform4ui"]
539        pub fn gl_uniform4ui(location: i32, x: u32, y: u32, z: u32, w: u32);
540        /// count vectors (GL semantics).
541        #[link_name = "uniform1fv"]
542        pub fn gl_uniform1fv(location: i32, count: i32, value: *const u8);
543        #[link_name = "uniform2fv"]
544        pub fn gl_uniform2fv(location: i32, count: i32, value: *const u8);
545        #[link_name = "uniform3fv"]
546        pub fn gl_uniform3fv(location: i32, count: i32, value: *const u8);
547        #[link_name = "uniform4fv"]
548        pub fn gl_uniform4fv(location: i32, count: i32, value: *const u8);
549        #[link_name = "uniform1iv"]
550        pub fn gl_uniform1iv(location: i32, count: i32, value: *const u8);
551        #[link_name = "uniform2iv"]
552        pub fn gl_uniform2iv(location: i32, count: i32, value: *const u8);
553        #[link_name = "uniform3iv"]
554        pub fn gl_uniform3iv(location: i32, count: i32, value: *const u8);
555        #[link_name = "uniform4iv"]
556        pub fn gl_uniform4iv(location: i32, count: i32, value: *const u8);
557        #[link_name = "uniform1uiv"]
558        pub fn gl_uniform1uiv(location: i32, count: i32, value: *const u8);
559        #[link_name = "uniform2uiv"]
560        pub fn gl_uniform2uiv(location: i32, count: i32, value: *const u8);
561        #[link_name = "uniform3uiv"]
562        pub fn gl_uniform3uiv(location: i32, count: i32, value: *const u8);
563        #[link_name = "uniform4uiv"]
564        pub fn gl_uniform4uiv(location: i32, count: i32, value: *const u8);
565        #[link_name = "uniform_matrix2fv"]
566        pub fn gl_uniform_matrix2fv(location: i32, count: i32, transpose: u32, value: *const u8);
567        #[link_name = "uniform_matrix3fv"]
568        pub fn gl_uniform_matrix3fv(location: i32, count: i32, transpose: u32, value: *const u8);
569        #[link_name = "uniform_matrix4fv"]
570        pub fn gl_uniform_matrix4fv(location: i32, count: i32, transpose: u32, value: *const u8);
571        #[link_name = "uniform_matrix2x3fv"]
572        pub fn gl_uniform_matrix2x3fv(location: i32, count: i32, transpose: u32, value: *const u8);
573        #[link_name = "uniform_matrix3x2fv"]
574        pub fn gl_uniform_matrix3x2fv(location: i32, count: i32, transpose: u32, value: *const u8);
575        #[link_name = "uniform_matrix2x4fv"]
576        pub fn gl_uniform_matrix2x4fv(location: i32, count: i32, transpose: u32, value: *const u8);
577        #[link_name = "uniform_matrix4x2fv"]
578        pub fn gl_uniform_matrix4x2fv(location: i32, count: i32, transpose: u32, value: *const u8);
579        #[link_name = "uniform_matrix3x4fv"]
580        pub fn gl_uniform_matrix3x4fv(location: i32, count: i32, transpose: u32, value: *const u8);
581        #[link_name = "uniform_matrix4x3fv"]
582        pub fn gl_uniform_matrix4x3fv(location: i32, count: i32, transpose: u32, value: *const u8);
583        #[link_name = "create_query"]
584        pub fn gl_create_query() -> u32;
585        #[link_name = "delete_query"]
586        pub fn gl_delete_query(query: u32);
587        #[link_name = "is_query"]
588        pub fn gl_is_query(query: u32) -> u32;
589        #[link_name = "begin_query"]
590        pub fn gl_begin_query(target: u32, query: u32);
591        #[link_name = "end_query"]
592        pub fn gl_end_query(target: u32);
593        /// GL_CURRENT_QUERY: the active query's name.
594        #[link_name = "get_queryiv"]
595        pub fn gl_get_queryiv(target: u32, pname: u32) -> u32;
596        /// Results are available from the next frame on, on every runner.
597        #[link_name = "get_query_objectuiv"]
598        pub fn gl_get_query_objectuiv(query: u32, pname: u32) -> u32;
599        /// A sync name (not a pointer).
600        #[link_name = "fence_sync"]
601        pub fn gl_fence_sync(condition: u32, flags: u32) -> u32;
602        #[link_name = "is_sync"]
603        pub fn gl_is_sync(sync: u32) -> u32;
604        #[link_name = "delete_sync"]
605        pub fn gl_delete_sync(sync: u32);
606        /// Signaled from the next frame on; a timeout above 0 that isn't met gives GL_TIMEOUT_EXPIRED.
607        #[link_name = "client_wait_sync"]
608        pub fn gl_client_wait_sync(sync: u32, flags: u32, timeout: u64) -> u32;
609        #[link_name = "wait_sync"]
610        pub fn gl_wait_sync(sync: u32, flags: u32, timeout: u64);
611        #[link_name = "get_synciv"]
612        pub fn gl_get_synciv(sync: u32, pname: u32) -> i32;
613        #[link_name = "create_transform_feedback"]
614        pub fn gl_create_transform_feedback() -> u32;
615        #[link_name = "delete_transform_feedback"]
616        pub fn gl_delete_transform_feedback(tf: u32);
617        #[link_name = "is_transform_feedback"]
618        pub fn gl_is_transform_feedback(tf: u32) -> u32;
619        #[link_name = "bind_transform_feedback"]
620        pub fn gl_bind_transform_feedback(target: u32, tf: u32);
621        #[link_name = "begin_transform_feedback"]
622        pub fn gl_begin_transform_feedback(primitive_mode: u32);
623        #[link_name = "end_transform_feedback"]
624        pub fn gl_end_transform_feedback();
625        #[link_name = "pause_transform_feedback"]
626        pub fn gl_pause_transform_feedback();
627        #[link_name = "resume_transform_feedback"]
628        pub fn gl_resume_transform_feedback();
629    }
630
631    #[link(wasm_import_module = "gasm:net")]
632    unsafe extern "C" {
633        /// Open a ws:// or wss:// URL. Handle > 0, or -1 if denied/invalid.
634        #[link_name = "open"]
635        pub fn net_open(url: *const u8, url_len: u32) -> i32;
636        /// GASM_NET_CONNECTING / OPEN / CLOSED / ERROR.
637        #[link_name = "state"]
638        pub fn net_state(conn: i32) -> u32;
639        /// Send one message (len > 0). 0, or -1 if not open.
640        #[link_name = "send"]
641        pub fn net_send(conn: i32, data: *const u8, len: u32) -> i32;
642        /// Next message's length (copied only if <= cap, else it stays queued), 0 if none, -1 if closed and drained.
643        #[link_name = "recv"]
644        pub fn net_recv(conn: i32, dst: *mut u8, cap: u32) -> i32;
645        /// Close (flushing queued messages); closing again does nothing.
646        #[link_name = "close"]
647        pub fn net_close(conn: i32);
648    }
649
650    #[link(wasm_import_module = "gasm:fetch")]
651    unsafe extern "C" {
652        /// 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).
653        #[link_name = "request"]
654        pub fn fetch_request(desc: *const u8, desc_len: u32, body: *const u8, body_len: u32) -> i32;
655        /// GASM_FETCH_PENDING / HEADERS (status and headers are in) / DONE (the whole body arrived) / FAILED.
656        #[link_name = "state"]
657        pub fn fetch_state(req: i32) -> u32;
658        /// HTTP status of the final response (after redirects), 0 before the headers or after a failure.
659        #[link_name = "status"]
660        pub fn fetch_status(req: i32) -> i32;
661        /// Response headers as "name: value\n" lines (names lowercase). Length (copied only if <= cap; cap = 0 queries), -1 before GASM_FETCH_HEADERS.
662        #[link_name = "headers"]
663        pub fn fetch_headers(req: i32, dst: *mut u8, cap: u32) -> i32;
664        /// 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.
665        #[link_name = "read"]
666        pub fn fetch_read(req: i32, dst: *mut u8, cap: u32) -> i32;
667        /// Cancel if still running and free the handle; closing again does nothing.
668        #[link_name = "close"]
669        pub fn fetch_close(req: i32);
670    }
671
672    #[link(wasm_import_module = "gasm:storage")]
673    unsafe extern "C" {
674        /// Value length, or -1 if missing. Copied only if length <= cap.
675        #[link_name = "get"]
676        pub fn storage_get(key: *const u8, key_len: u32, dst: *mut u8, cap: u32) -> i32;
677        /// 0, or a GASM_STORAGE_ERR_* code: invalid key, value too large, quota exceeded, I/O error.
678        #[link_name = "set"]
679        pub fn storage_set(key: *const u8, key_len: u32, data: *const u8, len: u32) -> i32;
680        /// 0 if deleted, -1 if it did not exist.
681        #[link_name = "delete"]
682        pub fn storage_delete(key: *const u8, key_len: u32) -> i32;
683        /// Number of keys in the namespace.
684        #[link_name = "count"]
685        pub fn storage_count() -> u32;
686        /// Key index (0 .. count-1, sorted): its length (copied only if <= cap; cap = 0 queries), or -1 if out of range.
687        #[link_name = "key"]
688        pub fn storage_key(index: u32, dst: *mut u8, cap: u32) -> i32;
689    }
690
691    #[link(wasm_import_module = "wasi_snapshot_preview1")]
692    unsafe extern "C" {
693        /// End the game; 0 is a normal exit.
694        pub fn proc_exit(code: i32) -> !;
695    }
696}
697
698#[cfg(target_arch = "wasm32")]
699pub use imports::*;
700
701#[cfg(not(target_arch = "wasm32"))]
702pub use crate::native::abi::*;
703
704/// Every import module and `module.function` of this ABI version (what `gasm::has` can report).
705pub const IMPORTS: [&str; 299] = [
706    "gasm", "gasm.log", "gasm.has", "gasm.time_ms",
707    "gasm.utc_offset_minutes", "gasm.set_frame_rate", "gasm.video_present", "gasm.video_set_aspect",
708    "gasm.audio_config", "gasm.audio_push", "gasm.input_pad", "gasm.text_input",
709    "gasm.input_mode", "gasm.key_state", "gasm.key_events", "gasm.pointer",
710    "gasm.gamepad", "gasm.gamepad_name", "gasm.asset_size", "gasm.asset_size64",
711    "gasm.asset_read", "gasm.asset_read_at", "gasm.asset_read_at64", "gasm.asset_count",
712    "gasm.asset_name", "gasm.asset_version", "gasm.param", "gasm.set_title",
713    "gasm.yield_frame", "gasm:gfx", "gasm:gfx.width", "gasm:gfx.height",
714    "gasm:gfx.create_shader", "gasm:gfx.create_buffer", "gasm:gfx.create_pipeline", "gasm:gfx.create_bind_group",
715    "gasm:gfx.create_bind_group_layout", "gasm:gfx.create_texture", "gasm:gfx.write_texture", "gasm:gfx.create_sampler",
716    "gasm:gfx.write_buffer", "gasm:gfx.begin_frame", "gasm:gfx.set_pipeline", "gasm:gfx.set_bind_group",
717    "gasm:gfx.set_bind_group_offsets", "gasm:gfx.set_viewport", "gasm:gfx.set_scissor_rect", "gasm:gfx.set_vertex_buffer",
718    "gasm:gfx.set_index_buffer", "gasm:gfx.draw", "gasm:gfx.draw_indexed", "gasm:gfx.end_frame",
719    "gasm:gfx.destroy", "gasm:gl", "gasm:gl.width", "gasm:gl.height",
720    "gasm:gl.frame_shown", "gasm:gl.present", "gasm:gl.get_error", "gasm:gl.get_string",
721    "gasm:gl.enable_extension", "gasm:gl.get_integerv", "gasm:gl.get_floatv", "gasm:gl.get_integer64v",
722    "gasm:gl.get_integeri_v", "gasm:gl.get_internalformativ", "gasm:gl.get_shader_precision_format", "gasm:gl.active_texture",
723    "gasm:gl.blend_color", "gasm:gl.blend_equation", "gasm:gl.blend_equation_separate", "gasm:gl.blend_func",
724    "gasm:gl.blend_func_separate", "gasm:gl.clear", "gasm:gl.clear_color", "gasm:gl.clear_depthf",
725    "gasm:gl.clear_stencil", "gasm:gl.color_mask", "gasm:gl.cull_face", "gasm:gl.depth_func",
726    "gasm:gl.depth_mask", "gasm:gl.depth_rangef", "gasm:gl.disable", "gasm:gl.enable",
727    "gasm:gl.is_enabled", "gasm:gl.front_face", "gasm:gl.hint", "gasm:gl.line_width",
728    "gasm:gl.pixel_storei", "gasm:gl.polygon_offset", "gasm:gl.sample_coverage", "gasm:gl.scissor",
729    "gasm:gl.viewport", "gasm:gl.stencil_func", "gasm:gl.stencil_func_separate", "gasm:gl.stencil_mask",
730    "gasm:gl.stencil_mask_separate", "gasm:gl.stencil_op", "gasm:gl.stencil_op_separate", "gasm:gl.finish",
731    "gasm:gl.flush", "gasm:gl.create_buffer", "gasm:gl.delete_buffer", "gasm:gl.is_buffer",
732    "gasm:gl.bind_buffer", "gasm:gl.bind_buffer_base", "gasm:gl.bind_buffer_range", "gasm:gl.buffer_data",
733    "gasm:gl.buffer_sub_data", "gasm:gl.copy_buffer_sub_data", "gasm:gl.get_buffer_sub_data", "gasm:gl.get_buffer_parameteriv",
734    "gasm:gl.create_vertex_array", "gasm:gl.delete_vertex_array", "gasm:gl.is_vertex_array", "gasm:gl.bind_vertex_array",
735    "gasm:gl.enable_vertex_attrib_array", "gasm:gl.disable_vertex_attrib_array", "gasm:gl.vertex_attrib_pointer", "gasm:gl.vertex_attrib_ipointer",
736    "gasm:gl.vertex_attrib_divisor", "gasm:gl.vertex_attrib4f", "gasm:gl.vertex_attribi4i", "gasm:gl.vertex_attribi4ui",
737    "gasm:gl.get_vertex_attribiv", "gasm:gl.get_vertex_attribfv", "gasm:gl.get_vertex_attrib_offset", "gasm:gl.draw_arrays",
738    "gasm:gl.draw_elements", "gasm:gl.draw_arrays_instanced", "gasm:gl.draw_elements_instanced", "gasm:gl.draw_range_elements",
739    "gasm:gl.draw_buffers", "gasm:gl.clear_bufferiv", "gasm:gl.clear_bufferuiv", "gasm:gl.clear_bufferfv",
740    "gasm:gl.clear_bufferfi", "gasm:gl.create_texture", "gasm:gl.delete_texture", "gasm:gl.is_texture",
741    "gasm:gl.bind_texture", "gasm:gl.tex_parameteri", "gasm:gl.tex_parameterf", "gasm:gl.get_tex_parameteriv",
742    "gasm:gl.get_tex_parameterfv", "gasm:gl.tex_image_2d", "gasm:gl.tex_image_3d", "gasm:gl.tex_sub_image_2d",
743    "gasm:gl.tex_sub_image_3d", "gasm:gl.tex_storage_2d", "gasm:gl.tex_storage_3d", "gasm:gl.compressed_tex_image_2d",
744    "gasm:gl.compressed_tex_image_3d", "gasm:gl.compressed_tex_sub_image_2d", "gasm:gl.compressed_tex_sub_image_3d", "gasm:gl.copy_tex_image_2d",
745    "gasm:gl.copy_tex_sub_image_2d", "gasm:gl.copy_tex_sub_image_3d", "gasm:gl.generate_mipmap", "gasm:gl.create_sampler",
746    "gasm:gl.delete_sampler", "gasm:gl.is_sampler", "gasm:gl.bind_sampler", "gasm:gl.sampler_parameteri",
747    "gasm:gl.sampler_parameterf", "gasm:gl.get_sampler_parameteriv", "gasm:gl.get_sampler_parameterfv", "gasm:gl.create_framebuffer",
748    "gasm:gl.delete_framebuffer", "gasm:gl.is_framebuffer", "gasm:gl.bind_framebuffer", "gasm:gl.check_framebuffer_status",
749    "gasm:gl.framebuffer_texture_2d", "gasm:gl.framebuffer_texture_layer", "gasm:gl.framebuffer_renderbuffer", "gasm:gl.get_framebuffer_attachment_parameteriv",
750    "gasm:gl.blit_framebuffer", "gasm:gl.invalidate_framebuffer", "gasm:gl.invalidate_sub_framebuffer", "gasm:gl.read_buffer",
751    "gasm:gl.read_pixels", "gasm:gl.create_renderbuffer", "gasm:gl.delete_renderbuffer", "gasm:gl.is_renderbuffer",
752    "gasm:gl.bind_renderbuffer", "gasm:gl.renderbuffer_storage", "gasm:gl.renderbuffer_storage_multisample", "gasm:gl.get_renderbuffer_parameteriv",
753    "gasm:gl.create_shader", "gasm:gl.delete_shader", "gasm:gl.is_shader", "gasm:gl.shader_source",
754    "gasm:gl.compile_shader", "gasm:gl.get_shaderiv", "gasm:gl.get_shader_info_log", "gasm:gl.get_shader_source",
755    "gasm:gl.create_program", "gasm:gl.delete_program", "gasm:gl.is_program", "gasm:gl.attach_shader",
756    "gasm:gl.detach_shader", "gasm:gl.link_program", "gasm:gl.use_program", "gasm:gl.validate_program",
757    "gasm:gl.get_programiv", "gasm:gl.get_program_info_log", "gasm:gl.get_attached_shaders", "gasm:gl.bind_attrib_location",
758    "gasm:gl.get_attrib_location", "gasm:gl.get_frag_data_location", "gasm:gl.get_active_attrib", "gasm:gl.get_active_uniform",
759    "gasm:gl.get_uniform_location", "gasm:gl.get_uniform_index", "gasm:gl.get_active_uniformsiv", "gasm:gl.get_uniform_block_index",
760    "gasm:gl.get_active_uniform_block_name", "gasm:gl.get_active_uniform_blockiv", "gasm:gl.uniform_block_binding", "gasm:gl.get_uniformfv",
761    "gasm:gl.get_uniformiv", "gasm:gl.get_uniformuiv", "gasm:gl.transform_feedback_varyings", "gasm:gl.get_transform_feedback_varying",
762    "gasm:gl.uniform1f", "gasm:gl.uniform2f", "gasm:gl.uniform3f", "gasm:gl.uniform4f",
763    "gasm:gl.uniform1i", "gasm:gl.uniform2i", "gasm:gl.uniform3i", "gasm:gl.uniform4i",
764    "gasm:gl.uniform1ui", "gasm:gl.uniform2ui", "gasm:gl.uniform3ui", "gasm:gl.uniform4ui",
765    "gasm:gl.uniform1fv", "gasm:gl.uniform2fv", "gasm:gl.uniform3fv", "gasm:gl.uniform4fv",
766    "gasm:gl.uniform1iv", "gasm:gl.uniform2iv", "gasm:gl.uniform3iv", "gasm:gl.uniform4iv",
767    "gasm:gl.uniform1uiv", "gasm:gl.uniform2uiv", "gasm:gl.uniform3uiv", "gasm:gl.uniform4uiv",
768    "gasm:gl.uniform_matrix2fv", "gasm:gl.uniform_matrix3fv", "gasm:gl.uniform_matrix4fv", "gasm:gl.uniform_matrix2x3fv",
769    "gasm:gl.uniform_matrix3x2fv", "gasm:gl.uniform_matrix2x4fv", "gasm:gl.uniform_matrix4x2fv", "gasm:gl.uniform_matrix3x4fv",
770    "gasm:gl.uniform_matrix4x3fv", "gasm:gl.create_query", "gasm:gl.delete_query", "gasm:gl.is_query",
771    "gasm:gl.begin_query", "gasm:gl.end_query", "gasm:gl.get_queryiv", "gasm:gl.get_query_objectuiv",
772    "gasm:gl.fence_sync", "gasm:gl.is_sync", "gasm:gl.delete_sync", "gasm:gl.client_wait_sync",
773    "gasm:gl.wait_sync", "gasm:gl.get_synciv", "gasm:gl.create_transform_feedback", "gasm:gl.delete_transform_feedback",
774    "gasm:gl.is_transform_feedback", "gasm:gl.bind_transform_feedback", "gasm:gl.begin_transform_feedback", "gasm:gl.end_transform_feedback",
775    "gasm:gl.pause_transform_feedback", "gasm:gl.resume_transform_feedback", "gasm:net", "gasm:net.open",
776    "gasm:net.state", "gasm:net.send", "gasm:net.recv", "gasm:net.close",
777    "gasm:fetch", "gasm:fetch.request", "gasm:fetch.state", "gasm:fetch.status",
778    "gasm:fetch.headers", "gasm:fetch.read", "gasm:fetch.close", "gasm:storage",
779    "gasm:storage.get", "gasm:storage.set", "gasm:storage.delete", "gasm:storage.count",
780    "gasm:storage.key", "wasi_snapshot_preview1", "wasi_snapshot_preview1.proc_exit",
781];
782
783// ---- buttons
784/// Virtual gamepad buttons (bit positions). Face buttons by position: East=A, South=B, North=X, West=Y.
785pub const GASM_BTN_A: u32 = 1 << 0;
786pub const GASM_BTN_B: u32 = 1 << 1;
787pub const GASM_BTN_X: u32 = 1 << 2;
788pub const GASM_BTN_Y: u32 = 1 << 3;
789pub const GASM_BTN_L: u32 = 1 << 4;
790pub const GASM_BTN_R: u32 = 1 << 5;
791pub const GASM_BTN_SELECT: u32 = 1 << 6;
792pub const GASM_BTN_START: u32 = 1 << 7;
793pub const GASM_BTN_UP: u32 = 1 << 8;
794pub const GASM_BTN_DOWN: u32 = 1 << 9;
795pub const GASM_BTN_LEFT: u32 = 1 << 10;
796pub const GASM_BTN_RIGHT: u32 = 1 << 11;
797
798// ---- buffer usage
799pub const GASM_BUF_COPY_DST: u32 = 0x08;
800pub const GASM_BUF_INDEX: u32 = 0x10;
801pub const GASM_BUF_VERTEX: u32 = 0x20;
802pub const GASM_BUF_UNIFORM: u32 = 0x40;
803pub const GASM_BUF_STORAGE: u32 = 0x80;
804
805// ---- shader stages
806/// Bind group layout entry visibility (WebGPU GPUShaderStage bits).
807pub const GASM_STAGE_VERTEX: u32 = 0x1;
808pub const GASM_STAGE_FRAGMENT: u32 = 0x2;
809
810// ---- index formats
811pub const GASM_INDEX_U16: u32 = 0;
812pub const GASM_INDEX_U32: u32 = 1;
813
814// ---- net states
815pub const GASM_NET_CONNECTING: u32 = 0;
816pub const GASM_NET_OPEN: u32 = 1;
817pub const GASM_NET_CLOSED: u32 = 2;
818pub const GASM_NET_ERROR: u32 = 3;
819
820// ---- fetch states
821pub const GASM_FETCH_PENDING: u32 = 0;
822pub const GASM_FETCH_HEADERS: u32 = 1;
823pub const GASM_FETCH_DONE: u32 = 2;
824pub const GASM_FETCH_FAILED: u32 = 3;
825
826// ---- input modes
827/// input_mode flags.
828pub const GASM_INPUT_KEYS_RAW: u32 = 1 << 0;
829pub const GASM_INPUT_POINTER_HIDDEN: u32 = 1 << 1;
830pub const GASM_INPUT_POINTER_LOCKED: u32 = 1 << 2;
831
832// ---- storage errors
833/// gasm_storage_set results.
834pub const GASM_STORAGE_OK: i32 = 0;
835pub const GASM_STORAGE_ERR_KEY: i32 = -1;
836pub const GASM_STORAGE_ERR_SIZE: i32 = -2;
837pub const GASM_STORAGE_ERR_QUOTA: i32 = -3;
838pub const GASM_STORAGE_ERR_IO: i32 = -4;
839
840// ---- pointer
841/// 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.
842pub const GASM_POINTER_BYTES: u32 = 48;
843pub const GASM_POINTER_OFF_X: u32 = 0;
844pub const GASM_POINTER_OFF_Y: u32 = 4;
845pub const GASM_POINTER_OFF_FX: u32 = 8;
846pub const GASM_POINTER_OFF_FY: u32 = 12;
847pub const GASM_POINTER_OFF_DX: u32 = 16;
848pub const GASM_POINTER_OFF_DY: u32 = 20;
849pub const GASM_POINTER_OFF_WHEEL_X: u32 = 24;
850pub const GASM_POINTER_OFF_WHEEL_Y: u32 = 28;
851pub const GASM_POINTER_OFF_BUTTONS: u32 = 32;
852pub const GASM_POINTER_OFF_PRESSED: u32 = 36;
853pub const GASM_POINTER_OFF_RELEASED: u32 = 40;
854pub const GASM_POINTER_OFF_FLAGS: u32 = 44;
855pub const GASM_MOUSE_LEFT: u32 = 1 << 0;
856pub const GASM_MOUSE_RIGHT: u32 = 1 << 1;
857pub const GASM_MOUSE_MIDDLE: u32 = 1 << 2;
858pub const GASM_MOUSE_BACK: u32 = 1 << 3;
859pub const GASM_MOUSE_FORWARD: u32 = 1 << 4;
860pub const GASM_POINTER_INSIDE: u32 = 1 << 0;
861pub const GASM_POINTER_IS_HIDDEN: u32 = 1 << 1;
862pub const GASM_POINTER_IS_LOCKED: u32 = 1 << 2;
863
864// ---- gamepad
865/// 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).
866pub const GASM_GAMEPAD_BYTES: u32 = 204;
867pub const GASM_GAMEPAD_BUTTONS: u32 = 32;
868pub const GASM_GAMEPAD_AXES: u32 = 16;
869pub const GASM_GAMEPAD_OFF_FLAGS: u32 = 0;
870pub const GASM_GAMEPAD_OFF_BUTTON_COUNT: u32 = 4;
871pub const GASM_GAMEPAD_OFF_AXIS_COUNT: u32 = 8;
872pub const GASM_GAMEPAD_OFF_BUTTONS: u32 = 12;
873pub const GASM_GAMEPAD_OFF_AXES: u32 = 140;
874pub const GASM_GAMEPAD_CONNECTED: u32 = 1 << 0;
875pub const GASM_GAMEPAD_STANDARD: u32 = 1 << 1;
876
877// ---- keyboard
878/// key_state() size, and the size of one key_events() record.
879pub const GASM_KEY_STATE_BYTES: u32 = 32;
880pub const GASM_KEY_EVENT_BYTES: u32 = 4;
881
882/// Physical keys (W3C KeyboardEvent.code names; layout-independent). The third column is the W3C name.
883pub mod keys {
884    pub const ESCAPE: u32 = 1;
885    pub const F1: u32 = 2;
886    pub const F2: u32 = 3;
887    pub const F3: u32 = 4;
888    pub const F4: u32 = 5;
889    pub const F5: u32 = 6;
890    pub const F6: u32 = 7;
891    pub const F7: u32 = 8;
892    pub const F8: u32 = 9;
893    pub const F9: u32 = 10;
894    pub const F10: u32 = 11;
895    pub const F11: u32 = 12;
896    pub const F12: u32 = 13;
897    pub const BACKQUOTE: u32 = 14;
898    pub const DIGIT0: u32 = 15;
899    pub const DIGIT1: u32 = 16;
900    pub const DIGIT2: u32 = 17;
901    pub const DIGIT3: u32 = 18;
902    pub const DIGIT4: u32 = 19;
903    pub const DIGIT5: u32 = 20;
904    pub const DIGIT6: u32 = 21;
905    pub const DIGIT7: u32 = 22;
906    pub const DIGIT8: u32 = 23;
907    pub const DIGIT9: u32 = 24;
908    pub const MINUS: u32 = 25;
909    pub const EQUAL: u32 = 26;
910    pub const BACKSPACE: u32 = 27;
911    pub const TAB: u32 = 28;
912    pub const KEY_A: u32 = 29;
913    pub const KEY_B: u32 = 30;
914    pub const KEY_C: u32 = 31;
915    pub const KEY_D: u32 = 32;
916    pub const KEY_E: u32 = 33;
917    pub const KEY_F: u32 = 34;
918    pub const KEY_G: u32 = 35;
919    pub const KEY_H: u32 = 36;
920    pub const KEY_I: u32 = 37;
921    pub const KEY_J: u32 = 38;
922    pub const KEY_K: u32 = 39;
923    pub const KEY_L: u32 = 40;
924    pub const KEY_M: u32 = 41;
925    pub const KEY_N: u32 = 42;
926    pub const KEY_O: u32 = 43;
927    pub const KEY_P: u32 = 44;
928    pub const KEY_Q: u32 = 45;
929    pub const KEY_R: u32 = 46;
930    pub const KEY_S: u32 = 47;
931    pub const KEY_T: u32 = 48;
932    pub const KEY_U: u32 = 49;
933    pub const KEY_V: u32 = 50;
934    pub const KEY_W: u32 = 51;
935    pub const KEY_X: u32 = 52;
936    pub const KEY_Y: u32 = 53;
937    pub const KEY_Z: u32 = 54;
938    pub const BRACKET_LEFT: u32 = 55;
939    pub const BRACKET_RIGHT: u32 = 56;
940    pub const BACKSLASH: u32 = 57;
941    pub const CAPS_LOCK: u32 = 58;
942    pub const SEMICOLON: u32 = 59;
943    pub const QUOTE: u32 = 60;
944    pub const ENTER: u32 = 61;
945    pub const SHIFT_LEFT: u32 = 62;
946    pub const INTL_BACKSLASH: u32 = 63;
947    pub const COMMA: u32 = 64;
948    pub const PERIOD: u32 = 65;
949    pub const SLASH: u32 = 66;
950    pub const SHIFT_RIGHT: u32 = 67;
951    pub const CONTROL_LEFT: u32 = 68;
952    pub const META_LEFT: u32 = 69;
953    pub const ALT_LEFT: u32 = 70;
954    pub const SPACE: u32 = 71;
955    pub const ALT_RIGHT: u32 = 72;
956    pub const META_RIGHT: u32 = 73;
957    pub const CONTEXT_MENU: u32 = 74;
958    pub const CONTROL_RIGHT: u32 = 75;
959    pub const PRINT_SCREEN: u32 = 76;
960    pub const SCROLL_LOCK: u32 = 77;
961    pub const PAUSE: u32 = 78;
962    pub const INSERT: u32 = 79;
963    pub const HOME: u32 = 80;
964    pub const PAGE_UP: u32 = 81;
965    pub const DELETE: u32 = 82;
966    pub const END: u32 = 83;
967    pub const PAGE_DOWN: u32 = 84;
968    pub const ARROW_UP: u32 = 85;
969    pub const ARROW_LEFT: u32 = 86;
970    pub const ARROW_DOWN: u32 = 87;
971    pub const ARROW_RIGHT: u32 = 88;
972    pub const NUM_LOCK: u32 = 89;
973    pub const NUMPAD_DIVIDE: u32 = 90;
974    pub const NUMPAD_MULTIPLY: u32 = 91;
975    pub const NUMPAD_SUBTRACT: u32 = 92;
976    pub const NUMPAD_ADD: u32 = 93;
977    pub const NUMPAD_ENTER: u32 = 94;
978    pub const NUMPAD_DECIMAL: u32 = 95;
979    pub const NUMPAD0: u32 = 96;
980    pub const NUMPAD1: u32 = 97;
981    pub const NUMPAD2: u32 = 98;
982    pub const NUMPAD3: u32 = 99;
983    pub const NUMPAD4: u32 = 100;
984    pub const NUMPAD5: u32 = 101;
985    pub const NUMPAD6: u32 = 102;
986    pub const NUMPAD7: u32 = 103;
987    pub const NUMPAD8: u32 = 104;
988    pub const NUMPAD9: u32 = 105;
989    pub const NUMPAD_EQUAL: u32 = 106;
990    pub const NUMPAD_COMMA: u32 = 107;
991    pub const INTL_RO: u32 = 108;
992    pub const INTL_YEN: u32 = 109;
993    pub const F13: u32 = 110;
994    pub const F14: u32 = 111;
995    pub const F15: u32 = 112;
996    pub const F16: u32 = 113;
997    pub const F17: u32 = 114;
998    pub const F18: u32 = 115;
999    pub const F19: u32 = 116;
1000    pub const F20: u32 = 117;
1001    pub const F21: u32 = 118;
1002    pub const F22: u32 = 119;
1003    pub const F23: u32 = 120;
1004    pub const F24: u32 = 121;
1005    /// W3C names by code (index 0 is unused).
1006    pub const NAMES: [&str; 122] = [
1007        "", "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",
1008    ];
1009}