Commit 14ea9e41 authored by Jan Holthuis's avatar Jan Holthuis
Browse files

linux-dist: Refactor the evdev input code

parent 452374af
#include "linux-dist/evdev_mappings.h"
#if defined(USE_EVDEV)
ControllerMapping controller_mapping_generic = {
"Generic Controller",
BTN_A,
BTN_B,
BTN_C,
BTN_THUMBL,
BTN_X,
BTN_Y,
BTN_Z,
BTN_START,
BTN_SELECT,
BTN_DPAD_LEFT,
BTN_DPAD_RIGHT,
BTN_DPAD_UP,
BTN_DPAD_DOWN,
-1,
-1,
-1,
-1,
BTN_TL,
BTN_TR,
ABS_HAT0X,
ABS_HAT0Y,
ABS_HAT1X,
ABS_HAT1Y,
ABS_X,
ABS_Y,
ABS_Z,
ABS_RZ,
};
ControllerMapping controller_mapping_xbox360 = {
"XBox360 Controller",
BTN_A,
BTN_B,
BTN_TL,
BTN_TR,
BTN_X,
BTN_Y,
BTN_THUMBL,
BTN_START,
BTN_SELECT,
BTN_TRIGGER_HAPPY1,
BTN_TRIGGER_HAPPY2,
BTN_TRIGGER_HAPPY3,
BTN_TRIGGER_HAPPY4,
-1,
-1,
-1,
-1,
-1,
-1,
ABS_HAT0X,
ABS_HAT0Y,
ABS_HAT1X,
ABS_HAT1Y,
ABS_X,
ABS_Y,
ABS_Z,
ABS_RZ
};
ControllerMapping controller_mapping_gcwz = {
"GCW Zero",
0x1D, // GCWZ_BTN_A
0x38, // GCWZ_BTN_B
0x0F, // GCWZ_BTN_L
0x0E, // GCWZ_BTN_R
0x2A, // GCWZ_BTN_X
0x39, // GCWZ_BTN_Y
-1,
0x1C, // GCWZ_BTN_START
0x01, // GCWZ_BTN_SELECT
0x69, // GCWZ_BTN_LEFT
0x6A, // GCWZ_BTN_RIGHT
0x67, // GCWZ_BTN_UP
0x6C, // GCWZ_BTN_DOWN
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1
};
ControllerMapping controller_mapping_pandora = {
"Pandora",
KEY_PAGEDOWN,
KEY_END,
KEY_SPACE,
-1,
KEY_HOME,
KEY_PAGEUP,
-1,
KEY_LEFTALT,
KEY_MENU,
KEY_LEFT,
KEY_RIGHT,
KEY_UP,
KEY_DOWN,
-1,
-1,
-1,
-1,
KEY_RIGHTSHIFT,
KEY_RIGHTCTRL,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1
};
#endif
\ No newline at end of file
#include <linux/input.h>
#pragma once
struct s_evdev_controller_mapping
{
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;
};
typedef struct s_evdev_controller_mapping ControllerMapping;
extern ControllerMapping controller_mapping_generic;
extern ControllerMapping controller_mapping_xbox360;
extern ControllerMapping controller_mapping_gcwz;
extern ControllerMapping controller_mapping_pandora;
\ No newline at end of file
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#if defined(USE_EVDEV)
#include "linux-dist/evdev_mappings.h"
#endif
#if defined(USE_JOYSTICK) #if defined(USE_JOYSTICK)
#include <linux/joystick.h> #include <linux/joystick.h>
#endif #endif
...@@ -87,46 +91,64 @@ u8 lt[4] = {0, 0, 0, 0}; ...@@ -87,46 +91,64 @@ u8 lt[4] = {0, 0, 0, 0};
u32 vks[4]; u32 vks[4];
s8 joyx[4], joyy[4]; s8 joyx[4], joyy[4];
enum DCPad enum DreamcastController
{ {
Btn_C = 1, DC_BTN_C = 1,
Btn_B = 1<<1, DC_BTN_B = 1<<1,
Btn_A = 1<<2, DC_BTN_A = 1<<2,
Btn_Start = 1<<3, DC_BTN_START = 1<<3,
DPad_Up = 1<<4, DC_DPAD_UP = 1<<4,
DPad_Down = 1<<5, DC_DPAD_DOWN = 1<<5,
DPad_Left = 1<<6, DC_DPAD_LEFT = 1<<6,
DPad_Right = 1<<7, DC_DPAD_RIGHT = 1<<7,
Btn_Z = 1<<8, DC_BTN_Z = 1<<8,
Btn_Y = 1<<9, DC_BTN_Y = 1<<9,
Btn_X = 1<<10, DC_BTN_X = 1<<10,
Btn_D = 1<<11, DC_BTN_D = 1<<11,
DPad2_Up = 1<<12, DC_DPAD2_UP = 1<<12,
DPad2_Down = 1<<13, DC_DPAD2_DOWN = 1<<13,
DPad2_Left = 1<<14, DC_DPAD2_LEFT = 1<<14,
DPad2_Right = 1<<15, DC_DPAD2_RIGHT = 1<<15,
Axis_LT = 0x10000, DC_AXIS_LT = 0X10000,
Axis_RT = 0x10001, DC_AXIS_RT = 0X10001,
Axis_X = 0x20000, DC_AXIS_X = 0X20000,
Axis_Y = 0x20001, DC_AXIS_Y = 0X20001,
}; };
void emit_WriteCodeCache(); void emit_WriteCodeCache();
/* evdev input */ /* evdev input */
static int evdev_fd[4] = { -1, -1, -1, -1 };
#if defined(USE_EVDEV) #if defined(USE_EVDEV)
struct s_controller
{
int fd;
ControllerMapping* mapping;
};
typedef struct s_controller Controller;
/* evdev input */
static Controller controllers[4] = {
{ -1, NULL },
{ -1, NULL },
{ -1, NULL },
{ -1, NULL }
};
#define EVDEV_DEVICE_STRING "/dev/input/event%d" #define EVDEV_DEVICE_STRING "/dev/input/event%d"
#ifdef TARGET_PANDORA #ifdef TARGET_PANDORA
#define EVDEV_DEFAULT_DEVICE_ID_1 4 #define EVDEV_DEFAULT_DEVICE_ID_1 4
#else #else
#define EVDEV_DEFAULT_DEVICE_ID_1 0 #define EVDEV_DEFAULT_DEVICE_ID_1 0
#endif #endif
#define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : -1) #define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : -1)
int input_evdev_init(const char* device) int input_evdev_init(Controller* controller, const char* device)
{ {
char name[256] = "Unknown"; char name[256] = "Unknown";
...@@ -140,147 +162,175 @@ static int evdev_fd[4] = { -1, -1, -1, -1 }; ...@@ -140,147 +162,175 @@ static int evdev_fd[4] = { -1, -1, -1, -1 };
if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)
{ {
perror("evdev: ioctl"); perror("evdev: ioctl");
return -2;
}
else
{
printf("evdev: Found '%s' at '%s'\n", name, device);
controller->fd = fd;
#if defined(TARGET_PANDORA)
*controller.mapping = &controller_mapping_pandora;
#elif defined(TARGET_GCW0)
*controller.mapping = &controller_mapping_gcwz;
#else
if (strcmp(name, "Microsoft X-Box 360 pad") == 0 ||
strcmp(name, "Xbox Gamepad (userspace driver)") == 0 ||
strcmp(name, "Xbox 360 Wireless Receiver (XBOX)") == 0)
{
controller->mapping = &controller_mapping_xbox360;
}
else
{
controller->mapping = &controller_mapping_generic;
}
#endif
printf("evdev: Using '%s' mapping\n", controller->mapping->name);
return 0;
} }
printf("evdev: Found '%s' at '%s'\n", name, device);
} }
else else
{ {
perror("evdev: open"); perror("evdev: open");
return -1;
} }
return fd;
} }
bool input_evdev_handle(int fd, u32 port) bool input_evdev_handle(Controller* controller, u32 port)
{ {
if (fd < 0) #define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
if (controller->fd < 0 || controller->mapping == NULL)
{ {
return false; return false;
} }
input_event ie; input_event ie;
#if defined(TARGET_GCW0) while(read(controller->fd, &ie, sizeof(ie)) == sizeof(ie))
#define KEY_A 0x1D
#define KEY_B 0x38
#define KEY_X 0x2A
#define KEY_Y 0x39
#define KEY_L 0xF
#define KEY_R 0xE
#define KEY_SELECT 0x1
#define KEY_START 0x1C
#define KEY_LEFT 0x69
#define KEY_RIGHT 0x6A
#define KEY_UP 0x67
#define KEY_DOWN 0x6C
#define KEY_LOCK 0x77 // Note that KEY_LOCK is a switch and remains pressed until it's switched back
#endif
static int keys[4][13];
static int dpad_btn[2];
static s8 axisval;
while(read(fd, &ie, sizeof(ie)) == sizeof(ie))
{ {
//printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); printf("type %i key %i state %i\n", ie.type, ie.code, ie.value);
switch(ie.type) switch(ie.type)
{ {
case EV_KEY: case EV_KEY:
switch (ie.code) if (ie.code == controller->mapping->Btn_A) {
{ SET_FLAG(kcode[port], DC_BTN_A, ie.value);
case KEY_UP: keys[port][ 1] = ie.value; break; } else if (ie.code == controller->mapping->Btn_B) {
case KEY_DOWN: keys[port][ 2] = ie.value; break; SET_FLAG(kcode[port], DC_BTN_B, ie.value);
case KEY_LEFT: keys[port][ 3] = ie.value; break; } else if (ie.code == controller->mapping->Btn_C) {
case KEY_RIGHT: keys[port][ 4] = ie.value; break; SET_FLAG(kcode[port], DC_BTN_C, ie.value);
} else if (ie.code == controller->mapping->Btn_D) {
//xbox360 SET_FLAG(kcode[port], DC_BTN_D, ie.value);
case BTN_Y: keys[port][ 5] = ie.value; break; } else if (ie.code == controller->mapping->Btn_X) {
case BTN_A: keys[port][ 6] = ie.value; break; SET_FLAG(kcode[port], DC_BTN_X, ie.value);
case BTN_B: keys[port][ 7] = ie.value; break; } else if (ie.code == controller->mapping->Btn_Y) {
case BTN_X: keys[port][ 8] = ie.value; break; SET_FLAG(kcode[port], DC_BTN_Y, ie.value);
case BTN_SELECT: keys[port][ 9] = ie.value; break; } else if (ie.code == controller->mapping->Btn_Z) {
case BTN_START: keys[port][12] = ie.value; break; SET_FLAG(kcode[port], DC_BTN_Z, ie.value);
case BTN_TRIGGER_HAPPY1: keys[port][3] = ie.value; break; } else if (ie.code == controller->mapping->Btn_Start) {
case BTN_TRIGGER_HAPPY2: keys[port][4] = ie.value; break; SET_FLAG(kcode[port], DC_BTN_START, ie.value);
case BTN_TRIGGER_HAPPY3: keys[port][1] = ie.value; break; } else if (ie.code == controller->mapping->Btn_Escape) {
case BTN_TRIGGER_HAPPY4: keys[port][2] = ie.value; break; die("death by escape key");
} else if (ie.code == controller->mapping->Btn_DPad_Left) {
#if defined(TARGET_GCW0) SET_FLAG(kcode[port], DC_DPAD_LEFT, ie.value);
case KEY_Y: keys[port][ 5] = ie.value; break; } else if (ie.code == controller->mapping->Btn_DPad_Right) {
case KEY_B: keys[port][ 6] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD_RIGHT, ie.value);
case KEY_A: keys[port][ 7] = ie.value; break; } else if (ie.code == controller->mapping->Btn_DPad_Up) {
case KEY_X: keys[port][ 8] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD_UP, ie.value);
case KEY_SELECT: keys[port][ 9] = ie.value; break; } else if (ie.code == controller->mapping->Btn_DPad_Down) {
case KEY_START: keys[port][12] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD_DOWN, ie.value);
#elif defined(TARGET_PANDORA) } else if (ie.code == controller->mapping->Btn_DPad2_Left) {
case KEY_SPACE: keys[port][ 0] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD2_LEFT, ie.value);
case KEY_PAGEUP: keys[port][ 5] = ie.value; break; } else if (ie.code == controller->mapping->Btn_DPad2_Right) {
case KEY_PAGEDOWN: keys[port][ 6] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD2_RIGHT, ie.value);
case KEY_END: keys[port][ 7] = ie.value; break; } else if (ie.code == controller->mapping->Btn_DPad2_Up) {
case KEY_HOME: keys[port][ 8] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD2_UP, ie.value);
case KEY_MENU: keys[port][ 9] = ie.value; break; } else if (ie.code == controller->mapping->Btn_DPad2_Down) {
case KEY_RIGHTSHIFT: keys[port][10] = ie.value; break; SET_FLAG(kcode[port], DC_DPAD2_DOWN, ie.value);
case KEY_RIGHTCTRL: keys[port][11] = ie.value; break; } else if (ie.code == controller->mapping->Btn_Trigger_Left) {
case KEY_LEFTALT: keys[port][12] = ie.value; break; lt[port] = (ie.value ? 255 : 0);
#endif } else if (ie.code == controller->mapping->Btn_Trigger_Right) {
rt[port] = (ie.value ? 255 : 0);
} }
break; break;
case EV_ABS: case EV_ABS:
switch(ie.code) if (ie.code == controller->mapping->Axis_DPad_X) {
{ switch(ie.value)
case ABS_X: {
case ABS_RX: case -1:
joyx[port] = (s8)(ie.value/256); SET_FLAG(kcode[port], DC_DPAD_LEFT, 1);
break; SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
case ABS_Y: break;
case ABS_RY: case 0:
joyy[port] = (s8)(ie.value/256); SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
break; SET_FLAG(kcode[port], DC_DPAD_RIGHT, 0);
case ABS_BRAKE: break;
case ABS_Z: case 1:
lt[port] = (s8)ie.value; SET_FLAG(kcode[port], DC_DPAD_LEFT, 0);
break; SET_FLAG(kcode[port], DC_DPAD_RIGHT, 1);
case ABS_GAS: break;
case ABS_RZ: }
rt[port] = (s8)ie.value; } else if (ie.code == controller->mapping->Axis_DPad_Y) {
break; switch(ie.value)
case ABS_HAT0X: {
case ABS_HAT0Y: case -1:
dpad_btn[0] = (ie.code == ABS_HAT0Y ? 1 : 3); SET_FLAG(kcode[port], DC_DPAD_UP, 1);
dpad_btn[1] = (ie.code == ABS_HAT0Y ? 2 : 4); SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
switch(ie.value) break;
{ case 0:
case -1: SET_FLAG(kcode[port], DC_DPAD_UP, 0);
keys[port][dpad_btn[0]] = 1; SET_FLAG(kcode[port], DC_DPAD_DOWN, 0);
keys[port][dpad_btn[1]] = 0; break;
break; case 1:
case 0: SET_FLAG(kcode[port], DC_DPAD_UP, 0);
keys[port][dpad_btn[0]] = 0; SET_FLAG(kcode[port], DC_DPAD_DOWN, 1);
keys[port][dpad_btn[1]] = 0; break;
break; }
case 1: } else if (ie.code == controller->mapping->Axis_DPad2_X) {
keys[port][dpad_btn[0]] = 0; switch(ie.value)
keys[port][dpad_btn[1]] = 1; {
break; case -1:
} SET_FLAG(kcode[port], DC_DPAD2_LEFT, 1);
break; 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] = (s8)(ie.value/256);
} else if (ie.code == controller->mapping->Axis_Analog_Y) {
joyy[port] = (s8)(ie.value/256);
} else if (ie.code == controller->mapping->Axis_Trigger_Left) {
lt[port] = (s8)ie.value;
} else if (ie.code == controller->mapping->Axis_Trigger_Right) {
rt[port] = (s8)ie.value;
} }
break;
} }
} }
if (keys[port][ 0]) { kcode[port] &= ~Btn_C; }
if (keys[port][ 6]) { kcode[port] &= ~Btn_A; }
if (keys[port][ 7]) { kcode[port] &= ~Btn_B; }
if (keys[port][ 5]) { kcode[port] &= ~Btn_Y; }
if (keys[port][ 8]) { kcode[port] &= ~Btn_X; }
if (keys[port][ 1]) { kcode[port] &= ~DPad_Up; }
if (keys[port][ 2]) { kcode[port] &= ~DPad_Down; }
if (keys[port][ 3]) { kcode[port] &= ~DPad_Left; }
if (keys[port][ 4]) { kcode[port] &= ~DPad_Right; }
if (keys[port][12]) { kcode[port] &= ~Btn_Start; }
if (keys[port][ 9]) { die("death by escape key"); }
if (keys[port][10]) { rt[port] = 255; }
if (keys[port][11]) { lt[port] = 255; }
return true;
} }
#endif #endif
...@@ -293,11 +343,11 @@ static int joystick_fd = -1; // Joystick file descriptor ...@@ -293,11 +343,11 @@ static int joystick_fd = -1; // Joystick file descriptor
#define JOYSTICK_DEFAULT_DEVICE_ID 0 #define JOYSTICK_DEFAULT_DEVICE_ID 0
#define JOYSTICK_MAP_SIZE 32 #define JOYSTICK_MAP_SIZE 32
const u32 joystick_map_btn_usb[JOYSTICK_MAP_SIZE] = { Btn_Y, Btn_B, Btn_A, Btn_X, 0, 0, 0, 0, 0, Btn_Start }; 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] = { Axis_X, Axis_Y, 0, 0, 0, 0, 0, 0, 0, 0 }; 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] = { Btn_A, Btn_B, Btn_X, Btn_Y, 0, 0, 0, Btn_Start, 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] = { Axis_X, Axis_Y, Axis_LT, 0, 0, Axis_RT, DPad_Left, DPad_Up, 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 =