Created
May 17, 2020 23:16
-
-
Save rtsuk/7cbd37937d831d25f48fb8458360da98 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use { | |
core::{ptr, slice}, | |
cstr_core::CString, | |
playdate_sys::{ | |
LCDBitmapDrawMode_kDrawModeBlackTransparent, LCDBitmapDrawMode_kDrawModeCopy, | |
LCDBitmapDrawMode_kDrawModeFillBlack, LCDBitmapDrawMode_kDrawModeFillWhite, | |
LCDBitmapDrawMode_kDrawModeInverted, LCDBitmapDrawMode_kDrawModeNXOR, | |
LCDBitmapDrawMode_kDrawModeWhiteTransparent, LCDBitmapDrawMode_kDrawModeXOR, | |
LCDSolidColor_kColorBlack, LCDSolidColor_kColorClear, LCDSolidColor_kColorWhite, | |
LCDSolidColor_kColorXOR, PDStringEncoding_kUTF8Encoding, LCD_ROWS, LCD_ROWSIZE, | |
}, | |
}; | |
pub use playdate_sys::LCDRect as Rect; | |
pub struct Bitmap(*mut playdate_sys::LCDBitmap); | |
type OptionalBitmap<'a> = Option<&'a mut Bitmap>; | |
fn raw_bitmap(bitmap: OptionalBitmap<'_>) -> *mut playdate_sys::LCDBitmap { | |
if let Some(bitmap) = bitmap { | |
bitmap.0 | |
} else { | |
ptr::null_mut() as *mut playdate_sys::LCDBitmap | |
} | |
} | |
pub struct Font(*mut playdate_sys::LCDFont); | |
impl Font { | |
pub fn new(font: *mut playdate_sys::LCDFont) -> Self { | |
assert!(font != ptr::null_mut()); | |
Self(font) | |
} | |
} | |
pub enum BitmapDrawMode { | |
Copy, | |
WhiteTransparent, | |
BlackTransparent, | |
FillWhite, | |
FillBlack, | |
XOR, | |
NXOR, | |
Inverted, | |
} | |
impl From<BitmapDrawMode> for u32 { | |
fn from(draw_mode: BitmapDrawMode) -> Self { | |
let lcd_draw_mode = match draw_mode { | |
BitmapDrawMode::Copy => LCDBitmapDrawMode_kDrawModeCopy, | |
BitmapDrawMode::WhiteTransparent => LCDBitmapDrawMode_kDrawModeWhiteTransparent, | |
BitmapDrawMode::BlackTransparent => LCDBitmapDrawMode_kDrawModeBlackTransparent, | |
BitmapDrawMode::FillWhite => LCDBitmapDrawMode_kDrawModeFillWhite, | |
BitmapDrawMode::FillBlack => LCDBitmapDrawMode_kDrawModeFillBlack, | |
BitmapDrawMode::XOR => LCDBitmapDrawMode_kDrawModeXOR, | |
BitmapDrawMode::NXOR => LCDBitmapDrawMode_kDrawModeNXOR, | |
BitmapDrawMode::Inverted => LCDBitmapDrawMode_kDrawModeInverted, | |
}; | |
lcd_draw_mode | |
} | |
} | |
pub enum SolidColor { | |
Black, | |
White, | |
Clear, | |
XOR, | |
} | |
impl From<SolidColor> for usize { | |
fn from(color: SolidColor) -> Self { | |
let solid_color = match color { | |
SolidColor::Black => LCDSolidColor_kColorBlack, | |
SolidColor::White => LCDSolidColor_kColorWhite, | |
SolidColor::Clear => LCDSolidColor_kColorClear, | |
SolidColor::XOR => LCDSolidColor_kColorXOR, | |
}; | |
solid_color as usize | |
} | |
} | |
pub struct Graphics(*mut playdate_sys::playdate_graphics); | |
impl Graphics { | |
pub fn new(graphics: *mut playdate_sys::playdate_graphics) -> Self { | |
Self(graphics) | |
} | |
pub fn get_frame(&self) -> Option<&'static mut [u8]> { | |
let frame = unsafe { | |
let get_frame_fn = (*self.0).getFrame.expect("getFrame"); | |
let ptr = get_frame_fn(); | |
if ptr == ptr::null_mut() { | |
None | |
} else { | |
Some(slice::from_raw_parts_mut( | |
ptr, | |
(LCD_ROWSIZE * LCD_ROWS) as usize, | |
)) | |
} | |
}; | |
frame | |
} | |
pub fn get_display_frame(&self) -> &'static mut [u8] { | |
let frame = unsafe { | |
let get_display_frame_fn = (*self.0).getDisplayFrame.expect("getDisplayFrame"); | |
slice::from_raw_parts_mut(get_display_frame_fn(), (LCD_ROWSIZE * LCD_ROWS) as usize) | |
}; | |
frame | |
} | |
pub fn mark_updated_rows(&self, x: i32, y: i32) { | |
unsafe { | |
let mark_updated_rows_fn = (*self.0) | |
.markUpdatedRows | |
.expect("failed to get markUpdatedRows function pointer from graphics structure"); | |
mark_updated_rows_fn(x, y); | |
} | |
} | |
pub fn clear(&self, color: SolidColor) { | |
let color = color.into(); | |
unsafe { | |
let clear_fn = (*self.0) | |
.clear | |
.expect("failed to get clear function pointer from graphics structure"); | |
clear_fn(color); | |
} | |
} | |
pub fn load_font(&self, path: &str) -> Font { | |
let c_path = CString::new(path).expect("CString::new failed"); | |
let font = unsafe { | |
let load_font_fn = (*self.0).loadFont.expect("loadFont"); | |
load_font_fn(c_path.as_ptr(), ptr::null_mut()) | |
}; | |
Font::new(font) | |
} | |
pub fn draw_text( | |
&self, | |
font: &Font, | |
target: OptionalBitmap, | |
stencil: OptionalBitmap, | |
text: &str, | |
x: i32, | |
y: i32, | |
mode: BitmapDrawMode, | |
tracking: i32, | |
clip: Rect, | |
) { | |
let c_text = CString::new(text).expect("CString::new failed"); | |
unsafe { | |
let draw_text_fn = (*self.0) | |
.drawText | |
.expect("failed to get drawText function pointer from graphics structure"); | |
draw_text_fn( | |
font.0, | |
raw_bitmap(target), | |
raw_bitmap(stencil), | |
c_text.as_ptr() as *const core::ffi::c_void, | |
text.len() as u64, | |
PDStringEncoding_kUTF8Encoding, | |
x, | |
y, | |
mode.into(), | |
tracking, | |
clip, | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment