write docs for windows

This commit is contained in:
Corwin 2022-08-06 12:33:06 +01:00
parent 78ff4011c7
commit e1448f7d81

View file

@ -1,7 +1,11 @@
#![deny(missing_docs)]
use crate::{fixnum::Rect, memory_mapped::MemoryMapped}; use crate::{fixnum::Rect, memory_mapped::MemoryMapped};
use super::{tiled::BackgroundID, DISPLAY_CONTROL, HEIGHT, WIDTH}; use super::{tiled::BackgroundID, DISPLAY_CONTROL, HEIGHT, WIDTH};
/// The windows feature of the Game Boy Advance can selectively display
/// backgrounds or objects on the screen and can selectively enable and disable
/// effects. This gives out references and holds changes before they can be committed.
pub struct Windows { pub struct Windows {
wins: [MovableWindow; 2], wins: [MovableWindow; 2],
out: Window, out: Window,
@ -13,8 +17,11 @@ const REG_VERTICAL_BASE: *mut u16 = 0x0400_0044 as *mut _;
const REG_WINDOW_CONTROL_BASE: *mut u16 = 0x0400_0048 as *mut _; const REG_WINDOW_CONTROL_BASE: *mut u16 = 0x0400_0048 as *mut _;
/// The two Windows that have an effect inside of them
pub enum WinIn { pub enum WinIn {
/// The higher priority window
Win0, Win0,
/// The lower priority window
Win1, Win1,
} }
@ -29,21 +36,27 @@ impl Windows {
s s
} }
/// Returns a reference to the window that is used when outside all other windows
#[inline(always)] #[inline(always)]
pub fn win_out(&mut self) -> &mut Window { pub fn win_out(&mut self) -> &mut Window {
&mut self.out &mut self.out
} }
/// Gives a reference to the specified window that has effect when inside of it's boundary
#[inline(always)] #[inline(always)]
pub fn win_in(&mut self, id: WinIn) -> &mut MovableWindow { pub fn win_in(&mut self, id: WinIn) -> &mut MovableWindow {
&mut self.wins[id as usize] &mut self.wins[id as usize]
} }
/// Gives a reference to the window that is controlled by sprites and objects
#[inline(always)] #[inline(always)]
pub fn win_obj(&mut self) -> &mut Window { pub fn win_obj(&mut self) -> &mut Window {
&mut self.obj &mut self.obj
} }
/// Commits the state of the windows as dictated by the various functions to
/// modify them. This should be done during vblank shortly after the wait
/// for next vblank call.
pub fn commit(&self) { pub fn commit(&self) {
for (id, win) in self.wins.iter().enumerate() { for (id, win) in self.wins.iter().enumerate() {
win.commit(id); win.commit(id);
@ -58,10 +71,12 @@ impl Windows {
} }
} }
/// A non movable window
pub struct Window { pub struct Window {
window_bits: u8, window_bits: u8,
} }
/// A window that can be moved
pub struct MovableWindow { pub struct MovableWindow {
inner: Window, inner: Window,
rect: Rect<u8>, rect: Rect<u8>,
@ -72,6 +87,9 @@ impl Window {
Self { window_bits: 0 } Self { window_bits: 0 }
} }
/// Enables the window, must call [Windows::commit] for this change to be
/// seen. If a window is not enabled it will not have an effect on the
/// display.
#[inline(always)] #[inline(always)]
pub fn enable(&mut self) -> &mut Self { pub fn enable(&mut self) -> &mut Self {
self.set_bit(7, true); self.set_bit(7, true);
@ -79,6 +97,8 @@ impl Window {
self self
} }
/// Disables the window, must call [Windows::commit] for this change to be
/// seen.
#[inline(always)] #[inline(always)]
pub fn disable(&mut self) -> &mut Self { pub fn disable(&mut self) -> &mut Self {
self.set_bit(7, false); self.set_bit(7, false);
@ -95,24 +115,33 @@ impl Window {
self.window_bits |= (value as u8) << bit; self.window_bits |= (value as u8) << bit;
} }
/// Resets the window to it's default state, must call [Windows::commit] for
/// this change to be seen. The default state is the window disabled with
/// nothing rendered.
#[inline(always)] #[inline(always)]
pub fn reset(&mut self) -> &mut Self { pub fn reset(&mut self) -> &mut Self {
*self = Self::new(); *self = Self::new();
self self
} }
/// Sets whether the blend is enabled inside of this window, must call
/// [Windows::commit] for this change to be seen.
#[inline(always)] #[inline(always)]
pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self {
self.set_bit(5, blnd); self.set_bit(5, blnd);
self self
} }
/// Sets whether the given background will be rendered inside this window,
/// must call [Windows::commit] for this change to be seen.
#[inline(always)] #[inline(always)]
pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self {
self.set_bit(back.0 as usize, enable); self.set_bit(back.0 as usize, enable);
self self
} }
/// Sets whether objects will be rendered inside this window, must call
/// [Windows::commit] for this change to be seen.
#[inline(always)] #[inline(always)]
pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { pub fn set_object_enable(&mut self, obj: bool) -> &mut Self {
self.set_bit(4, obj); self.set_bit(4, obj);
@ -139,6 +168,9 @@ impl MovableWindow {
} }
} }
/// Enables the window, must call [Windows::commit] for this change to be
/// seen. If a window is not enabled it will not have an effect on the
/// display.
#[inline(always)] #[inline(always)]
pub fn enable(&mut self) -> &mut Self { pub fn enable(&mut self) -> &mut Self {
self.inner.enable(); self.inner.enable();
@ -146,6 +178,8 @@ impl MovableWindow {
self self
} }
/// Disables the window, must call [Windows::commit] for this change to be
/// seen.
#[inline(always)] #[inline(always)]
pub fn disable(&mut self) -> &mut Self { pub fn disable(&mut self) -> &mut Self {
self.inner.disable(); self.inner.disable();
@ -157,22 +191,31 @@ impl MovableWindow {
self.inner.is_enabled() self.inner.is_enabled()
} }
/// Resets the window to it's default state, must call [Windows::commit] for
/// this change to be seen. The default state is the window disabled with
/// nothing rendered and represents a 0x0 rectangle at (0, 0).
#[inline(always)] #[inline(always)]
pub fn reset(&mut self) -> &mut Self { pub fn reset(&mut self) -> &mut Self {
*self = Self::new(); *self = Self::new();
self self
} }
/// Sets whether the blend is enabled inside of this window, must call
/// [Windows::commit] for this change to be seen.
#[inline(always)] #[inline(always)]
pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self {
self.inner.set_blend_enable(blnd); self.inner.set_blend_enable(blnd);
self self
} }
/// Sets whether the given background will be rendered inside this window,
/// must call [Windows::commit] for this change to be seen.
#[inline(always)] #[inline(always)]
pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self {
self.inner.set_background_enable(back, enable); self.inner.set_background_enable(back, enable);
self self
} }
/// Sets whether objects will be rendered inside this window, must call
/// [Windows::commit] for this change to be seen.
#[inline(always)] #[inline(always)]
pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { pub fn set_object_enable(&mut self, obj: bool) -> &mut Self {
self.inner.set_object_enable(obj); self.inner.set_object_enable(obj);
@ -193,6 +236,9 @@ impl MovableWindow {
} }
} }
/// Sets the area of what is inside the window using [u8] representation,
/// which is closest to what the GBA uses. Most of the time [set_position]
/// should be used.
#[inline(always)] #[inline(always)]
pub fn set_position_u8(&mut self, rect: Rect<u8>) -> &mut Self { pub fn set_position_u8(&mut self, rect: Rect<u8>) -> &mut Self {
self.rect = rect; self.rect = rect;
@ -200,6 +246,7 @@ impl MovableWindow {
self self
} }
/// Sets the position of the area that is inside the window.
#[inline(always)] #[inline(always)]
pub fn set_position(&mut self, rect: &Rect<i32>) -> &mut Self { pub fn set_position(&mut self, rect: &Rect<i32>) -> &mut Self {
let new_rect = Rect::new( let new_rect = Rect::new(