diff --git a/src/lib.rs b/src/lib.rs index 386d71b..c2af666 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ pub mod display; pub mod file; pub mod geometry; pub mod graphics; +pub mod lua; pub mod sound; pub mod sprite; pub mod system; @@ -18,6 +19,7 @@ use { display::Display, file::FileSystem, graphics::{Graphics, PDRect}, + lua::Lua, sound::Sound, sprite::{ Sprite, SpriteCollideFunction, SpriteDrawFunction, SpriteManager, SpriteUpdateFunction, @@ -48,6 +50,8 @@ impl Playdate { FileSystem::new(file); let graphics = unsafe { (*playdate).graphics }; Graphics::new(graphics); + let lua = unsafe { (*playdate).lua }; + Lua::new(lua); let sound = unsafe { (*playdate).sound }; Sound::new(sound)?; let display = unsafe { (*playdate).display }; @@ -210,6 +214,9 @@ impl GameRunner { #[macro_export] macro_rules! crankstart_game { ($game_struct:tt) => { + crankstart_game!($game_struct, PDSystemEvent::kEventInit) + }; + ($game_struct:tt, $pd_system_event:expr) => { pub mod game_setup { extern crate alloc; use super::*; @@ -250,7 +257,7 @@ macro_rules! crankstart_game { event: PDSystemEvent, _arg: u32, ) -> crankstart_sys::ctypes::c_int { - if event == PDSystemEvent::kEventInit { + if event == $pd_system_event { // This would only fail if PlaydateAPI has null pointers, which shouldn't happen. let mut playdate = match Playdate::new(playdate, sprite_update, sprite_draw) { Ok(playdate) => playdate, diff --git a/src/lua.rs b/src/lua.rs new file mode 100644 index 0000000..4283762 --- /dev/null +++ b/src/lua.rs @@ -0,0 +1,45 @@ +use { + crate::pd_func_caller, + alloc::string::String, + anyhow::{anyhow, Error}, + core::ptr, + crankstart_sys::{ctypes, lua_CFunction}, + cstr_core::{CStr, CString}, +}; + +static mut LUA: Lua = Lua(ptr::null_mut()); + +#[derive(Clone, Debug)] +pub struct Lua(*const crankstart_sys::playdate_lua); + +impl Lua { + pub(crate) fn new(file: *const crankstart_sys::playdate_lua) { + unsafe { + LUA = Lua(file); + } + } + + pub fn get() -> Self { + unsafe { LUA.clone() } + } + + pub fn add_function(&self, f: lua_CFunction, name: &str) -> Result<(), Error> { + let c_name = CString::new(name).map_err(Error::msg)?; + let mut out_err: *const crankstart_sys::ctypes::c_char = ptr::null_mut(); + pd_func_caller!((*self.0).addFunction, f, c_name.as_ptr(), &mut out_err)?; + if out_err != ptr::null_mut() { + let err_msg = unsafe { CStr::from_ptr(out_err).to_string_lossy().into_owned() }; + Err(anyhow!(err_msg)) + } else { + Ok(()) + } + } + + pub fn get_arg_string(&self, pos: i32) -> Result { + let c_arg_string = pd_func_caller!((*self.0).getArgString, pos as ctypes::c_int)?; + unsafe { + let arg_string = CStr::from_ptr(c_arg_string).to_string_lossy().into_owned(); + Ok(arg_string) + } + } +}