From bc1bf3416c891c2c6b31b26cf44e6169db826641 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 4 Jun 2022 13:52:58 +0100 Subject: [PATCH 1/3] Add some doc comments around the video struct --- agb/src/display/video.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/agb/src/display/video.rs b/agb/src/display/video.rs index 57ae60e3..6367eff0 100644 --- a/agb/src/display/video.rs +++ b/agb/src/display/video.rs @@ -4,6 +4,10 @@ use super::{ tiled::{Tiled0, VRamManager}, }; +/// The video struct controls access to the video hardware. +/// It ensures that only one video mode is active at a time. +/// +/// Most games will use tiled modes, as bitmap modes are too slow to run at the full 60 FPS. #[non_exhaustive] pub struct Video {} @@ -18,6 +22,7 @@ impl Video { unsafe { Bitmap4::new() } } + /// Tiled 0 mode provides 4 regular, tiled backgrounds pub fn tiled0(&mut self) -> (Tiled0, VRamManager) { (unsafe { Tiled0::new() }, VRamManager::new()) } From de965e966f733aa309587c4705244aa8872a38ec Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 4 Jun 2022 14:10:54 +0100 Subject: [PATCH 2/3] Write some doc comments for InfiniteScrolledMap --- .../display/tiled/infinite_scrolled_map.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/agb/src/display/tiled/infinite_scrolled_map.rs b/agb/src/display/tiled/infinite_scrolled_map.rs index 98c2d6e8..ade89a4d 100644 --- a/agb/src/display/tiled/infinite_scrolled_map.rs +++ b/agb/src/display/tiled/infinite_scrolled_map.rs @@ -7,6 +7,40 @@ use crate::{ fixnum::{Rect, Vector2D}, }; +/// The infinite scrolled map allows you to create a game space larger than a single GBA background. +/// The abstraction allows only for static tiles, but it is possible to animate the tiles if needed. +/// +/// When you create a new infinite scrolled map, you need to provide a background which it will render itself +/// onto and a function which takes a Vector2D position and returns which tile should be rendered there. +/// +/// The passed function should handle being out of bounds, as the scrolled map does buffer around the edges slightly. +/// +/// Note that nothing is copied to video memory until you call [`.commit()`](`InfiniteScrolledMap::commit`), and you +/// must call [`.clear()`](`InfiniteScrolledMap::clear`) before dropping the infinite scrolled map or you will leak video RAM. +/// +/// # Example +/// +/// ``` +/// let backdrop = InfiniteScrolledMap::new( +/// background.background(Priority::P2, RegularBackgroundSize::Background32x32), +/// Box::new(|pos| { +/// ( +/// &tileset, +/// TileSetting::from_raw( +/// *tilemap::BACKGROUND_MAP +/// .get((pos.x + tilemap::WIDTH * pos.y) as usize) +/// .unwrap_or(&0), +/// ), +/// ) +/// }), +/// ); +/// +/// // ... +/// +/// backdrop.set_pos(&mut vram, (3, 5).into()); +/// backdrop.commit(&mut vram); +/// backdrop.show(); +/// ``` pub struct InfiniteScrolledMap<'a> { map: MapLoan<'a, RegularMap>, tile: Box) -> (&'a TileSet<'a>, TileSetting) + 'a>, @@ -24,6 +58,12 @@ pub enum PartialUpdateStatus { } impl<'a> InfiniteScrolledMap<'a> { + /// Creates a new infinite scrolled map wrapping the provided background using the given function to + /// position tiles. + /// + /// This will not actually render anything until either [`.init()`](`InfiniteScrolledMap::init`) or + /// [`.init_partial()`](`InfiniteScrolledMap::init_partial`) is called to set up VRam and this is then + /// [`committed`](`InfiniteScrolledMap::commit`). #[must_use] pub fn new( map: MapLoan<'a, RegularMap>, From efeaeeac4d6585170f6f15c105a142f3d0751da5 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Thu, 16 Jun 2022 22:42:16 +0100 Subject: [PATCH 3/3] Finish off the comments in InfiniteScrolledMap --- .../display/tiled/infinite_scrolled_map.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/agb/src/display/tiled/infinite_scrolled_map.rs b/agb/src/display/tiled/infinite_scrolled_map.rs index ade89a4d..97dafea1 100644 --- a/agb/src/display/tiled/infinite_scrolled_map.rs +++ b/agb/src/display/tiled/infinite_scrolled_map.rs @@ -78,6 +78,17 @@ impl<'a> InfiniteScrolledMap<'a> { } } + /// Initialises the map and fills it, calling the between_updates occasionally to allow you to ensure that + /// music keeps playing without interruption. + /// + /// # Example + /// + /// ``` + /// background.init(&mut vram, start_position, || { + /// vblank.wait_for_vblank(); + /// mixer.frame(); + /// }); + /// ``` pub fn init( &mut self, vram: &mut VRamManager, @@ -89,6 +100,23 @@ impl<'a> InfiniteScrolledMap<'a> { } } + /// Does a partial initialisation of the background, rendering 2 rows. + /// This is because initialisation can take quite a while, so you will need to call + /// this method a few times to ensure that you update the entire frame. + /// + /// Returns [`PartialUpdateStatus::Done`] if complete, and [`PartialUpdateStatus::Continue`] + /// if you need to call this a few more times to fully update the screen. + /// + /// It is recommended you use [`.init()`](`InfiniteScrolledMap::init`) instead of this method + /// + /// # Example + /// + /// ``` + /// while background.init_partial(&mut vram, start_position) == PartialUpdateStatus::Continue { + /// vblank.wait_for_vblank(); + /// mixer.frame(); + /// } + /// ``` pub fn init_partial( &mut self, vram: &mut VRamManager, @@ -140,6 +168,8 @@ impl<'a> InfiniteScrolledMap<'a> { } } + /// Set the top left corner of the map. You may need to call this method multiple times if + /// [`PartialUpdateStatus::Continue`] is returned. pub fn set_pos( &mut self, vram: &mut VRamManager, @@ -241,18 +271,23 @@ impl<'a> InfiniteScrolledMap<'a> { PartialUpdateStatus::Done } + /// Makes the map visible pub fn show(&mut self) { self.map.show(); } + /// Hides the map pub fn hide(&mut self) { self.map.hide(); } + /// Copies data to vram. Needs to be called during vblank if possible pub fn commit(&mut self, vram: &mut VRamManager) { self.map.commit(vram); } + /// Clears the underlying map. You must call this before the scrolled map goes out of scope + /// or you will leak VRam. pub fn clear(&mut self, vram: &mut VRamManager) { self.map.clear(vram); }