Skip to content

Commit

Permalink
Fix double buffering in example via impl Swap and Flush for Console
Browse files Browse the repository at this point in the history
  • Loading branch information
AzureMarker committed Dec 24, 2023
1 parent ef1c913 commit 1f45da1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
18 changes: 6 additions & 12 deletions ctru-rs/examples/ir-user-circle-pad-pro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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
Expand Down
26 changes: 25 additions & 1 deletion ctru-rs/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) };

Expand Down Expand Up @@ -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> {
fn drop(&mut self) {
unsafe {
Expand Down
4 changes: 3 additions & 1 deletion ctru-rs/src/services/gfx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

Expand All @@ -22,6 +23,7 @@ mod private {
impl Sealed for TopScreenLeft {}
impl Sealed for TopScreenRight {}
impl Sealed for BottomScreen {}
impl<S: Screen> Sealed for Console<'_, S> {}
}

/// Trait to handle common functionality for all screens.
Expand Down

0 comments on commit 1f45da1

Please sign in to comment.