dotzuki_renderer/
tilemap.rs1use crate::palette::{ColorIndex, GbColor, Palette};
11use crate::tile::{RgbaTile, TileFormat, TileSet, TILE_PIXELS};
12use crate::TILE_SIZE;
13
14pub const BG_MAP_WIDTH: u32 = 32;
16pub const BG_MAP_HEIGHT: u32 = 32;
17pub const BG_MAP_PIXEL_WIDTH: u32 = BG_MAP_WIDTH * TILE_SIZE;
19pub const BG_MAP_PIXEL_HEIGHT: u32 = BG_MAP_HEIGHT * TILE_SIZE;
20pub const BG_MAP_SIZE: usize = (BG_MAP_WIDTH * BG_MAP_HEIGHT) as usize;
22
23pub struct TileCache {
28 cached: Vec<RgbaTile>,
29 valid: bool,
30}
31
32impl TileCache {
33 pub fn new() -> Self {
34 Self {
35 cached: Vec::new(),
36 valid: false,
37 }
38 }
39
40 pub fn ensure(&mut self, tileset: &TileSet, palette: &Palette) {
42 if self.valid {
43 return;
44 }
45 let count = tileset.len();
46 self.cached.clear();
47 self.cached.reserve(count);
48 for i in 0..count {
49 let tile = tileset.get(i);
50 let mut rgba = RgbaTile::blank();
51 for row in 0..TILE_PIXELS {
52 for col in 0..TILE_PIXELS {
53 let color_idx = tile.pixels[row][col];
54 rgba.pixels[row][col] = palette.color(GbColor::from_u8(color_idx));
55 }
56 }
57 self.cached.push(rgba);
58 }
59 self.valid = true;
60 }
61
62 pub fn ensure_with_format<C: ColorIndex>(&mut self, tileset: &TileSet, palette: &Palette<C>) {
68 if self.valid {
69 return;
70 }
71 let format = tileset.tile_format();
72 let count = tileset.len();
73 self.cached.clear();
74 self.cached.reserve(count);
75 for i in 0..count {
76 match format {
77 TileFormat::FullColor => {
78 if let Some(rgba_tile) = tileset.get_rgba(i) {
79 self.cached.push(rgba_tile.clone());
80 } else {
81 self.cached.push(RgbaTile::blank());
82 }
83 }
84 _ => {
85 let tile = tileset.get(i);
86 let mut rgba = RgbaTile::blank();
87 for row in 0..TILE_PIXELS {
88 for col in 0..TILE_PIXELS {
89 let color_idx = tile.pixels[row][col];
90 rgba.pixels[row][col] = palette.color(C::from_u8(color_idx));
91 }
92 }
93 self.cached.push(rgba);
94 }
95 }
96 }
97 self.valid = true;
98 }
99
100 pub fn invalidate(&mut self) {
102 self.valid = false;
103 }
104
105 #[inline]
107 pub fn get(&self, index: usize) -> Option<&RgbaTile> {
108 self.cached.get(index)
109 }
110}
111
112impl Default for TileCache {
113 fn default() -> Self {
114 Self::new()
115 }
116}