ref: 61f58168b98ed956dc1adde1272fae68e9c63aa3
parent: feef8a15f6a77f611d0dfd88bbfdbb3447232b54
author: allkern <lisandroaalarcon@gmail.com>
date: Thu Apr 25 20:13:23 EDT 2024
Compatibility improvements
--- a/frontend/config.c
+++ b/frontend/config.c
@@ -83,6 +83,7 @@
cfg->help_model = 0;
cfg->help_region = 0;
cfg->model = "scph1001";
+ cfg->scale = 3;
cfg->psxe_version = STR(REP_VERSION);
cfg->region = "ntsc";
cfg->settings_path = NULL;
@@ -104,6 +105,7 @@
int log_level = 0;
int quiet = 0;
int console_source = 0;
+ int scale = 0;
const char* settings_path = NULL;
const char* bios = NULL;
const char* bios_search = NULL;
@@ -133,6 +135,7 @@
OPT_INTEGER ('L', "log-level" , &log_level , "Set log level"),
OPT_STRING ('M', "model" , &model , "Specify console model (SPCH-XXXX)", NULL, 0, 0),
OPT_STRING ('r', "region" , ®ion , "Specify console region"),
+ OPT_INTEGER ('s', "scale" , &scale , "Display scaling factor", NULL, 0, 0),
OPT_STRING ('S', "settings-file" , &settings_path , "Specify settings file path", NULL, 0, 0),
OPT_BOOLEAN ('q', "quiet" , &quiet , "Silence all logs (ignores -L)"),
OPT_STRING ('x', "exe" , &exe , "Launch a PS-X EXE file"),
@@ -280,6 +283,9 @@
if (exp_path)
cfg->exp_path = exp_path;
+
+ if (scale)
+ cfg->scale = scale;
}
// To-do: Implement BIOS searching
--- a/frontend/config.h
+++ b/frontend/config.h
@@ -15,6 +15,7 @@
int log_level;
int quiet;
int console_source;
+ int scale;
const char* snap_path;
const char* settings_path;
const char* bios;
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -43,7 +43,7 @@
psxe_screen_t* screen = psxe_screen_create();
psxe_screen_init(screen, psx);
- psxe_screen_set_scale(screen, 3);
+ psxe_screen_set_scale(screen, cfg->scale);
psxe_screen_reload(screen);
SDL_Init(SDL_INIT_AUDIO);
--- a/psx/cpu.c
+++ b/psx/cpu.c
@@ -1795,6 +1795,66 @@
R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
R_IR3 = gte_clamp_ir_z(cpu, cpu->s_mac3, cpu->gte_sf, cpu->gte_lm); }
+#define NCS(i) { \
+ R_FLAG = 0; \
+ int64_t vx = (int64_t)((int16_t)cpu->cop2_dr.v[i].p[0]); \
+ int64_t vy = (int64_t)((int16_t)cpu->cop2_dr.v[i].p[1]); \
+ int64_t vz = (int64_t)cpu->cop2_dr.v[i].z; \
+ R_MAC1 = (int)(gte_clamp_mac(cpu, 1, (int64_t)R_L11 * vx + R_L12 * vy + R_L13 * vz)); \
+ R_MAC2 = (int)(gte_clamp_mac(cpu, 2, (int64_t)R_L21 * vx + R_L22 * vy + R_L23 * vz)); \
+ R_MAC3 = (int)(gte_clamp_mac(cpu, 3, (int64_t)R_L31 * vx + R_L32 * vy + R_L33 * vz)); \
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
+ R_IR3 = gte_clamp_ir_z(cpu, cpu->s_mac3, cpu->gte_sf, cpu->gte_lm); \
+ R_MAC1 = (int)(gte_clamp_mac(cpu, 1, gte_clamp_mac(cpu, 1, gte_clamp_mac(cpu, 1, (long)R_RBK * 0x1000 + R_LR1 * R_IR1) + (long)R_LG1 * R_IR2) + (long)R_LB1 * R_IR3)); \
+ R_MAC2 = (int)(gte_clamp_mac(cpu, 2, gte_clamp_mac(cpu, 2, gte_clamp_mac(cpu, 2, (long)R_GBK * 0x1000 + R_LR2 * R_IR1) + (long)R_LG2 * R_IR2) + (long)R_LB2 * R_IR3)); \
+ R_MAC3 = (int)(gte_clamp_mac(cpu, 3, gte_clamp_mac(cpu, 3, gte_clamp_mac(cpu, 3, (long)R_BBK * 0x1000 + R_LR3 * R_IR1) + (long)R_LG3 * R_IR2) + (long)R_LB3 * R_IR3)); \
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
+ R_IR3 = gte_clamp_ir_z(cpu, cpu->s_mac3, cpu->gte_sf, cpu->gte_lm); \
+ R_RGB0 = R_RGB1; \
+ R_RGB1 = R_RGB2; \
+ R_CD2 = R_CODE; \
+ R_RC2 = gte_clamp_rgb(cpu, 1, R_MAC1 >> 4); \
+ R_GC2 = gte_clamp_rgb(cpu, 2, R_MAC2 >> 4); \
+ R_BC2 = gte_clamp_rgb(cpu, 3, R_MAC3 >> 4); \
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
+ R_IR3 = gte_clamp_ir_z(cpu, cpu->s_mac3, cpu->gte_sf, cpu->gte_lm); }
+
+#define NCDS(i) { \
+ R_FLAG = 0; \
+ int64_t vx = (int64_t)((int16_t)cpu->cop2_dr.v[i].p[0]); \
+ int64_t vy = (int64_t)((int16_t)cpu->cop2_dr.v[i].p[1]); \
+ int64_t vz = (int64_t)cpu->cop2_dr.v[i].z; \
+ R_MAC1 = gte_clamp_mac(cpu, 1, (I64(R_L11) * vx) + (I64(R_L12) * vy) + (I64(R_L13) * vz)); \
+ R_MAC2 = gte_clamp_mac(cpu, 2, (I64(R_L21) * vx) + (I64(R_L22) * vy) + (I64(R_L23) * vz)); \
+ R_MAC3 = gte_clamp_mac(cpu, 3, (I64(R_L31) * vx) + (I64(R_L32) * vy) + (I64(R_L33) * vz)); \
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
+ R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm); \
+ R_MAC1 = gte_clamp_mac(cpu, 1, (I64(R_RBK) << 12) + (I64(R_LR1) * I64(R_IR1)) + (I64(R_LR2) * I64(R_IR2)) + (I64(R_LR3) * I64(R_IR3))); \
+ R_MAC2 = gte_clamp_mac(cpu, 2, (I64(R_GBK) << 12) + (I64(R_LG1) * I64(R_IR1)) + (I64(R_LG2) * I64(R_IR2)) + (I64(R_LG3) * I64(R_IR3))); \
+ R_MAC3 = gte_clamp_mac(cpu, 3, (I64(R_BBK) << 12) + (I64(R_LB1) * I64(R_IR1)) + (I64(R_LB2) * I64(R_IR2)) + (I64(R_LB3) * I64(R_IR3))); \
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
+ R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm); \
+ int64_t ir1 = gte_clamp_ir(cpu, 1, gte_clamp_mac(cpu, 1, ((I64(R_RFC) << 12) - ((I64(R_RC << 4)) * I64(R_IR1)))), 0); \
+ int64_t ir2 = gte_clamp_ir(cpu, 2, gte_clamp_mac(cpu, 2, ((I64(R_GFC) << 12) - ((I64(R_GC << 4)) * I64(R_IR2)))), 0); \
+ int64_t ir3 = gte_clamp_ir(cpu, 3, gte_clamp_mac(cpu, 3, ((I64(R_BFC) << 12) - ((I64(R_BC << 4)) * I64(R_IR3)))), 0); \
+ R_MAC1 = gte_clamp_mac(cpu, 1, ((I64(R_RC << 4)) * I64(R_IR1)) + (I64(R_IR0) * ir1)); \
+ R_MAC2 = gte_clamp_mac(cpu, 2, ((I64(R_GC << 4)) * I64(R_IR2)) + (I64(R_IR0) * ir2)); \
+ R_MAC3 = gte_clamp_mac(cpu, 3, ((I64(R_BC << 4)) * I64(R_IR3)) + (I64(R_IR0) * ir3)); \
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \
+ R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm); \
+ R_RGB0 = R_RGB1; \
+ R_RGB1 = R_RGB2; \
+ R_CD2 = R_CODE; \
+ R_RC2 = gte_clamp_rgb(cpu, 1, R_MAC1 >> 4); \
+ R_GC2 = gte_clamp_rgb(cpu, 2, R_MAC2 >> 4); \
+ R_BC2 = gte_clamp_rgb(cpu, 3, R_MAC3 >> 4); }
+
void psx_gte_i_rtps(psx_cpu_t* cpu) {
GTE_RTP_DQ(0);
}
@@ -1984,47 +2044,7 @@
// To-do: Fix flags
void psx_gte_i_ncds(psx_cpu_t* cpu) {
- R_FLAG = 0;
-
- int64_t vx = (int64_t)((int16_t)cpu->cop2_dr.v[0].p[0]);
- int64_t vy = (int64_t)((int16_t)cpu->cop2_dr.v[0].p[1]);
- int64_t vz = (int64_t)cpu->cop2_dr.v[0].z;
-
- R_MAC1 = gte_clamp_mac(cpu, 1, (I64(R_L11) * vx) + (I64(R_L12) * vy) + (I64(R_L13) * vz));
- R_MAC2 = gte_clamp_mac(cpu, 2, (I64(R_L21) * vx) + (I64(R_L22) * vy) + (I64(R_L23) * vz));
- R_MAC3 = gte_clamp_mac(cpu, 3, (I64(R_L31) * vx) + (I64(R_L32) * vy) + (I64(R_L33) * vz));
-
- R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm);
- R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm);
- R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm);
-
- R_MAC1 = gte_clamp_mac(cpu, 1, (I64(R_RBK) << 12) + (I64(R_LR1) * I64(R_IR1)) + (I64(R_LR2) * I64(R_IR2)) + (I64(R_LR3) * I64(R_IR3)));
- R_MAC2 = gte_clamp_mac(cpu, 2, (I64(R_GBK) << 12) + (I64(R_LG1) * I64(R_IR1)) + (I64(R_LG2) * I64(R_IR2)) + (I64(R_LG3) * I64(R_IR3)));
- R_MAC3 = gte_clamp_mac(cpu, 3, (I64(R_BBK) << 12) + (I64(R_LB1) * I64(R_IR1)) + (I64(R_LB2) * I64(R_IR2)) + (I64(R_LB3) * I64(R_IR3)));
-
- R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm);
- R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm);
- R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm);
-
- int64_t ir1 = gte_clamp_ir(cpu, 1, gte_clamp_mac(cpu, 1, ((I64(R_RFC) << 12) - ((I64(R_RC << 4)) * I64(R_IR1)))), 0);
- int64_t ir2 = gte_clamp_ir(cpu, 2, gte_clamp_mac(cpu, 2, ((I64(R_GFC) << 12) - ((I64(R_GC << 4)) * I64(R_IR2)))), 0);
- int64_t ir3 = gte_clamp_ir(cpu, 3, gte_clamp_mac(cpu, 3, ((I64(R_BFC) << 12) - ((I64(R_BC << 4)) * I64(R_IR3)))), 0);
-
- R_MAC1 = gte_clamp_mac(cpu, 1, ((I64(R_RC << 4)) * I64(R_IR1)) + (I64(R_IR0) * ir1));
- R_MAC2 = gte_clamp_mac(cpu, 2, ((I64(R_GC << 4)) * I64(R_IR2)) + (I64(R_IR0) * ir2));
- R_MAC3 = gte_clamp_mac(cpu, 3, ((I64(R_BC << 4)) * I64(R_IR3)) + (I64(R_IR0) * ir3));
-
- R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm);
- R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm);
- R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm);
-
- R_RGB0 = R_RGB1;
- R_RGB1 = R_RGB2;
- R_CD2 = R_CODE;
-
- R_RC2 = gte_clamp_rgb(cpu, 1, R_MAC1 >> 4);
- R_GC2 = gte_clamp_rgb(cpu, 2, R_MAC2 >> 4);
- R_BC2 = gte_clamp_rgb(cpu, 3, R_MAC3 >> 4);
+ NCDS(0);
}
void psx_gte_i_cdp(psx_cpu_t* cpu) {
@@ -2032,7 +2052,9 @@
}
void psx_gte_i_ncdt(psx_cpu_t* cpu) {
- printf("ncdt: Unimplemented GTE instruction\n");
+ NCDS(0);
+ NCDS(1);
+ NCDS(2);
}
void psx_gte_i_nccs(psx_cpu_t* cpu) {
@@ -2040,15 +2062,17 @@
}
void psx_gte_i_cc(psx_cpu_t* cpu) {
- printf("cc: Unimplemented GTE instruction\n");
+ NCS(0); // Hack
}
void psx_gte_i_ncs(psx_cpu_t* cpu) {
- printf("ncs: Unimplemented GTE instruction\n");
+ NCS(0);
}
void psx_gte_i_nct(psx_cpu_t* cpu) {
- printf("nct: Unimplemented GTE instruction\n");
+ NCS(0);
+ NCS(1);
+ NCS(2);
}
void psx_gte_i_sqr(psx_cpu_t* cpu) {
@@ -2174,4 +2198,4 @@
#undef DEBUG_ALL
#undef SE8
-#undef SE16
+#undef SE16
\ No newline at end of file
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -231,15 +231,15 @@
void cdrom_cmd_getstat(psx_cdrom_t* cdrom) {
switch (cdrom->state) {
case CD_STATE_RECV_CMD: {
- if (cdrom->ongoing_read_command) {
- cdrom->status |= STAT_BUSYSTS_MASK;
- // printf("command=%02x\n", cdrom->ongoing_read_command);
- cdrom->state = CD_STATE_SEND_RESP2;
- cdrom->delayed_command = cdrom->ongoing_read_command;
- cdrom->irq_delay = DELAY_1MS;
+ // if (cdrom->ongoing_read_command) {
+ // cdrom->status |= STAT_BUSYSTS_MASK;
+ // // printf("command=%02x\n", cdrom->ongoing_read_command);
+ // cdrom->state = CD_STATE_SEND_RESP2;
+ // cdrom->delayed_command = cdrom->ongoing_read_command;
+ // cdrom->irq_delay = DELAY_1MS;
- return;
- }
+ // return;
+ // }
if (cdrom->pfifo_index) {
log_fatal("CdlGetStat: Expected exactly 0 parameters");
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -349,10 +349,15 @@
}
}
+#define CLAMP(v, d, u) ((v) < (d)) ? (d) : (((v) >= (u)) ? (u) : (v))
+
void gpu_render_rect(psx_gpu_t* gpu, rect_data_t data) {
if ((data.v0.x >= 1024) || (data.v0.y >= 512))
return;
+ if ((data.v0.x <= -1024) || (data.v0.y <= -512))
+ return;
+
uint16_t width, height;
switch ((data.attrib >> 3) & 3) {
@@ -376,6 +381,11 @@
/* Calculate bounding box */
int xmax = data.v0.x + width;
int ymax = data.v0.y + height;
+
+ xmax = CLAMP(xmax, -1024, 1024);
+ ymax = CLAMP(ymax, -1024, 1024);
+ data.v0.x = CLAMP(data.v0.x, -1024, 1024);
+ data.v0.y = CLAMP(data.v0.y, -1024, 1024);
int32_t xc = 0, yc = 0;
--
⑨