aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/main.c1
-rw-r--r--frontend/menu.c32
-rw-r--r--frontend/plugin_lib.h3
-rw-r--r--plugins/gpu_neon/gpu.c69
-rw-r--r--plugins/gpu_neon/gpu.h11
-rw-r--r--plugins/gpu_neon/peops_if.c4
-rw-r--r--plugins/gpu_neon/psx_gpu_if.c9
-rw-r--r--plugins/gpu_neon/test.c2
-rw-r--r--plugins/gpu_neon/unai_if.cpp4
-rw-r--r--plugins/gpu_neon/vout_fb.c29
-rw-r--r--plugins/gpu_neon/vout_sdl.c23
11 files changed, 127 insertions, 60 deletions
diff --git a/frontend/main.c b/frontend/main.c
index fd4674b..7b3aac5 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -150,6 +150,7 @@ void emu_set_default_config(void)
pl_rearmed_cbs.gpu_unai.abe_hack =
pl_rearmed_cbs.gpu_unai.no_light =
pl_rearmed_cbs.gpu_unai.no_blend = 0;
+ pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto
iUseReverb = 2;
iUseInterpolation = 1;
diff --git a/frontend/menu.c b/frontend/menu.c
index ce5c3eb..c6a52de 100644
--- a/frontend/menu.c
+++ b/frontend/menu.c
@@ -290,6 +290,7 @@ static const struct {
CE_INTVAL_P(gpu_unai.abe_hack),
CE_INTVAL_P(gpu_unai.no_light),
CE_INTVAL_P(gpu_unai.no_blend),
+ CE_INTVAL_P(gpu_neon.allow_interlace),
CE_INTVAL_V(iUseReverb, 3),
CE_INTVAL_V(iXAPitch, 3),
CE_INTVAL_V(iUseInterpolation, 3),
@@ -1193,6 +1194,26 @@ static int menu_loop_gfx_options(int id, int keys)
// ------------ bios/plugins ------------
+#ifdef __ARM_NEON__
+
+static const char h_gpu_neon[] = "Configure built-in NEON GPU plugin";
+static const char *men_gpu_interlace[] = { "Off", "On", "Auto", NULL };
+
+static menu_entry e_menu_plugin_gpu_neon[] =
+{
+ mee_enum ("Enable interlace mode", 0, pl_rearmed_cbs.gpu_neon.allow_interlace, men_gpu_interlace),
+ mee_end,
+};
+
+static int menu_loop_plugin_gpu_neon(int id, int keys)
+{
+ int sel = 0;
+ me_loop(e_menu_plugin_gpu_neon, &sel);
+ return 0;
+}
+
+#endif
+
static menu_entry e_menu_plugin_gpu_unai[] =
{
mee_onoff ("Skip every 2nd line", 0, pl_rearmed_cbs.gpu_unai.lineskip, 1),
@@ -1210,12 +1231,12 @@ static int menu_loop_plugin_gpu_unai(int id, int keys)
}
static const char *men_gpu_dithering[] = { "None", "Game dependant", "Always", NULL };
-static const char h_gpu_0[] = "Needed for Chrono Cross";
+//static const char h_gpu_0[] = "Needed for Chrono Cross";
static const char h_gpu_1[] = "Capcom fighting games";
static const char h_gpu_2[] = "Black screens in Lunar";
static const char h_gpu_3[] = "Compatibility mode";
static const char h_gpu_6[] = "Pandemonium 2";
-static const char h_gpu_7[] = "Skip every second frame";
+//static const char h_gpu_7[] = "Skip every second frame";
static const char h_gpu_8[] = "Needed by Dark Forces";
static const char h_gpu_9[] = "better g-colors, worse textures";
static const char h_gpu_10[] = "Toggle busy flags after drawing";
@@ -1223,12 +1244,12 @@ static const char h_gpu_10[] = "Toggle busy flags after drawing";
static menu_entry e_menu_plugin_gpu_peops[] =
{
mee_enum ("Dithering", 0, pl_rearmed_cbs.gpu_peops.iUseDither, men_gpu_dithering),
- mee_onoff_h ("Odd/even bit hack", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<0, h_gpu_0),
+// mee_onoff_h ("Odd/even bit hack", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<0, h_gpu_0),
mee_onoff_h ("Expand screen width", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<1, h_gpu_1),
mee_onoff_h ("Ignore brightness color", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<2, h_gpu_2),
mee_onoff_h ("Disable coordinate check", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<3, h_gpu_3),
mee_onoff_h ("Lazy screen update", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<6, h_gpu_6),
- mee_onoff_h ("Old frame skipping", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<7, h_gpu_7),
+// mee_onoff_h ("Old frame skipping", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<7, h_gpu_7),
mee_onoff_h ("Repeated flat tex triangles ",0,pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<8, h_gpu_8),
mee_onoff_h ("Draw quads with triangles", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<9, h_gpu_9),
mee_onoff_h ("Fake 'gpu busy' states", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<10, h_gpu_10),
@@ -1279,6 +1300,9 @@ static menu_entry e_menu_plugin_options[] =
mee_enum_h ("BIOS", 0, bios_sel, bioses, h_bios),
mee_enum_h ("GPU plugin", 0, gpu_plugsel, gpu_plugins, h_plugin_xpu),
mee_enum_h ("SPU plugin", 0, spu_plugsel, spu_plugins, h_plugin_xpu),
+#ifdef __ARM_NEON__
+ mee_handler_h ("Configure built-in GPU plugin", menu_loop_plugin_gpu_neon, h_gpu_neon),
+#endif
mee_handler_h ("Configure gpu_peops plugin", menu_loop_plugin_gpu_peops, h_gpu_peops),
mee_handler_h ("Configure PCSX4ALL GPU plugin", menu_loop_plugin_gpu_unai, h_gpu_unai),
mee_handler_h ("Configure built-in SPU plugin", menu_loop_plugin_spu, h_spu),
diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h
index 2806056..44c5630 100644
--- a/frontend/plugin_lib.h
+++ b/frontend/plugin_lib.h
@@ -61,6 +61,9 @@ struct rearmed_cbs {
int no_light, no_blend;
int lineskip;
} gpu_unai;
+ struct {
+ int allow_interlace; // 0 off, 1 on, 2 guess
+ } gpu_neon;
};
extern struct rearmed_cbs pl_rearmed_cbs;
diff --git a/plugins/gpu_neon/gpu.c b/plugins/gpu_neon/gpu.c
index 02dd372..339cdfd 100644
--- a/plugins/gpu_neon/gpu.c
+++ b/plugins/gpu_neon/gpu.c
@@ -29,6 +29,7 @@ struct psx_gpu gpu __attribute__((aligned(2048)));
static noinline void do_reset(void)
{
memset(gpu.regs, 0, sizeof(gpu.regs));
+ memset(gpu.ex_regs, 0, sizeof(gpu.ex_regs));
gpu.status.reg = 0x14802000;
gpu.gp0 = 0;
gpu.regs[3] = 1;
@@ -264,10 +265,10 @@ static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
if (gpu.dma.h)
log_anomaly("start_vram_transfer while old unfinished\n");
- gpu.dma.x = pos_word & 1023;
- gpu.dma.y = (pos_word >> 16) & 511;
- gpu.dma.w = size_word & 0xffff; // ?
- gpu.dma.h = size_word >> 16;
+ gpu.dma.x = pos_word & 0x3ff;
+ gpu.dma.y = (pos_word >> 16) & 0x1ff;
+ gpu.dma.w = size_word & 0x3ff;
+ gpu.dma.h = (size_word >> 16) & 0x1ff;
gpu.dma.offset = 0;
renderer_flush_queues();
@@ -275,6 +276,7 @@ static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
gpu.status.img = 1;
// XXX: wrong for width 1
memcpy(&gpu.gp0, VRAM_MEM_XY(gpu.dma.x, gpu.dma.y), 4);
+ gpu.state.last_vram_read_frame = *gpu.state.frame_count;
}
else {
renderer_invalidate_caches(gpu.dma.x, gpu.dma.y, gpu.dma.w, gpu.dma.h);
@@ -362,7 +364,7 @@ static int check_cmd(uint32_t *data, int count)
return count - pos;
}
-void flush_cmd_buffer(void)
+static void flush_cmd_buffer(void)
{
int left = check_cmd(gpu.cmd_buffer, gpu.cmd_len);
if (left > 0)
@@ -533,8 +535,65 @@ long GPUfreeze(uint32_t type, struct GPUFreeze *freeze)
return 1;
}
+void GPUupdateLace(void)
+{
+ if (gpu.cmd_len > 0)
+ flush_cmd_buffer();
+ renderer_flush_queues();
+
+ if (gpu.status.blanking || !gpu.state.fb_dirty)
+ return;
+
+ if (gpu.frameskip.set) {
+ if (!gpu.frameskip.frame_ready) {
+ if (*gpu.state.frame_count - gpu.frameskip.last_flip_frame < 9)
+ return;
+ gpu.frameskip.active = 0;
+ }
+ gpu.frameskip.frame_ready = 0;
+ }
+
+ vout_update();
+ gpu.state.fb_dirty = 0;
+}
+
void GPUvBlank(int is_vblank, int lcf)
{
+ int interlace = gpu.state.allow_interlace
+ && gpu.status.interlace && gpu.status.dheight;
+ // interlace doesn't look nice on progressive displays,
+ // so we have this "auto" mode here for games that don't read vram
+ if (gpu.state.allow_interlace == 2
+ && *gpu.state.frame_count - gpu.state.last_vram_read_frame > 1)
+ {
+ interlace = 0;
+ }
+ if (interlace || interlace != gpu.state.old_interlace) {
+ gpu.state.old_interlace = interlace;
+
+ if (gpu.cmd_len > 0)
+ flush_cmd_buffer();
+ renderer_flush_queues();
+ renderer_set_interlace(interlace, !lcf);
+ }
+}
+
+#include "../../frontend/plugin_lib.h"
+
+void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
+{
+ gpu.frameskip.set = cbs->frameskip;
+ gpu.frameskip.advice = &cbs->fskip_advice;
+ gpu.frameskip.active = 0;
+ gpu.frameskip.frame_ready = 1;
+ gpu.state.hcnt = cbs->gpu_hcnt;
+ gpu.state.frame_count = cbs->gpu_frame_count;
+ gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace;
+
+ if (cbs->pl_vout_set_raw_vram)
+ cbs->pl_vout_set_raw_vram(gpu.vram);
+ renderer_set_config(cbs);
+ vout_set_config(cbs);
}
// vim:shiftwidth=2:expandtab
diff --git a/plugins/gpu_neon/gpu.h b/plugins/gpu_neon/gpu.h
index 6aa933e..36fdef8 100644
--- a/plugins/gpu_neon/gpu.h
+++ b/plugins/gpu_neon/gpu.h
@@ -64,6 +64,8 @@ struct psx_gpu {
uint32_t zero;
struct {
uint32_t fb_dirty:1;
+ uint32_t old_interlace:1;
+ uint32_t allow_interlace:2;
uint32_t *frame_count;
uint32_t *hcnt; /* hsync count */
struct {
@@ -72,6 +74,7 @@ struct psx_gpu {
uint32_t frame;
uint32_t hcnt;
} last_list;
+ uint32_t last_vram_read_frame;
} state;
struct {
int32_t set:3; /* -1 auto, 0 off, 1-3 fixed */
@@ -87,7 +90,6 @@ struct psx_gpu {
extern struct psx_gpu gpu;
extern const unsigned char cmd_lengths[256];
-void flush_cmd_buffer(void);
void do_cmd_list(uint32_t *list, int count);
@@ -97,10 +99,13 @@ int renderer_init(void);
void renderer_sync_ecmds(uint32_t * ecmds);
void renderer_invalidate_caches(int x, int y, int w, int h);
void renderer_flush_queues(void);
+void renderer_set_interlace(int enable, int is_odd);
void renderer_set_config(const struct rearmed_cbs *config);
-int vout_init(void);
-int vout_finish(void);
+int vout_init(void);
+int vout_finish(void);
+void vout_update(void);
+void vout_set_config(const struct rearmed_cbs *config);
/* listing these here for correct linkage if rasterizer uses c++ */
struct GPUFreeze;
diff --git a/plugins/gpu_neon/peops_if.c b/plugins/gpu_neon/peops_if.c
index 48fd431..2e967f2 100644
--- a/plugins/gpu_neon/peops_if.c
+++ b/plugins/gpu_neon/peops_if.c
@@ -385,6 +385,10 @@ void renderer_flush_queues(void)
{
}
+void renderer_set_interlace(int enable, int is_odd)
+{
+}
+
#include "../../frontend/plugin_lib.h"
void renderer_set_config(const struct rearmed_cbs *cbs)
diff --git a/plugins/gpu_neon/psx_gpu_if.c b/plugins/gpu_neon/psx_gpu_if.c
index 8907ac0..470f68e 100644
--- a/plugins/gpu_neon/psx_gpu_if.c
+++ b/plugins/gpu_neon/psx_gpu_if.c
@@ -48,6 +48,15 @@ void renderer_flush_queues(void)
flush_render_block_buffer(&egpu);
}
+void renderer_set_interlace(int enable, int is_odd)
+{
+ egpu.interlace_mode &= ~(RENDER_INTERLACE_ENABLED|RENDER_INTERLACE_ODD);
+ if (enable)
+ egpu.interlace_mode |= RENDER_INTERLACE_ENABLED;
+ if (is_odd)
+ egpu.interlace_mode |= RENDER_INTERLACE_ODD;
+}
+
void renderer_set_config(const struct rearmed_cbs *cbs)
{
}
diff --git a/plugins/gpu_neon/test.c b/plugins/gpu_neon/test.c
index be271b6..e523e20 100644
--- a/plugins/gpu_neon/test.c
+++ b/plugins/gpu_neon/test.c
@@ -89,6 +89,8 @@ int main(int argc, char *argv[])
pcnt_init();
renderer_init();
memcpy(gpu.vram, state.vram, sizeof(gpu.vram));
+ if ((state.gpu_register[8] & 0x24) == 0x24)
+ renderer_set_interlace(1, !(state.status >> 31));
start_cycles = pcnt_get();
diff --git a/plugins/gpu_neon/unai_if.cpp b/plugins/gpu_neon/unai_if.cpp
index 4e3e7f9..072993a 100644
--- a/plugins/gpu_neon/unai_if.cpp
+++ b/plugins/gpu_neon/unai_if.cpp
@@ -272,6 +272,10 @@ void renderer_flush_queues(void)
{
}
+void renderer_set_interlace(int enable, int is_odd)
+{
+}
+
#ifndef TEST
#include "../../frontend/plugin_lib.h"
diff --git a/plugins/gpu_neon/vout_fb.c b/plugins/gpu_neon/vout_fb.c
index a45b5f1..20c8ff3 100644
--- a/plugins/gpu_neon/vout_fb.c
+++ b/plugins/gpu_neon/vout_fb.c
@@ -88,28 +88,13 @@ static void blit(void)
screen_buf = cbs->pl_vout_flip();
}
-void GPUupdateLace(void)
+void vout_update(void)
{
- if (gpu.status.blanking || !gpu.state.fb_dirty)
- return;
-
- if (gpu.frameskip.set) {
- if (!gpu.frameskip.frame_ready) {
- if (*gpu.state.frame_count - gpu.frameskip.last_flip_frame < 9)
- return;
- }
- gpu.frameskip.frame_ready = 0;
- }
-
- if (gpu.cmd_len > 0)
- flush_cmd_buffer();
- renderer_flush_queues();
check_mode_change();
if (cbs->pl_vout_raw_flip)
cbs->pl_vout_raw_flip(gpu.screen.x, gpu.screen.y);
else
blit();
- gpu.state.fb_dirty = 0;
}
long GPUopen(void **unused)
@@ -128,19 +113,9 @@ long GPUclose(void)
return 0;
}
-void GPUrearmedCallbacks(const struct rearmed_cbs *cbs_)
+void vout_set_config(const struct rearmed_cbs *cbs_)
{
cbs = cbs_;
- gpu.frameskip.set = cbs->frameskip;
- gpu.frameskip.advice = &cbs->fskip_advice;
- gpu.frameskip.active = 0;
- gpu.frameskip.frame_ready = 1;
- gpu.state.hcnt = cbs->gpu_hcnt;
- gpu.state.frame_count = cbs->gpu_frame_count;
-
- if (cbs->pl_vout_set_raw_vram)
- cbs->pl_vout_set_raw_vram(gpu.vram);
- renderer_set_config(cbs_);
}
// vim:shiftwidth=2:expandtab
diff --git a/plugins/gpu_neon/vout_sdl.c b/plugins/gpu_neon/vout_sdl.c
index 0830c56..db1ae96 100644
--- a/plugins/gpu_neon/vout_sdl.c
+++ b/plugins/gpu_neon/vout_sdl.c
@@ -48,7 +48,7 @@ int vout_finish(void)
return 0;
}
-static void blit(void)
+void vout_update(void)
{
uint32_t *d;
int i;
@@ -77,17 +77,6 @@ static void blit(void)
SDL_UpdateRect(screen, 0, 0, 1024, 512);
}
-void GPUupdateLace(void)
-{
- if (!gpu.status.blanking && gpu.state.fb_dirty) {
- if (gpu.cmd_len > 0)
- flush_cmd_buffer();
- renderer_flush_queues();
- blit();
- gpu.state.fb_dirty = 0;
- }
-}
-
long GPUopen(void **dpy)
{
*dpy = x11_display;
@@ -99,16 +88,8 @@ long GPUclose(void)
return 0;
}
-#include "../../frontend/plugin_lib.h"
-
-void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
+void vout_set_config(const struct rearmed_cbs *cbs)
{
- gpu.state.hcnt = cbs->gpu_hcnt;
- gpu.state.frame_count = cbs->gpu_frame_count;
-
- if (cbs->pl_vout_set_raw_vram)
- cbs->pl_vout_set_raw_vram(gpu.vram);
- renderer_set_config(cbs);
}
// vim:shiftwidth=2:expandtab