diff --git a/src/rdpq/rdpq_tex.c b/src/rdpq/rdpq_tex.c index e84a39be2..21f4dd79e 100644 --- a/src/rdpq/rdpq_tex.c +++ b/src/rdpq/rdpq_tex.c @@ -13,6 +13,7 @@ #include "rdpq_tex.h" #include "rdpq_tex_internal.h" #include "utils.h" +#include "fmath.h" #include /** @brief Non-zero if we are doing a multi-texture upload */ @@ -469,7 +470,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) @@ -496,24 +497,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)) @@ -522,14 +525,14 @@ 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; - bool flip_y = (scaley < 0) ^ parms->flip_y; float mtx[3][2] = { { scalex, 0 }, @@ -542,8 +545,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 (parms->flip_x) { ks0 = os1 - s0 + os0 - 1; ks1 = os1 - s1 + os0 - 1; } + if (parms->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]; @@ -553,7 +556,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)) @@ -562,17 +565,24 @@ 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; float scaley = parms->scale_y == 0 ? 1.0f : parms->scale_y; + bool flip_x = parms->flip_x; + bool flip_y = parms->flip_y; + + if (scalex < 0) { flip_x = !flip_x; scalex = -scalex; } + if (scaley < 0) { flip_y = !flip_y; scaley = -scaley; } float sin_theta, cos_theta; - sincosf(parms->theta, &sin_theta, &cos_theta); + fm_sincosf(parms->theta, &sin_theta, &cos_theta); float mtx[3][2] = { { cos_theta * scalex, -sin_theta * scaley }, @@ -585,8 +595,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 (flip_x) { ks0 = os1 - ks0 + os0; ks1 = os1 - ks1 + os0; } + if (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]; @@ -608,8 +618,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 (flip_x) { ks0 = os1 - ks0 + os0; ks1 = os1 - ks1 + os0; } + if (flip_y) { kt0 = ot1 - kt0 + ot0; kt1 = ot1 - kt1 + ot0; } assert(s1-s0 == src_width); @@ -647,9 +657,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); } }