summaryrefslogtreecommitdiff
path: root/pcr
diff options
context:
space:
mode:
authorcoadde [Márcio Alexandre Silva Delgado] <coadde@parabola.nu>2016-03-19 02:47:05 -0300
committercoadde [Márcio Alexandre Silva Delgado] <coadde@parabola.nu>2016-03-19 02:47:05 -0300
commitf326fa638b4f279087b25fa9dc8563fd0dfc4104 (patch)
tree6921d70e06cc0d9893812ccc7a046f76e6b855b9 /pcr
parentd67412b3ffe38c911bc6a716dd444a71171cbf9d (diff)
remove reicast-multilib-git
Diffstat (limited to 'pcr')
-rw-r--r--pcr/reicast-multilib-git/PKGBUILD155
-rw-r--r--pcr/reicast-multilib-git/enable_multiplayer_support.patch37
-rw-r--r--pcr/reicast-multilib-git/fix-dyna-constprop.patch63
-rw-r--r--pcr/reicast-multilib-git/futuristic-memops.patch31
-rw-r--r--pcr/reicast-multilib-git/generalize-mappings.patch1979
-rw-r--r--pcr/reicast-multilib-git/loop-tracing.patch109
-rw-r--r--pcr/reicast-multilib-git/loungekatt_rm-nonfree-fp.patch1451
-rw-r--r--pcr/reicast-multilib-git/multiplayer-unstable.patch450
-rw-r--r--pcr/reicast-multilib-git/multiplayer.patch1211
-rw-r--r--pcr/reicast-multilib-git/refactor-rend-stuff.patch1244
-rw-r--r--pcr/reicast-multilib-git/sdl-opengl.patch251
-rw-r--r--pcr/reicast-multilib-git/sh-block-graphs.patch296
-rw-r--r--pcr/reicast-multilib-git/ta-hash-logs.patch120
13 files changed, 0 insertions, 7397 deletions
diff --git a/pcr/reicast-multilib-git/PKGBUILD b/pcr/reicast-multilib-git/PKGBUILD
deleted file mode 100644
index 6d511e847..000000000
--- a/pcr/reicast-multilib-git/PKGBUILD
+++ /dev/null
@@ -1,155 +0,0 @@
-# Maintainer (Arch): carstene1ns <arch carsten-teibes de> - http://git.io/ctPKG
-# Maintainer: André Silva <emulatorman@parabola.nu>
-# Maintainer: Márcio Silva <coadde@parabola.nu>
-
-# error: in fault_handler -> ../../core/linux/common.cpp : 99
-# read: error-mem.txt
-
-pkgname=reicast-multilib-git
-pkgver=r1665.915d6b2
-pkgrel=1
-pkgdesc="A multiplatform Sega Dreamcast emulator"
-arch=('x86_64')
-url="http://reicast.com/"
-license=('GPL2')
-provides=('reicast')
-conflicts=('reicast')
-makedepends=('git' 'gcc-multilib')
-depends=('lib32-libgl' 'lib32-alsa-plugins' 'lib32-libpulse' 'python-evdev' )
-source=(reicast::"git+https://github.com/reicast/reicast-emulator.git"
- 'enable_multiplayer_support.patch'
- 'fix-dyna-constprop.patch'
- 'futuristic-memops.patch'
- 'generalize-mappings.patch'
- 'loop-tracing.patch'
- 'loungekatt_rm-nonfree-fp.patch'
- 'multiplayer.patch'
- 'multiplayer-unstable.patch'
- 'refactor-rend-stuff.patch'
- 'sdl-opengl.patch'
- 'sh-block-graphs.patch'
- 'ta-hash-logs.patch')
-sha256sums=('SKIP'
- '12bfc58e12b3ee79b0c82159cdc70c76a4b6804f5c6986853156602bb0e6beb0'
- 'c14287cf2b2289b9de28cedeee06fcb89ca40da50e34607780dce55d7d8e5fd6'
- 'ce3fe9f10555c473cafbf4e85724ebe7a8535a1fa3bfae3c9bc0fe518024f71e'
- '4c0227db07dc9fa4713694bc438345261e401e0b10c89b25a3c1d20ac9acd9b9'
- 'af47982ca67babb18a96014643c2394b45316f474c3b07b4e38079f780606fce'
- '4a6025daded179e88174057affadbcfd539d919c35c36945aa3273fab0b0cb49'
- '09097f59200daaa919fee6f50473f4295a7de6702f40ad5e2648d12c9478a080'
- '7c0e2a158d7d37ddbf99a40d11a0a889e55c1e85f9c17a2602e5a2bc809ff4ac'
- 'aead8326ac6815b555be03030ffbdc8f6ced625c980e77eca89e570591c5eb34'
- 'cf386ebaeafce046a1fc971a5b140bb6a1245840ad2c2a341541327ed6f5606c'
- '94694d1b615facb39b5ee92ed90c6cefc77fab23fb97f2fcc82e0aa6e1cb14c5'
- 'ead1e44b82c5a58beca6550a7620fc426b7729f0b7e2ebe27583397fac2a574d')
-
-pkgver() {
- cd reicast
- printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
-}
-
-prepare () {
- cd reicast
-
- # Remove nonfree fp.h header
- # rm -v core/deps/libpng/fp.h
-
- # Add Multiplayer support
- patch -Np1 -i "$srcdir"/enable_multiplayer_support.patch
-
- # Add extra patches
- patch -Np1 -i "$srcdir"/fix-dyna-constprop.patch
- patch -Np1 -i "$srcdir"/futuristic-memops.patch
- patch -Np1 -i "$srcdir"/generalize-mappings.patch
-# patch -Np1 -i "$srcdir"/loop-tracing.patch # failed build on i686
- patch -Np1 -i "$srcdir"/loungekatt_rm-nonfree-fp.patch
- patch -Np1 -i "$srcdir"/refactor-rend-stuff.patch
- patch -Np1 -i "$srcdir"/sdl-opengl.patch
- patch -Np1 -i "$srcdir"/sh-block-graphs.patch
- patch -Np1 -i "$srcdir"/ta-hash-logs.patch
-
- # Add Multiplayer support (unstable)
- # core/linux-dist/main.cpp
- # evdev_controllers[port] = { -1, NULL };
- # evdev_device_id[port] = -1;
- # maple_controller[port].enabled = true;
-# patch -Np1 -i "$srcdir"/multiplayer-unstable.patch
-# sed -i 's|kcode[[]port[]]|maple_controller[port].buttons|g
-# s|lt[[]port[]]|maple_controller[port].trigger_left|g
-# s|rt[[]port[]]|maple_controller[port].trigger_right|g
-# s|joyx[[]port[]]|maple_controller[port].stick_x|g
-# s|joyy[[]port[]]|maple_controller[port].stick_y|g
-# s|DC_DPAD_LEFT|DC_BTN_DPAD1_LEFT|g
-# s|DC_DPAD_RIGHT|DC_BTN_DPAD1_RIGHT|g
-# s|DC_DPAD_UP|DC_BTN_DPAD1_UP|g
-# s|DC_DPAD_DOWN|DC_BTN_DPAD1_DOWN|g
-# s|DC_DPAD2_LEFT|DC_BTN_DPAD2_LEFT|g
-# s|DC_DPAD2_RIGHT|DC_BTN_DPAD2_RIGHT|g
-# s|DC_DPAD2_UP|DC_BTN_DPAD2_UP|g
-# s|DC_DPAD2_DOWN|DC_BTN_DPAD2_DOWN|g
-# s|const u32 sdl_map_|const DreamcastControllerCodes sdl_map_|
-# s|const u32[*] sdl_map_|const DreamcastControllerCodes* sdl_map_|
-# \|extern u16|d
-# \|extern u32|d
-# \|extern u8 |d
-# \|extern s8 |d
-# \|#define DC_|d
-# \|u16 kcode|d
-# \|u8 rt|d
-# \|u8 lt|d
-# \|u32 vks|d
-# \|s8 joy|d
-# \|int port = 0; port| s|4|MAPLE_NUM_PORTS|
-# \|enum DreamcastController|,+32 d
-# s|#include ["]types[.]h["]|#include "types.h"\n#include "hw/maple/maple_controller.h"|
-# ' core/sdl/sdl.cpp \
-# core/linux-dist/main.cpp \
-# core/linux-dist/main.h \
-# shell/apple/emulator-ios/emulator/EmulatorView.mm
-# sed -i 's|kcode[[]port[]]|maple_controller[port].buttons|g
-# s|lt[[]port[]]|maple_controller[port].trigger_left|g
-# s|rt[[]port[]]|maple_controller[port].trigger_right|g
-# s|joyx[[]port[]]|maple_controller[port].stick_x|g
-# s|joyy[[]port[]]|maple_controller[port].stick_y|g
-# s|DC_DPAD_LEFT|DC_BTN_DPAD1_LEFT|g
-# s|DC_DPAD_RIGHT|DC_BTN_DPAD1_RIGHT|g
-# s|DC_DPAD_UP|DC_BTN_DPAD1_UP|g
-# s|DC_DPAD_DOWN|DC_BTN_DPAD1_DOWN|g
-# s|DC_DPAD2_LEFT|DC_BTN_DPAD2_LEFT|g
-# s|DC_DPAD2_RIGHT|DC_BTN_DPAD2_RIGHT|g
-# s|DC_DPAD2_UP|DC_BTN_DPAD2_UP|g
-# s|DC_DPAD2_DOWN|DC_BTN_DPAD2_DOWN|g
-# \|extern u16|d
-# \|extern u8 |d
-# \|extern s8 |d
-# \|#define key_CONT_|d
-# s|#include ["]glshaders[.]h["]|#include "glshaders.h"\n#include "hw/maple/maple_controller.h"|
-# ' core/rend/gles/gles.cpp
-# sed -i 's|x11_keymap[[]53[]] = DC_BTN_X;|x11_keymap[53] = DC_BTN_X;\nx11_keymap[52] = DC_BTN_Y;|
-# ' core/linux-dist/x11.cpp
-# sed -i 's|DC_BTN_DPAD_|DC_BTN_DPAD1_|
-# ' core/hw/maple/maple_controller.h \
-# core/windows/winmain.cpp \
-# core/rend/gles/gles.cpp \
-# shell/apple/emulator-osx/emulator-osx/osx-main.mm
-
- # Add experimental shadow support: http://github.com/reicast-emulator/issues/94
- sed -i 's|//DrawModVols|DrawModVols|' core/rend/gles/gldraw.cpp
-
- # Fix Xbox Input Axis
- # sed -i 's|DC_AXIS_LT, 0, 0, DC_AXIS_RT|0, 0, DC_AXIS_RT, DC_AXIS_LT|' core/linux-dist/joystick.cpp
- sed -i 's|DC_AXIS_LT, 0, 0, DC_AXIS_RT|0, 0, DC_AXIS_RT, DC_AXIS_LT|' core/sdl/sdl.cpp # with generalize-mappings.patch
-
- # Enable Pulseaudio
- sed -i 's|#USE_PULSEAUDIO|USE_PULSEAUDIO|' shell/linux/Makefile
-}
-
-build () {
- mkdir -vm 0755 "$srcdir"/pkgbuild-dir
- make -C reicast/shell/linux platform=x86 PREFIX=/usr DESTDIR="$srcdir"/pkgbuild-dir install
-}
-
-package () {
- cp -va "$srcdir"/pkgbuild-dir/* "$pkgdir"
- install -Dm 644 reicast/LICENSE "$pkgdir"/usr/share/licenses/$pkgname/LICENSE
-}
diff --git a/pcr/reicast-multilib-git/enable_multiplayer_support.patch b/pcr/reicast-multilib-git/enable_multiplayer_support.patch
deleted file mode 100644
index 57794d1eb..000000000
--- a/pcr/reicast-multilib-git/enable_multiplayer_support.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-diff -Nur a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp
---- a/core/hw/maple/maple_cfg.cpp 2015-08-27 12:17:34.718561243 -0300
-+++ b/core/hw/maple/maple_cfg.cpp 2015-08-27 15:57:10.233166402 -0300
-@@ -22,10 +22,12 @@
- */
- void UpdateInputState(u32 port);
-
--extern u16 kcode[4];
--extern u32 vks[4];
--extern s8 joyx[4],joyy[4];
--extern u8 rt[4],lt[4];
-+#define NUM_PORTS 4
-+
-+extern u16 kcode[NUM_PORTS];
-+extern u32 vks[NUM_PORTS];
-+extern s8 joyx[NUM_PORTS],joyy[NUM_PORTS];
-+extern u8 rt[NUM_PORTS],lt[NUM_PORTS];
-
- u8 GetBtFromSgn(s8 val)
- {
-@@ -69,10 +71,13 @@
- void mcfg_CreateDevices()
- {
- #if DC_PLATFORM == DC_PLATFORM_DREAMCAST
-- mcfg_Create(MDT_SegaController,0,5);
-+ for (int i = 0; i < NUM_PORTS; i++)
-+ {
-+ mcfg_Create(MDT_SegaController,i,5);
-
-- mcfg_Create(MDT_SegaVMU,0,0);
-- mcfg_Create(MDT_SegaVMU,0,1);
-+ mcfg_Create(MDT_SegaVMU,i,0);
-+ mcfg_Create(MDT_SegaVMU,i,1);
-+ }
- #else
- mcfg_Create(MDT_NaomiJamma, 0, 5);
- #endif
diff --git a/pcr/reicast-multilib-git/fix-dyna-constprop.patch b/pcr/reicast-multilib-git/fix-dyna-constprop.patch
deleted file mode 100644
index c7c89b5e2..000000000
--- a/pcr/reicast-multilib-git/fix-dyna-constprop.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-diff -Nur a/core/hw/sh4/dyna/shil.cpp b/core/hw/sh4/dyna/shil.cpp
---- a/core/hw/sh4/dyna/shil.cpp 2015-10-06 21:43:53.031336322 -0300
-+++ b/core/hw/sh4/dyna/shil.cpp 2015-10-06 21:45:06.558863627 -0300
-@@ -521,20 +521,39 @@
- rv[op->rd._reg]=op->rs1._imm;
- }
-
-- //NOT WORKING
-- //WE NEED PROPER PAGELOCKS
-- if (op->op==shop_readm && op->rs1.is_imm() && op->rd.is_r32i() && op->rd._reg<16 && op->flags==0x4 && op->rs3.is_null())
-- {
-- u32 baddr=blk->addr&0x0FFFFFFF;
-+ if (0) {
-+ //a more minimalistic but still broken approach for this.
-+ //this is clearly a hack
-+ if (op->op == shop_readm && op->rs1.is_imm() && IsOnRam(op->rs1.imm_value()))
-+ {
-+ u32 round = op->rs1.imm_value() & ~PAGE_MASK;
-+ bool optmize_away = round == (blk->addr & ~PAGE_MASK) && (blk->addr & 0x007FFFFF) > 0x200000;
-+
-+ if (optmize_away && op->flags == 4) {
-+ u32 data = _vmem_ReadMem32(op->rs1.imm_value());
-+ op->op = shop_mov32;
-+ op->rs1.type = FMT_IMM;
-+ op->rs1._imm = data;
-+ }
-+ }
-+ }
-
-- if (/*baddr==0xC158400 &&*/ blk->addr/PAGE_SIZE == op->rs1._imm/PAGE_SIZE)
-+ if (0) {
-+ //NOT WORKING
-+ //WE NEED PROPER PAGELOCKS
-+ if (op->op == shop_readm && op->rs1.is_imm() && op->rd.is_r32i() && op->rd._reg<16 && op->flags == 0x4 && op->rs3.is_null())
- {
-- isi[op->rd._reg]=true;
-- rv[op->rd._reg]= ReadMem32(op->rs1._imm);
-- printf("IMM MOVE: %08X -> %08X\n",op->rs1._imm,rv[op->rd._reg]);
-+ u32 baddr = blk->addr & 0x0FFFFFFF;
-
-- op->op=shop_mov32;
-- op->rs1._imm=rv[op->rd._reg];
-+ if (/*baddr==0xC158400 &&*/ blk->addr / PAGE_SIZE == op->rs1._imm / PAGE_SIZE)
-+ {
-+ isi[op->rd._reg] = true;
-+ rv[op->rd._reg] = ReadMem32(op->rs1._imm);
-+ printf("IMM MOVE: %08X -> %08X\n", op->rs1._imm, rv[op->rd._reg]);
-+
-+ op->op = shop_mov32;
-+ op->rs1._imm = rv[op->rd._reg];
-+ }
- }
- }
- }
-@@ -925,7 +944,7 @@
- */
- if (settings.dynarec.unstable_opt)
- sq_pref(blk);
-- //constprop(blk); // crashes on ip
-+ constprop(blk); // maybe it works w/o the readm parts?
- #if HOST_CPU==CPU_X86
- // rdgrp(blk);
- // wtgrp(blk);
diff --git a/pcr/reicast-multilib-git/futuristic-memops.patch b/pcr/reicast-multilib-git/futuristic-memops.patch
deleted file mode 100644
index 517670402..000000000
--- a/pcr/reicast-multilib-git/futuristic-memops.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-diff -Nur a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h
---- a/core/hw/sh4/dyna/shil_canonical.h 2015-10-06 21:43:53.031336322 -0300
-+++ b/core/hw/sh4/dyna/shil_canonical.h 2015-10-06 21:48:30.009328396 -0300
-@@ -206,6 +206,27 @@
- shil_recimp()
- shil_opc_end()
-
-+//mem io v2
-+
-+//vref = vrans<mode|size>(ptr, nil)
-+//vref = vrans<mode|size>(base, offset)
-+shil_opc(vtrans)
-+shil_recimp()
-+shil_opc_end()
-+
-+//dst = readpvr<size>(vref)
-+//dst = readpvr<size>(vref, nil, offs) w/ offs < 1024
-+shil_opc(readvptr)
-+shil_recimp()
-+shil_opc_end()
-+
-+//writevptr<size>(vref, src)
-+//writevptr<size>(vref, src, offs) w/ offs < 1024
-+shil_opc(writevptr)
-+shil_recimp()
-+shil_opc_end()
-+
-+
- //Canonical impl. opcodes !
- shil_opc(sync_sr)
- shil_canonical
diff --git a/pcr/reicast-multilib-git/generalize-mappings.patch b/pcr/reicast-multilib-git/generalize-mappings.patch
deleted file mode 100644
index a47681f39..000000000
--- a/pcr/reicast-multilib-git/generalize-mappings.patch
+++ /dev/null
@@ -1,1979 +0,0 @@
-diff -Nur a/core/linux-dist/bimap.h b/core/linux-dist/bimap.h
---- a/core/linux-dist/bimap.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/bimap.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,67 @@
-+/* SimpleBimap
-+ *
-+ * A basic implementation of a bidirectional map that not only allows
-+ * you to get a mapped value from a key, but also the other way around.
-+ * Deleting elements and other fancy (and not-so-fancy) stuff is not
-+ * supported.
-+ *
-+ * Usage example:
-+ * SimpleBimap<std::string, std::string> bimap;
-+ * bimap.insert("foo", "bar");
-+ * printf("foo -> %s\n", bimap.get_by_key("foo")->c_str());
-+ * printf("bar <- %s\n", bimap.get_by_value("bar")->c_str());
-+ * if(bimap.get_by_key("somekey") == NULL)
-+ * puts("somekey not found");
-+ *
-+ * The above example's output:
-+ * foo -> bar
-+ * bar <- foo
-+ * somekey not found
-+ */
-+#include <cstddef>
-+#include <utility>
-+#include <map>
-+
-+template<typename T1, typename T2>
-+class SimpleBimap
-+{
-+ private:
-+ typedef typename std::map<T2, T1*> MapA;
-+ typedef typename std::map<T1, T2*> MapB;
-+ MapA map_a;
-+ MapB map_b;
-+ public:
-+ void insert(const T1& a, const T2& b)
-+ {
-+ // create first pair
-+ typename MapA::iterator iter_a = map_a.insert(std::pair<T2, T1*>(b, NULL)).first;
-+ T2* ptr_b = const_cast<T2*>(&(iter_a->first));
-+
-+ // insert second pair (a, pointer_to_b)
-+ typename MapB::iterator iter_b = map_b.insert(std::pair<T1, T2*>(a, ptr_b)).first;
-+
-+ // update pointer in map_a to point to a
-+ T1* ptr_a = const_cast<T1*>(&(iter_b->first));
-+ iter_a->second = ptr_a;
-+ }
-+
-+ const T2* get_by_key(const T1 &a)
-+ {
-+ typename MapB::iterator it = this->map_b.find(a);
-+ if(it != this->map_b.end())
-+ {
-+ return (it->second);
-+ }
-+ return NULL;
-+ }
-+
-+ const T1* get_by_value(const T2 &b)
-+ {
-+ typename MapA::iterator it = this->map_a.find(b);
-+ if(it != this->map_a.end())
-+ {
-+ return (it->second);
-+ }
-+ return NULL;
-+ }
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/evdev.cpp b/core/linux-dist/evdev.cpp
---- a/core/linux-dist/evdev.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/evdev.cpp 1969-12-31 21:00:00.000000000 -0300
-@@ -1,450 +0,0 @@
--#include <unistd.h>
--#include <fcntl.h>
--#include <linux/input.h>
--#include "linux-dist/evdev.h"
--#include "linux-dist/main.h"
--#include "cfg/ini.h"
--#include <vector>
--#include <map>
--#include <dlfcn.h>
--
--#if defined(USE_EVDEV)
-- bool libevdev_tried = false;
-- bool libevdev_available = false;
-- typedef int (*libevdev_func1_t)(int, const char*);
-- typedef const char* (*libevdev_func2_t)(int, int);
-- libevdev_func1_t libevdev_event_code_from_name;
-- libevdev_func2_t libevdev_event_code_get_name;
--
-- void load_libevdev()
-- {
-- if (libevdev_tried)
-- {
-- return;
-- }
--
-- libevdev_tried = true;
-- void* lib_handle = dlopen("libevdev.so", RTLD_NOW);
--
-- bool failed = false;
--
-- if (!lib_handle)
-- {
-- fprintf(stderr, "%s\n", dlerror());
-- failed = true;
-- }
-- else
-- {
-- libevdev_event_code_from_name = reinterpret_cast<libevdev_func1_t>(dlsym(lib_handle, "libevdev_event_code_from_name"));
--
-- const char* error1 = dlerror();
-- if (error1 != NULL)
-- {
-- fprintf(stderr, "%s\n", error1);
-- failed = true;
-- }
--
-- libevdev_event_code_get_name = reinterpret_cast<libevdev_func2_t>(dlsym(lib_handle, "libevdev_event_code_get_name"));
--
-- const char* error2 = dlerror();
-- if (error2 != NULL)
-- {
-- fprintf(stderr, "%s\n", error2);
-- failed = true;
-- }
-- }
--
-- if(failed)
-- {
-- puts("WARNING: libevdev is not available. You'll not be able to use button names instead of numeric codes in your controller mappings!\n");
-- return;
-- }
--
-- libevdev_available = true;
-- }
--
-- s8 EvdevAxisData::convert(s32 value)
-- {
-- return (((value - min) * 255) / range);
-- }
--
-- void EvdevAxisData::init(int fd, int code, bool inverted)
-- {
-- struct input_absinfo abs;
-- if(code < 0 || ioctl(fd, EVIOCGABS(code), &abs))
-- {
-- if(code >= 0)
-- {
-- perror("evdev ioctl");
-- }
-- this->range = 255;
-- this->min = 0;
-- return;
-- }
-- s32 min = abs.minimum;
-- s32 max = abs.maximum;
-- printf("evdev: range of axis %d is from %d to %d\n", code, min, max);
-- if(inverted)
-- {
-- this->range = (min - max);
-- this->min = max;
-- }
-- else
-- {
-- this->range = (max - min);
-- this->min = min;
-- }
-- }
--
-- void EvdevController::init()
-- {
-- this->data_x.init(this->fd, this->mapping->Axis_Analog_X, this->mapping->Axis_Analog_X_Inverted);
-- this->data_y.init(this->fd, this->mapping->Axis_Analog_Y, this->mapping->Axis_Analog_Y_Inverted);
-- this->data_trigger_left.init(this->fd, this->mapping->Axis_Trigger_Left, this->mapping->Axis_Trigger_Left_Inverted);
-- this->data_trigger_right.init(this->fd, this->mapping->Axis_Trigger_Right, this->mapping->Axis_Trigger_Right_Inverted);
-- }
--
-- std::map<std::string, EvdevControllerMapping> loaded_mappings;
--
-- int load_keycode(ConfigFile* cfg, string section, string dc_key)
-- {
-- int code = -1;
--
-- string keycode = cfg->get(section, dc_key, "-1");
-- if (strstr(keycode.c_str(), "KEY_") != NULL ||
-- strstr(keycode.c_str(), "BTN_") != NULL ||
-- strstr(keycode.c_str(), "ABS_") != NULL)
-- {
-- if(libevdev_available)
-- {
-- int type = ((strstr(keycode.c_str(), "ABS_") != NULL) ? EV_ABS : EV_KEY);
-- code = libevdev_event_code_from_name(type, keycode.c_str());
-- }
-- if(code < 0)
-- {
-- printf("evdev: failed to find keycode for '%s'\n", keycode.c_str());
-- }
-- else
-- {
-- printf("%s = %s (%d)\n", dc_key.c_str(), keycode.c_str(), code);
-- }
-- return code;
-- }
--
-- code = cfg->get_int(section, dc_key, -1);
-- if(code >= 0)
-- {
-- char* name = NULL;
-- if(libevdev_available)
-- {
-- int type = ((strstr(dc_key.c_str(), "axis_") != NULL) ? EV_ABS : EV_KEY);
-- name = (char*)libevdev_event_code_get_name(type, code);
-- }
-- if (name != NULL)
-- {
-- printf("%s = %s (%d)\n", dc_key.c_str(), name, code);
-- }
-- else
-- {
-- printf("%s = %d\n", dc_key.c_str(), code);
-- }
-- }
-- return code;
-- }
--
-- EvdevControllerMapping load_mapping(FILE* fd)
-- {
-- ConfigFile mf;
-- mf.parse(fd);
--
-- EvdevControllerMapping mapping = {
-- mf.get("emulator", "mapping_name", "<Unknown>").c_str(),
-- load_keycode(&mf, "dreamcast", "btn_a"),
-- load_keycode(&mf, "dreamcast", "btn_b"),
-- load_keycode(&mf, "dreamcast", "btn_c"),
-- load_keycode(&mf, "dreamcast", "btn_d"),
-- load_keycode(&mf, "dreamcast", "btn_x"),
-- load_keycode(&mf, "dreamcast", "btn_y"),
-- load_keycode(&mf, "dreamcast", "btn_z"),
-- load_keycode(&mf, "dreamcast", "btn_start"),
-- load_keycode(&mf, "emulator", "btn_escape"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_left"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_right"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_up"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_down"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_left"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_right"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_up"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_down"),
-- load_keycode(&mf, "compat", "btn_trigger_left"),
-- load_keycode(&mf, "compat", "btn_trigger_right"),
-- load_keycode(&mf, "compat", "axis_dpad1_x"),
-- load_keycode(&mf, "compat", "axis_dpad1_y"),
-- load_keycode(&mf, "compat", "axis_dpad2_x"),
-- load_keycode(&mf, "compat", "axis_dpad2_y"),
-- load_keycode(&mf, "dreamcast", "axis_x"),
-- load_keycode(&mf, "dreamcast", "axis_y"),
-- load_keycode(&mf, "dreamcast", "axis_trigger_left"),
-- load_keycode(&mf, "dreamcast", "axis_trigger_right"),
-- mf.get_bool("compat", "axis_x_inverted", false),
-- mf.get_bool("compat", "axis_y_inverted", false),
-- mf.get_bool("compat", "axis_trigger_left_inverted", false),
-- mf.get_bool("compat", "axis_trigger_right_inverted", false)
-- };
-- return mapping;
-- }
--
-- int input_evdev_init(EvdevController* controller, const char* device, const char* custom_mapping_fname = NULL)
-- {
-- load_libevdev();
--
-- char name[256] = "Unknown";
--
-- printf("evdev: Trying to open device at '%s'\n", device);
--
-- int fd = open(device, O_RDONLY);
--
-- if (fd >= 0)
-- {
-- fcntl(fd, F_SETFL, O_NONBLOCK);
-- if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)
-- {
-- perror("evdev: ioctl");
-- return -2;
-- }
-- else
-- {
-- printf("evdev: Found '%s' at '%s'\n", name, device);
--
-- controller->fd = fd;
--
-- const char* mapping_fname;
--
-- if(custom_mapping_fname != NULL)
-- {
-- mapping_fname = custom_mapping_fname;
-- }
-- else
-- {
-- #if defined(TARGET_PANDORA)
-- mapping_fname = "controller_pandora.cfg";
-- #elif defined(TARGET_GCW0)
-- mapping_fname = "controller_gcwz.cfg";
-- #else
-- if (strcmp(name, "Microsoft X-Box 360 pad") == 0 ||
-- strcmp(name, "Xbox 360 Wireless Receiver") == 0 ||
-- strcmp(name, "Xbox 360 Wireless Receiver (XBOX)") == 0)
-- {
-- mapping_fname = "controller_xpad.cfg";
-- }
-- else if (strstr(name, "Xbox Gamepad (userspace driver)") != NULL)
-- {
-- mapping_fname = "controller_xboxdrv.cfg";
-- }
-- else if (strstr(name, "keyboard") != NULL ||
-- strstr(name, "Keyboard") != NULL)
-- {
-- mapping_fname = "keyboard.cfg";
-- }
-- else
-- {
-- mapping_fname = "controller_generic.cfg";
-- }
-- #endif
-- }
-- if(loaded_mappings.count(string(mapping_fname)) == 0)
-- {
-- FILE* mapping_fd = NULL;
-- if(mapping_fname[0] == '/')
-- {
-- // Absolute mapping
-- mapping_fd = fopen(mapping_fname, "r");
-- }
-- else
-- {
-- // Mapping from ~/.reicast/mappings/
-- size_t size_needed = snprintf(NULL, 0, EVDEV_MAPPING_PATH, mapping_fname) + 1;
-- char* mapping_path = (char*)malloc(size_needed);
-- sprintf(mapping_path, EVDEV_MAPPING_PATH, mapping_fname);
-- mapping_fd = fopen(get_readonly_data_path(mapping_path).c_str(), "r");
-- free(mapping_path);
-- }
--
-- if(mapping_fd != NULL)
-- {
-- printf("evdev: reading mapping file: '%s'\n", mapping_fname);
-- loaded_mappings.insert(std::make_pair(string(mapping_fname), load_mapping(mapping_fd)));
-- fclose(mapping_fd);
--
-- }
-- else
-- {
-- printf("evdev: unable to open mapping file '%s'\n", mapping_fname);
-- perror("evdev");
-- return -3;
-- }
-- }
-- controller->mapping = &loaded_mappings[string(mapping_fname)];
-- printf("evdev: Using '%s' mapping\n", controller->mapping->name);
-- controller->init();
--
-- return 0;
-- }
-- }
-- else
-- {
-- perror("evdev: open");
-- return -1;
-- }
-- }
--
-- bool input_evdev_handle(EvdevController* controller, u32 port)
-- {
-- #define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
-- if (controller->fd < 0 || controller->mapping == NULL)
-- {
-- return false;
-- }
--
-- input_event ie;
--
-- while(read(controller->fd, &ie, sizeof(ie)) == sizeof(ie))
-- {
-- switch(ie.type)
-- {
-- case EV_KEY:
-- if (ie.code == controller->mapping->Btn_A) {
-- SET_FLAG(kcode[port], DC_BTN_A, ie.value);
-- } else if (ie.code == controller->mapping->Btn_B) {
-- SET_FLAG(kcode[port], DC_BTN_B, ie.value);
-- } else if (ie.code == controller->mapping->Btn_C) {
-- SET_FLAG(kcode[port], DC_BTN_C, ie.value);
-- } else if (ie.code == controller->mapping->Btn_D) {
-- SET_FLAG(kcode[port], DC_BTN_D, ie.value);
-- } else if (ie.code == controller->mapping->Btn_X) {
-- SET_FLAG(kcode[port], DC_BTN_X, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Y) {
-- SET_FLAG(kcode[port], DC_BTN_Y, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Z) {
-- SET_FLAG(kcode[port], DC_BTN_Z, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Start) {
-- SET_FLAG(kcode[port], DC_BTN_START, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Escape) {
-- die("death by escape key");
-- } else if (ie.code == controller->mapping->Btn_DPad_Left) {
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad_Right) {
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad_Up) {
-- SET_FLAG(kcode[port], DC_DPAD_UP, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad_Down) {
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Left) {
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Right) {
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Up) {
-- SET_FLAG(kcode[port], DC_DPAD2_UP, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Down) {
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Trigger_Left) {
-- lt[port] = (ie.value ? 255 : 0);
-- } else if (ie.code == controller->mapping->Btn_Trigger_Right) {
-- rt[port] = (ie.value ? 255 : 0);
-- }
-- break;
-- case EV_ABS:
-- if (ie.code == controller->mapping->Axis_DPad_X)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 1);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_DPad_Y)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 1);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_DPad2_X)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 1);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_DPad2_X)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 1);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_Analog_X)
-- {
-- joyx[port] = (controller->data_x.convert(ie.value) + 128);
-- }
-- else if (ie.code == controller->mapping->Axis_Analog_Y)
-- {
-- joyy[port] = (controller->data_y.convert(ie.value) + 128);
-- }
-- else if (ie.code == controller->mapping->Axis_Trigger_Left)
-- {
-- lt[port] = controller->data_trigger_left.convert(ie.value);
-- }
-- else if (ie.code == controller->mapping->Axis_Trigger_Right)
-- {
-- rt[port] = controller->data_trigger_right.convert(ie.value);
-- }
-- break;
-- }
-- }
-- }
--#endif
--
-diff -Nur a/core/linux-dist/evdev.h b/core/linux-dist/evdev.h
---- a/core/linux-dist/evdev.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/evdev.h 1969-12-31 21:00:00.000000000 -0300
-@@ -1,74 +0,0 @@
--#pragma once
--#include <linux/input.h>
--#include "types.h"
--
--struct EvdevControllerMapping
--{
-- const char* name;
-- const int Btn_A;
-- const int Btn_B;
-- const int Btn_C;
-- const int Btn_D;
-- const int Btn_X;
-- const int Btn_Y;
-- const int Btn_Z;
-- const int Btn_Start;
-- const int Btn_Escape;
-- const int Btn_DPad_Left;
-- const int Btn_DPad_Right;
-- const int Btn_DPad_Up;
-- const int Btn_DPad_Down;
-- const int Btn_DPad2_Left;
-- const int Btn_DPad2_Right;
-- const int Btn_DPad2_Up;
-- const int Btn_DPad2_Down;
-- const int Btn_Trigger_Left;
-- const int Btn_Trigger_Right;
-- const int Axis_DPad_X;
-- const int Axis_DPad_Y;
-- const int Axis_DPad2_X;
-- const int Axis_DPad2_Y;
-- const int Axis_Analog_X;
-- const int Axis_Analog_Y;
-- const int Axis_Trigger_Left;
-- const int Axis_Trigger_Right;
-- const bool Axis_Analog_X_Inverted;
-- const bool Axis_Analog_Y_Inverted;
-- const bool Axis_Trigger_Left_Inverted;
-- const bool Axis_Trigger_Right_Inverted;
--};
--
--struct EvdevAxisData
--{
-- s32 range; // smaller size than 32 bit might cause integer overflows
-- s32 min;
-- void init(int fd, int code, bool inverted);
-- s8 convert(int value);
--};
--
--struct EvdevController
--{
-- int fd;
-- EvdevControllerMapping* mapping;
-- EvdevAxisData data_x;
-- EvdevAxisData data_y;
-- EvdevAxisData data_trigger_left;
-- EvdevAxisData data_trigger_right;
-- void init();
--};
--
--#define EVDEV_DEVICE_CONFIG_KEY "evdev_device_id_%d"
--#define EVDEV_MAPPING_CONFIG_KEY "evdev_mapping_%d"
--#define EVDEV_DEVICE_STRING "/dev/input/event%d"
--#define EVDEV_MAPPING_PATH "/mappings/%s"
--
--#ifdef TARGET_PANDORA
-- #define EVDEV_DEFAULT_DEVICE_ID_1 4
--#else
-- #define EVDEV_DEFAULT_DEVICE_ID_1 0
--#endif
--
--#define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : -1)
--
--extern int input_evdev_init(EvdevController* controller, const char* device, const char* mapping_fname);
--extern bool input_evdev_handle(EvdevController* controller, u32 port);
-diff -Nur a/core/linux-dist/handler.cpp b/core/linux-dist/handler.cpp
---- a/core/linux-dist/handler.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,263 @@
-+#include "handler.h"
-+
-+#define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
-+static InputAxisID axis_ids[] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_TRIGGER_LEFT, DC_AXIS_TRIGGER_RIGHT, EMU_AXIS_DPAD1_X, EMU_AXIS_DPAD1_Y, EMU_AXIS_DPAD2_X, EMU_AXIS_DPAD2_Y };
-+
-+InputAxisConverter::InputAxisConverter(bool inverted, InputAxisLimits limits)
-+{
-+ this->m_deadzone = limits.deadzone;
-+ if(inverted)
-+ {
-+ this->m_range = (limits.minimum - limits.maximum);
-+ this->m_minimum = limits.maximum;
-+ }
-+ else
-+ {
-+ this->m_range = (limits.maximum - limits.minimum);
-+ this->m_minimum = limits.minimum;
-+ }
-+}
-+
-+s8 InputAxisConverter::convert(s32 value)
-+{
-+ // If value is in deadzone, return 0
-+ if (this->m_deadzone && ((value >= 0 && value <= this->m_deadzone) || (value < 0 && value >= -this->m_deadzone)))
-+ {
-+ return 0;
-+ }
-+ if (this->m_range)
-+ {
-+ return (((value - this->m_minimum) * 255) / this->m_range);
-+ }
-+ return value;
-+}
-+
-+InputMappingStore InputHandler::s_mappingstore;
-+
-+
-+InputHandler::InputHandler()
-+{
-+ this->m_initialized = false;
-+}
-+
-+InputHandler::~InputHandler()
-+{
-+ //TODO;
-+}
-+
-+bool InputHandler::initialize(u32 port, std::string device, std::string custom_mapping_filename)
-+{
-+ if(this->m_initialized)
-+ {
-+ printf("%s: Handler is already initialized!\n", this->get_api_name().c_str());
-+ return true;
-+ }
-+
-+ this->m_port = port;
-+
-+ bool success = this->setup_device(device);
-+
-+ if(!success)
-+ {
-+ printf("%s: Initialization of device '%s' failed!\n", this->get_api_name().c_str(), device.c_str());
-+ return false;
-+ }
-+
-+ if(custom_mapping_filename.empty())
-+ {
-+ this->m_mapping = NULL;
-+ }
-+ else
-+ {
-+ this->m_mapping = InputHandler::s_mappingstore.get(custom_mapping_filename, this->get_api_name());
-+ }
-+
-+ if(this->m_mapping == NULL)
-+ {
-+ if(!custom_mapping_filename.empty())
-+ {
-+ printf("%s: Loading custom mapping '%s' failed!\n", this->get_api_name().c_str(), custom_mapping_filename.c_str());
-+ }
-+ std::string default_mapping_filename = this->get_default_mapping_filename();
-+ if(default_mapping_filename.empty())
-+ {
-+ printf("%s: No default mapping available!\n", this->get_api_name().c_str());
-+ }
-+ else
-+ {
-+ printf("%s: Using default mapping '%s'.\n", this->get_api_name().c_str(), default_mapping_filename.c_str());
-+ this->m_mapping = InputHandler::s_mappingstore.get(default_mapping_filename, this->get_api_name());
-+ }
-+ }
-+
-+
-+ if(this->m_mapping == NULL)
-+ {
-+ printf("%s: Couldn't load a mapping!\n", this->get_api_name().c_str());
-+ return false;
-+ }
-+
-+ for(int i = 0; i < 8; i++)
-+ {
-+ InputAxisID id = axis_ids[i];
-+ const InputAxisCode* code = this->m_mapping->get_axis_code(id);
-+ if(code != NULL)
-+ {
-+ InputAxisLimits limits;
-+ this->get_axis_limits(*code, limits);
-+ if(limits.minimum != limits.maximum)
-+ {
-+ bool inverted = this->m_mapping->get_axis_inverted(*code);
-+ this->enable_axis_converter(id, inverted, limits);
-+ }
-+ }
-+ }
-+ this->m_initialized = true;
-+ return true;
-+}
-+
-+bool InputHandler::is_initialized()
-+{
-+ return this->m_initialized;
-+}
-+
-+std::string InputHandler::get_default_mapping_filename()
-+{
-+ return "default.cfg";
-+}
-+
-+void InputHandler::get_axis_limits(const InputAxisCode code, InputAxisLimits& limits)
-+{
-+ // Default stub, can be overridden in subclasses
-+ limits.minimum = 0;
-+ limits.maximum = 0;
-+ limits.deadzone = 0;
-+}
-+
-+void InputHandler::handle_button(InputButtonCode code, int value)
-+{
-+ if(this->m_mapping == NULL)
-+ {
-+ return;
-+ }
-+ const InputButtonID* button_id = this->m_mapping->get_button_id(code);
-+ if(button_id == NULL)
-+ {
-+ printf("Ignoring %d (%d)\n", code, button_id);
-+ return;
-+ }
-+ switch(*button_id)
-+ {
-+ case EMU_BTN_ESCAPE:
-+ if(value)
-+ {
-+ die("death by escape key");
-+ }
-+ break;
-+ case EMU_BTN_TRIGGER_LEFT:
-+ lt[this->m_port] = (value ? 255 : 0);
-+ break;
-+ case EMU_BTN_TRIGGER_RIGHT:
-+ rt[this->m_port] = (value ? 255 : 0);
-+ break;
-+ default:
-+ SET_FLAG(kcode[this->m_port], *button_id, value);
-+ };
-+}
-+
-+void InputHandler::handle_axis(InputAxisCode code, int value)
-+{
-+ if(this->m_mapping == NULL)
-+ {
-+ return;
-+ }
-+ const InputAxisID* axis_id = this->m_mapping->get_axis_id(code);
-+ if(axis_id == NULL)
-+ {
-+ printf("Ignoring %d\n", code);
-+ return;
-+ }
-+ switch(*axis_id)
-+ {
-+ case EMU_AXIS_DPAD1_X:
-+ case EMU_AXIS_DPAD1_Y:
-+ case EMU_AXIS_DPAD2_X:
-+ case EMU_AXIS_DPAD2_Y:
-+ {
-+ InputButtonID axis_button_id[2];
-+ switch(*axis_id)
-+ {
-+ case EMU_AXIS_DPAD1_X:
-+ axis_button_id[0] = DC_BTN_DPAD1_LEFT;
-+ axis_button_id[1] = DC_BTN_DPAD1_RIGHT;
-+ break;
-+ case EMU_AXIS_DPAD1_Y:
-+ axis_button_id[0] = DC_BTN_DPAD1_UP;
-+ axis_button_id[1] = DC_BTN_DPAD1_DOWN;
-+ break;
-+ case EMU_AXIS_DPAD2_X:
-+ axis_button_id[0] = DC_BTN_DPAD2_LEFT;
-+ axis_button_id[1] = DC_BTN_DPAD2_RIGHT;
-+ break;
-+ case EMU_AXIS_DPAD2_Y:
-+ axis_button_id[0] = DC_BTN_DPAD2_UP;
-+ axis_button_id[1] = DC_BTN_DPAD2_DOWN;
-+ }
-+ bool axis_button_value[2];
-+ axis_button_value[0] = (value < 0);
-+ axis_button_value[1] = (value > 0);
-+ SET_FLAG(kcode[this->m_port], axis_button_id[0], axis_button_value[0]);
-+ SET_FLAG(kcode[this->m_port], axis_button_id[1], axis_button_value[1]);
-+ break;
-+ }
-+ case DC_AXIS_X:
-+ case DC_AXIS_Y:
-+ case DC_AXIS_TRIGGER_LEFT:
-+ case DC_AXIS_TRIGGER_RIGHT:
-+ {
-+ InputAxisConverter* converter = this->get_axis_converter(*axis_id);
-+ s8 converted_value = ((converter == NULL) ? value : converter->convert(value));
-+ switch(*axis_id)
-+ {
-+ case DC_AXIS_X:
-+ joyx[this->m_port] = (converted_value + 128);
-+ break;
-+ case DC_AXIS_Y:
-+ joyy[this->m_port] = (converted_value + 128);
-+ break;
-+ case DC_AXIS_TRIGGER_LEFT:
-+ lt[this->m_port] = converted_value;
-+ break;
-+ case DC_AXIS_TRIGGER_RIGHT:
-+ rt[this->m_port] = converted_value;
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+void InputHandler::enable_axis_converter(InputAxisID axis, bool inverted, InputAxisLimits limits)
-+{
-+ this->disable_axis_converter(axis); // Delete old axis converter
-+ this->m_axis_converters[axis] = new InputAxisConverter(inverted, limits);
-+}
-+
-+void InputHandler::disable_axis_converter(InputAxisID axis)
-+{
-+ InputAxisConverterStore::iterator iter = this->m_axis_converters.find(axis);
-+ if(iter != this->m_axis_converters.end())
-+ {
-+ delete iter->second;
-+ this->m_axis_converters.erase(iter);
-+ }
-+}
-+
-+InputAxisConverter* InputHandler::get_axis_converter(InputAxisID axis)
-+{
-+ InputAxisConverterStore::iterator iter = this->m_axis_converters.find(axis);
-+ if(iter == this->m_axis_converters.end())
-+ {
-+ return NULL;
-+ }
-+ return iter->second;
-+}
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler_evdev.cpp b/core/linux-dist/handler_evdev.cpp
---- a/core/linux-dist/handler_evdev.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_evdev.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,132 @@
-+#if defined(USE_EVDEV)
-+#include "handler_evdev.h"
-+#include <cstring>
-+#include <cerrno>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <linux/input.h>
-+
-+#define EVDEV_DEVICE_STRING "/dev/input/event%s"
-+
-+void EvdevInputHandler::get_axis_limits(const InputAxisCode code, InputAxisLimits& limits)
-+{
-+ struct input_absinfo abs;
-+ if(!this->m_evdev_fd < 0 || code < 0 || ioctl(this->m_evdev_fd, EVIOCGABS(code), &abs))
-+ {
-+ if(this->m_evdev_fd >= 0 && code >= 0)
-+ {
-+ perror("evdev ioctl");
-+ }
-+ limits.minimum = 0;
-+ limits.maximum = 0;
-+ limits.deadzone = 0;
-+ return;
-+ }
-+ limits.minimum = abs.minimum;
-+ limits.maximum = abs.maximum;
-+ limits.deadzone = abs.flat;
-+}
-+
-+std::string EvdevInputHandler::get_api_name()
-+{
-+ return "evdev";
-+}
-+
-+bool EvdevInputHandler::setup_device(std::string device)
-+{
-+ size_t size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, device.c_str()) + 1;
-+ char* evdev_fname = (char*)malloc(size_needed);
-+ sprintf(evdev_fname, EVDEV_DEVICE_STRING, device.c_str());
-+
-+ printf("evdev: Trying to open device '%s'\n", evdev_fname);
-+
-+ this->m_evdev_fd = open(evdev_fname, O_RDONLY);
-+
-+ char device_name[256] = "Unknown";
-+
-+ if (this->m_evdev_fd < 0)
-+ {
-+ printf("evdev: Opening device '%s' failed - %s", evdev_fname, strerror(errno));
-+ free(evdev_fname);
-+ return false;
-+ }
-+
-+ fcntl(this->m_evdev_fd, F_SETFL, O_NONBLOCK);
-+
-+ // Get device name
-+ if(ioctl(this->m_evdev_fd, EVIOCGNAME(sizeof(device_name)), device_name) < 0)
-+ {
-+ printf("evdev: Getting name of '%s' (ioctl) failed - %s", evdev_fname, strerror(errno));
-+ free(evdev_fname);
-+ return false;
-+ }
-+
-+ printf("evdev: Found '%s' at '%s'\n", device_name, evdev_fname);
-+ this->m_evdev_devname = std::string(device_name);
-+
-+ free(evdev_fname);
-+
-+ return true;
-+}
-+
-+std::string EvdevInputHandler::get_default_mapping_filename()
-+{
-+ if (this->m_evdev_devname.empty())
-+ {
-+ return "";
-+ }
-+
-+ std::string mapping_filename;
-+ #if defined(TARGET_PANDORA)
-+ mapping_filename = "controller_pandora.cfg";
-+ #elif defined(TARGET_GCW0)
-+ mapping_filename = "controller_gcwz.cfg";
-+ #else
-+ if (strstr(this->m_evdev_devname.c_str(), "Microsoft X-Box 360 pad") == NULL || strstr(this->m_evdev_devname.c_str(), "Xbox 360 Wireless Receiver") == NULL)
-+ {
-+ mapping_filename = "controller_xpad.cfg";
-+ }
-+ else if (strstr(this->m_evdev_devname.c_str(), "Xbox Gamepad (userspace driver)") != NULL)
-+ {
-+ mapping_filename = "controller_xboxdrv.cfg";
-+ }
-+ else if (strstr(this->m_evdev_devname.c_str(), "keyboard") != NULL || strstr(this->m_evdev_devname.c_str(), "Keyboard") != NULL)
-+ {
-+ mapping_filename = "keyboard.cfg";
-+ }
-+ else
-+ {
-+ mapping_filename = "controller_generic.cfg";
-+ }
-+ #endif
-+
-+ return mapping_filename;
-+}
-+
-+void EvdevInputHandler::handle()
-+{
-+ if (!this->is_initialized())
-+ {
-+ return;
-+ }
-+
-+ input_event ie;
-+ while(read(this->m_evdev_fd, &ie, sizeof(ie)) == sizeof(ie))
-+ {
-+ //printf("evdev: type = %d - code = %d - value = %d\n", ie.type, ie.code, ie.value);
-+ switch(ie.type)
-+ {
-+ case EV_KEY:
-+ {
-+ this->handle_button(ie.code, ie.value);
-+ break;
-+ }
-+ case EV_ABS:
-+ {
-+ this->handle_axis(ie.code, ie.value);
-+ break;
-+ }
-+ }
-+ }
-+}
-+#endif
-diff -Nur a/core/linux-dist/handler_evdev.h b/core/linux-dist/handler_evdev.h
---- a/core/linux-dist/handler_evdev.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_evdev.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,15 @@
-+#pragma once
-+#include "handler.h"
-+
-+class EvdevInputHandler : public InputHandler
-+{
-+ private:
-+ int m_evdev_fd;
-+ std::string m_evdev_devname;
-+ void get_axis_limits(const InputAxisCode code, InputAxisLimits& limits);
-+ public:
-+ void handle();
-+ std::string get_api_name();
-+ std::string get_default_mapping_filename();
-+ bool setup_device(std::string device);
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler.h b/core/linux-dist/handler.h
---- a/core/linux-dist/handler.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,49 @@
-+#pragma once
-+#include "types.h"
-+#include "mapping.h"
-+#include "mappingstore.h"
-+
-+struct InputAxisLimits
-+{
-+ s32 minimum;
-+ s32 maximum;
-+ s32 deadzone;
-+};
-+
-+class InputAxisConverter
-+{
-+ private:
-+ s32 m_minimum;
-+ s32 m_range;
-+ s32 m_deadzone;
-+ public:
-+ InputAxisConverter(bool inverted, InputAxisLimits limits);
-+ s8 convert(s32 value);
-+};
-+
-+class InputHandler
-+{
-+ typedef std::map<InputAxisID, InputAxisConverter*> InputAxisConverterStore;
-+ private:
-+ InputAxisConverterStore m_axis_converters;
-+ void enable_axis_converter(InputAxisID axis, bool inverted, InputAxisLimits limits);
-+ void disable_axis_converter(InputAxisID axis);
-+ InputAxisConverter* get_axis_converter(InputAxisID axis);
-+ bool m_initialized;
-+ protected:
-+ static InputMappingStore s_mappingstore;
-+ u32 m_port;
-+ InputMapping* m_mapping;
-+ bool is_initialized();
-+ void handle_button(InputButtonCode code, int value);
-+ void handle_axis(InputAxisCode code, int value);
-+ virtual void get_axis_limits(const InputAxisCode code, InputAxisLimits& limits);
-+ public:
-+ InputHandler();
-+ ~InputHandler();
-+ bool initialize(u32 port, std::string device, std::string custom_mapping);
-+ virtual std::string get_default_mapping_filename();
-+ virtual void handle() = 0;
-+ virtual std::string get_api_name() = 0;
-+ virtual bool setup_device(std::string device) = 0;
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler_linuxjs.cpp b/core/linux-dist/handler_linuxjs.cpp
---- a/core/linux-dist/handler_linuxjs.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_linuxjs.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,127 @@
-+#if defined(USE_JOYSTICK)
-+#include "handler_linuxjs.h"
-+#include <cstring>
-+#include <cerrno>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <linux/joystick.h>
-+
-+#define LINUXJS_DEVICE_STRING "/dev/input/js%s"
-+
-+void LinuxJoystickInputHandler::get_axis_limits(const InputAxisCode code, InputAxisLimits& limits)
-+{
-+ // The Linux Joystick API's axes always normalized to this minimum/maximum
-+ limits.minimum = -32767;
-+ limits.maximum = 32767;
-+ limits.deadzone = 0;
-+}
-+
-+std::string LinuxJoystickInputHandler::get_api_name()
-+{
-+ return "linuxjs";
-+}
-+
-+bool LinuxJoystickInputHandler::setup_device(std::string device)
-+{
-+ size_t size_needed = snprintf(NULL, 0, LINUXJS_DEVICE_STRING, device.c_str()) + 1;
-+ char* linuxjs_fname = (char*)malloc(size_needed);
-+ sprintf(linuxjs_fname, LINUXJS_DEVICE_STRING, device.c_str());
-+
-+ printf("linuxjs: Trying to open device '%s'\n", linuxjs_fname);
-+
-+ this->m_linuxjs_fd = open(linuxjs_fname, O_RDONLY);
-+
-+ if (this->m_linuxjs_fd < 0)
-+ {
-+ printf("linuxjs: Opening device '%s' failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ fcntl(this->m_linuxjs_fd, F_SETFL, O_NONBLOCK);
-+
-+ char device_name[256] = "Unknown";
-+ int button_count = 0;
-+ int axis_count = 0;
-+
-+ // Get device name
-+ if(ioctl(this->m_linuxjs_fd, JSIOCGNAME(sizeof(device_name)), device_name) < 0)
-+ {
-+ printf("linuxjs: Getting name of '%s' (ioctl) failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ // Get number of buttons
-+ if(ioctl(this->m_linuxjs_fd, JSIOCGBUTTONS, &button_count) < 0)
-+ {
-+ printf("linuxjs: Getting button count of '%s' (ioctl) failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ // Get number of axes
-+ if(ioctl(this->m_linuxjs_fd, JSIOCGAXES, &axis_count) < 0)
-+ {
-+ printf("linuxjs: Getting axis count of '%s' (ioctl) failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ printf("linuxjs: Found '%s' with %d axes and %d buttons at '%s'\n", device_name, axis_count, button_count, linuxjs_fname);
-+ this->m_linuxjs_devname = std::string(device_name);
-+
-+ free(linuxjs_fname);
-+
-+ return true;
-+}
-+
-+std::string LinuxJoystickInputHandler::get_default_mapping_filename()
-+{
-+ if (this->m_linuxjs_devname.empty())
-+ {
-+ return "";
-+ }
-+
-+ std::string mapping_filename;
-+ if (strstr(this->m_linuxjs_devname.c_str(), "Microsoft X-Box 360 pad") != NULL ||
-+ strstr(this->m_linuxjs_devname.c_str(), "Xbox Gamepad (userspace driver)") != NULL ||
-+ strstr(this->m_linuxjs_devname.c_str(), "Xbox 360 Wireless Receiver") != NULL)
-+ {
-+ mapping_filename = "controller_xbox360.cfg";
-+ }
-+ else
-+ {
-+ mapping_filename = "controller_generic.cfg";
-+ }
-+
-+ return mapping_filename;
-+}
-+
-+void LinuxJoystickInputHandler::handle()
-+{
-+ if (!this->is_initialized())
-+ {
-+ return;
-+ }
-+
-+ struct js_event je;
-+ while(read(this->m_linuxjs_fd, &je, sizeof(je)) == sizeof(je))
-+ {
-+ printf("linuxjs: type = %d - code = %d - value = %d\n", je.type, je.number, je.value);
-+ switch(je.type)
-+ {
-+ case JS_EVENT_BUTTON:
-+ {
-+ this->handle_button(je.number, je.value);
-+ break;
-+ }
-+ case JS_EVENT_AXIS:
-+ {
-+ this->handle_axis(je.number, je.value);
-+ break;
-+ }
-+ }
-+ }
-+}
-+#endif
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler_linuxjs.h b/core/linux-dist/handler_linuxjs.h
---- a/core/linux-dist/handler_linuxjs.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_linuxjs.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,15 @@
-+#pragma once
-+#include "handler.h"
-+
-+class LinuxJoystickInputHandler : public InputHandler
-+{
-+ private:
-+ int m_linuxjs_fd;
-+ std::string m_linuxjs_devname;
-+ void get_axis_limits(const InputAxisCode code, InputAxisLimits& limits);
-+ public:
-+ void handle();
-+ std::string get_api_name();
-+ std::string get_default_mapping_filename();
-+ bool setup_device(std::string device);
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/joystick.cpp b/core/linux-dist/joystick.cpp
---- a/core/linux-dist/joystick.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/joystick.cpp 1969-12-31 21:00:00.000000000 -0300
-@@ -1,158 +0,0 @@
--#include <unistd.h>
--#include <fcntl.h>
--#include <sys/types.h>
--#include <linux/joystick.h>
--#include "linux-dist/joystick.h"
--
--#if defined(USE_JOYSTICK)
-- const u32 joystick_map_btn_usb[JOYSTICK_MAP_SIZE] = { DC_BTN_Y, DC_BTN_B, DC_BTN_A, DC_BTN_X, 0, 0, 0, 0, 0, DC_BTN_START };
-- const u32 joystick_map_axis_usb[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, 0, 0, 0, 0, 0, 0, 0, 0 };
--
-- const u32 joystick_map_btn_xbox360[JOYSTICK_MAP_SIZE] = { DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, 0, 0, 0, DC_BTN_START, 0, 0 };
-- const u32 joystick_map_axis_xbox360[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, 0, 0, DC_AXIS_RT, DC_DPAD_LEFT, DC_DPAD_UP, 0, 0 };
--
-- const u32* joystick_map_btn = joystick_map_btn_usb;
-- const u32* joystick_map_axis = joystick_map_axis_usb;
--
-- int input_joystick_init(const char* device)
-- {
-- int axis_count = 0;
-- int button_count = 0;
-- char name[128] = "Unknown";
--
-- printf("joystick: Trying to open device at '%s'\n", device);
--
-- int fd = open(device, O_RDONLY);
--
-- if(fd >= 0)
-- {
-- fcntl(fd, F_SETFL, O_NONBLOCK);
-- ioctl(fd, JSIOCGAXES, &axis_count);
-- ioctl(fd, JSIOCGBUTTONS, &button_count);
-- ioctl(fd, JSIOCGNAME(sizeof(name)), &name);
--
-- printf("joystick: Found '%s' with %d axis and %d buttons at '%s'.\n", name, axis_count, button_count, device);
--
-- if (strcmp(name, "Microsoft X-Box 360 pad") == 0 ||
-- strcmp(name, "Xbox Gamepad (userspace driver)") == 0 ||
-- strcmp(name, "Xbox 360 Wireless Receiver (XBOX)") == 0)
-- {
-- joystick_map_btn = joystick_map_btn_xbox360;
-- joystick_map_axis = joystick_map_axis_xbox360;
-- printf("joystick: Using Xbox 360 map\n");
-- }
-- }
-- else
-- {
-- perror("joystick open");
-- }
--
-- return fd;
-- }
--
-- bool input_joystick_handle(int fd, u32 port)
-- {
-- // Joystick must be connected
-- if(fd < 0) {
-- return false;
-- }
--
-- struct js_event JE;
-- while(read(fd, &JE, sizeof(JE)) == sizeof(JE))
-- if (JE.number < JOYSTICK_MAP_SIZE)
-- {
-- switch(JE.type & ~JS_EVENT_INIT)
-- {
-- case JS_EVENT_AXIS:
-- {
-- u32 mt = joystick_map_axis[JE.number] >> 16;
-- u32 mo = joystick_map_axis[JE.number] & 0xFFFF;
--
-- //printf("AXIS %d,%d\n",JE.number,JE.value);
-- s8 v=(s8)(JE.value/256); //-127 ... + 127 range
--
-- if (mt == 0)
-- {
-- kcode[port] |= mo;
-- kcode[port] |= mo*2;
-- if (v<-64)
-- {
-- kcode[port] &= ~mo;
-- }
-- else if (v>64)
-- {
-- kcode[port] &= ~(mo*2);
-- }
--
-- //printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
-- }
-- else if (mt == 1)
-- {
-- if (v >= 0)
-- {
-- v++; //up to 255
-- }
-- //printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
-- if (mo == 0)
-- {
-- lt[port] = (v + 127);
-- }
-- else if (mo == 1)
-- {
-- rt[port] = (v + 127);
-- }
-- }
-- else if (mt == 2)
-- {
-- // printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
-- if (mo == 0)
-- {
-- joyx[port] = v;
-- }
-- else if (mo == 1)
-- {
-- joyy[port] = v;
-- }
-- }
-- }
-- break;
--
-- case JS_EVENT_BUTTON:
-- {
-- u32 mt = joystick_map_btn[JE.number] >> 16;
-- u32 mo = joystick_map_btn[JE.number] & 0xFFFF;
--
-- // printf("BUTTON %d,%d\n",JE.number,JE.value);
--
-- if (mt == 0)
-- {
-- // printf("Mapped to %d\n",mo);
-- if (JE.value)
-- {
-- kcode[port] &= ~mo;
-- }
-- else
-- {
-- kcode[port] |= mo;
-- }
-- }
-- else if (mt == 1)
-- {
-- // printf("Mapped to %d %d\n",mo,JE.value?255:0);
-- if (mo==0)
-- {
-- lt[port] = JE.value ? 255 : 0;
-- }
-- else if (mo==1)
-- {
-- rt[port] = JE.value ? 255 : 0;
-- }
-- }
-- }
-- break;
-- }
-- }
--
-- return true;
-- }
--#endif
-diff -Nur a/core/linux-dist/joystick.h b/core/linux-dist/joystick.h
---- a/core/linux-dist/joystick.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/joystick.h 1969-12-31 21:00:00.000000000 -0300
-@@ -1,10 +0,0 @@
--#include "types.h"
--#include "linux-dist/main.h"
--
--#pragma once
--#define JOYSTICK_DEVICE_STRING "/dev/input/js%d"
--#define JOYSTICK_DEFAULT_DEVICE_ID -1
--#define JOYSTICK_MAP_SIZE 32
--
--extern int input_joystick_init(const char* device);
--extern bool input_joystick_handle(int fd, u32 port);
-diff -Nur a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp
---- a/core/linux-dist/main.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/main.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -14,6 +14,7 @@
- #include <sys/time.h>
- #include "hw/sh4/dyna/blockmanager.h"
- #include <unistd.h>
-+#include "proxy.h"
-
- #if defined(TARGET_EMSCRIPTEN)
- #include <emscripten.h>
-@@ -32,11 +33,11 @@
- #endif
-
- #if defined(USE_EVDEV)
-- #include "linux-dist/evdev.h"
-+ #include "linux-dist/handler_evdev.h"
- #endif
-
- #if defined(USE_JOYSTICK)
-- #include "linux-dist/joystick.h"
-+ #include "linux-dist/handler_linuxjs.h"
- #endif
-
- #ifdef TARGET_PANDORA
-@@ -84,82 +85,68 @@
-
- void emit_WriteCodeCache();
-
--#if defined(USE_EVDEV)
-- /* evdev input */
-- static EvdevController evdev_controllers[4] = {
-- { -1, NULL },
-- { -1, NULL },
-- { -1, NULL },
-- { -1, NULL }
-- };
--#endif
--
--#if defined(USE_JOYSTICK)
-- /* legacy joystick input */
-- static int joystick_fd = -1; // Joystick file descriptor
--#endif
-+static InputHandlerProxy input_handlers;
-
- void SetupInput()
- {
- #if defined(USE_EVDEV)
-- int evdev_device_id[4] = { -1, -1, -1, -1 };
-- size_t size_needed;
-- int port, i;
-+ #define EVDEV_DEVICE_CONFIG_KEY "evdev_device_id_%d"
-+ #define EVDEV_MAPPING_CONFIG_KEY "evdev_mapping_%d"
-
-- char* evdev_device;
-+ #ifdef TARGET_PANDORA
-+ #define EVDEV_DEFAULT_DEVICE_ID_1 "4"
-+ #else
-+ #define EVDEV_DEFAULT_DEVICE_ID_1 "0"
-+ #endif
-+ #define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : "-1")
-
-- for (port = 0; port < 4; port++)
-+ for (int port = 0; port < 4; port++)
- {
-+ size_t size_needed;
-+ char* evdev_config_key;
-+ std::string evdev_device;
-+ std::string custom_mapping_filename;
-+
- size_needed = snprintf(NULL, 0, EVDEV_DEVICE_CONFIG_KEY, port+1) + 1;
-- char* evdev_config_key = (char*)malloc(size_needed);
-+ evdev_config_key = (char*)malloc(size_needed);
- sprintf(evdev_config_key, EVDEV_DEVICE_CONFIG_KEY, port+1);
-- evdev_device_id[port] = cfgLoadInt("input", evdev_config_key, EVDEV_DEFAULT_DEVICE_ID(port+1));
-+ evdev_device = cfgLoadStr("input", evdev_config_key, EVDEV_DEFAULT_DEVICE_ID(port+1));
- free(evdev_config_key);
-
-- // Check if the same device is already in use on another port
-- if (evdev_device_id[port] < 0)
-+ if(evdev_device.c_str()[0] == '-')
- {
- printf("evdev: Controller %d disabled by config.\n", port + 1);
-+ continue;
- }
-- else
-- {
-- for (i = 0; i < port; i++)
-- {
-- if (evdev_device_id[port] == evdev_device_id[i])
-- {
-- die("You can't assign the same device to multiple ports!\n");
-- }
-- }
--
-- size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, evdev_device_id[port]) + 1;
-- evdev_device = (char*)malloc(size_needed);
-- sprintf(evdev_device, EVDEV_DEVICE_STRING, evdev_device_id[port]);
--
-- size_needed = snprintf(NULL, 0, EVDEV_MAPPING_CONFIG_KEY, port+1) + 1;
-- evdev_config_key = (char*)malloc(size_needed);
-- sprintf(evdev_config_key, EVDEV_MAPPING_CONFIG_KEY, port+1);
-- const char* mapping = (cfgExists("input", evdev_config_key) == 2 ? cfgLoadStr("input", evdev_config_key, "").c_str() : NULL);
-- free(evdev_config_key);
-
-- input_evdev_init(&evdev_controllers[port], evdev_device, mapping);
-+ size_needed = snprintf(NULL, 0, EVDEV_MAPPING_CONFIG_KEY, port+1) + 1;
-+ evdev_config_key = (char*)malloc(size_needed);
-+ sprintf(evdev_config_key, EVDEV_MAPPING_CONFIG_KEY, port+1);
-+ custom_mapping_filename = (cfgExists("input", evdev_config_key) == 2 ? cfgLoadStr("input", evdev_config_key, "") : "");
-+ free(evdev_config_key);
-
-- free(evdev_device);
-- }
-+ EvdevInputHandler* handler = new EvdevInputHandler();
-+ handler->initialize(port, evdev_device, custom_mapping_filename);
-+ input_handlers.add(port, handler);
- }
- #endif
-
- #if defined(USE_JOYSTICK)
-- int joystick_device_id = cfgLoadInt("input", "joystick_device_id", JOYSTICK_DEFAULT_DEVICE_ID);
-- if (joystick_device_id < 0) {
-- puts("Legacy Joystick input disabled by config.\n");
-+ #define JOYSTICK_DEFAULT_DEVICE_ID "-1"
-+
-+ std::string linuxjs_device;
-+ std::string custom_mapping_filename = "";
-+
-+ linuxjs_device = cfgLoadStr("input", "joystick_device_id", JOYSTICK_DEFAULT_DEVICE_ID);
-+ if (linuxjs_device.c_str()[0] == '-')
-+ {
-+ puts("LinuxJoystick input disabled by config.\n");
- }
- else
- {
-- int joystick_device_length = snprintf(NULL, 0, JOYSTICK_DEVICE_STRING, joystick_device_id);
-- char* joystick_device = (char*)malloc(joystick_device_length + 1);
-- sprintf(joystick_device, JOYSTICK_DEVICE_STRING, joystick_device_id);
-- joystick_fd = input_joystick_init(joystick_device);
-- free(joystick_device);
-+ LinuxJoystickInputHandler* handler = new LinuxJoystickInputHandler();
-+ handler->initialize(0, linuxjs_device, custom_mapping_filename);
-+ input_handlers.add(0, handler);
- }
- #endif
-
-@@ -178,13 +165,7 @@
- return;
- #endif
-
-- #if defined(USE_JOYSTICK)
-- input_joystick_handle(joystick_fd, port);
-- #endif
--
-- #if defined(USE_EVDEV)
-- input_evdev_handle(&evdev_controllers[port], port);
-- #endif
-+ input_handlers.handle(port);
-
- #if defined(USE_SDL)
- input_sdl_handle(port);
-diff -Nur a/core/linux-dist/main.h b/core/linux-dist/main.h
---- a/core/linux-dist/main.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/main.h 2015-10-06 21:55:43.966475140 -0300
-@@ -11,25 +11,34 @@
-
- enum DreamcastController
- {
-- DC_BTN_C = 1,
-- DC_BTN_B = 1<<1,
-- DC_BTN_A = 1<<2,
-- DC_BTN_START = 1<<3,
-- DC_DPAD_UP = 1<<4,
-- DC_DPAD_DOWN = 1<<5,
-- DC_DPAD_LEFT = 1<<6,
-- DC_DPAD_RIGHT = 1<<7,
-- DC_BTN_Z = 1<<8,
-- DC_BTN_Y = 1<<9,
-- DC_BTN_X = 1<<10,
-- DC_BTN_D = 1<<11,
-- DC_DPAD2_UP = 1<<12,
-- DC_DPAD2_DOWN = 1<<13,
-- DC_DPAD2_LEFT = 1<<14,
-- DC_DPAD2_RIGHT = 1<<15,
-+ EMU_BTN_NONE = 0,
-+ EMU_BTN_ESCAPE = 1<<16,
-+ EMU_BTN_TRIGGER_LEFT = 1<<17,
-+ EMU_BTN_TRIGGER_RIGHT = 1<<18,
-+ DC_BTN_C = 1,
-+ DC_BTN_B = 1<<1,
-+ DC_BTN_A = 1<<2,
-+ DC_BTN_START = 1<<3,
-+ DC_BTN_DPAD1_UP = 1<<4,
-+ DC_BTN_DPAD1_DOWN = 1<<5,
-+ DC_BTN_DPAD1_LEFT = 1<<6,
-+ DC_BTN_DPAD1_RIGHT = 1<<7,
-+ DC_BTN_Z = 1<<8,
-+ DC_BTN_Y = 1<<9,
-+ DC_BTN_X = 1<<10,
-+ DC_BTN_D = 1<<11,
-+ DC_BTN_DPAD2_UP = 1<<12,
-+ DC_BTN_DPAD2_DOWN = 1<<13,
-+ DC_BTN_DPAD2_LEFT = 1<<14,
-+ DC_BTN_DPAD2_RIGHT = 1<<15,
-
-- DC_AXIS_LT = 0X10000,
-- DC_AXIS_RT = 0X10001,
-- DC_AXIS_X = 0X20000,
-- DC_AXIS_Y = 0X20001,
-+ EMU_AXIS_NONE = 0X00000,
-+ EMU_AXIS_DPAD1_X = 0X00001,
-+ EMU_AXIS_DPAD1_Y = 0X00002,
-+ EMU_AXIS_DPAD2_X = 0X00003,
-+ EMU_AXIS_DPAD2_Y = 0X00004,
-+ DC_AXIS_TRIGGER_LEFT = 0X10000,
-+ DC_AXIS_TRIGGER_RIGHT = 0X10001,
-+ DC_AXIS_X = 0X20000,
-+ DC_AXIS_Y = 0X20001,
- };
-diff -Nur a/core/linux-dist/mapping.cpp b/core/linux-dist/mapping.cpp
---- a/core/linux-dist/mapping.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mapping.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,159 @@
-+#include "linux-dist/mapping.h"
-+#include "cfg/ini.h"
-+
-+struct ButtonMap
-+{
-+ InputButtonID id;
-+ string section;
-+ string option;
-+};
-+
-+struct AxisMap
-+{
-+ InputAxisID id;
-+ string section;
-+ string option;
-+ string section_inverted;
-+ string option_inverted;
-+};
-+
-+static ButtonMap button_list[19] = {
-+ { DC_BTN_A, "dreamcast", "btn_a" },
-+ { DC_BTN_B, "dreamcast", "btn_b" },
-+ { DC_BTN_C, "dreamcast", "btn_c" },
-+ { DC_BTN_D, "dreamcast", "btn_d" },
-+ { DC_BTN_X, "dreamcast", "btn_x" },
-+ { DC_BTN_Y, "dreamcast", "btn_y" },
-+ { DC_BTN_Z, "dreamcast", "btn_z" },
-+ { DC_BTN_START, "dreamcast", "btn_start" },
-+ { DC_BTN_DPAD1_LEFT, "dreamcast", "btn_dpad1_left" },
-+ { DC_BTN_DPAD1_RIGHT, "dreamcast", "btn_dpad1_right" },
-+ { DC_BTN_DPAD1_UP, "dreamcast", "btn_dpad1_up" },
-+ { DC_BTN_DPAD1_DOWN, "dreamcast", "btn_dpad1_down" },
-+ { DC_BTN_DPAD2_LEFT, "dreamcast", "btn_dpad2_left" },
-+ { DC_BTN_DPAD2_RIGHT, "dreamcast", "btn_dpad2_right" },
-+ { DC_BTN_DPAD2_UP, "dreamcast", "btn_dpad2_up" },
-+ { DC_BTN_DPAD2_DOWN, "dreamcast", "btn_dpad2_down" },
-+ { EMU_BTN_ESCAPE, "emulator", "btn_escape" },
-+ { EMU_BTN_TRIGGER_LEFT, "compat", "btn_trigger_left" },
-+ { EMU_BTN_TRIGGER_RIGHT, "compat", "btn_trigger_right" }
-+};
-+
-+static AxisMap axis_list[8] = {
-+ { DC_AXIS_X, "dreamcast", "axis_x", "compat", "axis_x_inverted" },
-+ { DC_AXIS_Y, "dreamcast", "axis_y", "compat", "axis_y_inverted" },
-+ { DC_AXIS_TRIGGER_LEFT, "dreamcast", "axis_trigger_left", "compat", "axis_trigger_left_inverted" },
-+ { DC_AXIS_TRIGGER_RIGHT, "dreamcast", "axis_trigger_right", "compat", "axis_trigger_right_inverted" },
-+ { EMU_AXIS_DPAD1_X, "compat", "axis_dpad1_x", "compat", "axis_dpad1_x_inverted" },
-+ { EMU_AXIS_DPAD1_Y, "compat", "axis_dpad1_y", "compat", "axis_dpad1_y_inverted" },
-+ { EMU_AXIS_DPAD2_X, "compat", "axis_dpad2_x", "compat", "axis_dpad2_x_inverted" },
-+ { EMU_AXIS_DPAD2_Y, "compat", "axis_dpad2_y", "compat", "axis_dpad2_y_inverted" }
-+};
-+
-+const InputButtonID* InputMapping::get_button_id(InputButtonCode code)
-+{
-+ return this->buttons.get_by_value(code);
-+}
-+
-+const InputButtonCode* InputMapping::get_button_code(InputButtonID id)
-+{
-+ return this->buttons.get_by_key(id);
-+}
-+
-+void InputMapping::set_button(InputButtonID id, InputButtonCode code)
-+{
-+ if(id != EMU_BTN_NONE)
-+ {
-+ this->buttons.insert(id, code);
-+ }
-+}
-+
-+const InputAxisID* InputMapping::get_axis_id(InputAxisCode code)
-+{
-+ return this->axes.get_by_value(code);
-+}
-+
-+const InputAxisCode* InputMapping::get_axis_code(InputAxisID id)
-+{
-+ return this->axes.get_by_key(id);
-+}
-+
-+bool InputMapping::get_axis_inverted(InputAxisCode code)
-+{
-+ std::map<InputAxisCode, bool>::iterator it = this->axes_inverted.find('b');
-+ if (it != this->axes_inverted.end())
-+ {
-+ return it->second;
-+ }
-+ return false;
-+}
-+
-+void InputMapping::set_axis(InputAxisID id, InputAxisCode code, bool is_inverted)
-+{
-+ if(id != EMU_AXIS_NONE)
-+ {
-+ this->axes.insert(id, code);
-+ this->axes_inverted.insert(std::pair<InputAxisCode,bool>(code, is_inverted));
-+ }
-+}
-+
-+void InputMapping::load(FILE* fd)
-+{
-+ ConfigFile mf;
-+ mf.parse(fd);
-+
-+ this->name = mf.get("emulator", "mapping_name", "<Unknown>").c_str();
-+
-+ int i;
-+ for(i = 0; i < 19; i++)
-+ {
-+ InputButtonCode button_code = mf.get_int(button_list[i].section, button_list[i].option, -1);
-+ if (button_code >= 0)
-+ {
-+ this->set_button(button_list[i].id, button_code);
-+ }
-+ }
-+
-+ for(i = 0; i < 8; i++)
-+ {
-+ InputAxisCode axis_code = mf.get_int(axis_list[i].section, axis_list[i].option, -1);
-+ if(axis_code >= 0)
-+ {
-+ this->set_axis(axis_list[i].id, axis_code, mf.get_bool(axis_list[i].section_inverted, axis_list[i].option_inverted, false));
-+ }
-+ }
-+}
-+
-+void InputMapping::print()
-+{
-+ int i;
-+
-+ printf("\nMAPPING NAME: %s\n", this->name);
-+
-+ puts("MAPPED BUTTONS:");
-+ for(i = 0; i < 19; i++)
-+ {
-+ const InputButtonCode* button_code = this->get_button_code(button_list[i].id);
-+ if(button_code)
-+ {
-+ printf("%-18s = %d\n", button_list[i].option.c_str(), *button_code);
-+ }
-+ }
-+
-+ puts("MAPPED AXES:");
-+ for(i = 0; i < 8; i++)
-+ {
-+ const InputAxisCode* axis_code = this->get_axis_code(axis_list[i].id);
-+ if(axis_code)
-+ {
-+ printf("%-18s = %d", axis_list[i].option.c_str(), *axis_code);
-+ if(this->get_axis_inverted(*axis_code))
-+ {
-+ printf("%s", "(inverted)");
-+ }
-+ printf("%s", "\n");
-+ }
-+ }
-+ puts("");
-+}
-+
-diff -Nur a/core/linux-dist/mapping.h b/core/linux-dist/mapping.h
---- a/core/linux-dist/mapping.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mapping.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,32 @@
-+#pragma once
-+#include <map>
-+#include "linux-dist/main.h"
-+#include "linux-dist/bimap.h"
-+
-+typedef DreamcastController InputButtonID;
-+typedef DreamcastController InputAxisID;
-+typedef int InputButtonCode;
-+typedef int InputAxisCode;
-+
-+class InputMapping
-+{
-+ private:
-+ SimpleBimap<InputButtonID, InputButtonCode> buttons;
-+ SimpleBimap<InputAxisID, InputAxisCode> axes;
-+ std::map<InputAxisCode, bool> axes_inverted;
-+
-+ public:
-+ const char* name;
-+
-+ void set_button(InputButtonID id, InputButtonCode code);
-+ const InputButtonID* get_button_id(InputButtonCode code);
-+ const InputButtonCode* get_button_code(InputButtonID id);
-+
-+ void set_axis(InputAxisID id, InputAxisCode code, bool inverted);
-+ const InputAxisID* get_axis_id(InputAxisCode code);
-+ const InputAxisCode* get_axis_code(InputAxisID id);
-+ bool get_axis_inverted(InputAxisCode code);
-+
-+ void load(FILE* file);
-+ void print();
-+};
-diff -Nur a/core/linux-dist/mappingstore.cpp b/core/linux-dist/mappingstore.cpp
---- a/core/linux-dist/mappingstore.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mappingstore.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,61 @@
-+#include "mappingstore.h"
-+#include <errno.h>
-+
-+static std::string get_mapping_path(std::string filepath, std::string subdir)
-+{
-+ if (filepath.empty())
-+ {
-+ return "";
-+ }
-+
-+ std::string new_filepath;
-+ if (filepath.at(0) != '/')
-+ {
-+ // It's not an absolute path
-+ std::string mapping_dir = "/mappings/";
-+ if(!subdir.empty())
-+ {
-+ mapping_dir.append(subdir);
-+ mapping_dir.append("/");
-+ }
-+ filepath.insert(0, mapping_dir);
-+ new_filepath = get_readonly_data_path(filepath);
-+ }
-+ else
-+ {
-+ new_filepath = filepath;
-+ }
-+
-+ // TODO: Some realpath magic? How portable is it?
-+
-+ return new_filepath;
-+}
-+
-+InputMapping* InputMappingStore::get(std::string filepath, std::string subdir)
-+{
-+ std::string full_filepath = get_mapping_path(filepath, subdir);
-+ if(!full_filepath.empty())
-+ {
-+ if(this->loaded_mappings.count(full_filepath) == 0)
-+ {
-+ // Mapping has not been loaded yet
-+ FILE* fp = fopen(full_filepath.c_str(), "r");
-+ if(fp == NULL)
-+ {
-+ printf("Unable to open mapping file '%s': %s\n", full_filepath.c_str(), strerror(errno));
-+ }
-+ else
-+ {
-+ InputMapping* mapping = new InputMapping();
-+ mapping->load(fp);
-+ this->loaded_mappings.insert(std::pair<std::string, InputMapping*>(full_filepath, mapping));
-+ }
-+ }
-+ std::map<std::string, InputMapping*>::iterator it = loaded_mappings.find(full_filepath);
-+ if(it != loaded_mappings.end())
-+ {
-+ return it->second;
-+ }
-+ }
-+ return NULL;
-+}
-\ No newline at end of file
-diff -Nur a/core/linux-dist/mappingstore.h b/core/linux-dist/mappingstore.h
---- a/core/linux-dist/mappingstore.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mappingstore.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,11 @@
-+#pragma once
-+#include "mapping.h"
-+#include <string>
-+
-+class InputMappingStore
-+{
-+ private:
-+ std::map<std::string, InputMapping*> loaded_mappings;
-+ public:
-+ InputMapping* get(std::string filepath, std::string subdir = "");
-+};
-diff -Nur a/core/linux-dist/proxy.cpp b/core/linux-dist/proxy.cpp
---- a/core/linux-dist/proxy.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/proxy.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,25 @@
-+#include "proxy.h"
-+
-+InputHandlerProxy::~InputHandlerProxy()
-+{
-+ //TODO
-+}
-+
-+void InputHandlerProxy::add(u32 port, InputHandler* handler)
-+{
-+ if(handler != NULL)
-+ {
-+ this->handlers.insert(std::pair<u32, InputHandler*>(port, handler));
-+ }
-+}
-+
-+void InputHandlerProxy::handle(u32 port)
-+{
-+ std::pair <InputHandlerStore::iterator, InputHandlerStore::iterator> range;
-+ range = this->handlers.equal_range(port);
-+
-+ for (InputHandlerStore::iterator it = range.first; it != range.second; ++it)
-+ {
-+ it->second->handle();
-+ }
-+}
-\ No newline at end of file
-diff -Nur a/core/linux-dist/proxy.h b/core/linux-dist/proxy.h
---- a/core/linux-dist/proxy.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/proxy.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,15 @@
-+#pragma once
-+#include <map>
-+#include "types.h"
-+#include "handler.h"
-+
-+class InputHandlerProxy
-+{
-+ typedef std::multimap<u32, InputHandler*> InputHandlerStore;
-+ private:
-+ InputHandlerStore handlers;
-+ public:
-+ ~InputHandlerProxy();
-+ void add(u32 port, InputHandler* handler);
-+ void handle(u32 port);
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp
---- a/core/linux-dist/x11.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/x11.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -112,11 +112,11 @@
-
- void input_x11_init()
- {
-- x11_keymap[113] = DC_DPAD_LEFT;
-- x11_keymap[114] = DC_DPAD_RIGHT;
-+ x11_keymap[113] = DC_BTN_DPAD1_LEFT;
-+ x11_keymap[114] = DC_BTN_DPAD1_RIGHT;
-
-- x11_keymap[111] = DC_DPAD_UP;
-- x11_keymap[116] = DC_DPAD_DOWN;
-+ x11_keymap[111] = DC_BTN_DPAD1_UP;
-+ x11_keymap[116] = DC_BTN_DPAD1_DOWN;
-
- x11_keymap[53] = DC_BTN_X;
- x11_keymap[54] = DC_BTN_B;
diff --git a/pcr/reicast-multilib-git/loop-tracing.patch b/pcr/reicast-multilib-git/loop-tracing.patch
deleted file mode 100644
index 2e2b5ea97..000000000
--- a/pcr/reicast-multilib-git/loop-tracing.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-diff -Nur a/core/rec-x86/rec_x86_driver.cpp b/core/rec-x86/rec_x86_driver.cpp
---- a/core/rec-x86/rec_x86_driver.cpp 2015-10-06 21:43:53.045336422 -0300
-+++ b/core/rec-x86/rec_x86_driver.cpp 2015-10-06 21:56:33.125833142 -0300
-@@ -289,6 +289,94 @@
- }
-
-
-+RuntimeBlockInfo* old_block;
-+
-+u32 old_loop;
-+u32 old_old_loop;
-+#include <map>
-+
-+#include <algorithm>
-+
-+u32 loops[RAM_SIZE];
-+u32 loops_cyc[RAM_SIZE];
-+u32 loops_hot[RAM_SIZE];
-+u32 loops_end[RAM_SIZE];
-+
-+
-+void print_loop_stats() {
-+
-+ vector<pair<u32, u32>> vc;
-+ int loopc = 0;
-+ int loopo = 0;
-+
-+ int ooc = 0;
-+ int ooo = 0;
-+
-+ for (int i = 0; i < RAM_SIZE; i += 2) {
-+ if (loops_hot[i]) {
-+ vc.push_back(pair<u32, u32>(-loops_cyc[i], i));
-+
-+ loopc += loops[i];
-+
-+ loopo += loops_cyc[i];
-+ }
-+
-+ ooc += loops[i];
-+ ooo += loops_cyc[i];
-+ }
-+
-+ sort(vc.begin(), vc.end());
-+
-+ printf("%d loops, %d, %d, %.2f, %.2f\n", vc.size(), loopc, loopo, loopc *100.0 / 1000000, loopo * 100.0 / ooo);
-+
-+ memset(loops, 0, sizeof(loops));
-+ memset(loops_cyc, 0, sizeof(loops_cyc));
-+ memset(loops_hot, 0, sizeof(loops_hot));
-+ memset(loops_end, 0, sizeof(loops_end));
-+}
-+int counts = 10000;
-+void DYNACALL ngen_enter(RuntimeBlockInfo* block) {
-+ if (BET_GET_CLS(block->BlockType) == BET_CLS_Dynamic)
-+ old_block = 0;
-+
-+ if (old_block) {
-+ if ((old_block->addr & RAM_MASK) >= (block->addr & RAM_MASK)) {
-+ loops[RAM_MASK & block->addr]++;
-+ loops_cyc[RAM_MASK & block->addr] += block->guest_cycles;
-+
-+ loops_end[RAM_MASK & block->addr] = max(loops_end[RAM_MASK & block->addr], RAM_MASK & old_block->addr);
-+
-+ if (!loops_hot[RAM_MASK & block->addr] && loops[RAM_MASK & block->addr] > 1000) {
-+ //printf("HOT LOOP %08X\n", block->addr);
-+
-+ loops_hot[RAM_MASK & block->addr] = 1;
-+ }
-+
-+ old_old_loop = old_loop;
-+ old_loop = old_block->addr & RAM_MASK;
-+ }
-+
-+ else {
-+ if ((block->addr & RAM_MASK) > loops_end[old_loop] && old_old_loop != -1) {
-+ old_loop = old_old_loop;
-+ old_old_loop = -1;
-+ }
-+
-+ if ((block->addr & RAM_MASK) <= loops_end[old_loop]) {
-+ loops[old_loop] ++;
-+ loops_cyc[old_loop] += block->guest_cycles;
-+ }
-+ }
-+ }
-+
-+ old_block = block;
-+
-+ if (--counts < 0) {
-+ counts = 10000000;
-+ print_loop_stats();
-+ }
-+}
-+
- void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise)
- {
- //initialise stuff
-@@ -306,6 +394,10 @@
-
- block->code=(DynarecCodeEntryPtr)emit_GetCCPtr();
-
-+ x86e->Emit(op_mov32, ECX, unat(block));
-+
-+ x86e->Emit(op_call, x86_ptr_imm(&ngen_enter));
-+
- x86e->Emit(op_add32,&memops_t,block->memops);
- x86e->Emit(op_add32,&memops_l,block->linkedmemops);
-
diff --git a/pcr/reicast-multilib-git/loungekatt_rm-nonfree-fp.patch b/pcr/reicast-multilib-git/loungekatt_rm-nonfree-fp.patch
deleted file mode 100644
index 9d0b588d9..000000000
--- a/pcr/reicast-multilib-git/loungekatt_rm-nonfree-fp.patch
+++ /dev/null
@@ -1,1451 +0,0 @@
-diff -Nur a/core/deps/libpng/fp.h b/core/deps/libpng/fp.h
---- a/core/deps/libpng/fp.h 2015-10-06 21:43:53.002336114 -0300
-+++ b/core/deps/libpng/fp.h 1969-12-31 21:00:00.000000000 -0300
-@@ -1,62 +0,0 @@
--/*
--* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
--*
--* @APPLE_LICENSE_HEADER_START@
--*
--* The contents of this file constitute Original Code as defined in and
--* are subject to the Apple Public Source License Version 1.1 (the
--* "License"). You may not use this file except in compliance with the
--* License. Please obtain a copy of the License at
--* http://www.apple.com/publicsource and read it before using this file.
--*
--* This Original Code and all software distributed under the License are
--* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
--* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
--* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
--* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
--* License for the specific language governing rights and limitations
--* under the License.
--*
--* @APPLE_LICENSE_HEADER_END@
--*/
--/* Copyright (c) 1992, NeXT Computer, Inc. All rights reserved.
--*
--* File: libc/m98k/gen/fp.h
--* Author: Derek B Clegg, NeXT Computer, Inc.
--*
--* HISTORY
--* 11-Nov-92 Derek B Clegg (dclegg@next.com)
--* Created.
--*
--* Common definitions for floating-point numbers.
--*/
--
--/* The following definitions for for double precision IEEE format numbers. */
--
--#define EXPONENT_BIAS 1023
--
--#define SIGN_BITS 1
--#define EXPONENT_BITS 11
--#define FRACTION_BITS 52
--#define HI_FRACTION_BITS 20
--#define LO_FRACTION_BITS 32
--
--struct double_format {
--unsigned sign: SIGN_BITS;
--unsigned exponent: EXPONENT_BITS;
--unsigned hi_fraction: HI_FRACTION_BITS;
--unsigned lo_fraction: LO_FRACTION_BITS;
--};
--
--union dbl {
--struct double_format s;
--unsigned int u[2];
--double value;
--};
--
--#define PlusInfinity (1.0/0.0)
--#define MinusInfinity (-1.0/0.0)
--
--#define not_a_number(x) ((x) != (x))
--#define positive_infinity(x) ((x) == PlusInfinity)
--#define negative_infinity(x) ((x) == MinusInfinity)
-Binary files a/shell/apple/emulator-ios/emulator/assets/Icon@2x.png and b/shell/apple/emulator-ios/emulator/assets/Icon@2x.png differ
-Binary files a/shell/apple/emulator-ios/emulator/assets/Icon-72@2x.png and b/shell/apple/emulator-ios/emulator/assets/Icon-72@2x.png differ
-Binary files a/shell/apple/emulator-ios/emulator/assets/Icon-72.png and b/shell/apple/emulator-ios/emulator/assets/Icon-72.png differ
-Binary files a/shell/apple/emulator-ios/emulator/assets/Icon.png and b/shell/apple/emulator-ios/emulator/assets/Icon.png differ
-diff -Nur a/shell/apple/emulator-ios/emulator/DiskViewCell.h b/shell/apple/emulator-ios/emulator/DiskViewCell.h
---- a/shell/apple/emulator-ios/emulator/DiskViewCell.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/emulator/DiskViewCell.h 2015-10-06 22:10:31.206968127 -0300
-@@ -0,0 +1,8 @@
-+#import <UIKit/UIKit.h>
-+
-+@interface DiskViewCell : UITableViewCell
-+
-+@property (nonatomic, retain) IBOutlet UIImageView *diskImage;
-+@property (nonatomic, retain) IBOutlet UILabel *nameLabel;
-+
-+@end
-diff -Nur a/shell/apple/emulator-ios/emulator/DiskViewCell.m b/shell/apple/emulator-ios/emulator/DiskViewCell.m
---- a/shell/apple/emulator-ios/emulator/DiskViewCell.m 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/emulator/DiskViewCell.m 2015-10-06 22:10:31.206968127 -0300
-@@ -0,0 +1,26 @@
-+#import "DiskViewCell.h"
-+
-+@implementation DiskViewCell
-+
-+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
-+{
-+ self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-+ if (self) {
-+ // Initialization code
-+ }
-+ return self;
-+}
-+
-+- (void)awakeFromNib
-+{
-+ // Initialization code
-+}
-+
-+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
-+{
-+ [super setSelected:selected animated:animated];
-+
-+ // Configure the view for the selected state
-+}
-+
-+@end
-diff -Nur a/shell/apple/emulator-ios/emulator/EmulatorViewController.h b/shell/apple/emulator-ios/emulator/EmulatorViewController.h
---- a/shell/apple/emulator-ios/emulator/EmulatorViewController.h 2015-10-06 21:43:53.121336967 -0300
-+++ b/shell/apple/emulator-ios/emulator/EmulatorViewController.h 2015-10-06 22:10:31.206968127 -0300
-@@ -10,10 +10,18 @@
- #import <GLKit/GLKit.h>
- #import <GameController/GameController.h>
- #import "iCadeReaderView.h"
-+#import "PadViewController.h"
-+#import "EmulatorView.h"
-
--@interface ViewController : GLKViewController <iCadeEventDelegate>
-+@interface EmulatorViewController : GLKViewController <iCadeEventDelegate>
-
-+@property NSString* diskImage;
- @property (nonatomic) iCadeReaderView* iCadeReader;
- @property (nonatomic) GCController *gController __attribute__((weak_import));
-+@property (nonatomic, strong) id connectObserver;
-+@property (nonatomic, strong) id disconnectObserver;
-+@property (nonatomic, strong) EmulatorView *emuView;
-+
-+@property (nonatomic, strong) PadViewController *controllerView;
-
- @end
-diff -Nur a/shell/apple/emulator-ios/emulator/EmulatorViewController.mm b/shell/apple/emulator-ios/emulator/EmulatorViewController.mm
---- a/shell/apple/emulator-ios/emulator/EmulatorViewController.mm 2015-10-06 21:43:53.121336967 -0300
-+++ b/shell/apple/emulator-ios/emulator/EmulatorViewController.mm 2015-10-06 22:10:31.206968127 -0300
-@@ -16,7 +16,7 @@
- #include "hw/maple/maple_devs.h"
- #include "hw/maple/maple_if.h"
-
--@interface ViewController () {
-+@interface EmulatorViewController () {
- }
-
- @property (strong, nonatomic) EAGLContext *context;
-@@ -35,25 +35,34 @@
- extern "C" int reicast_main(int argc, char* argv[]);
-
-
--@implementation ViewController
-+@implementation EmulatorViewController
-
- -(void)emuThread
- {
- install_prof_handler(1);
--
-
-- //This looks like the right place, rite?
-- char text[2]="";
--
-- char* prms[2];
-- prms[0]=text;
--
-- reicast_main(1, prms);
-+ char *Args[3];
-+ const char *P;
-+
-+ P = (const char *)[self.diskImage UTF8String];
-+ Args[0] = "dc";
-+ Args[1] = "-config";
-+ Args[2] = P&&P[0]? (char *)malloc(strlen(P)+32):0;
-+
-+ if(Args[2])
-+ {
-+ strcpy(Args[2],"config:image=");
-+ strcat(Args[2],P);
-+ }
-+
-+ reicast_main(Args[2]? 3:1,Args);
- }
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-+
-+ self.controllerView = [[PadViewController alloc] initWithNibName:@"PadViewController" bundle:nil];
-
- self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
-
-@@ -61,15 +70,33 @@
- NSLog(@"Failed to create ES context");
- }
-
-- GLKView *view = (GLKView *)self.view;
-- view.context = self.context;
-- view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
-+ self.emuView = (EmulatorView *)self.view;
-+ self.emuView.context = self.context;
-+ self.emuView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
-
-- self.iCadeReader = [[iCadeReaderView alloc] init];
-- [self.view addSubview:self.iCadeReader];
-- self.iCadeReader.delegate = self;
-- self.iCadeReader.active = YES;
-+ [self.controllerView setControlOutput:self.emuView];
-
-+ self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
-+ if ([[GCController controllers] count] == 1) {
-+ [self toggleHardwareController:YES];
-+ }
-+ }];
-+ self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
-+ if (![[GCController controllers] count]) {
-+ [self toggleHardwareController:NO];
-+ }
-+ }];
-+
-+ if ([[GCController controllers] count]) {
-+ [self toggleHardwareController:YES];
-+ }
-+ [self.controllerView showController:self.view];
-+
-+ self.iCadeReader = [[iCadeReaderView alloc] init];
-+ [self.view addSubview:self.iCadeReader];
-+ self.iCadeReader.delegate = self;
-+ self.iCadeReader.active = YES;
-+
- [self setupGL];
-
- if (!gles_init())
-@@ -82,7 +109,7 @@
- }
-
- - (void)dealloc
--{
-+{
- [self tearDownGL];
-
- if ([EAGLContext currentContext] == self.context) {
-@@ -127,6 +154,126 @@
-
- }
-
-+- (void)toggleHardwareController:(BOOL)useHardware {
-+ if (useHardware) {
-+// [self.controllerView hideController];
-+ self.gController = [GCController controllers][0];
-+ if (self.gController.gamepad) {
-+ [self.gController.gamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_a];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_a];
-+ }
-+ }];
-+ [self.gController.gamepad.buttonB setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_b];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_b];
-+ }
-+ }];
-+ [self.gController.gamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_x];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_x];
-+ }
-+ }];
-+ [self.gController.gamepad.buttonY setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_y];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_y];
-+ }
-+ }];
-+ [self.gController.gamepad.dpad setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue){
-+ if (xValue >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_r];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_r];
-+ }
-+ if (xValue <= -0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_l];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_l];
-+ }
-+ if (yValue >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_u];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_u];
-+ }
-+ if (yValue <= -0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_d];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_d];
-+ }
-+ }];
-+ //Add controller pause handler here
-+ }
-+ if (self.gController.extendedGamepad) {
-+ [self.gController.extendedGamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_a];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_a];
-+ }
-+ }];
-+ [self.gController.extendedGamepad.buttonB setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_b];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_b];
-+ }
-+ }];
-+ [self.gController.extendedGamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_x];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_x];
-+ }
-+ }];
-+ [self.gController.extendedGamepad.buttonY setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
-+ if (pressed && value >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_abxy_y];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_abxy_y];
-+ }
-+ }];
-+ [self.gController.extendedGamepad.dpad setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue){
-+ if (xValue >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_r];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_r];
-+ }
-+ if (xValue <= -0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_l];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_l];
-+ }
-+ if (yValue >= 0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_u];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_u];
-+ }
-+ if (yValue <= -0.1) {
-+ [self.emuView handleKeyDown:self.controllerView.img_dpad_d];
-+ } else {
-+ [self.emuView handleKeyUp:self.controllerView.img_dpad_d];
-+ }
-+ }];
-+ [self.gController.extendedGamepad.leftThumbstick.xAxis setValueChangedHandler:^(GCControllerAxisInput *axis, float value){
-+
-+ }];
-+ [self.gController.extendedGamepad.leftThumbstick.yAxis setValueChangedHandler:^(GCControllerAxisInput *axis, float value){
-+
-+ }];
-+ }
-+ } else {
-+ self.gController = nil;
-+// [self.controllerView showController:self.view];
-+ }
-+}
-
- - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
- {
-diff -Nur a/shell/apple/emulator-ios/emulator/EmulatorView.h b/shell/apple/emulator-ios/emulator/EmulatorView.h
---- a/shell/apple/emulator-ios/emulator/EmulatorView.h 2015-10-06 21:43:53.121336967 -0300
-+++ b/shell/apple/emulator-ios/emulator/EmulatorView.h 2015-10-06 22:10:31.206968127 -0300
-@@ -10,4 +10,9 @@
-
- @interface EmulatorView : GLKView
-
-+- (void)handleKeyDown:(UIButton*)button;
-+- (void)handleKeyUp:(UIButton*)button;
-+
-+@property (nonatomic, strong) UIViewController *controllerView;
-+
- @end
-diff -Nur a/shell/apple/emulator-ios/emulator/EmulatorView.mm b/shell/apple/emulator-ios/emulator/EmulatorView.mm
---- a/shell/apple/emulator-ios/emulator/EmulatorView.mm 2015-10-06 21:43:53.121336967 -0300
-+++ b/shell/apple/emulator-ios/emulator/EmulatorView.mm 2015-10-06 22:10:31.206968127 -0300
-@@ -7,6 +7,7 @@
- //
-
- #import "EmulatorView.h"
-+#import "PadViewController.h"
-
- #include "types.h"
-
-@@ -15,11 +16,27 @@
- extern s8 joyx[4],joyy[4];
- extern u8 rt[4],lt[4];
-
--#define key_CONT_A (1 << 2)
--#define key_CONT_START (1 << 3)
--#define key_CONT_DPAD_LEFT (1 << 6)
--
--int dpad_or_btn = 0;
-+#define DC_BTN_C (1)
-+#define DC_BTN_B (1<<1)
-+#define DC_BTN_A (1<<2)
-+#define DC_BTN_START (1<<3)
-+#define DC_DPAD_UP (1<<4)
-+#define DC_DPAD_DOWN (1<<5)
-+#define DC_DPAD_LEFT (1<<6)
-+#define DC_DPAD_RIGHT (1<<7)
-+#define DC_BTN_Z (1<<8)
-+#define DC_BTN_Y (1<<9)
-+#define DC_BTN_X (1<<10)
-+#define DC_BTN_D (1<<11)
-+#define DC_DPAD2_UP (1<<12)
-+#define DC_DPAD2_DOWN (1<<13)
-+#define DC_DPAD2_LEFT (1<<14)
-+#define DC_DPAD2_RIGHT (1<<15)
-+
-+#define DC_AXIS_LT (0X10000)
-+#define DC_AXIS_RT (0X10001)
-+#define DC_AXIS_X (0X20000)
-+#define DC_AXIS_Y (0X20001)
-
- @implementation EmulatorView
-
-@@ -31,23 +48,85 @@
- }
- */
-
---(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
--
-- if (dpad_or_btn &1)
-- kcode[0] &= ~(key_CONT_START|key_CONT_A);
-- else
-- kcode[0] &= ~(key_CONT_DPAD_LEFT);
-+- (void)setControlInput:(PadViewController *)input
-+{
-+ self.controllerView = input;
-+}
-+
-+- (void)handleKeyDown:(UIButton*)button
-+{
-+ PadViewController * controller = (PadViewController *)self.controllerView;
-+ if (button == controller.img_dpad_l) {
-+ kcode[0] &= ~(DC_DPAD_LEFT);
-+ }
-+ if (button == controller.img_dpad_r) {
-+ kcode[0] &= ~(DC_DPAD_RIGHT);
-+ }
-+ if (button == controller.img_dpad_u) {
-+ kcode[0] &= ~(DC_DPAD_UP);
-+ }
-+ if (button == controller.img_dpad_d) {
-+ kcode[0] &= ~(DC_DPAD_DOWN);
-+ }
-+ if (button == controller.img_abxy_a) {
-+ kcode[0] &= ~(DC_BTN_A);
-+ }
-+ if (button == controller.img_abxy_b) {
-+ kcode[0] &= ~(DC_BTN_B);
-+ }
-+ if (button == controller.img_abxy_x) {
-+ kcode[0] &= ~(DC_BTN_X);
-+ }
-+ if (button == controller.img_abxy_y) {
-+ kcode[0] &= ~(DC_BTN_Y);
-+ }
-+ if (button == controller.img_lt) {
-+ kcode[0] &= ~(DC_AXIS_LT);
-+ }
-+ if (button == controller.img_rt) {
-+ kcode[0] &= ~(DC_AXIS_RT);
-+ }
-+ if (button == controller.img_start) {
-+ kcode[0] &= ~(DC_BTN_START);
-+ }
- }
-
---(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
--
-- // [event allTouches];
--
-- if (dpad_or_btn &1)
-- kcode[0] |= (key_CONT_START|key_CONT_A);
-- else
-- kcode[0] |= (key_CONT_DPAD_LEFT);
--
-- dpad_or_btn++;
-+- (void)handleKeyUp:(UIButton*)button
-+{
-+ PadViewController * controller = (PadViewController *)self.controllerView;
-+ if (button == controller.img_dpad_l) {
-+ kcode[0] |= ~(DC_DPAD_LEFT);
-+ }
-+ if (button == controller.img_dpad_r) {
-+ kcode[0] |= ~(DC_DPAD_RIGHT);
-+ }
-+ if (button == controller.img_dpad_u) {
-+ kcode[0] |= ~(DC_DPAD_UP);
-+ }
-+ if (button == controller.img_dpad_d) {
-+ kcode[0] |= ~(DC_DPAD_DOWN);
-+ }
-+ if (button == controller.img_abxy_a) {
-+ kcode[0] |= (DC_BTN_A);
-+ }
-+ if (button == controller.img_abxy_b) {
-+ kcode[0] |= (DC_BTN_B);
-+ }
-+ if (button == controller.img_abxy_x) {
-+ kcode[0] |= (DC_BTN_X);
-+ }
-+ if (button == controller.img_abxy_y) {
-+ kcode[0] |= (DC_BTN_Y);
-+ }
-+ if (button == controller.img_lt) {
-+ kcode[0] |= (DC_AXIS_LT);
-+ }
-+ if (button == controller.img_rt) {
-+ kcode[0] |= (DC_AXIS_RT);
-+ }
-+ if (button == controller.img_start) {
-+ kcode[0] |= (DC_BTN_START);
-+ }
- }
-+
- @end
-Binary files a/shell/apple/emulator-ios/emulator/Images/disk_unknown.png and b/shell/apple/emulator-ios/emulator/Images/disk_unknown.png differ
-diff -Nur a/shell/apple/emulator-ios/emulator/MainStoryboard.storyboard b/shell/apple/emulator-ios/emulator/MainStoryboard.storyboard
---- a/shell/apple/emulator-ios/emulator/MainStoryboard.storyboard 2015-10-06 21:43:53.123336981 -0300
-+++ b/shell/apple/emulator-ios/emulator/MainStoryboard.storyboard 2015-10-06 22:10:31.207968135 -0300
-@@ -1,32 +1,100 @@
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
--<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="WRM-pR-XCP">
-+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="mSg-lr-0DL">
- <dependencies>
-- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
-+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
- </dependencies>
- <scenes>
-- <!--View Controller-->
-+ <!--Root View Controller-->
-+ <scene sceneID="q8K-fk-uPf">
-+ <objects>
-+ <tableViewController id="ZcT-ex-GUK" customClass="PathsViewController" sceneMemberID="viewController">
-+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="LNG-KY-d6N">
-+ <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
-+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
-+ <prototypes>
-+ <tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" rowHeight="80" id="mMa-C3-VYu" customClass="DiskViewCell">
-+ <rect key="frame" x="0.0" y="22" width="320" height="80"/>
-+ <autoresizingMask key="autoresizingMask"/>
-+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="mMa-C3-VYu" id="snt-ku-Aaq">
-+ <rect key="frame" x="0.0" y="0.0" width="287" height="79.5"/>
-+ <autoresizingMask key="autoresizingMask"/>
-+ <subviews>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="disk_unknown.png" id="6Qh-mW-Z9j">
-+ <rect key="frame" x="8" y="4" width="72" height="72"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Epl-iu-f5s">
-+ <rect key="frame" x="88" y="24" width="199" height="32"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
-+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
-+ <nil key="highlightedColor"/>
-+ </label>
-+ </subviews>
-+ </tableViewCellContentView>
-+ <connections>
-+ <outlet property="diskImage" destination="6Qh-mW-Z9j" id="b3r-L8-LS3"/>
-+ <outlet property="nameLabel" destination="Epl-iu-f5s" id="i0S-JF-deT"/>
-+ </connections>
-+ </tableViewCell>
-+ </prototypes>
-+ <connections>
-+ <outlet property="dataSource" destination="ZcT-ex-GUK" id="TGz-Qe-tBz"/>
-+ <outlet property="delegate" destination="ZcT-ex-GUK" id="LAp-Yu-Mwb"/>
-+ </connections>
-+ </tableView>
-+ <navigationItem key="navigationItem" title="Root View Controller" id="5jN-Uj-bBb"/>
-+ <simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
-+ <connections>
-+ <segue destination="WRM-pR-XCP" kind="modal" identifier="emulatorView" id="b10-sb-xpr"/>
-+ </connections>
-+ </tableViewController>
-+ <placeholder placeholderIdentifier="IBFirstResponder" id="mdD-bX-Gqc" userLabel="First Responder" sceneMemberID="firstResponder"/>
-+ </objects>
-+ <point key="canvasLocation" x="-88" y="-692"/>
-+ </scene>
-+ <!--Navigation Controller-->
-+ <scene sceneID="VLz-J1-2XD">
-+ <objects>
-+ <navigationController navigationBarHidden="YES" id="mSg-lr-0DL" sceneMemberID="viewController">
-+ <navigationBar key="navigationBar" contentMode="scaleToFill" id="vT9-en-Ct5">
-+ <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
-+ <autoresizingMask key="autoresizingMask"/>
-+ </navigationBar>
-+ <connections>
-+ <segue destination="ZcT-ex-GUK" kind="relationship" relationship="rootViewController" id="fhp-zt-Xhh"/>
-+ </connections>
-+ </navigationController>
-+ <placeholder placeholderIdentifier="IBFirstResponder" id="i7I-Ys-F6b" userLabel="First Responder" sceneMemberID="firstResponder"/>
-+ </objects>
-+ <point key="canvasLocation" x="-692" y="-692"/>
-+ </scene>
-+ <!--Emulator View Controller-->
- <scene sceneID="h6I-2s-MCy">
- <objects>
-- <viewController storyboardIdentifier="emulatorView" wantsFullScreenLayout="YES" id="WRM-pR-XCP" customClass="ViewController" sceneMemberID="viewController">
-- <view key="view" contentMode="scaleToFill" id="JQE-db-ZiC" customClass="EmulatorView">
-+ <viewController storyboardIdentifier="emulatorView" wantsFullScreenLayout="YES" id="WRM-pR-XCP" customClass="EmulatorViewController" sceneMemberID="viewController">
-+ <view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="JQE-db-ZiC" customClass="EmulatorView">
- <rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-- <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/>
-+ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
-+ <accessibility key="accessibilityConfiguration">
-+ <accessibilityTraits key="traits" none="YES" notEnabled="YES"/>
-+ </accessibility>
- <gestureRecognizers/>
- </view>
-+ <navigationItem key="navigationItem" id="FmO-Yo-nVN"/>
- <nil key="simulatedStatusBarMetrics"/>
- <simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
- </viewController>
- <placeholder placeholderIdentifier="IBFirstResponder" id="ioY-OH-Jev" userLabel="First Responder" sceneMemberID="firstResponder"/>
-- <pongPressGestureRecognizer delaysTouchesEnded="NO" allowableMovement="10" minimumPressDuration="0.5" id="J8w-PT-eHl">
-- <connections>
-- <action selector="doSaveState:" destination="WRM-pR-XCP" id="6ND-tU-CZE"/>
-- </connections>
-- </pongPressGestureRecognizer>
- </objects>
- <point key="canvasLocation" x="486" y="-692"/>
- </scene>
- </scenes>
-+ <resources>
-+ <image name="disk_unknown.png" width="95" height="95"/>
-+ </resources>
- <simulatedMetricsContainer key="defaultSimulatedMetrics">
- <simulatedStatusBarMetrics key="statusBar"/>
- <simulatedOrientationMetrics key="orientation"/>
-diff -Nur a/shell/apple/emulator-ios/emulator/PadViewController.h b/shell/apple/emulator-ios/emulator/PadViewController.h
---- a/shell/apple/emulator-ios/emulator/PadViewController.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/emulator/PadViewController.h 2015-10-06 22:10:31.207968135 -0300
-@@ -0,0 +1,34 @@
-+//
-+// PadViewController.h
-+// reicast-ios
-+//
-+// Created by Lounge Katt on 8/25/15.
-+// Copyright (c) 2015 reicast. All rights reserved.
-+//
-+
-+#import <UIKit/UIKit.h>
-+#import "EmulatorView.h"
-+
-+@interface PadViewController : UIViewController
-+
-+@property (nonatomic, strong) IBOutlet UIButton* img_dpad_l;
-+@property (nonatomic, strong) IBOutlet UIButton* img_dpad_r;
-+@property (nonatomic, strong) IBOutlet UIButton* img_dpad_u;
-+@property (nonatomic, strong) IBOutlet UIButton* img_dpad_d;
-+@property (nonatomic, strong) IBOutlet UIButton* img_abxy_a;
-+@property (nonatomic, strong) IBOutlet UIButton* img_abxy_b;
-+@property (nonatomic, strong) IBOutlet UIButton* img_abxy_x;
-+@property (nonatomic, strong) IBOutlet UIButton* img_abxy_y;
-+@property (nonatomic, strong) IBOutlet UIButton* img_vjoy;
-+@property (nonatomic, strong) IBOutlet UIButton* img_lt;
-+@property (nonatomic, strong) IBOutlet UIButton* img_rt;
-+@property (nonatomic, strong) IBOutlet UIButton* img_start;
-+
-+@property (nonatomic, strong) EmulatorView *handler;
-+
-+- (void) showController:(UIView *)parentView;
-+- (void) hideController;
-+- (BOOL) isControllerVisible;
-+- (void) setControlOutput:(EmulatorView *)output;
-+
-+@end
-diff -Nur a/shell/apple/emulator-ios/emulator/PadViewController.m b/shell/apple/emulator-ios/emulator/PadViewController.m
---- a/shell/apple/emulator-ios/emulator/PadViewController.m 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/emulator/PadViewController.m 2015-10-06 22:10:31.207968135 -0300
-@@ -0,0 +1,78 @@
-+//
-+// PadViewController.m
-+// reicast-ios
-+//
-+// Created by Lounge Katt on 8/25/15.
-+// Copyright (c) 2015 reicast. All rights reserved.
-+//
-+
-+#import "PadViewController.h"
-+#import "EmulatorView.h"
-+
-+@interface PadViewController ()
-+
-+@end
-+
-+@implementation PadViewController
-+
-+- (void)viewDidLoad {
-+ [super viewDidLoad];
-+}
-+
-+- (void)didReceiveMemoryWarning {
-+ [super didReceiveMemoryWarning];
-+ // Dispose of any resources that can be recreated.
-+}
-+
-+- (void)showController:(UIView *)parentView
-+{
-+ [parentView addSubview:self.view];
-+}
-+
-+- (void)hideController
-+{
-+ [self.view removeFromSuperview];
-+}
-+
-+- (BOOL)isControllerVisible {
-+ if (self.view.window != nil) {
-+ return YES;
-+ }
-+ return NO;
-+}
-+
-+- (void)setControlOutput:(EmulatorView *)output
-+{
-+ self.handler = output;
-+}
-+
-+- (IBAction)keycodeDown:(id)sender
-+{
-+ [self.handler handleKeyDown:(UIButton*)sender];
-+}
-+
-+- (IBAction)keycodeUp:(id)sender
-+{
-+ [self.handler handleKeyUp:(UIButton*)sender];
-+}
-+
-+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
-+{
-+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
-+ if (self) {
-+ // Custom initialization
-+ }
-+ return self;
-+}
-+
-+/*
-+#pragma mark - Navigation
-+
-+// In a storyboard-based application, you will often want to do a little preparation before navigation
-+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
-+ // Get the new view controller using [segue destinationViewController].
-+ // Pass the selected object to the new view controller.
-+}
-+*/
-+
-+@end
-diff -Nur a/shell/apple/emulator-ios/emulator/PadViewController.xib b/shell/apple/emulator-ios/emulator/PadViewController.xib
---- a/shell/apple/emulator-ios/emulator/PadViewController.xib 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/emulator/PadViewController.xib 2015-10-06 22:10:31.207968135 -0300
-@@ -0,0 +1,197 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
-+ <dependencies>
-+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
-+ </dependencies>
-+ <objects>
-+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PadViewController">
-+ <connections>
-+ <outlet property="img_abxy_a" destination="iKO-3z-Ias" id="ENi-No-2tP"/>
-+ <outlet property="img_abxy_b" destination="7LB-OY-vh3" id="pGH-6d-IgP"/>
-+ <outlet property="img_abxy_x" destination="iwO-7q-c8H" id="ZhP-Zp-Qnj"/>
-+ <outlet property="img_abxy_y" destination="hGZ-v7-VA5" id="5qv-nJ-V1w"/>
-+ <outlet property="img_dpad_d" destination="s7g-nq-lRU" id="9MP-1k-eUW"/>
-+ <outlet property="img_dpad_l" destination="rp6-Nd-1qa" id="LNo-9e-3og"/>
-+ <outlet property="img_dpad_r" destination="CVH-hw-R8F" id="vbf-4S-SBb"/>
-+ <outlet property="img_dpad_u" destination="WMD-Fv-ibu" id="1kE-zb-8gR"/>
-+ <outlet property="img_lt" destination="8Gl-Iv-u8L" id="4R8-pf-PYz"/>
-+ <outlet property="img_rt" destination="V8J-vG-dlF" id="Bn6-Zm-Ojo"/>
-+ <outlet property="img_start" destination="VtI-tC-PSX" id="o3u-Cb-G2g"/>
-+ <outlet property="view" destination="3M7-1s-N5r" id="Tac-YU-UYE"/>
-+ </connections>
-+ </placeholder>
-+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-+ <view multipleTouchEnabled="YES" contentMode="scaleToFill" id="3M7-1s-N5r">
-+ <rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
-+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-+ <subviews>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LTrigger.png" id="H57-MD-elm">
-+ <rect key="frame" x="0.0" y="0.0" width="80" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="8Gl-Iv-u8L" userLabel="LT-Button">
-+ <rect key="frame" x="0.0" y="0.0" width="80" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="34L-sO-g81"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="iDv-U3-6OX"/>
-+ </connections>
-+ </button>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="RTrigger.png" id="Cjn-zx-eSs">
-+ <rect key="frame" x="488" y="0.0" width="80" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="V8J-vG-dlF" userLabel="RT-Button">
-+ <rect key="frame" x="488" y="0.0" width="80" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="vPf-qF-m13"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="hQh-8f-5jG"/>
-+ </connections>
-+ </button>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="JoystickButton.png" id="ivh-8r-bw3" userLabel="JoystickThumbpad.png">
-+ <rect key="frame" x="20" y="206" width="100" height="100"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="JoystickBackground.png" id="OMP-L6-n0A">
-+ <rect key="frame" x="6" y="192" width="128" height="128"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="DPad.png" id="FLe-Gr-hny">
-+ <rect key="frame" x="0.0" y="44" width="140" height="140"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="rp6-Nd-1qa" userLabel="L-Button">
-+ <rect key="frame" x="0.0" y="94" width="46" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="3Yw-AP-xVf"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="5gI-j0-ANf"/>
-+ </connections>
-+ </button>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="CVH-hw-R8F" userLabel="R-Button">
-+ <rect key="frame" x="94" y="94" width="46" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="2Dv-zb-f8V"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="woi-3Y-IfD"/>
-+ </connections>
-+ </button>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="WMD-Fv-ibu" userLabel="U-Button">
-+ <rect key="frame" x="50" y="44" width="40" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="kT6-yy-ZtY"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="R0R-dl-GAG"/>
-+ </connections>
-+ </button>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="s7g-nq-lRU" userLabel="D-Button">
-+ <rect key="frame" x="50" y="144" width="40" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="Wck-mk-4Py"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="Qox-hz-p3A"/>
-+ </connections>
-+ </button>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ABXYPad.png" id="xbP-E4-fCE">
-+ <rect key="frame" x="408" y="159" width="160" height="161"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="iwO-7q-c8H" userLabel="X-Button">
-+ <rect key="frame" x="408" y="210" width="60" height="60"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="IBH-TK-vfV"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="dhr-NT-lcF"/>
-+ </connections>
-+ </button>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="7LB-OY-vh3" userLabel="B-Button">
-+ <rect key="frame" x="508" y="210" width="60" height="60"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="dhg-58-L8C"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="zqg-KK-Wxb"/>
-+ </connections>
-+ </button>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="hGZ-v7-VA5" userLabel="Y-Button">
-+ <rect key="frame" x="458" y="159" width="60" height="60"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="tyb-H4-TqJ"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="oai-Xb-scl"/>
-+ </connections>
-+ </button>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="iKO-3z-Ias" userLabel="A-Button">
-+ <rect key="frame" x="458" y="260" width="60" height="60"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="Ysa-m4-KnN"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="MTf-ND-WNy"/>
-+ </connections>
-+ </button>
-+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Start.png" id="9K0-cV-7zu">
-+ <rect key="frame" x="244" y="272" width="80" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ </imageView>
-+ <button opaque="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="VtI-tC-PSX" userLabel="S-Button">
-+ <rect key="frame" x="257" y="272" width="54" height="40"/>
-+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-+ <state key="normal">
-+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
-+ </state>
-+ <connections>
-+ <action selector="keycodeDown:" destination="-1" eventType="touchDown" id="kwd-jB-5Wn"/>
-+ <action selector="keycodeUp:" destination="-1" eventType="touchUpInside" id="gHx-tA-QlF"/>
-+ </connections>
-+ </button>
-+ </subviews>
-+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
-+ <simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
-+ <point key="canvasLocation" x="325" y="329"/>
-+ </view>
-+ </objects>
-+ <resources>
-+ <image name="ABXYPad.png" width="120" height="120"/>
-+ <image name="DPad.png" width="120" height="120"/>
-+ <image name="JoystickBackground.png" width="120" height="120"/>
-+ <image name="JoystickButton.png" width="56" height="56"/>
-+ <image name="LTrigger.png" width="67" height="44"/>
-+ <image name="RTrigger.png" width="67" height="44"/>
-+ <image name="Start.png" width="48" height="26"/>
-+ </resources>
-+ <simulatedMetricsContainer key="defaultSimulatedMetrics">
-+ <simulatedStatusBarMetrics key="statusBar"/>
-+ <simulatedOrientationMetrics key="orientation"/>
-+ <simulatedScreenMetrics key="destination" type="retina4"/>
-+ </simulatedMetricsContainer>
-+</document>
-diff -Nur a/shell/apple/emulator-ios/emulator/PathsViewController.h b/shell/apple/emulator-ios/emulator/PathsViewController.h
---- a/shell/apple/emulator-ios/emulator/PathsViewController.h 2015-10-06 21:43:53.123336981 -0300
-+++ b/shell/apple/emulator-ios/emulator/PathsViewController.h 2015-10-06 22:10:31.207968135 -0300
-@@ -8,7 +8,9 @@
-
- #import <UIKit/UIKit.h>
-
--@interface PathsViewController : UITableViewController
-+@interface PathsViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
- @property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
-
-+@property (nonatomic, strong) NSMutableArray* diskImages;
-+
- @end
-diff -Nur a/shell/apple/emulator-ios/emulator/PathsViewController.m b/shell/apple/emulator-ios/emulator/PathsViewController.m
---- a/shell/apple/emulator-ios/emulator/PathsViewController.m 2015-10-06 21:43:53.123336981 -0300
-+++ b/shell/apple/emulator-ios/emulator/PathsViewController.m 2015-10-06 22:10:31.207968135 -0300
-@@ -7,7 +7,9 @@
- //
-
- #import "PathsViewController.h"
--#import "SWRevealViewController.h"
-+//#import "SWRevealViewController.h"
-+#import "EmulatorViewController.h"
-+#import "DiskViewCell.h"
-
- @interface PathsViewController ()
-
-@@ -24,22 +26,32 @@
- return self;
- }
-
-+- (NSURL *)documents
-+{
-+ return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
-+}
-+
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- self.title = @"Paths";
-
- // Set the side bar button action. When it's tapped, it'll show up the sidebar.
-- _sidebarButton.target = self.revealViewController;
-- _sidebarButton.action = @selector(revealToggle:);
--
-+// _sidebarButton.target = self.revealViewController;
-+// _sidebarButton.action = @selector(revealToggle:);
-+
- // Set the gesture
-- [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
-+// [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
- // Uncomment the following line to preserve selection between presentations.
- // self.clearsSelectionOnViewWillAppear = NO;
-
- // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
- // self.navigationItem.rightBarButtonItem = self.editButtonItem;
-+
-+ self.diskImages = [[NSMutableArray alloc] init];
-+ NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self documents].path error:NULL];
-+ NSPredicate *diskPredicate = [NSPredicate predicateWithFormat:@"self ENDSWITH '.chd' || self ENDSWITH '.gdi' || self ENDSWITH '.cdi' || self ENDSWITH '.CHD' || self ENDSWITH '.GDI' || self ENDSWITH '.CDI'"];
-+ self.diskImages = [NSMutableArray arrayWithArray:[files filteredArrayUsingPredicate:diskPredicate]];
- }
-
- - (void)didReceiveMemoryWarning
-@@ -50,6 +62,52 @@
-
- #pragma mark - Table view data source
-
--// TODO: paths view controller logic
-+-(NSInteger)numberOfSectionsInTableView: (UITableView*)tableView
-+{
-+ return 1;
-+}
-+
-+-(NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section
-+{
-+ return [self.diskImages count];
-+}
-+
-+-(NSString*)tableView: (UITableView*)tableView titleForHeaderInSection: (NSInteger)section
-+{
-+ return @"";
-+}
-+
-+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
-+ return 80;
-+ // Assign the specific cell height to prevent issues with custom size
-+}
-+
-+-(UITableViewCell*)tableView: (UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath*)indexPath
-+{
-+ static NSString *CellIdentifier = @"Cell";
-+
-+ DiskViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
-+ NSString* imagePath = [self.diskImages objectAtIndex: indexPath.row];
-+
-+ cell.nameLabel.text = [[imagePath lastPathComponent] stringByDeletingPathExtension];
-+
-+ return cell;
-+}
-+
-+-(void)prepareForSegue: (UIStoryboardSegue*)segue sender: (id)sender
-+{
-+ if ([segue.identifier isEqualToString:@"emulatorView"]) {
-+ NSIndexPath* indexPath = self.tableView.indexPathForSelectedRow;
-+ NSString* filePath = [self.diskImages objectAtIndex: indexPath.row];
-+ NSString* diskPath = [[self documents].path stringByAppendingPathComponent: filePath];
-+ EmulatorViewController* emulatorView = segue.destinationViewController;
-+ emulatorView.diskImage = diskPath;
-+ }
-+}
-+
-+-(void)tableView: (UITableView*)tableView didSelectRowAtIndexPath: (NSIndexPath*)indexPath
-+{
-+ [self performSegueWithIdentifier: @"emulatorView" sender: self];
-+}
-
- @end
-diff -Nur a/shell/apple/emulator-ios/emulator/reicast-ios-Info.plist b/shell/apple/emulator-ios/emulator/reicast-ios-Info.plist
---- a/shell/apple/emulator-ios/emulator/reicast-ios-Info.plist 2015-10-06 21:43:53.124336988 -0300
-+++ b/shell/apple/emulator-ios/emulator/reicast-ios-Info.plist 2015-10-06 22:10:31.207968135 -0300
-@@ -8,13 +8,6 @@
- <string>Reicast</string>
- <key>CFBundleExecutable</key>
- <string>${EXECUTABLE_NAME}</string>
-- <key>CFBundleIconFiles</key>
-- <array>
-- <string>emulator/assets/Icon-72.png</string>
-- <string>emulator/assets/Icon-72@2x.png</string>
-- <string>emulator/assets/Icon.png</string>
-- <string>emulator/assets/Icon@2x.png</string>
-- </array>
- <key>CFBundleIdentifier</key>
- <string>com.reicast.$(PRODUCT_NAME:rfc1034identifier)</string>
- <key>CFBundleInfoDictionaryVersion</key>
-diff -Nur a/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Contents.json
---- a/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Contents.json 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Contents.json 2015-10-06 22:10:31.209968149 -0300
-@@ -0,0 +1,60 @@
-+{
-+ "images" : [
-+ {
-+ "idiom" : "iphone",
-+ "size" : "29x29",
-+ "scale" : "2x"
-+ },
-+ {
-+ "idiom" : "iphone",
-+ "size" : "40x40",
-+ "scale" : "2x"
-+ },
-+ {
-+ "size" : "60x60",
-+ "idiom" : "iphone",
-+ "filename" : "Icon-60@2x.png",
-+ "scale" : "2x"
-+ },
-+ {
-+ "idiom" : "iphone",
-+ "size" : "60x60",
-+ "scale" : "3x"
-+ },
-+ {
-+ "idiom" : "ipad",
-+ "size" : "29x29",
-+ "scale" : "1x"
-+ },
-+ {
-+ "idiom" : "ipad",
-+ "size" : "29x29",
-+ "scale" : "2x"
-+ },
-+ {
-+ "idiom" : "ipad",
-+ "size" : "40x40",
-+ "scale" : "1x"
-+ },
-+ {
-+ "idiom" : "ipad",
-+ "size" : "40x40",
-+ "scale" : "2x"
-+ },
-+ {
-+ "idiom" : "ipad",
-+ "size" : "76x76",
-+ "scale" : "1x"
-+ },
-+ {
-+ "size" : "76x76",
-+ "idiom" : "ipad",
-+ "filename" : "Icon-76@2x.png",
-+ "scale" : "2x"
-+ }
-+ ],
-+ "info" : {
-+ "version" : 1,
-+ "author" : "xcode"
-+ }
-+}
-\ No newline at end of file
-Binary files a/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png and b/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png differ
-Binary files a/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png and b/shell/apple/emulator-ios/reicast-ios/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png differ
-diff -Nur a/shell/apple/emulator-ios/reicast-ios/Images.xcassets/LaunchImage.launchimage/Contents.json b/shell/apple/emulator-ios/reicast-ios/Images.xcassets/LaunchImage.launchimage/Contents.json
---- a/shell/apple/emulator-ios/reicast-ios/Images.xcassets/LaunchImage.launchimage/Contents.json 1969-12-31 21:00:00.000000000 -0300
-+++ b/shell/apple/emulator-ios/reicast-ios/Images.xcassets/LaunchImage.launchimage/Contents.json 2015-10-06 22:10:31.209968149 -0300
-@@ -0,0 +1,49 @@
-+{
-+ "images" : [
-+ {
-+ "orientation" : "portrait",
-+ "idiom" : "ipad",
-+ "minimum-system-version" : "7.0",
-+ "extent" : "full-screen",
-+ "scale" : "2x"
-+ },
-+ {
-+ "orientation" : "landscape",
-+ "idiom" : "ipad",
-+ "minimum-system-version" : "7.0",
-+ "extent" : "full-screen",
-+ "scale" : "1x"
-+ },
-+ {
-+ "orientation" : "landscape",
-+ "idiom" : "ipad",
-+ "minimum-system-version" : "7.0",
-+ "extent" : "full-screen",
-+ "scale" : "2x"
-+ },
-+ {
-+ "orientation" : "portrait",
-+ "idiom" : "iphone",
-+ "minimum-system-version" : "7.0",
-+ "scale" : "2x"
-+ },
-+ {
-+ "orientation" : "portrait",
-+ "idiom" : "iphone",
-+ "minimum-system-version" : "7.0",
-+ "subtype" : "retina4",
-+ "scale" : "2x"
-+ },
-+ {
-+ "orientation" : "portrait",
-+ "idiom" : "ipad",
-+ "minimum-system-version" : "7.0",
-+ "extent" : "full-screen",
-+ "scale" : "1x"
-+ }
-+ ],
-+ "info" : {
-+ "version" : 1,
-+ "author" : "xcode"
-+ }
-+}
-\ No newline at end of file
-diff -Nur a/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj b/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj
---- a/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj 2015-10-06 21:43:53.125336995 -0300
-+++ b/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj 2015-10-06 22:10:31.209968149 -0300
-@@ -50,6 +50,9 @@
- 877652C61B6157BD00437F10 /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 877652BF1B6157BD00437F10 /* audiostream.cpp */; };
- 877652C91B6157FC00437F10 /* ngen_arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 877652C71B6157FC00437F10 /* ngen_arm.S */; };
- 877652CA1B6157FC00437F10 /* rec_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 877652C81B6157FC00437F10 /* rec_arm.cpp */; };
-+ 878B0CFC1B8BB5B400A8D1C5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 878B0CFB1B8BB5B400A8D1C5 /* Images.xcassets */; };
-+ 878B0D001B8BFE6200A8D1C5 /* disk_unknown.png in Resources */ = {isa = PBXBuildFile; fileRef = 878B0CFF1B8BFE6200A8D1C5 /* disk_unknown.png */; };
-+ 8794D9C31B88F3D600B1B3A3 /* DiskViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8794D9C21B88F3D600B1B3A3 /* DiskViewCell.m */; };
- 87C208D71B7A4BFA00638BDD /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87C208C61B7A4BFA00638BDD /* AboutViewController.m */; };
- 87C208D81B7A4BFA00638BDD /* BrowserTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87C208C81B7A4BFA00638BDD /* BrowserTableViewController.m */; };
- 87C208D91B7A4BFA00638BDD /* CloudVMUViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87C208CA1B7A4BFA00638BDD /* CloudVMUViewController.m */; };
-@@ -87,10 +90,8 @@
- 87D92F4E1B7A1B5700D8FD9E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87D92F4D1B7A1B5700D8FD9E /* GameController.framework */; };
- 87D92F541B7A1BB100D8FD9E /* iCadeReaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 87D92F511B7A1BB100D8FD9E /* iCadeReaderView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 87D92F551B7A1BB100D8FD9E /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 87D92F531B7A1BB100D8FD9E /* LICENSE */; };
-- 87DCDB251B7EE57D0054D67C /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC371A44B8DA00E7E939 /* Icon-72.png */; };
-- 87DCDB261B7EE5850054D67C /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */; };
-- 87DCDB271B7EE5850054D67C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC391A44B8DA00E7E939 /* Icon.png */; };
-- 87DCDB281B7EE5850054D67C /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC3A1A44B8DA00E7E939 /* Icon@2x.png */; };
-+ 87FA52E91B8CE18600CEFC32 /* PadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87FA52E71B8CE18600CEFC32 /* PadViewController.m */; };
-+ 87FA52EA1B8CE18600CEFC32 /* PadViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 87FA52E81B8CE18600CEFC32 /* PadViewController.xib */; };
- 9C7A393318C804A80070BB5F /* reicast.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 9C7A393218C804A80070BB5F /* reicast.entitlements */; };
- 9C7A3AA218C806E00070BB5F /* cfg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A395118C806DE0070BB5F /* cfg.cpp */; };
- 9C7A3AA318C806E00070BB5F /* cl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A395318C806DE0070BB5F /* cl.cpp */; };
-@@ -244,7 +245,6 @@
- 84967C751B8F492C005F1140 /* filter_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = filter_neon.S; sourceTree = "<group>"; };
- 84967C761B8F492C005F1140 /* filter_neon_intrinsics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = filter_neon_intrinsics.c; sourceTree = "<group>"; };
- 84967C771B8F492C005F1140 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
-- 84967C781B8F492C005F1140 /* fp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fp.h; sourceTree = "<group>"; };
- 84967C791B8F492C005F1140 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = png.c; sourceTree = "<group>"; };
- 84967C7A1B8F492C005F1140 /* png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = png.h; sourceTree = "<group>"; };
- 84967C7B1B8F492C005F1140 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pngconf.h; sourceTree = "<group>"; };
-@@ -282,10 +282,6 @@
- 849C0D6A1B072D14008BAAA4 /* gdrom_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gdrom_hle.h; path = reios/gdrom_hle.h; sourceTree = "<group>"; };
- 849C0D6B1B072D14008BAAA4 /* reios_elf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = reios_elf.cpp; path = reios/reios_elf.cpp; sourceTree = "<group>"; };
- 849C0D6C1B072D14008BAAA4 /* reios_elf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reios_elf.h; path = reios/reios_elf.h; sourceTree = "<group>"; };
-- 8703BC371A44B8DA00E7E939 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "emulator/assets/Icon-72.png"; sourceTree = "<group>"; };
-- 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72@2x.png"; path = "emulator/assets/Icon-72@2x.png"; sourceTree = "<group>"; };
-- 8703BC391A44B8DA00E7E939 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = emulator/assets/Icon.png; sourceTree = "<group>"; };
-- 8703BC3A1A44B8DA00E7E939 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "emulator/assets/Icon@2x.png"; sourceTree = "<group>"; };
- 87078A8318A47FE90034C7A0 /* reicast-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "reicast-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
- 87078A8618A47FE90034C7A0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- 87078A8818A47FE90034C7A0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
-@@ -316,6 +312,10 @@
- 877652C11B6157BD00437F10 /* oslib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oslib.h; sourceTree = "<group>"; };
- 877652C71B6157FC00437F10 /* ngen_arm.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = ngen_arm.S; sourceTree = "<group>"; };
- 877652C81B6157FC00437F10 /* rec_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rec_arm.cpp; sourceTree = "<group>"; };
-+ 878B0CFB1B8BB5B400A8D1C5 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = "../reicast-ios/Images.xcassets"; sourceTree = "<group>"; };
-+ 878B0CFF1B8BFE6200A8D1C5 /* disk_unknown.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = disk_unknown.png; path = emulator/Images/disk_unknown.png; sourceTree = "<group>"; };
-+ 8794D9C11B88F3D600B1B3A3 /* DiskViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DiskViewCell.h; path = emulator/DiskViewCell.h; sourceTree = "<group>"; };
-+ 8794D9C21B88F3D600B1B3A3 /* DiskViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DiskViewCell.m; path = emulator/DiskViewCell.m; sourceTree = "<group>"; };
- 87C208C51B7A4BFA00638BDD /* AboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AboutViewController.h; path = emulator/AboutViewController.h; sourceTree = "<group>"; };
- 87C208C61B7A4BFA00638BDD /* AboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AboutViewController.m; path = emulator/AboutViewController.m; sourceTree = "<group>"; };
- 87C208C71B7A4BFA00638BDD /* BrowserTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserTableViewController.h; path = emulator/BrowserTableViewController.h; sourceTree = "<group>"; };
-@@ -364,6 +364,9 @@
- 87D92F511B7A1BB100D8FD9E /* iCadeReaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iCadeReaderView.m; sourceTree = "<group>"; };
- 87D92F521B7A1BB100D8FD9E /* iCadeState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iCadeState.h; sourceTree = "<group>"; };
- 87D92F531B7A1BB100D8FD9E /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
-+ 87FA52E61B8CE18600CEFC32 /* PadViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PadViewController.h; path = emulator/PadViewController.h; sourceTree = "<group>"; };
-+ 87FA52E71B8CE18600CEFC32 /* PadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PadViewController.m; path = emulator/PadViewController.m; sourceTree = "<group>"; };
-+ 87FA52E81B8CE18600CEFC32 /* PadViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = PadViewController.xib; path = emulator/PadViewController.xib; sourceTree = "<group>"; };
- 9C7A393218C804A80070BB5F /* reicast.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = reicast.entitlements; sourceTree = "<group>"; };
- 9C7A393A18C806DE0070BB5F /* arm_coding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_coding.h; sourceTree = "<group>"; };
- 9C7A393B18C806DE0070BB5F /* arm_disasm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_disasm.h; sourceTree = "<group>"; };
-@@ -382,7 +385,6 @@
- 9C7A394818C806DE0070BB5F /* E_VLoadStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = E_VLoadStore.h; sourceTree = "<group>"; };
- 9C7A394918C806DE0070BB5F /* E_VRegXfer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = E_VRegXfer.h; sourceTree = "<group>"; };
- 9C7A394A18C806DE0070BB5F /* H_Branches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = H_Branches.h; sourceTree = "<group>"; };
-- 9C7A394B18C806DE0070BB5F /* H_fp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = H_fp.h; sourceTree = "<group>"; };
- 9C7A394C18C806DE0070BB5F /* H_LoadStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = H_LoadStore.h; sourceTree = "<group>"; };
- 9C7A394D18C806DE0070BB5F /* H_psuedo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = H_psuedo.h; sourceTree = "<group>"; };
- 9C7A394E18C806DE0070BB5F /* H_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = H_state.h; sourceTree = "<group>"; };
-@@ -722,17 +724,6 @@
- name = reios;
- sourceTree = "<group>";
- };
-- 8703BC361A44B8DA00E7E939 /* assets */ = {
-- isa = PBXGroup;
-- children = (
-- 8703BC371A44B8DA00E7E939 /* Icon-72.png */,
-- 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */,
-- 8703BC391A44B8DA00E7E939 /* Icon.png */,
-- 8703BC3A1A44B8DA00E7E939 /* Icon@2x.png */,
-- );
-- name = assets;
-- sourceTree = "<group>";
-- };
- 87078A7A18A47FE90034C7A0 = {
- isa = PBXGroup;
- children = (
-@@ -769,6 +760,7 @@
- 87078A9018A47FE90034C7A0 /* reicast */ = {
- isa = PBXGroup;
- children = (
-+ 878B0CFB1B8BB5B400A8D1C5 /* Images.xcassets */,
- 9C7A3BC318C84EA10070BB5F /* MainStoryboard.storyboard */,
- 87078A9918A47FE90034C7A0 /* AppDelegate.h */,
- 87078A9A18A47FE90034C7A0 /* AppDelegate.m */,
-@@ -790,7 +782,6 @@
- 87078A9118A47FE90034C7A0 /* Supporting Files */ = {
- isa = PBXGroup;
- children = (
-- 8703BC361A44B8DA00E7E939 /* assets */,
- 87078A9218A47FE90034C7A0 /* reicast-ios-Info.plist */,
- 87078A9618A47FE90034C7A0 /* main.m */,
- 87078A9818A47FE90034C7A0 /* reicast-ios-Prefix.pch */,
-@@ -823,6 +814,11 @@
- 9C7A393618C805F70070BB5F /* View Controller Subclasses */ = {
- isa = PBXGroup;
- children = (
-+ 87FA52E61B8CE18600CEFC32 /* PadViewController.h */,
-+ 87FA52E71B8CE18600CEFC32 /* PadViewController.m */,
-+ 87FA52E81B8CE18600CEFC32 /* PadViewController.xib */,
-+ 8794D9C11B88F3D600B1B3A3 /* DiskViewCell.h */,
-+ 8794D9C21B88F3D600B1B3A3 /* DiskViewCell.m */,
- 87C208C51B7A4BFA00638BDD /* AboutViewController.h */,
- 87C208C61B7A4BFA00638BDD /* AboutViewController.m */,
- 87C208C71B7A4BFA00638BDD /* BrowserTableViewController.h */,
-@@ -860,6 +856,7 @@
- 87D92F291B7A1B4800D8FD9E /* JoystickBackground.png */,
- 87D92F2A1B7A1B4800D8FD9E /* JoystickBackground@2x.png */,
- 87D92F2B1B7A1B4800D8FD9E /* JoystickButton.png */,
-+ 878B0CFF1B8BFE6200A8D1C5 /* disk_unknown.png */,
- 87D92F2C1B7A1B4800D8FD9E /* JoystickButton@2x.png */,
- 87D92F2D1B7A1B4800D8FD9E /* LTrigger.png */,
- 87D92F2E1B7A1B4800D8FD9E /* LTrigger@2x.png */,
-@@ -924,7 +921,6 @@
- 9C7A394818C806DE0070BB5F /* E_VLoadStore.h */,
- 9C7A394918C806DE0070BB5F /* E_VRegXfer.h */,
- 9C7A394A18C806DE0070BB5F /* H_Branches.h */,
-- 9C7A394B18C806DE0070BB5F /* H_fp.h */,
- 9C7A394C18C806DE0070BB5F /* H_LoadStore.h */,
- 9C7A394D18C806DE0070BB5F /* H_psuedo.h */,
- 9C7A394E18C806DE0070BB5F /* H_state.h */,
-@@ -1007,7 +1003,6 @@
- children = (
- 84967C731B8F492C005F1140 /* arm */,
- 84967C771B8F492C005F1140 /* config.h */,
-- 84967C781B8F492C005F1140 /* fp.h */,
- 84967C791B8F492C005F1140 /* png.c */,
- 84967C7A1B8F492C005F1140 /* png.h */,
- 84967C7B1B8F492C005F1140 /* pngconf.h */,
-@@ -1506,10 +1501,6 @@
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
-- 87DCDB251B7EE57D0054D67C /* Icon-72.png in Resources */,
-- 87DCDB261B7EE5850054D67C /* Icon-72@2x.png in Resources */,
-- 87DCDB271B7EE5850054D67C /* Icon.png in Resources */,
-- 87DCDB281B7EE5850054D67C /* Icon@2x.png in Resources */,
- 87D92F461B7A1B4800D8FD9E /* menuback@2x.png in Resources */,
- 87D92F491B7A1B4800D8FD9E /* RTrigger.png in Resources */,
- 87D92F4B1B7A1B4800D8FD9E /* Start.png in Resources */,
-@@ -1517,6 +1508,7 @@
- 87D92F391B7A1B4800D8FD9E /* 210-twitterbird.png in Resources */,
- 87D92F3A1B7A1B4800D8FD9E /* 210-twitterbird@2x.png in Resources */,
- 87D92F3D1B7A1B4800D8FD9E /* DPad.png in Resources */,
-+ 878B0CFC1B8BB5B400A8D1C5 /* Images.xcassets in Resources */,
- 87D92F3C1B7A1B4800D8FD9E /* ABXYPad@2x.png in Resources */,
- 87D92F401B7A1B4800D8FD9E /* JoystickBackground@2x.png in Resources */,
- 9C7A3AA418C806E00070BB5F /* core.mk in Resources */,
-@@ -1535,7 +1527,9 @@
- 87D92F441B7A1B4800D8FD9E /* LTrigger@2x.png in Resources */,
- 87D92F551B7A1BB100D8FD9E /* LICENSE in Resources */,
- 87D92F451B7A1B4800D8FD9E /* menuback.png in Resources */,
-+ 87FA52EA1B8CE18600CEFC32 /* PadViewController.xib in Resources */,
- 87078AA518A47FE90034C7A0 /* Shader.vsh in Resources */,
-+ 878B0D001B8BFE6200A8D1C5 /* disk_unknown.png in Resources */,
- 87D92F3B1B7A1B4800D8FD9E /* ABXYPad.png in Resources */,
- 87D92F481B7A1B4800D8FD9E /* menuicon@2x.png in Resources */,
- 87D92F371B7A1B4800D8FD9E /* 210-octocat.png in Resources */,
-@@ -1601,6 +1595,7 @@
- 9C7A3B2318C806E00070BB5F /* sh4_opcodes.cpp in Sources */,
- 84967C951B8F492C005F1140 /* pngmem.c in Sources */,
- 9C7A3ADA18C806E00070BB5F /* zip_name_locate.c in Sources */,
-+ 8794D9C31B88F3D600B1B3A3 /* DiskViewCell.m in Sources */,
- 9C7A3B1B18C806E00070BB5F /* ta_ctx.cpp in Sources */,
- 9C7A3AE018C806E00070BB5F /* zip_set_archive_flag.c in Sources */,
- 9C7A3B3518C806E00070BB5F /* cdi.cpp in Sources */,
-@@ -1635,6 +1630,7 @@
- 9C7A3B5918C81A4F0070BB5F /* SWRevealViewController.m in Sources */,
- 9C7A3B0F18C806E00070BB5F /* maple_cfg.cpp in Sources */,
- 9C7A3AF318C806E00070BB5F /* crc32.c in Sources */,
-+ 87FA52E91B8CE18600CEFC32 /* PadViewController.m in Sources */,
- 8497BCC01A41A0E900EFB9ED /* nixprof.cpp in Sources */,
- 9C7A3AE118C806E00070BB5F /* zip_set_file_comment.c in Sources */,
- 84967C9A1B8F492C005F1140 /* pngrutil.c in Sources */,
-@@ -1840,6 +1836,8 @@
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = armv7;
-+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
-+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
-@@ -1875,6 +1873,8 @@
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = armv7;
-+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
-+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
-diff -Nur a/shell/apple/reicast.xcworkspace/xcshareddata/xcschemes/reicast-ios.xcscheme b/shell/apple/reicast.xcworkspace/xcshareddata/xcschemes/reicast-ios.xcscheme
---- a/shell/apple/reicast.xcworkspace/xcshareddata/xcschemes/reicast-ios.xcscheme 2015-10-06 21:43:53.127337010 -0300
-+++ b/shell/apple/reicast.xcworkspace/xcshareddata/xcschemes/reicast-ios.xcscheme 2015-10-06 22:10:31.210968157 -0300
-@@ -62,7 +62,8 @@
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- allowLocationSimulation = "YES">
-- <BuildableProductRunnable>
-+ <BuildableProductRunnable
-+ runnableDebuggingMode = "0">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "87078A8218A47FE90034C7A0"
-@@ -80,7 +81,8 @@
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
- debugDocumentVersioning = "YES">
-- <BuildableProductRunnable>
-+ <BuildableProductRunnable
-+ runnableDebuggingMode = "0">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "87078A8218A47FE90034C7A0"
diff --git a/pcr/reicast-multilib-git/multiplayer-unstable.patch b/pcr/reicast-multilib-git/multiplayer-unstable.patch
deleted file mode 100644
index cc4e11906..000000000
--- a/pcr/reicast-multilib-git/multiplayer-unstable.patch
+++ /dev/null
@@ -1,450 +0,0 @@
-diff -Nur a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp
---- a/core/hw/maple/maple_cfg.cpp 2015-10-06 21:43:53.027336293 -0300
-+++ b/core/hw/maple/maple_cfg.cpp 2015-10-06 22:08:18.378992677 -0300
-@@ -3,6 +3,7 @@
- #include "maple_helper.h"
- #include "maple_devs.h"
- #include "maple_cfg.h"
-+#include "maple_controller.h"
-
- #define HAS_VMU
- /*
-@@ -22,11 +23,6 @@
- */
- void UpdateInputState(u32 port);
-
--extern u16 kcode[4];
--extern u32 vks[4];
--extern s8 joyx[4],joyy[4];
--extern u8 rt[4],lt[4];
--
- u8 GetBtFromSgn(s8 val)
- {
- return val+128;
-@@ -45,11 +41,11 @@
- {
- UpdateInputState(dev->bus_id);
-
-- pjs->kcode=kcode[dev->bus_id] | 0xF901;
-- pjs->joy[PJAI_X1]=GetBtFromSgn(joyx[dev->bus_id]);
-- pjs->joy[PJAI_Y1]=GetBtFromSgn(joyy[dev->bus_id]);
-- pjs->trigger[PJTI_R]=rt[dev->bus_id];
-- pjs->trigger[PJTI_L]=lt[dev->bus_id];
-+ pjs->kcode = maple_controller[dev->bus_id].buttons | 0xF901;
-+ pjs->joy[PJAI_X1] = GetBtFromSgn(maple_controller[dev->bus_id].stick_x);
-+ pjs->joy[PJAI_Y1] = GetBtFromSgn(maple_controller[dev->bus_id].stick_y);
-+ pjs->trigger[PJTI_R] = maple_controller[dev->bus_id].trigger_right;
-+ pjs->trigger[PJTI_L] = maple_controller[dev->bus_id].trigger_left;
- }
- void SetImage(void* img)
- {
-@@ -68,14 +64,19 @@
-
- void mcfg_CreateDevices()
- {
--#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
-- mcfg_Create(MDT_SegaController,0,5);
--
-- mcfg_Create(MDT_SegaVMU,0,0);
-- mcfg_Create(MDT_SegaVMU,0,1);
--#else
-- mcfg_Create(MDT_NaomiJamma, 0, 5);
--#endif
-+ for(int port = 0; port < MAPLE_NUM_PORTS; port++)
-+ {
-+ if(maple_controller[port].enabled)
-+ {
-+ #if DC_PLATFORM == DC_PLATFORM_DREAMCAST
-+ mcfg_Create(MDT_SegaController, port, 5);
-+ mcfg_Create(MDT_SegaVMU, port, 0);
-+ mcfg_Create(MDT_SegaVMU, port, 1);
-+ #else
-+ mcfg_Create(MDT_NaomiJamma, port, 5);
-+ #endif
-+ }
-+ }
- }
-
- void mcfg_DestroyDevices()
-diff -Nur a/core/hw/maple/maple_controller.cpp b/core/hw/maple/maple_controller.cpp
---- a/core/hw/maple/maple_controller.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/hw/maple/maple_controller.cpp 2015-10-06 22:08:18.378992677 -0300
-@@ -0,0 +1,8 @@
-+#include "hw/maple/maple_controller.h"
-+
-+MapleController maple_controller[MAPLE_NUM_PORTS] = {
-+ { 1 , 0xFFFF, 0, 0, 0, 0 },
-+ { 0 , 0xFFFF, 0, 0, 0, 0 },
-+ { 0 , 0xFFFF, 0, 0, 0, 0 },
-+ { 0 , 0xFFFF, 0, 0, 0, 0 }
-+};
-diff -Nur a/core/hw/maple/maple_controller.h b/core/hw/maple/maple_controller.h
---- a/core/hw/maple/maple_controller.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/hw/maple/maple_controller.h 2015-10-06 22:08:18.378992677 -0300
-@@ -0,0 +1,42 @@
-+#pragma once
-+#include "types.h"
-+
-+// If you change the value of MAPLE_NUM_PORTS, please note that you need to change the initializers in maple_controller.cpp as well
-+#define MAPLE_NUM_PORTS 4
-+
-+struct MapleController
-+{
-+ bool enabled;
-+ u16 buttons;
-+ u8 trigger_left;
-+ u8 trigger_right;
-+ s8 stick_x;
-+ s8 stick_y;
-+};
-+
-+extern MapleController maple_controller[MAPLE_NUM_PORTS];
-+
-+enum DreamcastControllerCodes
-+{
-+ DC_BTN_C = 1,
-+ DC_BTN_B = 1<<1,
-+ DC_BTN_A = 1<<2,
-+ DC_BTN_START = 1<<3,
-+ DC_BTN_DPAD_UP = 1<<4,
-+ DC_BTN_DPAD_DOWN = 1<<5,
-+ DC_BTN_DPAD_LEFT = 1<<6,
-+ DC_BTN_DPAD_RIGHT = 1<<7,
-+ DC_BTN_Z = 1<<8,
-+ DC_BTN_Y = 1<<9,
-+ DC_BTN_X = 1<<10,
-+ DC_BTN_D = 1<<11,
-+ DC_BTN_DPAD2_UP = 1<<12,
-+ DC_BTN_DPAD2_DOWN = 1<<13,
-+ DC_BTN_DPAD2_LEFT = 1<<14,
-+ DC_BTN_DPAD2_RIGHT = 1<<15,
-+
-+ DC_AXIS_LT = 0X10000,
-+ DC_AXIS_RT = 0X10001,
-+ DC_AXIS_X = 0X20000,
-+ DC_AXIS_Y = 0X20001
-+};
-diff -Nur a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp
---- a/core/linux-dist/x11.cpp 2015-10-06 22:04:14.520204440 -0300
-+++ b/core/linux-dist/x11.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -82,11 +82,11 @@
- int dc_key = x11_keymap[e.xkey.keycode];
- if (e.type == KeyPress)
- {
-- kcode[0] &= ~dc_key;
-+ maple_controller[0].buttons &= ~dc_key;
- }
- else
- {
-- kcode[0] |= dc_key;
-+ maple_controller[0].buttons |= dc_key;
- }
- }
- //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons );
-diff -Nur a/core/nacl/nacl.cpp b/core/nacl/nacl.cpp
---- a/core/nacl/nacl.cpp 2015-10-06 22:07:39.028703879 -0300
-+++ b/core/nacl/nacl.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -15,6 +15,7 @@
- #include "ppapi/utility/completion_callback_factory.h"
-
- #include "types.h"
-+#include "hw/maple/maple_controller.h"
-
- #include <GLES2/gl2.h>
-
-@@ -234,12 +235,6 @@
- }
- } // namespace pp
-
--
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- int get_mic_data(u8* buffer) { return 0; }
- int push_vmu_screen(u8* buffer) { return 0; }
-
-diff -Nur a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp
---- a/core/rend/gles/gles.cpp 2015-10-06 22:07:39.029703886 -0300
-+++ b/core/rend/gles/gles.cpp 2015-10-06 22:08:18.382992707 -0300
-@@ -1833,7 +1810,7 @@
- }
-
- bool do_swp=false;
-- //if (kcode[0]&(1<<9))
-+ //if (maple_controller[0].buttons&(1<<9))
- {
-
-
-diff -Nur a/core/windows/winmain.cpp b/core/windows/winmain.cpp
---- a/core/windows/winmain.cpp 2015-10-06 22:07:39.030703893 -0300
-+++ b/core/windows/winmain.cpp 2015-10-06 22:08:18.383992714 -0300
-@@ -1,5 +1,6 @@
- #include "oslib\oslib.h"
- #include "oslib\audiostream.h"
-+#include "hw\maple\maple_controller.h"
- #include "imgread\common.h"
-
- #define _WIN32_WINNT 0x0500
-@@ -173,66 +174,46 @@
- return MessageBox(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
- }
-
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--#define key_CONT_C (1 << 0)
--#define key_CONT_B (1 << 1)
--#define key_CONT_A (1 << 2)
--#define key_CONT_START (1 << 3)
--#define key_CONT_DPAD_UP (1 << 4)
--#define key_CONT_DPAD_DOWN (1 << 5)
--#define key_CONT_DPAD_LEFT (1 << 6)
--#define key_CONT_DPAD_RIGHT (1 << 7)
--#define key_CONT_Z (1 << 8)
--#define key_CONT_Y (1 << 9)
--#define key_CONT_X (1 << 10)
--#define key_CONT_D (1 << 11)
--#define key_CONT_DPAD2_UP (1 << 12)
--#define key_CONT_DPAD2_DOWN (1 << 13)
--#define key_CONT_DPAD2_LEFT (1 << 14)
--#define key_CONT_DPAD2_RIGHT (1 << 15)
- void UpdateInputState(u32 port)
- {
-- //joyx[port]=pad.Lx;
-- //joyy[port]=pad.Ly;
-- lt[port]=GetAsyncKeyState('A')?255:0;
-- rt[port]=GetAsyncKeyState('S')?255:0;
-+ //maple_controller[port].stick_x = pad.Lx;
-+ //maple_controller[port].stick_y = pad.Ly;
-+ maple_controller[port].trigger_left = GetAsyncKeyState('A') ? 255 : 0;
-+ maple_controller[port].trigger_right = GetAsyncKeyState('S') ? 255 : 0;
-
-- joyx[port]=joyy[port]=0;
-+ maple_controller[port].stick_x = maple_controller[port].stick_y = 0;
-
- if (GetAsyncKeyState('J'))
-- joyx[port]-=126;
-+ maple_controller[port].stick_x -= 126;
- if (GetAsyncKeyState('L'))
-- joyx[port]+=126;
-+ maple_controller[port].stick_x += 126;
-
- if (GetAsyncKeyState('I'))
-- joyy[port]-=126;
-+ maple_controller[port].stick_y -= 126;
- if (GetAsyncKeyState('K'))
-- joyy[port]+=126;
-+ maple_controller[port].stick_y += 126;
-
-- kcode[port]=0xFFFF;
-+ maple_controller[port].buttons = 0xFFFF;
- if (GetAsyncKeyState('V'))
-- kcode[port]&=~key_CONT_A;
-+ maple_controller[port].buttons &= ~DC_BTN_A;
- if (GetAsyncKeyState('C'))
-- kcode[port]&=~key_CONT_B;
-+ maple_controller[port].buttons &= ~DC_BTN_B;
- if (GetAsyncKeyState('X'))
-- kcode[port]&=~key_CONT_Y;
-+ maple_controller[port].buttons &= ~DC_BTN_Y;
- if (GetAsyncKeyState('Z'))
-- kcode[port]&=~key_CONT_X;
-+ maple_controller[port].buttons &= ~DC_BTN_X;
-
- if (GetAsyncKeyState(VK_SHIFT))
-- kcode[port]&=~key_CONT_START;
-+ maple_controller[port].buttons &= ~DC_BTN_START;
-
- if (GetAsyncKeyState(VK_UP))
-- kcode[port]&=~key_CONT_DPAD_UP;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_UP;
- if (GetAsyncKeyState(VK_DOWN))
-- kcode[port]&=~key_CONT_DPAD_DOWN;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_DOWN;
- if (GetAsyncKeyState(VK_LEFT))
-- kcode[port]&=~key_CONT_DPAD_LEFT;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_LEFT;
- if (GetAsyncKeyState(VK_RIGHT))
-- kcode[port]&=~key_CONT_DPAD_RIGHT;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_RIGHT;
-
- if (GetAsyncKeyState(VK_F1))
- settings.pvr.ta_skip = 100;
-diff -Nur a/shell/android/jni/src/Android.cpp b/shell/android/jni/src/Android.cpp
---- a/shell/android/jni/src/Android.cpp 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/android/jni/src/Android.cpp 2015-10-06 22:08:18.383992714 -0300
-@@ -16,6 +16,7 @@
- #include "rend/TexCache.h"
- #include "hw/maple/maple_devs.h"
- #include "hw/maple/maple_if.h"
-+#include "hw/maple/maple_controller.h"
- #include "oslib/audiobackend_android.h"
-
- #include "util.h"
-@@ -175,10 +176,6 @@
- // Additonal controllers 2, 3 and 4 connected ?
- static bool add_controllers[3] = { false, false, false };
-
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
- float vjoy_pos[14][8];
-
- extern bool print_stats;
-@@ -211,7 +208,7 @@
- }
-
- // Add additonal controllers
-- for (int i = 0; i < 3; i++)
-+ for (int i = 0; i < (MAPLE_NUM_PORTS - 1); i++)
- {
- if (add_controllers[i])
- mcfg_Create(MDT_SegaController,i+1,5);
-@@ -443,13 +440,13 @@
- jint *jx_body = env->GetIntArrayElements(jx, 0);
- jint *jy_body = env->GetIntArrayElements(jy, 0);
-
-- for(int i = 0; i < 4; i++)
-+ for(int i = 0; i < MAPLE_NUM_PORTS; i++)
- {
-- kcode[i] = k_code_body[i];
-- lt[i] = l_t_body[i];
-- rt[i] = r_t_body[i];
-- joyx[i] = jx_body[i];
-- joyy[i] = jy_body[i];
-+ maple_controller[i].buttons = k_code_body[i];
-+ maple_controller[i].trigger_left = l_t_body[i];
-+ maple_controller[i].trigger_right = r_t_body[i];
-+ maple_controller[i].stick_x = jx_body[i];
-+ maple_controller[i].stick_y = jy_body[i];
- }
-
- env->ReleaseIntArrayElements(k_code, k_code_body, 0);
-diff -Nur a/shell/apple/emulator-ios/emulator/ios_main.mm b/shell/apple/emulator-ios/emulator/ios_main.mm
---- a/shell/apple/emulator-ios/emulator/ios_main.mm 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/apple/emulator-ios/emulator/ios_main.mm 2015-10-06 22:08:18.383992714 -0300
-@@ -20,6 +20,7 @@
- #include <sys/mman.h>
- #include <sys/time.h>
- #include "hw/sh4/dyna/blockmanager.h"
-+#include "hw/maple/maple_controller.h"
- #include <unistd.h>
-
-
-@@ -55,11 +56,6 @@
- int dc_init(int argc,wchar* argv[]);
- void dc_run();
-
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- extern "C" int reicast_main(int argc, wchar* argv[])
- {
- //if (argc==2)
-diff -Nur a/shell/apple/emulator-osx/emulator-osx/osx-main.mm b/shell/apple/emulator-osx/emulator-osx/osx-main.mm
---- a/shell/apple/emulator-osx/emulator-osx/osx-main.mm 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/apple/emulator-osx/emulator-osx/osx-main.mm 2015-10-06 22:08:18.383992714 -0300
-@@ -8,6 +8,7 @@
- #import <Carbon/Carbon.h>
-
- #include "types.h"
-+#include "hw/maple/maple_controller.h"
- #include <sys/stat.h>
-
- #include <OpenGL/gl3.h>
-@@ -38,11 +39,6 @@
- return 0;
- }
-
--u16 kcode[4] = { 0xFFFF };
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- int get_mic_data(u8* buffer) { return 0; }
- int push_vmu_screen(u8* buffer) { return 0; }
-
-@@ -131,35 +127,11 @@
- gles_init();
- }
-
--enum DCPad {
-- Btn_C = 1,
-- Btn_B = 1<<1,
-- Btn_A = 1<<2,
-- Btn_Start = 1<<3,
-- DPad_Up = 1<<4,
-- DPad_Down = 1<<5,
-- DPad_Left = 1<<6,
-- DPad_Right = 1<<7,
-- Btn_Z = 1<<8,
-- Btn_Y = 1<<9,
-- Btn_X = 1<<10,
-- Btn_D = 1<<11,
-- DPad2_Up = 1<<12,
-- DPad2_Down = 1<<13,
-- DPad2_Left = 1<<14,
-- DPad2_Right = 1<<15,
--
-- Axis_LT= 0x10000,
-- Axis_RT= 0x10001,
-- Axis_X= 0x20000,
-- Axis_Y= 0x20001,
--};
--
- void handle_key(int dckey, int state) {
- if (state)
-- kcode[0] &= ~dckey;
-+ maple_controller[0].buttons &= ~dckey;
- else
-- kcode[0] |= dckey;
-+ maple_controller[0].buttons |= dckey;
- }
-
- void handle_trig(u8* dckey, int state) {
-@@ -172,18 +144,18 @@
- extern "C" void emu_key_input(char* keyt, int state) {
- int key = keyt[0];
- switch(key) {
-- case 'z': handle_key(Btn_X, state); break;
-- case 'x': handle_key(Btn_Y, state); break;
-- case 'c': handle_key(Btn_B, state); break;
-- case 'v': handle_key(Btn_A, state); break;
-+ case 'z': handle_key(DC_BTN_X, state); break;
-+ case 'x': handle_key(DC_BTN_Y, state); break;
-+ case 'c': handle_key(DC_BTN_B, state); break;
-+ case 'v': handle_key(DC_BTN_A, state); break;
-
- case 'a': handle_trig(lt, state); break;
- case 's': handle_trig(rt, state); break;
-
-- case 'j': handle_key(DPad_Left, state); break;
-- case 'k': handle_key(DPad_Down, state); break;
-- case 'l': handle_key(DPad_Right, state); break;
-- case 'i': handle_key(DPad_Up, state); break;
-- case 0xa: handle_key(Btn_Start, state); break;
-+ case 'j': handle_key(DC_BTN_DPAD_LEFT, state); break;
-+ case 'k': handle_key(DC_BTN_DPAD_DOWN, state); break;
-+ case 'l': handle_key(DC_BTN_DPAD_RIGHT, state); break;
-+ case 'i': handle_key(DC_BTN_DPAD_UP, state); break;
-+ case 0xa: handle_key(DC_BTN_START, state); break;
- }
- }
-\ No newline at end of file
-diff -Nur a/shell/reicast.vcxproj b/shell/reicast.vcxproj
---- a/shell/reicast.vcxproj 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/reicast.vcxproj 2015-10-06 22:08:18.383992714 -0300
-@@ -92,6 +92,7 @@
- <ClCompile Include="..\core\hw\holly\sb_dma.cpp" />
- <ClCompile Include="..\core\hw\holly\sb_mem.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_cfg.cpp" />
-+ <ClCompile Include="..\core\hw\maple\maple_controller.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_devs.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_helper.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_if.cpp" />
diff --git a/pcr/reicast-multilib-git/multiplayer.patch b/pcr/reicast-multilib-git/multiplayer.patch
deleted file mode 100644
index 19ee3c869..000000000
--- a/pcr/reicast-multilib-git/multiplayer.patch
+++ /dev/null
@@ -1,1211 +0,0 @@
-diff -Nur a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp
---- a/core/hw/maple/maple_cfg.cpp 2015-10-06 21:43:53.027336293 -0300
-+++ b/core/hw/maple/maple_cfg.cpp 2015-10-06 22:08:18.378992677 -0300
-@@ -3,6 +3,7 @@
- #include "maple_helper.h"
- #include "maple_devs.h"
- #include "maple_cfg.h"
-+#include "maple_controller.h"
-
- #define HAS_VMU
- /*
-@@ -22,11 +23,6 @@
- */
- void UpdateInputState(u32 port);
-
--extern u16 kcode[4];
--extern u32 vks[4];
--extern s8 joyx[4],joyy[4];
--extern u8 rt[4],lt[4];
--
- u8 GetBtFromSgn(s8 val)
- {
- return val+128;
-@@ -45,11 +41,11 @@
- {
- UpdateInputState(dev->bus_id);
-
-- pjs->kcode=kcode[dev->bus_id] | 0xF901;
-- pjs->joy[PJAI_X1]=GetBtFromSgn(joyx[dev->bus_id]);
-- pjs->joy[PJAI_Y1]=GetBtFromSgn(joyy[dev->bus_id]);
-- pjs->trigger[PJTI_R]=rt[dev->bus_id];
-- pjs->trigger[PJTI_L]=lt[dev->bus_id];
-+ pjs->kcode = maple_controller[dev->bus_id].buttons | 0xF901;
-+ pjs->joy[PJAI_X1] = GetBtFromSgn(maple_controller[dev->bus_id].stick_x);
-+ pjs->joy[PJAI_Y1] = GetBtFromSgn(maple_controller[dev->bus_id].stick_y);
-+ pjs->trigger[PJTI_R] = maple_controller[dev->bus_id].trigger_right;
-+ pjs->trigger[PJTI_L] = maple_controller[dev->bus_id].trigger_left;
- }
- void SetImage(void* img)
- {
-@@ -68,14 +64,19 @@
-
- void mcfg_CreateDevices()
- {
--#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
-- mcfg_Create(MDT_SegaController,0,5);
--
-- mcfg_Create(MDT_SegaVMU,0,0);
-- mcfg_Create(MDT_SegaVMU,0,1);
--#else
-- mcfg_Create(MDT_NaomiJamma, 0, 5);
--#endif
-+ for(int port = 0; port < MAPLE_NUM_PORTS; port++)
-+ {
-+ if(maple_controller[port].enabled)
-+ {
-+ #if DC_PLATFORM == DC_PLATFORM_DREAMCAST
-+ mcfg_Create(MDT_SegaController, port, 5);
-+ mcfg_Create(MDT_SegaVMU, port, 0);
-+ mcfg_Create(MDT_SegaVMU, port, 1);
-+ #else
-+ mcfg_Create(MDT_NaomiJamma, port, 5);
-+ #endif
-+ }
-+ }
- }
-
- void mcfg_DestroyDevices()
-diff -Nur a/core/hw/maple/maple_controller.cpp b/core/hw/maple/maple_controller.cpp
---- a/core/hw/maple/maple_controller.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/hw/maple/maple_controller.cpp 2015-10-06 22:08:18.378992677 -0300
-@@ -0,0 +1,8 @@
-+#include "hw/maple/maple_controller.h"
-+
-+MapleController maple_controller[MAPLE_NUM_PORTS] = {
-+ { 1 , 0xFFFF, 0, 0, 0, 0 },
-+ { 0 , 0xFFFF, 0, 0, 0, 0 },
-+ { 0 , 0xFFFF, 0, 0, 0, 0 },
-+ { 0 , 0xFFFF, 0, 0, 0, 0 }
-+};
-diff -Nur a/core/hw/maple/maple_controller.h b/core/hw/maple/maple_controller.h
---- a/core/hw/maple/maple_controller.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/hw/maple/maple_controller.h 2015-10-06 22:08:18.378992677 -0300
-@@ -0,0 +1,42 @@
-+#pragma once
-+#include "types.h"
-+
-+// If you change the value of MAPLE_NUM_PORTS, please note that you need to change the initializers in maple_controller.cpp as well
-+#define MAPLE_NUM_PORTS 4
-+
-+struct MapleController
-+{
-+ bool enabled;
-+ u16 buttons;
-+ u8 trigger_left;
-+ u8 trigger_right;
-+ s8 stick_x;
-+ s8 stick_y;
-+};
-+
-+extern MapleController maple_controller[MAPLE_NUM_PORTS];
-+
-+enum DreamcastControllerCodes
-+{
-+ DC_BTN_C = 1,
-+ DC_BTN_B = 1<<1,
-+ DC_BTN_A = 1<<2,
-+ DC_BTN_START = 1<<3,
-+ DC_BTN_DPAD_UP = 1<<4,
-+ DC_BTN_DPAD_DOWN = 1<<5,
-+ DC_BTN_DPAD_LEFT = 1<<6,
-+ DC_BTN_DPAD_RIGHT = 1<<7,
-+ DC_BTN_Z = 1<<8,
-+ DC_BTN_Y = 1<<9,
-+ DC_BTN_X = 1<<10,
-+ DC_BTN_D = 1<<11,
-+ DC_BTN_DPAD2_UP = 1<<12,
-+ DC_BTN_DPAD2_DOWN = 1<<13,
-+ DC_BTN_DPAD2_LEFT = 1<<14,
-+ DC_BTN_DPAD2_RIGHT = 1<<15,
-+
-+ DC_AXIS_LT = 0X10000,
-+ DC_AXIS_RT = 0X10001,
-+ DC_AXIS_X = 0X20000,
-+ DC_AXIS_Y = 0X20001
-+};
-diff -Nur a/core/linux-dist/evdev.cpp b/core/linux-dist/evdev.cpp
---- a/core/linux-dist/evdev.cpp 2015-10-06 22:07:39.028703879 -0300
-+++ b/core/linux-dist/evdev.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -314,43 +314,43 @@
- {
- case EV_KEY:
- if (ie.code == controller->mapping->Btn_A) {
-- SET_FLAG(kcode[port], DC_BTN_A, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_A, ie.value);
- } else if (ie.code == controller->mapping->Btn_B) {
-- SET_FLAG(kcode[port], DC_BTN_B, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_B, ie.value);
- } else if (ie.code == controller->mapping->Btn_C) {
-- SET_FLAG(kcode[port], DC_BTN_C, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_C, ie.value);
- } else if (ie.code == controller->mapping->Btn_D) {
-- SET_FLAG(kcode[port], DC_BTN_D, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_D, ie.value);
- } else if (ie.code == controller->mapping->Btn_X) {
-- SET_FLAG(kcode[port], DC_BTN_X, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_X, ie.value);
- } else if (ie.code == controller->mapping->Btn_Y) {
-- SET_FLAG(kcode[port], DC_BTN_Y, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_Y, ie.value);
- } else if (ie.code == controller->mapping->Btn_Z) {
-- SET_FLAG(kcode[port], DC_BTN_Z, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_Z, ie.value);
- } else if (ie.code == controller->mapping->Btn_Start) {
-- SET_FLAG(kcode[port], DC_BTN_START, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_START, ie.value);
- } else if (ie.code == controller->mapping->Btn_Escape) {
- die("death by escape key");
- } else if (ie.code == controller->mapping->Btn_DPad_Left) {
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_LEFT, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad_Right) {
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_RIGHT, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad_Up) {
-- SET_FLAG(kcode[port], DC_DPAD_UP, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_UP, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad_Down) {
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_DOWN, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad2_Left) {
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_LEFT, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad2_Right) {
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_RIGHT, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad2_Up) {
-- SET_FLAG(kcode[port], DC_DPAD2_UP, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_UP, ie.value);
- } else if (ie.code == controller->mapping->Btn_DPad2_Down) {
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, ie.value);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_DOWN, ie.value);
- } else if (ie.code == controller->mapping->Btn_Trigger_Left) {
-- lt[port] = (ie.value ? 255 : 0);
-+ maple_controller[port].trigger_left = (ie.value ? 255 : 0);
- } else if (ie.code == controller->mapping->Btn_Trigger_Right) {
-- rt[port] = (ie.value ? 255 : 0);
-+ maple_controller[port].trigger_right = (ie.value ? 255 : 0);
- }
- break;
- case EV_ABS:
-@@ -359,16 +359,16 @@
- switch(ie.value)
- {
- case -1:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 1);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_LEFT, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_RIGHT, 0);
- break;
- case 0:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_LEFT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_RIGHT, 0);
- break;
- case 1:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_LEFT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_RIGHT, 1);
- break;
- }
- }
-@@ -377,16 +377,16 @@
- switch(ie.value)
- {
- case -1:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 1);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_UP, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_DOWN, 0);
- break;
- case 0:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_UP, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_DOWN, 0);
- break;
- case 1:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_UP, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD_DOWN, 1);
- break;
- }
- }
-@@ -395,16 +395,16 @@
- switch(ie.value)
- {
- case -1:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 1);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_LEFT, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_RIGHT, 0);
- break;
- case 0:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_LEFT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_RIGHT, 0);
- break;
- case 1:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_LEFT, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_RIGHT, 1);
- break;
- }
- }
-@@ -413,34 +413,34 @@
- switch(ie.value)
- {
- case -1:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 1);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_UP, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_DOWN, 0);
- break;
- case 0:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_UP, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_DOWN, 0);
- break;
- case 1:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 1);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_UP, 0);
-+ SET_FLAG(maple_controller[port].buttons, DC_BTN_DPAD2_DOWN, 1);
- break;
- }
- }
- else if (ie.code == controller->mapping->Axis_Analog_X)
- {
-- joyx[port] = (controller->data_x.convert(ie.value) + 128);
-+ maple_controller[port].stick_x = (controller->data_x.convert(ie.value) + 128);
- }
- else if (ie.code == controller->mapping->Axis_Analog_Y)
- {
-- joyy[port] = (controller->data_y.convert(ie.value) + 128);
-+ maple_controller[port].stick_y = (controller->data_y.convert(ie.value) + 128);
- }
- else if (ie.code == controller->mapping->Axis_Trigger_Left)
- {
-- lt[port] = controller->data_trigger_left.convert(ie.value);
-+ maple_controller[port].trigger_left = controller->data_trigger_left.convert(ie.value);
- }
- else if (ie.code == controller->mapping->Axis_Trigger_Right)
- {
-- rt[port] = controller->data_trigger_right.convert(ie.value);
-+ maple_controller[port].trigger_right = controller->data_trigger_right.convert(ie.value);
- }
- break;
- }
-diff -Nur a/core/linux-dist/joystick.cpp b/core/linux-dist/joystick.cpp
---- a/core/linux-dist/joystick.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/joystick.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -5,14 +5,14 @@
- #include "linux-dist/joystick.h"
-
- #if defined(USE_JOYSTICK)
-- const u32 joystick_map_btn_usb[JOYSTICK_MAP_SIZE] = { DC_BTN_Y, DC_BTN_B, DC_BTN_A, DC_BTN_X, 0, 0, 0, 0, 0, DC_BTN_START };
-- const u32 joystick_map_axis_usb[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, 0, 0, 0, 0, 0, 0, 0, 0 };
-+ const DreamcastControllerCodes joystick_map_btn_usb[JOYSTICK_MAP_SIZE] = { DC_BTN_Y, DC_BTN_B, DC_BTN_A, DC_BTN_X, 0, 0, 0, 0, 0, DC_BTN_START };
-+ const DreamcastControllerCodes joystick_map_axis_usb[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-- const u32 joystick_map_btn_xbox360[JOYSTICK_MAP_SIZE] = { DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, 0, 0, 0, DC_BTN_START, 0, 0 };
-- const u32 joystick_map_axis_xbox360[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, 0, 0, DC_AXIS_RT, DC_DPAD_LEFT, DC_DPAD_UP, 0, 0 };
-+ const DreamcastControllerCodes joystick_map_btn_xbox360[JOYSTICK_MAP_SIZE] = { DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, 0, 0, 0, DC_BTN_START, 0, 0 };
-+ const DreamcastControllerCodes joystick_map_axis_xbox360[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, 0, 0, DC_AXIS_RT, DC_BTN_DPAD_LEFT, DC_BTN_DPAD_UP, 0, 0 };
-
-- const u32* joystick_map_btn = joystick_map_btn_usb;
-- const u32* joystick_map_axis = joystick_map_axis_usb;
-+ const DreamcastControllerCodes* joystick_map_btn = joystick_map_btn_usb;
-+ const DreamcastControllerCodes* joystick_map_axis = joystick_map_axis_usb;
-
- int input_joystick_init(const char* device)
- {
-@@ -73,18 +73,18 @@
-
- if (mt == 0)
- {
-- kcode[port] |= mo;
-- kcode[port] |= mo*2;
-+ maple_controller[port].buttons |= mo;
-+ maple_controller[port].buttons |= mo*2;
- if (v<-64)
- {
-- kcode[port] &= ~mo;
-+ maple_controller[port].buttons &= ~mo;
- }
- else if (v>64)
- {
-- kcode[port] &= ~(mo*2);
-+ maple_controller[port].buttons &= ~(mo*2);
- }
-
-- //printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
-+ //printf("Mapped to %d %d %d\n",mo,maple_controller[port].buttons&mo,maple_controller[port].buttons&(mo*2));
- }
- else if (mt == 1)
- {
-@@ -95,11 +95,11 @@
- //printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
- if (mo == 0)
- {
-- lt[port] = (v + 127);
-+ maple_controller[port].trigger_left = (v + 127);
- }
- else if (mo == 1)
- {
-- rt[port] = (v + 127);
-+ maple_controller[port].trigger_right = (v + 127);
- }
- }
- else if (mt == 2)
-@@ -107,11 +107,11 @@
- // printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
- if (mo == 0)
- {
-- joyx[port] = v;
-+ maple_controller[port].stick_x = v;
- }
- else if (mo == 1)
- {
-- joyy[port] = v;
-+ maple_controller[port].stick_y = v;
- }
- }
- }
-@@ -129,11 +129,11 @@
- // printf("Mapped to %d\n",mo);
- if (JE.value)
- {
-- kcode[port] &= ~mo;
-+ maple_controller[port].buttons &= ~mo;
- }
- else
- {
-- kcode[port] |= mo;
-+ maple_controller[port].buttons |= mo;
- }
- }
- else if (mt == 1)
-@@ -141,11 +141,11 @@
- // printf("Mapped to %d %d\n",mo,JE.value?255:0);
- if (mo==0)
- {
-- lt[port] = JE.value ? 255 : 0;
-+ maple_controller[port].trigger_left = JE.value ? 255 : 0;
- }
- else if (mo==1)
- {
-- rt[port] = JE.value ? 255 : 0;
-+ maple_controller[port].trigger_right = JE.value ? 255 : 0;
- }
- }
- }
-diff -Nur a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp
---- a/core/linux-dist/main.cpp 2015-10-06 22:07:39.028703879 -0300
-+++ b/core/linux-dist/main.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -69,22 +69,11 @@
- return x11_disp;
- }
-
--u16 kcode[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
--u8 rt[4] = {0, 0, 0, 0};
--u8 lt[4] = {0, 0, 0, 0};
--u32 vks[4];
--s8 joyx[4], joyy[4];
--
- void emit_WriteCodeCache();
-
- #if defined(USE_EVDEV)
- /* evdev input */
-- static EvdevController evdev_controllers[4] = {
-- { -1, NULL },
-- { -1, NULL },
-- { -1, NULL },
-- { -1, NULL }
-- };
-+ static EvdevController evdev_controllers[MAPLE_NUM_PORTS];
- #endif
-
- #if defined(USE_JOYSTICK)
-@@ -95,14 +84,17 @@
- void SetupInput()
- {
- #if defined(USE_EVDEV)
-- int evdev_device_id[4] = { -1, -1, -1, -1 };
-+ int evdev_device_id[MAPLE_NUM_PORTS];
- size_t size_needed;
- int port, i;
-
- char* evdev_device;
-
-- for (port = 0; port < 4; port++)
-+ for (port = 0; port < MAPLE_NUM_PORTS; port++)
- {
-+ evdev_controllers[port] = { -1, NULL };
-+ evdev_device_id[port] = -1;
-+
- size_needed = snprintf(NULL, 0, EVDEV_DEVICE_CONFIG_KEY, port+1) + 1;
- char* evdev_config_key = (char*)malloc(size_needed);
- sprintf(evdev_config_key, EVDEV_DEVICE_CONFIG_KEY, port+1);
-@@ -135,6 +127,7 @@
- free(evdev_config_key);
-
- input_evdev_init(&evdev_controllers[port], evdev_device, mapping);
-+ maple_controller[port].enabled = true;
-
- free(evdev_device);
- }
-diff -Nur a/core/linux-dist/main.h b/core/linux-dist/main.h
---- a/core/linux-dist/main.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/main.h 2015-10-06 22:08:18.381992699 -0300
-@@ -1,35 +1,6 @@
- #pragma once
- #include "types.h"
--
--extern u16 kcode[4];
--extern u32 vks[4];
--extern u8 rt[4], lt[4];
--extern s8 joyx[4], joyy[4];
-+#include "hw/maple/maple_controller.h"
-
- extern void* x11_win;
- extern void* x11_disp;
--
--enum DreamcastController
--{
-- DC_BTN_C = 1,
-- DC_BTN_B = 1<<1,
-- DC_BTN_A = 1<<2,
-- DC_BTN_START = 1<<3,
-- DC_DPAD_UP = 1<<4,
-- DC_DPAD_DOWN = 1<<5,
-- DC_DPAD_LEFT = 1<<6,
-- DC_DPAD_RIGHT = 1<<7,
-- DC_BTN_Z = 1<<8,
-- DC_BTN_Y = 1<<9,
-- DC_BTN_X = 1<<10,
-- DC_BTN_D = 1<<11,
-- DC_DPAD2_UP = 1<<12,
-- DC_DPAD2_DOWN = 1<<13,
-- DC_DPAD2_LEFT = 1<<14,
-- DC_DPAD2_RIGHT = 1<<15,
--
-- DC_AXIS_LT = 0X10000,
-- DC_AXIS_RT = 0X10001,
-- DC_AXIS_X = 0X20000,
-- DC_AXIS_Y = 0X20001,
--};
-diff -Nur a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp
---- a/core/linux-dist/x11.cpp 2015-10-06 22:04:14.520204440 -0300
-+++ b/core/linux-dist/x11.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -82,11 +82,11 @@
- int dc_key = x11_keymap[e.xkey.keycode];
- if (e.type == KeyPress)
- {
-- kcode[0] &= ~dc_key;
-+ maple_controller[0].buttons &= ~dc_key;
- }
- else
- {
-- kcode[0] |= dc_key;
-+ maple_controller[0].buttons |= dc_key;
- }
- }
- //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons );
-@@ -98,11 +98,11 @@
-
- void input_x11_init()
- {
-- x11_keymap[113] = DC_DPAD_LEFT;
-- x11_keymap[114] = DC_DPAD_RIGHT;
-+ x11_keymap[113] = DC_BTN_DPAD_LEFT;
-+ x11_keymap[114] = DC_BTN_DPAD_RIGHT;
-
-- x11_keymap[111] = DC_DPAD_UP;
-- x11_keymap[116] = DC_DPAD_DOWN;
-+ x11_keymap[111] = DC_BTN_DPAD_UP;
-+ x11_keymap[116] = DC_BTN_DPAD_DOWN;
-
- x11_keymap[53] = DC_BTN_X;
- x11_keymap[54] = DC_BTN_B;
-diff -Nur a/core/nacl/nacl.cpp b/core/nacl/nacl.cpp
---- a/core/nacl/nacl.cpp 2015-10-06 22:07:39.028703879 -0300
-+++ b/core/nacl/nacl.cpp 2015-10-06 22:08:18.381992699 -0300
-@@ -15,6 +15,7 @@
- #include "ppapi/utility/completion_callback_factory.h"
-
- #include "types.h"
-+#include "hw/maple/maple_controller.h"
-
- #include <GLES2/gl2.h>
-
-@@ -234,12 +235,6 @@
- }
- } // namespace pp
-
--
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- int get_mic_data(u8* buffer) { return 0; }
- int push_vmu_screen(u8* buffer) { return 0; }
-
-diff -Nur a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp
---- a/core/rend/gles/gles.cpp 2015-10-06 22:07:39.029703886 -0300
-+++ b/core/rend/gles/gles.cpp 2015-10-06 22:08:18.382992707 -0300
-@@ -2,6 +2,7 @@
- #include "gles.h"
- #include "rend/TexCache.h"
- #include "cfg/cfg.h"
-+#include "hw/maple/maple_controller.h"
-
- #ifdef TARGET_PANDORA
- #include <unistd.h>
-@@ -1043,28 +1044,6 @@
- //printf("%f\n",B*log(maxdev)/log(2.0)+A);
- }
-
--
--
--extern u16 kcode[4];
--extern u8 rt[4],lt[4];
--
--#define key_CONT_C (1 << 0)
--#define key_CONT_B (1 << 1)
--#define key_CONT_A (1 << 2)
--#define key_CONT_START (1 << 3)
--#define key_CONT_DPAD_UP (1 << 4)
--#define key_CONT_DPAD_DOWN (1 << 5)
--#define key_CONT_DPAD_LEFT (1 << 6)
--#define key_CONT_DPAD_RIGHT (1 << 7)
--#define key_CONT_Z (1 << 8)
--#define key_CONT_Y (1 << 9)
--#define key_CONT_X (1 << 10)
--#define key_CONT_D (1 << 11)
--#define key_CONT_DPAD2_UP (1 << 12)
--#define key_CONT_DPAD2_DOWN (1 << 13)
--#define key_CONT_DPAD2_LEFT (1 << 14)
--#define key_CONT_DPAD2_RIGHT (1 << 15)
--
- u32 osd_base;
- u32 osd_count;
-
-@@ -1260,21 +1239,21 @@
- osd_count=0;
-
- #ifndef TARGET_PANDORA
-- DrawButton2(vjoy_pos[0],kcode[0]&key_CONT_DPAD_LEFT);
-- DrawButton2(vjoy_pos[1],kcode[0]&key_CONT_DPAD_UP);
-- DrawButton2(vjoy_pos[2],kcode[0]&key_CONT_DPAD_RIGHT);
-- DrawButton2(vjoy_pos[3],kcode[0]&key_CONT_DPAD_DOWN);
-+ DrawButton2(vjoy_pos[0], maple_controller[0].buttons & DC_BTN_DPAD_LEFT);
-+ DrawButton2(vjoy_pos[1], maple_controller[0].buttons & DC_BTN_DPAD_UP);
-+ DrawButton2(vjoy_pos[2], maple_controller[0].buttons & DC_BTN_DPAD_RIGHT);
-+ DrawButton2(vjoy_pos[3], maple_controller[0].buttons & DC_BTN_DPAD_DOWN);
-
-- DrawButton2(vjoy_pos[4],kcode[0]&key_CONT_X);
-- DrawButton2(vjoy_pos[5],kcode[0]&key_CONT_Y);
-- DrawButton2(vjoy_pos[6],kcode[0]&key_CONT_B);
-- DrawButton2(vjoy_pos[7],kcode[0]&key_CONT_A);
-+ DrawButton2(vjoy_pos[4], maple_controller[0].buttons & DC_BTN_X);
-+ DrawButton2(vjoy_pos[5], maple_controller[0].buttons & DC_BTN_Y);
-+ DrawButton2(vjoy_pos[6], maple_controller[0].buttons & DC_BTN_B);
-+ DrawButton2(vjoy_pos[7], maple_controller[0].buttons & DC_BTN_A);
-
-- DrawButton2(vjoy_pos[8],kcode[0]&key_CONT_START);
-+ DrawButton2(vjoy_pos[8], maple_controller[0].buttons & DC_BTN_START);
-
-- DrawButton(vjoy_pos[9],lt[0]);
-+ DrawButton(vjoy_pos[9], maple_controller[0].trigger_left);
-
-- DrawButton(vjoy_pos[10],rt[0]);
-+ DrawButton(vjoy_pos[10], maple_controller[0].trigger_right);
-
- DrawButton2(vjoy_pos[11],1);
- DrawButton2(vjoy_pos[12],0);
-@@ -1818,8 +1797,6 @@
- #endif
- #endif
-
--extern u16 kcode[4];
--
- /*
- bool rend_single_frame()
- {
-@@ -1833,7 +1810,7 @@
- }
-
- bool do_swp=false;
-- //if (kcode[0]&(1<<9))
-+ //if (maple_controller[0].buttons&(1<<9))
- {
-
-
-diff -Nur a/core/sdl/main.cpp b/core/sdl/main.cpp
---- a/core/sdl/main.cpp 2015-10-06 22:07:39.029703886 -0300
-+++ b/core/sdl/main.cpp 2015-10-06 22:08:18.382992707 -0300
-@@ -21,6 +21,7 @@
- #include <execinfo.h>
-
- #include "hw/mem/_vmem.h"
-+#include "hw/maple/maple_controller.h"
-
- #ifdef TARGET_PANDORA
- #define WINDOW_WIDTH 800
-@@ -56,42 +57,10 @@
- return MBX_OK;
- }
-
--
--
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- extern bool KillTex;
-
- extern void dc_term();
-
--enum DCPad {
-- Btn_C = 1,
-- Btn_B = 1<<1,
-- Btn_A = 1<<2,
-- Btn_Start = 1<<3,
-- DPad_Up = 1<<4,
-- DPad_Down = 1<<5,
-- DPad_Left = 1<<6,
-- DPad_Right = 1<<7,
-- Btn_Z = 1<<8,
-- Btn_Y = 1<<9,
-- Btn_X = 1<<10,
-- Btn_D = 1<<11,
-- DPad2_Up = 1<<12,
-- DPad2_Down = 1<<13,
-- DPad2_Left = 1<<14,
-- DPad2_Right = 1<<15,
--
-- Axis_LT= 0x10000,
-- Axis_RT= 0x10001,
-- Axis_X= 0x20000,
-- Axis_Y= 0x20001,
--};
--
--
- void emit_WriteCodeCache();
-
- static SDL_Joystick *JoySDL = 0;
-@@ -100,33 +69,26 @@
-
- #define MAP_SIZE 32
-
--const u32 JMapBtn_USB[MAP_SIZE] =
-- { Btn_Y,Btn_B,Btn_A,Btn_X,0,0,0,0,0,Btn_Start };
-+const DreamcastControllerCodes JMapBtn_USB[MAP_SIZE] =
-+ { DC_BTN_Y, DC_BTN_B, DC_BTN_A, DC_BTN_X, 0, 0, 0, 0, 0, DC_BTN_START };
-
--const u32 JMapAxis_USB[MAP_SIZE] =
-- { Axis_X,Axis_Y,0,0,0,0,0,0,0,0 };
-+const DreamcastControllerCodes JMapAxis_USB[MAP_SIZE] =
-+ { DC_AXIS_X, DC_AXIS_Y, 0 ,0, 0, 0, 0, 0, 0, 0 };
-
--const u32 JMapBtn_360[MAP_SIZE] =
-- { Btn_A,Btn_B,Btn_X,Btn_Y,0,0,0,Btn_Start,0,0 };
-+const DreamcastControllerCodes JMapBtn_360[MAP_SIZE] =
-+ { DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, 0, 0, 0, DC_BTN_START, 0, 0 };
-
--const u32 JMapAxis_360[MAP_SIZE] =
-- { Axis_X,Axis_Y,Axis_LT,0,0,Axis_RT,DPad_Left,DPad_Up,0,0 };
-+const DreamcastControllerCodes JMapAxis_360[MAP_SIZE] =
-+ { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, 0, 0, DC_AXIS_RT, DC_BTN_DPAD_LEFT, DC_BTN_DPAD_UP, 0, 0 };
-
--const u32* JMapBtn=JMapBtn_USB;
--const u32* JMapAxis=JMapAxis_USB;
-+const DreamcastControllerCodes* JMapBtn = JMapBtn_USB;
-+const DreamcastControllerCodes* JMapAxis = JMapAxis_USB;
- #ifdef TARGET_PANDORA
- u32 JSensitivity[256]; // To have less sensitive value on nubs
- #endif
-
- void SetupInput()
- {
-- for (int port=0;port<4;port++)
-- {
-- kcode[port]=0xFFFF;
-- rt[port]=0;
-- lt[port]=0;
-- }
--
- // Open joystick device
- int numjoys = SDL_NumJoysticks();
- printf("Number of Joysticks found = %i\n", numjoys);
-@@ -236,17 +198,17 @@
- {
- // printf("Mapped to %d\n",mo);
- if (value)
-- kcode[port]&=~mo;
-+ maple_controller[port].buttons &= ~mo;
- else
-- kcode[port]|=mo;
-+ maple_controller[port].buttons |= mo;
- }
- else if (mt==1)
- {
- // printf("Mapped to %d %d\n",mo,JE.value?255:0);
- if (mo==0)
-- lt[port]=value?255:0;
-+ maple_controller[port].trigger_left = value ? 255 : 0;
- else if (mo==1)
-- rt[port]=value?255:0;
-+ maple_controller[port].trigger_right = value ? 255 : 0;
- }
-
- }
-@@ -266,18 +228,18 @@
-
- if (mt==0)
- {
-- kcode[port]|=mo;
-- kcode[port]|=mo*2;
-+ maple_controller[port].buttons |= mo;
-+ maple_controller[port].buttons |= mo*2;
- if (v<-64)
- {
-- kcode[port]&=~mo;
-+ maple_controller[port].buttons &= ~mo;
- }
- else if (v>64)
- {
-- kcode[port]&=~(mo*2);
-+ maple_controller[port].buttons &= ~(mo*2);
- }
-
-- // printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
-+ // printf("Mapped to %d %d %d\n",mo,maple_controller[port].buttons&mo,maple_controller[port].buttons&(mo*2));
- }
- else if (mt==1)
- {
-@@ -286,17 +248,17 @@
- // printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
-
- if (mo==0)
-- lt[port]=v+127;
-+ maple_controller[port].trigger_left = v+127;
- else if (mo==1)
-- rt[port]=v+127;
-+ maple_controller[port].trigger_right = v+127;
- }
- else if (mt==2)
- {
- // printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
- if (mo==0)
-- joyx[port]=v;
-+ maple_controller[port].stick_x = v;
- else if (mo==1)
-- joyy[port]=v;
-+ maple_controller[port].stick_y = v;
- }
- }
- break;
-@@ -314,18 +276,18 @@
- case 0: // nothing
- break;
- case 1: // Up=RT, Down=LT
-- if (yy<0) rt[port]=-yy;
-- if (yy>0) lt[port]=yy;
-+ if (yy<0) maple_controller[port].trigger_right = -yy;
-+ if (yy>0) maple_controller[port].trigger_left = yy;
- break;
- case 2: // Left=LT, Right=RT
-- if (xx<0) lt[port]=-xx;
-- if (xx>0) rt[port]=xx;
-+ if (xx<0) maple_controller[port].trigger_left = -xx;
-+ if (xx>0) maple_controller[port].trigger_right = xx;
- break;
- case 3: // Nub = ABXY
-- if (xx<-127) kcode[port] &= ~Btn_X;
-- if (xx>127) kcode[port] &= ~Btn_B;
-- if (yy<-127) kcode[port] &= ~Btn_Y;
-- if (yy>127) kcode[port] &= ~Btn_A;
-+ if (xx<-127) maple_controller[port].buttons &= ~DC_BTN_X;
-+ if (xx>127) maple_controller[port].buttons &= ~DC_BTN_B;
-+ if (yy<-127) maple_controller[port].buttons &= ~DC_BTN_Y;
-+ if (yy>127) maple_controller[port].buttons &= ~DC_BTN_A;
- break;
- }
- break;
-@@ -333,16 +295,16 @@
-
- }
-
-- if (keys[0]) { kcode[port] &= ~Btn_C; }
-- if (keys[6]) { kcode[port] &= ~Btn_A; }
-- if (keys[7]) { kcode[port] &= ~Btn_B; }
-- if (keys[5]) { kcode[port] &= ~Btn_Y; }
-- if (keys[8]) { kcode[port] &= ~Btn_X; }
-- if (keys[1]) { kcode[port] &= ~DPad_Up; }
-- if (keys[2]) { kcode[port] &= ~DPad_Down; }
-- if (keys[3]) { kcode[port] &= ~DPad_Left; }
-- if (keys[4]) { kcode[port] &= ~DPad_Right; }
-- if (keys[12]){ kcode[port] &= ~Btn_Start; }
-+ if (keys[0]) { maple_controller[port].buttons &= ~DC_BTN_C; }
-+ if (keys[6]) { maple_controller[port].buttons &= ~DC_BTN_A; }
-+ if (keys[7]) { maple_controller[port].buttons &= ~DC_BTN_B; }
-+ if (keys[5]) { maple_controller[port].buttons &= ~DC_BTN_Y; }
-+ if (keys[8]) { maple_controller[port].buttons &= ~DC_BTN_X; }
-+ if (keys[1]) { maple_controller[port].buttons &= ~DC_BTN_DPAD_UP; }
-+ if (keys[2]) { maple_controller[port].buttons &= ~DC_BTN_DPAD_DOWN; }
-+ if (keys[3]) { maple_controller[port].buttons &= ~DC_BTN_DPAD_LEFT; }
-+ if (keys[4]) { maple_controller[port].buttons &= ~DC_BTN_DPAD_RIGHT; }
-+ if (keys[12]){ maple_controller[port].buttons &= ~DC_BTN_START; }
- if (keys[9]){
- //die("death by escape key");
- //printf("death by escape key\n");
-@@ -352,8 +314,8 @@
- // is there a proper way to exit? dc_term() doesn't end the dc_run() loop it seems
- die("death by escape key");
- }
-- if (keys[10]) rt[port]=255;
-- if (keys[11]) lt[port]=255;
-+ if (keys[10]) maple_controller[port].trigger_right=255;
-+ if (keys[11]) maple_controller[port].trigger_left=255;
-
- return true;
- }
-@@ -362,9 +324,9 @@
- {
- static char key = 0;
-
-- kcode[port]=0xFFFF;
-- rt[port]=0;
-- lt[port]=0;
-+ maple_controller[port].buttons=0xFFFF;
-+ maple_controller[port].trigger_right=0;
-+ maple_controller[port].trigger_left=0;
-
- HandleEvents(port);
- }
-diff -Nur a/core/windows/winmain.cpp b/core/windows/winmain.cpp
---- a/core/windows/winmain.cpp 2015-10-06 22:07:39.030703893 -0300
-+++ b/core/windows/winmain.cpp 2015-10-06 22:08:18.383992714 -0300
-@@ -1,5 +1,6 @@
- #include "oslib\oslib.h"
- #include "oslib\audiostream.h"
-+#include "hw\maple\maple_controller.h"
- #include "imgread\common.h"
-
- #define _WIN32_WINNT 0x0500
-@@ -173,66 +174,46 @@
- return MessageBox(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
- }
-
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--#define key_CONT_C (1 << 0)
--#define key_CONT_B (1 << 1)
--#define key_CONT_A (1 << 2)
--#define key_CONT_START (1 << 3)
--#define key_CONT_DPAD_UP (1 << 4)
--#define key_CONT_DPAD_DOWN (1 << 5)
--#define key_CONT_DPAD_LEFT (1 << 6)
--#define key_CONT_DPAD_RIGHT (1 << 7)
--#define key_CONT_Z (1 << 8)
--#define key_CONT_Y (1 << 9)
--#define key_CONT_X (1 << 10)
--#define key_CONT_D (1 << 11)
--#define key_CONT_DPAD2_UP (1 << 12)
--#define key_CONT_DPAD2_DOWN (1 << 13)
--#define key_CONT_DPAD2_LEFT (1 << 14)
--#define key_CONT_DPAD2_RIGHT (1 << 15)
- void UpdateInputState(u32 port)
- {
-- //joyx[port]=pad.Lx;
-- //joyy[port]=pad.Ly;
-- lt[port]=GetAsyncKeyState('A')?255:0;
-- rt[port]=GetAsyncKeyState('S')?255:0;
-+ //maple_controller[port].stick_x = pad.Lx;
-+ //maple_controller[port].stick_y = pad.Ly;
-+ maple_controller[port].trigger_left = GetAsyncKeyState('A') ? 255 : 0;
-+ maple_controller[port].trigger_right = GetAsyncKeyState('S') ? 255 : 0;
-
-- joyx[port]=joyy[port]=0;
-+ maple_controller[port].stick_x = maple_controller[port].stick_y = 0;
-
- if (GetAsyncKeyState('J'))
-- joyx[port]-=126;
-+ maple_controller[port].stick_x -= 126;
- if (GetAsyncKeyState('L'))
-- joyx[port]+=126;
-+ maple_controller[port].stick_x += 126;
-
- if (GetAsyncKeyState('I'))
-- joyy[port]-=126;
-+ maple_controller[port].stick_y -= 126;
- if (GetAsyncKeyState('K'))
-- joyy[port]+=126;
-+ maple_controller[port].stick_y += 126;
-
-- kcode[port]=0xFFFF;
-+ maple_controller[port].buttons = 0xFFFF;
- if (GetAsyncKeyState('V'))
-- kcode[port]&=~key_CONT_A;
-+ maple_controller[port].buttons &= ~DC_BTN_A;
- if (GetAsyncKeyState('C'))
-- kcode[port]&=~key_CONT_B;
-+ maple_controller[port].buttons &= ~DC_BTN_B;
- if (GetAsyncKeyState('X'))
-- kcode[port]&=~key_CONT_Y;
-+ maple_controller[port].buttons &= ~DC_BTN_Y;
- if (GetAsyncKeyState('Z'))
-- kcode[port]&=~key_CONT_X;
-+ maple_controller[port].buttons &= ~DC_BTN_X;
-
- if (GetAsyncKeyState(VK_SHIFT))
-- kcode[port]&=~key_CONT_START;
-+ maple_controller[port].buttons &= ~DC_BTN_START;
-
- if (GetAsyncKeyState(VK_UP))
-- kcode[port]&=~key_CONT_DPAD_UP;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_UP;
- if (GetAsyncKeyState(VK_DOWN))
-- kcode[port]&=~key_CONT_DPAD_DOWN;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_DOWN;
- if (GetAsyncKeyState(VK_LEFT))
-- kcode[port]&=~key_CONT_DPAD_LEFT;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_LEFT;
- if (GetAsyncKeyState(VK_RIGHT))
-- kcode[port]&=~key_CONT_DPAD_RIGHT;
-+ maple_controller[port].buttons &= ~DC_BTN_DPAD_RIGHT;
-
- if (GetAsyncKeyState(VK_F1))
- settings.pvr.ta_skip = 100;
-diff -Nur a/shell/android/jni/src/Android.cpp b/shell/android/jni/src/Android.cpp
---- a/shell/android/jni/src/Android.cpp 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/android/jni/src/Android.cpp 2015-10-06 22:08:18.383992714 -0300
-@@ -16,6 +16,7 @@
- #include "rend/TexCache.h"
- #include "hw/maple/maple_devs.h"
- #include "hw/maple/maple_if.h"
-+#include "hw/maple/maple_controller.h"
- #include "oslib/audiobackend_android.h"
-
- #include "util.h"
-@@ -175,10 +176,6 @@
- // Additonal controllers 2, 3 and 4 connected ?
- static bool add_controllers[3] = { false, false, false };
-
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
- float vjoy_pos[14][8];
-
- extern bool print_stats;
-@@ -211,7 +208,7 @@
- }
-
- // Add additonal controllers
-- for (int i = 0; i < 3; i++)
-+ for (int i = 0; i < (MAPLE_NUM_PORTS - 1); i++)
- {
- if (add_controllers[i])
- mcfg_Create(MDT_SegaController,i+1,5);
-@@ -443,13 +440,13 @@
- jint *jx_body = env->GetIntArrayElements(jx, 0);
- jint *jy_body = env->GetIntArrayElements(jy, 0);
-
-- for(int i = 0; i < 4; i++)
-+ for(int i = 0; i < MAPLE_NUM_PORTS; i++)
- {
-- kcode[i] = k_code_body[i];
-- lt[i] = l_t_body[i];
-- rt[i] = r_t_body[i];
-- joyx[i] = jx_body[i];
-- joyy[i] = jy_body[i];
-+ maple_controller[i].buttons = k_code_body[i];
-+ maple_controller[i].trigger_left = l_t_body[i];
-+ maple_controller[i].trigger_right = r_t_body[i];
-+ maple_controller[i].stick_x = jx_body[i];
-+ maple_controller[i].stick_y = jy_body[i];
- }
-
- env->ReleaseIntArrayElements(k_code, k_code_body, 0);
-diff -Nur a/shell/apple/emulator-ios/emulator/EmulatorView.mm b/shell/apple/emulator-ios/emulator/EmulatorView.mm
---- a/shell/apple/emulator-ios/emulator/EmulatorView.mm 2015-10-06 21:43:53.121336967 -0300
-+++ b/shell/apple/emulator-ios/emulator/EmulatorView.mm 2015-10-06 22:08:18.383992714 -0300
-@@ -9,15 +9,7 @@
- #import "EmulatorView.h"
-
- #include "types.h"
--
--extern u16 kcode[4];
--extern u32 vks[4];
--extern s8 joyx[4],joyy[4];
--extern u8 rt[4],lt[4];
--
--#define key_CONT_A (1 << 2)
--#define key_CONT_START (1 << 3)
--#define key_CONT_DPAD_LEFT (1 << 6)
-+#include "hw/maple/maple_controller.h"
-
- int dpad_or_btn = 0;
-
-@@ -34,9 +26,9 @@
- -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
-
- if (dpad_or_btn &1)
-- kcode[0] &= ~(key_CONT_START|key_CONT_A);
-+ maple_controller[0].buttons &= ~(DC_BTN_START|DC_BTN_A);
- else
-- kcode[0] &= ~(key_CONT_DPAD_LEFT);
-+ maple_controller[0].buttons &= ~(DC_BTN_DPAD_LEFT);
- }
-
- -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
-@@ -44,9 +36,9 @@
- // [event allTouches];
-
- if (dpad_or_btn &1)
-- kcode[0] |= (key_CONT_START|key_CONT_A);
-+ maple_controller[0].buttons |= (DC_BTN_START|DC_BTN_A);
- else
-- kcode[0] |= (key_CONT_DPAD_LEFT);
-+ maple_controller[0].buttons |= (DC_BTN_DPAD_LEFT);
-
- dpad_or_btn++;
- }
-diff -Nur a/shell/apple/emulator-ios/emulator/ios_main.mm b/shell/apple/emulator-ios/emulator/ios_main.mm
---- a/shell/apple/emulator-ios/emulator/ios_main.mm 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/apple/emulator-ios/emulator/ios_main.mm 2015-10-06 22:08:18.383992714 -0300
-@@ -20,6 +20,7 @@
- #include <sys/mman.h>
- #include <sys/time.h>
- #include "hw/sh4/dyna/blockmanager.h"
-+#include "hw/maple/maple_controller.h"
- #include <unistd.h>
-
-
-@@ -55,11 +56,6 @@
- int dc_init(int argc,wchar* argv[]);
- void dc_run();
-
--u16 kcode[4];
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- extern "C" int reicast_main(int argc, wchar* argv[])
- {
- //if (argc==2)
-diff -Nur a/shell/apple/emulator-osx/emulator-osx/osx-main.mm b/shell/apple/emulator-osx/emulator-osx/osx-main.mm
---- a/shell/apple/emulator-osx/emulator-osx/osx-main.mm 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/apple/emulator-osx/emulator-osx/osx-main.mm 2015-10-06 22:08:18.383992714 -0300
-@@ -8,6 +8,7 @@
- #import <Carbon/Carbon.h>
-
- #include "types.h"
-+#include "hw/maple/maple_controller.h"
- #include <sys/stat.h>
-
- #include <OpenGL/gl3.h>
-@@ -38,11 +39,6 @@
- return 0;
- }
-
--u16 kcode[4] = { 0xFFFF };
--u32 vks[4];
--s8 joyx[4],joyy[4];
--u8 rt[4],lt[4];
--
- int get_mic_data(u8* buffer) { return 0; }
- int push_vmu_screen(u8* buffer) { return 0; }
-
-@@ -131,35 +127,11 @@
- gles_init();
- }
-
--enum DCPad {
-- Btn_C = 1,
-- Btn_B = 1<<1,
-- Btn_A = 1<<2,
-- Btn_Start = 1<<3,
-- DPad_Up = 1<<4,
-- DPad_Down = 1<<5,
-- DPad_Left = 1<<6,
-- DPad_Right = 1<<7,
-- Btn_Z = 1<<8,
-- Btn_Y = 1<<9,
-- Btn_X = 1<<10,
-- Btn_D = 1<<11,
-- DPad2_Up = 1<<12,
-- DPad2_Down = 1<<13,
-- DPad2_Left = 1<<14,
-- DPad2_Right = 1<<15,
--
-- Axis_LT= 0x10000,
-- Axis_RT= 0x10001,
-- Axis_X= 0x20000,
-- Axis_Y= 0x20001,
--};
--
- void handle_key(int dckey, int state) {
- if (state)
-- kcode[0] &= ~dckey;
-+ maple_controller[0].buttons &= ~dckey;
- else
-- kcode[0] |= dckey;
-+ maple_controller[0].buttons |= dckey;
- }
-
- void handle_trig(u8* dckey, int state) {
-@@ -172,18 +144,18 @@
- extern "C" void emu_key_input(char* keyt, int state) {
- int key = keyt[0];
- switch(key) {
-- case 'z': handle_key(Btn_X, state); break;
-- case 'x': handle_key(Btn_Y, state); break;
-- case 'c': handle_key(Btn_B, state); break;
-- case 'v': handle_key(Btn_A, state); break;
-+ case 'z': handle_key(DC_BTN_X, state); break;
-+ case 'x': handle_key(DC_BTN_Y, state); break;
-+ case 'c': handle_key(DC_BTN_B, state); break;
-+ case 'v': handle_key(DC_BTN_A, state); break;
-
- case 'a': handle_trig(lt, state); break;
- case 's': handle_trig(rt, state); break;
-
-- case 'j': handle_key(DPad_Left, state); break;
-- case 'k': handle_key(DPad_Down, state); break;
-- case 'l': handle_key(DPad_Right, state); break;
-- case 'i': handle_key(DPad_Up, state); break;
-- case 0xa: handle_key(Btn_Start, state); break;
-+ case 'j': handle_key(DC_BTN_DPAD_LEFT, state); break;
-+ case 'k': handle_key(DC_BTN_DPAD_DOWN, state); break;
-+ case 'l': handle_key(DC_BTN_DPAD_RIGHT, state); break;
-+ case 'i': handle_key(DC_BTN_DPAD_UP, state); break;
-+ case 0xa: handle_key(DC_BTN_START, state); break;
- }
- }
-\ No newline at end of file
-diff -Nur a/shell/reicast.vcxproj b/shell/reicast.vcxproj
---- a/shell/reicast.vcxproj 2015-10-06 22:07:39.030703893 -0300
-+++ b/shell/reicast.vcxproj 2015-10-06 22:08:18.383992714 -0300
-@@ -92,6 +92,7 @@
- <ClCompile Include="..\core\hw\holly\sb_dma.cpp" />
- <ClCompile Include="..\core\hw\holly\sb_mem.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_cfg.cpp" />
-+ <ClCompile Include="..\core\hw\maple\maple_controller.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_devs.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_helper.cpp" />
- <ClCompile Include="..\core\hw\maple\maple_if.cpp" />
diff --git a/pcr/reicast-multilib-git/refactor-rend-stuff.patch b/pcr/reicast-multilib-git/refactor-rend-stuff.patch
deleted file mode 100644
index 187ccb8d0..000000000
--- a/pcr/reicast-multilib-git/refactor-rend-stuff.patch
+++ /dev/null
@@ -1,1244 +0,0 @@
-diff -Nur a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp
---- a/core/rend/gles/gles.cpp 2015-10-06 21:43:53.047336437 -0300
-+++ b/core/rend/gles/gles.cpp 2015-10-06 21:51:21.723570329 -0300
-@@ -1,27 +1,3 @@
--#include <math.h>
--#include "gles.h"
--#include "rend/TexCache.h"
--#include "cfg/cfg.h"
--
--#ifdef TARGET_PANDORA
--#include <unistd.h>
--#include <fcntl.h>
--#include <sys/ioctl.h>
--#include <linux/fb.h>
--
--#ifndef FBIO_WAITFORVSYNC
-- #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
--#endif
--int fbdev = -1;
--#endif
--
--#ifndef GLES
--#if HOST_OS != OS_DARWIN
--#include <GL3/gl3w.c>
--#pragma comment(lib,"Opengl32.lib")
--#endif
--#endif
--
- /*
- GL|ES 2
- Slower, smaller subset of gl2
-@@ -54,305 +30,126 @@
-
- */
-
-+#include <math.h>
-+#include "cfg/cfg.h"
- #include "oslib/oslib.h"
- #include "rend/rend.h"
-+#include "rend/TexCache.h"
- #include "hw/pvr/Renderer_if.h"
-+#include "deps/libpng/png.h"
-+#include "gles.h"
-+#include "glshaders.h"
-
--void GenSorted();
--
--float fb_scale_x,fb_scale_y;
--
--#ifndef GLES
--#define attr "in"
--#define vary "out"
--#else
--#define attr "attribute"
--#define vary "varying"
-+#ifdef TARGET_PANDORA
-+ #include <unistd.h>
-+ #include <fcntl.h>
-+ #include <sys/ioctl.h>
-+ #include <linux/fb.h>
- #endif
--#if 1
-
--//Fragment and vertex shaders code
--//pretty much 1:1 copy of the d3d ones for now
--const char* VertexShaderSource =
--#ifndef GLES
-- "#version 140 \n"
-+#if !defined(GLES) && HOST_OS != OS_DARWIN
-+ #include <GL3/gl3w.c>
-+ #pragma comment(lib,"Opengl32.lib")
- #endif
--"\
--/* Vertex constants*/ \n\
--uniform highp vec4 scale; \n\
--uniform highp vec4 depth_scale; \n\
--uniform highp float sp_FOG_DENSITY; \n\
--/* Vertex input */ \n\
--" attr " highp vec4 in_pos; \n\
--" attr " lowp vec4 in_base; \n\
--" attr " lowp vec4 in_offs; \n\
--" attr " mediump vec2 in_uv; \n\
--/* output */ \n\
--" vary " lowp vec4 vtx_base; \n\
--" vary " lowp vec4 vtx_offs; \n\
--" vary " mediump vec2 vtx_uv; \n\
--" vary " highp vec3 vtx_xyz; \n\
--void main() \n\
--{ \n\
-- vtx_base=in_base; \n\
-- vtx_offs=in_offs; \n\
-- vtx_uv=in_uv; \n\
-- vec4 vpos=in_pos; \n\
-- vtx_xyz.xy = vpos.xy; \n\
-- vtx_xyz.z = vpos.z*sp_FOG_DENSITY; \n\
-- vpos.w=1.0/vpos.z; \n\
-- vpos.xy=vpos.xy*scale.xy-scale.zw; \n\
-- vpos.xy*=vpos.w; \n\
-- vpos.z=depth_scale.x+depth_scale.y*vpos.w; \n\
-- gl_Position = vpos; \n\
--}";
--
-
--#else
--
--
--
--const char* VertexShaderSource =
-- ""
-- "/* Test Projection Matrix */"
-- ""
-- "uniform highp mat4 Projection;"
-- ""
-- ""
-- "/* Vertex constants */"
-- ""
-- "uniform highp float sp_FOG_DENSITY;"
-- "uniform highp vec4 scale;"
-- ""
-- "/* Vertex output */"
-- ""
-- "attribute highp vec4 in_pos;"
-- "attribute lowp vec4 in_base;"
-- "attribute lowp vec4 in_offs;"
-- "attribute mediump vec2 in_uv;"
-- ""
-- "/* Transformed input */"
-- ""
-- "varying lowp vec4 vtx_base;"
-- "varying lowp vec4 vtx_offs;"
-- "varying mediump vec2 vtx_uv;"
-- "varying highp vec3 vtx_xyz;"
-- ""
-- "void main()"
-- "{"
-- " vtx_base = in_base;"
-- " vtx_offs = in_offs;"
-- " vtx_uv = in_uv;"
-- ""
-- " vec4 vpos = in_pos;"
-- " vtx_xyz.xy = vpos.xy; "
-- " vtx_xyz.z = vpos.z*sp_FOG_DENSITY; "
-- ""
-- " vpos.w = 1.0/vpos.z; "
-- " vpos.z *= -scale.w; "
-- " vpos.xy = vpos.xy*scale.xy-sign(scale.xy); "
-- " vpos.xy *= vpos.w; "
-- ""
-- " gl_Position = vpos;"
-- // " gl_Position = vpos * Projection;"
-- "}"
-- ;
-+#define OSD_TEX_W 512
-+#define OSD_TEX_H 256
-
-+#define key_CONT_C (1 << 0)
-+#define key_CONT_B (1 << 1)
-+#define key_CONT_A (1 << 2)
-+#define key_CONT_START (1 << 3)
-+#define key_CONT_DPAD_UP (1 << 4)
-+#define key_CONT_DPAD_DOWN (1 << 5)
-+#define key_CONT_DPAD_LEFT (1 << 6)
-+#define key_CONT_DPAD_RIGHT (1 << 7)
-+#define key_CONT_Z (1 << 8)
-+#define key_CONT_Y (1 << 9)
-+#define key_CONT_X (1 << 10)
-+#define key_CONT_D (1 << 11)
-+#define key_CONT_DPAD2_UP (1 << 12)
-+#define key_CONT_DPAD2_DOWN (1 << 13)
-+#define key_CONT_DPAD2_LEFT (1 << 14)
-+#define key_CONT_DPAD2_RIGHT (1 << 15)
-
--#endif
-+gl_ctx gl;
-
-+float fb_scale_x;
-+float fb_scale_y;
-+int screen_width;
-+int screen_height;
-
-+GLuint osd_tex;
-
-+extern u16 kcode[4];
-+extern u8 rt[4];
-+extern u8 lt[4];
-
-+u32 osd_base;
-+u32 osd_count;
-
-+#if defined(_ANDROID)
-+ extern float vjoy_pos[14][8];
-+#else
-+ float vjoy_pos[14][8]=
-+ {
-+ {24+0,24+64,64,64}, //LEFT
-+ {24+64,24+0,64,64}, //UP
-+ {24+128,24+64,64,64}, //RIGHT
-+ {24+64,24+128,64,64}, //DOWN
-+
-+ {440+0,280+64,64,64}, //X
-+ {440+64,280+0,64,64}, //Y
-+ {440+128,280+64,64,64}, //B
-+ {440+64,280+128,64,64}, //A
-+
-+ {320-32,360+32,64,64}, //Start
-+
-+ {440,200,90,64}, //RT
-+ {542,200,90,64}, //LT
-+
-+ {-24,128+224,128,128}, //ANALOG_RING
-+ {96,320,64,64}, //ANALOG_POINT
-+ {1}
-+ };
-+#endif // !_ANDROID
-
--/*
-+float vjoy_sz[2][14] = {
-+ { 64,64,64,64, 64,64,64,64, 64, 90,90, 128, 64 },
-+ { 64,64,64,64, 64,64,64,64, 64, 64,64, 128, 64 },
-+};
-
--cp_AlphaTest 0 1 2 2
--pp_ClipTestMode -1 0 1 3 6
--pp_UseAlpha 0 1 2 12
--pp_Texture 1
-- pp_IgnoreTexA 0 1 2 2
-- pp_ShadInstr 0 1 2 3 4 8
-- pp_Offset 0 1 2 16
-- pp_FogCtrl 0 1 2 3 4 64
--pp_Texture 0
-- pp_FogCtrl 0 2 3 4 4
--
--pp_Texture: off -> 12*4=48 shaders
--pp_Texture: on -> 12*64=768 shaders
--Total: 816 shaders
--
--highp float fdecp(highp float flt,out highp float e) \n\
--{ \n\
-- highp float lg2=log2(flt); //ie , 2.5 \n\
-- highp float frc=fract(lg2); //ie , 0.5 \n\
-- e=lg2-frc; //ie , 2.5-0.5=2 (exp) \n\
-- return pow(2.0,frc); //2^0.5 (manitsa) \n\
--} \n\
--lowp float fog_mode2(highp float invW) \n\
--{ \n\
-- highp float foginvW=invW; \n\
-- foginvW=clamp(foginvW,1.0,255.0); \n\
-- \n\
-- highp float fogexp; //0 ... 7 \n\
-- highp float fogman=fdecp(foginvW, fogexp); //[1,2) mantissa bits. that is 1.m \n\
-- \n\
-- highp float fogman_hi=fogman*16.0-16.0; //[16,32) -16 -> [0,16) \n\
-- highp float fogman_idx=floor(fogman_hi); //[0,15] \n\
-- highp float fogman_blend=fract(fogman_hi); //[0,1) -- can also be fogman_idx-fogman_idx ! \n\
-- highp float fog_idx_fr=fogexp*16.0+fogman_idx; //[0,127] \n\
-- \n\
-- highp float fog_idx_pixel_fr=fog_idx_fr+0.5; \n\
-- highp float fog_idx_pixel_n=fog_idx_pixel_fr/128.0;//normalise to [0.5/128,127.5/128) coordinates \n\
-- \n\
-- //fog is 128x1 texure \n\
-- lowp vec2 fog_coefs=texture2D(fog_table,vec2(fog_idx_pixel_n)).rg; \n\
-- \n\
-- lowp float fog_coef=mix(fog_coefs.r,fog_coefs.g,fogman_blend); \n\
-- \n\
-- return fog_coef; \n\
--} \n\
--*/
-+#ifdef TARGET_PANDORA
-+ #ifndef FBIO_WAITFORVSYNC
-+ #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
-+ #endif
-
--#ifndef GLES
--#define FRAGCOL "FragColor"
--#define TEXLOOKUP "texture"
--#define vary "in"
--#else
--#define FRAGCOL "gl_FragColor"
--#define TEXLOOKUP "texture2D"
-+ int fbdev = -1;
-+ char OSD_Info[128];
-+ int OSD_Delay = 0;
-+ char OSD_Counters[256];
-+ int OSD_Counter = 0;
-+ GLuint osd_font;
- #endif
-
--
--const char* PixelPipelineShader =
--#ifndef GLES
-- "#version 140 \n"
-- "out vec4 FragColor; \n"
-+#if !defined(_ANDROID) && !defined(TARGET_NACL32) && HOST_OS==OS_LINUX
-+ #define SET_AFNT 1
- #endif
--"\
--\
--#define cp_AlphaTest %d \n\
--#define pp_ClipTestMode %d.0 \n\
--#define pp_UseAlpha %d \n\
--#define pp_Texture %d \n\
--#define pp_IgnoreTexA %d \n\
--#define pp_ShadInstr %d \n\
--#define pp_Offset %d \n\
--#define pp_FogCtrl %d \n\
--/* Shader program params*/ \n\
--/* gles has no alpha test stage, so its emulated on the shader */ \n\
--uniform lowp float cp_AlphaTestValue; \n\
--uniform lowp vec4 pp_ClipTest; \n\
--uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT; \n\
--uniform highp vec2 sp_LOG_FOG_COEFS; \n\
--uniform sampler2D tex,fog_table; \n\
--/* Vertex input*/ \n\
--" vary " lowp vec4 vtx_base; \n\
--" vary " lowp vec4 vtx_offs; \n\
--" vary " mediump vec2 vtx_uv; \n\
--" vary " highp vec3 vtx_xyz; \n\
--lowp float fog_mode2(highp float val) \n\
--{ \n\
-- highp float fog_idx=clamp(val,0.0,127.99); \n\
-- return clamp(sp_LOG_FOG_COEFS.y*log2(fog_idx)+sp_LOG_FOG_COEFS.x,0.001,1.0); //the clamp is required due to yet another bug !\n\
--} \n\
--void main() \n\
--{ \n\
-- lowp vec4 color=vtx_base; \n\
-- #if pp_UseAlpha==0 \n\
-- color.a=1.0; \n\
-- #endif\n\
-- #if pp_FogCtrl==3 \n\
-- color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(vtx_xyz.z)); \n\
-- #endif\n\
-- #if pp_Texture==1 \n\
-- { \n\
-- lowp vec4 texcol=" TEXLOOKUP "(tex,vtx_uv); \n\
-- \n\
-- #if pp_IgnoreTexA==1 \n\
-- texcol.a=1.0; \n\
-- #endif\n\
-- \n\
-- #if pp_ShadInstr==0 \n\
-- { \n\
-- color.rgb=texcol.rgb; \n\
-- color.a=texcol.a; \n\
-- } \n\
-- #endif\n\
-- #if pp_ShadInstr==1 \n\
-- { \n\
-- color.rgb*=texcol.rgb; \n\
-- color.a=texcol.a; \n\
-- } \n\
-- #endif\n\
-- #if pp_ShadInstr==2 \n\
-- { \n\
-- color.rgb=mix(color.rgb,texcol.rgb,texcol.a); \n\
-- } \n\
-- #endif\n\
-- #if pp_ShadInstr==3 \n\
-- { \n\
-- color*=texcol; \n\
-- } \n\
-- #endif\n\
-- \n\
-- #if pp_Offset==1 \n\
-- { \n\
-- color.rgb+=vtx_offs.rgb; \n\
-- if (pp_FogCtrl==1) \n\
-- color.rgb=mix(color.rgb,sp_FOG_COL_VERT.rgb,vtx_offs.a); \n\
-- } \n\
-- #endif\n\
-- } \n\
-- #endif\n\
-- #if pp_FogCtrl==0 \n\
-- { \n\
-- color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(vtx_xyz.z)); \n\
-- } \n\
-- #endif\n\
-- #if cp_AlphaTest == 1 \n\
-- if (cp_AlphaTestValue>color.a) discard;\n\
-- #endif \n\
-- //color.rgb=vec3(vtx_xyz.z/255.0);\n\
-- " FRAGCOL "=color; \n\
--}";
-
--const char* ModifierVolumeShader =
--#ifndef GLES
-- "#version 140 \n"
-- "out vec4 FragColor; \n"
--#endif
--" \
--uniform lowp float sp_ShaderColor; \n\
--/* Vertex input*/ \n\
--void main() \n\
--{ \n\
-- " FRAGCOL "=vec4(0.0, 0.0, 0.0, sp_ShaderColor); \n\
--}";
-+FILE* pngfile;
-
--const char* OSD_Shader =
--#ifndef GLES
-- "#version 140 \n"
-- "out vec4 FragColor; \n"
--#endif
--" \
--" vary " lowp vec4 vtx_base; \n\
--" vary " mediump vec2 vtx_uv; \n\
--/* Vertex input*/ \n\
--uniform sampler2D tex; \n\
--void main() \n\
--{ \n\
-- mediump vec2 uv=vtx_uv; \n\
-- uv.y=1.0-uv.y; \n\
-- " FRAGCOL "=vtx_base*" TEXLOOKUP "(tex,uv.st); \n\n\
--}";
-+void GenSorted();
-
-+bool gl_init(void* wind, void* disp);
-
--gl_ctx gl;
-+//swap buffers
-+void gl_swap();
-+//destroy the gles context and free resources
-+void gl_term();
-
--int screen_width;
--int screen_height;
-+GLuint gl_CompileShader(const char* shader,GLuint type);
-+
-+bool gl_create_resources();
-
- #if (HOST_OS != OS_DARWIN) && !defined(TARGET_NACL32)
- #ifdef GLES
-@@ -843,11 +640,6 @@
- return glIsProgram(s->program)==GL_TRUE;
- }
-
--GLuint osd_tex;
--#ifdef TARGET_PANDORA
--GLuint osd_font;
--#endif
--
- bool gl_create_resources()
- {
-
-@@ -938,51 +730,8 @@
- return true;
- }
-
--bool gl_init(void* wind, void* disp);
--
--//swap buffers
--void gl_swap();
--//destroy the gles context and free resources
--void gl_term();
--
--GLuint gl_CompileShader(const char* shader,GLuint type);
--
--bool gl_create_resources();
--
- //setup
-
--
--bool gles_init()
--{
--
-- if (!gl_init((void*)libPvr_GetRenderTarget(),
-- (void*)libPvr_GetRenderSurface()))
-- return false;
--
-- if (!gl_create_resources())
-- return false;
--
--#if defined(GLES) && HOST_OS != OS_DARWIN && !defined(TARGET_NACL32)
-- #ifdef TARGET_PANDORA
-- fbdev=open("/dev/fb0", O_RDONLY);
-- #else
-- eglSwapInterval(gl.setup.display,1);
-- #endif
--#endif
--
-- //clean up all buffers ...
-- for (int i=0;i<10;i++)
-- {
-- glClearColor(0.f, 0.f, 0.f, 0.f);
-- glClear(GL_COLOR_BUFFER_BIT);
-- gl_swap();
-- }
--
-- return true;
--}
--
--
--
- float fog_coefs[]={0,0};
- void tryfit(float* x,float* y)
- {
-@@ -1043,64 +792,6 @@
- //printf("%f\n",B*log(maxdev)/log(2.0)+A);
- }
-
--
--
--extern u16 kcode[4];
--extern u8 rt[4],lt[4];
--
--#define key_CONT_C (1 << 0)
--#define key_CONT_B (1 << 1)
--#define key_CONT_A (1 << 2)
--#define key_CONT_START (1 << 3)
--#define key_CONT_DPAD_UP (1 << 4)
--#define key_CONT_DPAD_DOWN (1 << 5)
--#define key_CONT_DPAD_LEFT (1 << 6)
--#define key_CONT_DPAD_RIGHT (1 << 7)
--#define key_CONT_Z (1 << 8)
--#define key_CONT_Y (1 << 9)
--#define key_CONT_X (1 << 10)
--#define key_CONT_D (1 << 11)
--#define key_CONT_DPAD2_UP (1 << 12)
--#define key_CONT_DPAD2_DOWN (1 << 13)
--#define key_CONT_DPAD2_LEFT (1 << 14)
--#define key_CONT_DPAD2_RIGHT (1 << 15)
--
--u32 osd_base;
--u32 osd_count;
--
--
--#if defined(_ANDROID)
--extern float vjoy_pos[14][8];
--#else
--
--float vjoy_pos[14][8]=
--{
-- {24+0,24+64,64,64}, //LEFT
-- {24+64,24+0,64,64}, //UP
-- {24+128,24+64,64,64}, //RIGHT
-- {24+64,24+128,64,64}, //DOWN
--
-- {440+0,280+64,64,64}, //X
-- {440+64,280+0,64,64}, //Y
-- {440+128,280+64,64,64}, //B
-- {440+64,280+128,64,64}, //A
--
-- {320-32,360+32,64,64}, //Start
--
-- {440,200,90,64}, //RT
-- {542,200,90,64}, //LT
--
-- {-24,128+224,128,128}, //ANALOG_RING
-- {96,320,64,64}, //ANALOG_POINT
-- {1}
--};
--#endif // !_ANDROID
--
--float vjoy_sz[2][14] = {
-- { 64,64,64,64, 64,64,64,64, 64, 90,90, 128, 64 },
-- { 64,64,64,64, 64,64,64,64, 64, 64,64, 128, 64 },
--};
--
- static void DrawButton(float* xy, u32 state)
- {
- Vertex vtx;
-@@ -1139,12 +830,6 @@
- osd_count+=4;
- }
-
--static void ClearBG()
--{
--
--}
--
--
- void DrawButton2(float* xy, bool state) { DrawButton(xy,state?0:255); }
- #ifdef TARGET_PANDORA
- static void DrawCenteredText(float yy, float scale, int transparency, const char* text)
-@@ -1247,13 +932,6 @@
- }
- #endif
-
--#ifdef TARGET_PANDORA
--char OSD_Info[128];
--int OSD_Delay=0;
--char OSD_Counters[256];
--int OSD_Counter=0;
--#endif
--
- static void OSD_HOOK()
- {
- osd_base=pvrrc.verts.used();
-@@ -1290,128 +968,95 @@
- #endif
- }
-
--extern GLuint osd_tex;
--#ifdef TARGET_PANDORA
--extern GLuint osd_font;
--#endif
--
--#define OSD_TEX_W 512
--#define OSD_TEX_H 256
--
--void OSD_DRAW()
-+/*
-+bool rend_single_frame()
- {
-- #ifndef TARGET_PANDORA
-- if (osd_tex)
-- {
-- float u=0;
-- float v=0;
--
-- for (int i=0;i<13;i++)
-- {
-- //umin,vmin,umax,vmax
-- vjoy_pos[i][4]=(u+1)/OSD_TEX_W;
-- vjoy_pos[i][5]=(v+1)/OSD_TEX_H;
--
-- vjoy_pos[i][6]=((u+vjoy_sz[0][i]-1))/OSD_TEX_W;
-- vjoy_pos[i][7]=((v+vjoy_sz[1][i]-1))/OSD_TEX_H;
--
-- u+=vjoy_sz[0][i];
-- if (u>=OSD_TEX_W)
-- {
-- u-=OSD_TEX_W;
-- v+=vjoy_sz[1][i];
-- }
-- //v+=vjoy_pos[i][3];
-- }
--
-- verify(glIsProgram(gl.OSD_SHADER.program));
-+ //wait render start only if no frame pending
-+ _pvrrc = DequeueRender();
-
-- glBindTexture(GL_TEXTURE_2D,osd_tex);
-- glUseProgram(gl.OSD_SHADER.program);
-+ while (!_pvrrc)
-+ {
-+ rs.Wait();
-+ _pvrrc = DequeueRender();
-+ }
-
-- //reset rendering scale
--/*
-- float dc_width=640;
-- float dc_height=480;
-+ bool do_swp=false;
-+ //if (kcode[0]&(1<<9))
-+ {
-
-- float dc2s_scale_h=screen_height/480.0f;
-- float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
-
-- //-1 -> too much to left
-- ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
-- ShaderUniforms.scale_coefs[1]=-2/dc_height;
-- ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
-- ShaderUniforms.scale_coefs[3]=-1;
-+ //clear up & free data ..
-+ tactx_Recycle(_pvrrc);
-+ _pvrrc=0;
-
-- glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
-+ return do_swp;
-+}
- */
-
-- glEnable(GL_BLEND);
-- glDisable(GL_DEPTH_TEST);
-- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
--
-- glDepthMask(false);
-- glDepthFunc(GL_ALWAYS);
--
-- glDisable(GL_CULL_FACE);
-- glDisable(GL_SCISSOR_TEST);
--
-- int dfa=osd_count/4;
--
-- for (int i=0;i<dfa;i++)
-- glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
-- }
--#endif
--#ifdef TARGET_PANDORA
-- if (osd_font)
-- {
-- float u=0;
-- float v=0;
--
-- verify(glIsProgram(gl.OSD_SHADER.program));
--
-- float dc_width=640;
-- float dc_height=480;
--
-- float dc2s_scale_h=screen_height/480.0f;
-- float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
-
-+void rend_set_fb_scale(float x,float y)
-+{
-+ fb_scale_x=x;
-+ fb_scale_y=y;
-+}
-
-- glBindTexture(GL_TEXTURE_2D,osd_font);
-- glUseProgram(gl.OSD_SHADER.program);
-+struct glesrend : Renderer
-+{
-+ bool Init();
-+ void Resize(int width, int height);
-+ void Term();
-
-- /*
-- //-1 -> too much to left
-- ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
-- ShaderUniforms.scale_coefs[1]=-2/dc_height;
-- ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
-- ShaderUniforms.scale_coefs[3]=-1;
-+ bool Process(TA_context* ctx);
-+ bool Render();
-
-- glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
--*/
-+ void Present();
-
-- glEnable(GL_BLEND);
-- glDisable(GL_DEPTH_TEST);
-- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-+ void DrawOSD();
-
-+ virtual u32 GetTexture(TSP tsp, TCW tcw);
-+};
-
-- glDepthMask(false);
-- glDepthFunc(GL_ALWAYS);
-+bool glesrend::Init()
-+{
-+
-+ if (!gl_init((void*)libPvr_GetRenderTarget(), (void*)libPvr_GetRenderSurface()))
-+ {
-+ return false;
-+ }
-
-+ if (!gl_create_resources())
-+ {
-+ return false;
-+ }
-
-- glDisable(GL_CULL_FACE);
-- glDisable(GL_SCISSOR_TEST);
-+ #if defined(GLES) && HOST_OS != OS_DARWIN && !defined(TARGET_NACL32)
-+ #ifdef TARGET_PANDORA
-+ fbdev = open("/dev/fb0", O_RDONLY);
-+ #else
-+ eglSwapInterval(gl.setup.display,1);
-+ #endif
-+ #endif
-
-+ //clean up all buffers ...
-+ for (int i=0;i<10;i++)
-+ {
-+ glClearColor(0.f, 0.f, 0.f, 0.f);
-+ glClear(GL_COLOR_BUFFER_BIT);
-+ gl_swap();
-+ }
-
-- int dfa=osd_count/4;
-+ return true;
-+}
-
-- for (int i=0;i<dfa;i++)
-- glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
-- }
--#endif
-+void glesrend::Resize(int width, int height)
-+{
-+ screen_width = width;
-+ screen_height = height;
- }
-
--bool ProcessFrame(TA_context* ctx)
-+void glesrend::Term() { };
-+
-+bool glesrend::Process(TA_context* ctx)
- {
- //disable RTTs for now ..
- if (ctx->rend.isRTT)
-@@ -1435,7 +1080,7 @@
- return true;
- }
-
--bool RenderFrame()
-+bool glesrend::Render()
- {
- DoCleanup();
-
-@@ -1737,10 +1382,10 @@
- }
- else
- {
--#if HOST_OS != OS_DARWIN
-- //Fix this in a proper way
-- glBindFramebuffer(GL_FRAMEBUFFER,0);
--#endif
-+ #if HOST_OS != OS_DARWIN
-+ //Fix this in a proper way
-+ glBindFramebuffer(GL_FRAMEBUFFER,0);
-+ #endif
- }
-
- //Clear depth
-@@ -1812,68 +1457,93 @@
- return !is_rtt;
- }
-
--#if !defined(_ANDROID) && !defined(TARGET_NACL32)
--#if HOST_OS==OS_LINUX
--#define SET_AFNT 1
--#endif
--#endif
--
--extern u16 kcode[4];
-+void glesrend::Present()
-+{
-+ gl_swap();
-+ glViewport(0, 0, screen_width, screen_height);
-+}
-
--/*
--bool rend_single_frame()
-+void glesrend::DrawOSD()
- {
-- //wait render start only if no frame pending
-- _pvrrc = DequeueRender();
-+ #ifdef TARGET_PANDORA
-+ GLuint osd_texture = osd_font;
-+ #else
-+ GLuint osd_texture = osd_tex;
-+ #endif
-
-- while (!_pvrrc)
-+ if (!osd_texture)
- {
-- rs.Wait();
-- _pvrrc = DequeueRender();
-+ return;
- }
-
-- bool do_swp=false;
-- //if (kcode[0]&(1<<9))
-- {
-+ verify(glIsProgram(gl.OSD_SHADER.program));
-
-+ #ifndef TARGET_PANDORA
-+ float u = 0;
-+ float v = 0;
-+
-+ for (int i = 0; i < 13; i++)
-+ {
-+ //umin,vmin,umax,vmax
-+ vjoy_pos[i][4]=(u+1)/OSD_TEX_W;
-+ vjoy_pos[i][5]=(v+1)/OSD_TEX_H;
-
-- //clear up & free data ..
-- tactx_Recycle(_pvrrc);
-- _pvrrc=0;
-+ vjoy_pos[i][6]=((u+vjoy_sz[0][i]-1))/OSD_TEX_W;
-+ vjoy_pos[i][7]=((v+vjoy_sz[1][i]-1))/OSD_TEX_H;
-
-- return do_swp;
--}
--*/
-+ u+=vjoy_sz[0][i];
-+ if (u>=OSD_TEX_W)
-+ {
-+ u-=OSD_TEX_W;
-+ v+=vjoy_sz[1][i];
-+ }
-+ //v+=vjoy_pos[i][3];
-+ }
-+ #endif
-
-+ glBindTexture(GL_TEXTURE_2D, osd_texture);
-+ glUseProgram(gl.OSD_SHADER.program);
-
--void rend_set_fb_scale(float x,float y)
--{
-- fb_scale_x=x;
-- fb_scale_y=y;
--}
-+ /*
-+ //reset rendering scale
-
--struct glesrend : Renderer
--{
-- bool Init() { return gles_init(); }
-- void Resize(int w, int h) { screen_width=w; screen_height=h; }
-- void Term() { }
-+ float dc_width=640;
-+ float dc_height=480;
-
-- bool Process(TA_context* ctx) { return ProcessFrame(ctx); }
-- bool Render() { return RenderFrame(); }
-+ float dc2s_scale_h=screen_height/480.0f;
-+ float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
-
-- void Present() { gl_swap(); glViewport(0, 0, screen_width, screen_height); }
-+ //-1 -> too much to left
-+ ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
-+ ShaderUniforms.scale_coefs[1]=-2/dc_height;
-+ ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
-+ ShaderUniforms.scale_coefs[3]=-1;
-
-- void DrawOSD() { OSD_DRAW(); }
-+ glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
-+ */
-
-- virtual u32 GetTexture(TSP tsp, TCW tcw) {
-- return gl_GetTexture(tsp, tcw);
-- }
--};
-+ glEnable(GL_BLEND);
-+ glDisable(GL_DEPTH_TEST);
-+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-+ glDepthMask(false);
-+ glDepthFunc(GL_ALWAYS);
-
--#include "deps/libpng/png.h"
-+ glDisable(GL_CULL_FACE);
-+ glDisable(GL_SCISSOR_TEST);
-
--FILE* pngfile;
-+ int dfa = osd_count/4;
-+
-+ for (int i = 0; i < dfa; i++)
-+ {
-+ glDrawArrays(GL_TRIANGLE_STRIP, osd_base + i*4, 4);
-+ }
-+}
-+
-+u32 glesrend::GetTexture(TSP tsp, TCW tcw)
-+{
-+ return gl_GetTexture(tsp, tcw);
-+}
-
- void png_cstd_read(png_structp png_ptr, png_bytep data, png_size_t length)
- {
-@@ -2021,5 +1691,4 @@
- return texture;
- }
-
--
- Renderer* rend_GLES2() { return new glesrend(); }
-diff -Nur a/core/rend/gles/glshaders.cpp b/core/rend/gles/glshaders.cpp
---- a/core/rend/gles/glshaders.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/rend/gles/glshaders.cpp 2015-10-06 21:51:21.723570329 -0300
-@@ -0,0 +1,280 @@
-+#ifndef GLES
-+#define attr "in"
-+#define vary "out"
-+#else
-+#define attr "attribute"
-+#define vary "varying"
-+#endif
-+#if 1
-+
-+//Fragment and vertex shaders code
-+//pretty much 1:1 copy of the d3d ones for now
-+const char* VertexShaderSource =
-+#ifndef GLES
-+ "#version 140 \n"
-+#endif
-+"\
-+/* Vertex constants*/ \n\
-+uniform highp vec4 scale; \n\
-+uniform highp vec4 depth_scale; \n\
-+uniform highp float sp_FOG_DENSITY; \n\
-+/* Vertex input */ \n\
-+" attr " highp vec4 in_pos; \n\
-+" attr " lowp vec4 in_base; \n\
-+" attr " lowp vec4 in_offs; \n\
-+" attr " mediump vec2 in_uv; \n\
-+/* output */ \n\
-+" vary " lowp vec4 vtx_base; \n\
-+" vary " lowp vec4 vtx_offs; \n\
-+" vary " mediump vec2 vtx_uv; \n\
-+" vary " highp vec3 vtx_xyz; \n\
-+void main() \n\
-+{ \n\
-+ vtx_base=in_base; \n\
-+ vtx_offs=in_offs; \n\
-+ vtx_uv=in_uv; \n\
-+ vec4 vpos=in_pos; \n\
-+ vtx_xyz.xy = vpos.xy; \n\
-+ vtx_xyz.z = vpos.z*sp_FOG_DENSITY; \n\
-+ vpos.w=1.0/vpos.z; \n\
-+ vpos.xy=vpos.xy*scale.xy-scale.zw; \n\
-+ vpos.xy*=vpos.w; \n\
-+ vpos.z=depth_scale.x+depth_scale.y*vpos.w; \n\
-+ gl_Position = vpos; \n\
-+}";
-+
-+
-+#else
-+
-+
-+
-+const char* VertexShaderSource =
-+ ""
-+ "/* Test Projection Matrix */"
-+ ""
-+ "uniform highp mat4 Projection;"
-+ ""
-+ ""
-+ "/* Vertex constants */"
-+ ""
-+ "uniform highp float sp_FOG_DENSITY;"
-+ "uniform highp vec4 scale;"
-+ ""
-+ "/* Vertex output */"
-+ ""
-+ "attribute highp vec4 in_pos;"
-+ "attribute lowp vec4 in_base;"
-+ "attribute lowp vec4 in_offs;"
-+ "attribute mediump vec2 in_uv;"
-+ ""
-+ "/* Transformed input */"
-+ ""
-+ "varying lowp vec4 vtx_base;"
-+ "varying lowp vec4 vtx_offs;"
-+ "varying mediump vec2 vtx_uv;"
-+ "varying highp vec3 vtx_xyz;"
-+ ""
-+ "void main()"
-+ "{"
-+ " vtx_base = in_base;"
-+ " vtx_offs = in_offs;"
-+ " vtx_uv = in_uv;"
-+ ""
-+ " vec4 vpos = in_pos;"
-+ " vtx_xyz.xy = vpos.xy; "
-+ " vtx_xyz.z = vpos.z*sp_FOG_DENSITY; "
-+ ""
-+ " vpos.w = 1.0/vpos.z; "
-+ " vpos.z *= -scale.w; "
-+ " vpos.xy = vpos.xy*scale.xy-sign(scale.xy); "
-+ " vpos.xy *= vpos.w; "
-+ ""
-+ " gl_Position = vpos;"
-+ // " gl_Position = vpos * Projection;"
-+ "}"
-+ ;
-+
-+
-+#endif
-+
-+/*
-+
-+cp_AlphaTest 0 1 2 2
-+pp_ClipTestMode -1 0 1 3 6
-+pp_UseAlpha 0 1 2 12
-+pp_Texture 1
-+ pp_IgnoreTexA 0 1 2 2
-+ pp_ShadInstr 0 1 2 3 4 8
-+ pp_Offset 0 1 2 16
-+ pp_FogCtrl 0 1 2 3 4 64
-+pp_Texture 0
-+ pp_FogCtrl 0 2 3 4 4
-+
-+pp_Texture: off -> 12*4=48 shaders
-+pp_Texture: on -> 12*64=768 shaders
-+Total: 816 shaders
-+
-+highp float fdecp(highp float flt,out highp float e) \n\
-+{ \n\
-+ highp float lg2=log2(flt); //ie , 2.5 \n\
-+ highp float frc=fract(lg2); //ie , 0.5 \n\
-+ e=lg2-frc; //ie , 2.5-0.5=2 (exp) \n\
-+ return pow(2.0,frc); //2^0.5 (manitsa) \n\
-+} \n\
-+lowp float fog_mode2(highp float invW) \n\
-+{ \n\
-+ highp float foginvW=invW; \n\
-+ foginvW=clamp(foginvW,1.0,255.0); \n\
-+ \n\
-+ highp float fogexp; //0 ... 7 \n\
-+ highp float fogman=fdecp(foginvW, fogexp); //[1,2) mantissa bits. that is 1.m \n\
-+ \n\
-+ highp float fogman_hi=fogman*16.0-16.0; //[16,32) -16 -> [0,16) \n\
-+ highp float fogman_idx=floor(fogman_hi); //[0,15] \n\
-+ highp float fogman_blend=fract(fogman_hi); //[0,1) -- can also be fogman_idx-fogman_idx ! \n\
-+ highp float fog_idx_fr=fogexp*16.0+fogman_idx; //[0,127] \n\
-+ \n\
-+ highp float fog_idx_pixel_fr=fog_idx_fr+0.5; \n\
-+ highp float fog_idx_pixel_n=fog_idx_pixel_fr/128.0;//normalise to [0.5/128,127.5/128) coordinates \n\
-+ \n\
-+ //fog is 128x1 texure \n\
-+ lowp vec2 fog_coefs=texture2D(fog_table,vec2(fog_idx_pixel_n)).rg; \n\
-+ \n\
-+ lowp float fog_coef=mix(fog_coefs.r,fog_coefs.g,fogman_blend); \n\
-+ \n\
-+ return fog_coef; \n\
-+} \n\
-+*/
-+
-+#ifndef GLES
-+#define FRAGCOL "FragColor"
-+#define TEXLOOKUP "texture"
-+#define vary "in"
-+#else
-+#define FRAGCOL "gl_FragColor"
-+#define TEXLOOKUP "texture2D"
-+#endif
-+
-+
-+const char* PixelPipelineShader =
-+#ifndef GLES
-+ "#version 140 \n"
-+ "out vec4 FragColor; \n"
-+#endif
-+"\
-+\
-+#define cp_AlphaTest %d \n\
-+#define pp_ClipTestMode %d.0 \n\
-+#define pp_UseAlpha %d \n\
-+#define pp_Texture %d \n\
-+#define pp_IgnoreTexA %d \n\
-+#define pp_ShadInstr %d \n\
-+#define pp_Offset %d \n\
-+#define pp_FogCtrl %d \n\
-+/* Shader program params*/ \n\
-+/* gles has no alpha test stage, so its emulated on the shader */ \n\
-+uniform lowp float cp_AlphaTestValue; \n\
-+uniform lowp vec4 pp_ClipTest; \n\
-+uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT; \n\
-+uniform highp vec2 sp_LOG_FOG_COEFS; \n\
-+uniform sampler2D tex,fog_table; \n\
-+/* Vertex input*/ \n\
-+" vary " lowp vec4 vtx_base; \n\
-+" vary " lowp vec4 vtx_offs; \n\
-+" vary " mediump vec2 vtx_uv; \n\
-+" vary " highp vec3 vtx_xyz; \n\
-+lowp float fog_mode2(highp float val) \n\
-+{ \n\
-+ highp float fog_idx=clamp(val,0.0,127.99); \n\
-+ return clamp(sp_LOG_FOG_COEFS.y*log2(fog_idx)+sp_LOG_FOG_COEFS.x,0.001,1.0); //the clamp is required due to yet another bug !\n\
-+} \n\
-+void main() \n\
-+{ \n\
-+ lowp vec4 color=vtx_base; \n\
-+ #if pp_UseAlpha==0 \n\
-+ color.a=1.0; \n\
-+ #endif\n\
-+ #if pp_FogCtrl==3 \n\
-+ color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(vtx_xyz.z)); \n\
-+ #endif\n\
-+ #if pp_Texture==1 \n\
-+ { \n\
-+ lowp vec4 texcol=" TEXLOOKUP "(tex,vtx_uv); \n\
-+ \n\
-+ #if pp_IgnoreTexA==1 \n\
-+ texcol.a=1.0; \n\
-+ #endif\n\
-+ \n\
-+ #if pp_ShadInstr==0 \n\
-+ { \n\
-+ color.rgb=texcol.rgb; \n\
-+ color.a=texcol.a; \n\
-+ } \n\
-+ #endif\n\
-+ #if pp_ShadInstr==1 \n\
-+ { \n\
-+ color.rgb*=texcol.rgb; \n\
-+ color.a=texcol.a; \n\
-+ } \n\
-+ #endif\n\
-+ #if pp_ShadInstr==2 \n\
-+ { \n\
-+ color.rgb=mix(color.rgb,texcol.rgb,texcol.a); \n\
-+ } \n\
-+ #endif\n\
-+ #if pp_ShadInstr==3 \n\
-+ { \n\
-+ color*=texcol; \n\
-+ } \n\
-+ #endif\n\
-+ \n\
-+ #if pp_Offset==1 \n\
-+ { \n\
-+ color.rgb+=vtx_offs.rgb; \n\
-+ if (pp_FogCtrl==1) \n\
-+ color.rgb=mix(color.rgb,sp_FOG_COL_VERT.rgb,vtx_offs.a); \n\
-+ } \n\
-+ #endif\n\
-+ } \n\
-+ #endif\n\
-+ #if pp_FogCtrl==0 \n\
-+ { \n\
-+ color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(vtx_xyz.z)); \n\
-+ } \n\
-+ #endif\n\
-+ #if cp_AlphaTest == 1 \n\
-+ if (cp_AlphaTestValue>color.a) discard;\n\
-+ #endif \n\
-+ //color.rgb=vec3(vtx_xyz.z/255.0);\n\
-+ " FRAGCOL "=color; \n\
-+}";
-+
-+const char* ModifierVolumeShader =
-+#ifndef GLES
-+ "#version 140 \n"
-+ "out vec4 FragColor; \n"
-+#endif
-+" \
-+uniform lowp float sp_ShaderColor; \n\
-+/* Vertex input*/ \n\
-+void main() \n\
-+{ \n\
-+ " FRAGCOL "=vec4(0.0, 0.0, 0.0, sp_ShaderColor); \n\
-+}";
-+
-+const char* OSD_Shader =
-+#ifndef GLES
-+ "#version 140 \n"
-+ "out vec4 FragColor; \n"
-+#endif
-+" \
-+" vary " lowp vec4 vtx_base; \n\
-+" vary " mediump vec2 vtx_uv; \n\
-+/* Vertex input*/ \n\
-+uniform sampler2D tex; \n\
-+void main() \n\
-+{ \n\
-+ mediump vec2 uv=vtx_uv; \n\
-+ uv.y=1.0-uv.y; \n\
-+ " FRAGCOL "=vtx_base*" TEXLOOKUP "(tex,uv.st); \n\n\
-+}";
-diff -Nur a/core/rend/gles/glshaders.h b/core/rend/gles/glshaders.h
---- a/core/rend/gles/glshaders.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/rend/gles/glshaders.h 2015-10-06 21:51:21.723570329 -0300
-@@ -0,0 +1,5 @@
-+#pragma once
-+extern const char* VertexShaderSource;
-+extern const char* PixelPipelineShader;
-+extern const char* ModifierVolumeShader;
-+extern const char* OSD_Shader;
-\ No newline at end of file
diff --git a/pcr/reicast-multilib-git/sdl-opengl.patch b/pcr/reicast-multilib-git/sdl-opengl.patch
deleted file mode 100644
index 372ec9a52..000000000
--- a/pcr/reicast-multilib-git/sdl-opengl.patch
+++ /dev/null
@@ -1,251 +0,0 @@
-diff -Nur a/core/khronos/GL3/gl3w.c b/core/khronos/GL3/gl3w.c
---- a/core/khronos/GL3/gl3w.c 2015-10-06 21:43:53.040336386 -0300
-+++ b/core/khronos/GL3/gl3w.c 2015-10-06 22:04:39.682388782 -0300
-@@ -1,6 +1,25 @@
- #include <GL3/gl3w.h>
-
--#ifdef _WIN32
-+#if defined(USE_SDL2)
-+ #include <SDL2/SDL.h>
-+ static void open_libgl(void)
-+ {
-+ SDL_GL_LoadLibrary(NULL);
-+ }
-+
-+ static void close_libgl(void)
-+ {
-+ SDL_GL_UnloadLibrary();
-+ }
-+
-+ static void *get_proc(const char *proc)
-+ {
-+ void *res = NULL;
-+ res = (void*)SDL_GL_GetProcAddress(proc);
-+ return res;
-+ }
-+
-+#elif defined(_WIN32)
- #define WIN32_LEAN_AND_MEAN 1
- #include <windows.h>
-
-diff -Nur a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp
---- a/core/sdl/sdl.cpp 2015-10-06 21:43:53.048336444 -0300
-+++ b/core/sdl/sdl.cpp 2015-10-06 22:04:39.683388790 -0300
-@@ -5,6 +5,18 @@
- #include "sdl/sdl.h"
- #ifdef GLES
- #include <EGL/egl.h>
-+#else
-+ #ifndef USE_SDL2
-+ #error "Our SDL1.2 implementation only supports GLES. You need SDL2 for OpenGL 3 support!"
-+ #endif
-+ #include "khronos/GL3/gl3w.h"
-+#endif
-+
-+#ifdef USE_SDL2
-+ static SDL_Window* window = NULL;
-+ static SDL_GLContext glcontext;
-+#else
-+ SDL_Surface *screen = NULL;
- #endif
-
- #ifdef TARGET_PANDORA
-@@ -14,8 +26,6 @@
- #endif
- #define WINDOW_HEIGHT 480
-
--SDL_Surface *screen = NULL;
--
- static SDL_Joystick *JoySDL = 0;
-
- extern bool FrameSkipping;
-@@ -80,11 +90,15 @@
-
- AxisCount = SDL_JoystickNumAxes(JoySDL);
- ButtonCount = SDL_JoystickNumButtons(JoySDL);
-- Name = SDL_JoystickName(0);
--
-+ #ifdef USE_SDL2
-+ Name = SDL_JoystickName(JoySDL);
-+ #else
-+ Name = SDL_JoystickName(0);
-+ #endif
-+
- printf("SDK: Found '%s' joystick with %d axes and %d buttons\n", Name, AxisCount, ButtonCount);
-
-- if (strcmp(Name,"Microsoft X-Box 360 pad")==0)
-+ if (Name != NULL && strcmp(Name,"Microsoft X-Box 360 pad")==0)
- {
- sdl_map_btn = sdl_map_btn_xbox360;
- sdl_map_axis = sdl_map_axis_xbox360;
-@@ -113,12 +127,16 @@
- }
- #endif
-
-- SDL_ShowCursor(0);
-+ #ifndef USE_SDL2
-+ SDL_ShowCursor(0);
-
-- if (SDL_WM_GrabInput( SDL_GRAB_ON ) != SDL_GRAB_ON)
-- {
-- printf("SDK: Error while grabbing mouse\n");
-- }
-+ if (SDL_WM_GrabInput( SDL_GRAB_ON ) != SDL_GRAB_ON)
-+ {
-+ printf("SDL: Error while grabbing mouse\n");
-+ }
-+ #else
-+ SDL_SetRelativeMouseMode(SDL_TRUE);
-+ #endif
- }
-
- void input_sdl_handle(u32 port)
-@@ -397,7 +415,14 @@
- #ifdef TARGET_PANDORA
- strncpy(OSD_Counters, text, 256);
- #else
-- SDL_WM_SetCaption(text, NULL); // *TODO* Set Icon also...
-+ #ifdef USE_SDL2
-+ if(window)
-+ {
-+ SDL_SetWindowTitle(window, text); // *TODO* Set Icon also...
-+ }
-+ #else
-+ SDL_WM_SetCaption(text, NULL);
-+ #endif
- #endif
- }
-
-@@ -415,17 +440,79 @@
-
- int window_width = cfgLoadInt("x11","width", WINDOW_WIDTH);
- int window_height = cfgLoadInt("x11","height", WINDOW_HEIGHT);
-+
- #ifdef TARGET_PANDORA
- int flags = SDL_FULLSCREEN;
- #else
- int flags = SDL_SWSURFACE;
- #endif
-- screen = SDL_SetVideoMode(window_width, window_height, 0, flags);
-- if (!screen)
-- {
-- die("error creating SDL screen");
-- }
-- x11_disp = EGL_DEFAULT_DISPLAY;
-- printf("Created SDL Windows (%ix%i) successfully\n", window_width, window_height);
-+
-+ #if !defined(GLES) && defined(USE_SDL2)
-+ flags |= SDL_WINDOW_OPENGL;
-+
-+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
-+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
-+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
-+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
-+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
-+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
-+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
-+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
-+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
-+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-+
-+ window = SDL_CreateWindow("Reicast Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, flags);
-+ if (!window)
-+ {
-+ die("error creating SDL window");
-+ }
-+
-+ glcontext = SDL_GL_CreateContext(window);
-+ if (!glcontext)
-+ {
-+ die("Error creating SDL GL context");
-+ }
-+ SDL_GL_MakeCurrent(window, NULL);
-+ #else
-+ screen = SDL_SetVideoMode(window_width, window_height, 0, flags);
-+ if (!screen)
-+ {
-+ die("error creating SDL screen");
-+ }
-+
-+ x11_disp = EGL_DEFAULT_DISPLAY;
-+ #endif
-+
-+ printf("Created SDL Window (%ix%i) and GL Context successfully\n", window_width, window_height);
- }
- #endif
-+
-+#if !defined(GLES) && defined(USE_SDL2)
-+ extern int screen_width, screen_height;
-+
-+ bool gl_init(void* wind, void* disp)
-+ {
-+ SDL_GL_MakeCurrent(window, glcontext);
-+ return gl3wInit() != -1 && gl3wIsSupported(3, 1);
-+ }
-+
-+ void gl_swap()
-+ {
-+ SDL_GL_SwapWindow(window);
-+
-+ /* Check if drawable has been resized */
-+ int new_width, new_height;
-+ SDL_GL_GetDrawableSize(window, &new_width, &new_height);
-+
-+ if (new_width != screen_width || new_height != screen_height)
-+ {
-+ screen_width = new_width;
-+ screen_height = new_height;
-+ }
-+ }
-+
-+ void gl_term()
-+ {
-+ SDL_GL_DeleteContext(glcontext);
-+ }
-+#endif
-\ No newline at end of file
-diff -Nur a/core/sdl/sdl.h b/core/sdl/sdl.h
---- a/core/sdl/sdl.h 2015-10-06 21:43:53.048336444 -0300
-+++ b/core/sdl/sdl.h 2015-10-06 22:04:39.683388790 -0300
-@@ -1,5 +1,9 @@
- #pragma once
--#include <SDL/SDL.h>
-+#ifdef USE_SDL2
-+ #include <SDL2/SDL.h>
-+#else
-+ #include <SDL/SDL.h>
-+#endif
- extern void* sdl_glc;
- extern void input_sdl_init();
- extern void input_sdl_handle(u32 port);
-diff -Nur a/shell/linux/Makefile b/shell/linux/Makefile
---- a/shell/linux/Makefile 2015-10-06 21:43:53.161337253 -0300
-+++ b/shell/linux/Makefile 2015-10-06 22:04:39.683388790 -0300
-@@ -175,6 +175,10 @@
- $(error Unknown platform)
- endif
-
-+ifdef USE_SDL2
-+ USE_SDL := 1
-+endif
-+
- RZDCY_SRC_DIR = ../../core
- include $(RZDCY_SRC_DIR)/core.mk
-
-@@ -202,8 +206,14 @@
- endif
-
- ifdef USE_SDL
-- CXXFLAGS += `sdl-config --cflags` -D USE_SDL
-- LIBS += `sdl-config --libs`
-+ CXXFLAGS += -D USE_SDL
-+ ifdef USE_SDL2
-+ CXXFLAGS += `sdl2-config --cflags` -D USE_SDL2
-+ LIBS += `sdl2-config --libs`
-+ else
-+ CXXFLAGS += `sdl-config --cflags`
-+ LIBS += `sdl-config --libs`
-+ endif
- endif
-
- ifdef PGO_MAKE
diff --git a/pcr/reicast-multilib-git/sh-block-graphs.patch b/pcr/reicast-multilib-git/sh-block-graphs.patch
deleted file mode 100644
index c8e1bcf15..000000000
--- a/pcr/reicast-multilib-git/sh-block-graphs.patch
+++ /dev/null
@@ -1,296 +0,0 @@
-diff -Nur a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp
---- a/core/hw/sh4/dyna/blockmanager.cpp 2015-10-06 21:43:53.030336315 -0300
-+++ b/core/hw/sh4/dyna/blockmanager.cpp 2015-10-06 21:58:25.685653822 -0300
-@@ -122,7 +122,11 @@
- }
- else
- {
-- printf("bm_GetBlock(%08X) failed ..\n",dynarec_code);
-+ for (iter = blkmap.begin(); iter != blkmap.end(); iter++) {
-+ if ((*iter)->contains_code((u8*)dynarec_code))
-+ return *iter;
-+ }
-+ //printf("bm_GetBlock(%p, %p) failed ..\n",dynarec_code, ngen_FailedToFindBlock);
- return 0;
- }
- }
-@@ -158,6 +162,8 @@
- verify((void*)bm_GetCode(blk->addr)==(void*)ngen_FailedToFindBlock);
- FPCA(blk->addr)=blk->code;
-
-+ verify(bm_GetBlock(blk->addr) == blk);
-+
- #ifdef DYNA_OPROF
- if (oprofHandle)
- {
-diff -Nur a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h
---- a/core/hw/sh4/dyna/blockmanager.h 2015-10-06 21:43:53.030336315 -0300
-+++ b/core/hw/sh4/dyna/blockmanager.h 2015-10-06 21:58:25.685653822 -0300
-@@ -71,6 +71,7 @@
-
- u32 memops;
- u32 linkedmemops;
-+ bool entry_block;
- };
-
- struct CachedBlockInfo: RuntimeBlockInfo_Core
-diff -Nur a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp
---- a/core/hw/sh4/dyna/decoder.cpp 2015-10-06 21:43:53.030336315 -0300
-+++ b/core/hw/sh4/dyna/decoder.cpp 2015-10-06 21:58:25.685653822 -0300
-@@ -14,6 +14,7 @@
- #include "hw/sh4/sh4_core.h"
- #include "hw/sh4/sh4_mem.h"
- #include "decoder_opcodes.h"
-+#include "../interpr/sh4_opcodes.h"
-
- #define BLOCK_MAX_SH_OPS_SOFT 500
- #define BLOCK_MAX_SH_OPS_HARD 511
-@@ -1098,6 +1099,13 @@
- else
- blk->guest_cycles+=CPU_RATIO;
-
-+ if ((state.cpu.is_delayslot && OpDesc[op]->SetPC()) ||
-+ OpDesc[op]->oph == iNotImplemented) {
-+ blk->addr = -1;
-+ return;
-+ }
-+
-+
- verify(!(state.cpu.is_delayslot && OpDesc[op]->SetPC()));
- if (state.ngen.OnlyDynamicEnds || !OpDesc[op]->rec_oph)
- {
-@@ -1168,6 +1176,8 @@
- if (settings.dynarec.idleskip)
- {
- //Experimental hash-id based idle skip
-+ if (blk->addr == 0x8C0B926A)
-+ blk->guest_cycles *= 100;
- if (strstr(idle_hash,blk->hash(false,true)))
- {
- //printf("IDLESKIP: %08X reloc match %s\n",blk->addr,blk->hash(false,true));
-diff -Nur a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp
---- a/core/hw/sh4/dyna/driver.cpp 2015-10-06 21:43:53.030336315 -0300
-+++ b/core/hw/sh4/dyna/driver.cpp 2015-10-06 21:58:25.685653822 -0300
-@@ -72,11 +72,24 @@
- LastAddr=LastAddr_min;
- memset(emit_GetCCPtr(),0xCC,emit_FreeSpace());
- }
-+
-+#include <map>
-+#include <algorithm>
-+#include <set>
-+
-+typedef map<u32, RuntimeBlockInfo*> BlockGraph;
-+
-+vector<BlockGraph*> graphs;
-+map<u32, BlockGraph*> blockgraphs;
-+
- void recSh4_ClearCache()
- {
- LastAddr=LastAddr_min;
- bm_Reset();
-
-+ graphs.clear();
-+ blockgraphs.clear();
-+
- printf("recSh4:Dynarec Cache clear at %08X\n",curr_pc);
- }
-
-@@ -212,9 +225,145 @@
- AnalyseBlock(this);
- }
-
-+void merge_graphs(BlockGraph* one, BlockGraph* two) {
-+ for (BlockGraph::iterator it = two->begin(); it != two->end(); it++) {
-+ blockgraphs[it->second->addr] = one;
-+ (*one)[it->second->addr] = it->second;
-+ }
-+ graphs.erase(find(graphs.begin(), graphs.end(), two));
-+}
-+
-+void discover_graph(u32 bootstrap) {
-+ BlockGraph* graph;
-+ set<u32> resolved;
-+ vector<u32> unresolved;
-+
-+ if (blockgraphs.count(bootstrap)) {
-+ graph = blockgraphs[bootstrap];
-+ (*graph)[bootstrap]->entry_block = true;
-+ return;
-+ } else {
-+ graph = new BlockGraph();
-+
-+ graphs.push_back(graph);
-+ }
-+
-+ unresolved.push_back(bootstrap);
-+
-+ while (unresolved.size()) {
-+ u32 pc = unresolved[unresolved.size()-1];
-+ unresolved.pop_back();
-+
-+ if (resolved.count(pc))
-+ continue;
-+
-+ if (graph->count(pc))
-+ continue;
-+
-+ if (blockgraphs.count(pc)) {
-+ verify(blockgraphs[pc] != graph);
-+ merge_graphs(blockgraphs[pc], graph);
-+ graph = blockgraphs[pc];
-+ resolved.clear();
-+ continue;
-+ }
-+
-+ resolved.insert(pc);
-+ //printf("resolving %08X\n", pc);
-+
-+ RuntimeBlockInfo* rbi = ngen_AllocateBlock();
-+ rbi->Setup(pc,fpscr);
-+ rbi->entry_block = pc == bootstrap;
-+
-+ if (rbi->addr == -1)
-+ continue;
-+
-+ (*graph)[pc] = rbi;
-+ blockgraphs[pc] = graph;
-+
-+ if (rbi->BranchBlock !=-1 && rbi->BlockType != BET_StaticCall)
-+ unresolved.push_back(rbi->BranchBlock);
-+
-+ if (rbi->NextBlock != -1)
-+ unresolved.push_back(rbi->NextBlock);
-+ }
-+
-+ int entrypoints = 0;
-+
-+ for (BlockGraph::iterator it = graph->begin(); it != graph->end(); it++) {
-+ entrypoints += it->second->entry_block;
-+ }
-+
-+ //printf("Graph: %d blocks w/ %d entrypoints, %d graphs\n", graph->size(), entrypoints, graphs.size());
-+}
-+
-+void print_graphs() {
-+ int top_runs = 0;
-+ int total_runs = 0;
-+ map<BlockGraph*, u32> graph_runs;
-+
-+ for (size_t i = 0; i < graphs.size(); i++) {
-+ BlockGraph* graph = graphs[i];
-+ for (BlockGraph::iterator it = graphs[i]->begin(); it != graphs[i]->end(); it++) {
-+
-+ RuntimeBlockInfo* natblock = bm_GetBlock(it->first);
-+ if (!natblock || natblock->runs == 0)
-+ continue;
-+
-+ if (natblock->runs > top_runs)
-+ top_runs = natblock->runs;
-+
-+ total_runs += natblock->runs;
-+
-+ graph_runs[graph] += natblock->runs;
-+ }
-+ }
-+
-+ int baseline = top_runs / 100;
-+
-+ printf("<Graphdump\n");
-+ for (size_t i = 0; i < graphs.size(); i++) {
-+ BlockGraph* graph = graphs[i];
-+ if (graph_runs[graph] < baseline)
-+ continue;
-+ printf("\tGraph: %p\n", graphs[i]);
-+
-+ int cnt = 0;
-+ int cnt2 = 0;
-+ for (BlockGraph::iterator it = graphs[i]->begin(); it != graphs[i]->end(); it++) {
-+
-+ RuntimeBlockInfo* natblock = bm_GetBlock(it->first);
-+ if (!natblock || natblock->runs == 0 || natblock->runs < baseline) {
-+ if (natblock) {
-+ cnt2++;
-+ natblock->runs = 0;
-+ } else {
-+ cnt++;
-+ }
-+ continue;
-+ }
-+ printf("\t\tBlock %08X, compiled: %d, entrypoint: %d, type: %d, len: %d, cycles: %d, runs %d, loop %d\n",
-+ it->first, natblock != 0, it->second->entry_block, it->second->BlockType, it->second->oplist.size(),
-+ it->second->guest_cycles, natblock ? natblock->runs : 0,
-+ (it->second->BlockType == BET_Cond_0 || it->second->BlockType == BET_Cond_1) && graph->count(it->second->BranchBlock) );
-+
-+ if (natblock)
-+ natblock->runs = 0;
-+ }
-+ if (cnt2) {
-+ printf("\t\t and %d more not worth mentioning\n", cnt2);
-+ }
-+ if (cnt) {
-+ printf("\t\t and %d more that never run\n", cnt);
-+ }
-+ }
-+ printf("Graphdump>\n");
-+}
-+
- DynarecCodeEntryPtr rdv_CompilePC()
- {
- u32 pc=next_pc;
-+ discover_graph(pc);
-
- if (emit_FreeSpace()<16*1024 || pc==0x8c0000e0 || pc==0xac010000 || pc==0xac008300)
- recSh4_ClearCache();
-@@ -232,6 +381,7 @@
- rbi->staging_runs=do_opts?100:-100;
- ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts);
- verify(rbi->code!=0);
-+ verify(rbi->host_code_size!=0);
-
- bm_AddBlock(rbi);
-
-diff -Nur a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp
---- a/core/linux-dist/main.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/main.cpp 2015-10-06 21:58:25.685653822 -0300
-@@ -189,6 +189,18 @@
- #if defined(USE_SDL)
- input_sdl_handle(port);
- #endif
-+
-+ //Whatever happened to these?
-+#if FEAT_SHREC != DYNAREC_NONE
-+ /*
-+ void print_graphs();
-+ if ('b' == key) emit_WriteCodeCache();
-+ if ('n' == key) bm_Reset();
-+ if ('m' == key) bm_Sort();
-+ if (',' == key) { emit_WriteCodeCache(); bm_Sort(); }
-+ if ('q' == key) print_graphs();
-+ */
-+#endif
- }
-
- void os_DoEvents()
-diff -Nur a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp
---- a/core/rec-x64/rec_x64.cpp 2015-10-06 21:43:53.045336422 -0300
-+++ b/core/rec-x64/rec_x64.cpp 2015-10-06 21:58:25.685653822 -0300
-@@ -162,6 +162,10 @@
-
- sub(dword[rax], block->guest_cycles);
-
-+ mov(rax, (size_t)&block->runs);
-+ add(dword[rax], 1);
-+
-+
- sub(rsp, 0x28);
-
- for (size_t i = 0; i < block->oplist.size(); i++) {
-@@ -355,6 +359,7 @@
-
- block->code = (DynarecCodeEntryPtr)getCode();
-
-+ block->host_code_size = getSize();
- emit_Skip(getSize());
- }
-
diff --git a/pcr/reicast-multilib-git/ta-hash-logs.patch b/pcr/reicast-multilib-git/ta-hash-logs.patch
deleted file mode 100644
index 1d120852f..000000000
--- a/pcr/reicast-multilib-git/ta-hash-logs.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-diff -Nur a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp
---- a/core/hw/pvr/Renderer_if.cpp 2015-10-06 21:43:53.028336301 -0300
-+++ b/core/hw/pvr/Renderer_if.cpp 2015-10-06 21:49:25.016725724 -0300
-@@ -5,10 +5,16 @@
-
- #include "deps/zlib/zlib.h"
-
-+#include "deps/crypto/md5.h"
-+
- #if FEAT_HAS_NIXPROF
- #include "profiler/profiler.h"
- #endif
-
-+#define FRAME_MD5 0x1
-+FILE* fLogFrames;
-+FILE* fCheckFrames;
-+
- /*
-
- rendv3 ideas
-@@ -291,6 +297,48 @@
-
- if (ctx)
- {
-+ if (fLogFrames || fCheckFrames) {
-+ MD5Context md5;
-+ u8 digest[16];
-+
-+ MD5Init(&md5);
-+ MD5Update(&md5, ctx->tad.thd_root, ctx->tad.End() - ctx->tad.thd_root);
-+ MD5Final(digest, &md5);
-+
-+ if (fLogFrames) {
-+ fputc(FRAME_MD5, fLogFrames);
-+ fwrite(digest, 1, 16, fLogFrames);
-+ fflush(fLogFrames);
-+ }
-+
-+ if (fCheckFrames) {
-+ u8 v;
-+ u8 digest2[16];
-+ int ch = fgetc(fCheckFrames);
-+
-+ if (ch == EOF) {
-+ printf("Testing: TA Hash log matches, exiting\n");
-+ exit(1);
-+ }
-+
-+ verify(ch == FRAME_MD5);
-+
-+ fread(digest2, 1, 16, fCheckFrames);
-+
-+ verify(memcmp(digest, digest2, 16) == 0);
-+
-+
-+ }
-+
-+ /*
-+ u8* dig = digest;
-+ printf("FRAME: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
-+ digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
-+ digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]
-+ );
-+ */
-+ }
-+
- if (!ctx->rend.Overrun)
- {
- //printf("REP: %.2f ms\n",render_end_pending_cycles/200000.0);
-@@ -366,6 +414,13 @@
-
- bool rend_init()
- {
-+ if (fLogFrames = fopen(settings.pvr.HashLogFile.c_str(), "wb")) {
-+ printf("Saving frame hashes to: '%s'\n", settings.pvr.HashLogFile.c_str());
-+ }
-+
-+ if (fCheckFrames = fopen(settings.pvr.HashCheckFile.c_str(), "rb")) {
-+ printf("Comparing frame hashes against: '%s'\n", settings.pvr.HashCheckFile.c_str());
-+ }
-
- #ifdef NO_REND
- renderer = rend_norend();
-@@ -435,6 +490,11 @@
-
- void rend_term()
- {
-+ if (fCheckFrames)
-+ fclose(fCheckFrames);
-+
-+ if (fLogFrames)
-+ fclose(fLogFrames);
- }
-
- void rend_vblank()
-diff -Nur a/core/nullDC.cpp b/core/nullDC.cpp
---- a/core/nullDC.cpp 2015-10-06 21:43:53.043336408 -0300
-+++ b/core/nullDC.cpp 2015-10-06 21:49:25.017725731 -0300
-@@ -260,6 +260,8 @@
- #endif
-
- settings.bios.UseReios = cfgLoadInt("config", "bios.UseReios", 0);
-+ settings.pvr.HashLogFile = cfgLoadStr("testing", "ta.HashLogFile", "");
-+ settings.pvr.HashCheckFile = cfgLoadStr("testing", "ta.HashCheckFile", "");
-
- #if (HOST_OS != OS_LINUX || defined(_ANDROID) || defined(TARGET_PANDORA))
- settings.aica.BufferSize=2048;
-diff -Nur a/core/types.h b/core/types.h
---- a/core/types.h 2015-10-06 21:43:53.048336444 -0300
-+++ b/core/types.h 2015-10-06 21:49:25.017725731 -0300
-@@ -696,6 +696,9 @@
-
- u32 MaxThreads;
- u32 SynchronousRendering;
-+
-+ string HashLogFile;
-+ string HashCheckFile;
- } pvr;
-
- struct {