shithub: psxe

Download patch

ref: 93c6a6727cc410af6921820dc8ef6f2016aebba3
parent: 78f0d10e95318ba573e96ae4d35b111e06450466
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Sep 17 16:27:41 EDT 2023

Improve GPU emulation

--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -19,6 +19,13 @@
            ((color & 0xf80000) >> 9);
 }
 
+#define BGR555(c) \
+    (((c & 0x0000f8) >> 3) | \
+     ((c & 0x00f800) >> 6) | \
+     ((c & 0xf80000) >> 9))
+
+// #define BGR555(c) gpu_to_bgr555(c)
+
 psx_gpu_t* psx_gpu_create() {
     return (psx_gpu_t*)malloc(sizeof(psx_gpu_t));
 }
@@ -113,7 +120,7 @@
 
 #define EDGE(a, b, c) ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x))
 
-uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx, uint32_t tpy, int depth) {
+uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx, uint32_t tpy, uint16_t clutx, uint16_t cluty, int depth) {
     tx = (tx & ~gpu->texw_mx) | (gpu->texw_ox & gpu->texw_mx);
     ty = (ty & ~gpu->texw_my) | (gpu->texw_oy & gpu->texw_my);
 
@@ -124,7 +131,7 @@
 
             int index = (texel >> ((tx & 0x3) << 2)) & 0xf;
 
-            return gpu->vram[(gpu->clut_x + index) + (gpu->clut_y * 1024)];
+            return gpu->vram[(clutx + index) + (cluty * 1024)];
         } break;
 
         // 8-bit
@@ -133,7 +140,7 @@
 
             int index = (texel >> ((tx & 0x1) << 3)) & 0xff;
 
-            return gpu->vram[(gpu->clut_x + index) + (gpu->clut_y * 1024)];
+            return gpu->vram[(clutx + index) + (cluty * 1024)];
         } break;
 
         // 15-bit
@@ -228,7 +235,7 @@
     }
 }
 
-void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint32_t tpx, uint32_t tpy) {
+void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint16_t clutx, uint16_t cluty, uint32_t color) {
     vertex_t a = v;
 
     a.x += gpu->off_x;
@@ -243,13 +250,17 @@
 
     for (int y = ymin; y < ymax; y++) {
         for (int x = xmin; x < xmax; x++) {
-            uint16_t color = gpu_fetch_texel(gpu, a.tx + xc, a.ty + yc, tpx, tpy, gpu->texp_d);
+            uint16_t texel = gpu_fetch_texel(
+                gpu,
+                a.tx + xc, a.ty + yc,
+                gpu->texp_x, gpu->texp_y,
+                clutx, cluty,
+                gpu->texp_d
+            );
 
             ++xc;
 
-            if (!color) continue;
-
-            gpu->vram[x + (y * 1024)] = color;
+            gpu->vram[x + (y * 1024)] = texel;
         }
 
         xc = 0;
@@ -291,7 +302,7 @@
             int z2 = ((a.x - c.x) * (y - c.y)) - ((a.y - c.y) * (x - c.x));
 
             if ((z0 >= 0) && (z1 >= 0) && (z2 >= 0)) {
-                gpu->vram[x + (y * 1024)] = gpu_to_bgr555(color);
+                gpu->vram[x + (y * 1024)] = BGR555(color);
             }
         }
     }
@@ -364,13 +375,13 @@
 
                 uint32_t color = (cb << 16) | (cg << 8) | cr;
 
-                gpu->vram[x + (y * 1024)] = gpu_to_bgr555(color);
+                gpu->vram[x + (y * 1024)] = BGR555(color);
             }
         }
     }
 }
 
-void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t tpx, uint32_t tpy, int depth) {
+void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t tpx, uint32_t tpy, uint16_t clutx, uint16_t cluty, int depth) {
     vertex_t a, b, c;
 
     a = v0;
@@ -413,7 +424,13 @@
                 uint32_t tx = ((z0 * a.tx) + (z1 * b.tx) + (z2 * c.tx)) / area;
                 uint32_t ty = ((z0 * a.ty) + (z1 * b.ty) + (z2 * c.ty)) / area;
 
-                uint16_t color = gpu_fetch_texel(gpu, tx, ty, tpx, tpy, depth);
+                uint16_t color = gpu_fetch_texel(
+                    gpu,
+                    tx, ty,
+                    tpx, tpy,
+                    clutx, cluty,
+                    depth
+                );
 
                 if (!color) continue;
 
@@ -612,16 +629,15 @@
                 gpu->v3.x = gpu->buf[10] & 0xffff;
                 gpu->v3.y = gpu->buf[10] >> 16;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
+                uint16_t tpx = (texp & 0xf) << 6;
+                uint16_t tpy = (texp & 0x10) << 4;
+                uint16_t depth = (texp >> 7) & 0x3;
 
-                uint32_t tpx = (texp & 0xf) << 6;
-                uint32_t tpy = (texp & 0x10) << 4;
-                uint32_t depth = (texp >> 7) & 0x3;
+                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, clutx, cluty, depth);
+                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, clutx, cluty, depth);
 
-                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
-                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -660,16 +676,15 @@
                 gpu->v3.x = gpu->buf[7] & 0xffff;
                 gpu->v3.y = gpu->buf[7] >> 16;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
