summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pcr/reicast-git/PKGBUILD15
-rw-r--r--pcr/reicast-git/generalize-mappings.patch1979
-rw-r--r--pcr/reicast-git/loop-tracing.patch109
-rw-r--r--pcr/reicast-git/refactor-rend-stuff.patch1244
-rw-r--r--pcr/reicast-git/sdl-opengl.patch251
5 files changed, 0 insertions, 3598 deletions
diff --git a/pcr/reicast-git/PKGBUILD b/pcr/reicast-git/PKGBUILD
index 60c2fbf93..d6d7fa040 100644
--- a/pcr/reicast-git/PKGBUILD
+++ b/pcr/reicast-git/PKGBUILD
@@ -17,11 +17,6 @@ depends=('libgl' 'alsa-plugins' 'libpulse' 'python-evdev') # 'sdl2')
source=(${_pkgname}-${pkgver}::"git+https://github.com/${_pkgname}/${_pkgname}-emulator.git"
'fix-dyna-constprop.patch'
'futuristic-memops.patch'
- 'generalize-mappings.patch'
- 'loop-tracing.patch'
- 'loungekatt_rm-nonfree-fp.patch'
- 'refactor-rend-stuff.patch'
- 'sdl-opengl.patch'
'sh-block-graphs.patch'
'fix-android-translations.patch'
'purupuru.patch'
@@ -29,11 +24,6 @@ source=(${_pkgname}-${pkgver}::"git+https://github.com/${_pkgname}/${_pkgname}-e
sha256sums=('SKIP'
'c14287cf2b2289b9de28cedeee06fcb89ca40da50e34607780dce55d7d8e5fd6'
'ce3fe9f10555c473cafbf4e85724ebe7a8535a1fa3bfae3c9bc0fe518024f71e'
- '4c0227db07dc9fa4713694bc438345261e401e0b10c89b25a3c1d20ac9acd9b9'
- 'af47982ca67babb18a96014643c2394b45316f474c3b07b4e38079f780606fce'
- '4a6025daded179e88174057affadbcfd539d919c35c36945aa3273fab0b0cb49'
- 'aead8326ac6815b555be03030ffbdc8f6ced625c980e77eca89e570591c5eb34'
- 'cf386ebaeafce046a1fc971a5b140bb6a1245840ad2c2a341541327ed6f5606c'
'94694d1b615facb39b5ee92ed90c6cefc77fab23fb97f2fcc82e0aa6e1cb14c5'
'a651fd92d1bfbef0a1ca524c54b2a59a8a45c53ef76a1fe53d36d87abef93a85'
'02b01a8b1a33aa543213371ec6022559c1eebbeb2d6a20173995ee618d7396a1'
@@ -61,11 +51,6 @@ prepare() {
# 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"/fix-android-translations.patch
diff --git a/pcr/reicast-git/generalize-mappings.patch b/pcr/reicast-git/generalize-mappings.patch
deleted file mode 100644
index a47681f39..000000000
--- a/pcr/reicast-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-git/loop-tracing.patch b/pcr/reicast-git/loop-tracing.patch
deleted file mode 100644
index 2e2b5ea97..000000000
--- a/pcr/reicast-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-git/refactor-rend-stuff.patch b/pcr/reicast-git/refactor-rend-stuff.patch
deleted file mode 100644
index 187ccb8d0..000000000
--- a/pcr/reicast-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-git/sdl-opengl.patch b/pcr/reicast-git/sdl-opengl.patch
deleted file mode 100644
index 372ec9a52..000000000
--- a/pcr/reicast-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