summaryrefslogtreecommitdiff
path: root/pcr/reicast-multilib-git/generalize-mappings.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pcr/reicast-multilib-git/generalize-mappings.patch')
-rw-r--r--pcr/reicast-multilib-git/generalize-mappings.patch1979
1 files changed, 0 insertions, 1979 deletions
diff --git a/pcr/reicast-multilib-git/generalize-mappings.patch b/pcr/reicast-multilib-git/generalize-mappings.patch
deleted file mode 100644
index a47681f39..000000000
--- a/pcr/reicast-multilib-git/generalize-mappings.patch
+++ /dev/null
@@ -1,1979 +0,0 @@
-diff -Nur a/core/linux-dist/bimap.h b/core/linux-dist/bimap.h
---- a/core/linux-dist/bimap.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/bimap.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,67 @@
-+/* SimpleBimap
-+ *
-+ * A basic implementation of a bidirectional map that not only allows
-+ * you to get a mapped value from a key, but also the other way around.
-+ * Deleting elements and other fancy (and not-so-fancy) stuff is not
-+ * supported.
-+ *
-+ * Usage example:
-+ * SimpleBimap<std::string, std::string> bimap;
-+ * bimap.insert("foo", "bar");
-+ * printf("foo -> %s\n", bimap.get_by_key("foo")->c_str());
-+ * printf("bar <- %s\n", bimap.get_by_value("bar")->c_str());
-+ * if(bimap.get_by_key("somekey") == NULL)
-+ * puts("somekey not found");
-+ *
-+ * The above example's output:
-+ * foo -> bar
-+ * bar <- foo
-+ * somekey not found
-+ */
-+#include <cstddef>
-+#include <utility>
-+#include <map>
-+
-+template<typename T1, typename T2>
-+class SimpleBimap
-+{
-+ private:
-+ typedef typename std::map<T2, T1*> MapA;
-+ typedef typename std::map<T1, T2*> MapB;
-+ MapA map_a;
-+ MapB map_b;
-+ public:
-+ void insert(const T1& a, const T2& b)
-+ {
-+ // create first pair
-+ typename MapA::iterator iter_a = map_a.insert(std::pair<T2, T1*>(b, NULL)).first;
-+ T2* ptr_b = const_cast<T2*>(&(iter_a->first));
-+
-+ // insert second pair (a, pointer_to_b)
-+ typename MapB::iterator iter_b = map_b.insert(std::pair<T1, T2*>(a, ptr_b)).first;
-+
-+ // update pointer in map_a to point to a
-+ T1* ptr_a = const_cast<T1*>(&(iter_b->first));
-+ iter_a->second = ptr_a;
-+ }
-+
-+ const T2* get_by_key(const T1 &a)
-+ {
-+ typename MapB::iterator it = this->map_b.find(a);
-+ if(it != this->map_b.end())
-+ {
-+ return (it->second);
-+ }
-+ return NULL;
-+ }
-+
-+ const T1* get_by_value(const T2 &b)
-+ {
-+ typename MapA::iterator it = this->map_a.find(b);
-+ if(it != this->map_a.end())
-+ {
-+ return (it->second);
-+ }
-+ return NULL;
-+ }
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/evdev.cpp b/core/linux-dist/evdev.cpp
---- a/core/linux-dist/evdev.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/evdev.cpp 1969-12-31 21:00:00.000000000 -0300
-@@ -1,450 +0,0 @@
--#include <unistd.h>
--#include <fcntl.h>
--#include <linux/input.h>
--#include "linux-dist/evdev.h"
--#include "linux-dist/main.h"
--#include "cfg/ini.h"
--#include <vector>
--#include <map>
--#include <dlfcn.h>
--
--#if defined(USE_EVDEV)
-- bool libevdev_tried = false;
-- bool libevdev_available = false;
-- typedef int (*libevdev_func1_t)(int, const char*);
-- typedef const char* (*libevdev_func2_t)(int, int);
-- libevdev_func1_t libevdev_event_code_from_name;
-- libevdev_func2_t libevdev_event_code_get_name;
--
-- void load_libevdev()
-- {
-- if (libevdev_tried)
-- {
-- return;
-- }
--
-- libevdev_tried = true;
-- void* lib_handle = dlopen("libevdev.so", RTLD_NOW);
--
-- bool failed = false;
--
-- if (!lib_handle)
-- {
-- fprintf(stderr, "%s\n", dlerror());
-- failed = true;
-- }
-- else
-- {
-- libevdev_event_code_from_name = reinterpret_cast<libevdev_func1_t>(dlsym(lib_handle, "libevdev_event_code_from_name"));
--
-- const char* error1 = dlerror();
-- if (error1 != NULL)
-- {
-- fprintf(stderr, "%s\n", error1);
-- failed = true;
-- }
--
-- libevdev_event_code_get_name = reinterpret_cast<libevdev_func2_t>(dlsym(lib_handle, "libevdev_event_code_get_name"));
--
-- const char* error2 = dlerror();
-- if (error2 != NULL)
-- {
-- fprintf(stderr, "%s\n", error2);
-- failed = true;
-- }
-- }
--
-- if(failed)
-- {
-- puts("WARNING: libevdev is not available. You'll not be able to use button names instead of numeric codes in your controller mappings!\n");
-- return;
-- }
--
-- libevdev_available = true;
-- }
--
-- s8 EvdevAxisData::convert(s32 value)
-- {
-- return (((value - min) * 255) / range);
-- }
--
-- void EvdevAxisData::init(int fd, int code, bool inverted)
-- {
-- struct input_absinfo abs;
-- if(code < 0 || ioctl(fd, EVIOCGABS(code), &abs))
-- {
-- if(code >= 0)
-- {
-- perror("evdev ioctl");
-- }
-- this->range = 255;
-- this->min = 0;
-- return;
-- }
-- s32 min = abs.minimum;
-- s32 max = abs.maximum;
-- printf("evdev: range of axis %d is from %d to %d\n", code, min, max);
-- if(inverted)
-- {
-- this->range = (min - max);
-- this->min = max;
-- }
-- else
-- {
-- this->range = (max - min);
-- this->min = min;
-- }
-- }
--
-- void EvdevController::init()
-- {
-- this->data_x.init(this->fd, this->mapping->Axis_Analog_X, this->mapping->Axis_Analog_X_Inverted);
-- this->data_y.init(this->fd, this->mapping->Axis_Analog_Y, this->mapping->Axis_Analog_Y_Inverted);
-- this->data_trigger_left.init(this->fd, this->mapping->Axis_Trigger_Left, this->mapping->Axis_Trigger_Left_Inverted);
-- this->data_trigger_right.init(this->fd, this->mapping->Axis_Trigger_Right, this->mapping->Axis_Trigger_Right_Inverted);
-- }
--
-- std::map<std::string, EvdevControllerMapping> loaded_mappings;
--
-- int load_keycode(ConfigFile* cfg, string section, string dc_key)
-- {
-- int code = -1;
--
-- string keycode = cfg->get(section, dc_key, "-1");
-- if (strstr(keycode.c_str(), "KEY_") != NULL ||
-- strstr(keycode.c_str(), "BTN_") != NULL ||
-- strstr(keycode.c_str(), "ABS_") != NULL)
-- {
-- if(libevdev_available)
-- {
-- int type = ((strstr(keycode.c_str(), "ABS_") != NULL) ? EV_ABS : EV_KEY);
-- code = libevdev_event_code_from_name(type, keycode.c_str());
-- }
-- if(code < 0)
-- {
-- printf("evdev: failed to find keycode for '%s'\n", keycode.c_str());
-- }
-- else
-- {
-- printf("%s = %s (%d)\n", dc_key.c_str(), keycode.c_str(), code);
-- }
-- return code;
-- }
--
-- code = cfg->get_int(section, dc_key, -1);
-- if(code >= 0)
-- {
-- char* name = NULL;
-- if(libevdev_available)
-- {
-- int type = ((strstr(dc_key.c_str(), "axis_") != NULL) ? EV_ABS : EV_KEY);
-- name = (char*)libevdev_event_code_get_name(type, code);
-- }
-- if (name != NULL)
-- {
-- printf("%s = %s (%d)\n", dc_key.c_str(), name, code);
-- }
-- else
-- {
-- printf("%s = %d\n", dc_key.c_str(), code);
-- }
-- }
-- return code;
-- }
--
-- EvdevControllerMapping load_mapping(FILE* fd)
-- {
-- ConfigFile mf;
-- mf.parse(fd);
--
-- EvdevControllerMapping mapping = {
-- mf.get("emulator", "mapping_name", "<Unknown>").c_str(),
-- load_keycode(&mf, "dreamcast", "btn_a"),
-- load_keycode(&mf, "dreamcast", "btn_b"),
-- load_keycode(&mf, "dreamcast", "btn_c"),
-- load_keycode(&mf, "dreamcast", "btn_d"),
-- load_keycode(&mf, "dreamcast", "btn_x"),
-- load_keycode(&mf, "dreamcast", "btn_y"),
-- load_keycode(&mf, "dreamcast", "btn_z"),
-- load_keycode(&mf, "dreamcast", "btn_start"),
-- load_keycode(&mf, "emulator", "btn_escape"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_left"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_right"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_up"),
-- load_keycode(&mf, "dreamcast", "btn_dpad1_down"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_left"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_right"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_up"),
-- load_keycode(&mf, "dreamcast", "btn_dpad2_down"),
-- load_keycode(&mf, "compat", "btn_trigger_left"),
-- load_keycode(&mf, "compat", "btn_trigger_right"),
-- load_keycode(&mf, "compat", "axis_dpad1_x"),
-- load_keycode(&mf, "compat", "axis_dpad1_y"),
-- load_keycode(&mf, "compat", "axis_dpad2_x"),
-- load_keycode(&mf, "compat", "axis_dpad2_y"),
-- load_keycode(&mf, "dreamcast", "axis_x"),
-- load_keycode(&mf, "dreamcast", "axis_y"),
-- load_keycode(&mf, "dreamcast", "axis_trigger_left"),
-- load_keycode(&mf, "dreamcast", "axis_trigger_right"),
-- mf.get_bool("compat", "axis_x_inverted", false),
-- mf.get_bool("compat", "axis_y_inverted", false),
-- mf.get_bool("compat", "axis_trigger_left_inverted", false),
-- mf.get_bool("compat", "axis_trigger_right_inverted", false)
-- };
-- return mapping;
-- }
--
-- int input_evdev_init(EvdevController* controller, const char* device, const char* custom_mapping_fname = NULL)
-- {
-- load_libevdev();
--
-- char name[256] = "Unknown";
--
-- printf("evdev: Trying to open device at '%s'\n", device);
--
-- int fd = open(device, O_RDONLY);
--
-- if (fd >= 0)
-- {
-- fcntl(fd, F_SETFL, O_NONBLOCK);
-- if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)
-- {
-- perror("evdev: ioctl");
-- return -2;
-- }
-- else
-- {
-- printf("evdev: Found '%s' at '%s'\n", name, device);
--
-- controller->fd = fd;
--
-- const char* mapping_fname;
--
-- if(custom_mapping_fname != NULL)
-- {
-- mapping_fname = custom_mapping_fname;
-- }
-- else
-- {
-- #if defined(TARGET_PANDORA)
-- mapping_fname = "controller_pandora.cfg";
-- #elif defined(TARGET_GCW0)
-- mapping_fname = "controller_gcwz.cfg";
-- #else
-- if (strcmp(name, "Microsoft X-Box 360 pad") == 0 ||
-- strcmp(name, "Xbox 360 Wireless Receiver") == 0 ||
-- strcmp(name, "Xbox 360 Wireless Receiver (XBOX)") == 0)
-- {
-- mapping_fname = "controller_xpad.cfg";
-- }
-- else if (strstr(name, "Xbox Gamepad (userspace driver)") != NULL)
-- {
-- mapping_fname = "controller_xboxdrv.cfg";
-- }
-- else if (strstr(name, "keyboard") != NULL ||
-- strstr(name, "Keyboard") != NULL)
-- {
-- mapping_fname = "keyboard.cfg";
-- }
-- else
-- {
-- mapping_fname = "controller_generic.cfg";
-- }
-- #endif
-- }
-- if(loaded_mappings.count(string(mapping_fname)) == 0)
-- {
-- FILE* mapping_fd = NULL;
-- if(mapping_fname[0] == '/')
-- {
-- // Absolute mapping
-- mapping_fd = fopen(mapping_fname, "r");
-- }
-- else
-- {
-- // Mapping from ~/.reicast/mappings/
-- size_t size_needed = snprintf(NULL, 0, EVDEV_MAPPING_PATH, mapping_fname) + 1;
-- char* mapping_path = (char*)malloc(size_needed);
-- sprintf(mapping_path, EVDEV_MAPPING_PATH, mapping_fname);
-- mapping_fd = fopen(get_readonly_data_path(mapping_path).c_str(), "r");
-- free(mapping_path);
-- }
--
-- if(mapping_fd != NULL)
-- {
-- printf("evdev: reading mapping file: '%s'\n", mapping_fname);
-- loaded_mappings.insert(std::make_pair(string(mapping_fname), load_mapping(mapping_fd)));
-- fclose(mapping_fd);
--
-- }
-- else
-- {
-- printf("evdev: unable to open mapping file '%s'\n", mapping_fname);
-- perror("evdev");
-- return -3;
-- }
-- }
-- controller->mapping = &loaded_mappings[string(mapping_fname)];
-- printf("evdev: Using '%s' mapping\n", controller->mapping->name);
-- controller->init();
--
-- return 0;
-- }
-- }
-- else
-- {
-- perror("evdev: open");
-- return -1;
-- }
-- }
--
-- bool input_evdev_handle(EvdevController* controller, u32 port)
-- {
-- #define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
-- if (controller->fd < 0 || controller->mapping == NULL)
-- {
-- return false;
-- }
--
-- input_event ie;
--
-- while(read(controller->fd, &ie, sizeof(ie)) == sizeof(ie))
-- {
-- switch(ie.type)
-- {
-- case EV_KEY:
-- if (ie.code == controller->mapping->Btn_A) {
-- SET_FLAG(kcode[port], DC_BTN_A, ie.value);
-- } else if (ie.code == controller->mapping->Btn_B) {
-- SET_FLAG(kcode[port], DC_BTN_B, ie.value);
-- } else if (ie.code == controller->mapping->Btn_C) {
-- SET_FLAG(kcode[port], DC_BTN_C, ie.value);
-- } else if (ie.code == controller->mapping->Btn_D) {
-- SET_FLAG(kcode[port], DC_BTN_D, ie.value);
-- } else if (ie.code == controller->mapping->Btn_X) {
-- SET_FLAG(kcode[port], DC_BTN_X, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Y) {
-- SET_FLAG(kcode[port], DC_BTN_Y, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Z) {
-- SET_FLAG(kcode[port], DC_BTN_Z, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Start) {
-- SET_FLAG(kcode[port], DC_BTN_START, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Escape) {
-- die("death by escape key");
-- } else if (ie.code == controller->mapping->Btn_DPad_Left) {
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad_Right) {
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad_Up) {
-- SET_FLAG(kcode[port], DC_DPAD_UP, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad_Down) {
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Left) {
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Right) {
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Up) {
-- SET_FLAG(kcode[port], DC_DPAD2_UP, ie.value);
-- } else if (ie.code == controller->mapping->Btn_DPad2_Down) {
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, ie.value);
-- } else if (ie.code == controller->mapping->Btn_Trigger_Left) {
-- lt[port] = (ie.value ? 255 : 0);
-- } else if (ie.code == controller->mapping->Btn_Trigger_Right) {
-- rt[port] = (ie.value ? 255 : 0);
-- }
-- break;
-- case EV_ABS:
-- if (ie.code == controller->mapping->Axis_DPad_X)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 1);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD_RIGHT, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_DPad_Y)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 1);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD_DOWN, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_DPad2_X)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 1);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD2_LEFT, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_RIGHT, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_DPad2_X)
-- {
-- switch(ie.value)
-- {
-- case -1:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 1);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 0);
-- break;
-- case 0:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 0);
-- break;
-- case 1:
-- SET_FLAG(kcode[port], DC_DPAD2_UP, 0);
-- SET_FLAG(kcode[port], DC_DPAD2_DOWN, 1);
-- break;
-- }
-- }
-- else if (ie.code == controller->mapping->Axis_Analog_X)
-- {
-- joyx[port] = (controller->data_x.convert(ie.value) + 128);
-- }
-- else if (ie.code == controller->mapping->Axis_Analog_Y)
-- {
-- joyy[port] = (controller->data_y.convert(ie.value) + 128);
-- }
-- else if (ie.code == controller->mapping->Axis_Trigger_Left)
-- {
-- lt[port] = controller->data_trigger_left.convert(ie.value);
-- }
-- else if (ie.code == controller->mapping->Axis_Trigger_Right)
-- {
-- rt[port] = controller->data_trigger_right.convert(ie.value);
-- }
-- break;
-- }
-- }
-- }
--#endif
--
-diff -Nur a/core/linux-dist/evdev.h b/core/linux-dist/evdev.h
---- a/core/linux-dist/evdev.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/evdev.h 1969-12-31 21:00:00.000000000 -0300
-@@ -1,74 +0,0 @@
--#pragma once
--#include <linux/input.h>
--#include "types.h"
--
--struct EvdevControllerMapping
--{
-- const char* name;
-- const int Btn_A;
-- const int Btn_B;
-- const int Btn_C;
-- const int Btn_D;
-- const int Btn_X;
-- const int Btn_Y;
-- const int Btn_Z;
-- const int Btn_Start;
-- const int Btn_Escape;
-- const int Btn_DPad_Left;
-- const int Btn_DPad_Right;
-- const int Btn_DPad_Up;
-- const int Btn_DPad_Down;
-- const int Btn_DPad2_Left;
-- const int Btn_DPad2_Right;
-- const int Btn_DPad2_Up;
-- const int Btn_DPad2_Down;
-- const int Btn_Trigger_Left;
-- const int Btn_Trigger_Right;
-- const int Axis_DPad_X;
-- const int Axis_DPad_Y;
-- const int Axis_DPad2_X;
-- const int Axis_DPad2_Y;
-- const int Axis_Analog_X;
-- const int Axis_Analog_Y;
-- const int Axis_Trigger_Left;
-- const int Axis_Trigger_Right;
-- const bool Axis_Analog_X_Inverted;
-- const bool Axis_Analog_Y_Inverted;
-- const bool Axis_Trigger_Left_Inverted;
-- const bool Axis_Trigger_Right_Inverted;
--};
--
--struct EvdevAxisData
--{
-- s32 range; // smaller size than 32 bit might cause integer overflows
-- s32 min;
-- void init(int fd, int code, bool inverted);
-- s8 convert(int value);
--};
--
--struct EvdevController
--{
-- int fd;
-- EvdevControllerMapping* mapping;
-- EvdevAxisData data_x;
-- EvdevAxisData data_y;
-- EvdevAxisData data_trigger_left;
-- EvdevAxisData data_trigger_right;
-- void init();
--};
--
--#define EVDEV_DEVICE_CONFIG_KEY "evdev_device_id_%d"
--#define EVDEV_MAPPING_CONFIG_KEY "evdev_mapping_%d"
--#define EVDEV_DEVICE_STRING "/dev/input/event%d"
--#define EVDEV_MAPPING_PATH "/mappings/%s"
--
--#ifdef TARGET_PANDORA
-- #define EVDEV_DEFAULT_DEVICE_ID_1 4
--#else
-- #define EVDEV_DEFAULT_DEVICE_ID_1 0
--#endif
--
--#define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : -1)
--
--extern int input_evdev_init(EvdevController* controller, const char* device, const char* mapping_fname);
--extern bool input_evdev_handle(EvdevController* controller, u32 port);
-diff -Nur a/core/linux-dist/handler.cpp b/core/linux-dist/handler.cpp
---- a/core/linux-dist/handler.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,263 @@
-+#include "handler.h"
-+
-+#define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
-+static InputAxisID axis_ids[] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_TRIGGER_LEFT, DC_AXIS_TRIGGER_RIGHT, EMU_AXIS_DPAD1_X, EMU_AXIS_DPAD1_Y, EMU_AXIS_DPAD2_X, EMU_AXIS_DPAD2_Y };
-+
-+InputAxisConverter::InputAxisConverter(bool inverted, InputAxisLimits limits)
-+{
-+ this->m_deadzone = limits.deadzone;
-+ if(inverted)
-+ {
-+ this->m_range = (limits.minimum - limits.maximum);
-+ this->m_minimum = limits.maximum;
-+ }
-+ else
-+ {
-+ this->m_range = (limits.maximum - limits.minimum);
-+ this->m_minimum = limits.minimum;
-+ }
-+}
-+
-+s8 InputAxisConverter::convert(s32 value)
-+{
-+ // If value is in deadzone, return 0
-+ if (this->m_deadzone && ((value >= 0 && value <= this->m_deadzone) || (value < 0 && value >= -this->m_deadzone)))
-+ {
-+ return 0;
-+ }
-+ if (this->m_range)
-+ {
-+ return (((value - this->m_minimum) * 255) / this->m_range);
-+ }
-+ return value;
-+}
-+
-+InputMappingStore InputHandler::s_mappingstore;
-+
-+
-+InputHandler::InputHandler()
-+{
-+ this->m_initialized = false;
-+}
-+
-+InputHandler::~InputHandler()
-+{
-+ //TODO;
-+}
-+
-+bool InputHandler::initialize(u32 port, std::string device, std::string custom_mapping_filename)
-+{
-+ if(this->m_initialized)
-+ {
-+ printf("%s: Handler is already initialized!\n", this->get_api_name().c_str());
-+ return true;
-+ }
-+
-+ this->m_port = port;
-+
-+ bool success = this->setup_device(device);
-+
-+ if(!success)
-+ {
-+ printf("%s: Initialization of device '%s' failed!\n", this->get_api_name().c_str(), device.c_str());
-+ return false;
-+ }
-+
-+ if(custom_mapping_filename.empty())
-+ {
-+ this->m_mapping = NULL;
-+ }
-+ else
-+ {
-+ this->m_mapping = InputHandler::s_mappingstore.get(custom_mapping_filename, this->get_api_name());
-+ }
-+
-+ if(this->m_mapping == NULL)
-+ {
-+ if(!custom_mapping_filename.empty())
-+ {
-+ printf("%s: Loading custom mapping '%s' failed!\n", this->get_api_name().c_str(), custom_mapping_filename.c_str());
-+ }
-+ std::string default_mapping_filename = this->get_default_mapping_filename();
-+ if(default_mapping_filename.empty())
-+ {
-+ printf("%s: No default mapping available!\n", this->get_api_name().c_str());
-+ }
-+ else
-+ {
-+ printf("%s: Using default mapping '%s'.\n", this->get_api_name().c_str(), default_mapping_filename.c_str());
-+ this->m_mapping = InputHandler::s_mappingstore.get(default_mapping_filename, this->get_api_name());
-+ }
-+ }
-+
-+
-+ if(this->m_mapping == NULL)
-+ {
-+ printf("%s: Couldn't load a mapping!\n", this->get_api_name().c_str());
-+ return false;
-+ }
-+
-+ for(int i = 0; i < 8; i++)
-+ {
-+ InputAxisID id = axis_ids[i];
-+ const InputAxisCode* code = this->m_mapping->get_axis_code(id);
-+ if(code != NULL)
-+ {
-+ InputAxisLimits limits;
-+ this->get_axis_limits(*code, limits);
-+ if(limits.minimum != limits.maximum)
-+ {
-+ bool inverted = this->m_mapping->get_axis_inverted(*code);
-+ this->enable_axis_converter(id, inverted, limits);
-+ }
-+ }
-+ }
-+ this->m_initialized = true;
-+ return true;
-+}
-+
-+bool InputHandler::is_initialized()
-+{
-+ return this->m_initialized;
-+}
-+
-+std::string InputHandler::get_default_mapping_filename()
-+{
-+ return "default.cfg";
-+}
-+
-+void InputHandler::get_axis_limits(const InputAxisCode code, InputAxisLimits& limits)
-+{
-+ // Default stub, can be overridden in subclasses
-+ limits.minimum = 0;
-+ limits.maximum = 0;
-+ limits.deadzone = 0;
-+}
-+
-+void InputHandler::handle_button(InputButtonCode code, int value)
-+{
-+ if(this->m_mapping == NULL)
-+ {
-+ return;
-+ }
-+ const InputButtonID* button_id = this->m_mapping->get_button_id(code);
-+ if(button_id == NULL)
-+ {
-+ printf("Ignoring %d (%d)\n", code, button_id);
-+ return;
-+ }
-+ switch(*button_id)
-+ {
-+ case EMU_BTN_ESCAPE:
-+ if(value)
-+ {
-+ die("death by escape key");
-+ }
-+ break;
-+ case EMU_BTN_TRIGGER_LEFT:
-+ lt[this->m_port] = (value ? 255 : 0);
-+ break;
-+ case EMU_BTN_TRIGGER_RIGHT:
-+ rt[this->m_port] = (value ? 255 : 0);
-+ break;
-+ default:
-+ SET_FLAG(kcode[this->m_port], *button_id, value);
-+ };
-+}
-+
-+void InputHandler::handle_axis(InputAxisCode code, int value)
-+{
-+ if(this->m_mapping == NULL)
-+ {
-+ return;
-+ }
-+ const InputAxisID* axis_id = this->m_mapping->get_axis_id(code);
-+ if(axis_id == NULL)
-+ {
-+ printf("Ignoring %d\n", code);
-+ return;
-+ }
-+ switch(*axis_id)
-+ {
-+ case EMU_AXIS_DPAD1_X:
-+ case EMU_AXIS_DPAD1_Y:
-+ case EMU_AXIS_DPAD2_X:
-+ case EMU_AXIS_DPAD2_Y:
-+ {
-+ InputButtonID axis_button_id[2];
-+ switch(*axis_id)
-+ {
-+ case EMU_AXIS_DPAD1_X:
-+ axis_button_id[0] = DC_BTN_DPAD1_LEFT;
-+ axis_button_id[1] = DC_BTN_DPAD1_RIGHT;
-+ break;
-+ case EMU_AXIS_DPAD1_Y:
-+ axis_button_id[0] = DC_BTN_DPAD1_UP;
-+ axis_button_id[1] = DC_BTN_DPAD1_DOWN;
-+ break;
-+ case EMU_AXIS_DPAD2_X:
-+ axis_button_id[0] = DC_BTN_DPAD2_LEFT;
-+ axis_button_id[1] = DC_BTN_DPAD2_RIGHT;
-+ break;
-+ case EMU_AXIS_DPAD2_Y:
-+ axis_button_id[0] = DC_BTN_DPAD2_UP;
-+ axis_button_id[1] = DC_BTN_DPAD2_DOWN;
-+ }
-+ bool axis_button_value[2];
-+ axis_button_value[0] = (value < 0);
-+ axis_button_value[1] = (value > 0);
-+ SET_FLAG(kcode[this->m_port], axis_button_id[0], axis_button_value[0]);
-+ SET_FLAG(kcode[this->m_port], axis_button_id[1], axis_button_value[1]);
-+ break;
-+ }
-+ case DC_AXIS_X:
-+ case DC_AXIS_Y:
-+ case DC_AXIS_TRIGGER_LEFT:
-+ case DC_AXIS_TRIGGER_RIGHT:
-+ {
-+ InputAxisConverter* converter = this->get_axis_converter(*axis_id);
-+ s8 converted_value = ((converter == NULL) ? value : converter->convert(value));
-+ switch(*axis_id)
-+ {
-+ case DC_AXIS_X:
-+ joyx[this->m_port] = (converted_value + 128);
-+ break;
-+ case DC_AXIS_Y:
-+ joyy[this->m_port] = (converted_value + 128);
-+ break;
-+ case DC_AXIS_TRIGGER_LEFT:
-+ lt[this->m_port] = converted_value;
-+ break;
-+ case DC_AXIS_TRIGGER_RIGHT:
-+ rt[this->m_port] = converted_value;
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+void InputHandler::enable_axis_converter(InputAxisID axis, bool inverted, InputAxisLimits limits)
-+{
-+ this->disable_axis_converter(axis); // Delete old axis converter
-+ this->m_axis_converters[axis] = new InputAxisConverter(inverted, limits);
-+}
-+
-+void InputHandler::disable_axis_converter(InputAxisID axis)
-+{
-+ InputAxisConverterStore::iterator iter = this->m_axis_converters.find(axis);
-+ if(iter != this->m_axis_converters.end())
-+ {
-+ delete iter->second;
-+ this->m_axis_converters.erase(iter);
-+ }
-+}
-+
-+InputAxisConverter* InputHandler::get_axis_converter(InputAxisID axis)
-+{
-+ InputAxisConverterStore::iterator iter = this->m_axis_converters.find(axis);
-+ if(iter == this->m_axis_converters.end())
-+ {
-+ return NULL;
-+ }
-+ return iter->second;
-+}
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler_evdev.cpp b/core/linux-dist/handler_evdev.cpp
---- a/core/linux-dist/handler_evdev.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_evdev.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,132 @@
-+#if defined(USE_EVDEV)
-+#include "handler_evdev.h"
-+#include <cstring>
-+#include <cerrno>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <linux/input.h>
-+
-+#define EVDEV_DEVICE_STRING "/dev/input/event%s"
-+
-+void EvdevInputHandler::get_axis_limits(const InputAxisCode code, InputAxisLimits& limits)
-+{
-+ struct input_absinfo abs;
-+ if(!this->m_evdev_fd < 0 || code < 0 || ioctl(this->m_evdev_fd, EVIOCGABS(code), &abs))
-+ {
-+ if(this->m_evdev_fd >= 0 && code >= 0)
-+ {
-+ perror("evdev ioctl");
-+ }
-+ limits.minimum = 0;
-+ limits.maximum = 0;
-+ limits.deadzone = 0;
-+ return;
-+ }
-+ limits.minimum = abs.minimum;
-+ limits.maximum = abs.maximum;
-+ limits.deadzone = abs.flat;
-+}
-+
-+std::string EvdevInputHandler::get_api_name()
-+{
-+ return "evdev";
-+}
-+
-+bool EvdevInputHandler::setup_device(std::string device)
-+{
-+ size_t size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, device.c_str()) + 1;
-+ char* evdev_fname = (char*)malloc(size_needed);
-+ sprintf(evdev_fname, EVDEV_DEVICE_STRING, device.c_str());
-+
-+ printf("evdev: Trying to open device '%s'\n", evdev_fname);
-+
-+ this->m_evdev_fd = open(evdev_fname, O_RDONLY);
-+
-+ char device_name[256] = "Unknown";
-+
-+ if (this->m_evdev_fd < 0)
-+ {
-+ printf("evdev: Opening device '%s' failed - %s", evdev_fname, strerror(errno));
-+ free(evdev_fname);
-+ return false;
-+ }
-+
-+ fcntl(this->m_evdev_fd, F_SETFL, O_NONBLOCK);
-+
-+ // Get device name
-+ if(ioctl(this->m_evdev_fd, EVIOCGNAME(sizeof(device_name)), device_name) < 0)
-+ {
-+ printf("evdev: Getting name of '%s' (ioctl) failed - %s", evdev_fname, strerror(errno));
-+ free(evdev_fname);
-+ return false;
-+ }
-+
-+ printf("evdev: Found '%s' at '%s'\n", device_name, evdev_fname);
-+ this->m_evdev_devname = std::string(device_name);
-+
-+ free(evdev_fname);
-+
-+ return true;
-+}
-+
-+std::string EvdevInputHandler::get_default_mapping_filename()
-+{
-+ if (this->m_evdev_devname.empty())
-+ {
-+ return "";
-+ }
-+
-+ std::string mapping_filename;
-+ #if defined(TARGET_PANDORA)
-+ mapping_filename = "controller_pandora.cfg";
-+ #elif defined(TARGET_GCW0)
-+ mapping_filename = "controller_gcwz.cfg";
-+ #else
-+ if (strstr(this->m_evdev_devname.c_str(), "Microsoft X-Box 360 pad") == NULL || strstr(this->m_evdev_devname.c_str(), "Xbox 360 Wireless Receiver") == NULL)
-+ {
-+ mapping_filename = "controller_xpad.cfg";
-+ }
-+ else if (strstr(this->m_evdev_devname.c_str(), "Xbox Gamepad (userspace driver)") != NULL)
-+ {
-+ mapping_filename = "controller_xboxdrv.cfg";
-+ }
-+ else if (strstr(this->m_evdev_devname.c_str(), "keyboard") != NULL || strstr(this->m_evdev_devname.c_str(), "Keyboard") != NULL)
-+ {
-+ mapping_filename = "keyboard.cfg";
-+ }
-+ else
-+ {
-+ mapping_filename = "controller_generic.cfg";
-+ }
-+ #endif
-+
-+ return mapping_filename;
-+}
-+
-+void EvdevInputHandler::handle()
-+{
-+ if (!this->is_initialized())
-+ {
-+ return;
-+ }
-+
-+ input_event ie;
-+ while(read(this->m_evdev_fd, &ie, sizeof(ie)) == sizeof(ie))
-+ {
-+ //printf("evdev: type = %d - code = %d - value = %d\n", ie.type, ie.code, ie.value);
-+ switch(ie.type)
-+ {
-+ case EV_KEY:
-+ {
-+ this->handle_button(ie.code, ie.value);
-+ break;
-+ }
-+ case EV_ABS:
-+ {
-+ this->handle_axis(ie.code, ie.value);
-+ break;
-+ }
-+ }
-+ }
-+}
-+#endif
-diff -Nur a/core/linux-dist/handler_evdev.h b/core/linux-dist/handler_evdev.h
---- a/core/linux-dist/handler_evdev.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_evdev.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,15 @@
-+#pragma once
-+#include "handler.h"
-+
-+class EvdevInputHandler : public InputHandler
-+{
-+ private:
-+ int m_evdev_fd;
-+ std::string m_evdev_devname;
-+ void get_axis_limits(const InputAxisCode code, InputAxisLimits& limits);
-+ public:
-+ void handle();
-+ std::string get_api_name();
-+ std::string get_default_mapping_filename();
-+ bool setup_device(std::string device);
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler.h b/core/linux-dist/handler.h
---- a/core/linux-dist/handler.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,49 @@
-+#pragma once
-+#include "types.h"
-+#include "mapping.h"
-+#include "mappingstore.h"
-+
-+struct InputAxisLimits
-+{
-+ s32 minimum;
-+ s32 maximum;
-+ s32 deadzone;
-+};
-+
-+class InputAxisConverter
-+{
-+ private:
-+ s32 m_minimum;
-+ s32 m_range;
-+ s32 m_deadzone;
-+ public:
-+ InputAxisConverter(bool inverted, InputAxisLimits limits);
-+ s8 convert(s32 value);
-+};
-+
-+class InputHandler
-+{
-+ typedef std::map<InputAxisID, InputAxisConverter*> InputAxisConverterStore;
-+ private:
-+ InputAxisConverterStore m_axis_converters;
-+ void enable_axis_converter(InputAxisID axis, bool inverted, InputAxisLimits limits);
-+ void disable_axis_converter(InputAxisID axis);
-+ InputAxisConverter* get_axis_converter(InputAxisID axis);
-+ bool m_initialized;
-+ protected:
-+ static InputMappingStore s_mappingstore;
-+ u32 m_port;
-+ InputMapping* m_mapping;
-+ bool is_initialized();
-+ void handle_button(InputButtonCode code, int value);
-+ void handle_axis(InputAxisCode code, int value);
-+ virtual void get_axis_limits(const InputAxisCode code, InputAxisLimits& limits);
-+ public:
-+ InputHandler();
-+ ~InputHandler();
-+ bool initialize(u32 port, std::string device, std::string custom_mapping);
-+ virtual std::string get_default_mapping_filename();
-+ virtual void handle() = 0;
-+ virtual std::string get_api_name() = 0;
-+ virtual bool setup_device(std::string device) = 0;
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler_linuxjs.cpp b/core/linux-dist/handler_linuxjs.cpp
---- a/core/linux-dist/handler_linuxjs.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_linuxjs.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,127 @@
-+#if defined(USE_JOYSTICK)
-+#include "handler_linuxjs.h"
-+#include <cstring>
-+#include <cerrno>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <linux/joystick.h>
-+
-+#define LINUXJS_DEVICE_STRING "/dev/input/js%s"
-+
-+void LinuxJoystickInputHandler::get_axis_limits(const InputAxisCode code, InputAxisLimits& limits)
-+{
-+ // The Linux Joystick API's axes always normalized to this minimum/maximum
-+ limits.minimum = -32767;
-+ limits.maximum = 32767;
-+ limits.deadzone = 0;
-+}
-+
-+std::string LinuxJoystickInputHandler::get_api_name()
-+{
-+ return "linuxjs";
-+}
-+
-+bool LinuxJoystickInputHandler::setup_device(std::string device)
-+{
-+ size_t size_needed = snprintf(NULL, 0, LINUXJS_DEVICE_STRING, device.c_str()) + 1;
-+ char* linuxjs_fname = (char*)malloc(size_needed);
-+ sprintf(linuxjs_fname, LINUXJS_DEVICE_STRING, device.c_str());
-+
-+ printf("linuxjs: Trying to open device '%s'\n", linuxjs_fname);
-+
-+ this->m_linuxjs_fd = open(linuxjs_fname, O_RDONLY);
-+
-+ if (this->m_linuxjs_fd < 0)
-+ {
-+ printf("linuxjs: Opening device '%s' failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ fcntl(this->m_linuxjs_fd, F_SETFL, O_NONBLOCK);
-+
-+ char device_name[256] = "Unknown";
-+ int button_count = 0;
-+ int axis_count = 0;
-+
-+ // Get device name
-+ if(ioctl(this->m_linuxjs_fd, JSIOCGNAME(sizeof(device_name)), device_name) < 0)
-+ {
-+ printf("linuxjs: Getting name of '%s' (ioctl) failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ // Get number of buttons
-+ if(ioctl(this->m_linuxjs_fd, JSIOCGBUTTONS, &button_count) < 0)
-+ {
-+ printf("linuxjs: Getting button count of '%s' (ioctl) failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ // Get number of axes
-+ if(ioctl(this->m_linuxjs_fd, JSIOCGAXES, &axis_count) < 0)
-+ {
-+ printf("linuxjs: Getting axis count of '%s' (ioctl) failed - %s", linuxjs_fname, strerror(errno));
-+ free(linuxjs_fname);
-+ return false;
-+ }
-+
-+ printf("linuxjs: Found '%s' with %d axes and %d buttons at '%s'\n", device_name, axis_count, button_count, linuxjs_fname);
-+ this->m_linuxjs_devname = std::string(device_name);
-+
-+ free(linuxjs_fname);
-+
-+ return true;
-+}
-+
-+std::string LinuxJoystickInputHandler::get_default_mapping_filename()
-+{
-+ if (this->m_linuxjs_devname.empty())
-+ {
-+ return "";
-+ }
-+
-+ std::string mapping_filename;
-+ if (strstr(this->m_linuxjs_devname.c_str(), "Microsoft X-Box 360 pad") != NULL ||
-+ strstr(this->m_linuxjs_devname.c_str(), "Xbox Gamepad (userspace driver)") != NULL ||
-+ strstr(this->m_linuxjs_devname.c_str(), "Xbox 360 Wireless Receiver") != NULL)
-+ {
-+ mapping_filename = "controller_xbox360.cfg";
-+ }
-+ else
-+ {
-+ mapping_filename = "controller_generic.cfg";
-+ }
-+
-+ return mapping_filename;
-+}
-+
-+void LinuxJoystickInputHandler::handle()
-+{
-+ if (!this->is_initialized())
-+ {
-+ return;
-+ }
-+
-+ struct js_event je;
-+ while(read(this->m_linuxjs_fd, &je, sizeof(je)) == sizeof(je))
-+ {
-+ printf("linuxjs: type = %d - code = %d - value = %d\n", je.type, je.number, je.value);
-+ switch(je.type)
-+ {
-+ case JS_EVENT_BUTTON:
-+ {
-+ this->handle_button(je.number, je.value);
-+ break;
-+ }
-+ case JS_EVENT_AXIS:
-+ {
-+ this->handle_axis(je.number, je.value);
-+ break;
-+ }
-+ }
-+ }
-+}
-+#endif
-\ No newline at end of file
-diff -Nur a/core/linux-dist/handler_linuxjs.h b/core/linux-dist/handler_linuxjs.h
---- a/core/linux-dist/handler_linuxjs.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/handler_linuxjs.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,15 @@
-+#pragma once
-+#include "handler.h"
-+
-+class LinuxJoystickInputHandler : public InputHandler
-+{
-+ private:
-+ int m_linuxjs_fd;
-+ std::string m_linuxjs_devname;
-+ void get_axis_limits(const InputAxisCode code, InputAxisLimits& limits);
-+ public:
-+ void handle();
-+ std::string get_api_name();
-+ std::string get_default_mapping_filename();
-+ bool setup_device(std::string device);
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/joystick.cpp b/core/linux-dist/joystick.cpp
---- a/core/linux-dist/joystick.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/joystick.cpp 1969-12-31 21:00:00.000000000 -0300
-@@ -1,158 +0,0 @@
--#include <unistd.h>
--#include <fcntl.h>
--#include <sys/types.h>
--#include <linux/joystick.h>
--#include "linux-dist/joystick.h"
--
--#if defined(USE_JOYSTICK)
-- const u32 joystick_map_btn_usb[JOYSTICK_MAP_SIZE] = { DC_BTN_Y, DC_BTN_B, DC_BTN_A, DC_BTN_X, 0, 0, 0, 0, 0, DC_BTN_START };
-- const u32 joystick_map_axis_usb[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, 0, 0, 0, 0, 0, 0, 0, 0 };
--
-- const u32 joystick_map_btn_xbox360[JOYSTICK_MAP_SIZE] = { DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, 0, 0, 0, DC_BTN_START, 0, 0 };
-- const u32 joystick_map_axis_xbox360[JOYSTICK_MAP_SIZE] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, 0, 0, DC_AXIS_RT, DC_DPAD_LEFT, DC_DPAD_UP, 0, 0 };
--
-- const u32* joystick_map_btn = joystick_map_btn_usb;
-- const u32* joystick_map_axis = joystick_map_axis_usb;
--
-- int input_joystick_init(const char* device)
-- {
-- int axis_count = 0;
-- int button_count = 0;
-- char name[128] = "Unknown";
--
-- printf("joystick: Trying to open device at '%s'\n", device);
--
-- int fd = open(device, O_RDONLY);
--
-- if(fd >= 0)
-- {
-- fcntl(fd, F_SETFL, O_NONBLOCK);
-- ioctl(fd, JSIOCGAXES, &axis_count);
-- ioctl(fd, JSIOCGBUTTONS, &button_count);
-- ioctl(fd, JSIOCGNAME(sizeof(name)), &name);
--
-- printf("joystick: Found '%s' with %d axis and %d buttons at '%s'.\n", name, axis_count, button_count, device);
--
-- if (strcmp(name, "Microsoft X-Box 360 pad") == 0 ||
-- strcmp(name, "Xbox Gamepad (userspace driver)") == 0 ||
-- strcmp(name, "Xbox 360 Wireless Receiver (XBOX)") == 0)
-- {
-- joystick_map_btn = joystick_map_btn_xbox360;
-- joystick_map_axis = joystick_map_axis_xbox360;
-- printf("joystick: Using Xbox 360 map\n");
-- }
-- }
-- else
-- {
-- perror("joystick open");
-- }
--
-- return fd;
-- }
--
-- bool input_joystick_handle(int fd, u32 port)
-- {
-- // Joystick must be connected
-- if(fd < 0) {
-- return false;
-- }
--
-- struct js_event JE;
-- while(read(fd, &JE, sizeof(JE)) == sizeof(JE))
-- if (JE.number < JOYSTICK_MAP_SIZE)
-- {
-- switch(JE.type & ~JS_EVENT_INIT)
-- {
-- case JS_EVENT_AXIS:
-- {
-- u32 mt = joystick_map_axis[JE.number] >> 16;
-- u32 mo = joystick_map_axis[JE.number] & 0xFFFF;
--
-- //printf("AXIS %d,%d\n",JE.number,JE.value);
-- s8 v=(s8)(JE.value/256); //-127 ... + 127 range
--
-- if (mt == 0)
-- {
-- kcode[port] |= mo;
-- kcode[port] |= mo*2;
-- if (v<-64)
-- {
-- kcode[port] &= ~mo;
-- }
-- else if (v>64)
-- {
-- kcode[port] &= ~(mo*2);
-- }
--
-- //printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
-- }
-- else if (mt == 1)
-- {
-- if (v >= 0)
-- {
-- v++; //up to 255
-- }
-- //printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
-- if (mo == 0)
-- {
-- lt[port] = (v + 127);
-- }
-- else if (mo == 1)
-- {
-- rt[port] = (v + 127);
-- }
-- }
-- else if (mt == 2)
-- {
-- // printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
-- if (mo == 0)
-- {
-- joyx[port] = v;
-- }
-- else if (mo == 1)
-- {
-- joyy[port] = v;
-- }
-- }
-- }
-- break;
--
-- case JS_EVENT_BUTTON:
-- {
-- u32 mt = joystick_map_btn[JE.number] >> 16;
-- u32 mo = joystick_map_btn[JE.number] & 0xFFFF;
--
-- // printf("BUTTON %d,%d\n",JE.number,JE.value);
--
-- if (mt == 0)
-- {
-- // printf("Mapped to %d\n",mo);
-- if (JE.value)
-- {
-- kcode[port] &= ~mo;
-- }
-- else
-- {
-- kcode[port] |= mo;
-- }
-- }
-- else if (mt == 1)
-- {
-- // printf("Mapped to %d %d\n",mo,JE.value?255:0);
-- if (mo==0)
-- {
-- lt[port] = JE.value ? 255 : 0;
-- }
-- else if (mo==1)
-- {
-- rt[port] = JE.value ? 255 : 0;
-- }
-- }
-- }
-- break;
-- }
-- }
--
-- return true;
-- }
--#endif
-diff -Nur a/core/linux-dist/joystick.h b/core/linux-dist/joystick.h
---- a/core/linux-dist/joystick.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/joystick.h 1969-12-31 21:00:00.000000000 -0300
-@@ -1,10 +0,0 @@
--#include "types.h"
--#include "linux-dist/main.h"
--
--#pragma once
--#define JOYSTICK_DEVICE_STRING "/dev/input/js%d"
--#define JOYSTICK_DEFAULT_DEVICE_ID -1
--#define JOYSTICK_MAP_SIZE 32
--
--extern int input_joystick_init(const char* device);
--extern bool input_joystick_handle(int fd, u32 port);
-diff -Nur a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp
---- a/core/linux-dist/main.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/main.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -14,6 +14,7 @@
- #include <sys/time.h>
- #include "hw/sh4/dyna/blockmanager.h"
- #include <unistd.h>
-+#include "proxy.h"
-
- #if defined(TARGET_EMSCRIPTEN)
- #include <emscripten.h>
-@@ -32,11 +33,11 @@
- #endif
-
- #if defined(USE_EVDEV)
-- #include "linux-dist/evdev.h"
-+ #include "linux-dist/handler_evdev.h"
- #endif
-
- #if defined(USE_JOYSTICK)
-- #include "linux-dist/joystick.h"
-+ #include "linux-dist/handler_linuxjs.h"
- #endif
-
- #ifdef TARGET_PANDORA
-@@ -84,82 +85,68 @@
-
- void emit_WriteCodeCache();
-
--#if defined(USE_EVDEV)
-- /* evdev input */
-- static EvdevController evdev_controllers[4] = {
-- { -1, NULL },
-- { -1, NULL },
-- { -1, NULL },
-- { -1, NULL }
-- };
--#endif
--
--#if defined(USE_JOYSTICK)
-- /* legacy joystick input */
-- static int joystick_fd = -1; // Joystick file descriptor
--#endif
-+static InputHandlerProxy input_handlers;
-
- void SetupInput()
- {
- #if defined(USE_EVDEV)
-- int evdev_device_id[4] = { -1, -1, -1, -1 };
-- size_t size_needed;
-- int port, i;
-+ #define EVDEV_DEVICE_CONFIG_KEY "evdev_device_id_%d"
-+ #define EVDEV_MAPPING_CONFIG_KEY "evdev_mapping_%d"
-
-- char* evdev_device;
-+ #ifdef TARGET_PANDORA
-+ #define EVDEV_DEFAULT_DEVICE_ID_1 "4"
-+ #else
-+ #define EVDEV_DEFAULT_DEVICE_ID_1 "0"
-+ #endif
-+ #define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : "-1")
-
-- for (port = 0; port < 4; port++)
-+ for (int port = 0; port < 4; port++)
- {
-+ size_t size_needed;
-+ char* evdev_config_key;
-+ std::string evdev_device;
-+ std::string custom_mapping_filename;
-+
- size_needed = snprintf(NULL, 0, EVDEV_DEVICE_CONFIG_KEY, port+1) + 1;
-- char* evdev_config_key = (char*)malloc(size_needed);
-+ evdev_config_key = (char*)malloc(size_needed);
- sprintf(evdev_config_key, EVDEV_DEVICE_CONFIG_KEY, port+1);
-- evdev_device_id[port] = cfgLoadInt("input", evdev_config_key, EVDEV_DEFAULT_DEVICE_ID(port+1));
-+ evdev_device = cfgLoadStr("input", evdev_config_key, EVDEV_DEFAULT_DEVICE_ID(port+1));
- free(evdev_config_key);
-
-- // Check if the same device is already in use on another port
-- if (evdev_device_id[port] < 0)
-+ if(evdev_device.c_str()[0] == '-')
- {
- printf("evdev: Controller %d disabled by config.\n", port + 1);
-+ continue;
- }
-- else
-- {
-- for (i = 0; i < port; i++)
-- {
-- if (evdev_device_id[port] == evdev_device_id[i])
-- {
-- die("You can't assign the same device to multiple ports!\n");
-- }
-- }
--
-- size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, evdev_device_id[port]) + 1;
-- evdev_device = (char*)malloc(size_needed);
-- sprintf(evdev_device, EVDEV_DEVICE_STRING, evdev_device_id[port]);
--
-- size_needed = snprintf(NULL, 0, EVDEV_MAPPING_CONFIG_KEY, port+1) + 1;
-- evdev_config_key = (char*)malloc(size_needed);
-- sprintf(evdev_config_key, EVDEV_MAPPING_CONFIG_KEY, port+1);
-- const char* mapping = (cfgExists("input", evdev_config_key) == 2 ? cfgLoadStr("input", evdev_config_key, "").c_str() : NULL);
-- free(evdev_config_key);
-
-- input_evdev_init(&evdev_controllers[port], evdev_device, mapping);
-+ size_needed = snprintf(NULL, 0, EVDEV_MAPPING_CONFIG_KEY, port+1) + 1;
-+ evdev_config_key = (char*)malloc(size_needed);
-+ sprintf(evdev_config_key, EVDEV_MAPPING_CONFIG_KEY, port+1);
-+ custom_mapping_filename = (cfgExists("input", evdev_config_key) == 2 ? cfgLoadStr("input", evdev_config_key, "") : "");
-+ free(evdev_config_key);
-
-- free(evdev_device);
-- }
-+ EvdevInputHandler* handler = new EvdevInputHandler();
-+ handler->initialize(port, evdev_device, custom_mapping_filename);
-+ input_handlers.add(port, handler);
- }
- #endif
-
- #if defined(USE_JOYSTICK)
-- int joystick_device_id = cfgLoadInt("input", "joystick_device_id", JOYSTICK_DEFAULT_DEVICE_ID);
-- if (joystick_device_id < 0) {
-- puts("Legacy Joystick input disabled by config.\n");
-+ #define JOYSTICK_DEFAULT_DEVICE_ID "-1"
-+
-+ std::string linuxjs_device;
-+ std::string custom_mapping_filename = "";
-+
-+ linuxjs_device = cfgLoadStr("input", "joystick_device_id", JOYSTICK_DEFAULT_DEVICE_ID);
-+ if (linuxjs_device.c_str()[0] == '-')
-+ {
-+ puts("LinuxJoystick input disabled by config.\n");
- }
- else
- {
-- int joystick_device_length = snprintf(NULL, 0, JOYSTICK_DEVICE_STRING, joystick_device_id);
-- char* joystick_device = (char*)malloc(joystick_device_length + 1);
-- sprintf(joystick_device, JOYSTICK_DEVICE_STRING, joystick_device_id);
-- joystick_fd = input_joystick_init(joystick_device);
-- free(joystick_device);
-+ LinuxJoystickInputHandler* handler = new LinuxJoystickInputHandler();
-+ handler->initialize(0, linuxjs_device, custom_mapping_filename);
-+ input_handlers.add(0, handler);
- }
- #endif
-
-@@ -178,13 +165,7 @@
- return;
- #endif
-
-- #if defined(USE_JOYSTICK)
-- input_joystick_handle(joystick_fd, port);
-- #endif
--
-- #if defined(USE_EVDEV)
-- input_evdev_handle(&evdev_controllers[port], port);
-- #endif
-+ input_handlers.handle(port);
-
- #if defined(USE_SDL)
- input_sdl_handle(port);
-diff -Nur a/core/linux-dist/main.h b/core/linux-dist/main.h
---- a/core/linux-dist/main.h 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/main.h 2015-10-06 21:55:43.966475140 -0300
-@@ -11,25 +11,34 @@
-
- enum DreamcastController
- {
-- DC_BTN_C = 1,
-- DC_BTN_B = 1<<1,
-- DC_BTN_A = 1<<2,
-- DC_BTN_START = 1<<3,
-- DC_DPAD_UP = 1<<4,
-- DC_DPAD_DOWN = 1<<5,
-- DC_DPAD_LEFT = 1<<6,
-- DC_DPAD_RIGHT = 1<<7,
-- DC_BTN_Z = 1<<8,
-- DC_BTN_Y = 1<<9,
-- DC_BTN_X = 1<<10,
-- DC_BTN_D = 1<<11,
-- DC_DPAD2_UP = 1<<12,
-- DC_DPAD2_DOWN = 1<<13,
-- DC_DPAD2_LEFT = 1<<14,
-- DC_DPAD2_RIGHT = 1<<15,
-+ EMU_BTN_NONE = 0,
-+ EMU_BTN_ESCAPE = 1<<16,
-+ EMU_BTN_TRIGGER_LEFT = 1<<17,
-+ EMU_BTN_TRIGGER_RIGHT = 1<<18,
-+ DC_BTN_C = 1,
-+ DC_BTN_B = 1<<1,
-+ DC_BTN_A = 1<<2,
-+ DC_BTN_START = 1<<3,
-+ DC_BTN_DPAD1_UP = 1<<4,
-+ DC_BTN_DPAD1_DOWN = 1<<5,
-+ DC_BTN_DPAD1_LEFT = 1<<6,
-+ DC_BTN_DPAD1_RIGHT = 1<<7,
-+ DC_BTN_Z = 1<<8,
-+ DC_BTN_Y = 1<<9,
-+ DC_BTN_X = 1<<10,
-+ DC_BTN_D = 1<<11,
-+ DC_BTN_DPAD2_UP = 1<<12,
-+ DC_BTN_DPAD2_DOWN = 1<<13,
-+ DC_BTN_DPAD2_LEFT = 1<<14,
-+ DC_BTN_DPAD2_RIGHT = 1<<15,
-
-- DC_AXIS_LT = 0X10000,
-- DC_AXIS_RT = 0X10001,
-- DC_AXIS_X = 0X20000,
-- DC_AXIS_Y = 0X20001,
-+ EMU_AXIS_NONE = 0X00000,
-+ EMU_AXIS_DPAD1_X = 0X00001,
-+ EMU_AXIS_DPAD1_Y = 0X00002,
-+ EMU_AXIS_DPAD2_X = 0X00003,
-+ EMU_AXIS_DPAD2_Y = 0X00004,
-+ DC_AXIS_TRIGGER_LEFT = 0X10000,
-+ DC_AXIS_TRIGGER_RIGHT = 0X10001,
-+ DC_AXIS_X = 0X20000,
-+ DC_AXIS_Y = 0X20001,
- };
-diff -Nur a/core/linux-dist/mapping.cpp b/core/linux-dist/mapping.cpp
---- a/core/linux-dist/mapping.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mapping.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,159 @@
-+#include "linux-dist/mapping.h"
-+#include "cfg/ini.h"
-+
-+struct ButtonMap
-+{
-+ InputButtonID id;
-+ string section;
-+ string option;
-+};
-+
-+struct AxisMap
-+{
-+ InputAxisID id;
-+ string section;
-+ string option;
-+ string section_inverted;
-+ string option_inverted;
-+};
-+
-+static ButtonMap button_list[19] = {
-+ { DC_BTN_A, "dreamcast", "btn_a" },
-+ { DC_BTN_B, "dreamcast", "btn_b" },
-+ { DC_BTN_C, "dreamcast", "btn_c" },
-+ { DC_BTN_D, "dreamcast", "btn_d" },
-+ { DC_BTN_X, "dreamcast", "btn_x" },
-+ { DC_BTN_Y, "dreamcast", "btn_y" },
-+ { DC_BTN_Z, "dreamcast", "btn_z" },
-+ { DC_BTN_START, "dreamcast", "btn_start" },
-+ { DC_BTN_DPAD1_LEFT, "dreamcast", "btn_dpad1_left" },
-+ { DC_BTN_DPAD1_RIGHT, "dreamcast", "btn_dpad1_right" },
-+ { DC_BTN_DPAD1_UP, "dreamcast", "btn_dpad1_up" },
-+ { DC_BTN_DPAD1_DOWN, "dreamcast", "btn_dpad1_down" },
-+ { DC_BTN_DPAD2_LEFT, "dreamcast", "btn_dpad2_left" },
-+ { DC_BTN_DPAD2_RIGHT, "dreamcast", "btn_dpad2_right" },
-+ { DC_BTN_DPAD2_UP, "dreamcast", "btn_dpad2_up" },
-+ { DC_BTN_DPAD2_DOWN, "dreamcast", "btn_dpad2_down" },
-+ { EMU_BTN_ESCAPE, "emulator", "btn_escape" },
-+ { EMU_BTN_TRIGGER_LEFT, "compat", "btn_trigger_left" },
-+ { EMU_BTN_TRIGGER_RIGHT, "compat", "btn_trigger_right" }
-+};
-+
-+static AxisMap axis_list[8] = {
-+ { DC_AXIS_X, "dreamcast", "axis_x", "compat", "axis_x_inverted" },
-+ { DC_AXIS_Y, "dreamcast", "axis_y", "compat", "axis_y_inverted" },
-+ { DC_AXIS_TRIGGER_LEFT, "dreamcast", "axis_trigger_left", "compat", "axis_trigger_left_inverted" },
-+ { DC_AXIS_TRIGGER_RIGHT, "dreamcast", "axis_trigger_right", "compat", "axis_trigger_right_inverted" },
-+ { EMU_AXIS_DPAD1_X, "compat", "axis_dpad1_x", "compat", "axis_dpad1_x_inverted" },
-+ { EMU_AXIS_DPAD1_Y, "compat", "axis_dpad1_y", "compat", "axis_dpad1_y_inverted" },
-+ { EMU_AXIS_DPAD2_X, "compat", "axis_dpad2_x", "compat", "axis_dpad2_x_inverted" },
-+ { EMU_AXIS_DPAD2_Y, "compat", "axis_dpad2_y", "compat", "axis_dpad2_y_inverted" }
-+};
-+
-+const InputButtonID* InputMapping::get_button_id(InputButtonCode code)
-+{
-+ return this->buttons.get_by_value(code);
-+}
-+
-+const InputButtonCode* InputMapping::get_button_code(InputButtonID id)
-+{
-+ return this->buttons.get_by_key(id);
-+}
-+
-+void InputMapping::set_button(InputButtonID id, InputButtonCode code)
-+{
-+ if(id != EMU_BTN_NONE)
-+ {
-+ this->buttons.insert(id, code);
-+ }
-+}
-+
-+const InputAxisID* InputMapping::get_axis_id(InputAxisCode code)
-+{
-+ return this->axes.get_by_value(code);
-+}
-+
-+const InputAxisCode* InputMapping::get_axis_code(InputAxisID id)
-+{
-+ return this->axes.get_by_key(id);
-+}
-+
-+bool InputMapping::get_axis_inverted(InputAxisCode code)
-+{
-+ std::map<InputAxisCode, bool>::iterator it = this->axes_inverted.find('b');
-+ if (it != this->axes_inverted.end())
-+ {
-+ return it->second;
-+ }
-+ return false;
-+}
-+
-+void InputMapping::set_axis(InputAxisID id, InputAxisCode code, bool is_inverted)
-+{
-+ if(id != EMU_AXIS_NONE)
-+ {
-+ this->axes.insert(id, code);
-+ this->axes_inverted.insert(std::pair<InputAxisCode,bool>(code, is_inverted));
-+ }
-+}
-+
-+void InputMapping::load(FILE* fd)
-+{
-+ ConfigFile mf;
-+ mf.parse(fd);
-+
-+ this->name = mf.get("emulator", "mapping_name", "<Unknown>").c_str();
-+
-+ int i;
-+ for(i = 0; i < 19; i++)
-+ {
-+ InputButtonCode button_code = mf.get_int(button_list[i].section, button_list[i].option, -1);
-+ if (button_code >= 0)
-+ {
-+ this->set_button(button_list[i].id, button_code);
-+ }
-+ }
-+
-+ for(i = 0; i < 8; i++)
-+ {
-+ InputAxisCode axis_code = mf.get_int(axis_list[i].section, axis_list[i].option, -1);
-+ if(axis_code >= 0)
-+ {
-+ this->set_axis(axis_list[i].id, axis_code, mf.get_bool(axis_list[i].section_inverted, axis_list[i].option_inverted, false));
-+ }
-+ }
-+}
-+
-+void InputMapping::print()
-+{
-+ int i;
-+
-+ printf("\nMAPPING NAME: %s\n", this->name);
-+
-+ puts("MAPPED BUTTONS:");
-+ for(i = 0; i < 19; i++)
-+ {
-+ const InputButtonCode* button_code = this->get_button_code(button_list[i].id);
-+ if(button_code)
-+ {
-+ printf("%-18s = %d\n", button_list[i].option.c_str(), *button_code);
-+ }
-+ }
-+
-+ puts("MAPPED AXES:");
-+ for(i = 0; i < 8; i++)
-+ {
-+ const InputAxisCode* axis_code = this->get_axis_code(axis_list[i].id);
-+ if(axis_code)
-+ {
-+ printf("%-18s = %d", axis_list[i].option.c_str(), *axis_code);
-+ if(this->get_axis_inverted(*axis_code))
-+ {
-+ printf("%s", "(inverted)");
-+ }
-+ printf("%s", "\n");
-+ }
-+ }
-+ puts("");
-+}
-+
-diff -Nur a/core/linux-dist/mapping.h b/core/linux-dist/mapping.h
---- a/core/linux-dist/mapping.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mapping.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,32 @@
-+#pragma once
-+#include <map>
-+#include "linux-dist/main.h"
-+#include "linux-dist/bimap.h"
-+
-+typedef DreamcastController InputButtonID;
-+typedef DreamcastController InputAxisID;
-+typedef int InputButtonCode;
-+typedef int InputAxisCode;
-+
-+class InputMapping
-+{
-+ private:
-+ SimpleBimap<InputButtonID, InputButtonCode> buttons;
-+ SimpleBimap<InputAxisID, InputAxisCode> axes;
-+ std::map<InputAxisCode, bool> axes_inverted;
-+
-+ public:
-+ const char* name;
-+
-+ void set_button(InputButtonID id, InputButtonCode code);
-+ const InputButtonID* get_button_id(InputButtonCode code);
-+ const InputButtonCode* get_button_code(InputButtonID id);
-+
-+ void set_axis(InputAxisID id, InputAxisCode code, bool inverted);
-+ const InputAxisID* get_axis_id(InputAxisCode code);
-+ const InputAxisCode* get_axis_code(InputAxisID id);
-+ bool get_axis_inverted(InputAxisCode code);
-+
-+ void load(FILE* file);
-+ void print();
-+};
-diff -Nur a/core/linux-dist/mappingstore.cpp b/core/linux-dist/mappingstore.cpp
---- a/core/linux-dist/mappingstore.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mappingstore.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,61 @@
-+#include "mappingstore.h"
-+#include <errno.h>
-+
-+static std::string get_mapping_path(std::string filepath, std::string subdir)
-+{
-+ if (filepath.empty())
-+ {
-+ return "";
-+ }
-+
-+ std::string new_filepath;
-+ if (filepath.at(0) != '/')
-+ {
-+ // It's not an absolute path
-+ std::string mapping_dir = "/mappings/";
-+ if(!subdir.empty())
-+ {
-+ mapping_dir.append(subdir);
-+ mapping_dir.append("/");
-+ }
-+ filepath.insert(0, mapping_dir);
-+ new_filepath = get_readonly_data_path(filepath);
-+ }
-+ else
-+ {
-+ new_filepath = filepath;
-+ }
-+
-+ // TODO: Some realpath magic? How portable is it?
-+
-+ return new_filepath;
-+}
-+
-+InputMapping* InputMappingStore::get(std::string filepath, std::string subdir)
-+{
-+ std::string full_filepath = get_mapping_path(filepath, subdir);
-+ if(!full_filepath.empty())
-+ {
-+ if(this->loaded_mappings.count(full_filepath) == 0)
-+ {
-+ // Mapping has not been loaded yet
-+ FILE* fp = fopen(full_filepath.c_str(), "r");
-+ if(fp == NULL)
-+ {
-+ printf("Unable to open mapping file '%s': %s\n", full_filepath.c_str(), strerror(errno));
-+ }
-+ else
-+ {
-+ InputMapping* mapping = new InputMapping();
-+ mapping->load(fp);
-+ this->loaded_mappings.insert(std::pair<std::string, InputMapping*>(full_filepath, mapping));
-+ }
-+ }
-+ std::map<std::string, InputMapping*>::iterator it = loaded_mappings.find(full_filepath);
-+ if(it != loaded_mappings.end())
-+ {
-+ return it->second;
-+ }
-+ }
-+ return NULL;
-+}
-\ No newline at end of file
-diff -Nur a/core/linux-dist/mappingstore.h b/core/linux-dist/mappingstore.h
---- a/core/linux-dist/mappingstore.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/mappingstore.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,11 @@
-+#pragma once
-+#include "mapping.h"
-+#include <string>
-+
-+class InputMappingStore
-+{
-+ private:
-+ std::map<std::string, InputMapping*> loaded_mappings;
-+ public:
-+ InputMapping* get(std::string filepath, std::string subdir = "");
-+};
-diff -Nur a/core/linux-dist/proxy.cpp b/core/linux-dist/proxy.cpp
---- a/core/linux-dist/proxy.cpp 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/proxy.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,25 @@
-+#include "proxy.h"
-+
-+InputHandlerProxy::~InputHandlerProxy()
-+{
-+ //TODO
-+}
-+
-+void InputHandlerProxy::add(u32 port, InputHandler* handler)
-+{
-+ if(handler != NULL)
-+ {
-+ this->handlers.insert(std::pair<u32, InputHandler*>(port, handler));
-+ }
-+}
-+
-+void InputHandlerProxy::handle(u32 port)
-+{
-+ std::pair <InputHandlerStore::iterator, InputHandlerStore::iterator> range;
-+ range = this->handlers.equal_range(port);
-+
-+ for (InputHandlerStore::iterator it = range.first; it != range.second; ++it)
-+ {
-+ it->second->handle();
-+ }
-+}
-\ No newline at end of file
-diff -Nur a/core/linux-dist/proxy.h b/core/linux-dist/proxy.h
---- a/core/linux-dist/proxy.h 1969-12-31 21:00:00.000000000 -0300
-+++ b/core/linux-dist/proxy.h 2015-10-06 21:55:43.966475140 -0300
-@@ -0,0 +1,15 @@
-+#pragma once
-+#include <map>
-+#include "types.h"
-+#include "handler.h"
-+
-+class InputHandlerProxy
-+{
-+ typedef std::multimap<u32, InputHandler*> InputHandlerStore;
-+ private:
-+ InputHandlerStore handlers;
-+ public:
-+ ~InputHandlerProxy();
-+ void add(u32 port, InputHandler* handler);
-+ void handle(u32 port);
-+};
-\ No newline at end of file
-diff -Nur a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp
---- a/core/linux-dist/x11.cpp 2015-10-06 21:43:53.042336401 -0300
-+++ b/core/linux-dist/x11.cpp 2015-10-06 21:55:43.966475140 -0300
-@@ -112,11 +112,11 @@
-
- void input_x11_init()
- {
-- x11_keymap[113] = DC_DPAD_LEFT;
-- x11_keymap[114] = DC_DPAD_RIGHT;
-+ x11_keymap[113] = DC_BTN_DPAD1_LEFT;
-+ x11_keymap[114] = DC_BTN_DPAD1_RIGHT;
-
-- x11_keymap[111] = DC_DPAD_UP;
-- x11_keymap[116] = DC_DPAD_DOWN;
-+ x11_keymap[111] = DC_BTN_DPAD1_UP;
-+ x11_keymap[116] = DC_BTN_DPAD1_DOWN;
-
- x11_keymap[53] = DC_BTN_X;
- x11_keymap[54] = DC_BTN_B;