Merge branch 'mainline' into libretro
authornotaz <notasas@gmail.com>
Tue, 20 Sep 2016 23:24:37 +0000 (02:24 +0300)
committernotaz <notasas@gmail.com>
Tue, 20 Sep 2016 23:24:37 +0000 (02:24 +0300)
1  2 
Makefile
Makefile.libretro
frontend/libretro.c

diff --combined Makefile
+++ b/Makefile
@@@ -2,10 -2,8 +2,10 @@@
  
  # default stuff goes here, so that config can override
  TARGET ?= pcsx
 -CFLAGS += -Wall -ggdb -Iinclude -ffast-math
 -ifndef DEBUG
 +CFLAGS += -Wall -Iinclude -ffast-math
 +ifeq ($(DEBUG), 1)
 +CFLAGS += -O0 -ggdb
 +else
  CFLAGS += -O2 -DNDEBUG
  endif
  CXXFLAGS += $(CFLAGS)
@@@ -67,7 -65,6 +67,6 @@@ endi
  OBJS += libpcsxcore/new_dynarec/emu_if.o
  libpcsxcore/new_dynarec/new_dynarec.o: libpcsxcore/new_dynarec/assem_arm.c \
        libpcsxcore/new_dynarec/pcsxmem_inline.c
- libpcsxcore/new_dynarec/new_dynarec.o: CFLAGS += -Wno-all -Wno-pointer-sign
  ifdef DRC_DBG
  libpcsxcore/new_dynarec/emu_if.o: CFLAGS += -D_FILE_OFFSET_BITS=64
  CFLAGS += -DDRC_DBG
@@@ -197,7 -194,6 +196,7 @@@ endi
  ifeq "$(PLATFORM)" "libretro"
  OBJS += frontend/libretro.o
  CFLAGS += -DFRONTEND_SUPPORTS_RGB565
 +CFLAGS += -DHAVE_LIBRETRO
  
  ifeq ($(MMAP_WIN32),1)
  OBJS += libpcsxcore/memmap_win32.o
@@@ -250,19 -246,11 +249,19 @@@ frontend/revision.h: FORC
  %.o: %.S
        $(CC_AS) $(CFLAGS) -c $^ -o $@
  
 +%.o: %.cpp
 +      $(CXX) $(CXXFLAGS) -c -o $@ $<
 +
 +
  
  target_: $(TARGET)
  
  $(TARGET): $(OBJS)
 +ifeq ($(STATIC_LINKING), 1)
 +      $(AR) rcs $@ $(OBJS)
 +else
        $(CC_LINK) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(EXTRA_LDFLAGS)
 +endif
  
  clean: $(PLAT_CLEAN) clean_plugins
        $(RM) $(TARGET) $(OBJS) $(TARGET).map frontend/revision.h
diff --combined Makefile.libretro
@@@ -1,7 -1,5 +1,7 @@@
  # Makefile for PCSX ReARMed (libretro)
  
 +DEBUG=0
 +
  ifeq ($(platform),)
        platform = unix
        ifeq ($(shell uname -a),)
