Skip to content

Instantly share code, notes, and snippets.

@rtsuk
Created May 17, 2020 23:16
Show Gist options
  • Save rtsuk/7cbd37937d831d25f48fb8458360da98 to your computer and use it in GitHub Desktop.
Save rtsuk/7cbd37937d831d25f48fb8458360da98 to your computer and use it in GitHub Desktop.
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