aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortwinaphex2013-01-10 03:06:17 +0100
committertwinaphex2013-01-10 03:06:17 +0100
commite5f4d90401d099d5191f95e9f771ab5a81c87ed8 (patch)
tree8de3efcfd7bf5111ea62a43ecd7db558f2ec8350
parentac7b2a33ddb2392582c50d29c772e9e99cd762c9 (diff)
parentd77e74383a9134e51c31607cfddf4dcd3535a0ae (diff)
downloadpcsx_rearmed-e5f4d90401d099d5191f95e9f771ab5a81c87ed8.tar.gz
pcsx_rearmed-e5f4d90401d099d5191f95e9f771ab5a81c87ed8.tar.bz2
pcsx_rearmed-e5f4d90401d099d5191f95e9f771ab5a81c87ed8.zip
Merge git://github.com/notaz/pcsx_rearmed
m---------frontend/libpicofe0
-rw-r--r--frontend/main.c13
-rw-r--r--frontend/main.h2
-rw-r--r--frontend/menu.c182
-rw-r--r--frontend/plugin_lib.c20
-rw-r--r--libpcsxcore/new_dynarec/emu_if.c2
-rw-r--r--libpcsxcore/new_dynarec/pcsxmem.c14
-rw-r--r--libpcsxcore/new_dynarec/pcsxmem.h1
-rw-r--r--libpcsxcore/psxhw.c4
-rw-r--r--plugins/dfsound/spu.c67
-rw-r--r--plugins/dfxvideo/gpulib_if.c15
-rw-r--r--plugins/gpu-gles/gpulib_if.c15
-rw-r--r--plugins/gpu_neon/psx_gpu/psx_gpu_parse.c22
-rw-r--r--plugins/gpu_unai/gpulib_if.cpp12
-rw-r--r--plugins/gpulib/gpu.c71
-rw-r--r--plugins/gpulib/vout_pl.c1
-rw-r--r--readme.txt9
17 files changed, 343 insertions, 107 deletions
diff --git a/frontend/libpicofe b/frontend/libpicofe
-Subproject 0d645bc539fdc073f20c4dea9f4a4e218cebec0
+Subproject 4db02226eb3c80f49f5c412f7718c437c5e817f
diff --git a/frontend/main.c b/frontend/main.c
index c8841b9..43a1a03 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -48,7 +48,7 @@ extern int iUseInterpolation;
extern int iXAPitch;
extern int iVolume;
-int ready_to_go;
+int ready_to_go, g_resetting;
unsigned long gpuDisp;
char cfgfile_basename[MAXPATHLEN];
int state_slot;
@@ -311,12 +311,19 @@ do_state_slot:
hud_new_msg = 3;
}
+static char basic_lcase(char c)
+{
+ if ('A' <= c && c <= 'Z')
+ return c - 'A' + 'a';
+ return c;
+}
+
static int cdidcmp(const char *id1, const char *id2)
{
while (*id1 != 0 && *id2 != 0) {
if (*id1 == '_') { id1++; continue; }
if (*id2 == '_') { id2++; continue; }
- if (*id1 != *id2)
+ if (basic_lcase(*id1) != basic_lcase(*id2))
break;
id1++;
id2++;
@@ -669,6 +676,7 @@ void SysReset() {
// so we need to prevent updateLace() call..
void *real_lace = GPU_updateLace;
GPU_updateLace = dummy_lace;
+ g_resetting = 1;
// reset can run code, timing must be set
pl_timing_prepare(Config.PsxType);
@@ -679,6 +687,7 @@ void SysReset() {
CDR_stop();
GPU_updateLace = real_lace;
+ g_resetting = 0;
}
void SysClose() {
diff --git a/frontend/main.h b/frontend/main.h
index 45e0aeb..d971890 100644
--- a/frontend/main.h
+++ b/frontend/main.h
@@ -52,7 +52,7 @@ int emu_load_state(int slot);
void set_cd_image(const char *fname);
extern unsigned long gpuDisp;
-extern int ready_to_go;
+extern int ready_to_go, g_resetting;
extern char hud_msg[64];
extern int hud_new_msg;
diff --git a/frontend/menu.c b/frontend/menu.c
index 7bec49a..7dab2e6 100644
--- a/frontend/menu.c
+++ b/frontend/menu.c
@@ -1,5 +1,5 @@
/*
- * (C) Gražvydas "notaz" Ignotas, 2010-2011
+ * (C) Gražvydas "notaz" Ignotas, 2010-2013
*
* This work is licensed under the terms of any of these licenses
* (at your option):
@@ -8,6 +8,7 @@
* See the COPYING file in the top-level directory.
*/
+#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <errno.h>
@@ -16,6 +17,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <dirent.h>
#include "main.h"
#include "menu.h"
@@ -84,7 +86,6 @@ typedef enum
static int last_vout_w, last_vout_h, last_vout_bpp;
static int cpu_clock, cpu_clock_st, volume_boost, frameskip;
-static char rom_fname_reload[MAXPATHLEN];
static char last_selected_fname[MAXPATHLEN];
static int config_save_counter, region, in_type_sel1, in_type_sel2;
static int psx_clock;
@@ -187,6 +188,107 @@ static int emu_save_load_game(int load, int unused)
return ret;
}
+static void rm_namelist_entry(struct dirent **namelist,
+ int count, const char *name)
+{
+ int i;
+
+ for (i = 1; i < count; i++) {
+ if (namelist[i] == NULL || namelist[i]->d_type == DT_DIR)
+ continue;
+
+ if (strcmp(name, namelist[i]->d_name) == 0) {
+ free(namelist[i]);
+ namelist[i] = NULL;
+ break;
+ }
+ }
+}
+
+static int optional_cdimg_filter(struct dirent **namelist, int count,
+ const char *basedir)
+{
+ const char *ext, *p;
+ char buf[256], buf2[256];
+ int i, d, ret, good_cue;
+ struct stat64 statf;
+ FILE *f;
+
+ for (i = 1; i < count; i++) {
+ if (namelist[i] == NULL || namelist[i]->d_type == DT_DIR)
+ continue;
+
+ ext = strrchr(namelist[i]->d_name, '.');
+ if (ext == NULL) {
+ // should not happen but whatever
+ free(namelist[i]);
+ namelist[i] = NULL;
+ continue;
+ }
+ ext++;
+
+ // first find .cue files and remove files they reference
+ if (strcasecmp(ext, "cue") == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", basedir,
+ namelist[i]->d_name);
+
+ f = fopen(buf, "r");
+ if (f == NULL) {
+ free(namelist[i]);
+ namelist[i] = NULL;
+ continue;
+ }
+
+ good_cue = 0;
+ while (fgets(buf, sizeof(buf), f)) {
+ ret = sscanf(buf, " FILE \"%256[^\"]\"", buf2);
+ if (ret != 1)
+ ret = sscanf(buf, " FILE %256s", buf2);
+ if (ret != 1)
+ continue;
+
+ p = strrchr(buf2, '/');
+ if (p == NULL)
+ p = strrchr(buf2, '\\');
+ if (p == NULL)
+ p = buf2;
+
+ snprintf(buf, sizeof(buf), "%s/%s", basedir, p);
+ ret = stat64(buf, &statf);
+ if (ret == 0) {
+ rm_namelist_entry(namelist, count, p);
+ good_cue = 1;
+ }
+ }
+ fclose(f);
+
+ if (!good_cue) {
+ free(namelist[i]);
+ namelist[i] = NULL;
+ }
+ continue;
+ }
+
+ p = strcasestr(namelist[i]->d_name, "track");
+ if (p != NULL) {
+ ret = strtoul(p + 5, NULL, 10);
+ if (ret > 1) {
+ free(namelist[i]);
+ namelist[i] = NULL;
+ continue;
+ }
+ }
+ }
+
+ // compact namelist
+ for (i = d = 1; i < count; i++)
+ if (namelist[i] != NULL)
+ namelist[d++] = namelist[i];
+
+ return d;
+}
+
// propagate menu settings to the emu vars
static void menu_sync_config(void)
{
@@ -406,14 +508,18 @@ static int menu_write_config(int is_game)
static int menu_do_last_cd_img(int is_get)
{
+ static const char *defaults[] = { "/media", "/mnt/sd", "/mnt" };
char path[256];
+ struct stat64 st;
FILE *f;
- int ret;
+ int i, ret = -1;
snprintf(path, sizeof(path), "." PCSX_DOT_DIR "lastcdimg.txt");
f = fopen(path, is_get ? "r" : "w");
- if (f == NULL)
- return -1;
+ if (f == NULL) {
+ ret = -1;
+ goto out;
+ }
if (is_get) {
ret = fread(last_selected_fname, 1, sizeof(last_selected_fname) - 1, f);
@@ -424,6 +530,17 @@ static int menu_do_last_cd_img(int is_get)
fprintf(f, "%s\n", last_selected_fname);
fclose(f);
+out:
+ if (is_get) {
+ for (i = 0; last_selected_fname[0] == 0
+ || stat64(last_selected_fname, &st) != 0; i++)
+ {
+ if (i >= ARRAY_SIZE(defaults))
+ break;
+ strcpy(last_selected_fname, defaults[i]);
+ }
+ }
+
return 0;
}
@@ -547,20 +664,25 @@ fail:
return ret;
}
+static const char *filter_exts[] = {
+ "bin", "img", "mdf", "iso", "cue", "z",
+ "bz", "znx", "pbp", "cbn", NULL
+};
+
// rrrr rggg gggb bbbb
static unsigned short fname2color(const char *fname)
{
- static const char *cdimg_exts[] = { ".bin", ".img", ".mdf", ".iso", ".cue", ".z",
- ".bz", ".znx", ".pbp", ".cbn" };
- static const char *other_exts[] = { ".ccd", ".toc", ".mds", ".sub",
- ".table", ".index", ".sbi" };
+ static const char *other_exts[] = {
+ "ccd", "toc", "mds", "sub", "table", "index", "sbi"
+ };
const char *ext = strrchr(fname, '.');
int i;
if (ext == NULL)
return 0xffff;
- for (i = 0; i < array_size(cdimg_exts); i++)
- if (strcasecmp(ext, cdimg_exts[i]) == 0)
+ ext++;
+ for (i = 0; filter_exts[i] != NULL; i++)
+ if (strcasecmp(ext, filter_exts[i]) == 0)
return 0x7bff;
for (i = 0; i < array_size(other_exts); i++)
if (strcasecmp(ext, other_exts[i]) == 0)
@@ -570,10 +692,6 @@ static unsigned short fname2color(const char *fname)
static void draw_savestate_bg(int slot);
-static const char *filter_exts[] = {
- ".mp3", ".MP3", ".txt", ".htm", "html", ".jpg", ".pnd"
-};
-
#define MENU_ALIGN_LEFT
#ifdef __ARM_ARCH_7A__ // assume hires device
#define MENU_X2 1
@@ -603,8 +721,8 @@ static void draw_savestate_bg(int slot)
if (f == NULL)
return;
- if (gzseek(f, 0x29933d, SEEK_SET) != 0x29933d) {
- fprintf(stderr, "gzseek failed\n");
+ if ((ret = (int)gzseek(f, 0x29933d, SEEK_SET)) != 0x29933d) {
+ fprintf(stderr, "gzseek failed: %d\n", ret);
gzclose(f);
return;
}
@@ -1818,9 +1936,11 @@ static int run_bios(void)
static int run_exe(void)
{
+ const char *exts[] = { "exe", NULL };
const char *fname;
- fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
+ fname = menu_loop_romsel(last_selected_fname,
+ sizeof(last_selected_fname), exts, NULL);
if (fname == NULL)
return -1;
@@ -1874,7 +1994,9 @@ static int romsel_run(void)
int prev_gpu, prev_spu;
const char *fname;
- fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
+ fname = menu_loop_romsel(last_selected_fname,
+ sizeof(last_selected_fname), filter_exts,
+ optional_cdimg_filter);
if (fname == NULL)
return -1;
@@ -1898,16 +2020,18 @@ static int romsel_run(void)
return -1;
}
- strcpy(last_selected_fname, rom_fname_reload);
+ strcpy(last_selected_fname, fname);
menu_do_last_cd_img(0);
return 0;
}
static int swap_cd_image(void)
{
- char *fname;
+ const char *fname;
- fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
+ fname = menu_loop_romsel(last_selected_fname,
+ sizeof(last_selected_fname), filter_exts,
+ optional_cdimg_filter);
if (fname == NULL)
return -1;
@@ -1929,7 +2053,7 @@ static int swap_cd_image(void)
SetCdOpenCaseTime(time(NULL) + 2);
LidInterrupt();
- strcpy(last_selected_fname, rom_fname_reload);
+ strcpy(last_selected_fname, fname);
return 0;
}
@@ -1953,11 +2077,12 @@ static int swap_cd_multidisk(void)
static void load_pcsx_cht(void)
{
+ const char *exts[] = { "cht", NULL };
+ const char *fname;
char path[256];
- char *fname;
path[0] = 0;
- fname = menu_loop_romsel(path, sizeof(path));
+ fname = menu_loop_romsel(path, sizeof(path), exts, NULL);
if (fname == NULL)
return;
@@ -2278,8 +2403,6 @@ void menu_init(void)
char buff[MAXPATHLEN];
int i;
- strcpy(last_selected_fname, "/media");
-
cpu_clock_st = cpu_clock = plat_target_cpu_clock_get();
scan_bios_plugins();
@@ -2380,9 +2503,12 @@ void menu_prepare_emu(void)
plat_video_menu_leave();
psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec;
- if (psxCpu != prev_cpu)
+ if (psxCpu != prev_cpu) {
+ prev_cpu->Shutdown();
+ psxCpu->Init();
// note that this does not really reset, just clears drc caches
psxCpu->Reset();
+ }
// core doesn't care about Config.Cdda changes,
// so handle them manually here
diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c
index aa771ed..dfff868 100644
--- a/frontend/plugin_lib.c
+++ b/frontend/plugin_lib.c
@@ -44,7 +44,7 @@ void *tsdev;
void *pl_vout_buf;
int g_layer_x, g_layer_y, g_layer_w, g_layer_h;
static int pl_vout_w, pl_vout_h, pl_vout_bpp; /* output display/layer */
-static int pl_vout_scale;
+static int pl_vout_scale, pl_vout_yoffset;
static int psx_w, psx_h, psx_bpp;
static int vsync_cnt;
static int is_pal, frame_interval, frame_interval1024;
@@ -230,6 +230,7 @@ static int resolution_ok(int w, int h)
static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
{
int vout_w, vout_h, vout_bpp;
+ int buf_yoffset = 0;
// special h handling, Wipeout likes to change it by 1-6
static int vsync_cnt_ms_prev;
@@ -243,6 +244,12 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
vout_h = h;
vout_bpp = psx_bpp = bpp;
+ // don't use very low heights
+ if (vout_h < 192) {
+ buf_yoffset = (192 - vout_h) / 2;
+ vout_h = 192;
+ }
+
pl_vout_scale = 1;
#ifdef __ARM_NEON__
if (soft_filter) {
@@ -268,7 +275,11 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
pl_vout_w = vout_w;
pl_vout_h = vout_h;
pl_vout_bpp = vout_bpp;
+ pl_vout_yoffset = buf_yoffset;
}
+ if (pl_vout_buf != NULL)
+ pl_vout_buf = (char *)pl_vout_buf
+ + pl_vout_yoffset * pl_vout_w * pl_vout_bpp / 8;
menu_notify_mode_change(pl_vout_w, pl_vout_h, pl_vout_bpp);
}
@@ -366,6 +377,10 @@ out:
// let's flip now
pl_vout_buf = plat_gvideo_flip();
+ if (pl_vout_buf != NULL)
+ pl_vout_buf = (char *)pl_vout_buf
+ + pl_vout_yoffset * pl_vout_w * pl_vout_bpp / 8;
+
pl_rearmed_cbs.flip_cnt++;
}
@@ -591,6 +606,9 @@ void pl_frame_limit(void)
struct timeval now;
int diff, usadj;
+ if (g_resetting)
+ return;
+
vsync_cnt++;
/* doing input here because the pad is polled
diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c
index b8e9883..02e108f 100644
--- a/libpcsxcore/new_dynarec/emu_if.c
+++ b/libpcsxcore/new_dynarec/emu_if.c
@@ -344,6 +344,7 @@ static void ari64_clear(u32 addr, u32 size)
static void ari64_shutdown()
{
new_dynarec_cleanup();
+ new_dyna_pcsx_mem_shutdown();
}
extern void intExecute();
@@ -394,6 +395,7 @@ void invalidate_block(unsigned int block) {}
void new_dyna_pcsx_mem_init(void) {}
void new_dyna_pcsx_mem_reset(void) {}
void new_dyna_pcsx_mem_load_state(void) {}
+void new_dyna_pcsx_mem_shutdown(void) {}
#endif
#ifdef DRC_DBG
diff --git a/libpcsxcore/new_dynarec/pcsxmem.c b/libpcsxcore/new_dynarec/pcsxmem.c
index 90f7765..a42852a 100644
--- a/libpcsxcore/new_dynarec/pcsxmem.c
+++ b/libpcsxcore/new_dynarec/pcsxmem.c
@@ -147,9 +147,9 @@ make_rcnt_funcs(2)
static void io_write_ireg16(u32 value)
{
- if (Config.Sio) psxHu16ref(0x1070) |= 0x80;
+ //if (Config.Sio) psxHu16ref(0x1070) |= 0x80;
if (Config.SpuIrq) psxHu16ref(0x1070) |= 0x200;
- psxHu16ref(0x1070) &= psxHu16(0x1074) & value;
+ psxHu16ref(0x1070) &= value;
}
static void io_write_imask16(u32 value)
@@ -161,9 +161,9 @@ static void io_write_imask16(u32 value)
static void io_write_ireg32(u32 value)
{
- if (Config.Sio) psxHu32ref(0x1070) |= 0x80;
+ //if (Config.Sio) psxHu32ref(0x1070) |= 0x80;
if (Config.SpuIrq) psxHu32ref(0x1070) |= 0x200;
- psxHu32ref(0x1070) &= psxHu32(0x1074) & value;
+ psxHu32ref(0x1070) &= value;
}
static void io_write_imask32(u32 value)
@@ -475,3 +475,9 @@ void new_dyna_pcsx_mem_reset(void)
map_item(&mem_iowtab[IOMEM32(0x1810)], GPU_writeData, 1);
}
+
+void new_dyna_pcsx_mem_shutdown(void)
+{
+ psxUnmap(mem_readtab, 0x200000 * 4, MAP_TAG_LUTS);
+ mem_writetab = mem_readtab = NULL;
+}
diff --git a/libpcsxcore/new_dynarec/pcsxmem.h b/libpcsxcore/new_dynarec/pcsxmem.h
index f962562..99bb5d4 100644
--- a/libpcsxcore/new_dynarec/pcsxmem.h
+++ b/libpcsxcore/new_dynarec/pcsxmem.h
@@ -4,5 +4,6 @@ extern u8 zero_mem[0x1000];
void new_dyna_pcsx_mem_init(void);
void new_dyna_pcsx_mem_reset(void);
void new_dyna_pcsx_mem_load_state(void);
+void new_dyna_pcsx_mem_shutdown(void);
int pcsxmem_is_handler_dynamic(u_int addr);
diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c
index 1f85278..6b9125d 100644
--- a/libpcsxcore/psxhw.c
+++ b/libpcsxcore/psxhw.c
@@ -431,7 +431,7 @@ void psxHwWrite16(u32 add, u16 value) {
#endif
if (Config.Sio) psxHu16ref(0x1070) |= SWAPu16(0x80);
if (Config.SpuIrq) psxHu16ref(0x1070) |= SWAPu16(0x200);
- psxHu16ref(0x1070) &= SWAPu16((psxHu16(0x1074) & value));
+ psxHu16ref(0x1070) &= SWAPu16(value);
return;
case 0x1f801074:
@@ -546,7 +546,7 @@ void psxHwWrite32(u32 add, u32 value) {
#endif
if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80);
if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200);
- psxHu32ref(0x1070) &= SWAPu32((psxHu32(0x1074) & value));
+ psxHu32ref(0x1070) &= SWAPu32(value);
return;
case 0x1f801074:
#ifdef PSXHW_LOG
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c
index 9f91b8b..b89ab1a 100644
--- a/plugins/dfsound/spu.c
+++ b/plugins/dfsound/spu.c
@@ -444,24 +444,30 @@ static int decode_block(int ch)
{
unsigned char *start;
int predict_nr,shift_factor,flags;
+ int stop = 0;
int ret = 0;
- start=s_chan[ch].pCurr; // set up the current pos
+ start = s_chan[ch].pCurr; // set up the current pos
+ if(start == spuMemC) // ?
+ stop = 1;
if(s_chan[ch].prevflags&1) // 1: stop/loop
{
if(!(s_chan[ch].prevflags&2))
- {
- dwChannelOn&=~(1<<ch); // -> turn everything off
- s_chan[ch].bStop=1;
- s_chan[ch].ADSRX.EnvelopeVol=0;
- }
+ stop = 1;
start = s_chan[ch].pLoop;
}
else
ret = check_irq(ch, start); // hack, see check_irq below..
+ if(stop)
+ {
+ dwChannelOn &= ~(1<<ch); // -> turn everything off
+ s_chan[ch].bStop = 1;
+ s_chan[ch].ADSRX.EnvelopeVol = 0;
+ }
+
predict_nr=(int)start[0];
shift_factor=predict_nr&0xf;
predict_nr >>= 4;
@@ -665,12 +671,13 @@ static void noinline do_decode_bufs(int which, int start, int count)
{
const int *src = ChanBuf + start;
unsigned short *dst = &spuMem[0x800/2 + which*0x400/2];
- int cursor = decode_pos;
+ int cursor = decode_pos + start;
while (count-- > 0)
{
+ cursor &= 0x1ff;
dst[cursor] = *src++;
- cursor = (cursor + 1) & 0x1ff;
+ cursor++;
}
// decode_pos is updated and irqs are checked later, after voice loop
@@ -689,25 +696,18 @@ static int do_samples(int forced_updates)
int ch,d,silentch;
int bIRQReturn=0;
+ // ok, at the beginning we are looking if there is
+ // enuff free place in the dsound/oss buffer to
+ // fill in new data, or if there is a new channel to start.
+ // if not, we return until enuff free place is available
+ // /a new channel gets started
+
+ if(!forced_updates && out_current->busy()) // still enuff data in sound buffer?
+ return 0;
+
while(!bIRQReturn)
{
- // ok, at the beginning we are looking if there is
- // enuff free place in the dsound/oss buffer to
- // fill in new data, or if there is a new channel to start.
- // if not, we wait (thread) or return (timer/spuasync)
- // until enuff free place is available/a new channel gets
- // started
-
- if(!forced_updates && out_current->busy()) // still enuff data in sound buffer?
- {
- return 0;
- }
-
cycles_since_update = 0;
- if(forced_updates > 0)
- forced_updates--;
-
- //--------------------------------------------------// continue from irq handling in timer mode?
ns_from=0;
ns_to=NSSIZE;
@@ -777,9 +777,9 @@ static int do_samples(int forced_updates)
// no need for bIRQReturn since the channel is silent
skip_block(ch);
- if(start == s_chan[ch].pCurr)
+ if(start == s_chan[ch].pCurr || start - spuMemC < 0x1000)
{
- // looping on self
+ // looping on self or stopped(?)
dwChannelDead |= 1<<ch;
s_chan[ch].spos = 0;
break;
@@ -872,12 +872,21 @@ static int do_samples(int forced_updates)
// feed the sound
// wanna have around 1/60 sec (16.666 ms) updates
- if (iCycle++ > 16/FRAG_MSECS)
+ if (iCycle++ >= 16/FRAG_MSECS)
{
- out_current->feed(pSpuBuffer,
- ((unsigned char *)pS) - ((unsigned char *)pSpuBuffer));
+ out_current->feed(pSpuBuffer, (unsigned char *)pS - pSpuBuffer);
pS = (short *)pSpuBuffer;
iCycle = 0;
+
+ if(!forced_updates && out_current->busy())
+ break;
+ }
+
+ if(forced_updates > 0)
+ {
+ forced_updates--;
+ if(forced_updates == 0 && out_current->busy())
+ break;
}
}
diff --git a/plugins/dfxvideo/gpulib_if.c b/plugins/dfxvideo/gpulib_if.c
index d98520c..01b8dde 100644
--- a/plugins/dfxvideo/gpulib_if.c
+++ b/plugins/dfxvideo/gpulib_if.c
@@ -342,7 +342,12 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
while(1)
{
- if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
+ if(list_position >= list_end) {
+ cmd = -1;
+ goto breakloop;
+ }
+
+ if((*list_position & 0xf000f000) == 0x50005000)
break;
list_position++;
@@ -360,7 +365,12 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
while(1)
{
- if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
+ if(list_position >= list_end) {
+ cmd = -1;
+ goto breakloop;
+ }
+
+ if((*list_position & 0xf000f000) == 0x50005000)
break;
list_position += 2;
@@ -386,6 +396,7 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
}
}
+breakloop:
gpu.ex_regs[1] &= ~0x1ff;
gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
diff --git a/plugins/gpu-gles/gpulib_if.c b/plugins/gpu-gles/gpulib_if.c
index 068dc41..2090553 100644
--- a/plugins/gpu-gles/gpulib_if.c
+++ b/plugins/gpu-gles/gpulib_if.c
@@ -549,7 +549,12 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
while(1)
{
- if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
+ if(list_position >= list_end) {
+ cmd = -1;
+ goto breakloop;
+ }
+
+ if((*list_position & 0xf000f000) == 0x50005000)
break;
list_position++;
@@ -567,7 +572,12 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
while(1)
{
- if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
+ if(list_position >= list_end) {
+ cmd = -1;
+ goto breakloop;
+ }
+
+ if((*list_position & 0xf000f000) == 0x50005000)
break;
list_position += 2;
@@ -593,6 +603,7 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
}
}
+breakloop:
gpu.ex_regs[1] &= ~0x1ff;
gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
diff --git a/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c b/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
index a364eef..ffa9b9a 100644
--- a/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
+++ b/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
@@ -435,7 +435,10 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_command)
num_vertexes++;
if(list_position >= list_end)
- break;
+ {
+ current_command = (u32)-1;
+ goto breakloop;
+ }
xy = *list_position;
if((xy & 0xF000F000) == 0x50005000)
@@ -496,7 +499,10 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_command)
num_vertexes++;
if(list_position >= list_end)
- break;
+ {
+ current_command = (u32)-1;
+ goto breakloop;
+ }
color = list_position[0];
if((color & 0xF000F000) == 0x50005000)
@@ -774,9 +780,7 @@ u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_command)
}
}
-#ifdef PCSX
breakloop:
-#endif
if (last_command != NULL)
*last_command = current_command;
return list - list_start;
@@ -1193,7 +1197,10 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
num_vertexes++;
if(list_position >= list_end)
- break;
+ {
+ current_command = (u32)-1;
+ goto breakloop;
+ }
xy = *list_position;
if((xy & 0xF000F000) == 0x50005000)
@@ -1259,7 +1266,10 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
num_vertexes++;
if(list_position >= list_end)
- break;
+ {
+ current_command = (u32)-1;
+ goto breakloop;
+ }
color = list_position[0];
if((color & 0xF000F000) == 0x50005000)
diff --git a/plugins/gpu_unai/gpulib_if.cpp b/plugins/gpu_unai/gpulib_if.cpp
index de16721..0d506bc 100644
--- a/plugins/gpu_unai/gpulib_if.cpp
+++ b/plugins/gpu_unai/gpulib_if.cpp
@@ -307,7 +307,11 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
num_vertexes++;
- if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
+ if(list_position >= list_end) {
+ cmd = -1;
+ goto breakloop;
+ }
+ if((*list_position & 0xf000f000) == 0x50005000)
break;
}
@@ -338,7 +342,11 @@ int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
num_vertexes++;
- if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
+ if(list_position >= list_end) {
+ cmd = -1;
+ goto breakloop;
+ }
+ if((*list_position & 0xf000f000) == 0x50005000)
break;
}
diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c
index b300c88..337e27a 100644
--- a/plugins/gpulib/gpu.c
+++ b/plugins/gpulib/gpu.c
@@ -68,10 +68,11 @@ static noinline void update_width(void)
static noinline void update_height(void)
{
+ // TODO: emulate this properly..
int sh = gpu.screen.y2 - gpu.screen.y1;
if (gpu.status.dheight)
sh *= 2;
- if (sh <= 0)
+ if (sh <= 0 || sh > gpu.screen.vres)
sh = gpu.screen.vres;
gpu.screen.h = sh;
@@ -367,46 +368,62 @@ static void finish_vram_transfer(int is_read)
static noinline int do_cmd_list_skip(uint32_t *data, int count, int *last_cmd)
{
- int cmd = 0, pos = 0, len, dummy;
+ int cmd = 0, pos = 0, len, dummy, v;
int skip = 1;
gpu.frameskip.pending_fill[0] = 0;
- // XXX: polylines are not properly handled
while (pos < count && skip) {
uint32_t *list = data + pos;
cmd = list[0] >> 24;
len = 1 + cmd_lengths[cmd];
- if (cmd == 0x02) {
- if ((list[2] & 0x3ff) > gpu.screen.w || ((list[2] >> 16) & 0x1ff) > gpu.screen.h)
- // clearing something large, don't skip
- do_cmd_list(list, 3, &dummy);
- else
- memcpy(gpu.frameskip.pending_fill, list, 3 * 4);
- }
- else if ((cmd & 0xf4) == 0x24) {
- // flat textured prim
- gpu.ex_regs[1] &= ~0x1ff;
- gpu.ex_regs[1] |= list[4] & 0x1ff;
- }
- else if ((cmd & 0xf4) == 0x34) {
- // shaded textured prim
- gpu.ex_regs[1] &= ~0x1ff;
- gpu.ex_regs[1] |= list[5] & 0x1ff;
+ switch (cmd) {
+ case 0x02:
+ if ((list[2] & 0x3ff) > gpu.screen.w || ((list[2] >> 16) & 0x1ff) > gpu.screen.h)
+ // clearing something large, don't skip
+ do_cmd_list(list, 3, &dummy);
+ else
+ memcpy(gpu.frameskip.pending_fill, list, 3 * 4);
+ break;
+ case 0x24 ... 0x27:
+ case 0x2c ... 0x2f:
+ case 0x34 ... 0x37:
+ case 0x3c ... 0x3f:
+ gpu.ex_regs[1] &= ~0x1ff;
+ gpu.ex_regs[1] |= list[4 + ((cmd >> 4) & 1)] & 0x1ff;
+ break;
+ case 0x48 ... 0x4F:
+ for (v = 3; pos + v < count; v++)
+ {
+ if ((list[v] & 0xf000f000) == 0x50005000)
+ break;
+ }
+ len += v - 3;
+ break;
+ case 0x58 ... 0x5F:
+ for (v = 4; pos + v < count; v += 2)
+ {
+ if ((list[v] & 0xf000f000) == 0x50005000)
+ break;
+ }
+ len += v - 4;
+ break;
+ default:
+ if (cmd == 0xe3)
+ skip = decide_frameskip_allow(list[0]);
+ if ((cmd & 0xf8) == 0xe0)
+ gpu.ex_regs[cmd & 7] = list[0];
+ break;
}
- else if (cmd == 0xe3)
- skip = decide_frameskip_allow(list[0]);
-
- if ((cmd & 0xf8) == 0xe0)
- gpu.ex_regs[cmd & 7] = list[0];
if (pos + len > count) {
cmd = -1;
break; // incomplete cmd
}
- if (cmd == 0xa0 || cmd == 0xc0)
+ if (0xa0 <= cmd && cmd <= 0xdf)
break; // image i/o
+
pos += len;
}
@@ -432,9 +449,9 @@ static noinline int do_cmd_buffer(uint32_t *data, int count)
}
cmd = data[pos] >> 24;
- if (cmd == 0xa0 || cmd == 0xc0) {
+ if (0xa0 <= cmd && cmd <= 0xdf) {
// consume vram write/read cmd
- start_vram_transfer(data[pos + 1], data[pos + 2], cmd == 0xc0);
+ start_vram_transfer(data[pos + 1], data[pos + 2], (cmd & 0xe0) == 0xc0);
pos += 3;
continue;
}
diff --git a/plugins/gpulib/vout_pl.c b/plugins/gpulib/vout_pl.c
index 49f53d6..5af0762 100644
--- a/plugins/gpulib/vout_pl.c
+++ b/plugins/gpulib/vout_pl.c
@@ -106,6 +106,7 @@ long GPUopen(void **unused)
cbs->pl_vout_open();
check_mode_change(1);
+ vout_update();
return 0;
}
diff --git a/readme.txt b/readme.txt
index 68d2882..3e91118 100644
--- a/readme.txt
+++ b/readme.txt
@@ -109,7 +109,14 @@ the main menu where it is possible to enable/disable individual cheats.
Changelog
---------
-r17
+r18 (2013-01-06)
+* cdrom code greatly cleaned up
++ new GLES output mode for ARM Linux/R-Pi
+* various libretro improvements
+* fixed several compatibility regressions
+* various other tweaks and fixes
+
+r17 (2012-11-24)
+ added overlay support for generic Linux build
* attempted to fix sound breakage with PulseAudio
* fixed some regressions caused by hires mode code