Improve affine text renderer

This commit is contained in:
David Guillen Fandos 2023-08-04 00:26:46 +02:00
parent 71df26db98
commit 4822923b90
1 changed files with 61 additions and 26 deletions

View File

@ -150,6 +150,7 @@ static inline void render_part_tile_Nbpp(u32 bg_comb, u32 px_comb,
// tile_base already points to the right tile-line vertical offset // tile_base already points to the right tile-line vertical offset
const u8 *tile_ptr = &tile_base[(tile & 0x3FF) * (is8bpp ? 64 : 32)]; const u8 *tile_ptr = &tile_base[(tile & 0x3FF) * (is8bpp ? 64 : 32)];
const u16 *paltbl = &palette_ram_converted[0]; const u16 *paltbl = &palette_ram_converted[0];
u16 bgcolor = paltbl[0];
// On vertical flip, apply the mirror offset // On vertical flip, apply the mirror offset
if (tile & 0x800) if (tile & 0x800)
@ -173,7 +174,7 @@ static inline void render_part_tile_Nbpp(u32 bg_comb, u32 px_comb,
} }
else if (isbase) { else if (isbase) {
if (rdtype == FULLCOLOR) if (rdtype == FULLCOLOR)
*dest_ptr = paltbl[0]; *dest_ptr = bgcolor;
else else
*dest_ptr = 0 | bg_comb; // Add combine flags *dest_ptr = 0 | bg_comb; // Add combine flags
} }
@ -196,7 +197,7 @@ static inline void render_part_tile_Nbpp(u32 bg_comb, u32 px_comb,
} }
else if (isbase) { else if (isbase) {
if (rdtype == FULLCOLOR) if (rdtype == FULLCOLOR)
*dest_ptr = paltbl[0]; *dest_ptr = bgcolor;
else else
*dest_ptr = 0 | bg_comb; *dest_ptr = 0 | bg_comb;
} }
@ -211,6 +212,7 @@ static inline void render_tile_Nbpp(
const u8 *tile_base, int vertical_pixel_flip, const u16 *paltbl const u8 *tile_base, int vertical_pixel_flip, const u16 *paltbl
) { ) {
const u8 *tile_ptr = &tile_base[(tile & 0x3FF) * (is8bpp ? 64 : 32)]; const u8 *tile_ptr = &tile_base[(tile & 0x3FF) * (is8bpp ? 64 : 32)];
u16 bgcolor = paltbl[0];
if (tile & 0x800) if (tile & 0x800)
tile_ptr += vertical_pixel_flip; tile_ptr += vertical_pixel_flip;
@ -230,7 +232,7 @@ static inline void render_tile_Nbpp(
} }
else if (isbase) { else if (isbase) {
if (rdtype == FULLCOLOR) if (rdtype == FULLCOLOR)
*dest_ptr = paltbl[0]; *dest_ptr = bgcolor;
else else
*dest_ptr = 0 | bg_comb; // Add combine flags *dest_ptr = 0 | bg_comb; // Add combine flags
} }
@ -251,7 +253,7 @@ static inline void render_tile_Nbpp(
} }
else if (isbase) { else if (isbase) {
if (rdtype == FULLCOLOR) if (rdtype == FULLCOLOR)
*dest_ptr = paltbl[0]; *dest_ptr = bgcolor;
else else
*dest_ptr = 0 | bg_comb; *dest_ptr = 0 | bg_comb;
} }
@ -478,29 +480,32 @@ static inline void render_affine_background(
if (wrap) { if (wrap) {
// In wrap mode the entire space is covered, since it "wraps" at the edges // In wrap mode the entire space is covered, since it "wraps" at the edges
while (cnt--) { if (rotate) {
u32 pixel_x = (u32)(source_x >> 8) & (width_height-1); while (cnt--) {
u32 pixel_y = (u32)(source_y >> 8) & (width_height-1); u32 pixel_x = (u32)(source_x >> 8) & (width_height-1);
u32 pixel_y = (u32)(source_y >> 8) & (width_height-1);
// Lookup pixel and draw it. // Lookup pixel and draw it.
render_pixel_8bpp<dsttype, rdtype, isbase>( render_pixel_8bpp<dsttype, rdtype, isbase>(
layer, dst_ptr++, pixel_x, pixel_y, bg_comb, px_comb, layer, dst_ptr++, pixel_x, pixel_y, bg_comb, px_comb,
tile_base, map_base, map_size); tile_base, map_base, map_size);
// Move to the next pixel, update coords accordingly source_x += dx; source_y += dy; // Move to the next pixel
source_x += dx; }
if (rotate) } else {
source_y += dy; // Y coordinate stays contant across the walk.
const u32 pixel_y = (u32)(source_y >> 8) & (width_height-1);
while (cnt--) {
u32 pixel_x = (u32)(source_x >> 8) & (width_height-1);
render_pixel_8bpp<dsttype, rdtype, isbase>(
layer, dst_ptr++, pixel_x, pixel_y, bg_comb, px_comb,
tile_base, map_base, map_size);
source_x += dx; // Only moving in the X direction.
}
} }
} else { } else {
if (rotate) {
// Early optimization if Y-coord is out completely for this line.
// (if there's no rotation Y coord remains identical throughout the line).
bool is_y_out = !rotate && ((u32)(source_y >> 8)) >= width_height;
if (!is_y_out) {
// Draw backdrop pixels if necessary until we reach the background edge. // Draw backdrop pixels if necessary until we reach the background edge.
// TODO: on non-base cases this could perhaps be calculated in O(1)?
while (cnt) { while (cnt) {
// Draw backdrop pixels if they lie outside of the background. // Draw backdrop pixels if they lie outside of the background.
u32 pixel_x = (u32)(source_x >> 8), pixel_y = (u32)(source_y >> 8); u32 pixel_x = (u32)(source_x >> 8), pixel_y = (u32)(source_y >> 8);
@ -514,9 +519,7 @@ static inline void render_affine_background(
render_bdrop_pixel_8bpp<dsttype, rdtype>(dst_ptr, bg_comb); render_bdrop_pixel_8bpp<dsttype, rdtype>(dst_ptr, bg_comb);
dst_ptr++; dst_ptr++;
source_x += dx; source_x += dx; source_y += dy;
if (rotate)
source_y += dy;
cnt--; cnt--;
} }
@ -539,6 +542,37 @@ static inline void render_affine_background(
if (rotate) if (rotate)
source_y += dy; source_y += dy;
} }
} else {
// Specialized version for scaled-only backgrounds
const u32 pixel_y = (u32)(source_y >> 8);
if (pixel_y < width_height) { // Check if within Y-coord range
// Draw/find till left edge
while (cnt) {
u32 pixel_x = (u32)(source_x >> 8);
if (pixel_x < width_height)
break;
if (isbase)
render_bdrop_pixel_8bpp<dsttype, rdtype>(dst_ptr, bg_comb);
dst_ptr++;
source_x += dx;
cnt--;
}
// Draw actual background
while (cnt) {
u32 pixel_x = (u32)(source_x >> 8);
if (pixel_x >= width_height)
break;
render_pixel_8bpp<dsttype, rdtype, isbase>(
layer, dst_ptr++, pixel_x, pixel_y, bg_comb, px_comb,
tile_base, map_base, map_size);
source_x += dx;
cnt--;
}
}
} }
// Complete the line on the right, if we ran out over the bg edge. // Complete the line on the right, if we ran out over the bg edge.
@ -1451,9 +1485,10 @@ static void merge_brightness(u32 start, u32 end, u16 *srcdst) {
// Fills a segment using the backdrop color (in the right mode). // Fills a segment using the backdrop color (in the right mode).
template<rendtype rdmode, typename dsttype> template<rendtype rdmode, typename dsttype>
void fill_line_background(u32 start, u32 end, dsttype *scanline) { void fill_line_background(u32 start, u32 end, dsttype *scanline) {
dsttype bgcol = palette_ram_converted[0];
while (start < end) while (start < end)
if (rdmode == FULLCOLOR) if (rdmode == FULLCOLOR)
scanline[start++] = palette_ram_converted[0]; scanline[start++] = bgcol;
else else
scanline[start++] = 0; scanline[start++] = 0;
} }