mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
feat: GPU semi-transparency + 85 GTE library seeds + debug commands
GPU fixes: - Mono tri/quad/rect/dot/8x8/lines: route through sw_renderer with semi-transparency support (bit 25 extraction + sw_set_semi_transparency) - Add 16x16 mono sprite (0x78-0x7B) and 1x1 textured dot (0x6C-0x6F) - Add per-opcode execution counter (gpu_get_opcode_count) GTE library: batch-discovered 85 functions in BFC33000-BFC36000 including SetRotMatrix, SetTransMatrix, and full transform pipeline. Emitted: 1173 (was 1086). Seeds: 955. Zero dispatch misses. Debug commands: gpu_opcodes, gte_state, screenshot_file (BMP to disk). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/* AUTO-GENERATED by psxrecomp-bios --emit-full. DO NOT EDIT.
|
||||
*
|
||||
* BIOS SHA256: 71af94d1e47a68c11e8fdb9f8368040601514a42a5a399cda48c7d3bff1e99d3
|
||||
* Dispatch entries: 1087
|
||||
* Dispatch entries: 1174
|
||||
*/
|
||||
|
||||
#include "cpu_state.h"
|
||||
@@ -847,15 +847,57 @@ extern void func_1FC33358(CPUState* cpu);
|
||||
extern void func_1FC33400(CPUState* cpu);
|
||||
extern void func_1FC33538(CPUState* cpu);
|
||||
extern void func_1FC336F0(CPUState* cpu);
|
||||
extern void func_1FC33758(CPUState* cpu);
|
||||
extern void func_1FC337AC(CPUState* cpu);
|
||||
extern void func_1FC33800(CPUState* cpu);
|
||||
extern void func_1FC3388C(CPUState* cpu);
|
||||
extern void func_1FC33918(CPUState* cpu);
|
||||
extern void func_1FC33978(CPUState* cpu);
|
||||
extern void func_1FC339F0(CPUState* cpu);
|
||||
extern void func_1FC33AB8(CPUState* cpu);
|
||||
extern void func_1FC33B80(CPUState* cpu);
|
||||
extern void func_1FC33C04(CPUState* cpu);
|
||||
extern void func_1FC33C84(CPUState* cpu);
|
||||
extern void func_1FC33C98(CPUState* cpu);
|
||||
extern void func_1FC33CC0(CPUState* cpu);
|
||||
extern void func_1FC33D24(CPUState* cpu);
|
||||
extern void func_1FC33DA4(CPUState* cpu);
|
||||
extern void func_1FC33E20(CPUState* cpu);
|
||||
extern void func_1FC33E80(CPUState* cpu);
|
||||
extern void func_1FC33E90(CPUState* cpu);
|
||||
extern void func_1FC33EA0(CPUState* cpu);
|
||||
extern void func_1FC33EC0(CPUState* cpu);
|
||||
extern void func_1FC33ECC(CPUState* cpu);
|
||||
extern void func_1FC33EE0(CPUState* cpu);
|
||||
extern void func_1FC33EF4(CPUState* cpu);
|
||||
extern void func_1FC33F00(CPUState* cpu);
|
||||
extern void func_1FC33F20(CPUState* cpu);
|
||||
extern void func_1FC33F40(CPUState* cpu);
|
||||
extern void func_1FC33F54(CPUState* cpu);
|
||||
extern void func_1FC33F6C(CPUState* cpu);
|
||||
extern void func_1FC33F80(CPUState* cpu);
|
||||
extern void func_1FC33F94(CPUState* cpu);
|
||||
extern void func_1FC33FA8(CPUState* cpu);
|
||||
extern void func_1FC33FB4(CPUState* cpu);
|
||||
extern void func_1FC33FCC(CPUState* cpu);
|
||||
extern void func_1FC33FD8(CPUState* cpu);
|
||||
extern void func_1FC33FE4(CPUState* cpu);
|
||||
extern void func_1FC33FF0(CPUState* cpu);
|
||||
extern void func_1FC33FFC(CPUState* cpu);
|
||||
extern void func_1FC34008(CPUState* cpu);
|
||||
extern void func_1FC3401C(CPUState* cpu);
|
||||
extern void func_1FC34028(CPUState* cpu);
|
||||
extern void func_1FC3403C(CPUState* cpu);
|
||||
extern void func_1FC34054(CPUState* cpu);
|
||||
extern void func_1FC34068(CPUState* cpu);
|
||||
extern void func_1FC3407C(CPUState* cpu);
|
||||
extern void func_1FC34088(CPUState* cpu);
|
||||
extern void func_1FC3409C(CPUState* cpu);
|
||||
extern void func_1FC340CC(CPUState* cpu);
|
||||
extern void func_1FC340D8(CPUState* cpu);
|
||||
extern void func_1FC340E4(CPUState* cpu);
|
||||
extern void func_1FC34104(CPUState* cpu);
|
||||
extern void func_1FC34110(CPUState* cpu);
|
||||
extern void func_1FC34160(CPUState* cpu);
|
||||
extern void func_1FC34304(CPUState* cpu);
|
||||
extern void func_1FC344A4(CPUState* cpu);
|
||||
@@ -863,15 +905,60 @@ extern void func_1FC345F4(CPUState* cpu);
|
||||
extern void func_1FC34748(CPUState* cpu);
|
||||
extern void func_1FC34898(CPUState* cpu);
|
||||
extern void func_1FC348FC(CPUState* cpu);
|
||||
extern void func_1FC34924(CPUState* cpu);
|
||||
extern void func_1FC34928(CPUState* cpu);
|
||||
extern void func_1FC34954(CPUState* cpu);
|
||||
extern void func_1FC34958(CPUState* cpu);
|
||||
extern void func_1FC34980(CPUState* cpu);
|
||||
extern void func_1FC34984(CPUState* cpu);
|
||||
extern void func_1FC349B8(CPUState* cpu);
|
||||
extern void func_1FC34A04(CPUState* cpu);
|
||||
extern void func_1FC34A08(CPUState* cpu);
|
||||
extern void func_1FC34A30(CPUState* cpu);
|
||||
extern void func_1FC34A34(CPUState* cpu);
|
||||
extern void func_1FC34A60(CPUState* cpu);
|
||||
extern void func_1FC34A64(CPUState* cpu);
|
||||
extern void func_1FC34A90(CPUState* cpu);
|
||||
extern void func_1FC34AA0(CPUState* cpu);
|
||||
extern void func_1FC34AF0(CPUState* cpu);
|
||||
extern void func_1FC34B08(CPUState* cpu);
|
||||
extern void func_1FC34B58(CPUState* cpu);
|
||||
extern void func_1FC34EC0(CPUState* cpu);
|
||||
extern void func_1FC34EC4(CPUState* cpu);
|
||||
extern void func_1FC35128(CPUState* cpu);
|
||||
extern void func_1FC3524C(CPUState* cpu);
|
||||
extern void func_1FC35348(CPUState* cpu);
|
||||
extern void func_1FC35470(CPUState* cpu);
|
||||
extern void func_1FC35598(CPUState* cpu);
|
||||
extern void func_1FC35698(CPUState* cpu);
|
||||
extern void func_1FC357C4(CPUState* cpu);
|
||||
extern void func_1FC3582C(CPUState* cpu);
|
||||
extern void func_1FC3586C(CPUState* cpu);
|
||||
extern void func_1FC35890(CPUState* cpu);
|
||||
extern void func_1FC359B4(CPUState* cpu);
|
||||
extern void func_1FC35AD8(CPUState* cpu);
|
||||
extern void func_1FC35B08(CPUState* cpu);
|
||||
extern void func_1FC35B38(CPUState* cpu);
|
||||
extern void func_1FC35B68(CPUState* cpu);
|
||||
extern void func_1FC35B88(CPUState* cpu);
|
||||
extern void func_1FC35BC4(CPUState* cpu);
|
||||
extern void func_1FC35C28(CPUState* cpu);
|
||||
extern void func_1FC35C60(CPUState* cpu);
|
||||
extern void func_1FC35CC8(CPUState* cpu);
|
||||
extern void func_1FC35D10(CPUState* cpu);
|
||||
extern void func_1FC35D58(CPUState* cpu);
|
||||
extern void func_1FC35DA0(CPUState* cpu);
|
||||
extern void func_1FC35DD4(CPUState* cpu);
|
||||
extern void func_1FC35E30(CPUState* cpu);
|
||||
extern void func_1FC35E64(CPUState* cpu);
|
||||
extern void func_1FC35E98(CPUState* cpu);
|
||||
extern void func_1FC35EC0(CPUState* cpu);
|
||||
extern void func_1FC35EEC(CPUState* cpu);
|
||||
extern void func_1FC35F18(CPUState* cpu);
|
||||
extern void func_1FC35F38(CPUState* cpu);
|
||||
extern void func_1FC35F78(CPUState* cpu);
|
||||
extern void func_1FC35FA0(CPUState* cpu);
|
||||
extern void func_1FC35FD0(CPUState* cpu);
|
||||
extern void func_1FC36068(CPUState* cpu);
|
||||
extern void func_1FC362D0(CPUState* cpu);
|
||||
extern void func_1FC36740(CPUState* cpu);
|
||||
@@ -1113,7 +1200,7 @@ typedef struct {
|
||||
PsxRecompFunc func;
|
||||
} DispatchEntry;
|
||||
|
||||
static const DispatchEntry dispatch_table[1087] = {
|
||||
static const DispatchEntry dispatch_table[1174] = {
|
||||
{ 0x00000500u, func_00000500 },
|
||||
{ 0x00000510u, func_00000510 },
|
||||
{ 0x00000520u, func_00000520 },
|
||||
@@ -1943,15 +2030,57 @@ static const DispatchEntry dispatch_table[1087] = {
|
||||
{ 0x1FC33400u, func_1FC33400 },
|
||||
{ 0x1FC33538u, func_1FC33538 },
|
||||
{ 0x1FC336F0u, func_1FC336F0 },
|
||||
{ 0x1FC33758u, func_1FC33758 },
|
||||
{ 0x1FC337ACu, func_1FC337AC },
|
||||
{ 0x1FC33800u, func_1FC33800 },
|
||||
{ 0x1FC3388Cu, func_1FC3388C },
|
||||
{ 0x1FC33918u, func_1FC33918 },
|
||||
{ 0x1FC33978u, func_1FC33978 },
|
||||
{ 0x1FC339F0u, func_1FC339F0 },
|
||||
{ 0x1FC33AB8u, func_1FC33AB8 },
|
||||
{ 0x1FC33B80u, func_1FC33B80 },
|
||||
{ 0x1FC33C04u, func_1FC33C04 },
|
||||
{ 0x1FC33C84u, func_1FC33C84 },
|
||||
{ 0x1FC33C98u, func_1FC33C98 },
|
||||
{ 0x1FC33CC0u, func_1FC33CC0 },
|
||||
{ 0x1FC33D24u, func_1FC33D24 },
|
||||
{ 0x1FC33DA4u, func_1FC33DA4 },
|
||||
{ 0x1FC33E20u, func_1FC33E20 },
|
||||
{ 0x1FC33E80u, func_1FC33E80 },
|
||||
{ 0x1FC33E90u, func_1FC33E90 },
|
||||
{ 0x1FC33EA0u, func_1FC33EA0 },
|
||||
{ 0x1FC33EC0u, func_1FC33EC0 },
|
||||
{ 0x1FC33ECCu, func_1FC33ECC },
|
||||
{ 0x1FC33EE0u, func_1FC33EE0 },
|
||||
{ 0x1FC33EF4u, func_1FC33EF4 },
|
||||
{ 0x1FC33F00u, func_1FC33F00 },
|
||||
{ 0x1FC33F20u, func_1FC33F20 },
|
||||
{ 0x1FC33F40u, func_1FC33F40 },
|
||||
{ 0x1FC33F54u, func_1FC33F54 },
|
||||
{ 0x1FC33F6Cu, func_1FC33F6C },
|
||||
{ 0x1FC33F80u, func_1FC33F80 },
|
||||
{ 0x1FC33F94u, func_1FC33F94 },
|
||||
{ 0x1FC33FA8u, func_1FC33FA8 },
|
||||
{ 0x1FC33FB4u, func_1FC33FB4 },
|
||||
{ 0x1FC33FCCu, func_1FC33FCC },
|
||||
{ 0x1FC33FD8u, func_1FC33FD8 },
|
||||
{ 0x1FC33FE4u, func_1FC33FE4 },
|
||||
{ 0x1FC33FF0u, func_1FC33FF0 },
|
||||
{ 0x1FC33FFCu, func_1FC33FFC },
|
||||
{ 0x1FC34008u, func_1FC34008 },
|
||||
{ 0x1FC3401Cu, func_1FC3401C },
|
||||
{ 0x1FC34028u, func_1FC34028 },
|
||||
{ 0x1FC3403Cu, func_1FC3403C },
|
||||
{ 0x1FC34054u, func_1FC34054 },
|
||||
{ 0x1FC34068u, func_1FC34068 },
|
||||
{ 0x1FC3407Cu, func_1FC3407C },
|
||||
{ 0x1FC34088u, func_1FC34088 },
|
||||
{ 0x1FC3409Cu, func_1FC3409C },
|
||||
{ 0x1FC340CCu, func_1FC340CC },
|
||||
{ 0x1FC340D8u, func_1FC340D8 },
|
||||
{ 0x1FC340E4u, func_1FC340E4 },
|
||||
{ 0x1FC34104u, func_1FC34104 },
|
||||
{ 0x1FC34110u, func_1FC34110 },
|
||||
{ 0x1FC34160u, func_1FC34160 },
|
||||
{ 0x1FC34304u, func_1FC34304 },
|
||||
{ 0x1FC344A4u, func_1FC344A4 },
|
||||
@@ -1959,15 +2088,60 @@ static const DispatchEntry dispatch_table[1087] = {
|
||||
{ 0x1FC34748u, func_1FC34748 },
|
||||
{ 0x1FC34898u, func_1FC34898 },
|
||||
{ 0x1FC348FCu, func_1FC348FC },
|
||||
{ 0x1FC34924u, func_1FC34924 },
|
||||
{ 0x1FC34928u, func_1FC34928 },
|
||||
{ 0x1FC34954u, func_1FC34954 },
|
||||
{ 0x1FC34958u, func_1FC34958 },
|
||||
{ 0x1FC34980u, func_1FC34980 },
|
||||
{ 0x1FC34984u, func_1FC34984 },
|
||||
{ 0x1FC349B8u, func_1FC349B8 },
|
||||
{ 0x1FC34A04u, func_1FC34A04 },
|
||||
{ 0x1FC34A08u, func_1FC34A08 },
|
||||
{ 0x1FC34A30u, func_1FC34A30 },
|
||||
{ 0x1FC34A34u, func_1FC34A34 },
|
||||
{ 0x1FC34A60u, func_1FC34A60 },
|
||||
{ 0x1FC34A64u, func_1FC34A64 },
|
||||
{ 0x1FC34A90u, func_1FC34A90 },
|
||||
{ 0x1FC34AA0u, func_1FC34AA0 },
|
||||
{ 0x1FC34AF0u, func_1FC34AF0 },
|
||||
{ 0x1FC34B08u, func_1FC34B08 },
|
||||
{ 0x1FC34B58u, func_1FC34B58 },
|
||||
{ 0x1FC34EC0u, func_1FC34EC0 },
|
||||
{ 0x1FC34EC4u, func_1FC34EC4 },
|
||||
{ 0x1FC35128u, func_1FC35128 },
|
||||
{ 0x1FC3524Cu, func_1FC3524C },
|
||||
{ 0x1FC35348u, func_1FC35348 },
|
||||
{ 0x1FC35470u, func_1FC35470 },
|
||||
{ 0x1FC35598u, func_1FC35598 },
|
||||
{ 0x1FC35698u, func_1FC35698 },
|
||||
{ 0x1FC357C4u, func_1FC357C4 },
|
||||
{ 0x1FC3582Cu, func_1FC3582C },
|
||||
{ 0x1FC3586Cu, func_1FC3586C },
|
||||
{ 0x1FC35890u, func_1FC35890 },
|
||||
{ 0x1FC359B4u, func_1FC359B4 },
|
||||
{ 0x1FC35AD8u, func_1FC35AD8 },
|
||||
{ 0x1FC35B08u, func_1FC35B08 },
|
||||
{ 0x1FC35B38u, func_1FC35B38 },
|
||||
{ 0x1FC35B68u, func_1FC35B68 },
|
||||
{ 0x1FC35B88u, func_1FC35B88 },
|
||||
{ 0x1FC35BC4u, func_1FC35BC4 },
|
||||
{ 0x1FC35C28u, func_1FC35C28 },
|
||||
{ 0x1FC35C60u, func_1FC35C60 },
|
||||
{ 0x1FC35CC8u, func_1FC35CC8 },
|
||||
{ 0x1FC35D10u, func_1FC35D10 },
|
||||
{ 0x1FC35D58u, func_1FC35D58 },
|
||||
{ 0x1FC35DA0u, func_1FC35DA0 },
|
||||
{ 0x1FC35DD4u, func_1FC35DD4 },
|
||||
{ 0x1FC35E30u, func_1FC35E30 },
|
||||
{ 0x1FC35E64u, func_1FC35E64 },
|
||||
{ 0x1FC35E98u, func_1FC35E98 },
|
||||
{ 0x1FC35EC0u, func_1FC35EC0 },
|
||||
{ 0x1FC35EECu, func_1FC35EEC },
|
||||
{ 0x1FC35F18u, func_1FC35F18 },
|
||||
{ 0x1FC35F38u, func_1FC35F38 },
|
||||
{ 0x1FC35F78u, func_1FC35F78 },
|
||||
{ 0x1FC35FA0u, func_1FC35FA0 },
|
||||
{ 0x1FC35FD0u, func_1FC35FD0 },
|
||||
{ 0x1FC36068u, func_1FC36068 },
|
||||
{ 0x1FC362D0u, func_1FC362D0 },
|
||||
{ 0x1FC36740u, func_1FC36740 },
|
||||
@@ -2221,7 +2395,7 @@ void psx_dispatch(CPUState* cpu, uint32_t addr) {
|
||||
for (;;) {
|
||||
cpu->pc = 0;
|
||||
uint32_t phys = normalize(addr);
|
||||
int lo = 0, hi = 1087 - 1;
|
||||
int lo = 0, hi = 1174 - 1;
|
||||
int found = 0;
|
||||
while (lo <= hi) {
|
||||
int mid = (lo + hi) / 2;
|
||||
|
||||
+3487
-13
File diff suppressed because it is too large
Load Diff
+4788
-4353
File diff suppressed because it is too large
Load Diff
@@ -444,6 +444,47 @@ static void handle_irq_state(int id, const char *json)
|
||||
dma_get_dpcr(), dma_get_dicr());
|
||||
}
|
||||
|
||||
/* GPU opcode counter — defined in gpu.c */
|
||||
extern uint32_t gpu_get_opcode_count(uint8_t op);
|
||||
|
||||
static void handle_gpu_opcodes(int id, const char *json)
|
||||
{
|
||||
(void)json;
|
||||
/* Report non-zero GP0 opcode counts */
|
||||
char buf[4096];
|
||||
int pos = snprintf(buf, sizeof(buf), "{\"id\":%d,\"ok\":true,\"opcodes\":{", id);
|
||||
int first = 1;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
uint32_t cnt = gpu_get_opcode_count((uint8_t)i);
|
||||
if (cnt > 0) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "%s\"0x%02X\":%u",
|
||||
first ? "" : ",", i, cnt);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "}}");
|
||||
send_fmt("%s", buf);
|
||||
}
|
||||
|
||||
static void handle_gte_state(int id, const char *json)
|
||||
{
|
||||
(void)json;
|
||||
if (!s_cpu) { send_err(id, "no cpu"); return; }
|
||||
char buf[2048];
|
||||
int pos = snprintf(buf, sizeof(buf), "{\"id\":%d,\"ok\":true,\"gte_ctrl\":[", id);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "%s\"0x%08X\"",
|
||||
i ? "," : "", s_cpu->gte_ctrl[i]);
|
||||
}
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "],\"gte_data\":[");
|
||||
for (int i = 0; i < 32; i++) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "%s\"0x%08X\"",
|
||||
i ? "," : "", s_cpu->gte_data[i]);
|
||||
}
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "]}");
|
||||
send_fmt("%s", buf);
|
||||
}
|
||||
|
||||
static void handle_sio_state(int id, const char *json)
|
||||
{
|
||||
(void)json;
|
||||
@@ -1254,6 +1295,8 @@ static const CmdEntry s_commands[] = {
|
||||
{ "get_snapshots", handle_get_snapshots },
|
||||
{ "screenshot", handle_screenshot },
|
||||
{ "screenshot_file", handle_screenshot_file },
|
||||
{ "gpu_opcodes", handle_gpu_opcodes },
|
||||
{ "gte_state", handle_gte_state },
|
||||
{ "quit", handle_quit },
|
||||
{ "dispatch_check", handle_dispatch_check },
|
||||
{ "dispatch_tail", handle_dispatch_tail },
|
||||
|
||||
+57
-38
@@ -440,6 +440,7 @@ static void raster_triangle(int32_t x0, int32_t y0,
|
||||
|
||||
/* Execute mono triangle (GP0 0x20-0x23) */
|
||||
static void gp0_exec_mono_tri(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t vx[3], vy[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
@@ -447,11 +448,13 @@ static void gp0_exec_mono_tri(void) {
|
||||
vx[i] += draw_offset_x;
|
||||
vy[i] += draw_offset_y;
|
||||
}
|
||||
raster_triangle(vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], color);
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_flat_triangle(vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], color);
|
||||
}
|
||||
|
||||
/* Execute mono quad (GP0 0x28-0x2B) — two triangles: (0,1,2) and (2,1,3) */
|
||||
static void gp0_exec_mono_quad(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t vx[4], vy[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -459,8 +462,9 @@ static void gp0_exec_mono_quad(void) {
|
||||
vx[i] += draw_offset_x;
|
||||
vy[i] += draw_offset_y;
|
||||
}
|
||||
raster_triangle(vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], color);
|
||||
raster_triangle(vx[2], vy[2], vx[1], vy[1], vx[3], vy[3], color);
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_flat_triangle(vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], color);
|
||||
sw_draw_flat_triangle(vx[2], vy[2], vx[1], vy[1], vx[3], vy[3], color);
|
||||
}
|
||||
|
||||
/* Execute shaded triangle (GP0 0x30-0x33) — Gouraud shaded */
|
||||
@@ -656,29 +660,20 @@ static void gp0_exec_shaded_textured_quad(void) {
|
||||
|
||||
/* Execute mono line (GP0 0x40-0x47) — Bresenham */
|
||||
static void gp0_exec_mono_line(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t x0, y0, x1, y1;
|
||||
parse_vertex(gp0_cmd_buf[1], &x0, &y0);
|
||||
parse_vertex(gp0_cmd_buf[2], &x1, &y1);
|
||||
x0 += draw_offset_x; y0 += draw_offset_y;
|
||||
x1 += draw_offset_x; y1 += draw_offset_y;
|
||||
/* Simple Bresenham */
|
||||
int32_t dx = x1 - x0, dy = y1 - y0;
|
||||
int32_t sx = dx > 0 ? 1 : -1, sy = dy > 0 ? 1 : -1;
|
||||
if (dx < 0) dx = -dx;
|
||||
if (dy < 0) dy = -dy;
|
||||
int32_t err = dx - dy;
|
||||
for (;;) {
|
||||
raster_pixel(x0, y0, color);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int32_t e2 = 2 * err;
|
||||
if (e2 > -dy) { err -= dy; x0 += sx; }
|
||||
if (e2 < dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_line(x0, y0, x1, y1, color);
|
||||
}
|
||||
|
||||
/* Execute shaded line (GP0 0x50-0x57) — flat shaded for now */
|
||||
static void gp0_exec_shaded_line(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t x0, y0, x1, y1;
|
||||
parse_vertex(gp0_cmd_buf[1], &x0, &y0);
|
||||
@@ -686,34 +681,23 @@ static void gp0_exec_shaded_line(void) {
|
||||
parse_vertex(gp0_cmd_buf[3], &x1, &y1);
|
||||
x0 += draw_offset_x; y0 += draw_offset_y;
|
||||
x1 += draw_offset_x; y1 += draw_offset_y;
|
||||
int32_t dx = x1 - x0, dy = y1 - y0;
|
||||
int32_t sx = dx > 0 ? 1 : -1, sy = dy > 0 ? 1 : -1;
|
||||
if (dx < 0) dx = -dx;
|
||||
if (dy < 0) dy = -dy;
|
||||
int32_t err = dx - dy;
|
||||
for (;;) {
|
||||
raster_pixel(x0, y0, color);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int32_t e2 = 2 * err;
|
||||
if (e2 > -dy) { err -= dy; x0 += sx; }
|
||||
if (e2 < dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_line(x0, y0, x1, y1, color);
|
||||
}
|
||||
|
||||
/* Execute mono rectangle (GP0 0x60-0x63) */
|
||||
static void gp0_exec_mono_rect(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t x0, y0;
|
||||
parse_vertex(gp0_cmd_buf[1], &x0, &y0);
|
||||
x0 += draw_offset_x; y0 += draw_offset_y;
|
||||
uint32_t w = gp0_cmd_buf[2] & 0xFFFFu;
|
||||
uint32_t h = (gp0_cmd_buf[2] >> 16) & 0xFFFFu;
|
||||
/* Clamp to PS1 max */
|
||||
int w = gp0_cmd_buf[2] & 0xFFFFu;
|
||||
int h = (gp0_cmd_buf[2] >> 16) & 0xFFFFu;
|
||||
if (w > 1023) w = 1023;
|
||||
if (h > 511) h = 511;
|
||||
for (uint32_t dy = 0; dy < h; dy++)
|
||||
for (uint32_t dx = 0; dx < w; dx++)
|
||||
raster_pixel(x0 + (int32_t)dx, y0 + (int32_t)dy, color);
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_flat_rect(x0, y0, w, h, color);
|
||||
}
|
||||
|
||||
/* Execute textured rectangle (GP0 0x64-0x67) */
|
||||
@@ -739,11 +723,13 @@ static void gp0_exec_textured_rect(void) {
|
||||
|
||||
/* Execute 1x1 dot (GP0 0x68-0x6B) */
|
||||
static void gp0_exec_mono_dot(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t x, y;
|
||||
parse_vertex(gp0_cmd_buf[1], &x, &y);
|
||||
x += draw_offset_x; y += draw_offset_y;
|
||||
raster_pixel(x, y, color);
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_flat_rect(x, y, 1, 1, color);
|
||||
}
|
||||
|
||||
/* Execute 8x8 textured sprite (GP0 0x74-0x77) */
|
||||
@@ -765,13 +751,13 @@ static void gp0_exec_textured_8x8(void) {
|
||||
|
||||
/* Execute 8x8 sprite (GP0 0x70-0x73) */
|
||||
static void gp0_exec_mono_8x8(void) {
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t x0, y0;
|
||||
parse_vertex(gp0_cmd_buf[1], &x0, &y0);
|
||||
x0 += draw_offset_x; y0 += draw_offset_y;
|
||||
for (int32_t dy = 0; dy < 8; dy++)
|
||||
for (int32_t dx = 0; dx < 8; dx++)
|
||||
raster_pixel(x0 + dx, y0 + dy, color);
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_flat_rect(x0, y0, 8, 8, color);
|
||||
}
|
||||
|
||||
/* Execute 16x16 textured sprite (GP0 0x7C-0x7F) */
|
||||
@@ -1027,9 +1013,15 @@ static int gp0_command_word_count(uint8_t opcode) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Per-opcode execution counters (exposed via gpu_get_opcode_stats) */
|
||||
static uint32_t gp0_opcode_count[256];
|
||||
|
||||
uint32_t gpu_get_opcode_count(uint8_t op) { return gp0_opcode_count[op]; }
|
||||
|
||||
/* Execute a fully-collected GP0 command */
|
||||
static void gp0_execute_command(void) {
|
||||
uint8_t opcode = (gp0_cmd_buf[0] >> 24) & 0xFF;
|
||||
gp0_opcode_count[opcode]++;
|
||||
|
||||
/* Categorize for diagnostics */
|
||||
if (opcode <= 0x01) gp0_nop_count++;
|
||||
@@ -1118,12 +1110,39 @@ static void gp0_execute_command(void) {
|
||||
case 0x68: case 0x69: case 0x6A: case 0x6B:
|
||||
gp0_exec_mono_dot();
|
||||
break;
|
||||
case 0x6C: case 0x6D: case 0x6E: case 0x6F: {
|
||||
/* 1x1 textured dot: cmd, vertex, texcoord+clut (no size word) */
|
||||
uint32_t color24 = gp0_cmd_buf[0] & 0xFFFFFFu;
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
int32_t x0, y0;
|
||||
parse_vertex(gp0_cmd_buf[1], &x0, &y0);
|
||||
x0 += draw_offset_x; y0 += draw_offset_y;
|
||||
int u0 = gp0_cmd_buf[2] & 0xFF;
|
||||
int v0 = (gp0_cmd_buf[2] >> 8) & 0xFF;
|
||||
uint16_t clut = (uint16_t)(gp0_cmd_buf[2] >> 16);
|
||||
uint16_t clut_x = (clut & 0x3F) * 16;
|
||||
uint16_t clut_y = (clut >> 6) & 0x1FF;
|
||||
setup_textured_draw(color24, semi_trans);
|
||||
sw_draw_textured_rect(x0, y0, 1, 1, u0, v0, clut_x, clut_y, current_texpage());
|
||||
break;
|
||||
}
|
||||
case 0x70: case 0x71: case 0x72: case 0x73:
|
||||
gp0_exec_mono_8x8();
|
||||
break;
|
||||
case 0x74: case 0x75: case 0x76: case 0x77:
|
||||
gp0_exec_textured_8x8();
|
||||
break;
|
||||
case 0x78: case 0x79: case 0x7A: case 0x7B: {
|
||||
/* 16x16 mono sprite */
|
||||
int semi_trans = (gp0_cmd_buf[0] >> 25) & 1;
|
||||
uint16_t color = rgb888_to_rgb555(gp0_cmd_buf[0] & 0xFFFFFFu);
|
||||
int32_t x0, y0;
|
||||
parse_vertex(gp0_cmd_buf[1], &x0, &y0);
|
||||
x0 += draw_offset_x; y0 += draw_offset_y;
|
||||
sw_set_semi_transparency(semi_trans, (int)semi_transparency);
|
||||
sw_draw_flat_rect(x0, y0, 16, 16, color);
|
||||
break;
|
||||
}
|
||||
case 0x7C: case 0x7D: case 0x7E: case 0x7F:
|
||||
gp0_exec_textured_16x16();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user