From ac884683331fbb16b12c963738c19ff43d2e6eb1 Mon Sep 17 00:00:00 2001 From: Corwin Kuiper Date: Sun, 7 Mar 2021 01:03:47 +0000 Subject: [PATCH] refactor and add doc strings to display --- Makefile | 5 ++++- src/display/bitmap3.rs | 5 ++++- src/display/bitmap4.rs | 16 ++++++++++++--- src/display/mod.rs | 44 ++++++++++++++++++++++++++++-------------- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 8677bbd0..fc104f84 100644 --- a/Makefile +++ b/Makefile @@ -41,4 +41,7 @@ out/crt0.o: crt0.s interrupt_simple.s @$(CC) $(ARCH) -o out/crt0.o crt0.s clippy: - rustup run nightly cargo xclippy --target=gba.json \ No newline at end of file + rustup run nightly cargo xclippy --target=gba.json + +doc: + rustup run nightly cargo xdoc --target=gba.json \ No newline at end of file diff --git a/src/display/bitmap3.rs b/src/display/bitmap3.rs index b72b60a9..e36b990b 100644 --- a/src/display/bitmap3.rs +++ b/src/display/bitmap3.rs @@ -14,11 +14,14 @@ pub struct Bitmap3<'a> { } impl<'a> Bitmap3<'a> { - pub(crate) fn new(in_mode: SingleToken<'a>) -> Self { + pub(crate) unsafe fn new(in_mode: SingleToken<'a>) -> Self { set_graphics_mode(DisplayMode::Bitmap3); set_graphics_settings(GraphicsSettings::LAYER_BG2); Bitmap3 { _in_mode: in_mode } } + + /// Draws point to screen at (x, y) coordinates with colour and panics if + /// (x, y) is out of the bounds of the screen. pub fn draw_point(&self, x: i32, y: i32, colour: u16) { let x = x.try_into().unwrap(); let y = y.try_into().unwrap(); diff --git a/src/display/bitmap4.rs b/src/display/bitmap4.rs index 90a01740..8af475a4 100644 --- a/src/display/bitmap4.rs +++ b/src/display/bitmap4.rs @@ -31,12 +31,15 @@ pub struct Bitmap4<'a> { } impl<'a> Bitmap4<'a> { - pub(crate) fn new(in_mode: SingleToken<'a>) -> Self { + pub(crate) unsafe fn new(in_mode: SingleToken<'a>) -> Self { set_graphics_mode(DisplayMode::Bitmap4); set_graphics_settings(GraphicsSettings::LAYER_BG2); Bitmap4 { _in_mode: in_mode } } + /// Draws point on specified page at (x, y) coordinates with colour index + /// whose colour is specified in the background palette. Panics if (x, y) is + /// out of the bounds of the screen. pub fn draw_point_page(&self, x: i32, y: i32, colour: u8, page: Page) { let addr = match page { Page::Front => BITMAP_PAGE_FRONT_MODE_4, @@ -54,22 +57,29 @@ impl<'a> Bitmap4<'a> { } } + /// Draws point on the non-current page at (x, y) coordinates with colour + /// index whose colour is specified in the background palette. Panics if (x, + /// y) is out of the bounds of the screen. pub fn draw_point(&self, x: i32, y: i32, colour: u8) { let disp = DISPLAY_CONTROL.get(); + // get other page let page = if disp & GraphicsSettings::PAGE_SELECT.bits() != 0 { - Page::Back - } else { Page::Front + } else { + Page::Back }; self.draw_point_page(x, y, colour, page) } + /// Sets the colour of colour index in the background palette. pub fn set_palette_entry(&self, entry: u32, colour: u16) { PALETTE_BACKGROUND.set(entry as usize, colour); } + /// Flips page, changing the Gameboy advance to draw the contents of the + /// other page pub fn flip_page(&self) { let disp = DISPLAY_CONTROL.get(); let swapped = disp ^ GraphicsSettings::PAGE_SELECT.bits(); diff --git a/src/display/mod.rs b/src/display/mod.rs index 3901074f..b2cf83da 100644 --- a/src/display/mod.rs +++ b/src/display/mod.rs @@ -15,7 +15,7 @@ const DISPLAY_STATUS: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0004 const VCOUNT: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0006) }; bitflags! { - pub struct GraphicsSettings: u16 { + struct GraphicsSettings: u16 { const PAGE_SELECT = 1 << 0x4; const OAM_HBLANK = 1 << 0x5; const SPRITE1_D = 1 << 0x6; @@ -31,10 +31,12 @@ bitflags! { } } +/// Width of the Gameboy advance screen in pixels pub const WIDTH: i32 = 240; +/// Height of the Gameboy advance screen in pixels pub const HEIGHT: i32 = 160; -pub enum DisplayMode { +enum DisplayMode { Tiled0 = 0, Tiled1 = 1, Tiled2 = 2, @@ -43,6 +45,7 @@ pub enum DisplayMode { Bitmap5 = 5, } +/// Manages distribution of display modes, obtained from the gba struct pub struct Display { in_mode: Single, vblank: Single, @@ -56,20 +59,29 @@ impl Display { } } + /// Bitmap mode that provides a 16-bit colour framebuffer pub fn bitmap3(&self) -> Bitmap3 { - Bitmap3::new( - self.in_mode - .take() - .expect("Cannot create new mode as mode already taken"), - ) + unsafe { + Bitmap3::new( + self.in_mode + .take() + .expect("Cannot create new mode as mode already taken"), + ) + } } + + /// Bitmap 4 provides two 8-bit paletted framebuffers with page switching pub fn bitmap4(&self) -> Bitmap4 { - bitmap4::Bitmap4::new( - self.in_mode - .take() - .expect("Cannot create new mode as mode already taken"), - ) + unsafe { + bitmap4::Bitmap4::new( + self.in_mode + .take() + .expect("Cannot create new mode as mode already taken"), + ) + } } + + /// Gets a vblank handle where only one can be obtained at a time pub fn get_vblank(&self) -> VBlank { unsafe { VBlank::new( @@ -81,7 +93,7 @@ impl Display { } } -fn set_graphics_mode(mode: DisplayMode) { +unsafe fn set_graphics_mode(mode: DisplayMode) { let current = DISPLAY_CONTROL.get(); let current = current & (!0b111); let s = current | (mode as u16 & 0b111); @@ -89,7 +101,7 @@ fn set_graphics_mode(mode: DisplayMode) { DISPLAY_CONTROL.set(s); } -pub fn set_graphics_settings(settings: GraphicsSettings) { +unsafe fn set_graphics_settings(settings: GraphicsSettings) { let current = DISPLAY_CONTROL.get(); // preserve display mode let current = current & 0b111; @@ -107,6 +119,8 @@ pub fn busy_wait_for_VBlank() { while VCOUNT.get() < 160 {} } +/// Once obtained, this guarentees that interrupts are enabled and set up to +/// allow for waiting for vblank pub struct VBlank<'a> { _got: SingleToken<'a>, } @@ -120,6 +134,8 @@ impl<'a> VBlank<'a> { } #[allow(non_snake_case)] + /// Waits for VBlank using interrupts. This is the preferred method for + /// waiting until the next frame. pub fn wait_for_VBlank(&self) { crate::syscall::wait_for_VBlank(); }