From: notaz Date: Tue, 24 Dec 2024 18:39:34 +0000 (+0200) Subject: gpu: different offset handling X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4ce97e1c7564c16d9581eca4cbd4d919f6bac39;p=pcsx_rearmed.git gpu: different offset handling hopefully better, please report if something breaks libretro/pcsx_rearmed#622 --- diff --git a/plugins/gpu_neon/psx_gpu/psx_gpu.c b/plugins/gpu_neon/psx_gpu/psx_gpu.c index b37c277a..a716a8a5 100644 --- a/plugins/gpu_neon/psx_gpu/psx_gpu.c +++ b/plugins/gpu_neon/psx_gpu/psx_gpu.c @@ -2918,9 +2918,9 @@ char *render_block_flag_strings[] = (triangle_winding_##winding << 6)) \ static int prepare_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, - vertex_struct *vertexes_out[3]) + prepared_triangle *triangle_out) { - s32 y_top, y_bottom; + s32 y_top, y_bottom, offset_x, offset_y, i; s32 triangle_area; u32 triangle_winding = 0; @@ -2955,6 +2955,7 @@ static int prepare_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, y_bottom = c->y; y_top = a->y; + offset_y = sign_extend_11bit(y_top + psx_gpu->offset_y) - y_top; if((y_bottom - y_top) >= 512) { @@ -2982,7 +2983,7 @@ static int prepare_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, vertex_swap(a, b); } - if((c->x - psx_gpu->offset_x) >= 1024 || (c->x - a->x) >= 1024) + if(c->x - a->x >= 1024) { #ifdef PROFILE trivial_rejects++; @@ -2990,8 +2991,10 @@ static int prepare_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, return 0; } - if(invalidate_texture_cache_region_viewport(psx_gpu, a->x, y_top, c->x, - y_bottom) == 0) + offset_x = sign_extend_11bit(a->x + psx_gpu->offset_x) - a->x; + if(invalidate_texture_cache_region_viewport(psx_gpu, + a->x + offset_x, y_top + offset_y, + c->x + offset_x, y_bottom + offset_y) == 0) { #ifdef PROFILE trivial_rejects++; @@ -2999,12 +3002,20 @@ static int prepare_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, return 0; } + for (i = 0; i < 3; i++) + { + vertexes[i].x += offset_x; + vertexes[i].y += offset_y; + } + psx_gpu->triangle_area = triangle_area; psx_gpu->triangle_winding = triangle_winding; - vertexes_out[0] = a; - vertexes_out[1] = b; - vertexes_out[2] = c; + triangle_out->vertexes[0] = a; + triangle_out->vertexes[1] = b; + triangle_out->vertexes[2] = c; + triangle_out->offset_x = offset_x; + triangle_out->offset_y = offset_y; return 1; } @@ -3157,9 +3168,9 @@ static void render_triangle_p(psx_gpu_struct *psx_gpu, void render_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, u32 flags) { - vertex_struct *vertex_ptrs[3]; - if (prepare_triangle(psx_gpu, vertexes, vertex_ptrs)) - render_triangle_p(psx_gpu, vertex_ptrs, flags); + prepared_triangle triangle; + if (prepare_triangle(psx_gpu, vertexes, &triangle)) + render_triangle_p(psx_gpu, triangle.vertexes, flags); } #if !defined(NEON_BUILD) || defined(SIMD_BUILD) diff --git a/plugins/gpu_neon/psx_gpu/psx_gpu.h b/plugins/gpu_neon/psx_gpu/psx_gpu.h index 1ea39170..c37d9da7 100644 --- a/plugins/gpu_neon/psx_gpu/psx_gpu.h +++ b/plugins/gpu_neon/psx_gpu/psx_gpu.h @@ -32,6 +32,9 @@ #define unlikely(x) __builtin_expect((x), 0) #endif +#define sign_extend_11bit(value) \ + (((s32)((value) << 21)) >> 21) + typedef enum { PRIMITIVE_TYPE_TRIANGLE = 0, @@ -247,6 +250,13 @@ typedef struct __attribute__((aligned(16))) u32 padding; } vertex_struct; +typedef struct +{ + vertex_struct *vertexes[3]; + s16 offset_x; + s16 offset_y; +} prepared_triangle; + void render_block_fill(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y, u32 width, u32 height); void render_block_copy(psx_gpu_struct *psx_gpu, u16 *source, u32 x, u32 y, diff --git a/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c b/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c index 95f30120..9f31cfdf 100644 --- a/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c +++ b/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c @@ -202,14 +202,9 @@ static void do_fill(psx_gpu_struct *psx_gpu, u32 x, u32 y, } } -#define sign_extend_11bit(value) \ - (((s32)((value) << 21)) >> 21) \ - #define get_vertex_data_xy(vertex_number, offset16) \ - vertexes[vertex_number].x = \ - sign_extend_11bit(list_s16[offset16]) + psx_gpu->offset_x; \ - vertexes[vertex_number].y = \ - sign_extend_11bit(list_s16[(offset16) + 1]) + psx_gpu->offset_y; \ + vertexes[vertex_number].x = sign_extend_11bit(list_s16[offset16]); \ + vertexes[vertex_number].y = sign_extend_11bit(list_s16[(offset16) + 1]); \ #define get_vertex_data_uv(vertex_number, offset16) \ vertexes[vertex_number].u = list_s16[offset16] & 0xFF; \ @@ -260,6 +255,37 @@ static void textured_sprite(psx_gpu_struct *psx_gpu, const u32 *list, gput_sum(*cpu_cycles_sum, *cpu_cycles, gput_sprite(width, height)); } +static void undo_offset(vertex_struct *vertexes, prepared_triangle *triangle) +{ + s32 i; + for (i = 0; i < 3; i++) + { + vertexes[i].x -= triangle->offset_x; + vertexes[i].y -= triangle->offset_y; + } +} + +static void do_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, + u32 current_command) +{ + prepared_triangle triangle; + if (prepare_triangle(psx_gpu, vertexes, &triangle)) + render_triangle_p(psx_gpu, triangle.vertexes, current_command); +} + +static void do_quad(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, + u32 current_command) +{ + prepared_triangle triangle; + if (prepare_triangle(psx_gpu, vertexes, &triangle)) + { + render_triangle_p(psx_gpu, triangle.vertexes, current_command); + undo_offset(vertexes, &triangle); + } + if (prepare_triangle(psx_gpu, vertexes + 1, &triangle)) + render_triangle_p(psx_gpu, triangle.vertexes, current_command); +} + u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, s32 *cpu_cycles_sum_out, s32 *cpu_cycles_last, u32 *last_command) { @@ -307,7 +333,7 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy(1, 4); get_vertex_data_xy(2, 6); - render_triangle(psx_gpu, vertexes, current_command); + do_triangle(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base()); break; } @@ -322,7 +348,7 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy_uv(1, 6); get_vertex_data_xy_uv(2, 10); - render_triangle(psx_gpu, vertexes, current_command); + do_triangle(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_t()); break; } @@ -335,9 +361,8 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy(1, 4); get_vertex_data_xy(2, 6); get_vertex_data_xy(3, 8); - - render_triangle(psx_gpu, vertexes, current_command); - render_triangle(psx_gpu, &(vertexes[1]), current_command); + + do_quad(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base()); break; } @@ -364,9 +389,8 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy_uv(1, 6); get_vertex_data_xy_uv(2, 10); get_vertex_data_xy_uv(3, 14); - - render_triangle(psx_gpu, vertexes, current_command); - render_triangle(psx_gpu, &(vertexes[1]), current_command); + + do_quad(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_t()); break; } @@ -377,7 +401,7 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy_rgb(1, 4); get_vertex_data_xy_rgb(2, 8); - render_triangle(psx_gpu, vertexes, current_command); + do_triangle(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_g()); break; } @@ -391,7 +415,7 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy_uv_rgb(1, 6); get_vertex_data_xy_uv_rgb(2, 12); - render_triangle(psx_gpu, vertexes, current_command); + do_triangle(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_gt()); break; } @@ -402,9 +426,8 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy_rgb(1, 4); get_vertex_data_xy_rgb(2, 8); get_vertex_data_xy_rgb(3, 12); - - render_triangle(psx_gpu, vertexes, current_command); - render_triangle(psx_gpu, &(vertexes[1]), current_command); + + do_quad(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_g()); break; } @@ -430,9 +453,8 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, get_vertex_data_xy_uv_rgb(1, 6); get_vertex_data_xy_uv_rgb(2, 12); get_vertex_data_xy_uv_rgb(3, 18); - - render_triangle(psx_gpu, vertexes, current_command); - render_triangle(psx_gpu, &(vertexes[1]), current_command); + + do_quad(psx_gpu, vertexes, current_command); gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_gt()); break; } @@ -757,10 +779,8 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, case 0xE5: { - s32 offset_x = list[0] << 21; - s32 offset_y = list[0] << 10; - psx_gpu->offset_x = offset_x >> 21; - psx_gpu->offset_y = offset_y >> 21; + psx_gpu->offset_x = sign_extend_11bit(list[0]); + psx_gpu->offset_y = sign_extend_11bit(list[0] >> 11); SET_Ex(5, list[0]); break; @@ -1056,15 +1076,16 @@ static u32 uv_hack(psx_gpu_struct *psx_gpu, const vertex_struct *vertex_ptrs) static void do_triangle_enhanced(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, u32 current_command) { - vertex_struct *vertex_ptrs[3]; + prepared_triangle triangle; - if (!prepare_triangle(psx_gpu, vertexes, vertex_ptrs)) + if (!prepare_triangle(psx_gpu, vertexes, &triangle)) return; if (!psx_gpu->hack_disable_main) - render_triangle_p(psx_gpu, vertex_ptrs, current_command); + render_triangle_p(psx_gpu, triangle.vertexes, current_command); - if (!check_enhanced_range(psx_gpu, vertex_ptrs[0]->x, vertex_ptrs[2]->x)) + if (!check_enhanced_range(psx_gpu, triangle.vertexes[0]->x, + triangle.vertexes[2]->x)) return; if (!enhancement_enable(psx_gpu)) @@ -1072,17 +1093,21 @@ static void do_triangle_enhanced(psx_gpu_struct *psx_gpu, if ((current_command & RENDER_FLAGS_TEXTURE_MAP) && psx_gpu->hack_texture_adj) psx_gpu->hacks_active |= uv_hack(psx_gpu, vertexes); - shift_vertices3(vertex_ptrs); + shift_vertices3(triangle.vertexes); shift_triangle_area(); - render_triangle_p(psx_gpu, vertex_ptrs, current_command); - unshift_vertices3(vertex_ptrs); + render_triangle_p(psx_gpu, triangle.vertexes, current_command); + //unshift_vertices3(triangle.vertexes); } static void do_quad_enhanced(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, u32 current_command) { + s16 x12_save[2] = { vertexes[1].x, vertexes[2].x }; + s16 y12_save[2] = { vertexes[1].y, vertexes[2].y }; do_triangle_enhanced(psx_gpu, vertexes, current_command); enhancement_disable(); + vertexes[1].x = x12_save[0], vertexes[2].x = x12_save[1]; + vertexes[1].y = y12_save[0], vertexes[2].y = y12_save[1]; do_triangle_enhanced(psx_gpu, &vertexes[1], current_command); } diff --git a/plugins/gpu_unai/gpu_raster_polygon.h b/plugins/gpu_unai/gpu_raster_polygon.h index 6aaf9adc..fe7a8186 100644 --- a/plugins/gpu_unai/gpu_raster_polygon.h +++ b/plugins/gpu_unai/gpu_raster_polygon.h @@ -78,14 +78,12 @@ static void polyInitVertexBuffer(PolyVertex *vbuf, const PtrUnion packet, PolyTy int num_verts = (is_quad) ? 4 : 3; le32_t *ptr; - // X,Y coords, adjusted by draw offsets - s32 x_off = gpu_unai.DrawingOffset[0]; - s32 y_off = gpu_unai.DrawingOffset[1]; + // X,Y coords ptr = &packet.U4[1]; for (int i=0; i < num_verts; ++i, ptr += vert_stride) { u32 coords = le32_to_u32(*ptr); - vbuf[i].x = GPU_EXPANDSIGN((s16)coords) + x_off; - vbuf[i].y = GPU_EXPANDSIGN((s16)(coords >> 16)) + y_off; + vbuf[i].x = GPU_EXPANDSIGN(coords); + vbuf[i].y = GPU_EXPANDSIGN(coords >> 16); } // U,V texture coords (if applicable) @@ -174,7 +172,7 @@ static inline int vertIdxOfHighestYCoord3(const T *Tptr) // or 1 for second triangle of a quad (idx 1,2,3 of vbuf[]). // Returns true if triangle should be rendered, false if not. /////////////////////////////////////////////////////////////////////////////// -static bool polyUseTriangle(const PolyVertex *vbuf, int tri_num, const PolyVertex **vert_ptrs) +static bool polyUseTriangle(const PolyVertex *vbuf, int tri_num, const PolyVertex **vert_ptrs, s32 &x_off, s32 &y_off) { // Using verts 0,1,2 or is this the 2nd pass of a quad (verts 1,2,3)? const PolyVertex *tri_ptr = &vbuf[(tri_num == 0) ? 0 : 1]; @@ -195,14 +193,20 @@ static bool polyUseTriangle(const PolyVertex *vbuf, int tri_num, const PolyVerte (highest_y - lowest_y) >= CHKMAX_Y) return false; + // Determine offsets + x_off = gpu_unai.DrawingOffset[0]; + y_off = gpu_unai.DrawingOffset[1]; + x_off = GPU_EXPANDSIGN(lowest_x + x_off) - lowest_x; + y_off = GPU_EXPANDSIGN(lowest_y + y_off) - lowest_y; + // Determine if triangle is completely outside clipping range int xmin, xmax, ymin, ymax; xmin = gpu_unai.DrawingArea[0]; xmax = gpu_unai.DrawingArea[2]; ymin = gpu_unai.DrawingArea[1]; ymax = gpu_unai.DrawingArea[3]; - int clipped_lowest_x = Max2(xmin,lowest_x); - int clipped_lowest_y = Max2(ymin,lowest_y); - int clipped_highest_x = Min2(xmax,highest_x); - int clipped_highest_y = Min2(ymax,highest_y); + int clipped_lowest_x = Max2(xmin, lowest_x + x_off); + int clipped_lowest_y = Max2(ymin, lowest_y + y_off); + int clipped_highest_x = Min2(xmax, highest_x + x_off); + int clipped_highest_y = Min2(ymax, highest_y + y_off); if (clipped_lowest_x >= clipped_highest_x || clipped_lowest_y >= clipped_highest_y) return false; @@ -237,16 +241,17 @@ void gpuDrawPolyF(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_quad do { const PolyVertex* vptrs[3]; - if (polyUseTriangle(vbuf, cur_pass, vptrs) == false) + s32 x_off, y_off; + if (!polyUseTriangle(vbuf, cur_pass, vptrs, x_off, y_off)) continue; s32 xa, xb, ya, yb; s32 x3, dx3, x4, dx4, dx; s32 x0, x1, x2, y0, y1, y2; - x0 = vptrs[0]->x; y0 = vptrs[0]->y; - x1 = vptrs[1]->x; y1 = vptrs[1]->y; - x2 = vptrs[2]->x; y2 = vptrs[2]->y; + x0 = vptrs[0]->x + x_off; y0 = vptrs[0]->y + y_off; + x1 = vptrs[1]->x + x_off; y1 = vptrs[1]->y + y_off; + x2 = vptrs[2]->x + x_off; y2 = vptrs[2]->y + y_off; ya = y2 - y0; yb = y2 - y1; @@ -395,7 +400,8 @@ void gpuDrawPolyFT(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_qua do { const PolyVertex* vptrs[3]; - if (polyUseTriangle(vbuf, cur_pass, vptrs) == false) + s32 x_off, y_off; + if (!polyUseTriangle(vbuf, cur_pass, vptrs, x_off, y_off)) continue; s32 xa, xb, ya, yb; @@ -405,12 +411,12 @@ void gpuDrawPolyFT(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_qua s32 u0, u1, u2, v0, v1, v2; s32 du4, dv4; - x0 = vptrs[0]->x; y0 = vptrs[0]->y; - u0 = vptrs[0]->tex.u; v0 = vptrs[0]->tex.v; - x1 = vptrs[1]->x; y1 = vptrs[1]->y; - u1 = vptrs[1]->tex.u; v1 = vptrs[1]->tex.v; - x2 = vptrs[2]->x; y2 = vptrs[2]->y; - u2 = vptrs[2]->tex.u; v2 = vptrs[2]->tex.v; + x0 = vptrs[0]->x + x_off; y0 = vptrs[0]->y + y_off; + u0 = vptrs[0]->tex.u; v0 = vptrs[0]->tex.v; + x1 = vptrs[1]->x + x_off; y1 = vptrs[1]->y + y_off; + u1 = vptrs[1]->tex.u; v1 = vptrs[1]->tex.v; + x2 = vptrs[2]->x + x_off; y2 = vptrs[2]->y + y_off; + u2 = vptrs[2]->tex.u; v2 = vptrs[2]->tex.v; ya = y2 - y0; yb = y2 - y1; @@ -719,7 +725,8 @@ void gpuDrawPolyG(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_quad do { const PolyVertex* vptrs[3]; - if (polyUseTriangle(vbuf, cur_pass, vptrs) == false) + s32 x_off, y_off; + if (!polyUseTriangle(vbuf, cur_pass, vptrs, x_off, y_off)) continue; s32 xa, xb, ya, yb; @@ -729,12 +736,12 @@ void gpuDrawPolyG(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_quad s32 r0, r1, r2, g0, g1, g2, b0, b1, b2; s32 dr4, dg4, db4; - x0 = vptrs[0]->x; y0 = vptrs[0]->y; - r0 = vptrs[0]->col.r; g0 = vptrs[0]->col.g; b0 = vptrs[0]->col.b; - x1 = vptrs[1]->x; y1 = vptrs[1]->y; - r1 = vptrs[1]->col.r; g1 = vptrs[1]->col.g; b1 = vptrs[1]->col.b; - x2 = vptrs[2]->x; y2 = vptrs[2]->y; - r2 = vptrs[2]->col.r; g2 = vptrs[2]->col.g; b2 = vptrs[2]->col.b; + x0 = vptrs[0]->x + x_off; y0 = vptrs[0]->y + y_off; + r0 = vptrs[0]->col.r; g0 = vptrs[0]->col.g; b0 = vptrs[0]->col.b; + x1 = vptrs[1]->x + x_off; y1 = vptrs[1]->y + y_off; + r1 = vptrs[1]->col.r; g1 = vptrs[1]->col.g; b1 = vptrs[1]->col.b; + x2 = vptrs[2]->x + x_off; y2 = vptrs[2]->y + y_off; + r2 = vptrs[2]->col.r; g2 = vptrs[2]->col.g; b2 = vptrs[2]->col.b; ya = y2 - y0; yb = y2 - y1; @@ -1067,7 +1074,8 @@ void gpuDrawPolyGT(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_qua do { const PolyVertex* vptrs[3]; - if (polyUseTriangle(vbuf, cur_pass, vptrs) == false) + s32 x_off, y_off; + if (!polyUseTriangle(vbuf, cur_pass, vptrs, x_off, y_off)) continue; s32 xa, xb, ya, yb; @@ -1080,15 +1088,15 @@ void gpuDrawPolyGT(const PtrUnion packet, const PP gpuPolySpanDriver, u32 is_qua s32 du4, dv4; s32 dr4, dg4, db4; - x0 = vptrs[0]->x; y0 = vptrs[0]->y; - u0 = vptrs[0]->tex.u; v0 = vptrs[0]->tex.v; - r0 = vptrs[0]->col.r; g0 = vptrs[0]->col.g; b0 = vptrs[0]->col.b; - x1 = vptrs[1]->x; y1 = vptrs[1]->y; - u1 = vptrs[1]->tex.u; v1 = vptrs[1]->tex.v; - r1 = vptrs[1]->col.r; g1 = vptrs[1]->col.g; b1 = vptrs[1]->col.b; - x2 = vptrs[2]->x; y2 = vptrs[2]->y; - u2 = vptrs[2]->tex.u; v2 = vptrs[2]->tex.v; - r2 = vptrs[2]->col.r; g2 = vptrs[2]->col.g; b2 = vptrs[2]->col.b; + x0 = vptrs[0]->x + x_off; y0 = vptrs[0]->y + y_off; + u0 = vptrs[0]->tex.u; v0 = vptrs[0]->tex.v; + r0 = vptrs[0]->col.r; g0 = vptrs[0]->col.g; b0 = vptrs[0]->col.b; + x1 = vptrs[1]->x + x_off; y1 = vptrs[1]->y + y_off; + u1 = vptrs[1]->tex.u; v1 = vptrs[1]->tex.v; + r1 = vptrs[1]->col.r; g1 = vptrs[1]->col.g; b1 = vptrs[1]->col.b; + x2 = vptrs[2]->x + x_off; y2 = vptrs[2]->y + y_off; + u2 = vptrs[2]->tex.u; v2 = vptrs[2]->tex.v; + r2 = vptrs[2]->col.r; g2 = vptrs[2]->col.g; b2 = vptrs[2]->col.b; ya = y2 - y0; yb = y2 - y1; diff --git a/plugins/gpu_unai/gpulib_if.cpp b/plugins/gpu_unai/gpulib_if.cpp index 5fbb7f52..4d096344 100644 --- a/plugins/gpu_unai/gpulib_if.cpp +++ b/plugins/gpu_unai/gpulib_if.cpp @@ -361,8 +361,8 @@ static void gpuGP0Cmd_0xEx(gpu_unai_t &gpu_unai, u32 cmd_word) case 5: { // GP0(E5h) - Set Drawing Offset (X,Y) - gpu_unai.DrawingOffset[0] = ((s32)cmd_word<<(32-11))>>(32-11); - gpu_unai.DrawingOffset[1] = ((s32)cmd_word<<(32-22))>>(32-11); + gpu_unai.DrawingOffset[0] = GPU_EXPANDSIGN(cmd_word); + gpu_unai.DrawingOffset[1] = GPU_EXPANDSIGN(cmd_word >> 11); } break; case 6: {