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 {
|
pub struct FontLetter {
|
||||||
width: u8,
|
width: u8,
|
||||||
|
@ -62,7 +62,7 @@ impl Font {
|
||||||
bg: &mut RegularMap,
|
bg: &mut RegularMap,
|
||||||
vram_manager: &mut VRamManager,
|
vram_manager: &mut VRamManager,
|
||||||
) -> (i32, i32) {
|
) -> (i32, i32) {
|
||||||
let mut tiles: Vec<Vec<DynamicTile>> = vec![];
|
let mut tiles = HashMap::new();
|
||||||
|
|
||||||
let mut render_pixel = |x: u16, y: u16| {
|
let mut render_pixel = |x: u16, y: u16| {
|
||||||
let tile_x = (x / 8) as usize;
|
let tile_x = (x / 8) as usize;
|
||||||
|
@ -70,21 +70,15 @@ impl Font {
|
||||||
let inner_x = x % 8;
|
let inner_x = x % 8;
|
||||||
let inner_y = y % 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 colour = foreground_colour as u32;
|
||||||
|
|
||||||
let index = (inner_x + inner_y * 8) as usize;
|
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;
|
let mut current_x_pos = 0i32;
|
||||||
|
@ -118,16 +112,14 @@ impl Font {
|
||||||
current_x_pos += letter.advance_width as i32;
|
current_x_pos += letter.advance_width as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x, x_tiles) in tiles.into_iter().enumerate() {
|
for ((x, y), tile) in tiles.into_iter() {
|
||||||
for (y, tile) in x_tiles.into_iter().enumerate() {
|
bg.set_tile(
|
||||||
bg.set_tile(
|
vram_manager,
|
||||||
vram_manager,
|
(tile_x + x as u16, tile_y + y as u16).into(),
|
||||||
(tile_x + x as u16, tile_y + y as u16).into(),
|
&tile.tile_set(),
|
||||||
&tile.tile_set(),
|
TileSetting::from_raw(tile.tile_index()),
|
||||||
TileSetting::from_raw(tile.tile_index()),
|
);
|
||||||
);
|
vram_manager.remove_dynamic_tile(tile);
|
||||||
vram_manager.remove_dynamic_tile(tile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(current_x_pos, current_y_pos + self.line_height)
|
(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.
|
/// A view into an occupied entry in a `HashMap`. This is part of the [`Entry`] enum.
|
||||||
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
||||||
key: K,
|
key: K,
|
||||||
|
@ -908,7 +941,7 @@ mod test {
|
||||||
let mut num_found = 0;
|
let mut num_found = 0;
|
||||||
|
|
||||||
for (_, value) in map.into_iter() {
|
for (_, value) in map.into_iter() {
|
||||||
max_found = max_found.max(*value);
|
max_found = max_found.max(value);
|
||||||
num_found += 1;
|
num_found += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue