From: twinaphex Date: Thu, 10 Jan 2013 02:06:17 +0000 (+0100) Subject: Merge git://github.com/notaz/pcsx_rearmed X-Git-Tag: r24l~971 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5f4d90401d099d5191f95e9f771ab5a81c87ed8;hp=ac7b2a33ddb2392582c50d29c772e9e99cd762c9;p=pcsx_rearmed.git Merge git://github.com/notaz/pcsx_rearmed --- diff --git a/frontend/libpicofe b/frontend/libpicofe index 0d645bc5..4db02226 160000 --- a/frontend/libpicofe +++ b/frontend/libpicofe @@ -1 +1 @@ -Subproject commit 0d645bc539fdc073f20c4dea9f4a4e218cebec0e +Subproject commit 4db02226eb3c80f49f5c412f7718c437c5e817fc diff --git a/frontend/main.c b/frontend/main.c index c8841b99..43a1a032 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 45e0aebb..d9718906 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 7bec49ab..7dab2e68 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 #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #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 aa771ed1..dfff8681 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 b8e98836..02e108f8 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 90f77657..a42852ad 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 f9625626..99bb5d4f 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 1f85278d..6b9125d7 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 9f91b8b2..b89ab1af 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< 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< 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< 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 d98520cb..01b8dde2 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 068dc411..2090553d 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 a364eef3..ffa9b9a0 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 de167214..0d506bc7 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 b300c885..337e27a7 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 49f53d60..5af0762f 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 68d28822..3e911183 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