playdate_system/
lib.rs

1#![cfg_attr(not(test), no_std)]
2#![cfg_attr(feature = "try-trait-v2", feature(try_trait_v2))]
3
4extern crate sys;
5extern crate alloc;
6
7use core::ffi::c_float;
8use core::ffi::c_int;
9use core::ffi::c_uint;
10use core::time::Duration;
11use alloc::string::String;
12
13
14pub mod time;
15pub mod lang;
16pub mod update;
17pub mod event;
18
19pub mod prelude {
20	pub use crate::System;
21	pub use crate::time::*;
22	pub use crate::lang::*;
23	pub use crate::update::*;
24	pub use crate::event::*;
25}
26
27use time::*;
28use lang::*;
29
30
31#[derive(Debug, Clone, Copy)]
32pub struct System<Api = api::Default>(Api);
33
34impl System<api::Default> {
35	/// Creates default [`System`] without type parameter requirement.
36	///
37	/// Uses ZST [`api::Default`].
38	#[allow(non_snake_case)]
39	pub fn Default() -> Self { Self(Default::default()) }
40}
41
42impl System<api::Cache> {
43	/// Creates [`System`] without type parameter requirement.
44	///
45	/// Uses [`api::Cache`].
46	#[allow(non_snake_case)]
47	pub fn Cached() -> Self { Self(Default::default()) }
48}
49
50impl<Api: Default + api::Api> Default for System<Api> {
51	fn default() -> Self { Self(Default::default()) }
52}
53
54impl<Api: Default + api::Api> System<Api> {
55	pub fn new() -> Self { Self(Default::default()) }
56}
57
58impl<Api: api::Api> System<Api> {
59	pub fn new_with(api: Api) -> Self { Self(api) }
60
61	#[inline(always)]
62	pub const fn inner(&self) -> Api
63		where Api: Copy {
64		self.0
65	}
66}
67
68
69impl<Api: api::Api> System<Api> {
70	/// Equivalent to [`sys::ffi::playdate_sys::getLanguage`]
71	#[doc(alias = "sys::ffi::playdate_sys::getLanguage")]
72	#[inline(always)]
73	pub fn language(&self) -> PDLanguage {
74		let f = self.0.get_language();
75		unsafe { f() }
76	}
77
78	/// Equivalent to [`sys::ffi::playdate_sys::getCurrentTimeMilliseconds`]
79	#[doc(alias = "sys::ffi::playdate_sys::getCurrentTimeMilliseconds")]
80	#[inline(always)]
81	pub fn current_time(&self) -> Duration { Duration::from_millis(self.current_time_ms().into()) }
82
83	/// Equivalent to [`sys::ffi::playdate_sys::getCurrentTimeMilliseconds`]
84	#[doc(alias = "sys::ffi::playdate_sys::getCurrentTimeMilliseconds")]
85	pub fn current_time_ms(&self) -> c_uint {
86		let f = self.0.get_current_time_milliseconds();
87		unsafe { f() }
88	}
89
90	/// Returns the number of seconds elapsed since midnight (hour 0), January 1, 2000.
91	///
92	/// See also [`System::seconds_since_epoch_with_ms`].
93	///
94	/// Equivalent to [`sys::ffi::playdate_sys::getSecondsSinceEpoch`]
95	#[doc(alias = "sys::ffi::playdate_sys::getSecondsSinceEpoch")]
96	#[inline(always)]
97	pub fn seconds_since_epoch(&self) -> c_uint {
98		let f = self.0.get_seconds_since_epoch();
99		unsafe { f(core::ptr::null_mut()) }
100	}
101
102	/// Returns current time as `(seconds, milliseconds)`,
103	/// elapsed since midnight (hour 0), January 1, 2000.
104	///
105	/// Equivalent to [`sys::ffi::playdate_sys::getSecondsSinceEpoch`]
106	#[doc(alias = "sys::ffi::playdate_sys::getSecondsSinceEpoch")]
107	#[inline(always)]
108	pub fn seconds_since_epoch_with_ms(&self) -> (c_uint, c_uint) {
109		let f = self.0.get_seconds_since_epoch();
110		let mut millis: c_uint = 0;
111		let secs = unsafe { f(&mut millis) };
112		(secs, millis)
113	}
114
115	/// Equivalent to [`sys::ffi::playdate_sys::getSecondsSinceEpoch`]
116	#[doc(alias = "sys::ffi::playdate_sys::getSecondsSinceEpoch")]
117	#[inline(always)]
118	pub fn time_since_epoch(&self) -> Duration {
119		let f = self.0.get_seconds_since_epoch();
120		let mut millis: c_uint = 0;
121		let secs = unsafe { f(&mut millis) };
122		Duration::new(secs.into(), 0) + Duration::from_millis(millis.into())
123	}
124
125	/// Equivalent to [`sys::ffi::playdate_sys::drawFPS`]
126	#[doc(alias = "sys::ffi::playdate_sys::drawFPS")]
127	#[inline(always)]
128	pub fn draw_fps(&self, x: c_int, y: c_int) {
129		let f = self.0.draw_fps();
130		unsafe { f(x, y) }
131	}
132
133	/// Equivalent to [`sys::ffi::playdate_sys::getFlipped`]
134	#[doc(alias = "sys::ffi::playdate_sys::getFlipped")]
135	#[inline(always)]
136	pub fn flipped(&self) -> bool {
137		let f = self.0.get_flipped();
138		unsafe { f() == 1 }
139	}
140
141	/// Equivalent to [`sys::ffi::playdate_sys::setAutoLockDisabled`]
142	#[doc(alias = "sys::ffi::playdate_sys::setAutoLockDisabled")]
143	#[inline(always)]
144	pub fn set_auto_lock_disabled(&self, disable: bool) {
145		let f = self.0.set_auto_lock_disabled();
146		unsafe { f(disable as _) }
147	}
148
149	/// Equivalent to [`sys::ffi::playdate_sys::getReduceFlashing`]
150	#[doc(alias = "sys::ffi::playdate_sys::getReduceFlashing")]
151	#[inline(always)]
152	pub fn reduce_flashing(&self) -> bool {
153		let f = self.0.get_reduce_flashing();
154		unsafe { f() == 1 }
155	}
156
157	// TODO: invent analog of `std::time::Instant`
158
159	/// Returns the number of __seconds__ since [`reset_elapsed_time`] was called.
160	///
161	/// The value is a floating-point number with microsecond accuracy.
162	///
163	/// Equivalent to [`sys::ffi::playdate_sys::getElapsedTime`]
164	#[doc(alias = "sys::ffi::playdate_sys::getElapsedTime")]
165	#[inline(always)]
166	pub fn elapsed_time_secs(&self) -> c_float {
167		let f = self.0.get_elapsed_time();
168		unsafe { f() }
169	}
170
171	/// Equivalent to [`sys::ffi::playdate_sys::getElapsedTime`]
172	#[doc(alias = "sys::ffi::playdate_sys::getElapsedTime")]
173	#[inline(always)]
174	pub fn elapsed_time(&self) -> Duration {
175		let f = self.0.get_elapsed_time();
176		let secs = unsafe { f() };
177		Duration::from_secs_f32(secs)
178	}
179
180	/// Equivalent to [`sys::ffi::playdate_sys::resetElapsedTime`]
181	#[doc(alias = "sys::ffi::playdate_sys::resetElapsedTime")]
182	#[inline(always)]
183	pub fn reset_elapsed_time(&self) {
184		let f = self.0.reset_elapsed_time();
185		unsafe { f() }
186	}
187
188	/// Equivalent to [`sys::ffi::playdate_sys::getBatteryPercentage`]
189	#[doc(alias = "sys::ffi::playdate_sys::getBatteryPercentage")]
190	#[inline(always)]
191	pub fn battery_percentage(&self) -> c_float {
192		let f = self.0.get_battery_percentage();
193		unsafe { f() }
194	}
195
196
197	/// Equivalent to [`sys::ffi::playdate_sys::getBatteryVoltage`]
198	#[doc(alias = "sys::ffi::playdate_sys::getBatteryVoltage")]
199	#[inline(always)]
200	pub fn battery_voltage(&self) -> c_float {
201		let f = self.0.get_battery_voltage();
202		unsafe { f() }
203	}
204
205	/// Equivalent to [`sys::ffi::playdate_sys::getTimezoneOffset`]
206	#[doc(alias = "sys::ffi::playdate_sys::getTimezoneOffset")]
207	#[inline(always)]
208	pub fn timezone_offset(&self) -> i32 {
209		let f = self.0.get_timezone_offset();
210		unsafe { f() }
211	}
212
213	/// Equivalent to [`sys::ffi::playdate_sys::shouldDisplay24HourTime`]
214	#[doc(alias = "sys::ffi::playdate_sys::shouldDisplay24HourTime")]
215	#[inline(always)]
216	pub fn should_display_24_hour_time(&self) -> bool {
217		let f = self.0.should_display_24_hour_time();
218		unsafe { f() == 1 }
219	}
220
221	/// Equivalent to [`sys::ffi::playdate_sys::convertEpochToDateTime`]
222	#[doc(alias = "sys::ffi::playdate_sys::convertEpochToDateTime")]
223	#[inline(always)]
224	pub fn convert_epoch_to_date_time(&self, epoch: u32) -> PDDateTime {
225		let mut dt = PDDateTime { year: 0,
226		                          month: 0,
227		                          day: 0,
228		                          weekday: 0,
229		                          hour: 0,
230		                          minute: 0,
231		                          second: 0 };
232		self.convert_epoch_to_date_time_to(epoch, &mut dt);
233		dt
234	}
235
236	/// Equivalent to [`sys::ffi::playdate_sys::convertEpochToDateTime`]
237	#[doc(alias = "sys::ffi::playdate_sys::convertEpochToDateTime")]
238	#[inline(always)]
239	pub fn convert_epoch_to_date_time_to(&self, epoch: u32, dt: &mut PDDateTime) {
240		let f = self.0.convert_epoch_to_date_time();
241		unsafe { f(epoch, dt) }
242	}
243
244	/// Equivalent to [`sys::ffi::playdate_sys::convertDateTimeToEpoch`]
245	#[doc(alias = "sys::ffi::playdate_sys::convertDateTimeToEpoch")]
246	pub fn convert_date_time_to_epoch(&self, dt: &PDDateTime) -> u32 {
247		let f = self.0.convert_date_time_to_epoch();
248		let epoch = unsafe { f(dt as *const _ as *mut _) };
249		let _ = dt; // this to prevent earlier drop.
250		epoch
251	}
252
253	/// Equivalent to [`sys::ffi::playdate_sys::setSerialMessageCallback`]
254	#[doc(alias = "sys::ffi::playdate_sys::setSerialMessageCallback")]
255	pub fn set_serial_message_callback<F>(&self, callback: Option<F>)
256		where F: 'static + FnMut(String) + Sized {
257		use core::ffi::c_char;
258		use core::ffi::CStr;
259		use alloc::boxed::Box;
260		use alloc::string::String;
261
262
263		static mut STORE: Option<Box<dyn FnMut(String)>> = None;
264
265		pub unsafe extern "C" fn proxy_serial_message_callback<F: FnMut(String)>(data: *const c_char) {
266			let data = CStr::from_ptr(data as _).to_string_lossy().into_owned();
267			if let Some(ref mut f) = STORE.as_mut() {
268				f(data)
269			} else {
270				// Highly unlikely, mostly impossible case.
271				// Should be unreachable, but still possible in case when
272				// 0. new callback is None, we have to register it in the System;
273				// 1. write callback to `STORE`
274				// 2. interrupt, proxy_serial_message_callback called, BOOM!
275				// 3. call API::set_serial_message_callback to set our new (None) callback
276				// So, see difference in how to store & reg callback at couple lines below.
277				panic!("missed callback")
278			}
279		}
280
281
282		let f = self.0.set_serial_message_callback();
283
284		if let Some(callback) = callback {
285			let boxed = Box::new(callback);
286			// Store firstly, then register it.
287			unsafe { STORE = Some(boxed as _) }
288			unsafe { f(Some(proxy_serial_message_callback::<F>)) }
289		} else {
290			// Set firstly, then clear the `STORE`.
291			unsafe { f(None) }
292			unsafe { STORE = None }
293		}
294	}
295}
296
297pub mod api {
298	use core::ffi::c_char;
299	use core::ffi::c_float;
300	use core::ffi::c_int;
301	use core::ffi::c_uint;
302	use core::ffi::c_void;
303	use core::ptr::NonNull;
304
305	use sys::ffi::PDCallbackFunction;
306	use sys::ffi::PDDateTime;
307	use sys::ffi::PDLanguage;
308	use sys::ffi::playdate_sys;
309
310
311	pub type FnSerialMessageCallback = Option<unsafe extern "C" fn(data: *const c_char)>;
312
313
314	/// Default system api end-point, ZST.
315	///
316	/// All calls approximately costs ~3 derefs.
317	#[derive(Debug, Clone, Copy, core::default::Default)]
318	pub struct Default;
319	impl Api for Default {}
320
321
322	/// Cached system api end-point.
323	///
324	/// Stores one reference, so size on stack is eq `usize`.
325	///
326	/// All calls approximately costs ~1 deref.
327	#[derive(Clone, Copy)]
328	#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
329	pub struct Cache(&'static playdate_sys);
330
331	impl core::default::Default for Cache {
332		fn default() -> Self { Self(sys::api!(system)) }
333	}
334
335	impl From<*const playdate_sys> for Cache {
336		#[inline(always)]
337		fn from(ptr: *const playdate_sys) -> Self { Self(unsafe { ptr.as_ref() }.expect("system")) }
338	}
339
340	impl From<&'static playdate_sys> for Cache {
341		#[inline(always)]
342		fn from(r: &'static playdate_sys) -> Self { Self(r) }
343	}
344
345	impl From<NonNull<playdate_sys>> for Cache {
346		#[inline(always)]
347		fn from(ptr: NonNull<playdate_sys>) -> Self { Self(unsafe { ptr.as_ref() }) }
348	}
349
350	impl From<&'_ NonNull<playdate_sys>> for Cache {
351		#[inline(always)]
352		fn from(ptr: &NonNull<playdate_sys>) -> Self { Self(unsafe { ptr.as_ref() }) }
353	}
354
355	impl Cache {
356		#[inline(always)]
357		pub fn as_inner(&self) -> &'static playdate_sys { self.0 }
358	}
359
360
361	impl Api for Cache {
362		/// Equivalent to [`sys::ffi::playdate_sys::getLanguage`]
363		#[doc(alias = "sys::ffi::playdate_sys::getLanguage")]
364		#[inline(always)]
365		fn get_language(&self) -> unsafe extern "C" fn() -> PDLanguage { self.0.getLanguage.expect("getLanguage") }
366
367		/// Equivalent to [`sys::ffi::playdate_sys::getCurrentTimeMilliseconds`]
368		#[doc(alias = "sys::ffi::playdate_sys::getCurrentTimeMilliseconds")]
369		#[inline(always)]
370		fn get_current_time_milliseconds(&self) -> unsafe extern "C" fn() -> c_uint {
371			self.0
372			    .getCurrentTimeMilliseconds
373			    .expect("getCurrentTimeMilliseconds")
374		}
375
376		/// Equivalent to [`sys::ffi::playdate_sys::getSecondsSinceEpoch`]
377		#[doc(alias = "sys::ffi::playdate_sys::getSecondsSinceEpoch")]
378		#[inline(always)]
379		fn get_seconds_since_epoch(&self) -> unsafe extern "C" fn(milliseconds: *mut c_uint) -> c_uint {
380			self.0.getSecondsSinceEpoch.expect("getSecondsSinceEpoch")
381		}
382
383		/// Equivalent to [`sys::ffi::playdate_sys::drawFPS`]
384		#[doc(alias = "sys::ffi::playdate_sys::drawFPS")]
385		#[inline(always)]
386		fn draw_fps(&self) -> unsafe extern "C" fn(x: c_int, y: c_int) { self.0.drawFPS.expect("drawFPS") }
387
388		/// Equivalent to [`sys::ffi::playdate_sys::setUpdateCallback`]
389		#[doc(alias = "sys::ffi::playdate_sys::setUpdateCallback")]
390		#[inline(always)]
391		fn set_update_callback(&self) -> unsafe extern "C" fn(update: PDCallbackFunction, userdata: *mut c_void) {
392			self.0.setUpdateCallback.expect("setUpdateCallback")
393		}
394
395		/// Equivalent to [`sys::ffi::playdate_sys::getFlipped`]
396		#[doc(alias = "sys::ffi::playdate_sys::getFlipped")]
397		#[inline(always)]
398		fn get_flipped(&self) -> unsafe extern "C" fn() -> c_int { self.0.getFlipped.expect("getFlipped") }
399
400		/// Equivalent to [`sys::ffi::playdate_sys::setAutoLockDisabled`]
401		#[doc(alias = "sys::ffi::playdate_sys::setAutoLockDisabled")]
402		#[inline(always)]
403		fn set_auto_lock_disabled(&self) -> unsafe extern "C" fn(disable: c_int) {
404			self.0.setAutoLockDisabled.expect("setAutoLockDisabled")
405		}
406
407		/// Equivalent to [`sys::ffi::playdate_sys::getReduceFlashing`]
408		#[doc(alias = "sys::ffi::playdate_sys::getReduceFlashing")]
409		#[inline(always)]
410		fn get_reduce_flashing(&self) -> unsafe extern "C" fn() -> c_int {
411			self.0.getReduceFlashing.expect("getReduceFlashing")
412		}
413
414		/// Equivalent to [`sys::ffi::playdate_sys::getElapsedTime`]
415		#[doc(alias = "sys::ffi::playdate_sys::getElapsedTime")]
416		#[inline(always)]
417		fn get_elapsed_time(&self) -> unsafe extern "C" fn() -> c_float {
418			self.0.getElapsedTime.expect("getElapsedTime")
419		}
420
421		/// Equivalent to [`sys::ffi::playdate_sys::resetElapsedTime`]
422		#[doc(alias = "sys::ffi::playdate_sys::resetElapsedTime")]
423		#[inline(always)]
424		fn reset_elapsed_time(&self) -> unsafe extern "C" fn() {
425			self.0.resetElapsedTime.expect("resetElapsedTime")
426		}
427
428		/// Equivalent to [`sys::ffi::playdate_sys::getBatteryPercentage`]
429		#[doc(alias = "sys::ffi::playdate_sys::getBatteryPercentage")]
430		#[inline(always)]
431		fn get_battery_percentage(&self) -> unsafe extern "C" fn() -> c_float {
432			self.0.getBatteryPercentage.expect("getBatteryPercentage")
433		}
434
435		/// Equivalent to [`sys::ffi::playdate_sys::getBatteryVoltage`]
436		#[doc(alias = "sys::ffi::playdate_sys::getBatteryVoltage")]
437		#[inline(always)]
438		fn get_battery_voltage(&self) -> unsafe extern "C" fn() -> c_float {
439			self.0.getBatteryVoltage.expect("getBatteryVoltage")
440		}
441
442		/// Equivalent to [`sys::ffi::playdate_sys::getTimezoneOffset`]
443		#[doc(alias = "sys::ffi::playdate_sys::getTimezoneOffset")]
444		#[inline(always)]
445		fn get_timezone_offset(&self) -> unsafe extern "C" fn() -> i32 {
446			self.0.getTimezoneOffset.expect("getTimezoneOffset")
447		}
448
449		/// Equivalent to [`sys::ffi::playdate_sys::shouldDisplay24HourTime`]
450		#[doc(alias = "sys::ffi::playdate_sys::shouldDisplay24HourTime")]
451		#[inline(always)]
452		fn should_display_24_hour_time(&self) -> unsafe extern "C" fn() -> c_int {
453			self.0.shouldDisplay24HourTime.expect("shouldDisplay24HourTime")
454		}
455
456		/// Equivalent to [`sys::ffi::playdate_sys::convertEpochToDateTime`]
457		#[doc(alias = "sys::ffi::playdate_sys::convertEpochToDateTime")]
458		#[inline(always)]
459		fn convert_epoch_to_date_time(&self) -> unsafe extern "C" fn(epoch: u32, datetime: *mut PDDateTime) {
460			self.0.convertEpochToDateTime.expect("convertEpochToDateTime")
461		}
462
463		/// Equivalent to [`sys::ffi::playdate_sys::convertDateTimeToEpoch`]
464		#[doc(alias = "sys::ffi::playdate_sys::convertDateTimeToEpoch")]
465		#[inline(always)]
466		fn convert_date_time_to_epoch(&self) -> unsafe extern "C" fn(datetime: *mut PDDateTime) -> u32 {
467			self.0.convertDateTimeToEpoch.expect("convertDateTimeToEpoch")
468		}
469
470		/// Equivalent to [`sys::ffi::playdate_sys::setSerialMessageCallback`]
471		#[doc(alias = "sys::ffi::playdate_sys::setSerialMessageCallback")]
472		#[inline(always)]
473		fn set_serial_message_callback(&self) -> unsafe extern "C" fn(callback: FnSerialMessageCallback) {
474			self.0.setSerialMessageCallback.expect("setSerialMessageCallback")
475		}
476	}
477
478
479	pub trait Api {
480		/// Equivalent to [`sys::ffi::playdate_sys::getLanguage`]
481		#[doc(alias = "sys::ffi::playdate_sys::getLanguage")]
482		#[inline(always)]
483		fn get_language(&self) -> unsafe extern "C" fn() -> PDLanguage { *sys::api!(system.getLanguage) }
484
485		/// Equivalent to [`sys::ffi::playdate_sys::getCurrentTimeMilliseconds`]
486		#[doc(alias = "sys::ffi::playdate_sys::getCurrentTimeMilliseconds")]
487		#[inline(always)]
488		fn get_current_time_milliseconds(&self) -> unsafe extern "C" fn() -> c_uint {
489			*sys::api!(system.getCurrentTimeMilliseconds)
490		}
491
492		/// Equivalent to [`sys::ffi::playdate_sys::getSecondsSinceEpoch`]
493		#[doc(alias = "sys::ffi::playdate_sys::getSecondsSinceEpoch")]
494		#[inline(always)]
495		fn get_seconds_since_epoch(&self) -> unsafe extern "C" fn(milliseconds: *mut c_uint) -> c_uint {
496			*sys::api!(system.getSecondsSinceEpoch)
497		}
498
499		/// Equivalent to [`sys::ffi::playdate_sys::drawFPS`]
500		#[doc(alias = "sys::ffi::playdate_sys::drawFPS")]
501		#[inline(always)]
502		fn draw_fps(&self) -> unsafe extern "C" fn(x: c_int, y: c_int) { *sys::api!(system.drawFPS) }
503
504		/// Equivalent to [`sys::ffi::playdate_sys::setUpdateCallback`]
505		#[doc(alias = "sys::ffi::playdate_sys::setUpdateCallback")]
506		#[inline(always)]
507		fn set_update_callback(&self) -> unsafe extern "C" fn(update: PDCallbackFunction, userdata: *mut c_void) {
508			*sys::api!(system.setUpdateCallback)
509		}
510
511		/// Equivalent to [`sys::ffi::playdate_sys::getFlipped`]
512		#[doc(alias = "sys::ffi::playdate_sys::getFlipped")]
513		#[inline(always)]
514		fn get_flipped(&self) -> unsafe extern "C" fn() -> c_int { *sys::api!(system.getFlipped) }
515
516		/// Equivalent to [`sys::ffi::playdate_sys::setAutoLockDisabled`]
517		#[doc(alias = "sys::ffi::playdate_sys::setAutoLockDisabled")]
518		#[inline(always)]
519		fn set_auto_lock_disabled(&self) -> unsafe extern "C" fn(disable: c_int) {
520			*sys::api!(system.setAutoLockDisabled)
521		}
522
523		/// Equivalent to [`sys::ffi::playdate_sys::getReduceFlashing`]
524		#[doc(alias = "sys::ffi::playdate_sys::getReduceFlashing")]
525		#[inline(always)]
526		fn get_reduce_flashing(&self) -> unsafe extern "C" fn() -> c_int { *sys::api!(system.getReduceFlashing) }
527
528		/// Equivalent to [`sys::ffi::playdate_sys::getElapsedTime`]
529		#[doc(alias = "sys::ffi::playdate_sys::getElapsedTime")]
530		#[inline(always)]
531		fn get_elapsed_time(&self) -> unsafe extern "C" fn() -> c_float { *sys::api!(system.getElapsedTime) }
532
533		/// Equivalent to [`sys::ffi::playdate_sys::resetElapsedTime`]
534		#[doc(alias = "sys::ffi::playdate_sys::resetElapsedTime")]
535		#[inline(always)]
536		fn reset_elapsed_time(&self) -> unsafe extern "C" fn() { *sys::api!(system.resetElapsedTime) }
537
538		/// Equivalent to [`sys::ffi::playdate_sys::getBatteryPercentage`]
539		#[doc(alias = "sys::ffi::playdate_sys::getBatteryPercentage")]
540		#[inline(always)]
541		fn get_battery_percentage(&self) -> unsafe extern "C" fn() -> c_float {
542			*sys::api!(system.getBatteryPercentage)
543		}
544
545
546		/// Equivalent to [`sys::ffi::playdate_sys::getBatteryVoltage`]
547		#[doc(alias = "sys::ffi::playdate_sys::getBatteryVoltage")]
548		#[inline(always)]
549		fn get_battery_voltage(&self) -> unsafe extern "C" fn() -> c_float { *sys::api!(system.getBatteryVoltage) }
550
551		/// Equivalent to [`sys::ffi::playdate_sys::getTimezoneOffset`]
552		#[doc(alias = "sys::ffi::playdate_sys::getTimezoneOffset")]
553		#[inline(always)]
554		fn get_timezone_offset(&self) -> unsafe extern "C" fn() -> i32 { *sys::api!(system.getTimezoneOffset) }
555
556		/// Equivalent to [`sys::ffi::playdate_sys::shouldDisplay24HourTime`]
557		#[doc(alias = "sys::ffi::playdate_sys::shouldDisplay24HourTime")]
558		#[inline(always)]
559		fn should_display_24_hour_time(&self) -> unsafe extern "C" fn() -> c_int {
560			*sys::api!(system.shouldDisplay24HourTime)
561		}
562
563		/// Equivalent to [`sys::ffi::playdate_sys::convertEpochToDateTime`]
564		#[doc(alias = "sys::ffi::playdate_sys::convertEpochToDateTime")]
565		#[inline(always)]
566		fn convert_epoch_to_date_time(&self) -> unsafe extern "C" fn(epoch: u32, datetime: *mut PDDateTime) {
567			*sys::api!(system.convertEpochToDateTime)
568		}
569
570		/// Equivalent to [`sys::ffi::playdate_sys::convertDateTimeToEpoch`]
571		#[doc(alias = "sys::ffi::playdate_sys::convertDateTimeToEpoch")]
572		#[inline(always)]
573		fn convert_date_time_to_epoch(&self) -> unsafe extern "C" fn(datetime: *mut PDDateTime) -> u32 {
574			*sys::api!(system.convertDateTimeToEpoch)
575		}
576
577		/// Equivalent to [`sys::ffi::playdate_sys::setSerialMessageCallback`]
578		#[doc(alias = "sys::ffi::playdate_sys::setSerialMessageCallback")]
579		#[inline(always)]
580		fn set_serial_message_callback(&self) -> unsafe extern "C" fn(callback: FnSerialMessageCallback) {
581			*sys::api!(system.setSerialMessageCallback)
582		}
583	}
584}