gpu: different offset handling
authornotaz <notasas@gmail.com>
Tue, 24 Dec 2024 18:39:34 +0000 (20:39 +0200)
committernotaz <notasas@gmail.com>
Wed, 25 Dec 2024 00:24:46 +0000 (02:24 +0200)
hopefully better, please report if something breaks
libretro/pcsx_rearmed#622

plugins/gpu_neon/psx_gpu/psx_gpu.c
plugins/gpu_neon/psx_gpu/psx_gpu.h
plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
plugins/gpu_unai/gpu_raster_polygon.h
plugins/gpu_unai/gpulib_if.cpp

index b37c277..a716a8a 100644 (file)
@@ -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)
index 1ea3917..c37d9da 100644 (file)
@@ -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,
index 95f3012..9f31cfd 100644 (file)
@@ -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);
 }
 
index 6aaf9ad..fe7a818 100644 (file)
@@ -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;
index 5fbb7f5..4d09634 100644 (file)
@@ -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: {