Fix tilemap gaps in affine graphic modes #733 (#735)

- [x] Changelog updated
Fixes issue #733 where affine tilemaps have a gap.
This commit is contained in:
Gwilym Inzani 2024-07-11 21:32:52 +01:00 committed by GitHub
commit 5829d71b6b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 69 additions and 13 deletions

View file

@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Fixed
- There are no longer gaps between tiles in affine graphics modes.
## [0.20.5] - 2024/06/18 ## [0.20.5] - 2024/06/18
### Fixed ### Fixed

View file

@ -30,7 +30,6 @@ trait TiledMapPrivate: TiledMapTypes {
fn background_id(&self) -> usize; fn background_id(&self) -> usize;
fn screenblock(&self) -> usize; fn screenblock(&self) -> usize;
fn priority(&self) -> Priority;
fn map_size(&self) -> Self::Size; fn map_size(&self) -> Self::Size;
fn update_bg_registers(&self); fn update_bg_registers(&self);
@ -53,11 +52,7 @@ pub trait TiledMap: TiledMapTypes {
fn size(&self) -> Self::Size; fn size(&self) -> Self::Size;
} }
impl<T> TiledMap for T impl TiledMap for AffineMap {
where
T: TiledMapPrivate,
T::Size: BackgroundSizePrivate,
{
fn clear(&mut self, vram: &mut VRamManager) { fn clear(&mut self, vram: &mut VRamManager) {
let colours = self.colours(); let colours = self.colours();
@ -88,6 +83,70 @@ where
DISPLAY_CONTROL.get() & (1 << (self.background_id() + 0x08)) > 0 DISPLAY_CONTROL.get() & (1 << (self.background_id() + 0x08)) > 0
} }
fn commit(&mut self, vram: &mut VRamManager) {
let screenblock_memory = self.screenblock_memory() as *mut u8;
if *self.tiles_dirty() {
let tiledata: Vec<u8> = self
.tiles_mut()
.iter()
.map(|a| a.tile_index(TileFormat::EightBpp).raw_index() as u8)
.collect();
unsafe {
screenblock_memory.copy_from(tiledata.as_ptr(), self.map_size().num_tiles());
}
}
let tile_colour_flag: u16 = (self.colours() == TileFormat::EightBpp).into();
let new_bg_control_value = (self.priority() as u16)
| ((self.screenblock() as u16) << 8)
| (tile_colour_flag << 7)
| (self.map_size().size_flag() << 14);
self.bg_control_register().set(new_bg_control_value);
self.update_bg_registers();
vram.gc();
*self.tiles_dirty() = false;
}
fn size(&self) -> <AffineMap as TiledMapTypes>::Size {
self.map_size()
}
}
impl TiledMap for RegularMap {
fn clear(&mut self, vram: &mut VRamManager) {
let colours = self.colours();
for tile in self.tiles_mut() {
if *tile != Default::default() {
vram.remove_tile(tile.tile_index(colours));
}
*tile = Default::default();
}
}
/// Sets wether the map is visible
/// Use [is_visible](TiledMap::is_visible) to get the value
fn set_visible(&mut self, visible: bool) {
let mode = DISPLAY_CONTROL.get();
let new_mode = if visible {
mode | (1 << (self.background_id() + 0x08)) as u16
} else {
mode & !(1 << (self.background_id() + 0x08)) as u16
};
DISPLAY_CONTROL.set(new_mode);
}
/// Checks whether the map is not marked as hidden
/// Use [set_visible](TiledMap::set_visible) to set the value
fn is_visible(&self) -> bool {
DISPLAY_CONTROL.get() & (1 << (self.background_id() + 0x08)) > 0
}
fn commit(&mut self, vram: &mut VRamManager) { fn commit(&mut self, vram: &mut VRamManager) {
let screenblock_memory = self.screenblock_memory(); let screenblock_memory = self.screenblock_memory();
@ -115,7 +174,7 @@ where
*self.tiles_dirty() = false; *self.tiles_dirty() = false;
} }
fn size(&self) -> T::Size { fn size(&self) -> <RegularMap as TiledMapTypes>::Size {
self.map_size() self.map_size()
} }
} }
@ -156,9 +215,6 @@ impl TiledMapPrivate for RegularMap {
fn screenblock(&self) -> usize { fn screenblock(&self) -> usize {
self.screenblock as usize self.screenblock as usize
} }
fn priority(&self) -> Priority {
self.priority
}
fn map_size(&self) -> Self::Size { fn map_size(&self) -> Self::Size {
self.size self.size
} }
@ -340,9 +396,6 @@ impl TiledMapPrivate for AffineMap {
fn screenblock(&self) -> usize { fn screenblock(&self) -> usize {
self.screenblock as usize self.screenblock as usize
} }
fn priority(&self) -> Priority {
self.priority
}
fn map_size(&self) -> Self::Size { fn map_size(&self) -> Self::Size {
self.size self.size
} }