1#![cfg_attr(not(feature = "std"), no_std)]
2
3#[cfg(not(feature = "std"))]
15extern crate alloc;
16
17use core::ffi::c_void;
18
19#[repr(u32)]
21#[derive(Copy, Clone, Debug, Eq, PartialEq)]
22pub enum Button {
23 B = 0,
24 Y = 1,
25 Select = 2,
26 Start = 3,
27 Up = 4,
28 Down = 5,
29 Left = 6,
30 Right = 7,
31 A = 8,
32 X = 9,
33 L1 = 10,
34 R1 = 11,
35 L2 = 12,
36 R2 = 13,
37 L3 = 14,
38 R3 = 15,
39}
40
41#[repr(C)]
43#[derive(Copy, Clone, Debug, Eq, PartialEq)]
44pub struct TextSize {
45 pub width: u32,
46 pub height: u32,
47}
48
49#[allow(non_camel_case_types)]
51pub mod sys {
52 unsafe extern "C" {
53 #[link_name = "wasm96_graphics_set_size"]
55 pub fn graphics_set_size(width: u32, height: u32);
56 #[link_name = "wasm96_graphics_set_color"]
57 pub fn graphics_set_color(r: u32, g: u32, b: u32, a: u32);
58 #[link_name = "wasm96_graphics_background"]
59 pub fn graphics_background(r: u32, g: u32, b: u32);
60 #[link_name = "wasm96_graphics_point"]
61 pub fn graphics_point(x: i32, y: i32);
62 #[link_name = "wasm96_graphics_line"]
63 pub fn graphics_line(x1: i32, y1: i32, x2: i32, y2: i32);
64 #[link_name = "wasm96_graphics_rect"]
65 pub fn graphics_rect(x: i32, y: i32, w: u32, h: u32);
66 #[link_name = "wasm96_graphics_rect_outline"]
67 pub fn graphics_rect_outline(x: i32, y: i32, w: u32, h: u32);
68 #[link_name = "wasm96_graphics_circle"]
69 pub fn graphics_circle(x: i32, y: i32, r: u32);
70 #[link_name = "wasm96_graphics_circle_outline"]
71 pub fn graphics_circle_outline(x: i32, y: i32, r: u32);
72 #[link_name = "wasm96_graphics_image"]
73 pub fn graphics_image(x: i32, y: i32, w: u32, h: u32, ptr: u32, len: u32);
74 #[link_name = "wasm96_graphics_image_png"]
75 pub fn graphics_image_png(x: i32, y: i32, ptr: u32, len: u32);
76
77 #[link_name = "wasm96_graphics_svg_register"]
80 pub fn graphics_svg_register(key: u64, data_ptr: u32, data_len: u32) -> u32;
81 #[link_name = "wasm96_graphics_svg_draw_key"]
82 pub fn graphics_svg_draw_key(key: u64, x: i32, y: i32, w: u32, h: u32);
83 #[link_name = "wasm96_graphics_svg_unregister"]
84 pub fn graphics_svg_unregister(key: u64);
85
86 #[link_name = "wasm96_graphics_gif_register"]
88 pub fn graphics_gif_register(key: u64, data_ptr: u32, data_len: u32) -> u32;
89 #[link_name = "wasm96_graphics_gif_draw_key"]
90 pub fn graphics_gif_draw_key(key: u64, x: i32, y: i32);
91 #[link_name = "wasm96_graphics_gif_draw_key_scaled"]
92 pub fn graphics_gif_draw_key_scaled(key: u64, x: i32, y: i32, w: u32, h: u32);
93 #[link_name = "wasm96_graphics_gif_unregister"]
94 pub fn graphics_gif_unregister(key: u64);
95
96 #[link_name = "wasm96_graphics_png_register"]
98 pub fn graphics_png_register(key: u64, data_ptr: u32, data_len: u32) -> u32;
99 #[link_name = "wasm96_graphics_png_draw_key"]
100 pub fn graphics_png_draw_key(key: u64, x: i32, y: i32);
101 #[link_name = "wasm96_graphics_png_draw_key_scaled"]
102 pub fn graphics_png_draw_key_scaled(key: u64, x: i32, y: i32, w: u32, h: u32);
103 #[link_name = "wasm96_graphics_png_unregister"]
104 pub fn graphics_png_unregister(key: u64);
105
106 #[link_name = "wasm96_graphics_font_register_ttf"]
108 pub fn graphics_font_register_ttf(key: u64, data_ptr: u32, data_len: u32) -> u32;
109 #[link_name = "wasm96_graphics_font_register_spleen"]
110 pub fn graphics_font_register_spleen(key: u64, size: u32) -> u32;
111 #[link_name = "wasm96_graphics_font_unregister"]
112 pub fn graphics_font_unregister(key: u64);
113
114 #[link_name = "wasm96_graphics_text_key"]
115 pub fn graphics_text_key(x: i32, y: i32, font_key: u64, text_ptr: u32, text_len: u32);
116
117 #[link_name = "wasm96_graphics_text_measure_key"]
118 pub fn graphics_text_measure_key(font_key: u64, text_ptr: u32, text_len: u32) -> u64;
119
120 #[link_name = "wasm96_graphics_triangle"]
121 pub fn graphics_triangle(x1: i32, y1: i32, x2: i32, y2: i32, x3: i32, y3: i32);
122
123 #[link_name = "wasm96_graphics_triangle_outline"]
124 pub fn graphics_triangle_outline(x1: i32, y1: i32, x2: i32, y2: i32, x3: i32, y3: i32);
125
126 #[link_name = "wasm96_graphics_bezier_quadratic"]
127 pub fn graphics_bezier_quadratic(
128 x1: i32,
129 y1: i32,
130 cx: i32,
131 cy: i32,
132 x2: i32,
133 y2: i32,
134 segments: u32,
135 );
136
137 #[link_name = "wasm96_graphics_bezier_cubic"]
138 pub fn graphics_bezier_cubic(
139 x1: i32,
140 y1: i32,
141 cx1: i32,
142 cy1: i32,
143 cx2: i32,
144 cy2: i32,
145 x2: i32,
146 y2: i32,
147 segments: u32,
148 );
149
150 #[link_name = "wasm96_graphics_pill"]
151 pub fn graphics_pill(x: i32, y: i32, w: u32, h: u32);
152
153 #[link_name = "wasm96_graphics_pill_outline"]
154 pub fn graphics_pill_outline(x: i32, y: i32, w: u32, h: u32);
155
156 #[link_name = "wasm96_input_is_button_down"]
158 pub fn input_is_button_down(port: u32, btn: u32) -> u32;
159 #[link_name = "wasm96_input_is_key_down"]
160 pub fn input_is_key_down(key: u32) -> u32;
161 #[link_name = "wasm96_input_get_mouse_x"]
162 pub fn input_get_mouse_x() -> i32;
163 #[link_name = "wasm96_input_get_mouse_y"]
164 pub fn input_get_mouse_y() -> i32;
165 #[link_name = "wasm96_input_is_mouse_down"]
166 pub fn input_is_mouse_down(btn: u32) -> u32;
167
168 #[link_name = "wasm96_audio_init"]
170 pub fn audio_init(sample_rate: u32) -> u32;
171 #[link_name = "wasm96_audio_push_samples"]
172 pub fn audio_push_samples(ptr: u32, len: u32);
173
174 #[link_name = "wasm96_audio_play_wav"]
175 pub fn audio_play_wav(ptr: u32, len: u32);
176
177 #[link_name = "wasm96_audio_play_qoa"]
178 pub fn audio_play_qoa(ptr: u32, len: u32);
179
180 #[link_name = "wasm96_audio_play_xm"]
181 pub fn audio_play_xm(ptr: u32, len: u32);
182
183 #[link_name = "wasm96_system_log"]
185 pub fn system_log(ptr: u32, len: u32);
186 #[link_name = "wasm96_system_millis"]
187 pub fn system_millis() -> u64;
188 }
189}
190
191pub mod graphics {
193 use super::sys;
194 use crate::TextSize;
195
196 fn hash_key(key: &str) -> u64 {
197 let mut hash: u64 = 0xcbf29ce484222325;
198 for byte in key.bytes() {
199 hash ^= byte as u64;
200 hash = hash.wrapping_mul(0x100000001b3);
201 }
202 hash
203 }
204
205 pub fn set_size(width: u32, height: u32) {
207 unsafe { sys::graphics_set_size(width, height) }
208 }
209
210 pub fn set_color(r: u8, g: u8, b: u8, a: u8) {
212 unsafe { sys::graphics_set_color(r as u32, g as u32, b as u32, a as u32) }
213 }
214
215 pub fn background(r: u8, g: u8, b: u8) {
217 unsafe { sys::graphics_background(r as u32, g as u32, b as u32) }
218 }
219
220 pub fn point(x: i32, y: i32) {
222 unsafe { sys::graphics_point(x, y) }
223 }
224
225 pub fn line(x1: i32, y1: i32, x2: i32, y2: i32) {
227 unsafe { sys::graphics_line(x1, y1, x2, y2) }
228 }
229
230 pub fn rect(x: i32, y: i32, w: u32, h: u32) {
232 unsafe { sys::graphics_rect(x, y, w, h) }
233 }
234
235 pub fn rect_outline(x: i32, y: i32, w: u32, h: u32) {
237 unsafe { sys::graphics_rect_outline(x, y, w, h) }
238 }
239
240 pub fn circle(x: i32, y: i32, r: u32) {
242 unsafe { sys::graphics_circle(x, y, r) }
243 }
244
245 pub fn circle_outline(x: i32, y: i32, r: u32) {
247 unsafe { sys::graphics_circle_outline(x, y, r) }
248 }
249
250 pub fn image(x: i32, y: i32, w: u32, h: u32, data: &[u8]) {
253 unsafe { sys::graphics_image(x, y, w, h, data.as_ptr() as u32, data.len() as u32) }
254 }
255
256 pub fn image_png(x: i32, y: i32, data: &[u8]) {
258 unsafe { sys::graphics_image_png(x, y, data.as_ptr() as u32, data.len() as u32) }
259 }
260
261 pub fn gif_register(key: &str, gif_bytes: &[u8]) -> bool {
265 unsafe {
266 sys::graphics_gif_register(
267 hash_key(key),
268 gif_bytes.as_ptr() as u32,
269 gif_bytes.len() as u32,
270 ) != 0
271 }
272 }
273
274 pub fn gif_draw_key(key: &str, x: i32, y: i32) {
276 unsafe { sys::graphics_gif_draw_key(hash_key(key), x, y) }
277 }
278
279 pub fn gif_draw_key_scaled(key: &str, x: i32, y: i32, w: u32, h: u32) {
281 unsafe { sys::graphics_gif_draw_key_scaled(hash_key(key), x, y, w, h) }
282 }
283
284 pub fn gif_unregister(key: &str) {
286 unsafe { sys::graphics_gif_unregister(hash_key(key)) }
287 }
288
289 pub fn triangle(x1: i32, y1: i32, x2: i32, y2: i32, x3: i32, y3: i32) {
291 unsafe { sys::graphics_triangle(x1, y1, x2, y2, x3, y3) }
292 }
293
294 pub fn triangle_outline(x1: i32, y1: i32, x2: i32, y2: i32, x3: i32, y3: i32) {
296 unsafe { sys::graphics_triangle_outline(x1, y1, x2, y2, x3, y3) }
297 }
298
299 pub fn bezier_quadratic(x1: i32, y1: i32, cx: i32, cy: i32, x2: i32, y2: i32, segments: u32) {
301 unsafe { sys::graphics_bezier_quadratic(x1, y1, cx, cy, x2, y2, segments) }
302 }
303
304 pub fn bezier_cubic(
306 x1: i32,
307 y1: i32,
308 cx1: i32,
309 cy1: i32,
310 cx2: i32,
311 cy2: i32,
312 x2: i32,
313 y2: i32,
314 segments: u32,
315 ) {
316 unsafe { sys::graphics_bezier_cubic(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments) }
317 }
318
319 pub fn pill(x: i32, y: i32, w: u32, h: u32) {
321 unsafe { sys::graphics_pill(x, y, w, h) }
322 }
323
324 pub fn pill_outline(x: i32, y: i32, w: u32, h: u32) {
326 unsafe { sys::graphics_pill_outline(x, y, w, h) }
327 }
328
329 pub fn svg_register(key: &str, svg_bytes: &[u8]) -> bool {
332 unsafe {
333 sys::graphics_svg_register(
334 hash_key(key),
335 svg_bytes.as_ptr() as u32,
336 svg_bytes.len() as u32,
337 ) != 0
338 }
339 }
340
341 pub fn svg_draw_key(key: &str, x: i32, y: i32, w: u32, h: u32) {
343 unsafe { sys::graphics_svg_draw_key(hash_key(key), x, y, w, h) }
344 }
345
346 pub fn svg_unregister(key: &str) {
348 unsafe { sys::graphics_svg_unregister(hash_key(key)) }
349 }
350
351 pub fn png_register(key: &str, png_bytes: &[u8]) -> bool {
354 unsafe {
355 sys::graphics_png_register(
356 hash_key(key),
357 png_bytes.as_ptr() as u32,
358 png_bytes.len() as u32,
359 ) != 0
360 }
361 }
362
363 pub fn png_draw_key(key: &str, x: i32, y: i32) {
365 unsafe { sys::graphics_png_draw_key(hash_key(key), x, y) }
366 }
367
368 pub fn png_draw_key_scaled(key: &str, x: i32, y: i32, w: u32, h: u32) {
370 unsafe { sys::graphics_png_draw_key_scaled(hash_key(key), x, y, w, h) }
371 }
372
373 pub fn png_unregister(key: &str) {
375 unsafe { sys::graphics_png_unregister(hash_key(key)) }
376 }
377
378 pub fn font_register_ttf(key: &str, data: &[u8]) -> bool {
382 unsafe {
383 sys::graphics_font_register_ttf(hash_key(key), data.as_ptr() as u32, data.len() as u32)
384 != 0
385 }
386 }
387
388 pub fn font_register_spleen(key: &str, size: u32) -> bool {
392 unsafe { sys::graphics_font_register_spleen(hash_key(key), size) != 0 }
393 }
394
395 pub fn font_unregister(key: &str) {
397 unsafe { sys::graphics_font_unregister(hash_key(key)) }
398 }
399
400 pub fn text_key(x: i32, y: i32, font_key: &str, text: &str) {
402 unsafe {
403 sys::graphics_text_key(
404 x,
405 y,
406 hash_key(font_key),
407 text.as_ptr() as u32,
408 text.len() as u32,
409 )
410 }
411 }
412
413 pub fn text_measure_key(font_key: &str, text: &str) -> TextSize {
415 let packed = unsafe {
416 sys::graphics_text_measure_key(
417 hash_key(font_key),
418 text.as_ptr() as u32,
419 text.len() as u32,
420 )
421 };
422 TextSize {
423 width: (packed >> 32) as u32,
424 height: packed as u32,
425 }
426 }
427}
428
429pub mod input {
431 use super::{Button, sys};
432
433 pub fn is_button_down(port: u32, btn: Button) -> bool {
435 unsafe { sys::input_is_button_down(port, btn as u32) != 0 }
436 }
437
438 pub fn is_key_down(key: u32) -> bool {
440 unsafe { sys::input_is_key_down(key) != 0 }
441 }
442
443 pub fn get_mouse_x() -> i32 {
445 unsafe { sys::input_get_mouse_x() }
446 }
447
448 pub fn get_mouse_y() -> i32 {
450 unsafe { sys::input_get_mouse_y() }
451 }
452
453 pub fn is_mouse_down(btn: u32) -> bool {
456 unsafe { sys::input_is_mouse_down(btn) != 0 }
457 }
458}
459
460pub mod audio {
462 use super::sys;
463
464 pub fn init(sample_rate: u32) -> u32 {
466 unsafe { sys::audio_init(sample_rate) }
467 }
468
469 pub fn push_samples(samples: &[i16]) {
472 unsafe { sys::audio_push_samples(samples.as_ptr() as u32, samples.len() as u32) }
473 }
474
475 pub fn play_wav(data: &[u8]) {
478 unsafe { sys::audio_play_wav(data.as_ptr() as u32, data.len() as u32) }
479 }
480
481 pub fn play_qoa(data: &[u8]) {
484 unsafe { sys::audio_play_qoa(data.as_ptr() as u32, data.len() as u32) }
485 }
486
487 pub fn play_xm(data: &[u8]) {
491 unsafe { sys::audio_play_xm(data.as_ptr() as u32, data.len() as u32) }
492 }
493}
494
495pub mod system {
497 use super::sys;
498
499 pub fn log(message: &str) {
501 unsafe { sys::system_log(message.as_ptr() as u32, message.len() as u32) }
502 }
503
504 pub fn millis() -> u64 {
506 unsafe { sys::system_millis() }
507 }
508}
509
510pub mod prelude {
512 pub use crate::Button;
513 pub use crate::TextSize;
514 pub use crate::audio;
515 pub use crate::graphics;
516 pub use crate::input;
517 pub use crate::system;
518}
519
520#[allow(dead_code)]
522const _C_VOID: *const c_void = core::ptr::null();