Skip to content

Commit

Permalink
rdpq: fix rdpq_tex_blit when flipping with a source rect
Browse files Browse the repository at this point in the history
Also fix a bug that cause the texture loader to miscalculate the strip
heights when a source rect was activated, causing far more chunks to
be generated.

Updates DragonMinded#562
  • Loading branch information
rasky committed Jun 10, 2024
1 parent a7572eb commit 7ec5c9e
Showing 1 changed file with 32 additions and 26 deletions.
58 changes: 32 additions & 26 deletions src/rdpq/rdpq_tex.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ static void ltd_texloader(rdpq_tile_t tile, const surface_t *tex, int s0, int t0
tex_loader_t tload = tex_loader_init(tile, tex);

// Calculate the optimal height for a strip, based on strips of maximum length.
int tile_h = tex_loader_calc_max_height(&tload, tex->width);
int tile_h = tex_loader_calc_max_height(&tload, s1 - s0);

// Go through the surface
while (t0 < t1)
Expand All @@ -491,24 +491,26 @@ static void tex_xblit_norotate_noscale(const surface_t *surf, float x0, float y0
rdpq_tile_t tile = parms->tile;
int src_width = parms->width ? parms->width : surf->width;
int src_height = parms->height ? parms->height : surf->height;
int s0 = parms->s0;
int t0 = parms->t0;
int cx = parms->cx + s0;
int cy = parms->cy + t0;
int os0 = parms->s0;
int ot0 = parms->t0;
int os1 = os0 + src_width;
int ot1 = ot0 + src_height;
bool flip_x = parms->flip_x;
bool flip_y = parms->flip_y;
x0 -= os0 + parms->cx;
y0 -= ot0 + parms->cy;

void draw_cb(rdpq_tile_t tile, int s0, int t0, int s1, int t1)
{
int ks0 = s0, kt0 = t0, ks1 = s1, kt1 = t1;

if (flip_x) { ks0 = src_width - s0 - 1; ks1 = src_width - s1 - 1; }
if (flip_y) { kt0 = src_height - t0 - 1; kt1 = src_height - t1 - 1; }
if (flip_x) { ks0 = os1 - s0 + os0 - 1; ks1 = os1 - s1 + os0 - 1; }
if (flip_y) { kt0 = ot1 - t0 + ot0 - 1; kt1 = ot1 - t1 + ot0 - 1; }

rdpq_texture_rectangle(tile, x0 + ks0 - cx, y0 + kt0 - cy, x0 + ks1 - cx, y0 + kt1 - cy, s0, t0);
rdpq_texture_rectangle(tile, x0 + ks0, y0 + kt0, x0 + ks1, y0 + kt1, s0, t0);
}

(*ltd)(tile, surf, s0, t0, s0 + src_width, t0 + src_height, draw_cb, parms->filtering);
(*ltd)(tile, surf, os0, ot0, os1, ot1, draw_cb, parms->filtering);
}

__attribute__((noinline))
Expand All @@ -517,10 +519,12 @@ static void tex_xblit_norotate(const surface_t *surf, float x0, float y0, const
rdpq_tile_t tile = parms->tile;
int src_width = parms->width ? parms->width : surf->width;
int src_height = parms->height ? parms->height : surf->height;
int s0 = parms->s0;
int t0 = parms->t0;
int cx = parms->cx + s0;
int cy = parms->cy + t0;
int os0 = parms->s0;
int ot0 = parms->t0;
int os1 = os0 + src_width;
int ot1 = ot0 + src_height;
int cx = parms->cx + os0;
int cy = parms->cy + ot0;
float scalex = parms->scale_x == 0 ? 1.0f : parms->scale_x;
float scaley = parms->scale_y == 0 ? 1.0f : parms->scale_y;
bool flip_x = (scalex < 0) ^ parms->flip_x;
Expand All @@ -537,8 +541,8 @@ static void tex_xblit_norotate(const surface_t *surf, float x0, float y0, const
{
int ks0 = s0, kt0 = t0, ks1 = s1, kt1 = t1;

if (flip_x) { ks0 = src_width - s0 - 1; ks1 = src_width - s1 - 1; }
if (flip_y) { kt0 = src_height - t0 - 1; kt1 = src_height - t1 - 1; }
if (flip_x) { ks0 = os1 - s0 + os0 - 1; ks1 = os1 - s1 + os0 - 1; }
if (flip_y) { kt0 = ot1 - t0 + ot0 - 1; kt1 = ot1 - t1 + ot0 - 1; }

float k0x = mtx[0][0] * ks0 + mtx[1][0] * kt0 + mtx[2][0];
float k0y = mtx[0][1] * ks0 + mtx[1][1] * kt0 + mtx[2][1];
Expand All @@ -548,7 +552,7 @@ static void tex_xblit_norotate(const surface_t *surf, float x0, float y0, const
rdpq_texture_rectangle_scaled(tile, k0x, k0y, k2x, k2y, s0, t0, s1, t1);
}

(*ltd)(tile, surf, s0, t0, s0 + src_width, t0 + src_height, draw_cb, parms->filtering);
(*ltd)(tile, surf, os0, ot0, os1, ot1, draw_cb, parms->filtering);
}

__attribute__((noinline))
Expand All @@ -557,10 +561,12 @@ static void tex_xblit(const surface_t *surf, float x0, float y0, const rdpq_blit
rdpq_tile_t tile = parms->tile;
int src_width = parms->width ? parms->width : surf->width;
int src_height = parms->height ? parms->height : surf->height;
int s0 = parms->s0;
int t0 = parms->t0;
int cx = parms->cx + s0;
int cy = parms->cy + t0;
int os0 = parms->s0;
int ot0 = parms->t0;
int os1 = os0 + src_width;
int ot1 = ot0 + src_height;
int cx = parms->cx + os0;
int cy = parms->cy + ot0;
int nx = parms->nx;
int ny = parms->ny;
float scalex = parms->scale_x == 0 ? 1.0f : parms->scale_x;
Expand All @@ -580,8 +586,8 @@ static void tex_xblit(const surface_t *surf, float x0, float y0, const rdpq_blit
{
int ks0 = s0, kt0 = t0, ks1 = s1, kt1 = t1;

if (parms->flip_x) { ks0 = src_width - ks0; ks1 = src_width - ks1; }
if (parms->flip_y) { kt0 = src_height - kt0; kt1 = src_height - kt1; }
if (parms->flip_x) { ks0 = os1 - ks0 + os0; ks1 = os1 - ks1 + os0; }
if (parms->flip_y) { kt0 = ot1 - kt0 + ot0; kt1 = ot1 - kt1 + ot0; }

float k0x = mtx[0][0] * ks0 + mtx[1][0] * kt0 + mtx[2][0];
float k0y = mtx[0][1] * ks0 + mtx[1][1] * kt0 + mtx[2][1];
Expand All @@ -603,8 +609,8 @@ static void tex_xblit(const surface_t *surf, float x0, float y0, const rdpq_blit
void draw_cb_multi_rot(rdpq_tile_t tile, int s0, int t0, int s1, int t1)
{
int ks0 = s0, kt0 = t0, ks1 = s1, kt1 = t1;
if (parms->flip_x) { ks0 = src_width - ks0; ks1 = src_width - ks1; }
if (parms->flip_y) { kt0 = src_height - kt0; kt1 = src_height - kt1; }
if (parms->flip_x) { ks0 = os1 - ks0 + os0; ks1 = os1 - ks1 + os0; }
if (parms->flip_y) { kt0 = ot1 - kt0 + ot0; kt1 = ot1 - kt1 + ot0; }

assert(s1-s0 == src_width);

Expand Down Expand Up @@ -642,9 +648,9 @@ static void tex_xblit(const surface_t *surf, float x0, float y0, const rdpq_blit
}

if (nx || ny) {
(*ltd)(tile, surf, s0, t0, s0 + src_width, t0 + src_height, draw_cb_multi_rot, parms->filtering);
(*ltd)(tile, surf, os0, ot0, os1, ot1, draw_cb_multi_rot, parms->filtering);
} else {
(*ltd)(tile, surf, s0, t0, s0 + src_width, t0 + src_height, draw_cb, parms->filtering);
(*ltd)(tile, surf, os0, ot0, os1, ot1, draw_cb, parms->filtering);
}
}

Expand Down

0 comments on commit 7ec5c9e

Please sign in to comment.