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 = "gasm:clipboard")]
692    unsafe extern "C" {
693        /// 0: the runner puts it on the clipboard after this frame; -1: refused (over 1 MiB, or no clipboard). Invalid UTF-8 traps.
694        #[link_name = "set_text"]
695        pub fn clipboard_set_text(text: *const u8, text_len: u32) -> i32;
696        /// 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.
697        #[link_name = "get_text"]
698        pub fn clipboard_get_text(dst: *mut u8, cap: u32) -> i32;
699    }
700
701    #[link(wasm_import_module = "gasm:files")]
702    unsafe extern "C" {
703        /// 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.
704        #[link_name = "save"]
705        pub fn files_save(name: *const u8, name_len: u32, mime: *const u8, mime_len: u32, data: *const u8, len: u32) -> i32;
706        /// GASM_FILES_PENDING (0), GASM_FILES_SAVED (1) or GASM_FILES_FAILED (2: cancelled or not written). A handle save never returned traps.
707        #[link_name = "state"]
708        pub fn files_state(handle: i32) -> i32;
709    }
710
711    #[link(wasm_import_module = "wasi_snapshot_preview1")]
712    unsafe extern "C" {
713        /// End the game; 0 is a normal exit.
714        pub fn proc_exit(code: i32) -> !;
715    }
716}
717
718#[cfg(target_arch = "wasm32")]
719pub use imports::*;
720
721#[cfg(not(target_arch = "wasm32"))]
722pub use crate::native::abi::*;
723
724/// Every import module and `module.function` of this ABI version (what `gasm::has` can report).
725pub const IMPORTS: [&str; 305] = [
726    "gasm", "gasm.log", "gasm.has", "gasm.time_ms",
727    "gasm.utc_offset_minutes", "gasm.set_frame_rate", "gasm.video_present", "gasm.video_set_aspect",
728    "gasm.audio_config", "gasm.audio_push", "gasm.input_pad", "gasm.text_input",
729    "gasm.input_mode", "gasm.key_state", "gasm.key_events", "gasm.pointer",
730    "gasm.gamepad", "gasm.gamepad_name", "gasm.asset_size", "gasm.asset_size64",
731    "gasm.asset_read", "gasm.asset_read_at", "gasm.asset_read_at64", "gasm.asset_count",
732    "gasm.asset_name", "gasm.asset_version", "gasm.param", "gasm.set_title",
733    "gasm.yield_frame", "gasm:gfx", "gasm:gfx.width", "gasm:gfx.height",
734    "gasm:gfx.create_shader", "gasm:gfx.create_buffer", "gasm:gfx.create_pipeline", "gasm:gfx.create_bind_group",
735    "gasm:gfx.create_bind_group_layout", "gasm:gfx.create_texture", "gasm:gfx.write_texture", "gasm:gfx.create_sampler",
736    "gasm:gfx.write_buffer", "gasm:gfx.begin_frame", "gasm:gfx.set_pipeline", "gasm:gfx.set_bind_group",
737    "gasm:gfx.set_bind_group_offsets", "gasm:gfx.set_viewport", "gasm:gfx.set_scissor_rect", "gasm:gfx.set_vertex_buffer",
738    "gasm:gfx.set_index_buffer", "gasm:gfx.draw", "gasm:gfx.draw_indexed", "gasm:gfx.end_frame",
739    "gasm:gfx.destroy", "gasm:gl", "gasm:gl.width", "gasm:gl.height",
740    "gasm:gl.frame_shown", "gasm:gl.present", "gasm:gl.get_error", "gasm:gl.get_string",
741    "gasm:gl.enable_extension", "gasm:gl.get_integerv", "gasm:gl.get_floatv", "gasm:gl.get_integer64v",
742    "gasm:gl.get_integeri_v", "gasm:gl.get_internalformativ", "gasm:gl.get_shader_precision_format", "gasm:gl.active_texture",
743    "gasm:gl.blend_color", "gasm:gl.blend_equation", "gasm:gl.blend_equation_separate", "gasm:gl.blend_func",
744    "gasm:gl.blend_func_separate", "gasm:gl.clear", "gasm:gl.clear_color", "gasm:gl.clear_depthf",
745    "gasm:gl.clear_stencil", "gasm:gl.color_mask", "gasm:gl.cull_face", "gasm:gl.depth_func",
746    "gasm:gl.depth_mask", "gasm:gl.depth_rangef", "gasm:gl.disable", "gasm:gl.enable",
747    "gasm:gl.is_enabled", "gasm:gl.front_face", "gasm:gl.hint", "gasm:gl.line_width",
748    "gasm:gl.pixel_storei", "gasm:gl.polygon_offset", "gasm:gl.sample_coverage", "gasm:gl.scissor",
749    "gasm:gl.viewport", "gasm:gl.stencil_func", "gasm:gl.stencil_func_separate", "gasm:gl.stencil_mask",
750    "gasm:gl.stencil_mask_separate", "gasm:gl.stencil_op", "gasm:gl.stencil_op_separate", "gasm:gl.finish",
751    "gasm:gl.flush", "gasm:gl.create_buffer", "gasm:gl.delete_buffer", "gasm:gl.is_buffer",
752    "gasm:gl.bind_buffer", "gasm:gl.bind_buffer_base", "gasm:gl.bind_buffer_range", "gasm:gl.buffer_data",
753    "gasm:gl.buffer_sub_data", "gasm:gl.copy_buffer_sub_data", "gasm:gl.get_buffer_sub_data", "gasm:gl.get_buffer_parameteriv",
754    "gasm:gl.create_vertex_array", "gasm:gl.delete_vertex_array", "gasm:gl.is_vertex_array", "gasm:gl.bind_vertex_array",
755    "gasm:gl.enable_vertex_attrib_array", "gasm:gl.disable_vertex_attrib_array", "gasm:gl.vertex_attrib_pointer", "gasm:gl.vertex_attrib_ipointer",
756    "gasm:gl.vertex_attrib_divisor", "gasm:gl.vertex_attrib4f", "gasm:gl.vertex_attribi4i", "gasm:gl.vertex_attribi4ui",
757    "gasm:gl.get_vertex_attribiv", "gasm:gl.get_vertex_attribfv", "gasm:gl.get_vertex_attrib_offset", "gasm:gl.draw_arrays",
758    "gasm:gl.draw_elements", "gasm:gl.draw_arrays_instanced", "gasm:gl.draw_elements_instanced", "gasm:gl.draw_range_elements",
759    "gasm:gl.draw_buffers", "gasm:gl.clear_bufferiv", "gasm:gl.clear_bufferuiv", "gasm:gl.clear_bufferfv",
760    "gasm:gl.clear_bufferfi", "gasm:gl.create_texture", "gasm:gl.delete_texture", "gasm:gl.is_texture",
761    "gasm:gl.bind_texture", "gasm:gl.tex_parameteri", "gasm:gl.tex_parameterf", "gasm:gl.get_tex_parameteriv",
762    "gasm:gl.get_tex_parameterfv", "gasm:gl.tex_image_2d", "gasm:gl.tex_image_3d", "gasm:gl.tex_sub_image_2d",
763    "gasm:gl.tex_sub_image_3d", "gasm:gl.tex_storage_2d", "gasm:gl.tex_storage_3d", "gasm:gl.compressed_tex_image_2d",
764    "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",
765    "gasm:gl.copy_tex_sub_image_2d", "gasm:gl.copy_tex_sub_image_3d", "gasm:gl.generate_mipmap", "gasm:gl.create_sampler",
766    "gasm:gl.delete_sampler", "gasm:gl.is_sampler", "gasm:gl.bind_sampler", "gasm:gl.sampler_parameteri",
767    "gasm:gl.sampler_parameterf", "gasm:gl.get_sampler_parameteriv", "gasm:gl.get_sampler_parameterfv", "gasm:gl.create_framebuffer",
768    "gasm:gl.delete_framebuffer", "gasm:gl.is_framebuffer", "gasm:gl.bind_framebuffer", "gasm:gl.check_framebuffer_status",
769    "gasm:gl.framebuffer_texture_2d", "gasm:gl.framebuffer_texture_layer", "gasm:gl.framebuffer_renderbuffer", "gasm:gl.get_framebuffer_attachment_parameteriv",
770    "gasm:gl.blit_framebuffer", "gasm:gl.invalidate_framebuffer", "gasm:gl.invalidate_sub_framebuffer", "gasm:gl.read_buffer",
771    "gasm:gl.read_pixels", "gasm:gl.create_renderbuffer", "gasm:gl.delete_renderbuffer", "gasm:gl.is_renderbuffer",
772    "gasm:gl.bind_renderbuffer", "gasm:gl.renderbuffer_storage", "gasm:gl.renderbuffer_storage_multisample", "gasm:gl.get_renderbuffer_parameteriv",
773    "gasm:gl.create_shader", "gasm:gl.delete_shader", "gasm:gl.is_shader", "gasm:gl.shader_source",
774    "gasm:gl.compile_shader", "gasm:gl.get_shaderiv", "gasm:gl.get_shader_info_log", "gasm:gl.get_shader_source",
775    "gasm:gl.create_program", "gasm:gl.delete_program", "gasm:gl.is_program", "gasm:gl.attach_shader",
776    "gasm:gl.detach_shader", "gasm:gl.link_program", "gasm:gl.use_program", "gasm:gl.validate_program",
777    "gasm:gl.get_programiv", "gasm:gl.get_program_info_log", "gasm:gl.get_attached_shaders", "gasm:gl.bind_attrib_location",
778    "gasm:gl.get_attrib_location", "gasm:gl.get_frag_data_location", "gasm:gl.get_active_attrib", "gasm:gl.get_active_uniform",
779    "gasm:gl.get_uniform_location", "gasm:gl.get_uniform_index", "gasm:gl.get_active_uniformsiv", "gasm:gl.get_uniform_block_index",
780    "gasm:gl.get_active_uniform_block_name", "gasm:gl.get_active_uniform_blockiv", "gasm:gl.uniform_block_binding", "gasm:gl.get_uniformfv",
781    "gasm:gl.get_uniformiv", "gasm:gl.get_uniformuiv", "gasm:gl.transform_feedback_varyings", "gasm:gl.get_transform_feedback_varying",
782    "gasm:gl.uniform1f", "gasm:gl.uniform2f", "gasm:gl.uniform3f", "gasm:gl.uniform4f",
783    "gasm:gl.uniform1i", "gasm:gl.uniform2i", "gasm:gl.uniform3i", "gasm:gl.uniform4i",
784    "gasm:gl.uniform1ui", "gasm:gl.uniform2ui", "gasm:gl.uniform3ui", "gasm:gl.uniform4ui",
785    "gasm:gl.uniform1fv", "gasm:gl.uniform2fv", "gasm:gl.uniform3fv", "gasm:gl.uniform4fv",
786    "gasm:gl.uniform1iv", "gasm:gl.uniform2iv", "gasm:gl.uniform3iv", "gasm:gl.uniform4iv",
787    "gasm:gl.uniform1uiv", "gasm:gl.uniform2uiv", "gasm:gl.uniform3uiv", "gasm:gl.uniform4uiv",
788    "gasm:gl.uniform_matrix2fv", "gasm:gl.uniform_matrix3fv", "gasm:gl.uniform_matrix4fv", "gasm:gl.uniform_matrix2x3fv",
789    "gasm:gl.uniform_matrix3x2fv", "gasm:gl.uniform_matrix2x4fv", "gasm:gl.uniform_matrix4x2fv", "gasm:gl.uniform_matrix3x4fv",
790    "gasm:gl.uniform_matrix4x3fv", "gasm:gl.create_query", "gasm:gl.delete_query", "gasm:gl.is_query",
791    "gasm:gl.begin_query", "gasm:gl.end_query", "gasm:gl.get_queryiv", "gasm:gl.get_query_objectuiv",
792    "gasm:gl.fence_sync", "gasm:gl.is_sync", "gasm:gl.delete_sync", "gasm:gl.client_wait_sync",
793    "gasm:gl.wait_sync", "gasm:gl.get_synciv", "gasm:gl.create_transform_feedback", "gasm:gl.delete_transform_feedback",
794    "gasm:gl.is_transform_feedback", "gasm:gl.bind_transform_feedback", "gasm:gl.begin_transform_feedback", "gasm:gl.end_transform_feedback",
795    "gasm:gl.pause_transform_feedback", "gasm:gl.resume_transform_feedback", "gasm:net", "gasm:net.open",
796    "gasm:net.state", "gasm:net.send", "gasm:net.recv", "gasm:net.close",
797    "gasm:fetch", "gasm:fetch.request", "gasm:fetch.state", "gasm:fetch.status",
798    "gasm:fetch.headers", "gasm:fetch.read", "gasm:fetch.close", "gasm:storage",
799    "gasm:storage.get", "gasm:storage.set", "gasm:storage.delete", "gasm:storage.count",
800    "gasm:storage.key", "gasm:clipboard", "gasm:clipboard.set_text", "gasm:clipboard.get_text",
801    "gasm:files", "gasm:files.save", "gasm:files.state", "wasi_snapshot_preview1",
802    "wasi_snapshot_preview1.proc_exit",
803];
804
805// ---- buttons
806/// Virtual gamepad buttons (bit positions). Face buttons by position: East=A, South=B, North=X, West=Y.
807pub const GASM_BTN_A: u32 = 1 << 0;
808pub const GASM_BTN_B: u32 = 1 << 1;
809pub const GASM_BTN_X: u32 = 1 << 2;
810pub const GASM_BTN_Y: u32 = 1 << 3;
811pub const GASM_BTN_L: u32 = 1 << 4;
812pub const GASM_BTN_R: u32 = 1 << 5;
813pub const GASM_BTN_SELECT: u32 = 1 << 6;
814pub const GASM_BTN_START: u32 = 1 << 7;
815pub const GASM_BTN_UP: u32 = 1 << 8;
816pub const GASM_BTN_DOWN: u32 = 1 << 9;
817pub const GASM_BTN_LEFT: u32 = 1 << 10;
818pub const GASM_BTN_RIGHT: u32 = 1 << 11;
819
820// ---- buffer usage
821pub const GASM_BUF_COPY_DST: u32 = 0x08;
822pub const GASM_BUF_INDEX: u32 = 0x10;
823pub const GASM_BUF_VERTEX: u32 = 0x20;
824pub const GASM_BUF_UNIFORM: u32 = 0x40;
825pub const GASM_BUF_STORAGE: u32 = 0x80;
826
827// ---- shader stages
828/// Bind group layout entry visibility (WebGPU GPUShaderStage bits).
829pub const GASM_STAGE_VERTEX: u32 = 0x1;
830pub const GASM_STAGE_FRAGMENT: u32 = 0x2;
831
832// ---- index formats
833pub const GASM_INDEX_U16: u32 = 0;
834pub const GASM_INDEX_U32: u32 = 1;
835
836// ---- net states
837pub const GASM_NET_CONNECTING: u32 = 0;
838pub const GASM_NET_OPEN: u32 = 1;
839pub const GASM_NET_CLOSED: u32 = 2;
840pub const GASM_NET_ERROR: u32 = 3;
841
842// ---- fetch states
843pub const GASM_FETCH_PENDING: u32 = 0;
844pub const GASM_FETCH_HEADERS: u32 = 1;
845pub const GASM_FETCH_DONE: u32 = 2;
846pub const GASM_FETCH_FAILED: u32 = 3;
847
848// ---- input modes
849/// input_mode flags.
850pub const GASM_INPUT_KEYS_RAW: u32 = 1 << 0;
851pub const GASM_INPUT_POINTER_HIDDEN: u32 = 1 << 1;
852pub const GASM_INPUT_POINTER_LOCKED: u32 = 1 << 2;
853
854// ---- file save states
855/// gasm_files_state results.
856pub const GASM_FILES_PENDING: i32 = 0;
857pub const GASM_FILES_SAVED: i32 = 1;
858pub const GASM_FILES_FAILED: i32 = 2;
859
860// ---- storage errors
861/// gasm_storage_set results.
862pub const GASM_STORAGE_OK: i32 = 0;
863pub const GASM_STORAGE_ERR_KEY: i32 = -1;
864pub const GASM_STORAGE_ERR_SIZE: i32 = -2;
865pub const GASM_STORAGE_ERR_QUOTA: i32 = -3;
866pub const GASM_STORAGE_ERR_IO: i32 = -4;
867
868// ---- pointer
869/// 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.
870pub const GASM_POINTER_BYTES: u32 = 48;
871pub const GASM_POINTER_OFF_X: u32 = 0;
872pub const GASM_POINTER_OFF_Y: u32 = 4;
873pub const GASM_POINTER_OFF_FX: u32 = 8;
874pub const GASM_POINTER_OFF_FY: u32 = 12;
875pub const GASM_POINTER_OFF_DX: u32 = 16;
876pub const GASM_POINTER_OFF_DY: u32 = 20;
877pub const GASM_POINTER_OFF_WHEEL_X: u32 = 24;
878pub const GASM_POINTER_OFF_WHEEL_Y: u32 = 28;
879pub const GASM_POINTER_OFF_BUTTONS: u32 = 32;
880pub const GASM_POINTER_OFF_PRESSED: u32 = 36;
881pub const GASM_POINTER_OFF_RELEASED: u32 = 40;
882pub const GASM_POINTER_OFF_FLAGS: u32 = 44;
883pub const GASM_MOUSE_LEFT: u32 = 1 << 0;
884pub const GASM_MOUSE_RIGHT: u32 = 1 << 1;
885pub const GASM_MOUSE_MIDDLE: u32 = 1 << 2;
886pub const GASM_MOUSE_BACK: u32 = 1 << 3;
887pub const GASM_MOUSE_FORWARD: u32 = 1 << 4;
888pub const GASM_POINTER_INSIDE: u32 = 1 << 0;
889pub const GASM_POINTER_IS_HIDDEN: u32 = 1 << 1;
890pub const GASM_POINTER_IS_LOCKED: u32 = 1 << 2;
891
892// ---- gamepad
893/// 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).
894pub const GASM_GAMEPAD_BYTES: u32 = 204;
895pub const GASM_GAMEPAD_BUTTONS: u32 = 32;
896pub const GASM_GAMEPAD_AXES: u32 = 16;
897pub const GASM_GAMEPAD_OFF_FLAGS: u32 = 0;
898pub const GASM_GAMEPAD_OFF_BUTTON_COUNT: u32 = 4;
899pub const GASM_GAMEPAD_OFF_AXIS_COUNT: u32 = 8;
900pub const GASM_GAMEPAD_OFF_BUTTONS: u32 = 12;
901pub const GASM_GAMEPAD_OFF_AXES: u32 = 140;
902pub const GASM_GAMEPAD_CONNECTED: u32 = 1 << 0;
903pub const GASM_GAMEPAD_STANDARD: u32 = 1 << 1;
904
905// ---- keyboard
906/// key_state() size, and the size of one key_events() record.
907pub const GASM_KEY_STATE_BYTES: u32 = 32;
908pub const GASM_KEY_EVENT_BYTES: u32 = 4;
909
910/// Physical keys (W3C KeyboardEvent.code names; layout-independent). The third column is the W3C name.
911pub mod keys {
912    pub const ESCAPE: u32 = 1;
913    pub const F1: u32 = 2;
914    pub const F2: u32 = 3;
915    pub const F3: u32 = 4;
916    pub const F4: u32 = 5;
917    pub const F5: u32 = 6;
918    pub const F6: u32 = 7;
919    pub const F7: u32 = 8;
920    pub const F8: u32 = 9;
921    pub const F9: u32 = 10;
922    pub const F10: u32 = 11;
923    pub const F11: u32 = 12;
924    pub const F12: u32 = 13;
925    pub const BACKQUOTE: u32 = 14;
926    pub const DIGIT0: u32 = 15;
927    pub const DIGIT1: u32 = 16;
928    pub const DIGIT2: u32 = 17;
929    pub const DIGIT3: u32 = 18;
930    pub const DIGIT4: u32 = 19;
931    pub const DIGIT5: u32 = 20;
932    pub const DIGIT6: u32 = 21;
933    pub const DIGIT7: u32 = 22;
934    pub const DIGIT8: u32 = 23;
935    pub const DIGIT9: u32 = 24;
936    pub const MINUS: u32 = 25;
937    pub const EQUAL: u32 = 26;
938    pub const BACKSPACE: u32 = 27;
939    pub const TAB: u32 = 28;
940    pub const KEY_A: u32 = 29;
941    pub const KEY_B: u32 = 30;
942    pub const KEY_C: u32 = 31;
943    pub const KEY_D: u32 = 32;
944    pub const KEY_E: u32 = 33;
945    pub const KEY_F: u32 = 34;
946    pub const KEY_G: u32 = 35;
947    pub const KEY_H: u32 = 36;
948    pub const KEY_I: u32 = 37;
949    pub const KEY_J: u32 = 38;
950    pub const KEY_K: u32 = 39;
951    pub const KEY_L: u32 = 40;
952    pub const KEY_M: u32 = 41;
953    pub const KEY_N: u32 = 42;
954    pub const KEY_O: u32 = 43;
955    pub const KEY_P: u32 = 44;
956    pub const KEY_Q: u32 = 45;
957    pub const KEY_R: u32 = 46;
958    pub const KEY_S: u32 = 47;
959    pub const KEY_T: u32 = 48;
960    pub const KEY_U: u32 = 49;
961    pub const KEY_V: u32 = 50;
962    pub const KEY_W: u32 = 51;
963    pub const KEY_X: u32 = 52;
964    pub const KEY_Y: u32 = 53;
965    pub const KEY_Z: u32 = 54;
966    pub const BRACKET_LEFT: u32 = 55;
967    pub const BRACKET_RIGHT: u32 = 56;
968    pub const BACKSLASH: u32 = 57;
969    pub const CAPS_LOCK: u32 = 58;
970    pub const SEMICOLON: u32 = 59;
971    pub const QUOTE: u32 = 60;
972    pub const ENTER: u32 = 61;
973    pub const SHIFT_LEFT: u32 = 62;
974    pub const INTL_BACKSLASH: u32 = 63;
975    pub const COMMA: u32 = 64;
976    pub const PERIOD: u32 = 65;
977    pub const SLASH: u32 = 66;
978    pub const SHIFT_RIGHT: u32 = 67;
979    pub const CONTROL_LEFT: u32 = 68;
980    pub const META_LEFT: u32 = 69;
981    pub const ALT_LEFT: u32 = 70;
982    pub const SPACE: u32 = 71;
983    pub const ALT_RIGHT: u32 = 72;
984    pub const META_RIGHT: u32 = 73;
985    pub const CONTEXT_MENU: u32 = 74;
986    pub const CONTROL_RIGHT: u32 = 75;
987    pub const PRINT_SCREEN: u32 = 76;
988    pub const SCROLL_LOCK: u32 = 77;
989    pub const PAUSE: u32 = 78;
990    pub const INSERT: u32 = 79;
991    pub const HOME: u32 = 80;
992    pub const PAGE_UP: u32 = 81;
993    pub const DELETE: u32 = 82;
994    pub const END: u32 = 83;
995    pub const PAGE_DOWN: u32 = 84;
996    pub const ARROW_UP: u32 = 85;
997    pub const ARROW_LEFT: u32 = 86;
998    pub const ARROW_DOWN: u32 = 87;
999    pub const ARROW_RIGHT: u32 = 88;
1000    pub const NUM_LOCK: u32 = 89;
1001    pub const NUMPAD_DIVIDE: u32 = 90;
1002    pub const NUMPAD_MULTIPLY: u32 = 91;
1003    pub const NUMPAD_SUBTRACT: u32 = 92;
1004    pub const NUMPAD_ADD: u32 = 93;
1005    pub const NUMPAD_ENTER: u32 = 94;
1006    pub const NUMPAD_DECIMAL: u32 = 95;
1007    pub const NUMPAD0: u32 = 96;
1008    pub const NUMPAD1: u32 = 97;
1009    pub const NUMPAD2: u32 = 98;
1010    pub const NUMPAD3: u32 = 99;
1011    pub const NUMPAD4: u32 = 100;
1012    pub const NUMPAD5: u32 = 101;
1013    pub const NUMPAD6: u32 = 102;
1014    pub const NUMPAD7: u32 = 103;
1015    pub const NUMPAD8: u32 = 104;
1016    pub const NUMPAD9: u32 = 105;
1017    pub const NUMPAD_EQUAL: u32 = 106;
1018    pub const NUMPAD_COMMA: u32 = 107;
1019    pub const INTL_RO: u32 = 108;
1020    pub const INTL_YEN: u32 = 109;
1021    pub const F13: u32 = 110;
1022    pub const F14: u32 = 111;
1023    pub const F15: u32 = 112;
1024    pub const F16: u32 = 113;
1025    pub const F17: u32 = 114;
1026    pub const F18: u32 = 115;
1027    pub const F19: u32 = 116;
1028    pub const F20: u32 = 117;
1029    pub const F21: u32 = 118;
1030    pub const F22: u32 = 119;
1031    pub const F23: u32 = 120;
1032    pub const F24: u32 = 121;
1033    /// W3C names by code (index 0 is unused).
1034    pub const NAMES: [&str; 122] = [
1035        "", "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",
1036    ];
1037}