Browse Source

Split Screen enum into structs and trait

pull/22/head
Andrea Ciliberti 3 years ago
parent
commit
53aa05a003
  1. 6
      ctru-rs/src/console.rs
  2. 160
      ctru-rs/src/gfx.rs

6
ctru-rs/src/console.rs

@ -15,12 +15,10 @@ impl<'screen> Console<'screen> { @@ -15,12 +15,10 @@ impl<'screen> Console<'screen> {
/// Initialize a console on the chosen screen, overwriting whatever was on the screen
/// previously (including other consoles). The new console is automatically selected for
/// printing.
pub fn init(screen: Ref<'screen, Screen>) -> Self {
pub fn init(screen: Ref<'screen, impl Screen>) -> Self {
let mut context = Box::new(PrintConsole::default());
let screen_kind = *screen;
unsafe { consoleInit(screen_kind.into(), context.as_mut()) };
unsafe { consoleInit(screen.into_raw(), context.as_mut()) };
Console {
context,

160
ctru-rs/src/gfx.rs

@ -11,19 +11,39 @@ use crate::services::gspgpu::{self, FramebufferFormat}; @@ -11,19 +11,39 @@ use crate::services::gspgpu::{self, FramebufferFormat};
///
/// The service exits when this struct is dropped.
pub struct Gfx {
top_screen: RefCell<Screen>,
bottom_screen: RefCell<Screen>,
top_screen: RefCell<TopScreen>,
bottom_screen: RefCell<BottomScreen>,
}
/// Available screens on the 3DS
#[derive(Copy, Clone, Debug)]
pub enum Screen {
/// The top screen
Top,
/// The bottom screen
Bottom,
/// Trait implemented by TopScreen and BottomScreen for common methods
pub trait Screen {
/// Returns the libctru value for the Screen kind
fn into_raw(&self) -> ctru_sys::gfxScreen_t;
/// Sets whether to use double buffering. Enabled by default.
///
/// Note that even when double buffering is disabled, one should still use the `swap_buffers`
/// method on each frame to keep the gsp configuration up to date
fn set_double_buffering(&mut self, enabled: bool);
/// Gets the framebuffer format
fn get_framebuffer_format(&self) -> FramebufferFormat;
/// Change the framebuffer format
fn set_framebuffer_format(&mut self, fmt: FramebufferFormat);
/// 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);
}
pub struct TopScreen;
pub struct BottomScreen;
#[derive(Copy, Clone, Debug)]
/// Side of top screen framebuffer
///
@ -49,28 +69,28 @@ impl Gfx { @@ -49,28 +69,28 @@ impl Gfx {
ctru_sys::gfxInit(top_fb_fmt.into(), bottom_fb_fmt.into(), use_vram_buffers);
}
Gfx {
top_screen: RefCell::new(Screen::Top),
bottom_screen: RefCell::new(Screen::Bottom),
top_screen: RefCell::new(TopScreen),
bottom_screen: RefCell::new(BottomScreen),
}
}
/// Try to get an immutable reference to the Top screen
pub fn get_top_screen(&self) -> Result<Ref<'_, Screen>, BorrowError> {
pub fn get_top_screen(&self) -> Result<Ref<'_, TopScreen>, BorrowError> {
self.top_screen.try_borrow()
}
/// Try to get a mutable reference to the Top screen
pub fn get_top_screen_mut(&self) -> Result<RefMut<'_, Screen>, BorrowMutError> {
pub fn get_top_screen_mut(&self) -> Result<RefMut<'_, TopScreen>, BorrowMutError> {
self.top_screen.try_borrow_mut()
}
/// Try to get an immutable reference to the Bottom screen
pub fn get_bottom_screen(&self) -> Result<Ref<'_, Screen>, BorrowError> {
pub fn get_bottom_screen(&self) -> Result<Ref<'_, BottomScreen>, BorrowError> {
self.bottom_screen.try_borrow()
}
/// Try to get a mutable reference to the Bottom screen
pub fn get_bottom_screen_mut(&self) -> Result<RefMut<'_, Screen>, BorrowMutError> {
pub fn get_bottom_screen_mut(&self) -> Result<RefMut<'_, BottomScreen>, BorrowMutError> {
self.bottom_screen.try_borrow_mut()
}
@ -101,88 +121,88 @@ impl Gfx { @@ -101,88 +121,88 @@ impl Gfx {
}
}
impl Screen {
impl TopScreen {
/// Enable or disable the 3D stereoscopic effect
///
/// #Errors
/// When called by the Bottom screen
pub fn set_3d_enabled(&mut self, enabled: bool) -> Result<(), String> {
match self {
Screen::Top => unsafe {
pub fn set_3d_enabled(&mut self, enabled: bool) {
unsafe {
ctru_sys::gfxSet3D(enabled);
Ok(())
},
Screen::Bottom => Err("Tried to enable 3D on bottom screen".to_string()),
}
}
/// Enable or disable the wide screen mode (top screen).
/// This only works when 3D is disabled.
///
/// #Errors
/// When called by the Bottom screen
pub fn set_wide_mode(&mut self, enabled: bool) -> Result<(), String> {
match self {
Screen::Top => unsafe {
pub fn set_wide_mode(&mut self, enabled: bool) {
unsafe {
ctru_sys::gfxSetWide(enabled);
Ok(())
},
Screen::Bottom => Err("Tried to change wide-mode on bottom screen".to_string()),
}
}
/// Get the status of wide screen mode.
///
/// #Errors
/// When called by the Bottom screen
pub fn get_wide_mode(&self) -> Result<bool, String> {
match self {
Screen::Top => unsafe { Ok(ctru_sys::gfxIsWide()) },
Screen::Bottom => Err("Tried to check wide-mode status on bottom screen".to_string()),
pub fn get_wide_mode(&self) -> bool {
unsafe { ctru_sys::gfxIsWide() }
}
}
/// Sets whether to use double buffering. Enabled by default.
///
/// Note that even when double buffering is disabled, one should still use the `swap_buffers`
/// method on each frame to keep the gsp configuration up to date
pub fn set_double_buffering(&mut self, screen: Screen, enabled: bool) {
unsafe { ctru_sys::gfxSetDoubleBuffering(screen.into(), enabled) }
impl Screen for TopScreen {
fn into_raw(&self) -> ctru_sys::gfxScreen_t {
ctru_sys::GFX_TOP
}
/// Gets the framebuffer format
pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat {
unsafe { ctru_sys::gfxGetScreenFormat(screen.into()).into() }
fn set_double_buffering(&mut self, enabled: bool) {
unsafe { ctru_sys::gfxSetDoubleBuffering(ctru_sys::GFX_TOP, enabled) }
}
/// Change the framebuffer format
pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) {
unsafe { ctru_sys::gfxSetScreenFormat(screen.into(), fmt.into()) }
fn get_framebuffer_format(&self) -> FramebufferFormat {
unsafe { ctru_sys::gfxGetScreenFormat(ctru_sys::GFX_TOP).into() }
}
/// Returns a tuple containing a pointer to the specifified framebuffer (as determined by the
/// provided `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
pub fn get_raw_framebuffer(&self, screen: Screen, side: Side) -> (*mut u8, u16, u16) {
fn set_framebuffer_format(&mut self, fmt: FramebufferFormat) {
unsafe { ctru_sys::gfxSetScreenFormat(ctru_sys::GFX_TOP, fmt.into()) }
}
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(screen.into(), side.into(), &mut width, &mut height);
let buf: *mut u8 = ctru_sys::gfxGetFramebuffer(
ctru_sys::GFX_TOP,
side.into(),
&mut width,
&mut height,
);
(buf, width, height)
}
}
}
impl From<Screen> for ctru_sys::gfxScreen_t {
fn from(g: Screen) -> ctru_sys::gfxScreen_t {
use self::Screen::*;
match g {
Top => ctru_sys::GFX_TOP,
Bottom => ctru_sys::GFX_BOTTOM,
impl Screen for BottomScreen {
fn into_raw(&self) -> ctru_sys::gfxScreen_t {
ctru_sys::GFX_BOTTOM
}
fn set_double_buffering(&mut self, enabled: bool) {
unsafe { ctru_sys::gfxSetDoubleBuffering(ctru_sys::GFX_BOTTOM, enabled) }
}
fn get_framebuffer_format(&self) -> FramebufferFormat {
unsafe { ctru_sys::gfxGetScreenFormat(ctru_sys::GFX_BOTTOM).into() }
}
fn set_framebuffer_format(&mut self, fmt: FramebufferFormat) {
unsafe { ctru_sys::gfxSetScreenFormat(ctru_sys::GFX_BOTTOM, fmt.into()) }
}
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(
ctru_sys::GFX_BOTTOM,
side.into(),
&mut width,
&mut height,
);
(buf, width, height)
}
}
}
@ -201,8 +221,8 @@ impl Default for Gfx { @@ -201,8 +221,8 @@ impl Default for Gfx {
fn default() -> Self {
unsafe { ctru_sys::gfxInitDefault() };
Gfx {
top_screen: RefCell::new(Screen::Top),
bottom_screen: RefCell::new(Screen::Bottom),
top_screen: RefCell::new(TopScreen),
bottom_screen: RefCell::new(BottomScreen),
}
}
}

Loading…
Cancel
Save