From 1f45da1ebc5f9f3fea994046e97fd284621de6a6 Mon Sep 17 00:00:00 2001 From: AzureMarker Date: Sun, 24 Dec 2023 13:42:29 -0500 Subject: [PATCH] Fix double buffering in example via impl Swap and Flush for Console --- ctru-rs/examples/ir-user-circle-pad-pro.rs | 18 +++++---------- ctru-rs/src/console.rs | 26 +++++++++++++++++++++- ctru-rs/src/services/gfx.rs | 4 +++- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/ctru-rs/examples/ir-user-circle-pad-pro.rs b/ctru-rs/examples/ir-user-circle-pad-pro.rs index acd4b1d..10fa58d 100644 --- a/ctru-rs/examples/ir-user-circle-pad-pro.rs +++ b/ctru-rs/examples/ir-user-circle-pad-pro.rs @@ -80,10 +80,8 @@ impl<'screen> CirclePadProDemo<'screen> { bottom_console: Console<'screen, BottomScreen>, ) -> Self { // Set up double buffering on top screen - top_console.with_screen(|screen| { - screen.set_double_buffering(true); - screen.swap_buffers(); - }); + top_console.set_double_buffering(true); + top_console.swap_buffers(); // Write messages to bottom screen (not double buffered) bottom_console.select(); @@ -120,10 +118,8 @@ impl<'screen> CirclePadProDemo<'screen> { self.top_console.select(); self.top_console.clear(); println!("{:#x?}", self.ir_user.get_status_info()); - self.top_console.with_screen(|screen| { - screen.flush_buffers(); - screen.swap_buffers(); - }); + self.top_console.flush_buffers(); + self.top_console.swap_buffers(); self.bottom_console.select(); } @@ -238,10 +234,8 @@ impl<'screen> CirclePadProDemo<'screen> { println!("\n{cpp_response:#02x?}"); // Flush output and switch back to bottom screen - self.top_console.with_screen(|screen| { - screen.flush_buffers(); - screen.swap_buffers(); - }); + self.top_console.flush_buffers(); + self.top_console.swap_buffers(); self.bottom_console.select(); // Done handling the packets, release them diff --git a/ctru-rs/src/console.rs b/ctru-rs/src/console.rs index 452c785..322072e 100644 --- a/ctru-rs/src/console.rs +++ b/ctru-rs/src/console.rs @@ -10,7 +10,7 @@ use std::default::Default; 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) }; @@ -329,6 +329,30 @@ impl<'screen, S: Screen> Console<'screen, S> { } } +impl 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 Flush for Console<'_, S> { + fn flush_buffers(&mut self) { + self.screen.flush_buffers(); + } +} + impl Drop for Console<'_, S> { fn drop(&mut self) { unsafe { diff --git a/ctru-rs/src/services/gfx.rs b/ctru-rs/src/services/gfx.rs index 6eb04f6..2420842 100644 --- a/ctru-rs/src/services/gfx.rs +++ b/ctru-rs/src/services/gfx.rs @@ -13,7 +13,8 @@ use crate::services::gspgpu::{self, FramebufferFormat}; use crate::services::ServiceReference; mod private { - use super::{BottomScreen, TopScreen, TopScreen3D, TopScreenLeft, TopScreenRight}; + use super::{BottomScreen, Screen, TopScreen, TopScreen3D, TopScreenLeft, TopScreenRight}; + use crate::console::Console; pub trait Sealed {} @@ -22,6 +23,7 @@ mod private { impl Sealed for TopScreenLeft {} impl Sealed for TopScreenRight {} impl Sealed for BottomScreen {} + impl Sealed for Console<'_, S> {} } /// Trait to handle common functionality for all screens.