libretro: improve retro_memory_map master github/master
authornotaz <notasas@gmail.com>
Tue, 3 Sep 2024 21:19:25 +0000 (00:19 +0300)
committernotaz <notasas@gmail.com>
Tue, 3 Sep 2024 21:24:36 +0000 (00:24 +0300)
libretro/pcsx_rearmed#845

29 files changed:
Makefile
deps/libchdr
frontend/libretro.c
frontend/libretro_core_options.h
frontend/main.c
frontend/menu.c
frontend/plugin_lib.h
libpcsxcore/cdriso.c
libpcsxcore/cdrom.c
libpcsxcore/database.c
libpcsxcore/misc.c
libpcsxcore/ppf.c
libpcsxcore/ppf.h
libpcsxcore/psxbios.c
libpcsxcore/psxcommon.h
libpcsxcore/psxdma.c
plugins/gpu_neon/psx_gpu/common.h
plugins/gpu_neon/psx_gpu/psx_gpu.c
plugins/gpu_neon/psx_gpu/psx_gpu.h
plugins/gpu_neon/psx_gpu/psx_gpu_arm_neon.S
plugins/gpu_neon/psx_gpu/psx_gpu_main.c
plugins/gpu_neon/psx_gpu/psx_gpu_offsets.h
plugins/gpu_neon/psx_gpu/psx_gpu_offsets_update.c
plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
plugins/gpu_neon/psx_gpu/psx_gpu_simd.c
plugins/gpu_neon/psx_gpu/tests/Makefile
plugins/gpulib/gpu.c
plugins/gpulib/gpu.h
plugins/spunull/spunull.c

index 32cd6cf..5b89060 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -172,8 +172,8 @@ OBJS += plugins/cdrcimg/cdrcimg.o
 # libchdr
 #ifeq "$(HAVE_CHD)" "1"
 LCHDR = deps/libchdr
 # libchdr
 #ifeq "$(HAVE_CHD)" "1"
 LCHDR = deps/libchdr
-LCHDR_LZMA = $(LCHDR)/deps/lzma-22.01
-LCHDR_ZSTD = $(LCHDR)/deps/zstd-1.5.5/lib
+LCHDR_LZMA = $(LCHDR)/deps/lzma-24.05
+LCHDR_ZSTD = $(LCHDR)/deps/zstd-1.5.6/lib
 OBJS += $(LCHDR)/src/libchdr_bitstream.o
 OBJS += $(LCHDR)/src/libchdr_cdrom.o
 OBJS += $(LCHDR)/src/libchdr_chd.o
 OBJS += $(LCHDR)/src/libchdr_bitstream.o
 OBJS += $(LCHDR)/src/libchdr_cdrom.o
 OBJS += $(LCHDR)/src/libchdr_chd.o
@@ -181,31 +181,26 @@ OBJS += $(LCHDR)/src/libchdr_flac.o
 OBJS += $(LCHDR)/src/libchdr_huffman.o
 $(LCHDR)/src/%.o: CFLAGS += -Wno-unused -std=gnu11
 OBJS += $(LCHDR_LZMA)/src/Alloc.o
 OBJS += $(LCHDR)/src/libchdr_huffman.o
 $(LCHDR)/src/%.o: CFLAGS += -Wno-unused -std=gnu11
 OBJS += $(LCHDR_LZMA)/src/Alloc.o
-OBJS += $(LCHDR_LZMA)/src/Bra86.o
-OBJS += $(LCHDR_LZMA)/src/BraIA64.o
 OBJS += $(LCHDR_LZMA)/src/CpuArch.o
 OBJS += $(LCHDR_LZMA)/src/Delta.o
 OBJS += $(LCHDR_LZMA)/src/LzFind.o
 OBJS += $(LCHDR_LZMA)/src/CpuArch.o
 OBJS += $(LCHDR_LZMA)/src/Delta.o
 OBJS += $(LCHDR_LZMA)/src/LzFind.o
-OBJS += $(LCHDR_LZMA)/src/Lzma86Dec.o
 OBJS += $(LCHDR_LZMA)/src/LzmaDec.o
 OBJS += $(LCHDR_LZMA)/src/LzmaEnc.o
 OBJS += $(LCHDR_LZMA)/src/Sort.o
 OBJS += $(LCHDR_LZMA)/src/LzmaDec.o
 OBJS += $(LCHDR_LZMA)/src/LzmaEnc.o
 OBJS += $(LCHDR_LZMA)/src/Sort.o
-$(LCHDR_LZMA)/src/%.o: CFLAGS += -Wno-unused -D_7ZIP_ST -I$(LCHDR_LZMA)/include
+$(LCHDR_LZMA)/src/%.o: CFLAGS += -Wno-unused -DZ7_ST -I$(LCHDR_LZMA)/include
 $(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_LZMA)/include
 $(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_LZMA)/include
-OBJS += $(LCHDR_ZSTD)/common/debug.o
 OBJS += $(LCHDR_ZSTD)/common/entropy_common.o
 OBJS += $(LCHDR_ZSTD)/common/error_private.o
 OBJS += $(LCHDR_ZSTD)/common/fse_decompress.o
 OBJS += $(LCHDR_ZSTD)/common/entropy_common.o
 OBJS += $(LCHDR_ZSTD)/common/error_private.o
 OBJS += $(LCHDR_ZSTD)/common/fse_decompress.o
-OBJS += $(LCHDR_ZSTD)/common/pool.o
-OBJS += $(LCHDR_ZSTD)/common/threading.o
 OBJS += $(LCHDR_ZSTD)/common/xxhash.o
 OBJS += $(LCHDR_ZSTD)/common/zstd_common.o
 OBJS += $(LCHDR_ZSTD)/decompress/huf_decompress.o
 OBJS += $(LCHDR_ZSTD)/common/xxhash.o
 OBJS += $(LCHDR_ZSTD)/common/zstd_common.o
 OBJS += $(LCHDR_ZSTD)/decompress/huf_decompress.o
+OBJS += $(LCHDR_ZSTD)/decompress/huf_decompress_amd64.o
 OBJS += $(LCHDR_ZSTD)/decompress/zstd_ddict.o
 OBJS += $(LCHDR_ZSTD)/decompress/zstd_decompress_block.o
 OBJS += $(LCHDR_ZSTD)/decompress/zstd_decompress.o
 $(LCHDR_ZSTD)/common/%.o \
 OBJS += $(LCHDR_ZSTD)/decompress/zstd_ddict.o
 OBJS += $(LCHDR_ZSTD)/decompress/zstd_decompress_block.o
 OBJS += $(LCHDR_ZSTD)/decompress/zstd_decompress.o
 $(LCHDR_ZSTD)/common/%.o \
-$(LCHDR_ZSTD)/decompress/%.o: CFLAGS += -DZSTD_DISABLE_ASM -I$(LCHDR_ZSTD)
+$(LCHDR_ZSTD)/decompress/%.o: CFLAGS += -I$(LCHDR_ZSTD)
 $(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_ZSTD)
 libpcsxcore/cdriso.o: CFLAGS += -Wno-unused-function
 CFLAGS += -DHAVE_CHD -I$(LCHDR)/include
 $(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_ZSTD)
 libpcsxcore/cdriso.o: CFLAGS += -Wno-unused-function
 CFLAGS += -DHAVE_CHD -I$(LCHDR)/include
index 5c598c2..86b2720 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 5c598c2df3a7717552a76410d79f5af01ff51b1d
+Subproject commit 86b272076d542287d3f03952e7d4efe283e815bf
index 6a719ae..9b9149d 100644 (file)
@@ -1851,17 +1851,21 @@ strcasestr(const char *s, const char *find)
 
 static void set_retro_memmap(void)
 {
 
 static void set_retro_memmap(void)
 {
-#ifndef NDEBUG
+   uint64_t flags_ram = RETRO_MEMDESC_SYSTEM_RAM;
    struct retro_memory_map retromap = { 0 };
    struct retro_memory_map retromap = { 0 };
-   struct retro_memory_descriptor mmap = {
-      0, psxM, 0, 0, 0, 0, 0x200000
+   struct retro_memory_descriptor descs[] = {
+      { flags_ram, psxM, 0, 0x00000000, 0x5fe00000, 0, 0x200000 },
+      { flags_ram, psxH, 0, 0x1f800000, 0x7ffffc00, 0, 0x000400 },
+      // not ram but let the frontend patch it if it wants; should be last
+      { flags_ram, psxR, 0, 0x1fc00000, 0x5ff80000, 0, 0x080000 },
    };
 
    };
 
-   retromap.descriptors = &mmap;
-   retromap.num_descriptors = 1;
+   retromap.descriptors = descs;
+   retromap.num_descriptors = sizeof(descs) / sizeof(descs[0]);
+   if (Config.HLE)
+      retromap.num_descriptors--;
 
    environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &retromap);
 
    environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &retromap);
-#endif
 }
 
 static void show_notification(const char *msg_str,
 }
 
 static void show_notification(const char *msg_str,
@@ -2191,6 +2195,8 @@ bool retro_load_game(const struct retro_game_info *info)
 
    if (check_unsatisfied_libcrypt())
       show_notification("LibCrypt protected game with missing SBI detected", 3000, 3);
 
    if (check_unsatisfied_libcrypt())
       show_notification("LibCrypt protected game with missing SBI detected", 3000, 3);
+   if (Config.TurboCD)
+      show_notification("TurboCD is ON", 700, 2);
 
    return true;
 }
 
    return true;
 }
@@ -2451,7 +2457,7 @@ static void update_variables(bool in_flight)
    }
 
    var.value = NULL;
    }
 
    var.value = NULL;
-   var.key = "pcsx_rearmed_neon_enhancement_tex_adj";
+   var.key = "pcsx_rearmed_neon_enhancement_tex_adj_v2";
 
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
    {
 
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
    {
@@ -2473,6 +2479,16 @@ static void update_variables(bool in_flight)
          display_internal_fps = true;
    }
 
          display_internal_fps = true;
    }
 
+   var.value = NULL;
+   var.key = "pcsx_rearmed_cd_turbo";
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      if (strcmp(var.value, "enabled") == 0)
+         Config.TurboCD = true;
+      else
+         Config.TurboCD = false;
+   }
+
 #ifdef HAVE_CDROM
    var.value = NULL;
    var.key = "pcsx_rearmed_phys_cd_readahead";
 #ifdef HAVE_CDROM
    var.value = NULL;
    var.key = "pcsx_rearmed_phys_cd_readahead";
@@ -2747,6 +2763,18 @@ static void update_variables(bool in_flight)
       pl_rearmed_cbs.screen_centering_y = atoi(var.value);
    }
 
       pl_rearmed_cbs.screen_centering_y = atoi(var.value);
    }
 
+   var.value = NULL;
+   var.key = "pcsx_rearmed_show_overscan";
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      if (strcmp(var.value, "auto") == 0)
+         pl_rearmed_cbs.show_overscan = 1;
+      else if (strcmp(var.value, "hack") == 0)
+         pl_rearmed_cbs.show_overscan = 2;
+      else
+         pl_rearmed_cbs.show_overscan = 0;
+   }
+
 #ifdef THREAD_RENDERING
    var.key = "pcsx_rearmed_gpu_thread_rendering";
    var.value = NULL;
 #ifdef THREAD_RENDERING
    var.key = "pcsx_rearmed_gpu_thread_rendering";
    var.value = NULL;
index 451ee47..f20567b 100644 (file)
@@ -97,13 +97,11 @@ struct retro_core_option_v2_category option_cats_us[] = {
       "Compatibility Fixes",
       "Configure settings/workarounds required for correct operation of specific games."
    },
       "Compatibility Fixes",
       "Configure settings/workarounds required for correct operation of specific games."
    },
-#if !defined(DRC_DISABLE) && !defined(LIGHTREC)
    {
       "speed_hack",
       "Speed Hacks (Advanced)",
       "Configure hacks that may improve performance at the expense of decreased accuracy/stability."
    },
    {
       "speed_hack",
       "Speed Hacks (Advanced)",
       "Configure hacks that may improve performance at the expense of decreased accuracy/stability."
    },
-#endif
    { NULL, NULL, NULL },
 };
 
    { NULL, NULL, NULL },
 };
 
@@ -153,7 +151,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
    },
    {
       "pcsx_rearmed_memcard2",
    },
    {
       "pcsx_rearmed_memcard2",
-      "Enable Second Memory Card (Shared)",
+      "Second Memory Card (Shared)",
       NULL,
       "Emulate a second memory card in slot 2. This will be shared by all games.",
       NULL,
       NULL,
       "Emulate a second memory card in slot 2. This will be shared by all games.",
       NULL,
@@ -455,6 +453,21 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       },
       "auto",
    },
       },
       "auto",
    },
