From 10423d075233e7b7309ce2f5e6c7167d279d612f Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 21:41:48 +0100 Subject: [PATCH 01/13] background id exposed --- agb/src/display/tiled/infinite_scrolled_map.rs | 7 ++++++- agb/src/display/tiled/map.rs | 7 ++++++- agb/src/display/tiled/mod.rs | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/agb/src/display/tiled/infinite_scrolled_map.rs b/agb/src/display/tiled/infinite_scrolled_map.rs index decdd4db..4021494b 100644 --- a/agb/src/display/tiled/infinite_scrolled_map.rs +++ b/agb/src/display/tiled/infinite_scrolled_map.rs @@ -1,6 +1,6 @@ use alloc::boxed::Box; -use super::{MapLoan, RegularMap, TileSet, TileSetting, VRamManager}; +use super::{BackgroundID, MapLoan, RegularMap, TileSet, TileSetting, VRamManager}; use crate::{ display, @@ -414,6 +414,11 @@ impl<'a> InfiniteScrolledMap<'a> { pub fn clear(&mut self, vram: &mut VRamManager) { self.map.clear(vram); } + + #[must_use] + pub const fn background(&self) -> BackgroundID { + self.map.background() + } } fn div_floor(x: i32, y: i32) -> i32 { diff --git a/agb/src/display/tiled/map.rs b/agb/src/display/tiled/map.rs index c1519e4e..b245ab23 100644 --- a/agb/src/display/tiled/map.rs +++ b/agb/src/display/tiled/map.rs @@ -7,7 +7,7 @@ use crate::dma::dma_copy16; use crate::fixnum::Vector2D; use crate::memory_mapped::MemoryMapped; -use super::{RegularBackgroundSize, Tile, TileSet, TileSetting, VRamManager}; +use super::{BackgroundID, RegularBackgroundSize, Tile, TileSet, TileSetting, VRamManager}; use alloc::{vec, vec::Vec}; @@ -201,6 +201,11 @@ impl<'a, T> MapLoan<'a, T> { screenblock_list, } } + + #[must_use] + pub const fn background(&self) -> BackgroundID { + BackgroundID(self.background_id) + } } impl<'a, T> Drop for MapLoan<'a, T> { diff --git a/agb/src/display/tiled/mod.rs b/agb/src/display/tiled/mod.rs index 37e2f445..529b8681 100644 --- a/agb/src/display/tiled/mod.rs +++ b/agb/src/display/tiled/mod.rs @@ -17,6 +17,9 @@ pub enum RegularBackgroundSize { Background64x64, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BackgroundID(pub(crate) u8); + impl RegularBackgroundSize { #[must_use] pub fn width(&self) -> u32 { From a188e7ba6660e2ba5cc0642b55166f81415df5bc Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 21:41:58 +0100 Subject: [PATCH 02/13] add abstraction over windows --- agb-fixnum/src/lib.rs | 1 + agb/src/display/mod.rs | 15 +++- agb/src/display/window.rs | 152 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 agb/src/display/window.rs diff --git a/agb-fixnum/src/lib.rs b/agb-fixnum/src/lib.rs index b6bf46b4..d9a546f2 100644 --- a/agb-fixnum/src/lib.rs +++ b/agb-fixnum/src/lib.rs @@ -121,6 +121,7 @@ macro_rules! fixed_width_signed_integer_impl { }; } +fixed_width_unsigned_integer_impl!(u8); fixed_width_unsigned_integer_impl!(i16); fixed_width_unsigned_integer_impl!(u16); fixed_width_unsigned_integer_impl!(i32); diff --git a/agb/src/display/mod.rs b/agb/src/display/mod.rs index 11c4f7be..aef286cd 100644 --- a/agb/src/display/mod.rs +++ b/agb/src/display/mod.rs @@ -4,7 +4,7 @@ use bitflags::bitflags; use modular_bitfield::BitfieldSpecifier; use video::Video; -use self::object::ObjectController; +use self::{object::ObjectController, window::Windows}; /// Graphics mode 3. Bitmap mode that provides a 16-bit colour framebuffer. pub mod bitmap3; @@ -23,6 +23,8 @@ pub mod tiled; /// Giving out graphics mode. pub mod video; +pub mod window; + mod font; pub use font::{Font, FontLetter}; @@ -67,6 +69,7 @@ enum DisplayMode { pub struct Display { pub video: Video, pub object: ObjectDistribution, + pub window: WindowDist, } #[non_exhaustive] @@ -78,11 +81,21 @@ impl ObjectDistribution { } } +#[non_exhaustive] +pub struct WindowDist {} + +impl WindowDist { + pub fn get(&mut self) -> Windows { + Windows::new() + } +} + impl Display { pub(crate) const unsafe fn new() -> Self { Display { video: Video {}, object: ObjectDistribution {}, + window: WindowDist {}, } } } diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs new file mode 100644 index 00000000..d7ad1b10 --- /dev/null +++ b/agb/src/display/window.rs @@ -0,0 +1,152 @@ +use agb_fixnum::Rect; + +use crate::memory_mapped::MemoryMapped; + +use super::tiled::BackgroundID; + +pub struct Windows { + wins: [MovableWindow; 2], + out: Window, + obj: Window, +} + +const REG_HORIZONTAL_BASE: *mut u16 = 0x0400_0040 as *mut _; +const REG_VERTICAL_BASE: *mut u16 = 0x0400_0044 as *mut _; + +const REG_WINDOW_CONTROL_BASE: *mut u16 = 0x0400_0048 as *mut _; + +pub enum WinIn { + Win0, + Win1, +} + +impl Windows { + pub(crate) fn new() -> Self { + let s = Self { + wins: [MovableWindow::new(), MovableWindow::new()], + out: Window::new(), + obj: Window::new(), + }; + s.commit(); + s + } + + pub fn enable(&self) {} + + pub fn disable(&self) {} + + pub fn win_out(&mut self) -> &mut Window { + &mut self.out + } + + pub fn win_in(&mut self, id: WinIn) -> &mut MovableWindow { + &mut self.wins[id as usize] + } + + pub fn win_obj(&mut self) -> &mut Window { + &mut self.obj + } + + pub fn commit(&self) { + for (id, win) in self.wins.iter().enumerate() { + win.commit(id); + } + self.obj.commit(3); + self.out.commit(2); + } +} + +pub struct Window { + window_bits: u8, +} + +pub struct MovableWindow { + inner: Window, + rect: Rect, +} + +impl Window { + fn new() -> Window { + Self { window_bits: 0 } + } + + fn set_bit(&mut self, bit: usize, value: bool) { + self.window_bits &= u8::MAX ^ (1 << bit); + self.window_bits |= (value as u8) << bit; + } + pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { + self.set_bit(5, blnd); + + self + } + pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { + self.set_bit(back.0 as usize, enable); + + self + } + pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { + self.set_bit(4, obj); + + self + } + + fn commit(&self, id: usize) { + let base_reg = id / 2; + let offset_in_reg = (id % 2) * 8; + + unsafe { + let reg = MemoryMapped::new(REG_WINDOW_CONTROL_BASE.add(base_reg) as usize); + reg.set_bits(self.window_bits as u16, 8, offset_in_reg as u16); + } + } +} + +impl MovableWindow { + fn new() -> Self { + Self { + inner: Window::new(), + rect: Rect::new((0, 0).into(), (0, 0).into()), + } + } + + pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { + self.inner.set_blend_enable(blnd); + self + } + pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { + self.inner.set_background_enable(back, enable); + self + } + pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { + self.inner.set_object_enable(obj); + self + } + + fn commit(&self, id: usize) { + self.inner.commit(id); + + let left_right = + (self.rect.position.x as u16) << 8 | (self.rect.position.x + self.rect.size.x) as u16; + + let top_bottom = + (self.rect.position.y as u16) << 8 | (self.rect.position.y + self.rect.size.y) as u16; + unsafe { + REG_HORIZONTAL_BASE.add(id).write_volatile(left_right); + REG_VERTICAL_BASE.add(id).write_volatile(top_bottom); + } + } + + pub fn set_position_byte(&mut self, rect: Rect) -> &mut Self { + self.rect = rect; + + self + } + + pub fn set_position(&mut self, rect: &Rect) -> &mut Self { + let new_rect = Rect::new( + (rect.position.x as u8, rect.position.y as u8).into(), + (rect.size.x as u8, rect.size.y as u8).into(), + ); + self.set_position_byte(new_rect) + } +} From 7735baecc92aa72ae913617f3740058756952473 Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 21:47:52 +0100 Subject: [PATCH 03/13] use a more sensible ordering of numbers --- agb/src/display/window.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index d7ad1b10..b83d860e 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -51,8 +51,8 @@ impl Windows { for (id, win) in self.wins.iter().enumerate() { win.commit(id); } - self.obj.commit(3); self.out.commit(2); + self.obj.commit(3); } } From 44fd7d0027bfdaa4e98c54368b11aedaa5f74d87 Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 21:48:14 +0100 Subject: [PATCH 04/13] use a name matching rust conventions --- agb/src/display/window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index b83d860e..a4ccb7cb 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -136,7 +136,7 @@ impl MovableWindow { } } - pub fn set_position_byte(&mut self, rect: Rect) -> &mut Self { + pub fn set_position_u8(&mut self, rect: Rect) -> &mut Self { self.rect = rect; self @@ -147,6 +147,6 @@ impl MovableWindow { (rect.position.x as u8, rect.position.y as u8).into(), (rect.size.x as u8, rect.size.y as u8).into(), ); - self.set_position_byte(new_rect) + self.set_position_u8(new_rect) } } From f9d9220eadb5358ccd5c770876e2cfaf6b698a1d Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 21:49:21 +0100 Subject: [PATCH 05/13] function to reset the window --- agb/src/display/window.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index a4ccb7cb..0a218733 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -74,6 +74,12 @@ impl Window { self.window_bits &= u8::MAX ^ (1 << bit); self.window_bits |= (value as u8) << bit; } + + pub fn reset(&mut self) -> &mut Self { + *self = Self::new(); + + self + } pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { self.set_bit(5, blnd); @@ -109,6 +115,11 @@ impl MovableWindow { } } + pub fn reset(&mut self) -> &mut Self { + *self = Self::new(); + + self + } pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { self.inner.set_blend_enable(blnd); self From 648ce375d56271976af15aa0e99260cbd61e448d Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 21:55:05 +0100 Subject: [PATCH 06/13] enabling and disabling windows --- agb/src/display/window.rs | 43 ++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index 0a218733..87a5ffe7 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -2,7 +2,7 @@ use agb_fixnum::Rect; use crate::memory_mapped::MemoryMapped; -use super::tiled::BackgroundID; +use super::{tiled::BackgroundID, DISPLAY_CONTROL}; pub struct Windows { wins: [MovableWindow; 2], @@ -31,10 +31,6 @@ impl Windows { s } - pub fn enable(&self) {} - - pub fn disable(&self) {} - pub fn win_out(&mut self) -> &mut Window { &mut self.out } @@ -53,6 +49,11 @@ impl Windows { } self.out.commit(2); self.obj.commit(3); + + let enabled_bits = ((self.obj.is_enabled() as u16) << 2) + | ((self.wins[1].is_enabled() as u16) << 1) + | (self.wins[0].is_enabled() as u16); + DISPLAY_CONTROL.set_bits(enabled_bits, 3, 0xD); } } @@ -70,6 +71,22 @@ impl Window { Self { window_bits: 0 } } + pub fn enable(&mut self) -> &mut Self { + self.set_bit(7, true); + + self + } + + pub fn disable(&mut self) -> &mut Self { + self.set_bit(7, false); + + self + } + + fn is_enabled(&self) -> bool { + (self.window_bits >> 7) != 0 + } + fn set_bit(&mut self, bit: usize, value: bool) { self.window_bits &= u8::MAX ^ (1 << bit); self.window_bits |= (value as u8) << bit; @@ -115,6 +132,22 @@ impl MovableWindow { } } + pub fn enable(&mut self) -> &mut Self { + self.inner.enable(); + + self + } + + pub fn disable(&mut self) -> &mut Self { + self.inner.disable(); + + self + } + + fn is_enabled(&self) -> bool { + self.inner.is_enabled() + } + pub fn reset(&mut self) -> &mut Self { *self = Self::new(); From 2b4a95a4a981e3ae0054a0f8d36d6222f11f823b Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 01:03:51 +0100 Subject: [PATCH 07/13] clamp the position before converting to u8 --- agb/src/display/window.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index 87a5ffe7..92c5ef7e 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -2,7 +2,7 @@ use agb_fixnum::Rect; use crate::memory_mapped::MemoryMapped; -use super::{tiled::BackgroundID, DISPLAY_CONTROL}; +use super::{tiled::BackgroundID, DISPLAY_CONTROL, HEIGHT, WIDTH}; pub struct Windows { wins: [MovableWindow; 2], @@ -188,7 +188,11 @@ impl MovableWindow { pub fn set_position(&mut self, rect: &Rect) -> &mut Self { let new_rect = Rect::new( - (rect.position.x as u8, rect.position.y as u8).into(), + ( + rect.position.x.clamp(0, WIDTH) as u8, + rect.position.y.clamp(0, HEIGHT) as u8, + ) + .into(), (rect.size.x as u8, rect.size.y as u8).into(), ); self.set_position_u8(new_rect) From e31889819756abb7260f068b4f1792ecd61df90f Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 01:09:36 +0100 Subject: [PATCH 08/13] add example for window --- agb/examples/windows.rs | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 agb/examples/windows.rs diff --git a/agb/examples/windows.rs b/agb/examples/windows.rs new file mode 100644 index 00000000..ce4ee278 --- /dev/null +++ b/agb/examples/windows.rs @@ -0,0 +1,55 @@ +#![no_std] +#![no_main] + +use agb::display::{example_logo, tiled::RegularBackgroundSize, window::WinIn}; +use agb::display::{HEIGHT, WIDTH}; +use agb::fixnum::{Num, Rect, Vector2D}; +use agb::interrupt::VBlank; + +type FNum = Num; + +#[agb::entry] +fn entry(mut gba: agb::Gba) -> ! { + main(gba) +} + +fn main(mut gba: agb::Gba) -> ! { + let (gfx, mut vram) = gba.display.video.tiled0(); + + let mut map = gfx.background( + agb::display::Priority::P0, + RegularBackgroundSize::Background32x32, + ); + let mut window = gba.display.window.get(); + window + .win_in(WinIn::Win0) + .set_background_enable(map.background(), true) + .set_position(&Rect::new((10, 10).into(), (64, 64).into())) + .enable(); + + example_logo::display_logo(&mut map, &mut vram); + + let mut pos: Vector2D = (10, 10).into(); + let mut velocity: Vector2D = Vector2D::new(1.into(), 1.into()); + + let vblank = VBlank::get(); + + loop { + pos += velocity; + + if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 { + velocity.x *= -1; + } + + if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 { + velocity.y *= -1; + } + + window + .win_in(WinIn::Win0) + .set_position(&Rect::new(pos.floor(), (64, 64).into())); + + vblank.wait_for_vblank(); + window.commit(); + } +} From dbbd7a3d34a9582b2c04dff3f71fd9477b7488ee Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 01:33:03 +0100 Subject: [PATCH 09/13] add some inlines to small functions --- agb/src/display/window.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index 92c5ef7e..ef264d14 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -31,14 +31,17 @@ impl Windows { s } + #[inline(always)] pub fn win_out(&mut self) -> &mut Window { &mut self.out } + #[inline(always)] pub fn win_in(&mut self, id: WinIn) -> &mut MovableWindow { &mut self.wins[id as usize] } + #[inline(always)] pub fn win_obj(&mut self) -> &mut Window { &mut self.obj } @@ -71,12 +74,14 @@ impl Window { Self { window_bits: 0 } } + #[inline(always)] pub fn enable(&mut self) -> &mut Self { self.set_bit(7, true); self } + #[inline(always)] pub fn disable(&mut self) -> &mut Self { self.set_bit(7, false); @@ -92,21 +97,25 @@ impl Window { self.window_bits |= (value as u8) << bit; } + #[inline(always)] pub fn reset(&mut self) -> &mut Self { *self = Self::new(); self } + #[inline(always)] pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { self.set_bit(5, blnd); self } + #[inline(always)] pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { self.set_bit(back.0 as usize, enable); self } + #[inline(always)] pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { self.set_bit(4, obj); @@ -132,12 +141,14 @@ impl MovableWindow { } } + #[inline(always)] pub fn enable(&mut self) -> &mut Self { self.inner.enable(); self } + #[inline(always)] pub fn disable(&mut self) -> &mut Self { self.inner.disable(); @@ -148,19 +159,23 @@ impl MovableWindow { self.inner.is_enabled() } + #[inline(always)] pub fn reset(&mut self) -> &mut Self { *self = Self::new(); self } + #[inline(always)] pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { self.inner.set_blend_enable(blnd); self } + #[inline(always)] pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { self.inner.set_background_enable(back, enable); self } + #[inline(always)] pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { self.inner.set_object_enable(obj); self @@ -180,12 +195,14 @@ impl MovableWindow { } } + #[inline(always)] pub fn set_position_u8(&mut self, rect: Rect) -> &mut Self { self.rect = rect; self } + #[inline(always)] pub fn set_position(&mut self, rect: &Rect) -> &mut Self { let new_rect = Rect::new( ( From 78ff4011c762553ee54b8fc0b309ec7c9b039cd3 Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 12:20:13 +0100 Subject: [PATCH 10/13] merge imports --- agb/src/display/window.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index ef264d14..3f537c02 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -1,6 +1,4 @@ -use agb_fixnum::Rect; - -use crate::memory_mapped::MemoryMapped; +use crate::{fixnum::Rect, memory_mapped::MemoryMapped}; use super::{tiled::BackgroundID, DISPLAY_CONTROL, HEIGHT, WIDTH}; From e1448f7d81a8ea7957780f9926c6c87c3d14a06a Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 12:33:06 +0100 Subject: [PATCH 11/13] write docs for windows --- agb/src/display/window.rs | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index 3f537c02..d10f41cd 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -1,7 +1,11 @@ +#![deny(missing_docs)] use crate::{fixnum::Rect, memory_mapped::MemoryMapped}; 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 { wins: [MovableWindow; 2], 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 _; +/// The two Windows that have an effect inside of them pub enum WinIn { + /// The higher priority window Win0, + /// The lower priority window Win1, } @@ -29,21 +36,27 @@ impl Windows { s } + /// Returns a reference to the window that is used when outside all other windows #[inline(always)] pub fn win_out(&mut self) -> &mut Window { &mut self.out } + /// Gives a reference to the specified window that has effect when inside of it's boundary #[inline(always)] pub fn win_in(&mut self, id: WinIn) -> &mut MovableWindow { &mut self.wins[id as usize] } + /// Gives a reference to the window that is controlled by sprites and objects #[inline(always)] pub fn win_obj(&mut self) -> &mut Window { &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) { for (id, win) in self.wins.iter().enumerate() { win.commit(id); @@ -58,10 +71,12 @@ impl Windows { } } +/// A non movable window pub struct Window { window_bits: u8, } +/// A window that can be moved pub struct MovableWindow { inner: Window, rect: Rect, @@ -72,6 +87,9 @@ impl Window { 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)] pub fn enable(&mut self) -> &mut Self { self.set_bit(7, true); @@ -79,6 +97,8 @@ impl Window { self } + /// Disables the window, must call [Windows::commit] for this change to be + /// seen. #[inline(always)] pub fn disable(&mut self) -> &mut Self { self.set_bit(7, false); @@ -95,24 +115,33 @@ impl Window { 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)] pub fn reset(&mut self) -> &mut Self { *self = Self::new(); self } + /// Sets whether the blend is enabled inside of this window, must call + /// [Windows::commit] for this change to be seen. #[inline(always)] pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { self.set_bit(5, blnd); self } + /// Sets whether the given background will be rendered inside this window, + /// must call [Windows::commit] for this change to be seen. #[inline(always)] pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { self.set_bit(back.0 as usize, enable); self } + /// Sets whether objects will be rendered inside this window, must call + /// [Windows::commit] for this change to be seen. #[inline(always)] pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { 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)] pub fn enable(&mut self) -> &mut Self { self.inner.enable(); @@ -146,6 +178,8 @@ impl MovableWindow { self } + /// Disables the window, must call [Windows::commit] for this change to be + /// seen. #[inline(always)] pub fn disable(&mut self) -> &mut Self { self.inner.disable(); @@ -157,22 +191,31 @@ impl MovableWindow { 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)] pub fn reset(&mut self) -> &mut Self { *self = Self::new(); self } + /// Sets whether the blend is enabled inside of this window, must call + /// [Windows::commit] for this change to be seen. #[inline(always)] pub fn set_blend_enable(&mut self, blnd: bool) -> &mut Self { self.inner.set_blend_enable(blnd); self } + /// Sets whether the given background will be rendered inside this window, + /// must call [Windows::commit] for this change to be seen. #[inline(always)] pub fn set_background_enable(&mut self, back: BackgroundID, enable: bool) -> &mut Self { self.inner.set_background_enable(back, enable); self } + /// Sets whether objects will be rendered inside this window, must call + /// [Windows::commit] for this change to be seen. #[inline(always)] pub fn set_object_enable(&mut self, obj: bool) -> &mut Self { 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)] pub fn set_position_u8(&mut self, rect: Rect) -> &mut Self { self.rect = rect; @@ -200,6 +246,7 @@ impl MovableWindow { self } + /// Sets the position of the area that is inside the window. #[inline(always)] pub fn set_position(&mut self, rect: &Rect) -> &mut Self { let new_rect = Rect::new( From fc94f833f78c88534a9d769b988909aa43f000c5 Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 12:35:55 +0100 Subject: [PATCH 12/13] update changelog with windows --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef9e18b..9f51e456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Custom allocator support using the `Allocator` trait for `HashMap`. This means the `HashMap` can be used with `InternalAllocator` to allocate to IWRAM or the `ExternalAllocator` to explicitly allocate to EWRAM. +- Support for using windows on the GBA. Windows are used to selectively enable rendering of certain layers or effects. ## [0.11.1] - 2022/08/02 From 12d4a8cd81cb7031a2a6ea6e02a0bc22827ed2a4 Mon Sep 17 00:00:00 2001 From: Corwin Date: Sat, 6 Aug 2022 12:51:59 +0100 Subject: [PATCH 13/13] add module level docs --- agb/src/display/window.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/agb/src/display/window.rs b/agb/src/display/window.rs index d10f41cd..50d89b8b 100644 --- a/agb/src/display/window.rs +++ b/agb/src/display/window.rs @@ -1,4 +1,5 @@ #![deny(missing_docs)] +//! The window feature of the GBA. use crate::{fixnum::Rect, memory_mapped::MemoryMapped}; use super::{tiled::BackgroundID, DISPLAY_CONTROL, HEIGHT, WIDTH};