+                uint16_t tpx = (texp & 0xf) << 6;
+                uint16_t tpy = (texp & 0x10) << 4;
+                uint16_t depth = (texp >> 7) & 0x3;
 
-                uint32_t tpx = (texp & 0xf) << 6;
-                uint32_t tpy = (texp & 0x10) << 4;
-                uint32_t depth = (texp >> 7) & 0x3;
+                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, clutx, cluty, depth);
+                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, clutx, cluty, depth);
 
-                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
-                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -704,15 +719,15 @@
                 gpu->v2.x = gpu->buf[5] & 0xffff;
                 gpu->v2.y = gpu->buf[5] >> 16;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
+                uint16_t tpx = (texp & 0xf) << 6;
+                uint16_t tpy = (texp & 0x10) << 4;
+                uint16_t depth = (texp >> 7) & 0x3;
 
-                uint32_t tpx = (texp & 0xf) << 6;
-                uint32_t tpy = (texp & 0x10) << 4;
-                int depth = (texp >> 7) & 0x3;
+                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, clutx, cluty, depth);
+                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, clutx, cluty, depth);
 
-                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -751,16 +766,15 @@
                 gpu->v3.x = gpu->buf[7] & 0xffff;
                 gpu->v3.y = gpu->buf[7] >> 16;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
+                uint16_t tpx = (texp & 0xf) << 6;
+                uint16_t tpy = (texp & 0x10) << 4;
+                uint16_t depth = (texp >> 7) & 0x3;
 
-                uint32_t tpx = (texp & 0xf) << 6;
-                uint32_t tpy = (texp & 0x10) << 4;
-                int depth = (texp >> 7) & 0x3;
+                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, clutx, cluty, depth);
+                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, clutx, cluty, depth);
 
-                gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
-                gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -787,15 +801,11 @@
 
                 uint32_t w = gpu->buf[3] & 0xffff;
                 uint32_t h = gpu->buf[3] >> 16;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, clutx, cluty, gpu->color);
 
-                uint32_t tpx = gpu->texp_x;
-                uint32_t tpy = gpu->texp_y;
-
-                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, tpx, tpy);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -822,15 +832,11 @@
 
                 uint32_t w = 16;
                 uint32_t h = 16;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, clutx, cluty, gpu->color);
 
-                uint32_t tpx = gpu->texp_x;
-                uint32_t tpy = gpu->texp_y;
-
-                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, tpx, tpy);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -857,15 +863,11 @@
 
                 uint32_t w = 8;
                 uint32_t h = 8;
+                uint16_t clutx = (gpu->pal & 0x3f) << 4;
+                uint16_t cluty = (gpu->pal >> 6) & 0x1ff;
 
-                gpu->clut_x = (gpu->pal & 0x3f) << 4;
-                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, clutx, cluty, gpu->color);
 
-                uint32_t tpx = gpu->texp_x;
-                uint32_t tpy = gpu->texp_y;
-
-                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, tpx, tpy);
-
                 gpu->state = GPU_STATE_RECV_CMD;
             }
         } break;
@@ -892,7 +894,7 @@
                 gpu->v0.x += gpu->off_x;
                 gpu->v0.y += gpu->off_y;
 
-                gpu_render_flat_rectangle(gpu, gpu->v0, gpu->xsiz, gpu->ysiz, gpu_to_bgr555(gpu->color));
+                gpu_render_flat_rectangle(gpu, gpu->v0, gpu->xsiz, gpu->ysiz, BGR555(gpu->color));
 
                 gpu->state = GPU_STATE_RECV_CMD;
             }
@@ -918,7 +920,7 @@
                 gpu->v0.x += gpu->off_x;
                 gpu->v0.y += gpu->off_y;
 
-                gpu->vram[gpu->v0.x + (gpu->v0.y * 1024)] = gpu_to_bgr555(gpu->color);
+                gpu->vram[gpu->v0.x + (gpu->v0.y * 1024)] = BGR555(gpu->color);
 
                 gpu->state = GPU_STATE_RECV_CMD;
             }
@@ -941,7 +943,7 @@
                 gpu->v1.x  = gpu->buf[2] & 0xffff;
                 gpu->v1.y  = gpu->buf[2] >> 16;
 
-                gpu_render_flat_line(gpu, gpu->v0, gpu->v1, gpu_to_bgr555(gpu->color));
+                gpu_render_flat_line(gpu, gpu->v0, gpu->v1, BGR555(gpu->color));
 
                 gpu->state = GPU_STATE_RECV_CMD;
             }
@@ -999,10 +1001,13 @@
                 gpu->xsiz = (((gpu->xsiz & 0x3ff) + 0x0f) & 0xfffffff0);
                 gpu->ysiz = gpu->ysiz & 0x1ff;
 
-                gpu->v0.x += gpu->off_x;
-                gpu->v0.y += gpu->off_y;
+                uint16_t color = BGR555(gpu->color);
 
-                gpu_render_flat_rectangle(gpu, gpu->v0, gpu->xsiz, gpu->ysiz, gpu_to_bgr555(gpu->color));
+                for (uint32_t y = gpu->v0.y; y < (gpu->v0.y + gpu->ysiz); y++) {
+                    for (uint32_t x = gpu->v0.x; x < (gpu->v0.x + gpu->xsiz); x++) {
+                        gpu->vram[x + (y * 1024)] = color;
+                    }
+                }
 
                 gpu->state = GPU_STATE_RECV_CMD;
             }
--