+   {
+      "pcsx_rearmed_show_overscan",
+      "(GPU) Horizontal overscan",
+      NULL,
+      "The PSX can display graphics way into the horizontal borders, even if most screens would crop it. This option tries to display all such graphics. Note that this may result in unusual resolutions that your device might not handle well. The 'Hack' option is intended for the widescreen hacks.",
+      NULL,
+      "video",
+      {
+         { "disabled", NULL },
+         { "auto", "Auto" },
+         { "hack", "Hack" },
+         { NULL, NULL },
+      },
+      "disabled",
+   },
    {
       "pcsx_rearmed_screen_centering",
       "(GPU) Screen centering",
    {
       "pcsx_rearmed_screen_centering",
       "(GPU) Screen centering",
@@ -474,7 +487,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 #define V(x) { #x, NULL }
    {
       "pcsx_rearmed_screen_centering_x",
 #define V(x) { #x, NULL }
    {
       "pcsx_rearmed_screen_centering_x",
-      "(GPU) Manual screen centering X",
+      "(GPU) Manual position X",
       NULL,
       "X offset of the frame buffer. Only effective when 'Screen centering' is set to 'Manual'.",
       NULL,
       NULL,
       "X offset of the frame buffer. Only effective when 'Screen centering' is set to 'Manual'.",
       NULL,
@@ -487,7 +500,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
    },
    {
       "pcsx_rearmed_screen_centering_y",
    },
    {
       "pcsx_rearmed_screen_centering_y",
-      "(GPU) Manual screen centering Y",
+      "(GPU) Manual position Y",
       NULL,
       "Y offset of the frame buffer. Only effective when 'Screen centering' is set to 'Manual'.",
       NULL,
       NULL,
       "Y offset of the frame buffer. Only effective when 'Screen centering' is set to 'Manual'.",
       NULL,
@@ -533,7 +546,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
    {
       "pcsx_rearmed_neon_enhancement_no_main",
       "(GPU) Enhanced Resolution Speed Hack",
    {
       "pcsx_rearmed_neon_enhancement_no_main",
       "(GPU) Enhanced Resolution Speed Hack",
-      "Enhanced Resolution Speed Hack",
+      "Enh. Res. Speed Hack",
       "('Enhanced Resolution' Hack) Improves performance but reduces compatibility and may cause rendering errors.",
       NULL,
       "gpu_neon",
       "('Enhanced Resolution' Hack) Improves performance but reduces compatibility and may cause rendering errors.",
       NULL,
       "gpu_neon",
@@ -545,10 +558,10 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       "disabled",
    },
    {
       "disabled",
    },
    {
-      "pcsx_rearmed_neon_enhancement_tex_adj",
+      "pcsx_rearmed_neon_enhancement_tex_adj_v2",
       "(GPU) Enhanced Resolution Texture Adjustment",
       "(GPU) Enhanced Resolution Texture Adjustment",
-      "Enhanced Resolution Texture Adjustment",
-      "('Enhanced Resolution' Hack) Attempts to solve some texturing issues in some games, but causes new ones in others.",
+      "Enh. Res. Texture Fixup",
+      "('Enhanced Resolution' Hack) Solves some texturing issues in some games in Enhanced Resolution mode. May cause a small performance hit.",
       NULL,
       "gpu_neon",
       {
       NULL,
       "gpu_neon",
       {
@@ -556,7 +569,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
          { "enabled",  NULL },
          { NULL, NULL },
       },
          { "enabled",  NULL },
          { NULL, NULL },
       },
-      "disabled",
+      "enabled",
    },
 #endif /* GPU_NEON */
 #ifdef GPU_PEOPS
    },
 #endif /* GPU_NEON */
 #ifdef GPU_PEOPS
@@ -1572,6 +1585,20 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       },
       "disabled",
    },
       },
       "disabled",
    },
