refactor and add doc strings to display

This commit is contained in:
Corwin Kuiper 2021-03-07 01:03:47 +00:00
parent 9527d32521
commit ac88468333
4 changed files with 51 additions and 19 deletions

View file

@ -42,3 +42,6 @@ out/crt0.o: crt0.s interrupt_simple.s
clippy:
rustup run nightly cargo xclippy --target=gba.json
doc:
rustup run nightly cargo xdoc --target=gba.json

View file

@ -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();

View file

@ -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();

View file

@ -15,7 +15,7 @@ const DISPLAY_STATUS: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0004
const VCOUNT: MemoryMapped<u16> = 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();
}