Skip to content

Commit

Permalink
Merge pull request #113 from boozook/api/gfx-docs
Browse files Browse the repository at this point in the history
Improve docs in graphics crate
  • Loading branch information
boozook authored Sep 24, 2023
2 parents bfc9a28 + 50c0126 commit 543ca3a
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 12 deletions.
2 changes: 1 addition & 1 deletion 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 api/gfx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "playdate-graphics"
version = "0.2.1"
version = "0.2.2"
readme = "README.md"
description = "High-level graphics API built on-top of Playdate API"
keywords = ["playdate", "sdk", "api", "gamedev"]
Expand Down
95 changes: 87 additions & 8 deletions api/gfx/src/bitmap/bitmap.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Playdate Bitmap API
//! Playdate bitmap API
use core::ffi::c_char;
use core::ffi::c_float;
Expand Down Expand Up @@ -117,14 +117,22 @@ impl<'owner> BitmapRef<'owner> {
}


// TODO: Properly document methods of `Bitmap`.
impl<Api: api::Api> Bitmap<Api, true> {
/// Allocates and returns a new `width` by `height` Bitmap filled with `bg` color.
///
/// Calls [`sys::ffi::playdate_graphics::newBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::newBitmap")]
pub fn new(width: c_int, height: c_int, bg: Color) -> Result<Self, Error>
where Api: Default {
let api = Api::default();
Self::new_with(api, width, height, bg)
}

/// Allocates and returns a new `width` by `height` Bitmap filled with `bg` color,
/// using the given `api`.
///
/// Calls [`sys::ffi::playdate_graphics::newBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::newBitmap")]
pub fn new_with(api: Api, width: c_int, height: c_int, bg: Color) -> Result<Self, Error> {
let f = api.new_bitmap();
let ptr = unsafe { f(width, height, bg.into()) };
Expand All @@ -137,14 +145,20 @@ impl<Api: api::Api> Bitmap<Api, true> {


/// Load a bitmap from a file.
///
/// Calls [`sys::ffi::playdate_graphics::loadBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::loadBitmap")]
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, ApiError>
where Api: Default {
let api = Api::default();
Self::load_with(api, path)
}

/// Load a bitmap from a file,
/// create new bitmap with given api-access-point.
/// create new bitmap with given `api`.
///
/// Calls [`sys::ffi::playdate_graphics::loadBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::loadBitmap")]
pub fn load_with<P: AsRef<Path>>(api: Api, path: P) -> Result<Self, ApiError> {
let mut err = Box::new(core::ptr::null() as *const c_char);
let out_err = Box::into_raw(err);
Expand All @@ -168,6 +182,10 @@ impl<Api: api::Api> Bitmap<Api, true> {


impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
/// Load a bitmap from a file into `self`.
///
/// Calls [`sys::ffi::playdate_graphics::loadIntoBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::loadIntoBitmap")]
pub fn load_into<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ApiError> {
let mut err = Box::new(core::ptr::null() as *const c_char);
let out_err = Box::into_raw(err);
Expand Down Expand Up @@ -197,6 +215,11 @@ impl<Api: api::Api, const FOD: bool> Drop for Bitmap<Api, FOD> {
}

impl<Api: api::Api + Clone> Clone for Bitmap<Api, true> {
/// Allocates and returns a new `Bitmap` that is an exact copy of `self`,
/// __not a reference__.
///
/// Equivalent to [`sys::ffi::playdate_graphics::copyBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::copyBitmap")]
fn clone(&self) -> Self {
let f = self.1.copy_bitmap();
let ptr = unsafe { f(self.0) };
Expand All @@ -210,12 +233,20 @@ impl<Api: api::Api + Clone> Clone for Bitmap<Api, true> {


impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
/// Clears bitmap, filling with the given `bg` color.
///
/// Equivalent to [`sys::ffi::playdate_graphics::clearBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::clearBitmap")]
pub fn clear(&self, bg: Color) {
let f = self.1.clear_bitmap();
unsafe { f(self.0, bg.into()) };
}


/// Returns mutable borrow of bitmap-data by this bitmap.
///
/// Calls [`sys::ffi::playdate_graphics::getBitmapData`].
#[doc(alias = "sys::ffi::playdate_graphics::getBitmapData")]
pub fn bitmap_data<'bitmap>(&'bitmap mut self) -> Result<BitmapData<'bitmap>, Error> {
let mut width: c_int = 0;
let mut height: c_int = 0;
Expand Down Expand Up @@ -262,7 +293,11 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
}


/// Sets a mask image for the given bitmap. The set mask must be the same size as the target bitmap.
/// Sets a mask image for the bitmap.
/// The set mask must be the same size as the `self` bitmap.
///
/// Calls [`sys::ffi::playdate_graphics::setBitmapMask`].
#[doc(alias = "sys::ffi::playdate_graphics::setBitmapMask")]
pub fn set_mask<Api2: api::Api, const FREE: bool>(&self, mask: &mut Bitmap<Api2, FREE>) -> Result<(), Error> {
// TODO: investigate is it correct "res == 0 => Ok"
let f = self.1.set_bitmap_mask();
Expand All @@ -278,6 +313,9 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
/// If the image doesn’t have a mask, returns None.
///
/// Clones inner api-access.
///
/// Calls [`sys::ffi::playdate_graphics::getBitmapMask`].
#[doc(alias = "sys::ffi::playdate_graphics::getBitmapMask")]
#[inline(always)]
pub fn mask(&self) -> Option<Bitmap<Api, false>>
where Api: Clone {
Expand All @@ -288,6 +326,9 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
/// If the image doesn’t have a mask, returns None.
///
/// Produced `Bitmap` uses passed `api` api-access.
///
/// Calls [`sys::ffi::playdate_graphics::getBitmapMask`].
#[doc(alias = "sys::ffi::playdate_graphics::getBitmapMask")]
// XXX: investigate is it should be free-on-drop?
pub fn mask_with<NewApi: api::Api>(&self, api: NewApi) -> Option<Bitmap<NewApi, false>> {
let f = self.1.get_bitmap_mask();
Expand All @@ -299,7 +340,10 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
}
}

/// Returns a new, rotated and scaled Bitmap based on the given bitmap.
/// Returns a new, rotated and scaled Bitmap based on the bitmap.
///
/// Calls [`sys::ffi::playdate_graphics::rotatedBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::rotatedBitmap")]
#[inline(always)]
pub fn rotated_clone(&self,
rotation: c_float,
Expand All @@ -311,6 +355,10 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
self.rotated_clone_with(self.1.clone(), rotation, x_scale, y_scale)
}

/// Returns a new, rotated and scaled Bitmap based on the bitmap using given `api`.
///
/// Calls [`sys::ffi::playdate_graphics::rotatedBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::rotatedBitmap")]
pub fn rotated_clone_with<NewApi: api::Api>(&self,
api: NewApi,
rotation: c_float,
Expand All @@ -332,12 +380,22 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
}


/// Draws `self` with its upper-left corner at location `x`, `y`,
/// using the given `flip` orientation.
///
/// Equivalent to [`sys::ffi::playdate_graphics::drawBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::drawBitmap")]
#[inline(always)]
pub fn draw(&self, x: c_int, y: c_int, flip: BitmapFlip) {
let f = self.1.draw_bitmap();
unsafe { f(self.0, x, y, flip) }
}

/// Draws `self` with its upper-left corner at location `x`, `y`
/// __tiled inside a `width` by `height` rectangle__.
///
/// Equivalent to [`sys::ffi::playdate_graphics::tileBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::tileBitmap")]
#[inline(always)]
pub fn draw_tiled(&self, x: c_int, y: c_int, width: c_int, height: c_int, flip: BitmapFlip) {
let f = self.1.tile_bitmap();
Expand All @@ -352,6 +410,7 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
/// * if `center_x` and `center_y` are both 0 the top left corner of the image (before rotation) is at (`x`,`y`), etc.
///
/// Equivalent to [`sys::ffi::playdate_graphics::drawRotatedBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::drawRotatedBitmap")]
#[inline(always)]
pub fn draw_rotated(&self,
x: c_int,
Expand All @@ -365,15 +424,26 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
unsafe { f(self.0, x, y, degrees, center_x, center_y, x_scale, y_scale) }
}

/// Draws this bitmap scaled to `x_scale` and `y_scale` with its upper-left corner at location `x`, `y`.
///
/// Note that flip is not available when drawing scaled bitmaps but negative scale values will achieve the same effect.
///
/// Equivalent to [`sys::ffi::playdate_graphics::drawScaledBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::drawScaledBitmap")]
#[inline(always)]
pub fn draw_scaled(&self, x: c_int, y: c_int, x_scale: c_float, y_scale: c_float) {
let f = self.1.draw_scaled_bitmap();
unsafe { f(self.0, x, y, x_scale, y_scale) }
}


/// Returns `true` if any of the opaque pixels in this bitmap when positioned at `x, y` with `flip` overlap any of the opaque pixels in `other` bitmap at `x_other`, `y_other` with `flip_other` within the non-empty `rect`,
/// Returns `true` if any of the opaque pixels in this bitmap when positioned at `x, y` with `flip`
/// overlap any of the opaque pixels in `other` bitmap at `x_other`, `y_other` with `flip_other`
/// within the non-empty `rect`,
/// or `false` if no pixels overlap or if one or both fall completely outside of `rect`.
///
/// Equivalent to [`sys::ffi::playdate_graphics::checkMaskCollision`].
#[doc(alias = "sys::ffi::playdate_graphics::checkMaskCollision")]
#[inline(always)]
pub fn check_mask_collision<OApi: api::Api, const OFOD: bool>(&self,
x: c_int,
Expand All @@ -390,16 +460,21 @@ impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
}


/// Sets `color` to an 8 x 8 pattern using this bitmap.
/// Sets `color` to an `8 x 8` pattern using this bitmap.
/// `x, y` indicates the top left corner of the 8 x 8 pattern.
///
/// Equivalent to [`sys::ffi::playdate_graphics::setColorToPattern`].
#[doc(alias = "sys::ffi::playdate_graphics::setColorToPattern")]
pub fn set_color_to_pattern(&self, color: &mut LCDColor, x: c_int, y: c_int) {
let f = self.1.set_color_to_pattern();
unsafe { f(color as _, self.0, x, y) }
}
}


/// The data is 1 bit per pixel packed format, in MSB order; in other words, the high bit of the first byte in data is the top left pixel of the image.
/// The data is 1 bit per pixel packed format, in MSB order; in other words,
/// the high bit of the first byte in data is the top left pixel of the image.
///
/// The `mask` data is in same format but means transparency.
pub struct BitmapData<'bitmap> {
pub width: c_int,
Expand Down Expand Up @@ -441,6 +516,10 @@ pub fn debug_bitmap() -> Result<Bitmap<api::Default, false>, ApiError> {
}
}

/// Returns a bitmap containing the contents of the display buffer.
///
/// __The system owns this bitmap—​do not free it.__
///
/// Equivalent to [`sys::ffi::playdate_graphics::getDisplayBufferBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::getDisplayBufferBitmap")]
pub fn display_buffer_bitmap() -> Result<Bitmap<api::Default, false>, Error> {
Expand Down
33 changes: 33 additions & 0 deletions api/gfx/src/bitmap/table.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Playdate bitmap-table API
use alloc::boxed::Box;
use core::ffi::c_char;
use core::ffi::c_int;
Expand Down Expand Up @@ -27,12 +29,21 @@ impl<Api: api::Api, const FOD: bool> Drop for BitmapTable<Api, FOD> {


impl<Api: api::Api> BitmapTable<Api, true> {
/// Allocates and returns a new [`BitmapTable`] that can hold count `width` by `height` [`Bitmap`]s.
///
/// Equivalent to [`sys::ffi::playdate_graphics::newBitmapTable`].
#[doc(alias = "sys::ffi::playdate_graphics::newBitmapTable")]
pub fn new(count: c_int, width: c_int, height: c_int) -> Result<Self, Error>
where Api: Default {
let api = Api::default();
Self::new_with(api, count, width, height)
}

/// Allocates and returns a new [`BitmapTable`] that can hold count `width` by `height` [`Bitmap`]s,
/// using the given `api`.
///
/// Equivalent to [`sys::ffi::playdate_graphics::newBitmapTable`].
#[doc(alias = "sys::ffi::playdate_graphics::newBitmapTable")]
pub fn new_with(api: Api, count: c_int, width: c_int, height: c_int) -> Result<Self, Error> {
let f = api.new_bitmap_table();
let ptr = unsafe { f(count, width, height) };
Expand All @@ -44,12 +55,24 @@ impl<Api: api::Api> BitmapTable<Api, true> {
}


/// Allocates and returns a new [`Bitmap`] from the file at `path`.
///
/// If there is no file at `path`, the function returns error.
///
/// Calls [`sys::ffi::playdate_graphics::loadBitmapTable`].
#[doc(alias = "sys::ffi::playdate_graphics::loadBitmapTable")]
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, ApiError>
where Api: Default {
let api = Api::default();
Self::load_with(api, path)
}

/// Allocates and returns a new [`Bitmap`] from the file at `path`.
///
/// If there is no file at `path`, the function returns error.
///
/// Calls [`sys::ffi::playdate_graphics::loadBitmapTable`].
#[doc(alias = "sys::ffi::playdate_graphics::loadBitmapTable")]
pub fn load_with<P: AsRef<Path>>(api: Api, path: P) -> Result<Self, ApiError> {
let mut err = Box::new(core::ptr::null() as *const c_char);
let out_err = Box::into_raw(err);
Expand All @@ -72,6 +95,10 @@ impl<Api: api::Api> BitmapTable<Api, true> {
}

impl<Api: api::Api, const FOD: bool> BitmapTable<Api, FOD> {
/// Loads the image-table at `path` into the previously allocated this table.
///
/// Equivalent to [`sys::ffi::playdate_graphics::loadIntoBitmapTable`].
#[doc(alias = "sys::ffi::playdate_graphics::loadIntoBitmapTable")]
pub fn load_into<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ApiError> {
let mut err = Box::new(core::ptr::null() as *const c_char);
let out_err = Box::into_raw(err);
Expand All @@ -93,6 +120,9 @@ impl<Api: api::Api, const FOD: bool> BitmapTable<Api, FOD> {
/// if `index` is out of bounds, the function returns `None`.
///
/// Creates new default api access-point.
///
/// Equivalent to [`sys::ffi::playdate_graphics::getTableBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::getTableBitmap")]
pub fn get<'table, BitApi: BitmapApi>(&'table self, index: c_int) -> Option<Bitmap<BitApi, true>>
where Bitmap<BitApi, true>: 'table,
BitApi: Default {
Expand All @@ -103,6 +133,9 @@ impl<Api: api::Api, const FOD: bool> BitmapTable<Api, FOD> {
/// if `index` is out of bounds, the function returns `None`.
///
/// Produced `Bitmap` uses passed `api` access-point.
///
/// Equivalent to [`sys::ffi::playdate_graphics::getTableBitmap`].
#[doc(alias = "sys::ffi::playdate_graphics::getTableBitmap")]
pub fn get_with<'table, BitApi: BitmapApi>(&'table self,
api: BitApi,
index: c_int)
Expand Down
2 changes: 1 addition & 1 deletion api/gfx/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Playdate Graphics API
//! Playdate graphics API
#![cfg_attr(not(test), no_std)]
#![feature(error_in_core)]

Expand Down
2 changes: 1 addition & 1 deletion api/gfx/src/text.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Playdate Text API
//! Playdate text API
use core::ffi::{c_int, c_char};

Expand Down

0 comments on commit 543ca3a

Please sign in to comment.