From 7dfcc169de9016eb3db440c20351963c43c83071 Mon Sep 17 00:00:00 2001 From: David Walters Date: Wed, 29 Nov 2017 18:32:58 +0000 Subject: [PATCH] Add new lighgun/mouse-bind features to X11 driver --- input/drivers/x11_input.c | 197 ++++++++++++++++++++++++++++++-------- 1 file changed, 157 insertions(+), 40 deletions(-) diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index 40842f0719..e21e9a100e 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -30,6 +30,7 @@ #include "../../gfx/video_driver.h" #include "../common/input_x11_common.h" +#include "../../configuration.h" #include "../../verbosity.h" typedef struct x11_input @@ -72,6 +73,78 @@ static void *x_input_init(const char *joypad_driver) return x11; } +static bool x_keyboard_pressed(x11_input_t *x11, unsigned key) +{ + int keycode = XKeysymToKeycode(x11->display, rarch_keysym_lut[(enum retro_key)key]); + return x11->state[keycode >> 3] & (1 << (keycode & 7)); +} + +static bool x_mbutton_pressed(x11_input_t *x11, unsigned port, unsigned key) +{ + bool result; + settings_t *settings = config_get_ptr(); + + if (port >= MAX_USERS) + return false; + + /* the driver only supports one mouse */ + if ( settings->uints.input_mouse_index[ port ] != 0 ) + return false; + + switch ( key ) + { + + case RETRO_DEVICE_ID_MOUSE_LEFT: + return x11->mouse_l; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return x11->mouse_r; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + return x11->mouse_m; +/* case RETRO_DEVICE_ID_MOUSE_BUTTON_4: + return x11->mouse_b4;*/ +/* case RETRO_DEVICE_ID_MOUSE_BUTTON_5: + return x11->mouse_b5;*/ + + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + return x_mouse_state_wheel( key ); + +/* case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP: + result = x11->mouse_hwu; + x11->mouse_hwu = false; + return result; + + case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN: + result = x11->mouse_hwd; + x11->mouse_hwd = false; + return result; +*/ + } + + return false; +} + +static bool x_is_pressed(x11_input_t *x11, + rarch_joypad_info_t joypad_info, + const struct retro_keybind *binds, + unsigned port, unsigned id) +{ + const struct retro_keybind *bind = &binds[id]; + + if ( (bind->key < RETROK_LAST) && x_keyboard_pressed(x11, bind->key) ) + return true; + + if (binds && binds[id].valid) + { + if (x_mbutton_pressed(x11, port, bind->mbutton)) + return true; + if (input_joypad_pressed(x11->joypad, joypad_info, port, binds, id)) + return true; + } + + return false; +} + static int16_t x_pressed_analog(x11_input_t *x11, const struct retro_keybind *binds, unsigned idx, unsigned id) { @@ -111,6 +184,44 @@ static bool x_input_meta_key_pressed(void *data, int key) return false; } +static int16_t x_lightgun_aiming_state( x11_input_t *x11, unsigned idx, unsigned id ) +{ + const int edge_detect = 32700; + struct video_viewport vp; + bool inside = false; + int16_t res_x = 0; + int16_t res_y = 0; + int16_t res_screen_x = 0; + int16_t res_screen_y = 0; + + vp.x = 0; + vp.y = 0; + vp.width = 0; + vp.height = 0; + vp.full_width = 0; + vp.full_height = 0; + + if (!(video_driver_translate_coord_viewport_wrap(&vp, x11->mouse_x, x11->mouse_y, + &res_x, &res_y, &res_screen_x, &res_screen_y))) + return 0; + + inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect); + + switch ( id ) + { + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + return inside ? res_x : 0; + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + return inside ? res_y : 0; + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + return !inside; + default: + break; + } + + return 0; +} + static int16_t x_mouse_state(x11_input_t *x11, unsigned id) { switch (id) @@ -193,29 +304,6 @@ static int16_t x_pointer_state(x11_input_t *x11, return 0; } -static int16_t x_lightgun_state(x11_input_t *x11, unsigned id) -{ - switch (id) - { - case RETRO_DEVICE_ID_LIGHTGUN_X: - return x11->mouse_x - x11->mouse_last_x; - case RETRO_DEVICE_ID_LIGHTGUN_Y: - return x11->mouse_y - x11->mouse_last_y; - case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: - return x11->mouse_l; - case RETRO_DEVICE_ID_LIGHTGUN_CURSOR: - return x11->mouse_m; - case RETRO_DEVICE_ID_LIGHTGUN_TURBO: - return x11->mouse_r; - case RETRO_DEVICE_ID_LIGHTGUN_START: - return x11->mouse_m && x11->mouse_r; - case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: - return x11->mouse_m && x11->mouse_l; - } - - return 0; -} - static int16_t x_input_state(void *data, rarch_joypad_info_t joypad_info, const struct retro_keybind **binds, unsigned port, @@ -227,23 +315,11 @@ static int16_t x_input_state(void *data, switch (device) { case RETRO_DEVICE_JOYPAD: - { - int keycode = XKeysymToKeycode(x11->display, - rarch_keysym_lut[(enum retro_key)binds[port][id].key]); - ret = (binds[port][id].key < RETROK_LAST) && (x11->state[keycode >> 3] & (1 << (keycode & 7))); - if (!ret) - ret = input_joypad_pressed(x11->joypad, - joypad_info, port, binds[port], id); - } - return ret; + if (id < RARCH_BIND_LIST_END) + return x_is_pressed(x11, joypad_info, binds[port], port, id); + break; case RETRO_DEVICE_KEYBOARD: - if (id < RETROK_LAST) - { - int keycode = XKeysymToKeycode(x11->display, - rarch_keysym_lut[(enum retro_key)id]); - ret = x11->state[keycode >> 3] & (1 << (keycode & 7)); - } - return ret; + return (id < RETROK_LAST) && x_keyboard_pressed(x11, id); case RETRO_DEVICE_ANALOG: ret = x_pressed_analog(x11, binds[port], idx, id); if (!ret && binds[port]) @@ -263,7 +339,48 @@ static int16_t x_input_state(void *data, device == RARCH_DEVICE_POINTER_SCREEN); break; case RETRO_DEVICE_LIGHTGUN: - return x_lightgun_state(x11, id); + switch ( id ) + { + /*aiming*/ + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + return x_lightgun_aiming_state( x11, idx, id ); + + /*buttons*/ + case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_TRIGGER); + case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_RELOAD); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_A); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_B); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_C); + case RETRO_DEVICE_ID_LIGHTGUN_START: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); + case RETRO_DEVICE_ID_LIGHTGUN_SELECT: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_SELECT); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_UP); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_DOWN); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_LEFT); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_RIGHT); + + /*deprecated*/ + case RETRO_DEVICE_ID_LIGHTGUN_X: + return x11->mouse_x - x11->mouse_last_x; + case RETRO_DEVICE_ID_LIGHTGUN_Y: + return x11->mouse_y - x11->mouse_last_y; + case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: + return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); + + } + break; } return 0;