@@@ -22,45 -20,35 +22,45 @@@ CC_AS ?= $(CC
  CFLAGS ?=
  
  TARGET_NAME := pcsx_rearmed
 -
 +LIBZ := -lz
 +LIBPTHREAD := -lpthread
 +LIBDL := -ldl
  MMAP_WIN32=0
 +EXTRA_LDFLAGS =
  
  # Unix
  ifeq ($(platform), unix)
        TARGET := $(TARGET_NAME)_libretro.so
        fpic := -fPIC
 -      SHARED := -shared -Wl,--version-script=libretro/link.T
 +
 +else ifeq ($(platform), linux-portable)
 +      TARGET := $(TARGET_NAME)_libretro.so
 +      fpic := -fPIC -nostdlib
 +      EXTRA_LDFLAGS += -fPIC -nostdlib
 +      LIBZ :=
 +      LIBPTHREAD :=
 +      LIBDL :=
 +      NO_UNDEF_CHECK = 1
  
  # OS X
  else ifeq ($(platform), osx)
        TARGET := $(TARGET_NAME)_libretro.dylib
        fpic := -fPIC
 -      SHARED := -dynamiclib
 -      OSXVER = `sw_vers -productVersion | cut -d. -f 2`
 -      OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"`
 -      ifeq ($(OSX_LT_MAVERICKS),"YES")
 -              fpic += -mmacosx-version-min=10.5
 -      endif
 +      fpic += -mmacosx-version-min=10.1
  
  # iOS
 -else ifeq ($(platform), ios)
 +else ifneq (,$(findstring ios,$(platform)))
        ARCH := arm
 +      USE_DYNAREC ?= 1
        TARGET := $(TARGET_NAME)_libretro_ios.dylib
 +ifeq ($(USE_DYNAREC),0)
 +      # Override
 +      TARGET := $(TARGET_NAME)_interpreter_libretro_ios.dylib
 +endif
        fpic := -fPIC
 -      SHARED := -dynamiclib
  
        ifeq ($(IOSSDK),)
 -              IOSSDK := $(shell xcrun -sdk iphoneos -show-sdk-path)
 +              IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path)
        endif
  
        CC = clang -arch armv7 -isysroot $(IOSSDK)
        ASFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon
        HAVE_NEON = 1
        BUILTIN_GPU = neon
 -      USE_DYNAREC = 1
        CFLAGS += -DIOS
 -      OSXVER = `sw_vers -productVersion | cut -d. -f 2`
 -      OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"`
 -      ifeq ($(OSX_LT_MAVERICKS),"YES")
 -              CC +=  -miphoneos-version-min=5.0
 -              CXX +=  -miphoneos-version-min=5.0
 -              CC_AS +=  -miphoneos-version-min=5.0
 -              CFLAGS += -miphoneos-version-min=5.0
 -      endif
 +ifeq ($(platform),ios9)
 +      CC     += -miphoneos-version-min=8.0
 +      CXX    += -miphoneos-version-min=8.0
 +      CC_AS  += -miphoneos-version-min=8.0
 +      CFLAGS += -miphoneos-version-min=8.0
 +else
 +      CC     += -miphoneos-version-min=5.0
 +      CXX    += -miphoneos-version-min=5.0
 +      CC_AS  += -miphoneos-version-min=5.0
 +      CFLAGS += -miphoneos-version-min=5.0
 +endif
  
  # PS3
  else ifeq ($(platform), ps3)
