mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-26 09:06:33 +11:00
Use a hash map rather than an array in vram manager
This commit is contained in:
parent
9170acb1a8
commit
e6d47afa31
1 changed files with 13 additions and 15 deletions
|
@ -1,12 +1,12 @@
|
||||||
use core::{alloc::Layout, ptr::NonNull};
|
use core::{alloc::Layout, ptr::NonNull};
|
||||||
|
|
||||||
use alloc::vec;
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
agb_alloc::{block_allocator::BlockAllocator, bump_allocator::StartEnd},
|
agb_alloc::{block_allocator::BlockAllocator, bump_allocator::StartEnd},
|
||||||
display::palette16,
|
display::palette16,
|
||||||
dma::dma_copy16,
|
dma::dma_copy16,
|
||||||
|
hash_map::HashMap,
|
||||||
memory_mapped::MemoryMapped1DArray,
|
memory_mapped::MemoryMapped1DArray,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ impl<'a> TileSet<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_tiles(&self) -> usize {
|
fn num_tiles(&self) -> usize {
|
||||||
self.tiles.len() / self.format.tile_size()
|
self.tiles.len() / self.format.tile_size() * 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,18 +104,20 @@ pub struct VRamManager<'a> {
|
||||||
generation: u16,
|
generation: u16,
|
||||||
free_pointer: Option<usize>,
|
free_pointer: Option<usize>,
|
||||||
|
|
||||||
tile_set_to_vram: Vec<Vec<Option<TileReference>>>,
|
tile_set_to_vram: HashMap<(u16, u16), TileReference>,
|
||||||
reference_counts: Vec<(u16, Option<(TileSetReference, u16)>)>,
|
reference_counts: Vec<(u16, Option<(TileSetReference, u16)>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VRamManager<'a> {
|
impl<'a> VRamManager<'a> {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
|
let tile_set_to_vram: HashMap<(u16, u16), TileReference> = HashMap::with_capacity(256);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
tilesets: Vec::new(),
|
tilesets: Vec::new(),
|
||||||
generation: 0,
|
generation: 0,
|
||||||
free_pointer: None,
|
free_pointer: None,
|
||||||
|
|
||||||
tile_set_to_vram: Default::default(),
|
tile_set_to_vram,
|
||||||
reference_counts: Default::default(),
|
reference_counts: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +126,6 @@ impl<'a> VRamManager<'a> {
|
||||||
let generation = self.generation;
|
let generation = self.generation;
|
||||||
self.generation = self.generation.wrapping_add(1);
|
self.generation = self.generation.wrapping_add(1);
|
||||||
|
|
||||||
let num_tiles = tileset.num_tiles();
|
|
||||||
let tileset = ArenaStorageItem::Data(tileset, generation);
|
let tileset = ArenaStorageItem::Data(tileset, generation);
|
||||||
|
|
||||||
let index = if let Some(ptr) = self.free_pointer.take() {
|
let index = if let Some(ptr) = self.free_pointer.take() {
|
||||||
|
@ -145,10 +146,6 @@ impl<'a> VRamManager<'a> {
|
||||||
self.tilesets.len() - 1
|
self.tilesets.len() - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
self.tile_set_to_vram
|
|
||||||
.resize(self.tilesets.len(), Default::default());
|
|
||||||
self.tile_set_to_vram[index] = vec![Default::default(); num_tiles];
|
|
||||||
|
|
||||||
TileSetReference::new(index as u16, generation)
|
TileSetReference::new(index as u16, generation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,10 +182,10 @@ impl<'a> VRamManager<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_tile(&mut self, tile_set_ref: TileSetReference, tile: u16) -> TileIndex {
|
pub(crate) fn add_tile(&mut self, tile_set_ref: TileSetReference, tile: u16) -> TileIndex {
|
||||||
let reference = self.tile_set_to_vram[tile_set_ref.id as usize][tile as usize];
|
let reference = self.tile_set_to_vram.get(&(tile_set_ref.id, tile));
|
||||||
|
|
||||||
if let Some(reference) = reference {
|
if let Some(reference) = reference {
|
||||||
let index = Self::index_from_reference(reference);
|
let index = Self::index_from_reference(*reference);
|
||||||
self.reference_counts[index].0 += 1;
|
self.reference_counts[index].0 += 1;
|
||||||
return TileIndex::new(index);
|
return TileIndex::new(index);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +207,7 @@ impl<'a> VRamManager<'a> {
|
||||||
panic!("Tile set ref must point to existing tile set");
|
panic!("Tile set ref must point to existing tile set");
|
||||||
};
|
};
|
||||||
|
|
||||||
let tile_size_in_half_words = TileFormat::FourBpp.tile_size() / 2;
|
let tile_size_in_half_words = tile_slice.len() / 2;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
dma_copy16(
|
dma_copy16(
|
||||||
|
@ -224,7 +221,8 @@ impl<'a> VRamManager<'a> {
|
||||||
|
|
||||||
let index = Self::index_from_reference(tile_reference);
|
let index = Self::index_from_reference(tile_reference);
|
||||||
|
|
||||||
self.tile_set_to_vram[tile_set_ref.id as usize][tile as usize] = Some(tile_reference);
|
self.tile_set_to_vram
|
||||||
|
.insert((tile_set_ref.id, tile), tile_reference);
|
||||||
|
|
||||||
self.reference_counts
|
self.reference_counts
|
||||||
.resize(self.reference_counts.len().max(index + 1), (0, None));
|
.resize(self.reference_counts.len().max(index + 1), (0, None));
|
||||||
|
@ -250,11 +248,11 @@ impl<'a> VRamManager<'a> {
|
||||||
|
|
||||||
let tile_reference = Self::reference_from_index(tile_index);
|
let tile_reference = Self::reference_from_index(tile_index);
|
||||||
unsafe {
|
unsafe {
|
||||||
TILE_ALLOCATOR.dealloc(tile_reference.0.cast().as_ptr(), TILE_LAYOUT);
|
TILE_ALLOCATOR.dealloc_no_normalise(tile_reference.0.cast().as_ptr(), TILE_LAYOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tile_ref = self.reference_counts[index].1.unwrap();
|
let tile_ref = self.reference_counts[index].1.unwrap();
|
||||||
self.tile_set_to_vram[tile_ref.0.id as usize][tile_ref.1 as usize] = None;
|
self.tile_set_to_vram.remove(&(tile_ref.0.id, tile_ref.1));
|
||||||
self.reference_counts[index].1 = None;
|
self.reference_counts[index].1 = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue