use std::ffi::{c_uchar, c_uint, c_void}; use std::os::raw::c_char; mod renderer; mod window; pub use renderer::Renderer; pub use window::{Window, WindowConfig, WindowEvent}; type CRenderer = *mut (); type CWindow = *mut (); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[repr(C)] pub struct RendererConfig { pub width: c_uint, pub height: c_uint, pub instance_capacity: c_uint, pub fullscreen: bool, pub vsync: bool, } #[repr(C)] pub struct Vertex { x: f32, y: f32, z: f32, curve_a: f32, curve_b: f32, color1_r: f32, color1_g: f32, color1_b: f32, color1_a: f32, normal_x: f32, normal_y: f32, normal_z: f32, } #[derive(Debug, Clone, Copy)] #[repr(C)] struct CWindowConfig { default_width: c_uint, default_height: c_uint, default_x: c_uint, default_y: c_uint, title: *const c_char, visible: bool, borderless_fullscreen: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[repr(C)] pub enum CWindowEvent { AboutToWait, Other, CloseRequest, ScaleFactorChange, Resume, RedrawRequest, } #[link(name = "alligator_backend", kind = "static")] extern "C" { fn new_renderer(config: RendererConfig, window: CWindow) -> CRenderer; fn resize_renderer(renderer: CRenderer, width: c_uint, height: c_uint); fn set_vsync(renderer: CRenderer, vsync: bool); fn create_vertex_buffer(renderer: CRenderer, count: c_uint, instances: *const Vertex); fn set_camera( renderer: CRenderer, x: f32, y: f32, zoom: f32, rotation: f32, width: f32, height: f32, ); fn render_frame(renderer: CRenderer); fn destroy_renderer(renderer: CRenderer); fn create_window(config: CWindowConfig) -> CWindow; fn set_visible(window: CWindow, visible: bool); fn resize_window(window: CWindow, width: c_uint, height: c_uint); fn set_fullscreen(window: CWindow, fullscreen: bool); fn set_title(window: CWindow, title: *const c_char); fn wait_for_event(window: CWindow); fn pop_event(window: CWindow) -> bool; fn wait_for_resume(window: CWindow); fn set_event_handler(window: CWindow, closure: *mut c_void); fn run_event_handler(window: CWindow, event: CWindowEvent); fn request_redraw(window: CWindow); fn destroy_window(window: CWindow); } #[no_mangle] unsafe extern "C" fn alligator_run_closure(closure: *mut c_void, event: CWindowEvent) { let closure: &mut &mut dyn FnMut(CWindowEvent) = unsafe { &mut *closure.cast() }; closure(event) }