Skip to content

Commit

Permalink
Merge pull request #144 from boozook/api/ctrls
Browse files Browse the repository at this point in the history
Improve controls api
  • Loading branch information
boozook authored Sep 30, 2023
2 parents 0ae5cfc + 9ddbb50 commit d08454c
Show file tree
Hide file tree
Showing 19 changed files with 517 additions and 151 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repository = "https://github.com/boozook/playdate.git"

[workspace.dependencies]
color = { version = "0.2", path = "api/color", package = "playdate-color", default-features = false }
ctrl = { version = "0.2", path = "api/ctrl", package = "playdate-controls", default-features = false }
ctrl = { version = "0.3", path = "api/ctrl", package = "playdate-controls", default-features = false }
display = { version = "0.3", path = "api/display", package = "playdate-display", default-features = false }
fs = { version = "0.2", path = "api/fs", package = "playdate-fs", default-features = false }
gfx = { version = "0.3", path = "api/gfx", package = "playdate-graphics", default-features = false }
Expand Down
8 changes: 4 additions & 4 deletions api/ctrl/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "playdate-controls"
version = "0.2.1"
version = "0.3.0"
readme = "README.md"
description = "High-level controls API built on-top of Playdate API"
keywords = ["playdate", "sdk", "api", "gamedev"]
Expand All @@ -22,9 +22,9 @@ bindgen-static = ["sys/bindgen-static"]
bindings-derive-debug = ["sys/bindings-derive-debug"]


[dependencies.sys]
workspace = true
default-features = false
[dependencies]
sys = { workspace = true, default-features = false }
system = { workspace = true, default-features = false }

[dev-dependencies]
gfx = { workspace = true, default-features = false }
Expand Down
9 changes: 4 additions & 5 deletions api/ctrl/examples/accelerometer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use controls::peripherals::Accelerometer;

