break;
}
- case 0x80: // vid -> vid
+#ifdef PCSX
+ case 0x80 ... 0x9F: // vid -> vid
+ case 0xA0 ... 0xBF: // sys -> vid
+ case 0xC0 ... 0xDF: // vid -> sys
+ goto breakloop;
+#else
+ case 0x80 ... 0x9F: // vid -> vid
{
u32 sx = list_s16[2] & 0x3FF;
u32 sy = list_s16[3] & 0x1FF;
break;
}
-#ifdef PCSX
- case 0xA0: // sys -> vid
- case 0xC0: // vid -> sys
- goto breakloop;
-#else
- case 0xA0: // sys -> vid
+ case 0xA0 ... 0xBF: // sys -> vid
{
u32 load_x = list_s16[2] & 0x3FF;
u32 load_y = list_s16[3] & 0x1FF;
break;
}
- case 0xC0: // vid -> sys
- break;
+ case 0xC0 ... 0xDF: // vid -> sys
+ break;
#endif
case 0xE1:
psx_gpu->viewport_start_y = psx_gpu->saved_viewport_start_y * 2; \
psx_gpu->viewport_end_x = psx_gpu->saved_viewport_end_x * 2 + 1; \
psx_gpu->viewport_end_y = psx_gpu->saved_viewport_end_y * 2 + 1; \
- psx_gpu->uvrgb_phase = 0x1000; \
+ psx_gpu->uvrgb_phase = 0x7fff; \
}
#define shift_vertices3(v) { \
static int check_enhanced_range(psx_gpu_struct *psx_gpu, int x, int x_end)
{
- // simple reject to avoid oveflowing the 1024 width
+ // reject to avoid oveflowing the 1024 width
// (assume some offscreen render-to-texture thing)
- if (x >= (int)(psx_gpu->saved_viewport_start_x + 512))
+ int fb_index;
+ if (x < 0)
+ return 1;
+ fb_index = select_enhancement_buf_index(psx_gpu, x);
+ if (x >= psx_gpu->enhancement_buf_start[fb_index] + 512)
return 0;
return 1;
}
+static int is_in_array(int val, int array[], int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ if (array[i] == val)
+ return 1;
+ return 0;
+}
+
+static int make_members_unique(int array[], int len)
+{
+ int i, j;
+ for (i = j = 1; i < len; i++)
+ if (!is_in_array(array[i], array, j))
+ array[j++] = array[i];
+
+ if (array[0] > array[1]) {
+ i = array[0]; array[0] = array[1]; array[1] = i;
+ }
+ return j;
+}
+
+static void patch_u(vertex_struct *vertex_ptrs, int count, int old, int new)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ if (vertex_ptrs[i].u == old)
+ vertex_ptrs[i].u = new;
+}
+
+static void patch_v(vertex_struct *vertex_ptrs, int count, int old, int new)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ if (vertex_ptrs[i].v == old)
+ vertex_ptrs[i].v = new;
+}
+
+static void uv_hack(vertex_struct *vertex_ptrs, int vertex_count)
+{
+ int i, u[4], v[4];
+
+ for (i = 0; i < vertex_count; i++) {
+ u[i] = vertex_ptrs[i].u;
+ v[i] = vertex_ptrs[i].v;
+ }
+ if (make_members_unique(u, vertex_count) == 2 && u[1] - u[0] >= 8) {
+ if ((u[0] & 7) == 7) {
+ patch_u(vertex_ptrs, vertex_count, u[0], u[0] + 1);
+ //printf("u hack: %3u-%3u -> %3u-%3u\n", u[0], u[1], u[0]+1, u[1]);
+ }
+ else if ((u[1] & 7) == 0 || u[1] - u[0] > 128) {
+ patch_u(vertex_ptrs, vertex_count, u[1], u[1] - 1);
+ //printf("u hack: %3u-%3u -> %3u-%3u\n", u[0], u[1], u[0], u[1]-1);
+ }
+ }
+ if (make_members_unique(v, vertex_count) == 2 && ((v[0] - v[1]) & 7) == 0) {
+ if ((v[0] & 7) == 7) {
+ patch_v(vertex_ptrs, vertex_count, v[0], v[0] + 1);
+ //printf("v hack: %3u-%3u -> %3u-%3u\n", v[0], v[1], v[0]+1, v[1]);
+ }
+ else if ((v[1] & 7) == 0) {
+ patch_v(vertex_ptrs, vertex_count, v[1], v[1] - 1);
+ //printf("v hack: %3u-%3u -> %3u-%3u\n", v[0], v[1], v[0], v[1]-1);
+ }
+ }
+}
+
static void do_triangle_enhanced(psx_gpu_struct *psx_gpu,
vertex_struct *vertexes, u32 current_command)
{
get_vertex_data_xy_uv(2, 10);
get_vertex_data_xy_uv(3, 14);
+ uv_hack(vertexes, 4);
do_quad_enhanced(psx_gpu, vertexes, current_command);
break;
}
get_vertex_data_xy_uv_rgb(2, 12);
get_vertex_data_xy_uv_rgb(3, 18);
+ uv_hack(vertexes, 4);
do_quad_enhanced(psx_gpu, vertexes, current_command);
break;
}
do_sprite_enhanced(psx_gpu, x, y, u, v, 16, 16, list[0]);
break;
}
-
- case 0x80: // vid -> vid
- {
- u32 sx = list_s16[2] & 0x3FF;
- u32 sy = list_s16[3] & 0x1FF;
- u32 dx = list_s16[4] & 0x3FF;
- u32 dy = list_s16[5] & 0x1FF;
- u32 w = ((list_s16[6] - 1) & 0x3FF) + 1;
- u32 h = ((list_s16[7] - 1) & 0x1FF) + 1;
-
- if (sx == dx && sy == dy && psx_gpu->mask_msb == 0)
- break;
- render_block_move(psx_gpu, sx, sy, dx, dy, w, h);
- sync_enhancement_buffers(dx, dy, w, h);
- break;
- }
-
- case 0xA0: // sys -> vid
- case 0xC0: // vid -> sys
+ case 0x80 ... 0x9F: // vid -> vid
+ case 0xA0 ... 0xBF: // sys -> vid
+ case 0xC0 ... 0xDF: // vid -> sys
goto breakloop;
case 0xE1: