mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
Remove hash map lookup for every pixel rendered
This commit is contained in:
parent
6d0f95c21b
commit
fec4015978
|
@ -86,7 +86,7 @@ pub struct TextRenderer<'a> {
|
||||||
bg: &'a mut RegularMap,
|
bg: &'a mut RegularMap,
|
||||||
background_colour: u8,
|
background_colour: u8,
|
||||||
foreground_colour: u8,
|
foreground_colour: u8,
|
||||||
tiles: HashMap<(usize, usize), DynamicTile<'a>>,
|
tiles: HashMap<(i32, i32), DynamicTile<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Write for TextRenderer<'a> {
|
impl<'a> Write for TextRenderer<'a> {
|
||||||
|
@ -96,23 +96,6 @@ impl<'a> Write for TextRenderer<'a> {
|
||||||
let foreground_colour = self.foreground_colour;
|
let foreground_colour = self.foreground_colour;
|
||||||
let background_colour = self.background_colour;
|
let background_colour = self.background_colour;
|
||||||
|
|
||||||
let mut render_pixel = |x: u16, y: u16| {
|
|
||||||
let tile_x = (x / 8) as usize;
|
|
||||||
let tile_y = (y / 8) as usize;
|
|
||||||
let inner_x = x % 8;
|
|
||||||
let inner_y = y % 8;
|
|
||||||
|
|
||||||
let colour = foreground_colour as u32;
|
|
||||||
|
|
||||||
let index = (inner_x + inner_y * 8) as usize;
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
for c in text.chars() {
|
for c in text.chars() {
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
self.current_y_pos += self.font.line_height;
|
self.current_y_pos += self.font.line_height;
|
||||||
|
@ -126,15 +109,56 @@ impl<'a> Write for TextRenderer<'a> {
|
||||||
let y_start =
|
let y_start =
|
||||||
self.current_y_pos + self.font.ascent - letter.height as i32 - letter.ymin as i32;
|
self.current_y_pos + self.font.ascent - letter.height as i32 - letter.ymin as i32;
|
||||||
|
|
||||||
for letter_y in 0..(letter.height as i32) {
|
let x_tile_start = x_start / 8;
|
||||||
for letter_x in 0..(letter.width as i32) {
|
let y_tile_start = y_start / 8;
|
||||||
let x = x_start + letter_x;
|
|
||||||
let y = y_start + letter_y;
|
|
||||||
|
|
||||||
let px = letter.data[(letter_x + letter_y * letter.width as i32) as usize];
|
let letter_offset_x = x_start.rem_euclid(8);
|
||||||
|
let letter_offset_y = y_start.rem_euclid(8);
|
||||||
|
|
||||||
if px > 100 {
|
let x_tiles = div_ceil(letter.width as i32 + letter_offset_x, 8);
|
||||||
render_pixel(x as u16, y as u16);
|
let y_tiles = div_ceil(letter.height as i32 + letter_offset_y, 8);
|
||||||
|
|
||||||
|
for letter_y_tile in 0..(y_tiles + 1) {
|
||||||
|
let letter_y_start = 0.max(letter_offset_y - 8 * letter_y_tile) + 8 * letter_y_tile;
|
||||||
|
let letter_y_end =
|
||||||
|
(letter_offset_y + letter.height as i32).min((letter_y_tile + 1) * 8);
|
||||||
|
|
||||||
|
let tile_y = y_tile_start + letter_y_tile;
|
||||||
|
|
||||||
|
for letter_x_tile in 0..(x_tiles + 1) {
|
||||||
|
let letter_x_start =
|
||||||
|
0.max(letter_offset_x - 8 * letter_x_tile) + 8 * letter_x_tile;
|
||||||
|
let letter_x_end =
|
||||||
|
(letter_offset_x + letter.width as i32).min((letter_x_tile + 1) * 8);
|
||||||
|
|
||||||
|
let tile_x = x_tile_start + letter_x_tile;
|
||||||
|
|
||||||
|
let mut masks = [0u32; 8];
|
||||||
|
let mut zero = true;
|
||||||
|
|
||||||
|
for letter_y in letter_y_start..letter_y_end {
|
||||||
|
let y = letter_y - letter_offset_y;
|
||||||
|
|
||||||
|
for letter_x in letter_x_start..letter_x_end {
|
||||||
|
let x = letter_x - letter_offset_x;
|
||||||
|
let px = letter.data[(x + y * letter.width as i32) as usize];
|
||||||
|
|
||||||
|
if px > 100 {
|
||||||
|
masks[(letter_y & 7) as usize] |=
|
||||||
|
(foreground_colour as u32) << ((letter_x & 7) * 4);
|
||||||
|
zero = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !zero {
|
||||||
|
let tile = tiles.entry((tile_x, tile_y)).or_insert_with(|| {
|
||||||
|
vram_manager.new_dynamic_tile().fill_with(background_colour)
|
||||||
|
});
|
||||||
|
|
||||||
|
for (i, tile_data_line) in tile.tile_data.iter_mut().enumerate() {
|
||||||
|
*tile_data_line |= masks[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,6 +170,10 @@ impl<'a> Write for TextRenderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn div_ceil(quotient: i32, divisor: i32) -> i32 {
|
||||||
|
(quotient + divisor - 1) / divisor
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> TextRenderer<'a> {
|
impl<'a> TextRenderer<'a> {
|
||||||
pub fn commit(mut self) {
|
pub fn commit(mut self) {
|
||||||
let tiles = core::mem::take(&mut self.tiles);
|
let tiles = core::mem::take(&mut self.tiles);
|
||||||
|
|
Loading…
Reference in a new issue