diff --git a/agb/examples/chicken.rs b/agb/examples/chicken.rs index 86cbfd1..019af3c 100644 --- a/agb/examples/chicken.rs +++ b/agb/examples/chicken.rs @@ -3,7 +3,7 @@ extern crate agb; use agb::{ - display::{object::ObjectStandard, tiled0::Map, HEIGHT, WIDTH}, + display::{background::Map, object::ObjectStandard, HEIGHT, WIDTH}, input::Button, }; use core::convert::TryInto; @@ -51,7 +51,7 @@ pub fn main() -> ! { gfx.set_background_palette_raw(&MAP_PALETTE); gfx.set_background_tilemap(0, &MAP_TILES); - let mut background = gfx.get_background().unwrap(); + let mut background = gfx.get_regular().unwrap(); background.set_map(Map::new(&MAP_MAP, (32_u32, 32_u32).into(), 0)); background.show(); background.commit(); diff --git a/agb/src/display/tiled0.rs b/agb/src/display/background.rs similarity index 90% rename from agb/src/display/tiled0.rs rename to agb/src/display/background.rs index 2cd864d..c40d726 100644 --- a/agb/src/display/tiled0.rs +++ b/agb/src/display/background.rs @@ -79,7 +79,7 @@ impl<'a> MapStorage<'a> { /// The map background is the method of drawing game maps to the screen. It /// automatically handles copying the correct portion of a provided map to the /// assigned block depending on given coordinates. -pub struct Background<'a> { +pub struct BackgroundRegular<'a> { background: u8, block: u8, commited_position: Vector2D, @@ -125,9 +125,9 @@ impl<'a> Map<'a> { } } -impl<'a> Background<'a> { - unsafe fn new(background: u8, block: u8) -> Background<'a> { - let mut b = Background { +impl<'a> BackgroundRegular<'a> { + unsafe fn new(background: u8, block: u8) -> BackgroundRegular<'a> { + let mut b = BackgroundRegular { background, block, commited_position: (0, 0).into(), @@ -281,18 +281,32 @@ impl<'a> Background<'a> { } } -pub struct Tiled0 { - used_blocks: u32, - num_backgrounds: u8, +fn decide_background_mode(num_regular: u8, num_affine: u8) -> Option { + if num_affine == 0 && num_regular <= 4 { + Some(DisplayMode::Tiled0) + } else if num_affine == 1 && num_regular <= 2 { + Some(DisplayMode::Tiled1) + } else if num_affine == 2 && num_regular == 0 { + Some(DisplayMode::Tiled2) + } else { + None + } } -impl<'b> Tiled0 { +pub struct BackgroundDistributor { + used_blocks: u32, + num_regular: u8, + num_affine: u8, +} + +impl<'b> BackgroundDistributor { pub(crate) unsafe fn new() -> Self { set_graphics_settings(GraphicsSettings::empty() | GraphicsSettings::SPRITE1_D); set_graphics_mode(DisplayMode::Tiled0); - Tiled0 { + BackgroundDistributor { used_blocks: 0, - num_backgrounds: 0, + num_regular: 0, + num_affine: 0, } } @@ -321,10 +335,11 @@ impl<'b> Tiled0 { } /// Gets a map background if possible and assigns an unused block to it. - pub fn get_background(&mut self) -> Result, &'static str> { - if self.num_backgrounds >= 4 { - return Err("too many backgrounds created, maximum is 4"); - } + pub fn get_regular(&mut self) -> Result, &'static str> { + let new_mode = decide_background_mode(self.num_regular + 1, self.num_affine) + .ok_or("there is no mode compatible with the requested backgrounds")?; + + unsafe { set_graphics_mode(new_mode) }; if !self.used_blocks == 0 { return Err("all blocks are used"); @@ -346,9 +361,9 @@ impl<'b> Tiled0 { self.used_blocks |= 1 << availiable_block; - let background = self.num_backgrounds; - self.num_backgrounds = background + 1; - Ok(unsafe { Background::new(background, availiable_block) }) + let background = self.num_regular; + self.num_regular += 1; + Ok(unsafe { BackgroundRegular::new(background, availiable_block) }) } /// Copies tiles to tilemap starting at the starting tile. Cannot overwrite diff --git a/agb/src/display/example_logo.rs b/agb/src/display/example_logo.rs index f601d99..424a740 100644 --- a/agb/src/display/example_logo.rs +++ b/agb/src/display/example_logo.rs @@ -1,13 +1,13 @@ -use crate::display::tiled0::Tiled0; +use crate::display::background::BackgroundDistributor; crate::include_gfx!("gfx/agb_logo.toml"); -pub fn display_logo(gfx: &mut Tiled0) { - use super::tiled0::Map; +pub fn display_logo(gfx: &mut BackgroundDistributor) { + use super::background::Map; gfx.set_background_palettes(agb_logo::test_logo.palettes); gfx.set_background_tilemap(0, agb_logo::test_logo.tiles); - let mut back = gfx.get_background().unwrap(); + let mut back = gfx.get_regular().unwrap(); let mut entries: [u16; 30 * 20] = [0; 30 * 20]; for tile_id in 0..(30 * 20) { diff --git a/agb/src/display/mod.rs b/agb/src/display/mod.rs index a05b137..e4ce520 100644 --- a/agb/src/display/mod.rs +++ b/agb/src/display/mod.rs @@ -5,6 +5,8 @@ use video::Video; use self::object::ObjectControl; +/// Graphics mode 0. Four regular backgrounds. +pub mod background; /// Graphics mode 3. Bitmap mode that provides a 16-bit colour framebuffer. pub mod bitmap3; /// Graphics mode 4. Bitmap 4 provides two 8-bit paletted framebuffers with page switching. @@ -17,8 +19,6 @@ pub mod object; pub mod palette16; /// Data produced by agb-image-converter pub mod tile_data; -/// Graphics mode 0. Four regular backgrounds. -pub mod tiled0; /// Giving out graphics mode. pub mod video; diff --git a/agb/src/display/video.rs b/agb/src/display/video.rs index 3c7974a..2652b8a 100644 --- a/agb/src/display/video.rs +++ b/agb/src/display/video.rs @@ -1,4 +1,4 @@ -use super::{bitmap3::Bitmap3, bitmap4::Bitmap4, tiled0::Tiled0}; +use super::{background::BackgroundDistributor, bitmap3::Bitmap3, bitmap4::Bitmap4}; #[non_exhaustive] pub struct Video {} @@ -14,7 +14,7 @@ impl Video { unsafe { Bitmap4::new() } } - pub fn tiled0(&mut self) -> Tiled0 { - unsafe { Tiled0::new() } + pub fn tiled0(&mut self) -> BackgroundDistributor { + unsafe { BackgroundDistributor::new() } } }