mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 09:31:34 +11:00
Minimise generated dynamic tiles by using a hashmap
This commit is contained in:
parent
22f89ed9e2
commit
5c24e4089a
|
@ -1,6 +1,6 @@
|
|||
use super::tiled::{DynamicTile, RegularMap, TileSetting, VRamManager};
|
||||
use crate::hash_map::HashMap;
|
||||
|
||||
use alloc::{vec, vec::Vec};
|
||||
use super::tiled::{RegularMap, TileSetting, VRamManager};
|
||||
|
||||
pub struct FontLetter {
|
||||
width: u8,
|
||||
|
@ -62,7 +62,7 @@ impl Font {
|
|||
bg: &mut RegularMap,
|
||||
vram_manager: &mut VRamManager,
|
||||
) -> (i32, i32) {
|
||||
let mut tiles: Vec<Vec<DynamicTile>> = vec![];
|
||||
let mut tiles = HashMap::new();
|
||||
|
||||
let mut render_pixel = |x: u16, y: u16| {
|
||||
let tile_x = (x / 8) as usize;
|
||||
|
@ -70,21 +70,15 @@ impl Font {
|
|||
let inner_x = x % 8;
|
||||
let inner_y = y % 8;
|
||||
|
||||
if tiles.len() <= tile_x {
|
||||
tiles.resize_with(tile_x + 1, || vec![]);
|
||||
}
|
||||
|
||||
let x_dynamic_tiles = &mut tiles[tile_x];
|
||||
if x_dynamic_tiles.len() <= tile_y {
|
||||
x_dynamic_tiles.resize_with(tile_y + 1, || {
|
||||
vram_manager.new_dynamic_tile().fill_with(background_colour)
|
||||
});
|
||||
}
|
||||
|
||||
let colour = foreground_colour as u32;
|
||||
|
||||
let index = (inner_x + inner_y * 8) as usize;
|
||||
tiles[tile_x][tile_y].tile_data[index / 8] |= colour << ((index % 8) * 4);
|
||||
|
||||
let tile = tiles
|
||||
.entry((tile_x, tile_y))
|
||||
.or_insert_with(|| vram_manager.new_dynamic_tile().fill_with(background_colour));
|
||||
|
||||
tile.tile_data[index / 8] |= colour << ((index % 8) * 4);
|
||||
};
|
||||
|
||||
let mut current_x_pos = 0i32;
|
||||
|
@ -118,16 +112,14 @@ impl Font {
|
|||
current_x_pos += letter.advance_width as i32;
|
||||
}
|
||||
|
||||
for (x, x_tiles) in tiles.into_iter().enumerate() {
|
||||
for (y, tile) in x_tiles.into_iter().enumerate() {
|
||||
bg.set_tile(
|
||||
vram_manager,
|
||||
(tile_x + x as u16, tile_y + y as u16).into(),
|
||||
&tile.tile_set(),
|
||||
TileSetting::from_raw(tile.tile_index()),
|
||||
);
|
||||
vram_manager.remove_dynamic_tile(tile);
|
||||
}
|
||||
for ((x, y), tile) in tiles.into_iter() {
|
||||
bg.set_tile(
|
||||
vram_manager,
|
||||
(tile_x + x as u16, tile_y + y as u16).into(),
|
||||
&tile.tile_set(),
|
||||
TileSetting::from_raw(tile.tile_index()),
|
||||
);
|
||||
vram_manager.remove_dynamic_tile(tile);
|
||||
}
|
||||
|
||||
(current_x_pos, current_y_pos + self.line_height)
|
||||
|
|
|
@ -324,6 +324,39 @@ impl<'a, K, V> IntoIterator for &'a HashMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct IterOwned<K, V> {
|
||||
map: HashMap<K, V>,
|
||||
at: usize,
|
||||
}
|
||||
|
||||
impl<K, V> Iterator for IterOwned<K, V> {
|
||||
type Item = (K, V);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if self.at >= self.map.nodes.backing_vec_size() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let maybe_kv = self.map.nodes.nodes[self.at].take_key_value();
|
||||
self.at += 1;
|
||||
|
||||
if let Some((k, v, _)) = maybe_kv {
|
||||
return Some((k, v));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> IntoIterator for HashMap<K, V> {
|
||||
type Item = (K, V);
|
||||
type IntoIter = IterOwned<K, V>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IterOwned { map: self, at: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
/// A view into an occupied entry in a `HashMap`. This is part of the [`Entry`] enum.
|
||||
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
||||
key: K,
|
||||
|
@ -908,7 +941,7 @@ mod test {
|
|||
let mut num_found = 0;
|
||||
|
||||
for (_, value) in map.into_iter() {
|
||||
max_found = max_found.max(*value);
|
||||
max_found = max_found.max(value);
|
||||
num_found += 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue