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> {
/// Initialize a console on the chosen screen, overwriting whatever was on the 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 /// previously (including other consoles). The new console is automatically selected for
/// printing. /// 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 mut context = Box::new(PrintConsole::default());
let screen_kind = *screen; unsafe { consoleInit(screen.into_raw(), context.as_mut()) };
unsafe { consoleInit(screen_kind.into(), context.as_mut()) };
Console { Console {
context, context,

160
ctru-rs/src/gfx.rs

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

Loading…
Cancel
Save