diff --git a/ctru-rs/examples/graphics-bitmap.rs b/ctru-rs/examples/graphics-bitmap.rs index 8afc3ac..6ec7b97 100644 --- a/ctru-rs/examples/graphics-bitmap.rs +++ b/ctru-rs/examples/graphics-bitmap.rs @@ -15,6 +15,10 @@ use ctru::Gfx; /// -channel RGB -combine -rotate 90 \ /// assets/ferris.rgb /// ``` +/// +/// This creates an image appropriate for the default frame buffer format of +/// BGR888 and rotates the image 90° to account for the screen actually being +/// in portrait mode. static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb"); fn main() { @@ -32,10 +36,8 @@ fn main() { // In this way we can draw our image only once on screen. bottom_screen.set_double_buffering(false); - // The "Left" side framebuffer is the only valid one for bottom screen - // TODO: make `get_raw_framebuffer` only accept a side for top screen - // Also, we assume the image is the correct size already... - let (frame_buffer, _width, _height) = bottom_screen.get_raw_framebuffer(Side::Left); + // We assume the image is the correct size already, so we drop width + height. + let (frame_buffer, _width, _height) = bottom_screen.get_raw_framebuffer(); // Copy the image into the frame buffer unsafe { diff --git a/ctru-rs/src/gfx.rs b/ctru-rs/src/gfx.rs index 1092640..9d39284 100644 --- a/ctru-rs/src/gfx.rs +++ b/ctru-rs/src/gfx.rs @@ -28,26 +28,11 @@ pub trait Screen { fn set_framebuffer_format(&mut self, fmt: FramebufferFormat) { unsafe { ctru_sys::gfxSetScreenFormat(self.as_raw(), fmt.into()) } } - - /// Returns a tuple containing a pointer to the specifified framebuffer (as determined by the - /// calling screen and `Side`), the width of the framebuffer in pixels, and the height of - /// the framebuffer in pixels - /// - /// Note that the pointer returned by this function can change after each call to this function - /// if double buffering is enabled - fn get_raw_framebuffer(&self, side: Side) -> (*mut u8, u16, u16) { - let mut width: u16 = 0; - let mut height: u16 = 0; - unsafe { - let buf: *mut u8 = - ctru_sys::gfxGetFramebuffer(self.as_raw(), side.into(), &mut width, &mut height); - (buf, width, height) - } - } } #[non_exhaustive] pub struct TopScreen; + #[non_exhaustive] pub struct BottomScreen; @@ -138,6 +123,44 @@ impl TopScreen { pub fn get_wide_mode(&self) -> bool { unsafe { ctru_sys::gfxIsWide() } } + + /// Returns a tuple containing a pointer to the top screen's framebuffer + /// (as determined by the `side`), the width of the framebuffer in pixels, + /// and the height of the framebuffer in pixels. + /// + /// Note that the pointer returned by this function can change after each call to this function + /// if double buffering is enabled + pub fn get_raw_framebuffer(&mut self, side: Side) -> (*mut u8, u16, u16) { + let mut width: u16 = 0; + let mut height: u16 = 0; + unsafe { + let buf: *mut u8 = + ctru_sys::gfxGetFramebuffer(self.as_raw(), side.into(), &mut width, &mut height); + (buf, width, height) + } + } +} + +impl BottomScreen { + /// Returns a tuple containing a pointer to the bottom screen's framebuffer, + /// the width of the framebuffer in pixels, and the height of the framebuffer in pixels. + /// + /// Note that the pointer returned by this function can change after each call to this function + /// if double buffering is enabled + pub fn get_raw_framebuffer(&mut self) -> (*mut u8, u16, u16) { + let mut width: u16 = 0; + let mut height: u16 = 0; + unsafe { + let buf: *mut u8 = ctru_sys::gfxGetFramebuffer( + self.as_raw(), + Side::Left.into(), + &mut width, + &mut height, + ); + // TODO: does it make sense to use a struct for this instead of a tuple? + (buf, width, height) + } + } } impl Screen for TopScreen {