@@@ -111,48 -97,6 +111,48 @@@ else ifeq ($(platform), psp1
        AR = psp-ar$(EXE_EXT)
        CFLAGS += -DPSP -G0
  
 +# Vita
 +else ifeq ($(platform), vita)
 +      TARGET := $(TARGET_NAME)_libretro_vita.a
 +      CC = arm-vita-eabi-gcc$(EXE_EXT)
 +      AR = arm-vita-eabi-ar$(EXE_EXT)
 +      CFLAGS += -DVITA
 +      CFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -marm
 +      CFLAGS += -I$(VITASDK)/include -Ifrontend/vita
 +      CFLAGS += -DNO_SOCKET -DNO_OS -DNO_DYLIB
 +      ASFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon
 +
 +#     CFLAGS += -U__ARM_NEON__
 +      HAVE_NEON = 1
 +      BUILTIN_GPU = neon
 +
 +      USE_DYNAREC = 1
 +      DRC_CACHE_BASE = 0
 +
 +      ARCH = arm
 +      STATIC_LINKING = 1
 +
 +# CTR(3DS)
 +else ifeq ($(platform), ctr)
 +      TARGET := $(TARGET_NAME)_libretro_ctr.a
 +      CC = $(DEVKITARM)/bin/arm-none-eabi-gcc$(EXE_EXT)
 +      CXX = $(DEVKITARM)/bin/arm-none-eabi-g++$(EXE_EXT)
 +      AR = $(DEVKITARM)/bin/arm-none-eabi-ar$(EXE_EXT)
 +      CFLAGS += -DARM11 -D_3DS -DNO_OS -DNO_DYLIB -DNO_SOCKET
 +      CFLAGS += -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft
 +      CFLAGS += -Wall -mword-relocations
 +      CFLAGS += -fomit-frame-pointer -ffast-math      
 +      CFLAGS += -Ifrontend/3ds
 +      CFLAGS += -Werror=implicit-function-declaration
 +
 +#     CFLAGS += -DPCSX
 +#     BUILTIN_GPU = unai
 +      USE_DYNAREC = 1
 +      DRC_CACHE_BASE = 1
 +      ARCH = arm
 +
 +      STATIC_LINKING = 1
 +
  # Xbox 360
  else ifeq ($(platform), xenon)
        TARGET := $(TARGET_NAME)_libretro_xenon360.a
@@@ -177,7 -121,6 +177,7 @@@ else ifeq ($(platform), wii
  # QNX
  else ifeq ($(platform), qnx)
        TARGET := $(TARGET_NAME)_libretro_qnx.so
 +      fpic := -fPIC
        CC = qcc -Vgcc_ntoarmv7le
        CC_AS = $(CC)
        HAVE_NEON = 1
        DRC_CACHE_BASE = 0
        BUILTIN_GPU = neon
        ARCH = arm
-       CFLAGS += -DBASE_ADDR_FIXED=0 -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp
+       CFLAGS += -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp
        ASFLAGS +=  -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
 +      MAIN_LDLIBS += -lsocket
 +      LIBPTHREAD :=
 +      LIBDL :=
 +
 +#Raspberry Pi 2
 +else ifeq ($(platform), rpi2)
 +      TARGET := $(TARGET_NAME)_libretro.so
 +      fpic := -fPIC
 +      CFLAGS += -marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
 +      ASFLAGS += -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
 +      HAVE_NEON = 1
 +      ARCH = arm
 +      BUILTIN_GPU = neon
 +      USE_DYNAREC = 1
 +      
 +#Raspberry Pi 3
 +else ifeq ($(platform), rpi3)
 +      TARGET := $(TARGET_NAME)_libretro.so
 +      fpic := -fPIC
 +      CFLAGS += -marm -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
 +      ASFLAGS += -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
 +      HAVE_NEON = 1
 +      ARCH = arm
 +      BUILTIN_GPU = neon
 +      USE_DYNAREC = 1
  
  # ARM
  else ifneq (,$(findstring armv,$(platform)))
        TARGET := $(TARGET_NAME)_libretro.so
 -      SHARED := -shared -Wl,--no-undefined
 +      fpic := -fPIC
        DRC_CACHE_BASE = 0
        ifneq (,$(findstring cortexa8,$(platform)))
                CFLAGS += -marm -mcpu=cortex-a8
  # Windows
  else
        TARGET := $(TARGET_NAME)_libretro.dll
 -      CC = gcc
 -      fpic := -fPIC
 -      LD_FLAGS := -fPIC
 -      SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=libretro/link.T
 -      CFLAGS += -D__WIN32__ -D__WIN32_LIBRETRO__
 +      MAIN_LDFLAGS += -static-libgcc -static-libstdc++ -s
 +      CFLAGS += -D__WIN32__
        MMAP_WIN32=1
 -endif
 -
 -CFLAGS += -fPIC
 -ifeq ($(platform),win)
        MAIN_LDLIBS += -lws2_32
 -else ifneq ($(platform),qnx)
 -      LDLIBS += -lpthread
 -      MAIN_LDLIBS += -ldl
 +      LIBPTHREAD :=
 +      LIBDL :=
  endif
 +
 +CFLAGS += $(fpic)
  MAIN_LDFLAGS += -shared
 -MAIN_LDLIBS += -lm -lz
 -EXTRA_LDFLAGS =
 +MAIN_LDLIBS += $(LIBPTHREAD) $(LIBDL) $(LIBZ)
 +
 +# try to autodetect stuff for the lazy
 +ifndef ARCH
 +ARCH = $(shell $(CC) -dumpmachine | awk -F- '{print $$1}')
 +endif
 +ifndef HAVE_NEON
 +HAVE_NEON = $(shell $(CC) -E -dD - < /dev/null 2> /dev/null | grep -q __ARM_NEON__ && echo 1 || echo 0)
 +endif
 +ifeq ($(NO_UNDEF_CHECK)$(shell ld -v 2> /dev/null | awk '{print $$1}'),GNU)
 +MAIN_LDFLAGS += -Wl,--no-undefined
 +endif
  
+ # try to autodetect stuff for the lazy
+ ifndef ARCH
+ ARCH = $(shell $(CC) -dumpmachine | awk -F- '{print $$1}')
+ endif
+ ifndef HAVE_NEON
+ HAVE_NEON = $(shell $(CC) -E -dD - < /dev/null 2> /dev/null | grep -q __ARM_NEON__ && echo 1 || echo 0)
+ endif
+ ifeq ($(shell ld -v 2> /dev/null | awk '{print $$1}'),GNU)
+ MAIN_LDFLAGS += -Wl,--no-undefined
+ endif
  TARGET ?= libretro.so
  PLATFORM = libretro
  BUILTIN_GPU ?= peops
@@@ -275,14 -200,6 +286,14 @@@ SOUND_DRIVERS = libretr
  PLUGINS =
  NO_CONFIG_MAK = yes
  
 +libretro_all: all
 +ifeq ($(platform),ios)
 +ifeq ($(USE_DYNAREC),1)
 +      make -f Makefile.libretro USE_DYNAREC=0 platform=$(platform) clean
 +      make -f Makefile.libretro USE_DYNAREC=0 platform=$(platform)
 +endif
 +endif
 +
  include Makefile
  
  # no special AS needed for gpu_neon
diff --combined frontend/libretro.c
  #include <stdlib.h>
  #include <string.h>
  #include <strings.h>
+ #ifdef __MACH__
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #endif
  
  #include "../libpcsxcore/misc.h"
  #include "../libpcsxcore/psxcounters.h"
  #include "revision.h"
  #include "libretro.h"
  
 +#ifdef _3DS
 +#include "3ds/3ds_utils.h"
 +#endif
 +
 +#define PORTS_NUMBER 8
 +
  static retro_video_refresh_t video_cb;
  static retro_input_poll_t input_poll_cb;
  static retro_input_state_t input_state_cb;
@@@ -56,15 -54,9 +60,15 @@@ extern char Mcd1Data[MCD_SIZE]
  extern char McdDisable[2];
  
  /* PCSX ReARMed core calls and stuff */
 -int in_type1, in_type2;
 -int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
 -int in_keystate;
 +int in_type[8] =  { PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
 +                  PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
 +                  PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
 +                  PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE };
 +int in_analog_left[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
 +int in_analog_right[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
 +unsigned short in_keystate[PORTS_NUMBER];
 +int multitap1 = 0;
 +int multitap2 = 0;
  int in_enable_vibration = 1;
  
  /* PSX max resolution is 640x512, but with enhancement it's 1024x512 */
@@@ -177,164 -169,6 +181,164 @@@ static void vout_close(void
  {
  }
  
 +#ifdef _3DS
 +typedef struct
 +{
 +   void* buffer;
 +   uint32_t target_map;
 +   size_t size;
 +   enum psxMapTag tag;
 +}psx_map_t;
 +
 +psx_map_t custom_psx_maps[] = {
 +   {NULL, 0x13000000, 0x210000, MAP_TAG_RAM},   // 0x80000000
 +   {NULL, 0x12800000, 0x010000, MAP_TAG_OTHER}, // 0x1f800000
 +   {NULL, 0x12c00000, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000
 +   {NULL, 0x11000000, 0x800000, MAP_TAG_LUTS},  // 0x08000000
 +   {NULL, 0x12000000, 0x200000, MAP_TAG_VRAM},  // 0x00000000
 +};
 +
 +void* pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed,
 +      enum psxMapTag tag)
 +{
 +   (void)is_fixed;
 +   (void)addr;
 +
 +   if (__ctr_svchax)
 +   {
 +      psx_map_t* custom_map = custom_psx_maps;
 +
 +      for (; custom_map->size; custom_map++)
 +      {
 +         if ((custom_map->size == size) && (custom_map->tag == tag))
 +         {
 +            uint32_t ptr_aligned, tmp;
 +
 +            custom_map->buffer = malloc(size + 0x1000);
 +            ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
 +
 +            if(svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_MAP, 0x3) < 0)
 +            {
 +               SysPrintf("could not map memory @0x%08X\n", custom_map->target_map);
 +               exit(1);
 +            }
 +
 +            return (void*)custom_map->target_map;
 +         }
 +      }
 +   }
 +
 +   return malloc(size);
 +}
 +
 +void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag)
 +{
 +   (void)tag;
 +
 +   if (__ctr_svchax)
 +   {
 +      psx_map_t* custom_map = custom_psx_maps;
 +
 +      for (; custom_map->size; custom_map++)
 +      {
 +         if ((custom_map->target_map == (uint32_t)ptr))
 +         {
 +            uint32_t ptr_aligned, tmp;
 +
 +            ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
 +
 +            svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_UNMAP, 0x3);
 +
 +            free(custom_map->buffer);
 +            custom_map->buffer = NULL;
 +            return;
 +         }
 +      }
 +   }
 +
 +   free(ptr);
 +}
 +#endif
 +
 +#ifdef VITA
 +typedef struct
 +{
 +   void* buffer;
 +   uint32_t target_map;
 +   size_t size;
 +   enum psxMapTag tag;
 +}psx_map_t;
 +
 +psx_map_t custom_psx_maps[] = {
 +   {NULL, NULL, 0x210000, MAP_TAG_RAM},   // 0x80000000
 +   {NULL, NULL, 0x010000, MAP_TAG_OTHER}, // 0x1f800000
 +   {NULL, NULL, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000
 +   {NULL, NULL, 0x800000, MAP_TAG_LUTS},  // 0x08000000
 +   {NULL, NULL, 0x200000, MAP_TAG_VRAM},  // 0x00000000
 +};
 +
 +void* pl_vita_mmap(unsigned long addr, size_t size, int is_fixed,
 +      enum psxMapTag tag)
 +{
 +   (void)is_fixed;
 +   (void)addr;
 +
 +
 +    psx_map_t* custom_map = custom_psx_maps;
 +
 +    for (; custom_map->size; custom_map++)
 +    {
 +       if ((custom_map->size == size) && (custom_map->tag == tag))
 +       {
 +          int block, ret;
 +          char blockname[32];
 +          sprintf(blockname, "CODE 0x%08X",tag);
 +
 +          block = sceKernelAllocMemBlock(blockname, size + 0x1000);
 +          if(block<=0){
 +            sceClibPrintf("could not alloc mem block @0x%08X 0x%08X \n", block, tag);
 +            exit(1);
 +          }
 +
 +          // get base address
 +          ret = sceKernelGetMemBlockBase(block, &custom_map->buffer);
 +          if (ret < 0)
 +          {
 +            sceClibPrintf("could get address @0x%08X 0x%08X 0x%08X \n", block, ret, tag);
 +            exit(1);
 +          }
 +          custom_map->buffer = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
 +          custom_map->target_map = block;
 +
 +          return custom_map->buffer;
 +       }
 +    }
 +
 +
 +   return malloc(size);
 +}
 +
 +void pl_vita_munmap(void *ptr, size_t size, enum psxMapTag tag)
 +{
 +   (void)tag;
 +
 +   psx_map_t* custom_map = custom_psx_maps;
 +
 +  for (; custom_map->size; custom_map++)
 +  {
 +     if ((custom_map->buffer == ptr))
 +     {
 +        sceKernelFreeMemBlock(custom_map->target_map);
 +        custom_map->buffer = NULL;
 +        custom_map->target_map = NULL;
 +        return;
 +     }
 +  }
 +
 +   free(ptr);
 +}
 +#endif
 +
  static void *pl_mmap(unsigned int size)
  {
        return psxMap(0, size, 0, MAP_TAG_VRAM);
@@@ -414,16 -248,8 +418,16 @@@ void retro_set_environment(retro_enviro
     static const struct retro_variable vars[] = {
        { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" },
        { "pcsx_rearmed_region", "Region; Auto|NTSC|PAL" },
 -      { "pcsx_rearmed_pad1type", "Pad 1 Type; standard|analog" },
 -      { "pcsx_rearmed_pad2type", "Pad 2 Type; standard|analog" },
 +      { "pcsx_rearmed_pad1type", "Pad 1 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad2type", "Pad 2 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad3type", "Pad 3 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad4type", "Pad 4 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad5type", "Pad 5 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad6type", "Pad 6 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad7type", "Pad 7 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_pad8type", "Pad 8 Type; default|none|standard|analog|negcon" },
 +      { "pcsx_rearmed_multitap1", "Multitap 1; auto|disabled|enabled" },
 +      { "pcsx_rearmed_multitap2", "Multitap 2; auto|disabled|enabled" },
  #ifndef DRC_DISABLE
        { "pcsx_rearmed_drc", "Dynamic recompiler; enabled|disabled" },
  #endif
        { "pcsx_rearmed_duping_enable", "Frame duping; on|off" },
        { "pcsx_rearmed_spu_reverb", "Sound: Reverb; on|off" },
        { "pcsx_rearmed_spu_interpolation", "Sound: Interpolation; simple|gaussian|cubic|off" },
 +      { "pcsx_rearmed_pe2_fix", "Parasite Eve 2/Vandal Hearts 1/2 Fix; disabled|enabled" },
 +      { "pcsx_rearmed_inuyasha_fix", "InuYasha Sengoku Battle Fix; disabled|enabled" },
        { NULL, NULL },
     };
  
@@@ -456,160 -280,8 +460,160 @@@ unsigned retro_api_version(void
        return RETRO_API_VERSION;
  }
  
 +static int controller_port_variable(unsigned port, struct retro_variable *var)
 +{
 +      if (port >= PORTS_NUMBER)
 +              return 0;
 +
 +      if (!environ_cb)
 +              return 0;
 +
 +      var->value = NULL;
 +      switch (port) {
 +      case 0:
 +              var->key = "pcsx_rearmed_pad1type";
 +              break;
 +      case 1:
 +              var->key = "pcsx_rearmed_pad2type";
 +              break;
 +      case 2:
 +              var->key = "pcsx_rearmed_pad3type";
 +              break;
 +      case 3:
 +              var->key = "pcsx_rearmed_pad4type";
 +              break;
 +      case 4:
 +              var->key = "pcsx_rearmed_pad5type";
 +              break;
 +      case 5:
 +              var->key = "pcsx_rearmed_pad6type";
 +              break;
 +      case 6:
 +              var->key = "pcsx_rearmed_pad7type";
 +              break;
 +      case 7:
 +              var->key = "pcsx_rearmed_pad8type";
 +              break;
 +      }
 +
 +      return environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, var) || var->value;
 +}
 +
 +static void update_controller_port_variable(unsigned port)
 +{
 +      if (port >= PORTS_NUMBER)
 +              return;
 +
 +      struct retro_variable var;
 +
 +      if (controller_port_variable(port, &var))
 +      {
 +              if (strcmp(var.value, "standard") == 0)
 +                      in_type[0] = PSE_PAD_TYPE_STANDARD;
 +              else if (strcmp(var.value, "analog") == 0)
 +                      in_type[0] = PSE_PAD_TYPE_ANALOGPAD;
 +              else if (strcmp(var.value, "negcon") == 0)
 +                      in_type[0] = PSE_PAD_TYPE_NEGCON;
 +              else if (strcmp(var.value, "none") == 0)
 +                      in_type[0] = PSE_PAD_TYPE_NONE;
 +              // else 'default' case, do nothing
 +      }
 +}
 +
 +static void update_controller_port_device(unsigned port, unsigned device)
 +{
 +      if (port >= PORTS_NUMBER)
 +              return;
 +
 +      struct retro_variable var;
 +
 +      if (!controller_port_variable(port, &var))
 +              return;
 +
 +      if (strcmp(var.value, "default") != 0)
 +              return;
 +
 +      switch (device)
 +      {
 +      case RETRO_DEVICE_JOYPAD:
 +              in_type[port] = PSE_PAD_TYPE_STANDARD;
 +              break;
 +      case RETRO_DEVICE_ANALOG:
 +              in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
 +              break;
 +      case RETRO_DEVICE_MOUSE:
 +              in_type[port] = PSE_PAD_TYPE_MOUSE;
 +              break;
 +      case RETRO_DEVICE_LIGHTGUN:
 +              in_type[port] = PSE_PAD_TYPE_GUN;
 +              break;
 +      case RETRO_DEVICE_NONE:
 +      default:
 +              in_type[port] = PSE_PAD_TYPE_NONE;
 +      }
 +}
 +
 +static void update_multitap()
 +{
 +      struct retro_variable var;
 +      int auto_case, port;
 +
 +      var.value = NULL;
 +      var.key = "pcsx_rearmed_multitap1";
 +      auto_case = 0;
 +      if (environ_cb && (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value))
 +      {
 +              if (strcmp(var.value, "enabled") == 0)
 +                      multitap1 = 1;
 +              else if (strcmp(var.value, "disabled") == 0)
 +                      multitap1 = 0;
 +              else // 'auto' case
 +                      auto_case = 1;
 +      }
 +      else
 +              auto_case = 1;
 +
 +      if (auto_case)
 +      {
 +              // If a gamepad is plugged after port 2, we need a first multitap.
 +              multitap1 = 0;
 +              for (port = 2; port < PORTS_NUMBER; port++)
 +                      multitap1 |= in_type[port] != PSE_PAD_TYPE_NONE;
 +      }
 +
 +      var.value = NULL;
 +      var.key = "pcsx_rearmed_multitap2";
 +      auto_case = 0;
 +      if (environ_cb && (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value))
 +      {
 +              if (strcmp(var.value, "enabled") == 0)
 +                      multitap2 = 1;
 +              else if (strcmp(var.value, "disabled") == 0)
 +                      multitap2 = 0;
 +              else // 'auto' case
 +                      auto_case = 1;
 +      }
 +      else
 +              auto_case = 1;
 +
 +      if (auto_case)
 +      {
 +              // If a gamepad is plugged after port 4, we need a second multitap.
 +              multitap2 = 0;
 +              for (port = 4; port < PORTS_NUMBER; port++)
 +                      multitap2 |= in_type[port] != PSE_PAD_TYPE_NONE;
 +      }
 +}
 +
  void retro_set_controller_port_device(unsigned port, unsigned device)
  {
 +      SysPrintf("port %u  device %u",port,device);
 +
 +      if (port >= PORTS_NUMBER)
 +              return;
 +
 +      update_controller_port_device(port, device);
 +      update_multitap();
  }
  
  void retro_get_system_info(struct retro_system_info *info)
@@@ -634,8 -306,8 +638,8 @@@ void retro_get_system_av_info(struct re
  }
  
  /* savestates */
 -size_t retro_serialize_size(void) 
 -{ 
 +size_t retro_serialize_size(void)
 +{
        // it's currently 4380651-4397047 bytes,
        // but have some reserved for future
        return 0x440000;
@@@ -721,7 -393,7 +725,7 @@@ static void save_close(void *file
  }
  
  bool retro_serialize(void *data, size_t size)
 -{ 
 +{
        int ret = SaveState(data);
        return ret == 0 ? true : false;
  }
@@@ -1089,7 -761,7 +1093,7 @@@ bool retro_load_game(const struct retro
        { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2,    "R2" },
        { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3,    "R3" },
        { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,    "Select" },
 -      { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START,    "Start" }, 
 +      { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START,    "Start" },
        { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" },
        { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" },
        { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" },
        { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2,    "R2" },
        { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3,    "R3" },
        { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,    "Select" },
 -      { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START,    "Start" }, 
 +      { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START,    "Start" },
        { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" },
        { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" },
        { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" },
        { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2,    "R2" },
        { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3,    "R3" },
        { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,    "Select" },
 -      { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START,    "Start" }, 
 +      { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START,    "Start" },
        { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" },
        { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" },
        { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" },
@@@ -1230,7 -902,7 +1234,7 @@@ bool retro_load_game_special(unsigned g
        return false;
  }
  
 -void retro_unload_game(void) 
 +void retro_unload_game(void)
  {
  }
  
@@@ -1283,15 -955,16 +1287,15 @@@ static const unsigned short retro_psx_m
  static void update_variables(bool in_flight)
  {
     struct retro_variable var;
 -   
 +   int i;
 +
     var.value = NULL;
     var.key = "pcsx_rearmed_frameskip";
 -
     if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
        pl_rearmed_cbs.frameskip = atoi(var.value);
  
     var.value = NULL;
     var.key = "pcsx_rearmed_region";
 -
     if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
     {
        Config.PsxAuto = 0;
           Config.PsxType = 1;
     }
  
 -   var.value = NULL;
 -   var.key = "pcsx_rearmed_pad1type";
 +   for (i = 0; i < PORTS_NUMBER; i++)
 +      update_controller_port_variable(i);
  
 -   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
 -   {
 -      in_type1 = PSE_PAD_TYPE_STANDARD;
 -      if (strcmp(var.value, "analog") == 0)
 -         in_type1 = PSE_PAD_TYPE_ANALOGPAD;
 -   }
 -
 -   var.value = NULL;
 -   var.key = "pcsx_rearmed_pad2type";
 -
 -   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
 -   {
 -      in_type2 = PSE_PAD_TYPE_STANDARD;
 -      if (strcmp(var.value, "analog") == 0)
 -         in_type2 = PSE_PAD_TYPE_ANALOGPAD;
 -   }
 +   update_multitap();
  
  #ifdef __ARM_NEON__
     var.value = "NULL";
     {
        R3000Acpu *prev_cpu = psxCpu;
  
 +#ifdef _3DS
 +      if(!__ctr_svchax)
 +         Config.Cpu = CPU_INTERPRETER;
 +      else
 +#endif
        if (strcmp(var.value, "disabled") == 0)
           Config.Cpu = CPU_INTERPRETER;
        else if (strcmp(var.value, "enabled") == 0)
           spu_config.iUseInterpolation = 0;
     }
  
 +   var.value = "NULL";
 +   var.key = "pcsx_rearmed_pe2_fix";
 +
 +   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
 +   {
 +      if (strcmp(var.value, "disabled") == 0)
 +         Config.RCntFix = 0;
 +      else if (strcmp(var.value, "enabled") == 0)
 +         Config.RCntFix = 1;
 +   }
 +
 +   var.value = "NULL";
 +   var.key = "pcsx_rearmed_inuyasha_fix";
 +
 +   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
 +   {
 +      if (strcmp(var.value, "disabled") == 0)
 +         Config.VSyncWA = 0;
 +      else if (strcmp(var.value, "enabled") == 0)
 +         Config.VSyncWA = 1;
 +   }
 +
     if (in_flight) {
        // inform core things about possible config changes
        plugin_call_rearmed_cbs();
     }
  }
  
 -void retro_run(void) 
 +void retro_run(void)
  {
 -      int i;
 +    int i;
  
        input_poll_cb();
  
        if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
                update_variables(true);
  
 -      in_keystate = 0;
 -      for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
 -              if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, i))
 -                      in_keystate |= retro_psx_map[i];
 -      in_keystate <<= 16;
 -      for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
 -              if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i))
 -                      in_keystate |= retro_psx_map[i];
 +      // reset all keystate, query libretro for keystate
 +      int j;
 +      for(i = 0; i < PORTS_NUMBER; i++) {
 +              in_keystate[i] = 0;
  
 -      if (in_type1 == PSE_PAD_TYPE_ANALOGPAD)
 -      {
 -              in_a1[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
 -              in_a1[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
 -              in_a2[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
 -              in_a2[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
 +              if (in_type[i] == PSE_PAD_TYPE_NONE)
 +                      continue;
 +
 +              // query libretro for keystate
 +              for (j = 0; j < RETRO_PSX_MAP_LEN; j++)
 +                      if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, j))
 +                              in_keystate[i] |= retro_psx_map[j];
 +
 +              if (in_type[i] == PSE_PAD_TYPE_ANALOGPAD)
 +              {
 +                      in_analog_left[i][0] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
 +                      in_analog_left[i][1] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
 +                      in_analog_right[i][0] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
 +                      in_analog_right[i][1] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
 +              }
        }
  
        stop = 0;
@@@ -1506,7 -1162,7 +1510,7 @@@ static bool try_use_bios(const char *pa
        return true;
  }
  
 -#if 1
 +#ifndef VITA
  #include <sys/types.h>
  #include <dirent.h>
  
@@@ -1550,29 -1206,19 +1554,34 @@@ void retro_init(void
        int i, ret;
        bool found_bios = false;
  
+ #ifdef __MACH__
+       // magic sauce to make the dynarec work on iOS
+       syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0);
+ #endif
 +#ifdef _3DS
 +   psxMapHook = pl_3ds_mmap;
 +   psxUnmapHook = pl_3ds_munmap;
 +#endif
 +#ifdef VITA
 +   psxMapHook = pl_vita_mmap;
 +   psxUnmapHook = pl_vita_munmap;
 +#endif
        ret = emu_core_preinit();
 +#ifdef _3DS
 +   /* emu_core_preinit sets the cpu to dynarec */
 +   if(!__ctr_svchax)
 +      Config.Cpu = CPU_INTERPRETER;
 +#endif
        ret |= emu_core_init();
        if (ret != 0) {
                SysPrintf("PCSX init failed.\n");
                exit(1);
        }
  
 -#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)
 +#ifdef _3DS
 +   vout_buf = linearMemAlign(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2, 0x80);
 +#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && !defined(VITA)
        posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
  #else
        vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
  
        if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
        {
 -              snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s/", dir);
 +              snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
  
                for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) {
                        snprintf(path, sizeof(path), "%s/%s.bin", dir, bios[i]);
        else
        {
                SysPrintf("no BIOS files found.\n");
 -              struct retro_message msg = 
 +              struct retro_message msg =
                {
                        "no BIOS found, expect bugs!",
                        180
  void retro_deinit(void)
  {
        SysClose();
 +#ifdef _3DS
 +   linearFree(vout_buf);
 +#else
        free(vout_buf);
 +#endif
        vout_buf = NULL;
  }
 +
 +#ifdef VITA
 +#include <psp2/kernel/threadmgr.h>
 +int usleep (unsigned long us)
 +{
 +   sceKernelDelayThread(us);
 +}
 +#endif