diff --git a/agb/src/display/tiled/infinite_scrolled_map.rs b/agb/src/display/tiled/infinite_scrolled_map.rs index 6be831d..41dc67d 100644 --- a/agb/src/display/tiled/infinite_scrolled_map.rs +++ b/agb/src/display/tiled/infinite_scrolled_map.rs @@ -63,8 +63,8 @@ impl<'a> InfiniteScrolledMap<'a> { let offset = self.current_pos - (x_start * 8, y_start * 8).into(); let offset_scroll = ( - self.map.size().rem_euclid_width(offset.x), - self.map.size().rem_euclid_height(offset.y), + self.map.size().tile_pos_x(offset.x), + self.map.size().tile_pos_y(offset.y), ) .into(); @@ -179,8 +179,8 @@ impl<'a> InfiniteScrolledMap<'a> { self.map.set_tile( vram, ( - size.rem_euclid_width(tile_x - self.offset.x), - size.rem_euclid_height(tile_y - self.offset.y), + size.tile_pos_x(tile_x - self.offset.x), + size.tile_pos_y(tile_y - self.offset.y), ) .into(), tileset, @@ -190,8 +190,8 @@ impl<'a> InfiniteScrolledMap<'a> { let current_scroll = self.map.scroll_pos(); let new_scroll = ( - size.rem_euclid_width_px(current_scroll.x as i32 + difference.x), - size.rem_euclid_height_px(current_scroll.y as i32 + difference.y), + size.px_offset_x(current_scroll.x as i32 + difference.x), + size.px_offset_y(current_scroll.y as i32 + difference.y), ) .into(); diff --git a/agb/src/display/tiled/map.rs b/agb/src/display/tiled/map.rs index 568091f..34cdc77 100644 --- a/agb/src/display/tiled/map.rs +++ b/agb/src/display/tiled/map.rs @@ -56,7 +56,7 @@ impl RegularMap { tileset: &TileSet<'_>, tile_setting: TileSetting, ) { - let pos = (pos.x + pos.y * self.size.width() as u16) as usize; + let pos = self.size.gba_offset(pos); let old_tile = self.tiles[pos]; if old_tile != Tile::default() { diff --git a/agb/src/display/tiled/mod.rs b/agb/src/display/tiled/mod.rs index 3abc9cf..68ae2e9 100644 --- a/agb/src/display/tiled/mod.rs +++ b/agb/src/display/tiled/mod.rs @@ -3,6 +3,7 @@ mod map; mod tiled0; mod vram_manager; +use agb_fixnum::Vector2D; pub use infinite_scrolled_map::{InfiniteScrolledMap, PartialUpdateStatus}; pub use map::{MapLoan, RegularMap}; pub use tiled0::Tiled0; @@ -52,6 +53,17 @@ impl RegularBackgroundSize { self.num_tiles() / (32 * 32) } + pub(crate) fn gba_offset(&self, pos: Vector2D) -> usize { + let x_mod = pos.x & (self.width() as u16 - 1); + let y_mod = pos.y & (self.height() as u16 - 1); + + let screenblock = (x_mod / 32) + (y_mod / 32) * (self.width() as u16 / 32); + + let pos = screenblock * 32 * 32 + (x_mod % 32 + 32 * (y_mod % 32)); + + pos as usize + } + pub(crate) fn tile_pos_x(&self, x: i32) -> u16 { ((x as u32) & (self.width() - 1)) as u16 } diff --git a/examples/the-hat-chooses-the-wizard/src/main.rs b/examples/the-hat-chooses-the-wizard/src/main.rs index cf5524d..578fc7d 100644 --- a/examples/the-hat-chooses-the-wizard/src/main.rs +++ b/examples/the-hat-chooses-the-wizard/src/main.rs @@ -846,7 +846,7 @@ fn main(mut agb: agb::Gba) -> ! { let map_current_level = current_level; let mut background = InfiniteScrolledMap::new( - tiled.background(Priority::P2, RegularBackgroundSize::Background64x64), + tiled.background(Priority::P2, RegularBackgroundSize::Background32x64), Box::new(|pos: Vector2D| { let level = &map_tiles::LEVELS[map_current_level as usize]; ( @@ -861,7 +861,7 @@ fn main(mut agb: agb::Gba) -> ! { }), ); let mut foreground = InfiniteScrolledMap::new( - tiled.background(Priority::P0, RegularBackgroundSize::Background64x64), + tiled.background(Priority::P0, RegularBackgroundSize::Background64x32), Box::new(|pos: Vector2D| { let level = &map_tiles::LEVELS[map_current_level as usize]; (