+   {
+      "pcsx_rearmed_cd_turbo",
+      "Turbo CD",
+      NULL,
+      "This makes the emulated CD-ROM extremely fast and can reduce loading times in some cases. Warning: many games were not programmed to handle such a speed. The game (or even the emulator) MAY CRASH at ANY TIME if this is enabled.",
+      NULL,
+      "speed_hack",
+      {
+         { "disabled", NULL },
+         { "enabled",  NULL },
+         { NULL, NULL },
+      },
+      "disabled",
+   },
 #if !defined(DRC_DISABLE) && !defined(LIGHTREC)
    {
       "pcsx_rearmed_nocompathacks",
 #if !defined(DRC_DISABLE) && !defined(LIGHTREC)
    {
       "pcsx_rearmed_nocompathacks",
@@ -1634,13 +1661,13 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       "pcsx_rearmed_nostalls",
       "Disable CPU/GTE Stalls",
       NULL,
       "pcsx_rearmed_nostalls",
       "Disable CPU/GTE Stalls",
       NULL,
-      "Will cause some games to run too quickly."
+      "Will cause some games to run too quickly. Should be disabled in almost all cases."
 #if defined(LIGHTREC)
       " Interpreter only."
 #endif
       ,
       NULL,
 #if defined(LIGHTREC)
       " Interpreter only."
 #endif
       ,
       NULL,
-      "compat_hack",
+      "speed_hack",
       {
          { "disabled", NULL },
          { "enabled",  NULL },
       {
          { "disabled", NULL },
          { "enabled",  NULL },
index ce7eca6..82e670e 100644 (file)
@@ -141,6 +141,7 @@ void emu_set_default_config(void)
        pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto
        pl_rearmed_cbs.gpu_neon.enhancement_enable =
        pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0;
        pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto
        pl_rearmed_cbs.gpu_neon.enhancement_enable =
        pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0;
+       pl_rearmed_cbs.gpu_neon.enhancement_tex_adj = 1;
        pl_rearmed_cbs.gpu_peops.iUseDither = 0;
        pl_rearmed_cbs.gpu_peops.dwActFixes = 1<<7;
        pl_rearmed_cbs.gpu_unai.ilace_force = 0;
        pl_rearmed_cbs.gpu_peops.iUseDither = 0;
        pl_rearmed_cbs.gpu_peops.dwActFixes = 1<<7;
        pl_rearmed_cbs.gpu_unai.ilace_force = 0;
@@ -417,6 +418,8 @@ void emu_on_new_cd(int show_hud_msg)
                SysPrintf("note: running with HLE BIOS, expect compatibility problems\n");
                SysPrintf("----------------------------------------------------------\n");
        }
                SysPrintf("note: running with HLE BIOS, expect compatibility problems\n");
                SysPrintf("----------------------------------------------------------\n");
        }
+       if (Config.TurboCD)
+               SysPrintf("note: TurboCD is enabled, this breaks games\n");
 
        if (show_hud_msg) {
                if (check_unsatisfied_libcrypt())
 
        if (show_hud_msg) {
                if (check_unsatisfied_libcrypt())
index 58efd21..15034a9 100644 (file)
@@ -40,6 +40,7 @@
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
+#include "../libpcsxcore/ppf.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "psemu_plugin_defs.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "psemu_plugin_defs.h"
@@ -92,6 +93,7 @@ typedef enum
        MA_OPT_SCANLINES,
        MA_OPT_SCANLINE_LEVEL,
        MA_OPT_CENTERING,
        MA_OPT_SCANLINES,
        MA_OPT_SCANLINE_LEVEL,
        MA_OPT_CENTERING,
+       MA_OPT_OVERSCAN,
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
@@ -410,6 +412,7 @@ static const struct {
        CE_CONFIG_VAL(GpuListWalking),
        CE_CONFIG_VAL(FractionalFramerate),
        CE_CONFIG_VAL(PreciseExceptions),
        CE_CONFIG_VAL(GpuListWalking),
        CE_CONFIG_VAL(FractionalFramerate),
        CE_CONFIG_VAL(PreciseExceptions),
+       CE_CONFIG_VAL(TurboCD),
        CE_INTVAL(region),
        CE_INTVAL_V(g_scaler, 3),
        CE_INTVAL(g_gamma),
        CE_INTVAL(region),
        CE_INTVAL_V(g_scaler, 3),
        CE_INTVAL(g_gamma),
@@ -451,7 +454,7 @@ static const struct {
        CE_INTVAL_P(gpu_neon.allow_interlace),
        CE_INTVAL_P(gpu_neon.enhancement_enable),
        CE_INTVAL_P(gpu_neon.enhancement_no_main),
        CE_INTVAL_P(gpu_neon.allow_interlace),
        CE_INTVAL_P(gpu_neon.enhancement_enable),
        CE_INTVAL_P(gpu_neon.enhancement_no_main),
-       CE_INTVAL_P(gpu_neon.enhancement_tex_adj),
+       CE_INTVAL_PV(gpu_neon.enhancement_tex_adj, 2),
        CE_INTVAL_P(gpu_peopsgl.bDrawDither),
        CE_INTVAL_P(gpu_peopsgl.iFilterType),
        CE_INTVAL_P(gpu_peopsgl.iFrameTexType),
        CE_INTVAL_P(gpu_peopsgl.bDrawDither),
        CE_INTVAL_P(gpu_peopsgl.iFilterType),
        CE_INTVAL_P(gpu_peopsgl.iFrameTexType),
@@ -465,6 +468,7 @@ static const struct {
        CE_INTVAL_P(screen_centering_type),
        CE_INTVAL_P(screen_centering_x),
        CE_INTVAL_P(screen_centering_y),
        CE_INTVAL_P(screen_centering_type),
        CE_INTVAL_P(screen_centering_x),
        CE_INTVAL_P(screen_centering_y),
+       CE_INTVAL_P(show_overscan),
        CE_INTVAL(spu_config.iUseReverb),
        CE_INTVAL(spu_config.iXAPitch),
        CE_INTVAL(spu_config.iUseInterpolation),
        CE_INTVAL(spu_config.iUseReverb),
        CE_INTVAL(spu_config.iXAPitch),
        CE_INTVAL(spu_config.iUseInterpolation),
@@ -739,7 +743,7 @@ static const char *filter_exts[] = {
        #ifdef HAVE_CHD
        "chd",
        #endif
        #ifdef HAVE_CHD
        "chd",
        #endif
-       "bz",  "znx", "pbp", "cbn", NULL
+       "bz",  "znx", "pbp", "cbn", "ppf", NULL
 };
 
 // rrrr rggg gggb bbbb
 };
 
 // rrrr rggg gggb bbbb
@@ -1278,6 +1282,7 @@ static const char *men_soft_filter[] = { "None",
        NULL };
 static const char *men_dummy[] = { NULL };
 static const char *men_centering[] = { "Auto", "Ingame", "Borderless", "Force", NULL };
        NULL };
 static const char *men_dummy[] = { NULL };
 static const char *men_centering[] = { "Auto", "Ingame", "Borderless", "Force", NULL };
+static const char *men_overscan[] = { "OFF", "Auto", "Hack", NULL };
 static const char h_scaler[]    = "int. 2x  - scales w. or h. 2x if it fits on screen\n"
                                  "int. 4:3 - uses integer if possible, else fractional";
 static const char h_cscaler[]   = "Displays the scaler layer, you can resize it\n"
 static const char h_scaler[]    = "int. 2x  - scales w. or h. 2x if it fits on screen\n"
                                  "int. 4:3 - uses integer if possible, else fractional";
 static const char h_cscaler[]   = "Displays the scaler layer, you can resize it\n"
@@ -1374,6 +1379,7 @@ static int menu_loop_cscaler(int id, int keys)
 static menu_entry e_menu_gfx_options[] =
 {
        mee_enum      ("Screen centering",         MA_OPT_CENTERING, pl_rearmed_cbs.screen_centering_type, men_centering),
 static menu_entry e_menu_gfx_options[] =
 {
        mee_enum      ("Screen centering",         MA_OPT_CENTERING, pl_rearmed_cbs.screen_centering_type, men_centering),
+       mee_enum      ("Show overscan",            MA_OPT_OVERSCAN, pl_rearmed_cbs.show_overscan, men_overscan),
        mee_enum_h    ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler, h_scaler),
        mee_enum      ("Video output mode",        MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
        mee_enum_h    ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler, h_scaler),
        mee_enum      ("Video output mode",        MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
@@ -1405,10 +1411,12 @@ static int menu_loop_gfx_options(int id, int keys)
 static const char h_gpu_neon[] =
        "Configure built-in NEON GPU plugin";
 static const char h_gpu_neon_enhanced[] =
 static const char h_gpu_neon[] =
        "Configure built-in NEON GPU plugin";
 static const char h_gpu_neon_enhanced[] =
-       "Renders in double resolution at the cost of lower performance\n"
+       "Renders in double resolution at perf. cost\n"
        "(not available for high resolution games)";
 static const char h_gpu_neon_enhanced_hack[] =
        "Speed hack for above option (glitches some games)";
        "(not available for high resolution games)";
 static const char h_gpu_neon_enhanced_hack[] =
        "Speed hack for above option (glitches some games)";
+static const char h_gpu_neon_enhanced_texadj[] =
+       "Solves some Enh. res. texture issues, some perf hit";
 static const char *men_gpu_interlace[] = { "Off", "On", "Auto", NULL };
 
 static menu_entry e_menu_plugin_gpu_neon[] =
 static const char *men_gpu_interlace[] = { "Off", "On", "Auto", NULL };
 
 static menu_entry e_menu_plugin_gpu_neon[] =
@@ -1416,7 +1424,7 @@ 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_onoff_h   ("Enhanced resolution",        0, pl_rearmed_cbs.gpu_neon.enhancement_enable, 1, h_gpu_neon_enhanced),
        mee_onoff_h   ("Enhanced res. speed hack",   0, pl_rearmed_cbs.gpu_neon.enhancement_no_main, 1, h_gpu_neon_enhanced_hack),
        mee_enum      ("Enable interlace mode",      0, pl_rearmed_cbs.gpu_neon.allow_interlace, men_gpu_interlace),
        mee_onoff_h   ("Enhanced resolution",        0, pl_rearmed_cbs.gpu_neon.enhancement_enable, 1, h_gpu_neon_enhanced),
        mee_onoff_h   ("Enhanced res. speed hack",   0, pl_rearmed_cbs.gpu_neon.enhancement_no_main, 1, h_gpu_neon_enhanced_hack),
-       mee_onoff     ("Enh. res. texture adjust",   0, pl_rearmed_cbs.gpu_neon.enhancement_tex_adj, 1),
+       mee_onoff_h   ("Enh. res. texture adjust",   0, pl_rearmed_cbs.gpu_neon.enhancement_tex_adj, 1, h_gpu_neon_enhanced_texadj),
        mee_end,
 };
 
        mee_end,
 };
 
@@ -1660,10 +1668,11 @@ static const char h_cfg_gpul[]   = "Try enabling this if the game misses some gr
                                   "causes a performance hit";
 static const char h_cfg_ffps[]   = "Instead of 50/60fps for PAL/NTSC use ~49.75/59.81\n"
                                   "Closer to real hw but doesn't match modern displays.";
                                   "causes a performance hit";
 static const char h_cfg_ffps[]   = "Instead of 50/60fps for PAL/NTSC use ~49.75/59.81\n"
                                   "Closer to real hw but doesn't match modern displays.";
+static const char h_cfg_tcd[]    = "Greatly reduce CD load times. Breaks some games.";
 static const char h_cfg_psxclk[]  = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n"
                                    "(adjust this if the game is too slow/too fast/hangs)";
 
 static const char h_cfg_psxclk[]  = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n"
                                    "(adjust this if the game is too slow/too fast/hangs)";
 
-enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, AMO_GPUL, AMO_FFPS };
+enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, AMO_GPUL, AMO_FFPS, AMO_TCD };
 
 static menu_entry e_menu_adv_options[] =
 {
 
 static menu_entry e_menu_adv_options[] =
 {
@@ -1676,6 +1685,7 @@ static menu_entry e_menu_adv_options[] =
        mee_onoff_h   ("BP exception emulation", 0, menu_iopts[AMO_BP],   1, h_cfg_exc),
        mee_enum_h    ("GPU l-list slow walking",0, menu_iopts[AMO_GPUL], men_autooo, h_cfg_gpul),
        mee_enum_h    ("Fractional framerate",   0, menu_iopts[AMO_FFPS], men_autooo, h_cfg_ffps),
        mee_onoff_h   ("BP exception emulation", 0, menu_iopts[AMO_BP],   1, h_cfg_exc),
        mee_enum_h    ("GPU l-list slow walking",0, menu_iopts[AMO_GPUL], men_autooo, h_cfg_gpul),
        mee_enum_h    ("Fractional framerate",   0, menu_iopts[AMO_FFPS], men_autooo, h_cfg_ffps),
+       mee_onoff_h   ("Turbo CD-ROM ",          0, menu_iopts[AMO_TCD], 1, h_cfg_tcd),
 #if !defined(DRC_DISABLE) || defined(LIGHTREC)
        mee_onoff_h   ("Disable dynarec (slow!)",0, menu_iopts[AMO_CPU],  1, h_cfg_nodrc),
 #endif
 #if !defined(DRC_DISABLE) || defined(LIGHTREC)
        mee_onoff_h   ("Disable dynarec (slow!)",0, menu_iopts[AMO_CPU],  1, h_cfg_nodrc),
 #endif
@@ -1696,6 +1706,7 @@ static int menu_loop_adv_options(int id, int keys)
                { &Config.icache_emulation, &menu_iopts[AMO_IC] },
                { &Config.PreciseExceptions, &menu_iopts[AMO_BP] },
                { &Config.Cpu,     &menu_iopts[AMO_CPU] },
                { &Config.icache_emulation, &menu_iopts[AMO_IC] },
                { &Config.PreciseExceptions, &menu_iopts[AMO_BP] },
                { &Config.Cpu,     &menu_iopts[AMO_CPU] },
+               { &Config.TurboCD, &menu_iopts[AMO_TCD] },
        };
        int i;
        for (i = 0; i < ARRAY_SIZE(opts); i++)
        };
        int i;
        for (i = 0; i < ARRAY_SIZE(opts); i++)
@@ -2153,6 +2164,18 @@ static int run_exe(void)
 static int run_cd_image(const char *fname)
 {
        int autoload_state = g_autostateld_opt;
 static int run_cd_image(const char *fname)
 {
        int autoload_state = g_autostateld_opt;
+       size_t fname_len = strlen(fname);
+       const char *ppfname = NULL;
+       char fname2[256];
+
+       // simle ppf handling, like game.chd.ppf
+       if (4 < fname_len && fname_len < sizeof(fname2)
+           && strcasecmp(fname + fname_len - 4, ".ppf") == 0) {
+               memcpy(fname2, fname, fname_len - 4);
+               fname2[fname_len - 4] = 0;
+               ppfname = fname;
+               fname = fname2;
+       }
 
        ready_to_go = 0;
        reload_plugins(fname);
 
        ready_to_go = 0;
        reload_plugins(fname);
@@ -2166,6 +2189,8 @@ static int run_cd_image(const char *fname)
                menu_update_msg("unsupported/invalid CD image");
                return -1;
        }
                menu_update_msg("unsupported/invalid CD image");
                return -1;
        }
+       if (ppfname)
+               BuildPPFCache(ppfname);
 
        SysReset();
 
 
        SysReset();
 
@@ -2181,7 +2206,7 @@ static int run_cd_image(const char *fname)
 
        if (autoload_state) {
                unsigned int newest = 0;
 
        if (autoload_state) {
                unsigned int newest = 0;
-               int time, slot, newest_slot = -1;
+               int time = 0, slot, newest_slot = -1;
 
                for (slot = 0; slot < 10; slot++) {
                        if (emu_check_save_file(slot, &time)) {
 
                for (slot = 0; slot < 10; slot++) {
                        if (emu_check_save_file(slot, &time)) {
index 7879e70..71fcd3f 100644 (file)
@@ -115,6 +115,7 @@ struct rearmed_cbs {
        int screen_centering_type_default;
        int screen_centering_x;
        int screen_centering_y;
        int screen_centering_type_default;
        int screen_centering_x;
        int screen_centering_y;
+       int show_overscan;
 };
 
 extern struct rearmed_cbs pl_rearmed_cbs;
 };
 
 extern struct rearmed_cbs pl_rearmed_cbs;
index cd2d202..243c036 100644 (file)
@@ -1457,7 +1457,7 @@ static long CALLBACK ISOopen(void) {
                }
        }
 
                }
        }
 
-       SysPrintf("%s.\n", image_str);
+       SysPrintf("%s (%lld bytes).\n", image_str, (long long)size_main);
 
        PrintTracks();
 
 
        PrintTracks();
 
index 1615e18..335c2dc 100644 (file)
@@ -111,7 +111,7 @@ static struct {
        u8 AdpcmActive;
        u32 LastReadSeekCycles;
 
        u8 AdpcmActive;
        u32 LastReadSeekCycles;
 
-       u8 unused7;
+       u8 RetryDetected;
 
        u8 DriveState; // enum drive_state
        u8 FastForward;
 
        u8 DriveState; // enum drive_state
        u8 FastForward;
@@ -232,7 +232,7 @@ enum drive_state {
        DRIVESTATE_SEEK,
 };
 
        DRIVESTATE_SEEK,
 };
 
-static struct CdrStat stat;
+static struct CdrStat cdr_stat;
 
 static unsigned int msf2sec(const u8 *msf) {
        return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
 
 static unsigned int msf2sec(const u8 *msf) {
        return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
@@ -327,10 +327,10 @@ void cdrLidSeekInterrupt(void)
                //StopReading();
                SetPlaySeekRead(cdr.StatP, 0);
 
                //StopReading();
                SetPlaySeekRead(cdr.StatP, 0);
 
-               if (CDR_getStatus(&stat) == -1)
+               if (CDR_getStatus(&cdr_stat) == -1)
                        return;
 
                        return;
 
-               if (stat.Status & STATUS_SHELLOPEN)
+               if (cdr_stat.Status & STATUS_SHELLOPEN)
                {
                        memset(cdr.Prev, 0xff, sizeof(cdr.Prev));
                        cdr.DriveState = DRIVESTATE_LID_OPEN;
                {
                        memset(cdr.Prev, 0xff, sizeof(cdr.Prev));
                        cdr.DriveState = DRIVESTATE_LID_OPEN;
@@ -339,8 +339,8 @@ void cdrLidSeekInterrupt(void)
                break;
 
        case DRIVESTATE_LID_OPEN:
                break;
 
        case DRIVESTATE_LID_OPEN:
-               if (CDR_getStatus(&stat) == -1)
-                       stat.Status &= ~STATUS_SHELLOPEN;
+               if (CDR_getStatus(&cdr_stat) == -1)
+                       cdr_stat.Status &= ~STATUS_SHELLOPEN;
 
                // 02, 12, 10
                if (!(cdr.StatP & STATUS_SHELLOPEN)) {
 
                // 02, 12, 10
                if (!(cdr.StatP & STATUS_SHELLOPEN)) {
@@ -367,7 +367,7 @@ void cdrLidSeekInterrupt(void)
                else if (cdr.StatP & STATUS_ROTATING) {
                        cdr.StatP &= ~STATUS_ROTATING;
                }
                else if (cdr.StatP & STATUS_ROTATING) {
                        cdr.StatP &= ~STATUS_ROTATING;
                }
-               else if (!(stat.Status & STATUS_SHELLOPEN)) {
+               else if (!(cdr_stat.Status & STATUS_SHELLOPEN)) {
                        // closed now
                        CheckCdrom();
 
                        // closed now
                        CheckCdrom();
 
@@ -576,6 +576,14 @@ static void cdrPlayInterrupt_Autopause()
                cdr.ReportDelay--;
 }
 
                cdr.ReportDelay--;
 }
 
+static boolean canDoTurbo(void)
+{
+       u32 c = psxRegs.cycle;
+       return Config.TurboCD && !cdr.RetryDetected && !cdr.AdpcmActive
+               //&& c - psxRegs.intCycle[PSXINT_SPUDMA].sCycle > (u32)cdReadTime * 2
+               && c - psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle > (u32)cdReadTime * 16;
+}
+
 static int cdrSeekTime(unsigned char *target)
 {
        int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target);
 static int cdrSeekTime(unsigned char *target)
 {
        int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target);
@@ -654,6 +662,11 @@ static void msfiSub(u8 *msfi, u32 count)
        }
 }
 
        }
 }
 
+static int msfiEq(const u8 *a, const u8 *b)
+{
+       return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
+}
+
 void cdrPlayReadInterrupt(void)
 {
        int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
 void cdrPlayReadInterrupt(void)
 {
        int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
@@ -708,8 +721,8 @@ void cdrPlayReadInterrupt(void)
 
 static void softReset(void)
 {
 
 static void softReset(void)
 {
-       CDR_getStatus(&stat);
-       if (stat.Status & STATUS_SHELLOPEN) {
+       CDR_getStatus(&cdr_stat);
+       if (cdr_stat.Status & STATUS_SHELLOPEN) {
                cdr.DriveState = DRIVESTATE_LID_OPEN;
                cdr.StatP = STATUS_SHELLOPEN;
        }
                cdr.DriveState = DRIVESTATE_LID_OPEN;
                cdr.StatP = STATUS_SHELLOPEN;
        }
@@ -822,6 +835,11 @@ void cdrInterrupt(void) {
                        {
                                for (i = 0; i < 3; i++)
                                        set_loc[i] = btoi(cdr.Param[i]);
                        {
                                for (i = 0; i < 3; i++)
                                        set_loc[i] = btoi(cdr.Param[i]);
+                               if ((msfiEq(cdr.SetSector, set_loc)) //|| msfiEq(cdr.Param, cdr.Transfer))
+                                               && !cdr.SetlocPending)
+                                       cdr.RetryDetected++;
+                               else
+                                       cdr.RetryDetected = 0;
                                memcpy(cdr.SetSector, set_loc, 3);
                                cdr.SetSector[3] = 0;
                                cdr.SetlocPending = 1;
                                memcpy(cdr.SetSector, set_loc, 3);
                                cdr.SetSector[3] = 0;
                                cdr.SetlocPending = 1;
@@ -971,27 +989,22 @@ void cdrInterrupt(void) {
                        cdr.sectorsRead = 0;
 
                        /*
                        cdr.sectorsRead = 0;
 
                        /*
-                       Gundam Battle Assault 2: much slower (*)
-                       - Fixes boot, gameplay
-
-                       Hokuto no Ken 2: slower
-                       - Fixes intro + subtitles
-
-                       InuYasha - Feudal Fairy Tale: slower
-                       - Fixes battles
+                       Gundam Battle Assault 2
+                       Hokuto no Ken 2
+                       InuYasha - Feudal Fairy Tale
+                       Dance Dance Revolution Konamix
+                       Digimon Rumble Arena
+                       ...
                        */
                        */
-                       /* Gameblabla - Tightening the timings (as taken from Duckstation). 
-                        * The timings from Duckstation are based upon hardware tests.
-                        * Mednafen's timing don't work for Gundam Battle Assault 2 in PAL/50hz mode,
-                        * seems to be timing sensitive as it can depend on the CPU's clock speed.
-                        * */
                        if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ)))
                        {
                                second_resp_time = 7000;
                        }
                        else
                        {
                        if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ)))
                        {
                                second_resp_time = 7000;
                        }
                        else
                        {
-                               second_resp_time = (((cdr.Mode & MODE_SPEED) ? 1 : 2) * 1097107);
+                               second_resp_time = 2100011;
+                               // a hack to try to avoid weird cmd vs irq1 races causing games to retry
+                               second_resp_time += (cdr.RetryDetected & 15) * 100001;
                        }
                        SetPlaySeekRead(cdr.StatP, 0);
                        DriveStateOld = cdr.DriveState;
                        }
                        SetPlaySeekRead(cdr.StatP, 0);
                        DriveStateOld = cdr.DriveState;
@@ -1111,7 +1124,8 @@ void cdrInterrupt(void) {
                        StopReading();
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK | STATUS_ROTATING);
 
                        StopReading();
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK | STATUS_ROTATING);
 
-                       seekTime = cdrSeekTime(cdr.SetSector);
+                       if (!canDoTurbo())
+                               seekTime = cdrSeekTime(cdr.SetSector);
                        memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
                        cdr.DriveState = DRIVESTATE_SEEK;
                        CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
                        memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
                        cdr.DriveState = DRIVESTATE_SEEK;
                        CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
@@ -1179,11 +1193,11 @@ void cdrInterrupt(void) {
                        cdr.Result[3] = 0;
 
                        // 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
                        cdr.Result[3] = 0;
 
                        // 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
-                       if (CDR_getStatus(&stat) == -1 || stat.Type == 0 || stat.Type == 0xff) {
+                       if (CDR_getStatus(&cdr_stat) == -1 || cdr_stat.Type == 0 || cdr_stat.Type == 0xff) {
                                cdr.Result[1] = 0xc0;
                        }
                        else {
                                cdr.Result[1] = 0xc0;
                        }
                        else {
-                               if (stat.Type == 2)
+                               if (cdr_stat.Type == 2)
                                        cdr.Result[1] |= 0x10;
                                if (CdromId[0] == '\0')
                                        cdr.Result[1] |= 0x80;
                                        cdr.Result[1] |= 0x10;
                                if (CdromId[0] == '\0')
                                        cdr.Result[1] |= 0x80;
@@ -1260,6 +1274,8 @@ void cdrInterrupt(void) {
                        cycles += seekTime;
                        if (Config.hacks.cdr_read_timing)
                                cycles = cdrAlignTimingHack(cycles);
                        cycles += seekTime;
                        if (Config.hacks.cdr_read_timing)
                                cycles = cdrAlignTimingHack(cycles);
+                       else if (canDoTurbo())
+                               cycles = cdReadTime / 2;
                        CDRPLAYREAD_INT(cycles, 1);
 
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK);
                        CDRPLAYREAD_INT(cycles, 1);
 
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK);
@@ -1451,6 +1467,8 @@ unsigned char cdrRead0(void) {
        cdr.Ctrl |= cdr.AdpcmActive << 2;
        cdr.Ctrl |= cdr.ResultReady << 5;
 
        cdr.Ctrl |= cdr.AdpcmActive << 2;
        cdr.Ctrl |= cdr.ResultReady << 5;
 
+       //cdr.Ctrl &= ~0x40;
+       //if (cdr.FifoOffset != DATA_SIZE)
        cdr.Ctrl |= 0x40; // data fifo not empty
 
        // What means the 0x10 and the 0x08 bits? I only saw it used by the bios
        cdr.Ctrl |= 0x40; // data fifo not empty
 
        // What means the 0x10 and the 0x08 bits? I only saw it used by the bios
@@ -1650,7 +1668,7 @@ void cdrWrite3(unsigned char rt) {
 }
 
 void psxDma3(u32 madr, u32 bcr, u32 chcr) {
 }
 
 void psxDma3(u32 madr, u32 bcr, u32 chcr) {
-       u32 cdsize, max_words;
+       u32 cdsize, max_words, cycles;
        int size;
        u8 *ptr;
 
        int size;
        u8 *ptr;
 
@@ -1696,7 +1714,8 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                        }
                        psxCpu->Clear(madr, cdsize / 4);
 
                        }
                        psxCpu->Clear(madr, cdsize / 4);
 
-                       set_event(PSXINT_CDRDMA, (cdsize / 4) * 24);
+                       cycles = (cdsize / 4) * 24;
+                       set_event(PSXINT_CDRDMA, cycles);
 
                        HW_DMA3_CHCR &= SWAPu32(~0x10000000);
                        if (chcr & 0x100) {
 
                        HW_DMA3_CHCR &= SWAPu32(~0x10000000);
                        if (chcr & 0x100) {
@@ -1705,8 +1724,10 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                        }
                        else {
                                // halted
                        }
                        else {
                                // halted
-                               psxRegs.cycle += (cdsize/4) * 24 - 20;
+                               psxRegs.cycle += cycles - 20;
                        }
                        }
+                       if (canDoTurbo() && cdr.Reading && cdr.FifoOffset >= 2048)
+                               CDRPLAYREAD_INT(cycles + 4096, 1);
                        return;
 
                default:
                        return;
 
                default:
index ef990ac..159b7e4 100644 (file)
@@ -120,6 +120,8 @@ cycle_multiplier_overrides[] =
        { 222, { "SLES01549", "SLES02063", "SLES02064" } },
        /* Digimon World */
        { 153, { "SLUS01032", "SLES02914" } },
        { 222, { "SLES01549", "SLES02063", "SLES02064" } },
        /* Digimon World */
        { 153, { "SLUS01032", "SLES02914" } },
+       /* Power Rangers: Lightspeed Rescue - jumping fails if FPS is over 30 */
+       { 310, { "SLUS01114", "SLES03286" } },
        /* Syphon Filter - reportedly hangs under unknown conditions */
        { 169, { "SCUS94240" } },
        /* Psychic Detective - some weird race condition in the game's cdrom code */
        /* Syphon Filter - reportedly hangs under unknown conditions */
        { 169, { "SCUS94240" } },
        /* Psychic Detective - some weird race condition in the game's cdrom code */
index 889639d..aafe522 100644 (file)
@@ -379,7 +379,7 @@ int CheckCdrom() {
        time[2] = itob(0x10);
 
        if (!Config.HLE && Config.SlowBoot) {
        time[2] = itob(0x10);
 
        if (!Config.HLE && Config.SlowBoot) {
-               // boot to BIOS in case of CDDA ir lid open
+               // boot to BIOS in case of CDDA or lid is open
                CDR_getStatus(&stat);
                if ((stat.Status & 0x10) || stat.Type == 2 || !CDR_readTrack(time))
                        return 0;
                CDR_getStatus(&stat);
                if ((stat.Status & 0x10) || stat.Type == 2 || !CDR_readTrack(time))
                        return 0;
@@ -466,7 +466,7 @@ int CheckCdrom() {
        
        Apply_Hacks_Cdrom();
 
        
        Apply_Hacks_Cdrom();
 
-       BuildPPFCache();
+       BuildPPFCache(NULL);
 
        return 0;
 }
 
        return 0;
 }
index f37687c..6a88e05 100644 (file)
@@ -181,7 +181,7 @@ static void AddToPPF(s32 ladr, s32 pos, s32 anz, unsigned char *ppfmem) {
        }
 }
 
        }
 }
 
-void BuildPPFCache() {
+void BuildPPFCache(const char *fname) {
        FILE                    *ppffile;
        char                    buffer[12];
        char                    method, undo = 0, blockcheck = 0;
        FILE                    *ppffile;
        char                    buffer[12];
        char                    method, undo = 0, blockcheck = 0;
@@ -196,23 +196,25 @@ void BuildPPFCache() {
 
        if (CdromId[0] == '\0') return;
 
 
        if (CdromId[0] == '\0') return;
 
-       // Generate filename in the format of SLUS_123.45
-       buffer[0] = toupper(CdromId[0]);
-       buffer[1] = toupper(CdromId[1]);
-       buffer[2] = toupper(CdromId[2]);
-       buffer[3] = toupper(CdromId[3]);
-       buffer[4] = '_';
-       buffer[5] = CdromId[4];
-       buffer[6] = CdromId[5];
-       buffer[7] = CdromId[6];
-       buffer[8] = '.';
-       buffer[9] = CdromId[7];
-       buffer[10] = CdromId[8];
-       buffer[11] = '\0';
-
-       sprintf(szPPF, "%s%s", Config.PatchesDir, buffer);
-
-       ppffile = fopen(szPPF, "rb");
+       if (!fname) {
+               // Generate filename in the format of SLUS_123.45
+               buffer[0] = toupper(CdromId[0]);
+               buffer[1] = toupper(CdromId[1]);
+               buffer[2] = toupper(CdromId[2]);
+               buffer[3] = toupper(CdromId[3]);
+               buffer[4] = '_';
+               buffer[5] = CdromId[4];
+               buffer[6] = CdromId[5];
+               buffer[7] = CdromId[6];
+               buffer[8] = '.';
+               buffer[9] = CdromId[7];
+               buffer[10] = CdromId[8];
+               buffer[11] = '\0';
+
+               sprintf(szPPF, "%s%s", Config.PatchesDir, buffer);
+               fname = szPPF;
+       }
+       ppffile = fopen(fname, "rb");
        if (ppffile == NULL) return;
 
        memset(buffer, 0, 5);
        if (ppffile == NULL) return;
 
        memset(buffer, 0, 5);
@@ -220,7 +222,7 @@ void BuildPPFCache() {
                goto fail_io;
 
        if (strcmp(buffer, "PPF") != 0) {
                goto fail_io;
 
        if (strcmp(buffer, "PPF") != 0) {
-               SysPrintf(_("Invalid PPF patch: %s.\n"), szPPF);
+               SysPrintf(_("Invalid PPF patch: %s.\n"), fname);
                fclose(ppffile);
                return;
        }
                fclose(ppffile);
                return;
        }
@@ -346,7 +348,8 @@ void BuildPPFCache() {
 
        FillPPFCache(); // build address array
 
 
        FillPPFCache(); // build address array
 
-       SysPrintf(_("Loaded PPF %d.0 patch: %s.\n"), method + 1, szPPF);
+       SysPrintf(_("Loaded PPF %d.0 patch: %s.\n"), method + 1, fname);
+       return;
 
 fail_io:
 #ifndef NDEBUG
 
 fail_io:
 #ifndef NDEBUG
index a1b1475..e646e55 100644 (file)
@@ -23,7 +23,7 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-void BuildPPFCache();
+void BuildPPFCache(const char *fname);
 void FreePPFCache();
 void CheckPPFCache(unsigned char *pB, unsigned char m, unsigned char s, unsigned char f);
 
 void FreePPFCache();
 void CheckPPFCache(unsigned char *pB, unsigned char m, unsigned char s, unsigned char f);
 
index 1f2e37a..64a04b8 100644 (file)
@@ -3615,7 +3615,8 @@ void psxBiosInit() {
        biosA0[0x03] = biosB0[0x35] = psxBios_write_psxout;
        biosA0[0x3c] = biosB0[0x3d] = psxBios_putchar_psxout;
        biosA0[0x3e] = biosB0[0x3f] = psxBios_puts_psxout;
        biosA0[0x03] = biosB0[0x35] = psxBios_write_psxout;
        biosA0[0x3c] = biosB0[0x3d] = psxBios_putchar_psxout;
        biosA0[0x3e] = biosB0[0x3f] = psxBios_puts_psxout;
-       biosA0[0x3f] = psxBios_printf_psxout;
+       // calls putchar() internally so no need to override
+       //biosA0[0x3f] = psxBios_printf_psxout;
 
        if (!Config.HLE) {
                char verstr[0x24+1];
 
        if (!Config.HLE) {
                char verstr[0x24+1];
index 53bda97..0a0bd86 100644 (file)
@@ -142,6 +142,7 @@ typedef struct {
        boolean icache_emulation;
        boolean DisableStalls;
        boolean PreciseExceptions;
        boolean icache_emulation;
        boolean DisableStalls;
        boolean PreciseExceptions;
+       boolean TurboCD;
        int cycle_multiplier; // 100 for 1.0
        int cycle_multiplier_override;
        s8 GpuListWalking;
        int cycle_multiplier; // 100 for 1.0
        int cycle_multiplier_override;
        s8 GpuListWalking;
index 55d2a0a..68b9694 100644 (file)
@@ -136,7 +136,9 @@ static u32 gpuDmaChainSize(u32 addr) {
 void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
        u32 *ptr, madr_next, *madr_next_p;
        u32 words, words_left, words_max, words_copy;
 void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
        u32 *ptr, madr_next, *madr_next_p;
        u32 words, words_left, words_max, words_copy;
-       int cycles_sum, cycles_last_cmd = 0, do_walking;
+       s32 cycles_last_cmd = 0;
+       int do_walking;
+       long cycles_sum;
 
        madr &= ~3;
        switch (chcr) {
 
        madr &= ~3;
        switch (chcr) {
@@ -225,7 +227,9 @@ void gpuInterrupt() {
        if (HW_DMA2_CHCR == SWAP32(0x01000401) && !(HW_DMA2_MADR & SWAP32(0x800000)))
        {
                u32 madr_next = 0xffffff, madr = SWAPu32(HW_DMA2_MADR);
        if (HW_DMA2_CHCR == SWAP32(0x01000401) && !(HW_DMA2_MADR & SWAP32(0x800000)))
        {
                u32 madr_next = 0xffffff, madr = SWAPu32(HW_DMA2_MADR);
-               int cycles_sum, cycles_last_cmd = 0;
+               s32 cycles_last_cmd = 0;
+               long cycles_sum;
+
                cycles_sum = GPU_dmaChain((u32 *)psxM, madr & 0x1fffff,
                                &madr_next, &cycles_last_cmd);
                HW_DMA2_MADR = SWAPu32(madr_next);
                cycles_sum = GPU_dmaChain((u32 *)psxM, madr & 0x1fffff,
                                &madr_next, &cycles_last_cmd);
                HW_DMA2_MADR = SWAPu32(madr_next);
index 820dfbe..5881e2a 100644 (file)
@@ -9,7 +9,5 @@
 #include "vector_types.h"
 #include "psx_gpu.h"
 
 #include "vector_types.h"
 #include "psx_gpu.h"
 
-#define unlikely(x) __builtin_expect((x), 0)
-
 #endif
 
 #endif
 
index b671a75..19f1c19 100644 (file)
@@ -560,8 +560,9 @@ void flush_render_block_buffer(psx_gpu_struct *psx_gpu)
   y##set##_b.e[1] = vertex->b                                                  \
   
 
   y##set##_b.e[1] = vertex->b                                                  \
   
 
-void compute_all_gradients(psx_gpu_struct *psx_gpu, vertex_struct *a,
- vertex_struct *b, vertex_struct *c)
+void compute_all_gradients(psx_gpu_struct * __restrict__ psx_gpu,
+ const vertex_struct * __restrict__ a, const vertex_struct * __restrict__ b,
+ const vertex_struct * __restrict__ c)
 {
   u32 triangle_area = psx_gpu->triangle_area;
   u32 winding_mask_scalar;
 {
   u32 triangle_area = psx_gpu->triangle_area;
   u32 winding_mask_scalar;
@@ -1163,6 +1164,8 @@ static void setup_spans_debug_check(psx_gpu_struct *psx_gpu,
       setup_spans_set_x4(alternate, down, alternate_active);                   \
       height -= 4;                                                             \
     } while(height > 0);                                                       \
       setup_spans_set_x4(alternate, down, alternate_active);                   \
       height -= 4;                                                             \
     } while(height > 0);                                                       \
+    if (psx_gpu->hacks_active & (AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V))   \
+      span_uvrg_offset[height - 1].low = span_uvrg_offset[height - 2].low;     \
   }                                                                            \
 
 
   }                                                                            \
 
 
@@ -1216,6 +1219,8 @@ static void setup_spans_debug_check(psx_gpu_struct *psx_gpu,
       setup_spans_set_x4(alternate, up, alternate_active);                     \
       height -= 4;                                                             \
     }                                                                          \
       setup_spans_set_x4(alternate, up, alternate_active);                     \
       height -= 4;                                                             \
     }                                                                          \
+    if (psx_gpu->hacks_active & AHACK_TEXTURE_ADJ_V)                           \
+      psx_gpu->span_uvrg_offset[0].low = psx_gpu->span_uvrg_offset[1].low;     \
   }                                                                            \
 
 #define index_left  0
   }                                                                            \
 
 #define index_left  0
@@ -1452,6 +1457,11 @@ void setup_spans_up_down(psx_gpu_struct *psx_gpu, vertex_struct *v_a,
       setup_spans_set_x4(none, down, no);
       height_minor_b -= 4;
     }
       setup_spans_set_x4(none, down, no);
       height_minor_b -= 4;
     }
+    if (psx_gpu->hacks_active & (AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V))
+    {
+      span_uvrg_offset[height_minor_b - 1].low =
+        span_uvrg_offset[height_minor_b - 2].low;
+    }
   }
 
   left_split_triangles++;
   }
 
   left_split_triangles++;
@@ -1459,6 +1469,41 @@ void setup_spans_up_down(psx_gpu_struct *psx_gpu, vertex_struct *v_a,
 
 #endif
 
 
 #endif
 
+// this is some hacky mess, can this be improved somehow?
+// ideally change things to not have to do this hack at all
+void __attribute__((noinline))
+setup_blocks_uv_adj_hack(psx_gpu_struct *psx_gpu, block_struct *block,
+    edge_data_struct *span_edge_data, vec_4x32u *span_uvrg_offset)
+{
+  size_t span_i = span_uvrg_offset - psx_gpu->span_uvrg_offset;
+  if (span_i != 0 && span_i != psx_gpu->num_spans - 1
+      && !(psx_gpu->hacks_active & AHACK_TEXTURE_ADJ_U))
+    return;
+  u32 num_blocks = span_edge_data->num_blocks - 1;
+  s32 offset = __builtin_ctz(span_edge_data->right_mask | 0x100) - 1;
+  s32 toffset = 8 * num_blocks + offset - 1;
+  if (toffset < 0 && !(psx_gpu->hacks_active & AHACK_TEXTURE_ADJ_U))
+    return;
+
+  toffset += span_edge_data->left_x;
+  s32 u_dx = psx_gpu->uvrg_dx.low.e[0];
+  s32 v_dx = psx_gpu->uvrg_dx.low.e[1];
+  u32 u = span_uvrg_offset->low.e[0];
+  u32 v = span_uvrg_offset->low.e[1];
+  u += u_dx * toffset;
+  v += v_dx * toffset;
+  u = (u >> 16) & psx_gpu->texture_mask_width;
+  v = (v >> 16) & psx_gpu->texture_mask_height;
+  if (!(psx_gpu->render_state_base & (TEXTURE_MODE_16BPP << 8))) {
+    // 4bpp 8bpp are swizzled
+    u32 u_ = u;
+    u = (u & 0x0f) | ((v & 0x0f) << 4);
+    v = (v & 0xf0) | (u_ >> 4);
+  }
+  assert(offset >= 0);
+  //assert(block->uv.e[offset] == ((v << 8) | u));
+  block->uv.e[offset] = (v << 8) | u;
+}
 
 #define dither_table_entry_normal(value)                                       \
   (value)                                                                      \
 
 #define dither_table_entry_normal(value)                                       \
   (value)                                                                      \
@@ -1868,6 +1913,14 @@ void setup_spans_up_down(psx_gpu_struct *psx_gpu, vertex_struct *v_a,
 
 #define setup_blocks_store_draw_mask_untextured_direct(_block, bits)           \
 
 
 #define setup_blocks_store_draw_mask_untextured_direct(_block, bits)           \
 
+#define setup_blocks_uv_adj_hack_untextured(_block, edge_data, uvrg_offset)    \
+
+#define setup_blocks_uv_adj_hack_textured(_block, edge_data, uvrg_offset)      \
+{                                                                              \
+  u32 m_ = AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V;                          \
+  if (unlikely(psx_gpu->hacks_active & m_))                                    \
+    setup_blocks_uv_adj_hack(psx_gpu, _block, edge_data, uvrg_offset);         \
+}                                                                              \
 
 #define setup_blocks_add_blocks_indirect()                                     \
   num_blocks += span_num_blocks;                                               \
 
 #define setup_blocks_add_blocks_indirect()                                     \
   num_blocks += span_num_blocks;                                               \
@@ -1938,6 +1991,8 @@ void setup_blocks_##shading##_##texturing##_##dithering##_##sw##_##target(     \
       setup_blocks_store_##shading##_##texturing(sw, dithering, target, edge); \
       setup_blocks_store_draw_mask_##texturing##_##target(block,               \
        span_edge_data->right_mask);                                            \
       setup_blocks_store_##shading##_##texturing(sw, dithering, target, edge); \
       setup_blocks_store_draw_mask_##texturing##_##target(block,               \
        span_edge_data->right_mask);                                            \
+      setup_blocks_uv_adj_hack_##texturing(block, span_edge_data,              \
+          span_uvrg_offset);                                                   \
                                                                                \
       block++;                                                                 \
     }                                                                          \
                                                                                \
       block++;                                                                 \
     }                                                                          \
@@ -4810,8 +4865,7 @@ void render_block_fill(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y,
   u32 r = color & 0xFF;
   u32 g = (color >> 8) & 0xFF;
   u32 b = (color >> 16) & 0xFF;
   u32 r = color & 0xFF;
   u32 g = (color >> 8) & 0xFF;
   u32 b = (color >> 16) & 0xFF;
-  u32 color_16bpp = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10) |
-   psx_gpu->mask_msb;
+  u32 color_16bpp = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10);
   u32 color_32bpp = color_16bpp | (color_16bpp << 16);
 
   u32 *vram_ptr = (u32 *)(psx_gpu->vram_out_ptr + x + (y * 1024));
   u32 color_32bpp = color_16bpp | (color_16bpp << 16);
 
   u32 *vram_ptr = (u32 *)(psx_gpu->vram_out_ptr + x + (y * 1024));
@@ -4863,8 +4917,7 @@ void render_block_fill_enh(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y,
   u32 r = color & 0xFF;
   u32 g = (color >> 8) & 0xFF;
   u32 b = (color >> 16) & 0xFF;
   u32 r = color & 0xFF;
   u32 g = (color >> 8) & 0xFF;
   u32 b = (color >> 16) & 0xFF;
-  u32 color_16bpp = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10) |
-   psx_gpu->mask_msb;
+  u32 color_16bpp = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10);
   u32 color_32bpp = color_16bpp | (color_16bpp << 16);
 
   u32 *vram_ptr = (u32 *)(psx_gpu->vram_out_ptr + x + (y * 1024));
   u32 color_32bpp = color_16bpp | (color_16bpp << 16);
 
   u32 *vram_ptr = (u32 *)(psx_gpu->vram_out_ptr + x + (y * 1024));
@@ -5018,8 +5071,10 @@ void initialize_psx_gpu(psx_gpu_struct *psx_gpu, u16 *vram)
   psx_gpu->primitive_type = PRIMITIVE_TYPE_UNKNOWN;
 
   psx_gpu->saved_hres = 256;
   psx_gpu->primitive_type = PRIMITIVE_TYPE_UNKNOWN;
 
   psx_gpu->saved_hres = 256;
+  psx_gpu->hacks_active = 0;
 
 
-  // check some offset
+  // check some offsets, asm relies on these
+  psx_gpu->reserved_a[(offsetof(psx_gpu_struct, test_mask) == 0) - 1] = 0;
   psx_gpu->reserved_a[(offsetof(psx_gpu_struct, blocks) == psx_gpu_blocks_offset) - 1] = 0;
 }
 
   psx_gpu->reserved_a[(offsetof(psx_gpu_struct, blocks) == psx_gpu_blocks_offset) - 1] = 0;
 }
 
index 2539521..f65351c 100644 (file)
 
 #define SPAN_DATA_BLOCKS_SIZE 32
 
 
 #define SPAN_DATA_BLOCKS_SIZE 32
 
+#define AHACK_TEXTURE_ADJ_U   (1 << 0)
+#define AHACK_TEXTURE_ADJ_V   (1 << 1)
+
 #ifndef __ASSEMBLER__
 
 #include "vector_types.h"
 
 #ifndef __ASSEMBLER__
 
 #include "vector_types.h"
 
+#ifndef unlikely
+#define unlikely(x) __builtin_expect((x), 0)
+#endif
+
 typedef enum
 {
   PRIMITIVE_TYPE_TRIANGLE = 0,
 typedef enum
 {
   PRIMITIVE_TYPE_TRIANGLE = 0,
@@ -189,6 +196,7 @@ typedef struct
   // enhancement stuff
   u16 *enhancement_buf_ptr;          // main alloc
   u16 *enhancement_current_buf_ptr;  // offset into above, 4 bufs
   // enhancement stuff
   u16 *enhancement_buf_ptr;          // main alloc
   u16 *enhancement_current_buf_ptr;  // offset into above, 4 bufs
+  u32 hacks_active;                  // AHACK_TEXTURE_ADJ_U ...
   u32 saved_hres;
   s16 saved_viewport_start_x;
   s16 saved_viewport_start_y;
   u32 saved_hres;
   s16 saved_viewport_start_x;
   s16 saved_viewport_start_y;
@@ -205,7 +213,7 @@ typedef struct
 
   // Align up to 64 byte boundary to keep the upcoming buffers cache line
   // aligned, also make reachable with single immediate addition
 
   // Align up to 64 byte boundary to keep the upcoming buffers cache line
   // aligned, also make reachable with single immediate addition
-  u8 reserved_a[184 + 9*4 - 9*sizeof(void *)];
+  u8 reserved_a[184 + 8*4 - 9*sizeof(void *)];
 
   // 8KB
   block_struct blocks[MAX_BLOCKS_PER_ROW];
 
   // 8KB
   block_struct blocks[MAX_BLOCKS_PER_ROW];
@@ -256,6 +264,9 @@ u32 texture_region_mask(s32 x1, s32 y1, s32 x2, s32 y2);
 void update_texture_8bpp_cache(psx_gpu_struct *psx_gpu);
 void flush_render_block_buffer(psx_gpu_struct *psx_gpu);
 
 void update_texture_8bpp_cache(psx_gpu_struct *psx_gpu);
 void flush_render_block_buffer(psx_gpu_struct *psx_gpu);
 
+void setup_blocks_uv_adj_hack(psx_gpu_struct *psx_gpu, block_struct *block,
+    edge_data_struct *span_edge_data, vec_4x32u *span_uvrg_offset);
+
 void initialize_psx_gpu(psx_gpu_struct *psx_gpu, u16 *vram);
 u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
  s32 *cpu_cycles_sum_out, s32 *cpu_cycles_last, u32 *last_command);
 void initialize_psx_gpu(psx_gpu_struct *psx_gpu, u16 *vram);
 u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
  s32 *cpu_cycles_sum_out, s32 *cpu_cycles_last, u32 *last_command);
index ffbea04..8273885 100644 (file)
 #ifdef __MACH__
 #define flush_render_block_buffer _flush_render_block_buffer
 #define update_texture_8bpp_cache _update_texture_8bpp_cache
 #ifdef __MACH__
 #define flush_render_block_buffer _flush_render_block_buffer
 #define update_texture_8bpp_cache _update_texture_8bpp_cache
+#define setup_blocks_uv_adj_hack _setup_blocks_uv_adj_hack
 #endif
 
 @ r0: psx_gpu
 #endif
 
 @ r0: psx_gpu
@@ -543,6 +544,7 @@ function(compute_all_gradients)
 
 #define uvrg                                     q14
 #define uvrg_dy                                  q15
 
 #define uvrg                                     q14
 #define uvrg_dy                                  q15
+#define uv                                       d28
 
 #define alternate_x_16                           d4
 
 
 #define alternate_x_16                           d4
 
@@ -925,6 +927,14 @@ function(compute_all_gradients)
   subs height, height, #4;                                                     \
   bhi 2b;                                                                      \
                                                                                \
   subs height, height, #4;                                                     \
   bhi 2b;                                                                      \
                                                                                \
+  nop;                                                                         \
+  ldr temp, [psx_gpu, #psx_gpu_hacks_active_offset];                           \
+  tst temp, #(AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V);                      \
+  beq 1f;                                                                      \
+  add temp, span_uvrg_offset, height, lsl #4;                                  \
+  vldr uv, [temp, #(-16*2)];                                                   \
+  vstr uv, [temp, #(-16)];                                                     \
+                                                                               \
  1:                                                                            \
 
 
  1:                                                                            \
 
 
@@ -986,6 +996,14 @@ function(compute_all_gradients)
   subs height, height, #4;                                                     \
   bhi 2b;                                                                      \
                                                                                \
   subs height, height, #4;                                                     \
   bhi 2b;                                                                      \
                                                                                \
+  nop;                                                                         \
+  ldr temp, [psx_gpu, #psx_gpu_hacks_active_offset];                           \
+  tst temp, #AHACK_TEXTURE_ADJ_V;                                              \
+  beq 1f;                                                                      \
+  add temp, psx_gpu, #psx_gpu_span_uvrg_offset_offset;                         \
+  vldr uv, [temp, #16];                                                        \
+  vstr uv, [temp, #0];                                                         \
+                                                                               \
  1:                                                                            \
 
 
  1:                                                                            \
 
 
@@ -1216,6 +1234,14 @@ function(setup_spans_up_down)
   subs height_minor_b, height_minor_b, #4
   bhi 2b
 
   subs height_minor_b, height_minor_b, #4
   bhi 2b
 
+  nop
+  ldr temp, [psx_gpu, #psx_gpu_hacks_active_offset]
+  tst temp, #(AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V)
+  beq 1f
+  add temp, span_uvrg_offset, height, lsl #4
+  vldr uv, [temp, #(-16*2)]
+  vstr uv, [temp, #(-16)]
+
  1:
   setup_spans_epilogue()
 
  1:
   setup_spans_epilogue()
 
@@ -1256,6 +1282,7 @@ function(setup_spans_up_down)
 
 #define uvrg_dx_ptr                              r2
 #define texture_mask_ptr                         r3
 
 #define uvrg_dx_ptr                              r2
 #define texture_mask_ptr                         r3
+#define hacks_active                             r6
 #define dither_shift                             r8
 #define dither_row                               r10
 
 #define dither_shift                             r8
 #define dither_row                               r10
 
@@ -1273,6 +1300,7 @@ function(setup_spans_up_down)
 #define color_b                                  r5
 
 #undef uvrg
 #define color_b                                  r5
 
 #undef uvrg
+#undef uv
 
 #define u_block                                  q0
 #define v_block                                  q1
 
 #define u_block                                  q0
 #define v_block                                  q1
@@ -1350,6 +1378,26 @@ function(setup_spans_up_down)
 
 #define setup_blocks_texture_unswizzled()                                      \
 
 
 #define setup_blocks_texture_unswizzled()                                      \
 
+#define setup_blocks_uv_adj_hack_textured(hacks_active)                        \
+  tst hacks_active, #(AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V);              \
+  beq 91f;                                                                     \
+  /* see flush_render_block_buffer below for a reg saving note */              \
+  vpush { texture_mask };                                                      \
+  vpush { uvrg_dx4 };                                                          \
+                                                                               \
+  stmdb sp!, { r0 - r3, EXTRA_UNSAVED_REGS r12, r14 };                         \
+  mov r12, span_uvrg_offset;                                                   \
+  sub r1, block_ptr_a, #64;                                                    \
+  mov r2, span_edge_data;                                                      \
+  mov r3, r12;                                                                 \
+  bl setup_blocks_uv_adj_hack; /* psx_gpu=r0 */                                \
+  ldmia sp!, { r0 - r3, EXTRA_UNSAVED_REGS r12, r14 };                         \
+                                                                               \
+  vpop { uvrg_dx4 };                                                           \
+  vpop { texture_mask };                                                       \
+  vadd.u32 uvrg_dx8, uvrg_dx4, uvrg_dx4;                                       \
+91:                                                                            \
+
 
 #define setup_blocks_shaded_textured_builder(swizzling)                        \
 .align 3;                                                                      \
 
 #define setup_blocks_shaded_textured_builder(swizzling)                        \
 .align 3;                                                                      \
@@ -1575,6 +1623,7 @@ function(setup_blocks_shaded_textured_dithered_##swizzling##_indirect)         \
   vld1.u32 { test_mask }, [psx_gpu, :128];                                     \
   vdup.u8 draw_mask, right_mask;                                               \
                                                                                \
   vld1.u32 { test_mask }, [psx_gpu, :128];                                     \
   vdup.u8 draw_mask, right_mask;                                               \
                                                                                \
+  ldr hacks_active, [psx_gpu, #psx_gpu_hacks_active_offset];                   \
   vmov.u32 fb_mask_ptrs[0], right_mask;                                        \
   vtst.u16 draw_mask, draw_mask, test_mask;                                    \
   vzip.u8 u_whole_8, v_whole_8;                                                \
   vmov.u32 fb_mask_ptrs[0], right_mask;                                        \
   vtst.u16 draw_mask, draw_mask, test_mask;                                    \
   vzip.u8 u_whole_8, v_whole_8;                                                \
@@ -1585,6 +1634,8 @@ function(setup_blocks_shaded_textured_dithered_##swizzling##_indirect)         \
   vst1.u32 { dither_offsets }, [block_ptr_b, :128], c_32;                      \
   vst1.u32 { b_whole_8, fb_mask_ptrs }, [block_ptr_a, :128], c_32;             \
                                                                                \
   vst1.u32 { dither_offsets }, [block_ptr_b, :128], c_32;                      \
   vst1.u32 { b_whole_8, fb_mask_ptrs }, [block_ptr_a, :128], c_32;             \
                                                                                \
+  setup_blocks_uv_adj_hack_textured(hacks_active);                             \
+                                                                               \
  1:                                                                            \
   add span_uvrg_offset, span_uvrg_offset, #16;                                 \
   add span_b_offset, span_b_offset, #4;                                        \
  1:                                                                            \
   add span_uvrg_offset, span_uvrg_offset, #16;                                 \
   add span_b_offset, span_b_offset, #4;                                        \
@@ -1599,7 +1650,8 @@ function(setup_blocks_shaded_textured_dithered_##swizzling##_indirect)         \
   ldmia sp!, { r4 - r11, pc };                                                 \
                                                                                \
  2:                                                                            \
   ldmia sp!, { r4 - r11, pc };                                                 \
                                                                                \
  2:                                                                            \
-  /* TODO: Load from psx_gpu instead of saving/restoring these               */\
+  /* this callee-save reg saving may look unnecessary but it actually is */    \
+  /* because the callee violates the ABI */                                    \
   vpush { texture_mask };                                                      \
   vpush { uvrg_dx4 };                                                          \
                                                                                \
   vpush { texture_mask };                                                      \
   vpush { uvrg_dx4 };                                                          \
                                                                                \
@@ -1776,6 +1828,7 @@ function(setup_blocks_unshaded_textured_dithered_##swizzling##_indirect)       \
   vld1.u32 { test_mask }, [psx_gpu, :128];                                     \
   vdup.u8 draw_mask, right_mask;                                               \
                                                                                \
   vld1.u32 { test_mask }, [psx_gpu, :128];                                     \
   vdup.u8 draw_mask, right_mask;                                               \
                                                                                \
+  ldr hacks_active, [psx_gpu, #psx_gpu_hacks_active_offset];                   \
   vmov.u32 fb_mask_ptrs[0], right_mask;                                        \
   vtst.u16 draw_mask, draw_mask, test_mask;                                    \
   vzip.u8 u_whole_8, v_whole_8;                                                \
   vmov.u32 fb_mask_ptrs[0], right_mask;                                        \
   vtst.u16 draw_mask, draw_mask, test_mask;                                    \
   vzip.u8 u_whole_8, v_whole_8;                                                \
@@ -1786,6 +1839,8 @@ function(setup_blocks_unshaded_textured_dithered_##swizzling##_indirect)       \
   vst1.u32 { dither_offsets }, [block_ptr_b, :128], c_32;                      \
   vst1.u32 { b_whole_8, fb_mask_ptrs }, [block_ptr_a, :128], c_32;             \
                                                                                \
   vst1.u32 { dither_offsets }, [block_ptr_b, :128], c_32;                      \
   vst1.u32 { b_whole_8, fb_mask_ptrs }, [block_ptr_a, :128], c_32;             \
                                                                                \
+  setup_blocks_uv_adj_hack_textured(hacks_active);                             \
+                                                                               \
  1:                                                                            \
   add span_uvrg_offset, span_uvrg_offset, #16;                                 \
   add span_edge_data, span_edge_data, #8;                                      \
  1:                                                                            \
   add span_uvrg_offset, span_uvrg_offset, #16;                                 \
   add span_edge_data, span_edge_data, #8;                                      \
@@ -1798,7 +1853,6 @@ function(setup_blocks_unshaded_textured_dithered_##swizzling##_indirect)       \
   ldmia sp!, { r4 - r11, pc };                                                 \
                                                                                \
  2:                                                                            \
   ldmia sp!, { r4 - r11, pc };                                                 \
                                                                                \
  2:                                                                            \
-  /* TODO: Load from psx_gpu instead of saving/restoring these               */\
   vpush { texture_mask };                                                      \
   vpush { uvrg_dx4 };                                                          \
                                                                                \
   vpush { texture_mask };                                                      \
   vpush { uvrg_dx4 };                                                          \
                                                                                \
@@ -2334,7 +2388,6 @@ function(setup_blocks_shaded_untextured_##dithering##_unswizzled_indirect)     \
   ldmia sp!, { r4 - r11, pc };                                                 \
                                                                                \
  2:                                                                            \
   ldmia sp!, { r4 - r11, pc };                                                 \
                                                                                \
  2:                                                                            \
-  /* TODO: Load from psx_gpu instead of saving/restoring these               */\
   vpush { rg_dx4 };                                                            \
                                                                                \
   stmdb sp!, { r0 - r3, EXTRA_UNSAVED_REGS r12, r14 };                        \
   vpush { rg_dx4 };                                                            \
                                                                                \
   stmdb sp!, { r0 - r3, EXTRA_UNSAVED_REGS r12, r14 };                        \
@@ -4386,51 +4439,6 @@ function(warmup)
 
 #undef vram_ptr
 #undef color
 
 #undef vram_ptr
 #undef color
-#undef width
-#undef height
-#undef pitch
-
-#define vram_ptr                                          r0
-#define color                                             r1
-#define width                                             r2
-#define height                                            r3
-
-#define pitch                                             r1
-
-#define num_width                                         r12
-
-#undef colors_a
-#undef colors_b
-
-#define colors_a                                          q0
-#define colors_b                                          q1
-
-.align 3
-
-function(render_block_fill_body)
-  vdup.u16 colors_a, color
-  mov pitch, #2048
-
-  vmov colors_b, colors_a
-  sub pitch, pitch, width, lsl #1
-
-  mov num_width, width
-
- 0:  
-  vst1.u32 { colors_a, colors_b }, [vram_ptr, :256]!
-
-  subs num_width, num_width, #16
-  bne 0b
-
-  add vram_ptr, vram_ptr, pitch
-  mov num_width, width
-
-  subs height, height, #1
-  bne 0b
-
-  bx lr
-
 #undef x
 #undef y
 #undef width
 #undef x
 #undef y
 #undef width
@@ -4523,6 +4531,7 @@ function(render_block_fill_body)
 #define texels_wide_high                                  d15
 #define texels_wide                                       q7
 
 #define texels_wide_high                                  d15
 #define texels_wide                                       q7
 
+.align 3
 
 setup_sprite_flush_blocks:
   vpush { q1 - q5 }
 
 setup_sprite_flush_blocks:
   vpush { q1 - q5 }
index 435c51a..5f1f383 100644 (file)
@@ -136,7 +136,8 @@ int main(int argc, char *argv[])
   FILE *list_file;
   u32 no_display = 0;
   s32 dummy0 = 0;
   FILE *list_file;
   u32 no_display = 0;
   s32 dummy0 = 0;
-  u32 dummy1 = 0;
+  s32 dummy1 = 0;
+  u32 dummy2 = 0;
 
   if((argc != 3) && (argc != 4))
   {
 
   if((argc != 3) && (argc != 4))
   {
@@ -180,7 +181,7 @@ int main(int argc, char *argv[])
   u32 fbdev_handle = open("/dev/fb1", O_RDWR);
   vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
    MAP_SHARED | 0xA0000000, fbdev_handle, 0));
   u32 fbdev_handle = open("/dev/fb1", O_RDWR);
   vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
    MAP_SHARED | 0xA0000000, fbdev_handle, 0));
-#elif 1
+#elif 0
   #ifndef MAP_HUGETLB
   #define MAP_HUGETLB 0x40000 /* arch specific */
   #endif
   #ifndef MAP_HUGETLB
   #define MAP_HUGETLB 0x40000 /* arch specific */
   #endif
@@ -211,23 +212,23 @@ int main(int argc, char *argv[])
 
   clear_stats();
 
 
   clear_stats();
 
-#ifdef NEON_BUILD
+#ifdef CYCLE_COUNTER
   init_counter();
 #endif
 
   init_counter();
 #endif
 
-  gpu_parse(psx_gpu, list, size, &dummy0, &dummy1);
+  gpu_parse(psx_gpu, list, size, &dummy0, &dummy1, &dummy2);
   flush_render_block_buffer(psx_gpu);
 
   clear_stats();
 
   flush_render_block_buffer(psx_gpu);
 
   clear_stats();
 
-#ifdef NEON_BUILD
+#ifdef CYCLE_COUNTER
   u32 cycles = get_counter();
 #endif
 
   u32 cycles = get_counter();
 #endif
 
-  gpu_parse(psx_gpu, list, size, &dummy0, &dummy1);
+  gpu_parse(psx_gpu, list, size, &dummy0, &dummy1, &dummy2);
   flush_render_block_buffer(psx_gpu);
 
   flush_render_block_buffer(psx_gpu);
 
-#ifdef NEON_BUILD
+#ifdef CYCLE_COUNTER
   u32 cycles_elapsed = get_counter() - cycles;
 
   printf("%-64s: %d\n", argv[1], cycles_elapsed);
   u32 cycles_elapsed = get_counter() - cycles;
 
   printf("%-64s: %d\n", argv[1], cycles_elapsed);
index 2f8a646..7c21d31 100644 (file)
@@ -36,6 +36,7 @@
 #define psx_gpu_texture_mask_width_offset                 0xfa
 #define psx_gpu_texture_mask_height_offset                0xfb
 #define psx_gpu_reciprocal_table_ptr_offset               0x108
 #define psx_gpu_texture_mask_width_offset                 0xfa
 #define psx_gpu_texture_mask_height_offset                0xfb
 #define psx_gpu_reciprocal_table_ptr_offset               0x108
+#define psx_gpu_hacks_active_offset                       0x114
 #define psx_gpu_blocks_offset                             0x200
 #define psx_gpu_span_uvrg_offset_offset                   0x2200
 #define psx_gpu_span_edge_data_offset                     0x4200
 #define psx_gpu_blocks_offset                             0x200
 #define psx_gpu_span_uvrg_offset_offset                   0x2200
 #define psx_gpu_span_edge_data_offset                     0x4200
index 9b37848..740df98 100644 (file)
@@ -76,6 +76,7 @@ int main()
        //WRITE_OFFSET(f, clut_settings);
        //WRITE_OFFSET(f, texture_settings);
        WRITE_OFFSET(f, reciprocal_table_ptr);
        //WRITE_OFFSET(f, clut_settings);
        //WRITE_OFFSET(f, texture_settings);
        WRITE_OFFSET(f, reciprocal_table_ptr);
+       WRITE_OFFSET(f, hacks_active);
        WRITE_OFFSET(f, blocks);
        WRITE_OFFSET(f, span_uvrg_offset);
        WRITE_OFFSET(f, span_edge_data);
        WRITE_OFFSET(f, blocks);
        WRITE_OFFSET(f, span_uvrg_offset);
        WRITE_OFFSET(f, span_edge_data);
index d81b707..f398695 100644 (file)
@@ -200,21 +200,14 @@ static void do_fill(psx_gpu_struct *psx_gpu, u32 x, u32 y,
   }
 }
 
   }
 }
 
-#define sign_extend_12bit(value)                                               \
-  (((s32)((value) << 20)) >> 20)                                               \
-
 #define sign_extend_11bit(value)                                               \
   (((s32)((value) << 21)) >> 21)                                               \
 
 #define sign_extend_11bit(value)                                               \
   (((s32)((value) << 21)) >> 21)                                               \
 
-#define sign_extend_10bit(value)                                               \
-  (((s32)((value) << 22)) >> 22)                                               \
-
-
 #define get_vertex_data_xy(vertex_number, offset16)                            \
   vertexes[vertex_number].x =                                                  \
 #define get_vertex_data_xy(vertex_number, offset16)                            \
   vertexes[vertex_number].x =                                                  \
-   sign_extend_12bit(list_s16[offset16]) + psx_gpu->offset_x;                  \
+   sign_extend_11bit(list_s16[offset16]) + psx_gpu->offset_x;                  \
   vertexes[vertex_number].y =                                                  \
   vertexes[vertex_number].y =                                                  \
-   sign_extend_12bit(list_s16[(offset16) + 1]) + psx_gpu->offset_y;            \
+   sign_extend_11bit(list_s16[(offset16) + 1]) + psx_gpu->offset_y;            \
 
 #define get_vertex_data_uv(vertex_number, offset16)                            \
   vertexes[vertex_number].u = list_s16[offset16] & 0xFF;                       \
 
 #define get_vertex_data_uv(vertex_number, offset16)                            \
   vertexes[vertex_number].u = list_s16[offset16] & 0xFF;                       \
@@ -910,6 +903,7 @@ static void select_enhancement_buf(psx_gpu_struct *psx_gpu)
   psx_gpu->viewport_start_y = psx_gpu->saved_viewport_start_y; \
   psx_gpu->viewport_end_x = psx_gpu->saved_viewport_end_x; \
   psx_gpu->viewport_end_y = psx_gpu->saved_viewport_end_y; \
   psx_gpu->viewport_start_y = psx_gpu->saved_viewport_start_y; \
   psx_gpu->viewport_end_x = psx_gpu->saved_viewport_end_x; \
   psx_gpu->viewport_end_y = psx_gpu->saved_viewport_end_y; \
+  psx_gpu->hacks_active = 0; \
   psx_gpu->uvrgb_phase = 0x8000; \
 }
 
   psx_gpu->uvrgb_phase = 0x8000; \
 }
 
@@ -924,7 +918,7 @@ static int enhancement_enable(psx_gpu_struct *psx_gpu)
   psx_gpu->viewport_end_y = psx_gpu->saved_viewport_end_y * 2 + 1;
   if (psx_gpu->viewport_end_x - psx_gpu->viewport_start_x + 1 > 1024)
     psx_gpu->viewport_end_x = psx_gpu->viewport_start_x + 1023;
   psx_gpu->viewport_end_y = psx_gpu->saved_viewport_end_y * 2 + 1;
   if (psx_gpu->viewport_end_x - psx_gpu->viewport_start_x + 1 > 1024)
     psx_gpu->viewport_end_x = psx_gpu->viewport_start_x + 1023;
-  psx_gpu->uvrgb_phase = 0x7fff;
+  //psx_gpu->uvrgb_phase = 0x7fff;
   return 1;
 }
 
   return 1;
 }
 
@@ -1025,73 +1019,29 @@ static int check_enhanced_range(psx_gpu_struct *psx_gpu, int x, int y)
   return 1;
 }
 
   return 1;
 }
 
-static int is_in_array(int val, int array[], int len)
-{
-  int i;
-  for (i = 0; i < len; i++)
-    if (array[i] == val)
-      return 1;
-  return 0;
-}
-
-static int make_members_unique(int array[], int len)
+static u32 uv_hack(psx_gpu_struct *psx_gpu, const vertex_struct *vertex_ptrs)
 {
 {
-  int i, j;
-  for (i = j = 1; i < len; i++)
-    if (!is_in_array(array[i], array, j))
-      array[j++] = array[i];
-
-  if (array[0] > array[1]) {
-    i = array[0]; array[0] = array[1]; array[1] = i;
-  }
-  return j;
-}
-
-static void patch_u(vertex_struct *vertex_ptrs, int count, int old, int new)
-{
-  int i;
-  for (i = 0; i < count; i++)
-    if (vertex_ptrs[i].u == old)
-      vertex_ptrs[i].u = new;
-}
-
-static void patch_v(vertex_struct *vertex_ptrs, int count, int old, int new)
-{
-  int i;
-  for (i = 0; i < count; i++)
-    if (vertex_ptrs[i].v == old)
-      vertex_ptrs[i].v = new;
-}
-
-// this sometimes does more harm than good, like in PE2
-static void uv_hack(vertex_struct *vertex_ptrs, int vertex_count)
-{
-  int i, u[4], v[4];
-
-  for (i = 0; i < vertex_count; i++) {
-    u[i] = vertex_ptrs[i].u;
-    v[i] = vertex_ptrs[i].v;
-  }
-  if (make_members_unique(u, vertex_count) == 2 && u[1] - u[0] >= 8) {
-    if ((u[0] & 7) == 7) {
-      patch_u(vertex_ptrs, vertex_count, u[0], u[0] + 1);
-      //printf("u hack: %3u-%3u -> %3u-%3u\n", u[0], u[1], u[0]+1, u[1]);
-    }
-    else if ((u[1] & 7) == 0 || u[1] - u[0] > 128) {
-      patch_u(vertex_ptrs, vertex_count, u[1], u[1] - 1);
-      //printf("u hack: %3u-%3u -> %3u-%3u\n", u[0], u[1], u[0], u[1]-1);
-    }
-  }
-  if (make_members_unique(v, vertex_count) == 2 && ((v[0] - v[1]) & 7) == 0) {
-    if ((v[0] & 7) == 7) {
-      patch_v(vertex_ptrs, vertex_count, v[0], v[0] + 1);
-      //printf("v hack: %3u-%3u -> %3u-%3u\n", v[0], v[1], v[0]+1, v[1]);
-    }
-    else if ((v[1] & 7) == 0) {
-      patch_v(vertex_ptrs, vertex_count, v[1], v[1] - 1);
-      //printf("v hack: %3u-%3u -> %3u-%3u\n", v[0], v[1], v[0], v[1]-1);
-    }
+  int i, have_right_edge = 0, have_bottom_edge = 0, bad_u = 0, bad_v = 0;
+  u32 hacks = 0;
+
+  for (i = 0; i < 3; i++) {
+    int j = (i + 1) % 3, k = (i + 2) % 3;
+    int du = abs((int)vertex_ptrs[i].u - (int)vertex_ptrs[j].u);
+    int dv = abs((int)vertex_ptrs[i].v - (int)vertex_ptrs[j].v);
+    if (du && (du & 7) != 7)
+      bad_u = 1;
+    if (dv && (dv & 7) != 7)
+      bad_v = 1;
+    if (vertex_ptrs[i].x == vertex_ptrs[j].x && vertex_ptrs[k].x < vertex_ptrs[j].x)
+      have_right_edge = 1;
+    if (vertex_ptrs[i].y == vertex_ptrs[j].y)// && vertex_ptrs[k].y < vertex_ptrs[j].y)
+      have_bottom_edge = 1;
   }
   }
+  if (have_right_edge && bad_u)
+    hacks |= AHACK_TEXTURE_ADJ_U;
+  if (have_bottom_edge && bad_v)
+    hacks |= AHACK_TEXTURE_ADJ_V;
+  return hacks;
 }
 
 static void do_triangle_enhanced(psx_gpu_struct *psx_gpu,
 }
 
 static void do_triangle_enhanced(psx_gpu_struct *psx_gpu,
@@ -1111,6 +1061,8 @@ static void do_triangle_enhanced(psx_gpu_struct *psx_gpu,
   if (!enhancement_enable(psx_gpu))
     return;
 
   if (!enhancement_enable(psx_gpu))
     return;
 
+  if ((current_command & RENDER_FLAGS_TEXTURE_MAP) && psx_gpu->hack_texture_adj)
+    psx_gpu->hacks_active |= uv_hack(psx_gpu, vertexes);
   shift_vertices3(vertex_ptrs);
   shift_triangle_area();
   render_triangle_p(psx_gpu, vertex_ptrs, current_command);
   shift_vertices3(vertex_ptrs);
   shift_triangle_area();
   render_triangle_p(psx_gpu, vertex_ptrs, current_command);
@@ -1321,8 +1273,6 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
         get_vertex_data_xy_uv(2, 10);  
         get_vertex_data_xy_uv(3, 14);
   
         get_vertex_data_xy_uv(2, 10);  
         get_vertex_data_xy_uv(3, 14);
   
-        if (psx_gpu->hack_texture_adj)
-          uv_hack(vertexes, 4);
         do_quad_enhanced(psx_gpu, vertexes, current_command);
         gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_t());
         break;
         do_quad_enhanced(psx_gpu, vertexes, current_command);
         gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_t());
         break;
@@ -1375,8 +1325,6 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
         get_vertex_data_xy_uv_rgb(2, 12);
         get_vertex_data_xy_uv_rgb(3, 18);
 
         get_vertex_data_xy_uv_rgb(2, 12);
         get_vertex_data_xy_uv_rgb(3, 18);
 
-        if (psx_gpu->hack_texture_adj)
-          uv_hack(vertexes, 4);
         do_quad_enhanced(psx_gpu, vertexes, current_command);
         gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_gt());
         break;
         do_quad_enhanced(psx_gpu, vertexes, current_command);
         gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_gt());
         break;
@@ -1746,10 +1694,8 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
   
       case 0xE5:
       {
   
       case 0xE5:
       {
-        s32 offset_x = list[0] << 21;
-        s32 offset_y = list[0] << 10;
-        psx_gpu->offset_x = offset_x >> 21;
-        psx_gpu->offset_y = offset_y >> 21; 
+        psx_gpu->offset_x = sign_extend_11bit(list[0]);
+        psx_gpu->offset_y = sign_extend_11bit(list[0] >> 11);
   
         SET_Ex(5, list[0]);
         break;
   
         SET_Ex(5, list[0]);
         break;
index b527436..174e61d 100644 (file)
@@ -192,6 +192,7 @@ typedef union
 
 #define gvld1_u8(d, s)           d.u8  = vld1_u8(s)
 #define gvld1_u32(d, s)          d.u32 = vld1_u32((const u32 *)(s))
 
 #define gvld1_u8(d, s)           d.u8  = vld1_u8(s)
 #define gvld1_u32(d, s)          d.u32 = vld1_u32((const u32 *)(s))
+#define gvld1_u64(d, s)          d.u64 = vld1_u64((const u64 *)(s))
 #define gvld1q_u8(d, s)          d.u8  = vld1q_u8(s)
 #define gvld1q_u16(d, s)         d.u16 = vld1q_u16(s)
 #define gvld1q_u32(d, s)         d.u32 = vld1q_u32((const u32 *)(s))
 #define gvld1q_u8(d, s)          d.u8  = vld1q_u8(s)
 #define gvld1q_u16(d, s)         d.u16 = vld1q_u16(s)
 #define gvld1q_u32(d, s)         d.u32 = vld1q_u32((const u32 *)(s))
@@ -206,6 +207,8 @@ typedef union
 
 #define gvst1_u8(v, p) \
   vst1_u8(p, v.u8)
 
 #define gvst1_u8(v, p) \
   vst1_u8(p, v.u8)
+#define gvst1_u64(v, p) \
+  vst1_u64((u64 *)(p), v.u64)
 #define gvst1q_u16(v, p) \
   vst1q_u16(p, v.u16)
 #define gvst1q_inc_u32(v, p, i) { \
 #define gvst1q_u16(v, p) \
   vst1q_u16(p, v.u16)
 #define gvst1q_inc_u32(v, p, i) { \
@@ -388,10 +391,14 @@ typedef union
 
 #define gvld1_u8(d, s)           d.m = _mm_loadu_si64(s)
 #define gvld1_u32                gvld1_u8
 
 #define gvld1_u8(d, s)           d.m = _mm_loadu_si64(s)
 #define gvld1_u32                gvld1_u8
+#define gvld1_u64                gvld1_u8
 #define gvld1q_u8(d, s)          d.m = _mm_loadu_si128((__m128i *)(s))
 #define gvld1q_u16               gvld1q_u8
 #define gvld1q_u32               gvld1q_u8
 
 #define gvld1q_u8(d, s)          d.m = _mm_loadu_si128((__m128i *)(s))
 #define gvld1q_u16               gvld1q_u8
 #define gvld1q_u32               gvld1q_u8
 
+#define gvst1_u8(v, p)           _mm_storeu_si64(p, v.m)
+#define gvst1_u64                gvst1_u8
+
 #define gvst4_4_inc_u32(v0, v1, v2, v3, p, i) { \
   __m128i t0 = _mm_unpacklo_epi32(v0.m, v1.m); \
   __m128i t1 = _mm_unpacklo_epi32(v2.m, v3.m); \
 #define gvst4_4_inc_u32(v0, v1, v2, v3, p, i) { \
   __m128i t0 = _mm_unpacklo_epi32(v0.m, v1.m); \
   __m128i t1 = _mm_unpacklo_epi32(v2.m, v3.m); \
@@ -1401,6 +1408,12 @@ void compute_all_gradients(psx_gpu_struct * __restrict__ psx_gpu,
       setup_spans_set_x4(alternate, down, alternate_active);                   \
       height -= 4;                                                             \
     } while(height > 0);                                                       \
       setup_spans_set_x4(alternate, down, alternate_active);                   \
       height -= 4;                                                             \
     } while(height > 0);                                                       \
+    if (psx_gpu->hacks_active & (AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V))   \
+    {                                                                          \
+      vec_2x32u tmp;                                                           \
+      gvld1_u64(tmp, &span_uvrg_offset[height - 2]);                           \
+      gvst1_u64(tmp, &span_uvrg_offset[height - 1]);                           \
+    }                                                                          \
   }                                                                            \
 
 
   }                                                                            \
 
 
@@ -1452,6 +1465,12 @@ void compute_all_gradients(psx_gpu_struct * __restrict__ psx_gpu,
       setup_spans_set_x4(alternate, up, alternate_active);                     \
       height -= 4;                                                             \
     }                                                                          \
       setup_spans_set_x4(alternate, up, alternate_active);                     \
       height -= 4;                                                             \
     }                                                                          \
+    if (psx_gpu->hacks_active & AHACK_TEXTURE_ADJ_V)                           \
+    {                                                                          \
+      vec_2x32u tmp;                                                           \
+      gvld1_u64(tmp, &psx_gpu->span_uvrg_offset[1]);                           \
+      gvst1_u64(tmp, &psx_gpu->span_uvrg_offset[0]);                           \
+    }                                                                          \
   }                                                                            \
 
 #define half_left  lo
   }                                                                            \
 
 #define half_left  lo
@@ -1714,6 +1733,12 @@ void setup_spans_up_down(psx_gpu_struct *psx_gpu, vertex_struct *v_a,
       setup_spans_set_x4(none, down, no);
       height_minor_b -= 4;
     }
       setup_spans_set_x4(none, down, no);
       height_minor_b -= 4;
     }
+    if (psx_gpu->hacks_active & (AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V))
+    {
+      vec_2x32u tmp;
+      gvld1_u64(tmp, &span_uvrg_offset[height_minor_b - 2]);
+      gvst1_u64(tmp, &span_uvrg_offset[height_minor_b - 1]);
+    }
   }
 }
 
   }
 }
 
@@ -2152,6 +2177,15 @@ void setup_spans_up_down(psx_gpu_struct *psx_gpu, vertex_struct *v_a,
 
 #define setup_blocks_store_draw_mask_untextured_direct(_block, bits)           \
 
 
 #define setup_blocks_store_draw_mask_untextured_direct(_block, bits)           \
 
+#define setup_blocks_uv_adj_hack_untextured(_block, edge_data, uvrg_offset)    \
+
+#define setup_blocks_uv_adj_hack_textured(_block, edge_data, uvrg_offset)      \
+{                                                                              \
+  u32 m_ = AHACK_TEXTURE_ADJ_U | AHACK_TEXTURE_ADJ_V;                          \
+  if (unlikely(psx_gpu->hacks_active & m_))                                    \
+    setup_blocks_uv_adj_hack(psx_gpu, _block, edge_data, (void *)uvrg_offset); \
+}                                                                              \
+
 #define setup_blocks_add_blocks_indirect()                                     \
   num_blocks += span_num_blocks;                                               \
                                                                                \
 #define setup_blocks_add_blocks_indirect()                                     \
   num_blocks += span_num_blocks;                                               \
                                                                                \
@@ -2211,6 +2245,8 @@ void setup_spans_up_down(psx_gpu_struct *psx_gpu, vertex_struct *v_a,
       setup_blocks_store_##shading##_##texturing(sw, dithering, target, edge); \
       setup_blocks_store_draw_mask_##texturing##_##target(block,               \
        span_edge_data->right_mask);                                            \
       setup_blocks_store_##shading##_##texturing(sw, dithering, target, edge); \
       setup_blocks_store_draw_mask_##texturing##_##target(block,               \
        span_edge_data->right_mask);                                            \
+      setup_blocks_uv_adj_hack_##texturing(block, span_edge_data,              \
+          span_uvrg_offset);                                                   \
                                                                                \
       block++;                                                                 \
     }                                                                          \
                                                                                \
       block++;                                                                 \
     }                                                                          \
index bb91a5a..21d6155 100644 (file)
@@ -4,7 +4,7 @@ CFLAGS += -Wall -ggdb
 CFLAGS += -fno-strict-aliasing
 
 CFLAGS += `sdl-config --cflags`
 CFLAGS += -fno-strict-aliasing
 
 CFLAGS += `sdl-config --cflags`
-LDFLAGS += `sdl-config --libs`
+LDLIBS += `sdl-config --libs`
 
 VPATH += ..
 
 
 VPATH += ..
 
@@ -12,6 +12,9 @@ ifdef NEON
 CFLAGS += -mcpu=cortex-a8 -mfpu=neon -DNEON_BUILD
 ASFLAGS = $(CFLAGS)
 OBJ += psx_gpu_arm_neon.o
 CFLAGS += -mcpu=cortex-a8 -mfpu=neon -DNEON_BUILD
 ASFLAGS = $(CFLAGS)
 OBJ += psx_gpu_arm_neon.o
+else
+CFLAGS += -DNEON_BUILD -DSIMD_BUILD
+OBJ += psx_gpu_simd.o
 endif
 ifndef DEBUG
 CFLAGS += -O2 -DNDEBUG
 endif
 ifndef DEBUG
 CFLAGS += -O2 -DNDEBUG
index b444dcf..54bf63e 100644 (file)
@@ -89,6 +89,11 @@ static noinline void update_width(void)
     x = (x + 1) & ~1;   // blitter limitation
     sw /= hdiv;
     sw = (sw + 2) & ~3; // according to nocash
     x = (x + 1) & ~1;   // blitter limitation
     sw /= hdiv;
     sw = (sw + 2) & ~3; // according to nocash
+
+    if (gpu.state.show_overscan == 2) // widescreen hack
+      sw = (sw + 63) & ~63;
+    if (gpu.state.show_overscan && sw >= hres)
+      x = 0, hres = sw;
     switch (type) {
     case C_INGAME:
       break;
     switch (type) {
     case C_INGAME:
       break;
@@ -113,8 +118,8 @@ static noinline void update_width(void)
   gpu.screen.w = sw;
   gpu.screen.hres = hres;
   gpu.state.dims_changed = 1;
   gpu.screen.w = sw;
   gpu.screen.hres = hres;
   gpu.state.dims_changed = 1;
-  //printf("xx %d %d -> %2d, %d / %d\n",
-  //  gpu.screen.x1, gpu.screen.x2, x, sw, hres);
+  //printf("xx %d %d (%d) -> %2d, %d / %d\n", gpu.screen.x1,
+  //  gpu.screen.x2, gpu.screen.x2 - gpu.screen.x1, x, sw, hres);
 }
 
 static noinline void update_height(void)
 }
 
 static noinline void update_height(void)
@@ -365,21 +370,31 @@ const unsigned char cmd_lengths[256] =
 
 #define VRAM_MEM_XY(x, y) &gpu.vram[(y) * 1024 + (x)]
 
 
 #define VRAM_MEM_XY(x, y) &gpu.vram[(y) * 1024 + (x)]
 
-static void cpy_msb(uint16_t *dst, const uint16_t *src, int l, uint16_t msb)
+// this isn't very useful so should be rare
+static void cpy_mask(uint16_t *dst, const uint16_t *src, int l, uint32_t r6)
 {
   int i;
 {
   int i;
-  for (i = 0; i < l; i++)
-    dst[i] = src[i] | msb;
+  if (r6 == 1) {
+    for (i = 0; i < l; i++)
+      dst[i] = src[i] | 0x8000;
+  }
+  else {
+    uint16_t msb = r6 << 15;
+    for (i = 0; i < l; i++) {
+      uint16_t mask = (int16_t)dst[i] >> 15;
+      dst[i] = (dst[i] & mask) | ((src[i] | msb) & ~mask);
+    }
+  }
 }
 
 static inline void do_vram_line(int x, int y, uint16_t *mem, int l,
 }
 
 static inline void do_vram_line(int x, int y, uint16_t *mem, int l,
-    int is_read, uint16_t msb)
+    int is_read, uint32_t r6)
 {
   uint16_t *vram = VRAM_MEM_XY(x, y);
   if (unlikely(is_read))
     memcpy(mem, vram, l * 2);
 {
   uint16_t *vram = VRAM_MEM_XY(x, y);
   if (unlikely(is_read))
     memcpy(mem, vram, l * 2);
-  else if (unlikely(msb))
-    cpy_msb(vram, mem, l, msb);
+  else if (unlikely(r6))
+    cpy_mask(vram, mem, l, r6);
   else
     memcpy(vram, mem, l * 2);
 }
   else
     memcpy(vram, mem, l * 2);
 }
@@ -387,7 +402,7 @@ static inline void do_vram_line(int x, int y, uint16_t *mem, int l,
 static int do_vram_io(uint32_t *data, int count, int is_read)
 {
   int count_initial = count;
 static int do_vram_io(uint32_t *data, int count, int is_read)
 {
   int count_initial = count;
-  uint16_t msb = gpu.ex_regs[6] << 15;
+  uint32_t r6 = gpu.ex_regs[6] & 3;
   uint16_t *sdata = (uint16_t *)data;
   int x = gpu.dma.x, y = gpu.dma.y;
   int w = gpu.dma.w, h = gpu.dma.h;
   uint16_t *sdata = (uint16_t *)data;
   int x = gpu.dma.x, y = gpu.dma.y;
   int w = gpu.dma.w, h = gpu.dma.h;
@@ -400,7 +415,7 @@ static int do_vram_io(uint32_t *data, int count, int is_read)
     if (count < l)
       l = count;
 
     if (count < l)
       l = count;
 
-    do_vram_line(x + o, y, sdata, l, is_read, msb);
+    do_vram_line(x + o, y, sdata, l, is_read, r6);
 
     if (o + l < w)
       o += l;
 
     if (o + l < w)
       o += l;
@@ -415,13 +430,13 @@ static int do_vram_io(uint32_t *data, int count, int is_read)
 
   for (; h > 0 && count >= w; sdata += w, count -= w, y++, h--) {
     y &= 511;
 
   for (; h > 0 && count >= w; sdata += w, count -= w, y++, h--) {
     y &= 511;
-    do_vram_line(x, y, sdata, w, is_read, msb);
+    do_vram_line(x, y, sdata, w, is_read, r6);
   }
 
   if (h > 0) {
     if (count > 0) {
       y &= 511;
   }
 
   if (h > 0) {
     if (count > 0) {
       y &= 511;
-      do_vram_line(x, y, sdata, count, is_read, msb);
+      do_vram_line(x, y, sdata, count, is_read, r6);
       o = count;
       count = 0;
     }
       o = count;
       count = 0;
     }
@@ -919,17 +934,19 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
   gpu.frameskip.advice = &cbs->fskip_advice;
   gpu.frameskip.active = 0;
   gpu.frameskip.frame_ready = 1;
   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.hcnt = (uint32_t *)cbs->gpu_hcnt;
+  gpu.state.frame_count = (uint32_t *)cbs->gpu_frame_count;
   gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace;
   gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable;
   gpu.state.screen_centering_type_default = cbs->screen_centering_type_default;
   if (gpu.state.screen_centering_type != cbs->screen_centering_type
       || gpu.state.screen_centering_x != cbs->screen_centering_x
   gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace;
   gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable;
   gpu.state.screen_centering_type_default = cbs->screen_centering_type_default;
   if (gpu.state.screen_centering_type != cbs->screen_centering_type
       || gpu.state.screen_centering_x != cbs->screen_centering_x
-      || gpu.state.screen_centering_y != cbs->screen_centering_y) {
+      || gpu.state.screen_centering_y != cbs->screen_centering_y
+      || gpu.state.show_overscan != cbs->show_overscan) {
     gpu.state.screen_centering_type = cbs->screen_centering_type;
     gpu.state.screen_centering_x = cbs->screen_centering_x;
     gpu.state.screen_centering_y = cbs->screen_centering_y;
     gpu.state.screen_centering_type = cbs->screen_centering_type;
     gpu.state.screen_centering_x = cbs->screen_centering_x;
     gpu.state.screen_centering_y = cbs->screen_centering_y;
+    gpu.state.show_overscan = cbs->show_overscan;
     update_width();
     update_height();
   }
     update_width();
     update_height();
   }
index 96a8183..fb5c4ff 100644 (file)
@@ -81,6 +81,7 @@ struct psx_gpu {
     uint32_t downscale_enable:1;
     uint32_t downscale_active:1;
     uint32_t dims_changed:1;
     uint32_t downscale_enable:1;
     uint32_t downscale_active:1;
     uint32_t dims_changed:1;
+    uint32_t show_overscan:2;
     uint32_t *frame_count;
     uint32_t *hcnt; /* hsync count */
     struct {
     uint32_t *frame_count;
     uint32_t *hcnt; /* hsync count */
     struct {
index 7f16ed5..38cd44b 100644 (file)
@@ -182,7 +182,7 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, unsigned i
 
 ////////////////////////////////////////////////////////////////////////\r
 
 
 ////////////////////////////////////////////////////////////////////////\r
 
-unsigned short CALLBACK SPUreadRegister(unsigned long reg)
+unsigned short CALLBACK SPUreadRegister(unsigned long reg, unsigned int cycles)
 {
  unsigned long r=reg&0xfff;
 
 {
  unsigned long r=reg&0xfff;
 
@@ -280,7 +280,7 @@ void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cy
 // XA AUDIO
 ////////////////////////////////////////////////////////////////////////
 
 // XA AUDIO
 ////////////////////////////////////////////////////////////////////////
 
-void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap)
+void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycles, int is_start)
 {
 }
 
 {
 }
 
@@ -352,7 +352,7 @@ void SPUasync(unsigned int cycle, unsigned int flags)
 {
 }
 
 {
 }
 
-int SPUplayCDDAchannel(short *pcm, int nbytes)
+int SPUplayCDDAchannel(short *pcm, int nbytes, unsigned int cycle, int is_start)
 {
  return -1;
 }
 {
  return -1;
 }
@@ -542,3 +542,7 @@ void CALLBACK SPUstopChannels2(unsigned short channels)
 { 
  //SoundOff(16,24,channels); 
 } 
 { 
  //SoundOff(16,24,channels); 
 } 
+
+void CALLBACK SPUregisterScheduleCb(void (CALLBACK *callback)(unsigned int))
+{
+}