Merge git://github.com/notaz/pcsx_rearmed
authortwinaphex <autechre1024@hotmail.com>
Thu, 10 Jan 2013 02:06:17 +0000 (03:06 +0100)
committertwinaphex <autechre1024@hotmail.com>
Thu, 10 Jan 2013 02:06:17 +0000 (03:06 +0100)
17 files changed:
frontend/libpicofe
frontend/main.c
frontend/main.h
frontend/menu.c
frontend/plugin_lib.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/new_dynarec/pcsxmem.c
libpcsxcore/new_dynarec/pcsxmem.h
libpcsxcore/psxhw.c
plugins/dfsound/spu.c
plugins/dfxvideo/gpulib_if.c
plugins/gpu-gles/gpulib_if.c
plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
plugins/gpu_unai/gpulib_if.cpp
plugins/gpulib/gpu.c
plugins/gpulib/vout_pl.c
readme.txt

index 0d645bc..4db0222 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0d645bc539fdc073f20c4dea9f4a4e218cebec0e
+Subproject commit 4db02226eb3c80f49f5c412f7718c437c5e817fc
index c8841b9..43a1a03 100644 (file)
@@ -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() {
index 45e0aeb..d971890 100644 (file)
@@ -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;
index 7bec49a..7dab2e6 100644 (file)
@@ -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
index aa771ed..dfff868 100644 (file)
@@ -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
index b8e9883..02e108f 100644 (file)
@@ -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
index 90f7765..a42852a 100644 (file)
@@ -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;
+}
index f962562..99bb5d4 100644 (file)
@@ -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);
index 1f85278..6b9125d 100644 (file)
@@ -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
index 9f91b8b..b89ab1a 100644 (file)
@@ -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;
    }
  }
 
index d98520c..01b8dde 100644 (file)
@@ -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;
 
index 068dc41..2090553 100644 (file)
@@ -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;
 
index a364eef..ffa9b9a 100644 (file)
@@ -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)
index de16721..0d506bc 100644 (file)
@@ -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;
         }
 
index b300c88..337e27a 100644 (file)
@@ -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;
     }
index 49f53d6..5af0762 100644 (file)
@@ -106,6 +106,7 @@ long GPUopen(void **unused)
 
   cbs->pl_vout_open();
   check_mode_change(1);
+  vout_update();
   return 0;
 }
 
index 68d2882..3e91118 100644 (file)
@@ -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