use display::Display;
use gfx::color::Color;
use sys::error::NullPtrError;
use sys::ffi::PlaydateAPI;
use sys::EventLoopCtrl;
use system::prelude::*;
Expand Down Expand Up @@ -50,7 +49,7 @@ fn init() -> EventLoopCtrl {
graphics.clear(Color::WHITE);

// get accelerometer data
let (x, y, z) = Accelerometer::get().ok_or(NullPtrError)?;
let (x, y, z) = Accelerometer::Default().get();

// render state to string
let text = format!("[{x:.2},{y:.2},{z:.2}]");
Expand Down Expand Up @@ -93,18 +92,18 @@ fn event_handler(_: NonNull<PlaydateAPI>, event: SystemEvent, _: u32) -> EventLo
match event {
SystemEvent::Init => {
// turn on the accelerometer
Accelerometer::enable().ok_or(NullPtrError)?;
Accelerometer::Default().enable();
return init();
},

SystemEvent::Resume | SystemEvent::Unlock => {
// turn on the accelerometer
Accelerometer::enable().ok_or(NullPtrError)?;
Accelerometer::Default().enable();
},

SystemEvent::Terminate | SystemEvent::Pause | SystemEvent::Lock => {
// turn off the accelerometer
Accelerometer::disable().ok_or(NullPtrError)?;
Accelerometer::Default().disable();
},

// Ignore any other events, just for this minimalistic example
Expand Down
8 changes: 4 additions & 4 deletions api/ctrl/examples/buttons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use display::Display;
use gfx::color::Color;
use sys::EventLoopCtrl;
use sys::ffi::PlaydateAPI;
use sys::error::NullPtrError;
use system::prelude::*;


Expand Down Expand Up @@ -54,15 +53,16 @@ fn event_handler(_: NonNull<PlaydateAPI>, event: SystemEvent, _: u32) -> EventLo
// Create cached end-points that we using every update
let system = system::System::Cached();
let graphics = gfx::Graphics::Cached();
let buttons = Buttons::Cached();

// Register update handler
// Just to draw current playback position
system.set_update_callback_boxed(
move |pos| {
move |(pos, buttons)| {
graphics.clear(Color::WHITE);

// Get buttons state
let buttons = Buttons::get().ok_or(NullPtrError)?;
let buttons = buttons.get();

// Render buttons state to string
let text: Cow<str> = if buttons.current.is_empty() {
Expand Down Expand Up @@ -108,7 +108,7 @@ fn event_handler(_: NonNull<PlaydateAPI>, event: SystemEvent, _: u32) -> EventLo

UpdateCtrl::Continue
},
pos,
(pos, buttons),
);

EventLoopCtrl::Continue
Expand Down
181 changes: 181 additions & 0 deletions api/ctrl/src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
use core::ffi::c_float;
use core::ffi::c_int;
use core::ptr::NonNull;

use sys::ffi::PDButtons;
use sys::ffi::PDPeripherals;
use sys::ffi::playdate_sys;

/// Default system api end-point, ZST.
///
/// All calls approximately costs ~3 derefs.
#[derive(Debug, Clone, Copy, core::default::Default)]
pub struct Default;
impl Api for Default {}


/// Cached system api end-point.
///
/// Stores one reference, so size on stack is eq `usize`.
///
/// All calls approximately costs ~1 deref.
#[derive(Clone, Copy)]
#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
pub struct Cache(&'static playdate_sys);

impl core::default::Default for Cache {
fn default() -> Self { Self(api!(system)) }
}

impl From<*const playdate_sys> for Cache {
#[inline(always)]
fn from(ptr: *const playdate_sys) -> Self { Self(unsafe { ptr.as_ref() }.expect("system")) }
}

impl From<&'static playdate_sys> for Cache {
#[inline(always)]
fn from(r: &'static playdate_sys) -> Self { Self(r) }
}

impl From<NonNull<playdate_sys>> for Cache {
#[inline(always)]
fn from(ptr: NonNull<playdate_sys>) -> Self { Self(unsafe { ptr.as_ref() }) }
}

impl From<&'_ NonNull<playdate_sys>> for Cache {
#[inline(always)]
fn from(ptr: &NonNull<playdate_sys>) -> Self { Self(unsafe { ptr.as_ref() }) }
}

impl From<system::api::Cache> for Cache {
#[inline(always)]
fn from(api: system::api::Cache) -> Self { Self(api.as_inner()) }
}


impl Api for Cache {
#[inline(always)]
fn set_peripherals_enabled(&self) -> unsafe extern "C" fn(mask: PDPeripherals) {
self.0.setPeripheralsEnabled.expect("setPeripheralsEnabled")
}

#[inline(always)]
fn get_button_state(
&self)
-> unsafe extern "C" fn(current: *mut PDButtons, pushed: *mut PDButtons, released: *mut PDButtons) {
self.0.getButtonState.expect("getButtonState")
}

#[inline(always)]
fn get_accelerometer(
&self)
-> unsafe extern "C" fn(out_x: *mut c_float, out_y: *mut c_float, out_z: *mut c_float) {
self.0.getAccelerometer.expect("getAccelerometer")
}

#[inline(always)]
fn get_crank_change(&self) -> unsafe extern "C" fn() -> c_float {
self.0.getCrankChange.expect("getCrankChange")
}

#[inline(always)]
fn get_crank_angle(&self) -> unsafe extern "C" fn() -> c_float { self.0.getCrankAngle.expect("getCrankAngle") }

#[inline(always)]
fn is_crank_docked(&self) -> unsafe extern "C" fn() -> c_int { self.0.isCrankDocked.expect("isCrankDocked") }

#[inline(always)]
fn set_crank_sounds_disabled(&self) -> unsafe extern "C" fn(flag: c_int) -> c_int {
self.0.setCrankSoundsDisabled.expect("setCrankSoundsDisabled")
}
}


impl Api for system::api::Default {}

impl Api for system::api::Cache {
#[inline(always)]
fn set_peripherals_enabled(&self) -> unsafe extern "C" fn(mask: PDPeripherals) {
self.as_inner()
.setPeripheralsEnabled
.expect("setPeripheralsEnabled")
}

#[inline(always)]
fn get_button_state(
&self)
-> unsafe extern "C" fn(current: *mut PDButtons, pushed: *mut PDButtons, released: *mut PDButtons) {
self.as_inner().getButtonState.expect("getButtonState")
}

#[inline(always)]
fn get_accelerometer(
&self)
-> unsafe extern "C" fn(out_x: *mut c_float, out_y: *mut c_float, out_z: *mut c_float) {
self.as_inner().getAccelerometer.expect("getAccelerometer")
}

#[inline(always)]
fn get_crank_change(&self) -> unsafe extern "C" fn() -> c_float {
self.as_inner().getCrankChange.expect("getCrankChange")
}

#[inline(always)]
fn get_crank_angle(&self) -> unsafe extern "C" fn() -> c_float {
self.as_inner().getCrankAngle.expect("getCrankAngle")
}

#[inline(always)]
fn is_crank_docked(&self) -> unsafe extern "C" fn() -> c_int {
self.as_inner().isCrankDocked.expect("isCrankDocked")
}

#[inline(always)]
fn set_crank_sounds_disabled(&self) -> unsafe extern "C" fn(flag: c_int) -> c_int {
self.as_inner()
.setCrankSoundsDisabled
.expect("setCrankSoundsDisabled")
}
}

pub trait Api {
/// Returns [`sys::ffi::playdate_sys::setPeripheralsEnabled`]
#[doc(alias = "sys::ffi::playdate_sys::setPeripheralsEnabled")]
fn set_peripherals_enabled(&self) -> unsafe extern "C" fn(mask: PDPeripherals) {
*sys::api!(system.setPeripheralsEnabled)
}

/// Returns [`sys::ffi::playdate_sys::getButtonState`]
#[doc(alias = "sys::ffi::playdate_sys::getButtonState")]
fn get_button_state(
&self)
-> unsafe extern "C" fn(current: *mut PDButtons, pushed: *mut PDButtons, released: *mut PDButtons) {
*sys::api!(system.getButtonState)
}

/// Returns [`sys::ffi::playdate_sys::getAccelerometer`]
#[doc(alias = "sys::ffi::playdate_sys::getAccelerometer")]
fn get_accelerometer(
&self)
-> unsafe extern "C" fn(out_x: *mut c_float, out_y: *mut c_float, out_z: *mut c_float) {
*sys::api!(system.getAccelerometer)
}

/// Returns [`sys::ffi::playdate_sys::getCrankChange`]
#[doc(alias = "sys::ffi::playdate_sys::getCrankChange")]
fn get_crank_change(&self) -> unsafe extern "C" fn() -> c_float { *sys::api!(system.getCrankChange) }

/// Returns [`sys::ffi::playdate_sys::getCrankAngle`]
#[doc(alias = "sys::ffi::playdate_sys::getCrankAngle")]
fn get_crank_angle(&self) -> unsafe extern "C" fn() -> c_float { *sys::api!(system.getCrankAngle) }

/// Returns [`sys::ffi::playdate_sys::isCrankDocked`]
#[doc(alias = "sys::ffi::playdate_sys::isCrankDocked")]
fn is_crank_docked(&self) -> unsafe extern "C" fn() -> c_int { *sys::api!(system.isCrankDocked) }

/// Returns [`sys::ffi::playdate_sys::setCrankSoundsDisabled`]
#[doc(alias = "sys::ffi::playdate_sys::setCrankSoundsDisabled")]
fn set_crank_sounds_disabled(&self) -> unsafe extern "C" fn(flag: c_int) -> c_int {
*sys::api!(system.setCrankSoundsDisabled)
}
}
3 changes: 3 additions & 0 deletions api/ctrl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#[macro_use]
extern crate alloc;
#[macro_use]
extern crate sys;

pub mod api;
pub mod buttons;
pub mod peripherals;
Loading

0 comments on commit d08454c

Please sign in to comment.