pyxel_platform/
platform.rs1use std::mem::transmute;
2use std::ptr::{addr_of_mut, null_mut};
3
4use cfg_if::cfg_if;
5use glow::Context as GlowContext;
6
7use crate::gamepad::{init_gamepads, Gamepad};
8use crate::sdl2_sys::*;
9use crate::window::{init_glow, init_window};
10
11pub struct Platform {
12 pub window: *mut SDL_Window,
13 pub glow_context: *mut GlowContext,
14 pub audio_device_id: SDL_AudioDeviceID,
15 pub mouse_x: i32,
16 pub mouse_y: i32,
17 pub gamepads: Vec<Gamepad>,
18 #[cfg(target_os = "emscripten")]
19 pub virtual_gamepad_states: [bool; 8],
20}
21
22static mut PLATFORM: *mut Platform = null_mut();
23
24pub fn platform() -> &'static mut Platform {
25 unsafe { &mut *PLATFORM }
26}
27
28pub fn init<'a, F: FnOnce(u32, u32) -> (&'a str, u32, u32)>(window_params: F) {
29 assert!(
30 unsafe { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER,) } >= 0,
31 "Failed to initialize SDL2"
32 );
33
34 let mut display_mode = SDL_DisplayMode {
35 format: 0,
36 w: 0,
37 h: 0,
38 refresh_rate: 0,
39 driverdata: null_mut(),
40 };
41 assert!(
42 unsafe { SDL_GetCurrentDisplayMode(0, addr_of_mut!(display_mode)) } == 0,
43 "Failed to get display size"
44 );
45
46 let (title, width, height) = window_params(display_mode.w as u32, display_mode.h as u32);
47
48 let window = init_window(title, width, height);
49 let glow_context = init_glow(window);
50 let gamepads = init_gamepads();
51
52 unsafe {
53 PLATFORM = transmute::<Box<Platform>, *mut Platform>(Box::new(Platform {
54 window,
55 glow_context,
56 audio_device_id: 0,
57 mouse_x: i32::MIN,
58 mouse_y: i32::MIN,
59 gamepads,
60 #[cfg(target_os = "emscripten")]
61 virtual_gamepad_states: [false; 8],
62 }));
63 }
64}
65
66#[allow(unused_mut)]
67pub fn run<F: FnMut()>(mut main_loop: F) {
68 cfg_if! {
69 if #[cfg(target_os = "emscripten")] {
70 crate::emscripten::run(main_loop);
71 } else {
72 loop {
73 let start_ms = elapsed_time() as f64;
74 main_loop();
75 let elapsed_ms = elapsed_time() as f64 - start_ms;
76 let wait_ms = 1000.0 / 60.0 - elapsed_ms;
77 if wait_ms > 0.0 {
78 sleep((wait_ms / 2.0) as u32);
79 }
80 }
81 }
82 }
83}
84
85pub fn quit() {
86 unsafe {
87 SDL_Quit();
88 }
89
90 cfg_if! {
91 if #[cfg(target_os = "emscripten")] {
92 crate::emscripten::exit(0);
93 } else {
94 std::process::exit(0);
95 }
96 }
97}
98
99pub fn elapsed_time() -> u32 {
100 unsafe { SDL_GetTicks() }
101}
102
103pub fn sleep(ms: u32) {
104 unsafe {
105 SDL_Delay(ms);
106 }
107}