Browse Source

Fix double buffering in example via impl Swap and Flush for Console

pull/86/head
AzureMarker 1 year ago
parent
commit
1f45da1ebc
  1. 18
      ctru-rs/examples/ir-user-circle-pad-pro.rs
  2. 26
      ctru-rs/src/console.rs
  3. 4
      ctru-rs/src/services/gfx.rs

18
ctru-rs/examples/ir-user-circle-pad-pro.rs

@ -80,10 +80,8 @@ impl<'screen> CirclePadProDemo<'screen> {
bottom_console: Console<'screen, BottomScreen>, bottom_console: Console<'screen, BottomScreen>,
) -> Self { ) -> Self {
// Set up double buffering on top screen // Set up double buffering on top screen
top_console.with_screen(|screen| { top_console.set_double_buffering(true);
screen.set_double_buffering(true); top_console.swap_buffers();
screen.swap_buffers();
});
// Write messages to bottom screen (not double buffered) // Write messages to bottom screen (not double buffered)
bottom_console.select(); bottom_console.select();
@ -120,10 +118,8 @@ impl<'screen> CirclePadProDemo<'screen> {
self.top_console.select(); self.top_console.select();
self.top_console.clear(); self.top_console.clear();
println!("{:#x?}", self.ir_user.get_status_info()); println!("{:#x?}", self.ir_user.get_status_info());
self.top_console.with_screen(|screen| { self.top_console.flush_buffers();
screen.flush_buffers(); self.top_console.swap_buffers();
screen.swap_buffers();
});
self.bottom_console.select(); self.bottom_console.select();
} }
@ -238,10 +234,8 @@ impl<'screen> CirclePadProDemo<'screen> {
println!("\n{cpp_response:#02x?}"); println!("\n{cpp_response:#02x?}");
// Flush output and switch back to bottom screen // Flush output and switch back to bottom screen
self.top_console.with_screen(|screen| { self.top_console.flush_buffers();
screen.flush_buffers(); self.top_console.swap_buffers();
screen.swap_buffers();
});
self.bottom_console.select(); self.bottom_console.select();
// Done handling the packets, release them // Done handling the packets, release them

26
ctru-rs/src/console.rs

@ -10,7 +10,7 @@ use std::default::Default;
use ctru_sys::{consoleClear, consoleInit, consoleSelect, consoleSetWindow, PrintConsole}; use ctru_sys::{consoleClear, consoleInit, consoleSelect, consoleSetWindow, PrintConsole};
use crate::services::gfx::Screen; use crate::services::gfx::{Flush, Screen, Swap};
static mut EMPTY_CONSOLE: PrintConsole = unsafe { const_zero::const_zero!(PrintConsole) }; static mut EMPTY_CONSOLE: PrintConsole = unsafe { const_zero::const_zero!(PrintConsole) };
@ -329,6 +329,30 @@ impl<'screen, S: Screen> Console<'screen, S> {
} }
} }
impl<S: Screen + Swap> Swap for Console<'_, S> {
/// Swaps the video buffers. Note: The console's cursor position is not reset, only the framebuffer is changed.
///
/// Even if double buffering is disabled, "swapping" the buffers has the side effect
/// of committing any configuration changes to the buffers (e.g. [`TopScreen::set_wide_mode()`],
/// [`Screen::set_framebuffer_format()`], [`Swap::set_double_buffering()`]), so it should still be used.
///
/// This should be called once per frame at most.
fn swap_buffers(&mut self) {
self.screen.swap_buffers();
self.context.frameBuffer = self.screen.raw_framebuffer().ptr as *mut u16;
}
fn set_double_buffering(&mut self, enabled: bool) {
self.screen.set_double_buffering(enabled);
}
}
impl<S: Screen + Flush> Flush for Console<'_, S> {
fn flush_buffers(&mut self) {
self.screen.flush_buffers();
}
}
impl<S: Screen> Drop for Console<'_, S> { impl<S: Screen> Drop for Console<'_, S> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {

4
ctru-rs/src/services/gfx.rs

@ -13,7 +13,8 @@ use crate::services::gspgpu::{self, FramebufferFormat};
use crate::services::ServiceReference; use crate::services::ServiceReference;
mod private { mod private {
use super::{BottomScreen, TopScreen, TopScreen3D, TopScreenLeft, TopScreenRight}; use super::{BottomScreen, Screen, TopScreen, TopScreen3D, TopScreenLeft, TopScreenRight};
use crate::console::Console;
pub trait Sealed {} pub trait Sealed {}
@ -22,6 +23,7 @@ mod private {
impl Sealed for TopScreenLeft {} impl Sealed for TopScreenLeft {}
impl Sealed for TopScreenRight {} impl Sealed for TopScreenRight {}
impl Sealed for BottomScreen {} impl Sealed for BottomScreen {}
impl<S: Screen> Sealed for Console<'_, S> {}
} }
/// Trait to handle common functionality for all screens. /// Trait to handle common functionality for all screens.

Loading…
Cancel
Save