1#![cfg_attr(not(test), no_std)]
2extern crate sys;
3
4use core::ffi::c_float;
5use core::ffi::c_int;
6use core::ffi::c_uint;
7
8
9#[derive(Debug, Clone, Copy)]
10pub struct Display<Api = api::Default>(Api);
11
12impl Display<api::Default> {
13 #[allow(non_snake_case)]
17 pub fn Default() -> Self { Self(Default::default()) }
18}
19
20impl Display<api::Cache> {
21 #[allow(non_snake_case)]
25 pub fn Cached() -> Self { Self(Default::default()) }
26}
27
28impl<Api: Default + api::Api> Default for Display<Api> {
29 fn default() -> Self { Self(Default::default()) }
30}
31
32impl<Api: Default + api::Api> Display<Api> {
33 pub fn new() -> Self { Self(Default::default()) }
34}
35
36impl<Api: api::Api> Display<Api> {
37 pub fn new_with(api: Api) -> Self { Self(api) }
38}
39
40
41impl Display<api::Default> {
42 pub const COLUMNS: u32 = sys::ffi::LCD_COLUMNS;
43 pub const ROWS: u32 = sys::ffi::LCD_ROWS;
44 pub const ROW_SIZE: u32 = sys::ffi::LCD_ROWSIZE;
45 pub const SCREEN_RECT: sys::ffi::LCDRect = sys::ffi::LCDRect { left: 0,
46 right: 0,
47 top: Self::COLUMNS as _,
48 bottom: Self::ROWS as _ };
49}
50
51
52impl<Api: api::Api> Display<Api> {
53 #[doc(alias = "sys::ffi::playdate_display::getWidth")]
61 pub fn width(&self) -> c_int {
62 let f = self.0.get_width();
63 unsafe { f() }
64 }
65
66 #[doc(alias = "sys::ffi::playdate_display::getHeight")]
74 pub fn height(&self) -> c_int {
75 let f = self.0.get_height();
76 unsafe { f() }
77 }
78
79 #[doc(alias = "sys::ffi::playdate_display::setRefreshRate")]
85 pub fn set_refresh_rate(&self, rate: c_float) {
86 let f = self.0.set_refresh_rate();
87 unsafe { f(rate) }
88 }
89
90 #[doc(alias = "sys::ffi::playdate_display::setInverted")]
94 pub fn set_inverted(&self, value: bool) {
95 let f = self.0.set_inverted();
96 unsafe { f(value as _) }
97 }
98
99 #[doc(alias = "sys::ffi::playdate_display::setScale")]
108 pub fn set_scale(&self, scale: DisplayScale) { self.set_scale_raw(scale.into()); }
109
110 #[doc(alias = "sys::ffi::playdate_display::setScale")]
121 pub fn set_scale_raw(&self, scale: c_uint) {
122 let f = self.0.set_scale();
123 unsafe { f(scale) }
124 }
125
126 #[doc(alias = "sys::ffi::playdate_display::setMosaic")]
132 pub fn set_mosaic(&self, x: c_uint, y: c_uint) {
133 let f = self.0.set_mosaic();
134 unsafe { f(x, y) }
135 }
136
137 #[doc(alias = "sys::ffi::playdate_display::setFlipped")]
141 pub fn set_flipped(&self, x: bool, y: bool) {
142 let f = self.0.set_flipped();
143 unsafe { f(x as _, y as _) }
144 }
145
146 #[doc(alias = "sys::ffi::playdate_display::setOffset")]
154 pub fn set_offset(&self, x: c_int, y: c_int) {
155 let f = self.0.set_offset();
156 unsafe { f(x, y) }
157 }
158}
159
160
161#[repr(u8)]
162#[derive(Debug, Clone, Copy, PartialEq, Eq)]
163pub enum DisplayScale {
164 Normal = 1,
165 Double = 2,
166 Quad = 4,
167 Eight = 8,
168}
169
170impl Into<c_uint> for DisplayScale {
171 #[inline(always)]
172 fn into(self) -> c_uint { (self as u8).into() }
173}
174
175impl core::fmt::Display for DisplayScale {
176 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", *self as u8) }
177}
178
179impl DisplayScale {
180 #[inline(always)]
181 pub const fn as_u8(self) -> u8 { self as u8 }
182 #[inline(always)]
183 pub const fn as_int(self) -> c_int { self as u8 as _ }
184}
185
186
187pub mod api {
188 use core::ffi::c_float;
189 use core::ffi::c_int;
190 use core::ffi::c_uint;
191 use core::ptr::NonNull;
192 use sys::ffi::playdate_display;
193
194
195 #[derive(Debug, Clone, Copy, core::default::Default)]
199 pub struct Default;
200 impl Api for Default {}
201
202
203 #[derive(Clone, Copy)]
209 #[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
210 pub struct Cache(&'static playdate_display);
211
212 impl core::default::Default for Cache {
213 fn default() -> Self { Self(sys::api!(display)) }
214 }
215
216 impl From<*const playdate_display> for Cache {
217 #[inline(always)]
218 fn from(ptr: *const playdate_display) -> Self { Self(unsafe { ptr.as_ref() }.expect("display")) }
219 }
220
221 impl From<&'static playdate_display> for Cache {
222 #[inline(always)]
223 fn from(r: &'static playdate_display) -> Self { Self(r) }
224 }
225
226 impl From<NonNull<playdate_display>> for Cache {
227 #[inline(always)]
228 fn from(ptr: NonNull<playdate_display>) -> Self { Self(unsafe { ptr.as_ref() }) }
229 }
230
231 impl From<&'_ NonNull<playdate_display>> for Cache {
232 #[inline(always)]
233 fn from(ptr: &NonNull<playdate_display>) -> Self { Self(unsafe { ptr.as_ref() }) }
234 }
235
236
237 impl Api for Cache {
238 #[inline(always)]
239 fn get_width(&self) -> unsafe extern "C" fn() -> c_int { self.0.getWidth.expect("getWidth") }
240
241 #[inline(always)]
242 fn get_height(&self) -> unsafe extern "C" fn() -> c_int { self.0.getHeight.expect("getHeight") }
243
244 #[inline(always)]
245 fn set_refresh_rate(&self) -> unsafe extern "C" fn(rate: c_float) {
246 self.0.setRefreshRate.expect("setRefreshRate")
247 }
248
249 #[inline(always)]
250 fn set_inverted(&self) -> unsafe extern "C" fn(flag: c_int) { self.0.setInverted.expect("setInverted") }
251
252 #[inline(always)]
253 fn set_scale(&self) -> unsafe extern "C" fn(s: c_uint) { self.0.setScale.expect("setScale") }
254
255 #[inline(always)]
256 fn set_mosaic(&self) -> unsafe extern "C" fn(x: c_uint, y: c_uint) { self.0.setMosaic.expect("setMosaic") }
257
258 #[inline(always)]
259 fn set_flipped(&self) -> unsafe extern "C" fn(x: c_int, y: c_int) { self.0.setFlipped.expect("setFlipped") }
260
261 #[inline(always)]
262 fn set_offset(&self) -> unsafe extern "C" fn(x: c_int, y: c_int) { self.0.setOffset.expect("setOffset") }
263 }
264
265
266 pub trait Api {
267 #[doc(alias = "sys::ffi::playdate_display::getWidth")]
269 fn get_width(&self) -> unsafe extern "C" fn() -> c_int { *sys::api!(display.getWidth) }
270 #[doc(alias = "sys::ffi::playdate_display::getHeight")]
272 fn get_height(&self) -> unsafe extern "C" fn() -> c_int { *sys::api!(display.getHeight) }
273 #[doc(alias = "sys::ffi::playdate_display::setRefreshRate")]
275 fn set_refresh_rate(&self) -> unsafe extern "C" fn(rate: c_float) { *sys::api!(display.setRefreshRate) }
276 #[doc(alias = "sys::ffi::playdate_display::setInverted")]
278 fn set_inverted(&self) -> unsafe extern "C" fn(flag: c_int) { *sys::api!(display.setInverted) }
279 #[doc(alias = "sys::ffi::playdate_display::setScale")]
281 fn set_scale(&self) -> unsafe extern "C" fn(s: c_uint) { *sys::api!(display.setScale) }
282 #[doc(alias = "sys::ffi::playdate_display::setMosaic")]
284 fn set_mosaic(&self) -> unsafe extern "C" fn(x: c_uint, y: c_uint) { *sys::api!(display.setMosaic) }
285 #[doc(alias = "sys::ffi::playdate_display::setFlipped")]
287 fn set_flipped(&self) -> unsafe extern "C" fn(x: c_int, y: c_int) { *sys::api!(display.setFlipped) }
288 #[doc(alias = "sys::ffi::playdate_display::setOffset")]
290 fn set_offset(&self) -> unsafe extern "C" fn(x: c_int, y: c_int) { *sys::api!(display.setOffset) }
291 }
292}