diff --git a/input/common/hid/device_ds3.c b/input/common/hid/device_ds3.c index a66cfb8ae9..65b8235676 100644 --- a/input/common/hid/device_ds3.c +++ b/input/common/hid/device_ds3.c @@ -335,20 +335,14 @@ static const char *ds3_get_name(void *data) static int16_t ds3_button(void *data, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; ds3_instance_t *pad = (ds3_instance_t *)data; - if(!pad) - return false; - for (; i < end; i++) - { - if (i < 31) - if (pad->buttons & (1 << i)) - ret |= (1 << i); - } - return ret; + if (!pad) + return 0; + if (joykey < 31) + if (pad->buttons & (1 << joykey)) + ret |= (1 << joykey); + return 0; } pad_connection_interface_t ds3_pad_connection = { diff --git a/input/common/hid/device_wiiu_gca.c b/input/common/hid/device_wiiu_gca.c index 153af77fbf..534af65028 100644 --- a/input/common/hid/device_wiiu_gca.c +++ b/input/common/hid/device_wiiu_gca.c @@ -343,20 +343,13 @@ static const char *wiiu_gca_get_name(void *data) static int16_t wiiu_gca_button(void *data, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - gca_pad_t *pad = (gca_pad_t *)data; - + gca_pad_t *pad = (gca_pad_t *)data; if (!pad) return 0; - for (; i < end; i++) - { - if (i < 31) - if (pad->buttons & (1 << i)) - ret |= (1 << i); - } - return ret; + if (joykey < 31) + if (pad->buttons & (1 << joykey)) + ret |= (1 << joykey); + return 0; } pad_connection_interface_t wiiu_gca_pad_connection = { diff --git a/input/common/hid/hid_device_driver.c b/input/common/hid/hid_device_driver.c index ccab2dc569..960740054c 100644 --- a/input/common/hid/hid_device_driver.c +++ b/input/common/hid/hid_device_driver.c @@ -18,25 +18,32 @@ hid_driver_instance_t hid_instance = {0}; -hid_device_t *hid_device_list[] = { - &wiiu_gca_hid_device, - &ds3_hid_device, -/* &ds4_hid_device, */ - NULL /* must be last entry in list */ +hid_device_t *hid_device_list[] = +{ + &wiiu_gca_hid_device, + &ds3_hid_device, +#if 0 + &ds4_hid_device, +#endif + NULL /* must be last entry in list */ }; -hid_device_t *hid_device_driver_lookup(uint16_t vendor_id, uint16_t product_id) { - int i = 0; +hid_device_t *hid_device_driver_lookup( + uint16_t vendor_id, uint16_t product_id) +{ + int i = 0; - for(i = 0; hid_device_list[i] != NULL; i++) { - if(hid_device_list[i]->detect(vendor_id, product_id)) - return hid_device_list[i]; - } + for (i = 0; hid_device_list[i] != NULL; i++) + { + if (hid_device_list[i]->detect(vendor_id, product_id)) + return hid_device_list[i]; + } - return NULL; + return NULL; } -joypad_connection_t *hid_pad_register(void *pad_handle, pad_connection_interface_t *iface) +joypad_connection_t *hid_pad_register( + void *pad_handle, pad_connection_interface_t *iface) { int slot; joypad_connection_t *result; @@ -51,9 +58,9 @@ joypad_connection_t *hid_pad_register(void *pad_handle, pad_connection_interface return NULL; } - result = &(hid_instance.pad_list[slot]); - result->iface = iface; - result->data = iface->init(pad_handle, slot, hid_instance.os_driver); + result = &(hid_instance.pad_list[slot]); + result->iface = iface; + result->data = iface->init(pad_handle, slot, hid_instance.os_driver); result->connected = true; input_pad_connect(slot, hid_instance.pad_driver); @@ -65,12 +72,13 @@ void hid_pad_deregister(joypad_connection_t *pad) if(!pad) return; - if(pad->data) { + if(pad->data) + { pad->iface->deinit(pad->data); pad->data = NULL; } - pad->iface = NULL; + pad->iface = NULL; pad->connected = false; } @@ -97,7 +105,8 @@ static bool init_pad_list(hid_driver_instance_t *instance, unsigned slots) * * @argument instance the hid_driver_instance_t struct to fill in * @argument hid_driver the HID driver to initialize - * @argument pad_driver the gamepad driver to handle HID pads detected by the HID driver. + * @argument pad_driver the gamepad driver to handle HID pads + * detected by the HID driver. * * @returns true if init is successful, false otherwise. */ diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index 1364c43f81..fb49dbd455 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -1423,17 +1423,13 @@ static int16_t android_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = android->joypad->state( + joypad_info, binds[port], port); for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if ( - button_is_pressed( - android->joypad, joypad_info, binds[port], - port, i) - || android_keyboard_port_input_pressed(binds[port], i) - ) + if (android_keyboard_port_input_pressed(binds[port], i)) ret |= (1 << i); } } diff --git a/input/drivers/ctr_input.c b/input/drivers/ctr_input.c index 96a3e237bf..9e9862d3eb 100644 --- a/input/drivers/ctr_input.c +++ b/input/drivers/ctr_input.c @@ -58,33 +58,14 @@ static int16_t ctr_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if (button_is_pressed( - ctr->joypad, joypad_info, binds[port], port, i)) - ret |= (1 << i); - } - } + return ctr->joypad->state( + joypad_info, binds[port], port); - return ret; - } - else - { - if (id < RARCH_BIND_LIST_END) - { - if (binds[port][id].valid) - { - if (button_is_pressed( + if (id < RARCH_BIND_LIST_END) + if (binds[port][id].valid) + if (button_is_pressed( ctr->joypad, joypad_info, binds[port], port, id)) - return 1; - } - } - } + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/dinput.c b/input/drivers/dinput.c index fd7194c618..03fdbf1005 100644 --- a/input/drivers/dinput.c +++ b/input/drivers/dinput.c @@ -571,22 +571,20 @@ static int16_t dinput_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = di->joypad->state( + joypad_info, binds[port], port); - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + if (settings->uints.input_mouse_index[port] == 0) { - if (binds[port][i].valid) + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - if (button_is_pressed( - di->joypad, - joypad_info, binds[port], port, i)) - ret |= (1 << i); - else if ( - settings->uints.input_mouse_index[port] == 0 - && dinput_mouse_button_pressed( - di, port, binds[port][i].mbutton) + if (binds[port][i].valid) + { + if (dinput_mouse_button_pressed( + di, port, binds[port][i].mbutton) ) - ret |= (1 << i); + ret |= (1 << i); + } } } diff --git a/input/drivers/dos_input.c b/input/drivers/dos_input.c index 799ae2eafd..a6d2ab27bc 100644 --- a/input/drivers/dos_input.c +++ b/input/drivers/dos_input.c @@ -26,6 +26,8 @@ #include "../input_keymaps.h" #include "../drivers_keyboard/keyboard_event_dos.h" +#define MAX_KEYS LAST_KEYCODE + 1 + /* TODO/FIXME - * fix game focus toggle */ @@ -34,9 +36,8 @@ typedef struct dos_input const input_device_driver_t *joypad; } dos_input_t; -#define MAX_KEYS LAST_KEYCODE + 1 - /* First ports are used to keeping track of gamepad states. Last port is used for keyboard state */ +/* TODO/FIXME - static globals */ static uint16_t dos_key_state[DEFAULT_MAX_PADS+1][MAX_KEYS]; static bool dos_keyboard_port_input_pressed( @@ -86,18 +87,16 @@ static int16_t dos_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = dos->joypad->state( + joypad_info, binds[port], port); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if ( - button_is_pressed( - dos->joypad, joypad_info, binds[port], - port, i) - || dos_keyboard_port_input_pressed(binds[port], i) - ) - ret |= (1 << i); + if (id < RARCH_BIND_LIST_END) + if (dos_key_state[DOS_KEYBOARD_PORT][rarch_keysym_lut[binds[i].key]]) + ret |= (1 << i); } } @@ -108,9 +107,9 @@ static int16_t dos_input_state(void *data, if (binds[port][id].valid) { if ( - button_is_pressed( - dos->joypad, joypad_info, binds[port], - port, id) + button_is_pressed( + dos->joypad, joypad_info, binds[port], + port, id) || dos_keyboard_port_input_pressed(binds[port], id) ) return 1; @@ -118,7 +117,9 @@ static int16_t dos_input_state(void *data, } break; case RETRO_DEVICE_KEYBOARD: - return dos_keyboard_port_input_pressed(binds[port], id); + if (id < RARCH_BIND_LIST_END) + return (dos_key_state[DOS_KEYBOARD_PORT][rarch_keysym_lut[binds[id].key]]); + break; } return 0; diff --git a/input/drivers/gx_input.c b/input/drivers/gx_input.c index 1cafe4d7b8..dd3f05e4dd 100644 --- a/input/drivers/gx_input.c +++ b/input/drivers/gx_input.c @@ -149,31 +149,14 @@ static int16_t gx_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if ( - button_is_pressed( - gx->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } + return gx->joypad->state( + joypad_info, binds[port], port); - return ret; - } - else - { - if (binds[port][id].valid) - if ( - button_is_pressed(gx->joypad, joypad_info, binds[port], - port, id)) - return 1; - } + if (binds[port][id].valid) + if ( + button_is_pressed(gx->joypad, joypad_info, binds[port], + port, id)) + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/linuxraw_input.c b/input/drivers/linuxraw_input.c index d1260f1835..3f7c51446f 100644 --- a/input/drivers/linuxraw_input.c +++ b/input/drivers/linuxraw_input.c @@ -119,18 +119,14 @@ static int16_t linuxraw_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = linuxraw->joypad->state( + joypad_info, binds[port], port); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { if ( - button_is_pressed( - linuxraw->joypad, joypad_info, binds[port], - port, i) - ) - ret |= (1 << i); - else if ( linuxraw->state[rarch_keysym_lut[ (enum retro_key)binds[port][i].key]] ) diff --git a/input/drivers/ps2_input.c b/input/drivers/ps2_input.c index 94a0236f9d..77743e6f0b 100644 --- a/input/drivers/ps2_input.c +++ b/input/drivers/ps2_input.c @@ -51,30 +51,13 @@ static int16_t ps2_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if (button_is_pressed(ps2->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } + return ps2->joypad->state( + joypad_info, binds[port], port); - return ret; - } - else - { - if (binds[port][id].valid) - { - if (button_is_pressed(ps2->joypad, joypad_info, binds[port], - port, id)) - return 1; - } - } + if (binds[port][id].valid) + if (button_is_pressed(ps2->joypad, joypad_info, binds[port], + port, id)) + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/ps3_input.c b/input/drivers/ps3_input.c index 012ae64afc..6677ae0e96 100644 --- a/input/drivers/ps3_input.c +++ b/input/drivers/ps3_input.c @@ -108,31 +108,14 @@ static int16_t ps3_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if ( - button_is_pressed(ps3->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } + return ps3->joypad->state( + joypad_info, binds[port], port); + + if (binds[port][id].valid) + if (button_is_pressed(ps3->joypad, joypad_info, binds[port], + port, id)) + return 1; - return ret; - } - else - { - if (binds[port][id].valid) - { - if (button_is_pressed(ps3->joypad, joypad_info, binds[port], - port, id)) - return 1; - } - } break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/ps4_input.c b/input/drivers/ps4_input.c index 533b4dc681..608425d28d 100644 --- a/input/drivers/ps4_input.c +++ b/input/drivers/ps4_input.c @@ -57,32 +57,14 @@ static int16_t ps4_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if ( - button_is_pressed(ps4->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } + return ps4->joypad->state( + joypad_info, binds[port], port); - return ret; - } - else - { - if (binds[port][id].valid) - { - if ( - button_is_pressed(ps4->joypad, joypad_info, binds[port], - port, id)) - return 1; - } - } + if (binds[port][id].valid) + if ( + button_is_pressed(ps4->joypad, joypad_info, binds[port], + port, id)) + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/psl1ght_input.c b/input/drivers/psl1ght_input.c index f8509d7ac5..02df22bdcb 100644 --- a/input/drivers/psl1ght_input.c +++ b/input/drivers/psl1ght_input.c @@ -220,16 +220,14 @@ static int16_t ps3_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = ps3->joypad->state( + joypad_info, binds[port], port); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if ( - button_is_pressed(ps3->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - else if (psl1ght_keyboard_port_input_pressed(ps3, binds[port][i].key)) + if (psl1ght_keyboard_port_input_pressed(ps3, binds[port][i].key)) ret |= (1 << i); } } @@ -424,46 +422,34 @@ static uint16_t transform_buttons(const padData *data) ); } -static int16_t ps3_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t ps3_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; uint16_t state = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (port_num >= MAX_PADS) + if (port >= MAX_PADS) return 0; - state = transform_buttons( - &pad_state[port_num]); - for (; i < end; i++) - { - if (state & (UINT64_C(1) << i)) - ret |= (UINT64_C(1) << i); - } - return ret; + &pad_state[port]); + return (state & (UINT64_C(1) << joykey); } -static void ps3_joypad_get_buttons(unsigned port_num, input_bits_t *state) +static void ps3_joypad_get_buttons(unsigned port, input_bits_t *state) { - if (port_num < MAX_PADS) + if (port < MAX_PADS) { - uint16_t v = transform_buttons(&pad_state[port_num]); + uint16_t v = transform_buttons(&pad_state[port]); BITS_COPY16_PTR( state, v); } else BIT256_CLEAR_ALL_PTR(state); } -static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t ps3_joypad_axis_state(unsigned port, uint32_t joyaxis) { int val = 0x80; int axis = -1; bool is_neg = false; bool is_pos = false; - if (port_num >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -478,16 +464,16 @@ static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) switch (axis) { case 0: - val = pad_state[port_num].ANA_L_H; + val = pad_state[port].ANA_L_H; break; case 1: - val = pad_state[port_num].ANA_L_V; + val = pad_state[port].ANA_L_V; break; case 2: - val = pad_state[port_num].ANA_R_H; + val = pad_state[port].ANA_R_H; break; case 3: - val = pad_state[port_num].ANA_R_V; + val = pad_state[port].ANA_R_V; break; } @@ -500,6 +486,48 @@ static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t ps3_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (port >= DEFAULT_MAX_PADS) + return 0; + return ps3_joypad_axis_state(port, joyaxis); +} + +static int16_t ps3_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + uint16_t state = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + state = transform_buttons(&pad_state[port]); + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && (state & (UINT64_C(1) << (uint16_t)joykey)) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(ps3_joypad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void ps3_joypad_poll(void) { unsigned port; @@ -547,6 +575,7 @@ input_device_driver_t ps3_joypad = { ps3_joypad_query_pad, ps3_joypad_destroy, ps3_joypad_button, + ps3_joypad_state, ps3_joypad_get_buttons, ps3_joypad_axis, ps3_joypad_poll, diff --git a/input/drivers/psp_input.c b/input/drivers/psp_input.c index 285b857c3d..93c56b882b 100644 --- a/input/drivers/psp_input.c +++ b/input/drivers/psp_input.c @@ -300,32 +300,14 @@ static int16_t psp_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if ( - button_is_pressed(psp->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } + return psp->joypad->state( + joypad_info, binds[port], port); - return ret; - } - else - { - if (binds[port][id].valid) - { - if ( - button_is_pressed(psp->joypad, joypad_info, binds[port], - port, id)) - return 1; - } - } + if (binds[port][id].valid) + if ( + button_is_pressed(psp->joypad, joypad_info, binds[port], + port, id)) + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/qnx_input.c b/input/drivers/qnx_input.c index 407b88ef43..897dea31a0 100644 --- a/input/drivers/qnx_input.c +++ b/input/drivers/qnx_input.c @@ -788,18 +788,8 @@ static int16_t qnx_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; - - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if (button_is_pressed( - qnx->joypad, - joypad_info, binds[port], port, i)) - ret |= (1 << i); - } - } + int16_t ret = qnx->joypad->state( + joypad_info, binds[port], port); if (!input_qnx.keyboard_mapping_blocked) { diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 4000b43389..d0760dc56f 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -202,18 +202,14 @@ static int16_t sdl_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = sdl->joypad->state( + joypad_info, binds[port], port); for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) - { - if (button_is_pressed( - sdl->joypad, joypad_info, binds[port], port, i)) + if (sdl_key_pressed(binds[port][i].key)) ret |= (1 << i); - else if (sdl_key_pressed(binds[port][i].key)) - ret |= (1 << i); - } } return ret; diff --git a/input/drivers/switch_input.c b/input/drivers/switch_input.c index cc2b7fd55d..76eabeac0f 100644 --- a/input/drivers/switch_input.c +++ b/input/drivers/switch_input.c @@ -394,32 +394,14 @@ static int16_t switch_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if ( - button_is_pressed(sw->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } + return sw->joypad->state( + joypad_info, binds[port], port); - return ret; - } - else - { - if (binds[port][id].valid) - { - if ( - button_is_pressed(sw->joypad, joypad_info, binds[port], - port, id)) - return 1; - } - } + if (binds[port][id].valid) + if ( + button_is_pressed(sw->joypad, joypad_info, binds[port], + port, id)) + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index 99b935640a..9714d4c436 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -994,16 +994,14 @@ static int16_t udev_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = udev->joypad->state( + joypad_info, binds[port], port); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if (button_is_pressed( - udev->joypad, - joypad_info, binds[port], port, i)) - ret |= (1 << i); - else if (udev_mouse_button_pressed(udev, port, binds[port][i].mbutton)) + if (udev_mouse_button_pressed(udev, port, binds[port][i].mbutton)) ret |= (1 << i); } } diff --git a/input/drivers/uwp_input.c b/input/drivers/uwp_input.c index ad8c25e7f5..146daa6e54 100644 --- a/input/drivers/uwp_input.c +++ b/input/drivers/uwp_input.c @@ -148,17 +148,16 @@ static int16_t uwp_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = uwp->joypad->state( + joypad_info, binds[port], port); + if (input_uwp.keyboard_mapping_blocked) { for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if (button_is_pressed( - uwp->joypad, joypad_info, binds[port], port, i)) - ret |= (1 << i); - else if (uwp_mouse_state(port, + if (uwp_mouse_state(port, binds[port][i].mbutton, false)) ret |= (1 << i); } @@ -170,9 +169,9 @@ static int16_t uwp_input_state(void *data, { if (binds[port][i].valid) { - if ( button_is_pressed( - uwp->joypad, joypad_info, binds[port], port, i) - || ((binds[port][i].key < RETROK_LAST) && uwp_keyboard_pressed(binds[port][i].key)) + if ( + ((binds[port][i].key < RETROK_LAST) + && uwp_keyboard_pressed(binds[port][i].key)) ) ret |= (1 << i); else if (uwp_mouse_state(port, diff --git a/input/drivers/wayland_input.c b/input/drivers/wayland_input.c index 25cc76f794..dba61d8158 100644 --- a/input/drivers/wayland_input.c +++ b/input/drivers/wayland_input.c @@ -308,15 +308,14 @@ static int16_t input_wl_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = wl->joypad->state( + joypad_info, binds[port], port); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if (button_is_pressed(wl->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - else if (BIT_GET(wl->key_state, + if (BIT_GET(wl->key_state, rarch_keysym_lut[binds[port][i].key]) ) ret |= (1 << i); } diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 5f8457ce9f..849ce8abbd 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -136,28 +136,13 @@ static int16_t wiiu_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; + return wiiu->joypad->state( + joypad_info, binds[port], port); - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - if (button_is_pressed( - wiiu->joypad, - joypad_info, binds[port], port, i)) - ret |= (1 << i); - } - - return ret; - } - else - { - if (binds[port][id].valid) - return button_is_pressed( - wiiu->joypad, - joypad_info, binds[port], port, id); - } + if (binds[port][id].valid) + return button_is_pressed( + wiiu->joypad, + joypad_info, binds[port], port, id); break; case RETRO_DEVICE_KEYBOARD: if (id < RETROK_LAST && keyboard_state[id] && (keyboard_channel > 0)) diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c index 7a3efa0745..12b98f379c 100644 --- a/input/drivers/winraw_input.c +++ b/input/drivers/winraw_input.c @@ -599,21 +599,22 @@ static int16_t winraw_input_state(void *d, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = wr->joypad->state( + joypad_info, binds[port], port); - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + if (mouse) { - if (binds[port][i].valid) + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - if (button_is_pressed( - wr->joypad, - joypad_info, binds[port], port, i)) - ret |= (1 << i); - else if (mouse && winraw_mouse_button_pressed(wr, - mouse, port, binds[port][i].mbutton)) - ret |= (1 << i); + if (binds[port][i].valid) + { + if (winraw_mouse_button_pressed(wr, + mouse, port, binds[port][i].mbutton)) + ret |= (1 << i); + } } } + if (!input_winraw.keyboard_mapping_blocked) { for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index 7df787aac4..5141cff33b 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -289,16 +289,14 @@ static int16_t x_input_state(void *data, if (id == RETRO_DEVICE_ID_JOYPAD_MASK) { unsigned i; - int16_t ret = 0; + int16_t ret = x11->joypad->state( + joypad_info, binds[port], port); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (binds[port][i].valid) { - if (button_is_pressed( - x11->joypad, - joypad_info, binds[port], port, i)) - ret |= (1 << i); - else if (x_mouse_button_pressed(x11, port, + if (x_mouse_button_pressed(x11, port, binds[port][i].mbutton)) ret |= (1 << i); } diff --git a/input/drivers/xdk_xinput_input.c b/input/drivers/xdk_xinput_input.c index 62fea44dc1..59fd13e607 100644 --- a/input/drivers/xdk_xinput_input.c +++ b/input/drivers/xdk_xinput_input.c @@ -63,33 +63,14 @@ static int16_t xdk_input_state(void *data, { case RETRO_DEVICE_JOYPAD: if (id == RETRO_DEVICE_ID_JOYPAD_MASK) - { - unsigned i; - int16_t ret = 0; + return xdk->joypad->state( + joypad_info, binds[port], port); - for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) - { - if (binds[port][i].valid) - { - if ( - button_is_pressed(xdk->joypad, joypad_info, binds[port], - port, i)) - ret |= (1 << i); - } - } - - return ret; - } - else - { - if (binds[port][id].valid) - { - if ( - button_is_pressed(xdk->joypad, joypad_info, binds[port], - port, id)) - return 1; - } - } + if (binds[port][id].valid) + if ( + button_is_pressed(xdk->joypad, joypad_info, binds[port], + port, id)) + return 1; break; case RETRO_DEVICE_ANALOG: break; diff --git a/input/drivers_hid/btstack_hid.c b/input/drivers_hid/btstack_hid.c index 1758e32f5f..682f9ee679 100644 --- a/input/drivers_hid/btstack_hid.c +++ b/input/drivers_hid/btstack_hid.c @@ -1367,19 +1367,45 @@ static int16_t btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { input_bits_t buttons; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; btstack_hid_joypad_get_buttons(data, port, &buttons); - for (; i < end; i++) + /* Check hat. */ + if (GET_HAT_DIR(joykey)) + return 0; + else if ((port < MAX_USERS) && (joykey < 32)) + return (BIT256_GET(buttons, joykey) != 0); + return 0; +} + +static int16_t btstack_hid_joypad_state( + void *data, + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + const struct dinput_joypad_data *pad = &g_pads[port]; + + if (!pad || !pad->joypad) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - /* Check hat. */ - if (GET_HAT_DIR(i)) - continue; - else if ((port < MAX_USERS) && (i < 32)) - if (BIT256_GET(buttons, i) != 0) - ret |= (1 << i); + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && btstack_hid_joypad_button(data, + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(btstack_hid_joypad_axis(data, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); } return ret; @@ -1464,6 +1490,7 @@ hid_driver_t btstack_hid = { btstack_hid_joypad_query, btstack_hid_free, btstack_hid_joypad_button, + btstack_hid_joypad_state, btstack_hid_joypad_get_buttons, btstack_hid_joypad_axis, btstack_hid_poll, diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index d750c4fe83..82cfc2561e 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -149,10 +149,8 @@ static void iohidmanager_hid_joypad_get_buttons(void *data, static int16_t iohidmanager_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { + unsigned hat_dir; input_bits_t buttons; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; if (port >= DEFAULT_MAX_PADS) @@ -160,44 +158,60 @@ static int16_t iohidmanager_hid_joypad_button(void *data, iohidmanager_hid_joypad_get_buttons(data, port, &buttons); - for (; i < end; i++) + hat_dir = GET_HAT_DIR(joykey); + + /* Check hat. */ + if (hat_dir) { - unsigned hat_dir = GET_HAT_DIR(i); + unsigned h = GET_HAT(joykey); + if (h >= 1) + return 0; - /* Check hat. */ - if (hat_dir) + switch (hat_dir) { - unsigned h = GET_HAT(i); - if (h >= 1) - continue; - - switch (hat_dir) - { - case HAT_LEFT_MASK: - if (hid->hats[port][0] < 0) - ret |= (1 << i); - break; - case HAT_RIGHT_MASK: - if (hid->hats[port][0] > 0) - ret |= (1 << i); - break; - case HAT_UP_MASK: - if (hid->hats[port][1] < 0) - ret |= (1 << i); - break; - case HAT_DOWN_MASK: - if (hid->hats[port][1] > 0) - ret |= (1 << i); - break; - default: - break; - } - /* hat requested and no hat button down */ + case HAT_LEFT_MASK: + return (hid->hats[port][0] < 0); + case HAT_RIGHT_MASK: + return (hid->hats[port][0] > 0); + case HAT_UP_MASK: + return (hid->hats[port][1] < 0); + case HAT_DOWN_MASK: + return (hid->hats[port][1] > 0); + default: + break; } - else if (i < 32) - if ((BIT256_GET(buttons, i) != 0) - || ((hid->buttons[port] & (1 << i)) != 0)) - ret |= (1 << i); + /* hat requested and no hat button down */ + } + else if (joykey < 32) + return ((BIT256_GET(buttons, joykey) != 0) + || ((hid->buttons[port] & (1 << joykey)) != 0)); + return 0; +} + +static int16_t iohidmanager_hid_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && iohidmanager_hid_joypad_button(data, + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(iohidmanager_hid_joypad_axis(data, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); } return ret; @@ -1146,6 +1160,7 @@ hid_driver_t iohidmanager_hid = { iohidmanager_hid_joypad_query, iohidmanager_hid_free, iohidmanager_hid_joypad_button, + iohidmanager_hid_joypad_state, iohidmanager_hid_joypad_get_buttons, iohidmanager_hid_joypad_axis, iohidmanager_hid_poll, diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index a268c5d90b..c83c3a3b10 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -458,24 +458,17 @@ static int16_t libusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { input_bits_t buttons; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port >= DEFAULT_MAX_PADS) return 0; libusb_hid_joypad_get_buttons(data, port, &buttons); - for (; i < end; i++) - { - /* Check hat. */ - if (GET_HAT_DIR(i)) - continue; - else if (i < 32) - if (BIT256_GET(buttons, i) != 0) - ret |= (1 << i); - } - return ret; + /* Check hat. */ + if (GET_HAT_DIR(joykey)) + continue; + else if (joykey < 32) + return (BIT256_GET(buttons, joykey) != 0); + return 0; } static bool libusb_hid_joypad_rumble(void *data, unsigned pad, @@ -513,6 +506,36 @@ static int16_t libusb_hid_joypad_axis(void *data, return val; } +static int16_t libusb_hid_joypad_state( + void *data, + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && libusb_hid_joypad_button(data, + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(libusb_hid_joypad_axis(data, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void libusb_hid_free(const void *data) { libusb_hid_t *hid = (libusb_hid_t*)data; @@ -652,6 +675,7 @@ hid_driver_t libusb_hid = { libusb_hid_joypad_query, libusb_hid_free, libusb_hid_joypad_button, + libusb_hid_joypad_state, libusb_hid_joypad_get_buttons, libusb_hid_joypad_axis, libusb_hid_poll, diff --git a/input/drivers_hid/wiiu_hid.c b/input/drivers_hid/wiiu_hid.c index 85f0fe6402..9bbc0cc516 100644 --- a/input/drivers_hid/wiiu_hid.c +++ b/input/drivers_hid/wiiu_hid.c @@ -17,10 +17,13 @@ #include "../include/wiiu/hid.h" #include +/* TODO/FIXME - static globals */ static wiiu_event_list events; static wiiu_adapter_list adapters; -static void report_hid_error(const char *msg, wiiu_adapter_t *adapter, int32_t error); +/* Forward declaration */ +static void report_hid_error(const char *msg, + wiiu_adapter_t *adapter, int32_t error); static bool wiiu_hid_joypad_query(void *data, unsigned slot) { @@ -64,18 +67,40 @@ static void wiiu_hid_joypad_get_buttons(void *data, unsigned slot, input_bits_t static int16_t wiiu_hid_joypad_button(void *data, unsigned slot, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot); - if (!pad) return 0; - for (; i < end; i++) + return pad->iface->button(pad->data, joykey); +} + +static int16_t wiiu_hid_joypad_state( + void *data, + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - if (pad->iface->button(pad->data, i)) + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && wiiu_hid_joypad_button( + data, + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(wiiu_hid_joypad_axis(data, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) ret |= (1 << i); } + return ret; } @@ -504,9 +529,7 @@ static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error, } if (error < 0) - { report_hid_error("async read failed", adapter, error); - } if (adapter->state == ADAPTER_STATE_READING) { @@ -828,6 +851,7 @@ hid_driver_t wiiu_hid = { wiiu_hid_joypad_query, wiiu_hid_free, wiiu_hid_joypad_button, + wiiu_hid_joypad_state, wiiu_hid_joypad_get_buttons, wiiu_hid_joypad_axis, wiiu_hid_poll, diff --git a/input/drivers_hid/wiiusb_hid.c b/input/drivers_hid/wiiusb_hid.c index a78965770c..4666d6626f 100644 --- a/input/drivers_hid/wiiusb_hid.c +++ b/input/drivers_hid/wiiusb_hid.c @@ -543,22 +543,46 @@ static int16_t wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { input_bits_t buttons; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port >= DEFAULT_MAX_PADS) return 0; wiiusb_hid_joypad_get_buttons(data, port, &buttons); - for (; i < end; i++) + /* Check hat. */ + if (GET_HAT_DIR(joykey)) + return 0; + else if (joykey < 32) + return (BIT256_GET(buttons, joykey) != 0); + + return 0; +} + +static int16_t wiiusb_hid_joypad_state( + void *data, + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - /* Check hat. */ - if (GET_HAT_DIR(i)) - continue; - else if (i < 32) - if (BIT256_GET(buttons, i) != 0) - ret |= (1 << i); + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && wiiusb_hid_joypad_button( + data, + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(wiiusb_hid_joypad_axis(data, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); } return ret; @@ -679,6 +703,7 @@ hid_driver_t wiiusb_hid = { wiiusb_hid_joypad_query, wiiusb_hid_free, wiiusb_hid_joypad_button, + wiiusb_hid_joypad_state, wiiusb_hid_joypad_get_buttons, wiiusb_hid_joypad_axis, wiiusb_hid_poll, diff --git a/input/drivers_joypad/android_joypad.c b/input/drivers_joypad/android_joypad.c index 8daf0ca46d..93e59b604e 100644 --- a/input/drivers_joypad/android_joypad.c +++ b/input/drivers_joypad/android_joypad.c @@ -30,55 +30,48 @@ static bool android_joypad_init(void *data) return true; } +static int16_t android_joypad_button_state( + uint8_t *buf, + unsigned port, uint16_t joykey) +{ + struct android_app + *android_app = (struct android_app*)g_android; + unsigned hat_dir = GET_HAT_DIR(joykey); + + if (hat_dir) + { + unsigned h = GET_HAT(joykey); + if (h > 0) + return 0; + + switch (hat_dir) + { + case HAT_LEFT_MASK: + return (android_app->hat_state[port][0] == -1); + case HAT_RIGHT_MASK: + return (android_app->hat_state[port][0] == 1); + case HAT_UP_MASK: + return (android_app->hat_state[port][1] == -1); + case HAT_DOWN_MASK: + return (android_app->hat_state[port][1] == 1); + default: + break; + } + /* hat requested and no hat button down */ + } + else if (joykey < LAST_KEYCODE) + return BIT_GET(buf, joykey); + return 0; +} + static int16_t android_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; uint8_t *buf = android_keyboard_state_get(port); - struct android_app *android_app = (struct android_app*)g_android; - unsigned hat_dir = GET_HAT_DIR(joykey); - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (hat_dir) - { - unsigned h = GET_HAT(i); - if (h > 0) - continue; - - switch (hat_dir) - { - case HAT_LEFT_MASK: - if (android_app->hat_state[port][0] == -1) - ret |= (1 << i); - break; - case HAT_RIGHT_MASK: - if (android_app->hat_state[port][0] == 1) - ret |= (1 << i); - break; - case HAT_UP_MASK: - if (android_app->hat_state[port][1] == -1) - ret |= (1 << i); - break; - case HAT_DOWN_MASK: - if (android_app->hat_state[port][1] == 1) - ret |= (1 << i); - break; - default: - break; - } - /* hat requested and no hat button down */ - } - else if (i < LAST_KEYCODE) - if (BIT_GET(buf, i)) - ret |= (1 << i); - } - - return ret; + return android_joypad_button_state(buf, port, joykey); } static int16_t android_joypad_axis(unsigned port, uint32_t joyaxis) @@ -102,6 +95,38 @@ static int16_t android_joypad_axis(unsigned port, uint32_t joyaxis) return val; } +static int16_t android_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + uint8_t *buf = android_keyboard_state_get(port); + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ((uint16_t)joykey != NO_BTN && android_joypad_button_state( + buf, + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(android_joypad_axis(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void android_joypad_poll(void) { } static bool android_joypad_query_pad(unsigned pad) @@ -128,6 +153,7 @@ input_device_driver_t android_joypad = { android_joypad_query_pad, android_joypad_destroy, android_joypad_button, + android_joypad_state, NULL, android_joypad_axis, android_joypad_poll, diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index 24748650fe..894d674833 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -57,18 +57,9 @@ static bool ctr_joypad_init(void *data) static int16_t ctr_joypad_button(unsigned port_num, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port_num >= DEFAULT_MAX_PADS) return 0; - - for (; i < end; i++) - { - if (pad_state & (1 << i)) - ret |= (1 << i); - } - return ret; + return (pad_state & (1 << joykey)); } static void ctr_joypad_get_buttons(unsigned port_num, input_bits_t *state) @@ -126,6 +117,37 @@ static int16_t ctr_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t ctr_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + + if ((uint16_t)joykey != NO_BTN && + (pad_state & (1 << (uint16_t)joykey))) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(ctr_joypad_axis(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static int16_t ctr_joypad_fix_range(int16_t val) { val = (val > 127)? 127: (val < -127)? -127: val; @@ -195,6 +217,7 @@ input_device_driver_t ctr_joypad = { ctr_joypad_query_pad, ctr_joypad_destroy, ctr_joypad_button, + ctr_joypad_state, ctr_joypad_get_buttons, ctr_joypad_axis, ctr_joypad_poll, diff --git a/input/drivers_joypad/dinput_joypad.c b/input/drivers_joypad/dinput_joypad.c index 8344e410ea..ab27602cde 100644 --- a/input/drivers_joypad/dinput_joypad.c +++ b/input/drivers_joypad/dinput_joypad.c @@ -442,103 +442,84 @@ static bool dinput_joypad_init(void *data) return true; } -static int16_t dinput_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t dinput_joypad_button_state( + const struct dinput_joypad_data *pad, + uint16_t joykey) { - const struct dinput_joypad_data *pad = &g_pads[port_num]; - int16_t ret = 0; - unsigned hat_dir = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; + unsigned hat_dir = GET_HAT_DIR(joykey); - if (!pad || !pad->joypad) - return 0; - - for (; i < end; i++) + if (hat_dir) { - hat_dir = GET_HAT_DIR(i); - - if (hat_dir) + unsigned h = GET_HAT(joykey); + if (h < NUM_HATS) { - unsigned h = GET_HAT(i); - if (h < NUM_HATS) + unsigned pov = pad->joy_state.rgdwPOV[h]; + switch (hat_dir) { - unsigned pov = pad->joy_state.rgdwPOV[h]; - switch (hat_dir) - { - case HAT_UP_MASK: - { - static const unsigned check1 = (JOY_POVRIGHT/2); - static const unsigned check2 = (JOY_POVLEFT+JOY_POVRIGHT/2); - if ( + case HAT_UP_MASK: + { + static const unsigned check1 = (JOY_POVRIGHT/2); + static const unsigned check2 = (JOY_POVLEFT+JOY_POVRIGHT/2); + return ( (pov == JOY_POVFORWARD) || (pov == check1) || (pov == check2) - ) - ret |= (1 << i); - } - break; - case HAT_RIGHT_MASK: - { - static const unsigned check1 = (JOY_POVRIGHT/2); - static const unsigned check2 = (JOY_POVRIGHT+JOY_POVRIGHT/2); - if ( + ); + } + case HAT_RIGHT_MASK: + { + static const unsigned check1 = (JOY_POVRIGHT/2); + static const unsigned check2 = (JOY_POVRIGHT+JOY_POVRIGHT/2); + return ( (pov == JOY_POVRIGHT) || (pov == check1) || (pov == check2) - ) - ret |= (1 << i); - } - break; - case HAT_DOWN_MASK: - { - static const unsigned check1 = (JOY_POVRIGHT+JOY_POVRIGHT/2); - static const unsigned check2 = (JOY_POVBACKWARD+JOY_POVRIGHT/2); - if - ( - (pov == JOY_POVBACKWARD) || - (pov == check1) || - (pov == check2) - ) - ret |= (1 << i); - } - break; - case HAT_LEFT_MASK: - { - static const unsigned check1 = (JOY_POVBACKWARD+JOY_POVRIGHT/2); - static const unsigned check2 = (JOY_POVLEFT+JOY_POVRIGHT/2); - if - ( - (pov == JOY_POVLEFT) || - (pov == check1) || - (pov == check2) - ) - ret |= (1 << i); - } - break; - default: - break; - } - } - /* hat requested and no hat button down */ - } - else if (i < ARRAY_SIZE_RGB_BUTTONS) - if (pad->joy_state.rgbButtons[i]) - ret |= (1 << i); - } + ); + } + case HAT_DOWN_MASK: + { + static const unsigned check1 = (JOY_POVRIGHT+JOY_POVRIGHT/2); + static const unsigned check2 = (JOY_POVBACKWARD+JOY_POVRIGHT/2); + return + ( + (pov == JOY_POVBACKWARD) || + (pov == check1) || + (pov == check2) + ); + } + case HAT_LEFT_MASK: + { + static const unsigned check1 = (JOY_POVBACKWARD+JOY_POVRIGHT/2); + static const unsigned check2 = (JOY_POVLEFT+JOY_POVRIGHT/2); - return ret; + return + ( + (pov == JOY_POVLEFT) || + (pov == check1) || + (pov == check2) + ); + } + break; + default: + break; + } + } + /* hat requested and no hat button down */ + } + else if (joykey < ARRAY_SIZE_RGB_BUTTONS) + if (pad->joy_state.rgbButtons[joykey]) + return 1; + return 0; } -static int16_t dinput_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t dinput_joypad_axis_state( + const struct dinput_joypad_data *pad, + uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - const struct dinput_joypad_data *pad = &g_pads[port_num]; - - if (!pad->joypad) - return 0; if (AXIS_NEG_GET(joyaxis) <= 7) { @@ -587,6 +568,55 @@ static int16_t dinput_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t dinput_joypad_button(unsigned port_num, uint16_t joykey) +{ + const struct dinput_joypad_data *pad = &g_pads[port_num]; + if (!pad || !pad->joypad) + return 0; + return dinput_joypad_button_state(pad, joykey); +} + +static int16_t dinput_joypad_axis(unsigned port_num, uint32_t joyaxis) +{ + const struct dinput_joypad_data *pad = &g_pads[port_num]; + if (!pad || !pad->joypad) + return 0; + return dinput_joypad_axis_state(pad, joyaxis); +} + +static int16_t dinput_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + const struct dinput_joypad_data *pad = &g_pads[port]; + + if (!pad || !pad->joypad) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && dinput_joypad_button_state( + pad, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(dinput_joypad_axis_state(pad, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void dinput_joypad_poll(void) { unsigned i; @@ -686,6 +716,7 @@ input_device_driver_t dinput_joypad = { dinput_joypad_query_pad, dinput_joypad_destroy, dinput_joypad_button, + dinput_joypad_state, NULL, dinput_joypad_axis, dinput_joypad_poll, diff --git a/input/drivers_joypad/dos_joypad.c b/input/drivers_joypad/dos_joypad.c index 8887a48257..e79f3721fc 100644 --- a/input/drivers_joypad/dos_joypad.c +++ b/input/drivers_joypad/dos_joypad.c @@ -159,71 +159,76 @@ static bool dos_joypad_init(void *data) dos_joypad_autodetect_add(0); - (void)data; - return true; } +static int16_t dos_joypad_button_state( + uint16_t *buf, uint16_t joykey) +{ + switch (key) + { + case RETRO_DEVICE_ID_JOYPAD_A: + return buf[DOSKEY_x]; + case RETRO_DEVICE_ID_JOYPAD_B: + return buf[DOSKEY_z]; + case RETRO_DEVICE_ID_JOYPAD_X: + return buf[DOSKEY_s]; + case RETRO_DEVICE_ID_JOYPAD_Y: + return buf[DOSKEY_a]; + case RETRO_DEVICE_ID_JOYPAD_SELECT: + return buf[DOSKEY_RSHIFT]; + case RETRO_DEVICE_ID_JOYPAD_START: + return buf[DOSKEY_RETURN]; + case RETRO_DEVICE_ID_JOYPAD_UP: + return buf[DOSKEY_UP]; + case RETRO_DEVICE_ID_JOYPAD_DOWN: + return buf[DOSKEY_DOWN]; + case RETRO_DEVICE_ID_JOYPAD_LEFT: + return buf[DOSKEY_LEFT]; + case RETRO_DEVICE_ID_JOYPAD_RIGHT: + return buf[DOSKEY_RIGHT]; + } + + return 0; +} + static int16_t dos_joypad_button(unsigned port_num, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - uint16_t *buf = dos_keyboard_state_get(port_num); + uint16_t *buf = dos_keyboard_state_get(port_num); if (port_num >= DEFAULT_MAX_PADS) return 0; + return dos_joypad_button_state(buf, joykey); +} - for (; i < end; i++) +static int16_t dos_joypad_axis(unsigned port_num, uint32_t joyaxis) { return 0; } + +static int16_t dos_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + uint16_t *buf = dos_keyboard_state_get(port); + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - switch (key) - { - case RETRO_DEVICE_ID_JOYPAD_A: - if (buf[DOSKEY_x]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_B: - if (buf[DOSKEY_z]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_X: - if (buf[DOSKEY_s]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_Y: - if (buf[DOSKEY_a]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_SELECT: - if (buf[DOSKEY_RSHIFT]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_START: - if (buf[DOSKEY_RETURN]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_UP: - if (buf[DOSKEY_UP]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_DOWN: - if (buf[DOSKEY_DOWN]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_LEFT: - if (buf[DOSKEY_LEFT]) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_RIGHT: - if (buf[DOSKEY_RIGHT]) - ret |= (1 << i); - break; - } + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + if ((uint16_t)joykey != NO_BTN && dos_joypad_button_state( + buf, (uint16_t)joykey)) + ret |= ( 1 << i); } return ret; } + static void dos_joypad_poll(void) { uint32_t i; @@ -252,11 +257,6 @@ static bool dos_joypad_query_pad(unsigned pad) return (pad < MAX_USERS); } -static int16_t dos_joypad_axis(unsigned port_num, uint32_t joyaxis) -{ - return 0; -} - static void dos_joypad_destroy(void) { unhook_keyb_int(); @@ -267,6 +267,7 @@ input_device_driver_t dos_joypad = { dos_joypad_query_pad, dos_joypad_destroy, dos_joypad_button, + dos_joypad_state, NULL, dos_joypad_axis, dos_joypad_poll, diff --git a/input/drivers_joypad/gx_joypad.c b/input/drivers_joypad/gx_joypad.c index cda6054ca0..d5d390b51b 100644 --- a/input/drivers_joypad/gx_joypad.c +++ b/input/drivers_joypad/gx_joypad.c @@ -245,17 +245,9 @@ static void check_port0_active(uint8_t pad_count) static int16_t gx_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (pad_state[port] & (UINT64_C(1) << i)) - ret |= (1 << i); - } - return ret; + return (pad_state[port] & (UINT64_C(1) << joykey)); } static void gx_joypad_get_buttons(unsigned port, input_bits_t *state) @@ -268,51 +260,86 @@ static void gx_joypad_get_buttons(unsigned port, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t gx_joypad_axis(unsigned port, uint32_t joyaxis) +static int16_t gx_joypad_axis_state(unsigned port, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - if (port >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) < 4) { - axis = AXIS_NEG_GET(joyaxis); - is_neg = true; + axis = AXIS_NEG_GET(joyaxis); + is_neg = true; } else if (AXIS_POS_GET(joyaxis) < 4) { - axis = AXIS_POS_GET(joyaxis); - is_pos = true; + axis = AXIS_POS_GET(joyaxis); + is_pos = true; } switch (axis) { case 0: - val = analog_state[port][0][0]; + val = analog_state[port][0][0]; break; case 1: - val = analog_state[port][0][1]; + val = analog_state[port][0][1]; break; case 2: - val = analog_state[port][1][0]; + val = analog_state[port][1][0]; break; case 3: - val = analog_state[port][1][1]; + val = analog_state[port][1][1]; break; } if (is_neg && val > 0) - val = 0; + val = 0; else if (is_pos && val < 0) - val = 0; - + val = 0; return val; } +static int16_t gx_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (port >= DEFAULT_MAX_PADS) + return 0; + return gx_joypad_axis_state(port, joyaxis); +} + +static int16_t gx_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN && + (pad_state[port] & (UINT64_C(1) << joykey)) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(gx_joypad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + #ifdef HW_RVL #ifndef PI @@ -410,10 +437,10 @@ static int16_t WPAD_StickY(WPADData *data, u8 right) static void gx_joypad_poll(void) { unsigned i, j, port; - uint8_t pad_count = 0; - uint8_t gcpad = 0; - uint64_t state_p1; - uint64_t check_menu_toggle; + uint64_t state_p1 = 0; + uint64_t check_menu_toggle = 0; + uint8_t pad_count = 0; + uint8_t gcpad = 0; pad_state[0] = 0; pad_state[1] = 0; @@ -636,6 +663,7 @@ input_device_driver_t gx_joypad = { gx_joypad_query_pad, gx_joypad_destroy, gx_joypad_button, + gx_joypad_state, gx_joypad_get_buttons, gx_joypad_axis, gx_joypad_poll, diff --git a/input/drivers_joypad/hid_joypad.c b/input/drivers_joypad/hid_joypad.c index ff383130d5..6c1a68a0cc 100644 --- a/input/drivers_joypad/hid_joypad.c +++ b/input/drivers_joypad/hid_joypad.c @@ -55,6 +55,40 @@ static int16_t hid_joypad_button(unsigned port, uint16_t joykey) return 0; } +static int16_t hid_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (generic_hid && generic_hid->axis) + return generic_hid->axis((void*)hid_driver_get_data(), port, joyaxis); + return 0; +} + +static int16_t hid_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ((uint16_t)joykey != NO_BTN && hid_joypad_button( + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(hid_joypad_axis(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void hid_joypad_get_buttons(unsigned port, input_bits_t *state) { if (generic_hid && generic_hid->get_buttons) @@ -63,13 +97,6 @@ static void hid_joypad_get_buttons(unsigned port, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t hid_joypad_axis(unsigned port, uint32_t joyaxis) -{ - if (generic_hid && generic_hid->axis) - return generic_hid->axis((void*)hid_driver_get_data(), port, joyaxis); - return 0; -} - static void hid_joypad_poll(void) { if (generic_hid && generic_hid->poll) @@ -96,6 +123,7 @@ input_device_driver_t hid_joypad = { hid_joypad_query_pad, hid_joypad_free, hid_joypad_button, + hid_joypad_state, hid_joypad_get_buttons, hid_joypad_axis, hid_joypad_poll, diff --git a/input/drivers_joypad/linuxraw_joypad.c b/input/drivers_joypad/linuxraw_joypad.c index 0d5672ad46..2ccaae6ca5 100644 --- a/input/drivers_joypad/linuxraw_joypad.c +++ b/input/drivers_joypad/linuxraw_joypad.c @@ -303,20 +303,13 @@ static void linuxraw_joypad_destroy(void) static int16_t linuxraw_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) &linuxraw_pads[port]; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (i < NUM_BUTTONS) - if (BIT32_GET(pad->buttons, i)) - ret |= (1 << i); - } - return ret; + if (joykey < NUM_BUTTONS) + return (BIT32_GET(pad->buttons, joykey)); + return 0; } static void linuxraw_joypad_get_buttons(unsigned port, input_bits_t *state) @@ -332,12 +325,11 @@ static void linuxraw_joypad_get_buttons(unsigned port, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis) +static int16_t linuxraw_joypad_axis_state( + const struct linuxraw_joypad *pad, + unsigned port, uint32_t joyaxis) { int16_t val = 0; - const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) - &linuxraw_pads[port]; - if (AXIS_NEG_GET(joyaxis) < NUM_AXES) { val = pad->axes[AXIS_NEG_GET(joyaxis)]; @@ -355,6 +347,46 @@ static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis) return val; } +static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis) +{ + const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) + &linuxraw_pads[port]; + return linuxraw_joypad_axis_state(pad, port, joyaxis); +} + +static int16_t linuxraw_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) + &linuxraw_pads[port]; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ((uint16_t)joykey != NO_BTN && + (joykey < NUM_BUTTONS) && + (BIT32_GET(pad->buttons, joykey))) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(linuxraw_joypad_axis_state(pad, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static bool linuxraw_joypad_query_pad(unsigned pad) { return pad < MAX_USERS && linuxraw_pads[pad].fd >= 0; @@ -365,6 +397,7 @@ input_device_driver_t linuxraw_joypad = { linuxraw_joypad_query_pad, linuxraw_joypad_destroy, linuxraw_joypad_button, + linuxraw_joypad_state, linuxraw_joypad_get_buttons, linuxraw_joypad_axis, linuxraw_joypad_poll, diff --git a/input/drivers_joypad/mfi_joypad.m b/input/drivers_joypad/mfi_joypad.m index 7218c2bd18..c1f933f6dc 100644 --- a/input/drivers_joypad/mfi_joypad.m +++ b/input/drivers_joypad/mfi_joypad.m @@ -331,32 +331,23 @@ bool apple_gamecontroller_joypad_init(void *data) return true; } -static void apple_gamecontroller_joypad_destroy(void) -{ -} +static void apple_gamecontroller_joypad_destroy(void) { } static int16_t apple_gamecontroller_joypad_button( unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - /* Check hat. */ - if (GET_HAT_DIR(i)) - continue; - else if (i < 32) - if ((mfi_buttons[port] & (1 << i)) != 0) - ret |= (1 << i); - } - return ret; + /* Check hat. */ + else if (GET_HAT_DIR(i)) + return 0; + else if (i < 32) + return ((mfi_buttons[port] & (1 << i)) != 0); + return 0; } static void apple_gamecontroller_joypad_get_buttons(unsigned port, - input_bits_t *state) + input_bits_t *state) { BITS_COPY16_PTR(state, mfi_buttons[port]); } @@ -404,6 +395,39 @@ static int16_t apple_gamecontroller_joypad_axis( return val; } +static int16_t apple_gamecontroller_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( (uint16_t)joykey != NO_BTN + && !GET_HAT_DIR(i) + && (i < 32) + && ((mfi_buttons[port] & (1 << i)) != 0) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(apple_gamecontroller_joypad_axis(pad, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static bool apple_gamecontroller_joypad_query_pad(unsigned pad) { return pad < MAX_USERS; @@ -422,6 +446,7 @@ input_device_driver_t mfi_joypad = { apple_gamecontroller_joypad_query_pad, apple_gamecontroller_joypad_destroy, apple_gamecontroller_joypad_button, + apple_gamecontroller_joypad_state, apple_gamecontroller_joypad_get_buttons, apple_gamecontroller_joypad_axis, apple_gamecontroller_joypad_poll, diff --git a/input/drivers_joypad/parport_joypad.c b/input/drivers_joypad/parport_joypad.c index 533b5e0f76..bdd6d53d55 100644 --- a/input/drivers_joypad/parport_joypad.c +++ b/input/drivers_joypad/parport_joypad.c @@ -331,19 +331,46 @@ static void parport_joypad_destroy(void) static int16_t parport_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; const struct parport_joypad *pad = (const struct parport_joypad*) &parport_pads[port]; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) + if (joykey < PARPORT_NUM_BUTTONS) + return (BIT32_GET(pad->buttons, joykey); + return 0; +} + +static int16_t parport_joypad_axis(unsigned port, uint32_t joyaxis) +{ + /* Parport does not support analog sticks */ + return 0; +} + +static int16_t parport_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + const struct parport_joypad *pad = (const struct parport_joypad*) + &parport_pads[port]; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - if (i < PARPORT_NUM_BUTTONS) - if (BIT32_GET(pad->buttons, i)) - ret |= (1 << i); + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + if ( + (uint16_t)joykey != NO_BTN + && (joykey < PARPORT_NUM_BUTTONS) + && (BIT32_GET(pad->buttons, (uint16_t)joykey))) + ret |= ( 1 << i); } + return ret; } @@ -360,12 +387,6 @@ static void parport_joypad_get_buttons(unsigned port, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t parport_joypad_axis(unsigned port, uint32_t joyaxis) -{ - /* Parport does not support analog sticks */ - return 0; -} - static bool parport_joypad_query_pad(unsigned pad) { return pad < MAX_USERS && parport_pads[pad].fd >= 0; @@ -384,6 +405,7 @@ input_device_driver_t parport_joypad = { parport_joypad_query_pad, parport_joypad_destroy, parport_joypad_button, + parport_joypad_state, parport_joypad_get_buttons, parport_joypad_axis, parport_joypad_poll, diff --git a/input/drivers_joypad/ps2_joypad.c b/input/drivers_joypad/ps2_joypad.c index 1b471d678e..8a35b20a8b 100644 --- a/input/drivers_joypad/ps2_joypad.c +++ b/input/drivers_joypad/ps2_joypad.c @@ -84,36 +84,20 @@ static bool ps2_joypad_init(void *data) return init; } -static int16_t ps2_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t ps2_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (port_num >= DEFAULT_MAX_PADS) + if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (pad_state[port_num] & (UINT64_C(1) << i)) - ret |= (1 << i); - } - return ret; + return pad_state[port] & (UINT64_C(1) << i); } -static void ps2_joypad_get_buttons(unsigned port_num, input_bits_t *state) -{ - BIT256_CLEAR_ALL_PTR(state); -} - -static int16_t ps2_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t ps2_joypad_axis_state(unsigned port_num, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - if (port_num >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -149,6 +133,50 @@ static int16_t ps2_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t ps2_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && pad_state[port] & (UINT64_C(1) << joykey) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(ps2_joypad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + +static int16_t ps2_joypad_axis(unsigned port_num, uint32_t joyaxis) +{ + if (port_num >= DEFAULT_MAX_PADS) + return 0; + return ps2_joypad_axis_state(port_num, joyaxis); +} + +static void ps2_joypad_get_buttons(unsigned port_num, input_bits_t *state) +{ + BIT256_CLEAR_ALL_PTR(state); +} + static void ps2_joypad_poll(void) { unsigned player; @@ -220,6 +248,7 @@ input_device_driver_t ps2_joypad = { ps2_joypad_query_pad, ps2_joypad_destroy, ps2_joypad_button, + ps2_joypad_state, ps2_joypad_get_buttons, ps2_joypad_axis, ps2_joypad_poll, diff --git a/input/drivers_joypad/ps3_joypad.c b/input/drivers_joypad/ps3_joypad.c index bf88fac382..87424a0144 100644 --- a/input/drivers_joypad/ps3_joypad.c +++ b/input/drivers_joypad/ps3_joypad.c @@ -61,19 +61,11 @@ static bool ps3_joypad_init(void *data) return true; } -static int16_t ps3_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t ps3_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (port_num >= DEFAULT_MAX_PADS) + if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (pad_state[port_num] & (UINT64_C(1) << i)) - ret |= (1 << i); - } - return ret; + return pad_state[port] & (UINT64_C(1) << joykey); } static void ps3_joypad_get_buttons(unsigned port_num, input_bits_t *state) @@ -86,16 +78,13 @@ static void ps3_joypad_get_buttons(unsigned port_num, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t ps3_joypad_axis_state(unsigned port, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - if (port_num >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -110,16 +99,16 @@ static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) switch (axis) { case 0: - val = analog_state[port_num][0][0]; + val = analog_state[port][0][0]; break; case 1: - val = analog_state[port_num][0][1]; + val = analog_state[port][0][1]; break; case 2: - val = analog_state[port_num][1][0]; + val = analog_state[port][1][0]; break; case 3: - val = analog_state[port_num][1][1]; + val = analog_state[port][1][1]; break; } @@ -131,6 +120,45 @@ static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t ps3_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (port >= DEFAULT_MAX_PADS) + return 0; + return ps3_joypad_axis_state(port, joyaxis); +} + +static int16_t ps3_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && pad_state[port] & (UINT64_C(1) << (uint16_t)joykey) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(ps3_joypad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void ps3_joypad_poll(void) { unsigned port; @@ -259,6 +287,7 @@ input_device_driver_t ps3_joypad = { ps3_joypad_query_pad, ps3_joypad_destroy, ps3_joypad_button, + ps3_joypad_state, ps3_joypad_get_buttons, ps3_joypad_axis, ps3_joypad_poll, diff --git a/input/drivers_joypad/ps4_joypad.c b/input/drivers_joypad/ps4_joypad.c index fe9e3bfbcf..7bec0f6e7b 100644 --- a/input/drivers_joypad/ps4_joypad.c +++ b/input/drivers_joypad/ps4_joypad.c @@ -130,18 +130,42 @@ static bool ps4_joypad_init(void *data) return true; } -static int16_t ps4_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t ps4_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (port_num >= PS4_MAX_ORBISPADS) + if (port >= PS4_MAX_ORBISPADS) return 0; - for (; i < end; i++) + return pad_state[port] & (UINT64_C(1) << joykey); +} + +static int16_t ps4_joypad_axis(unsigned port, uint32_t joyaxis) +{ + /* TODO/FIXME - implement */ + return 0; +} + +static int16_t ps4_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= PS4_MAX_ORBISPADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - if (pad_state[port_num] & (UINT64_C(1) << i)) - ret |= (1 << i); + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + if ( + (uint16_t)joykey != NO_BTN + && pad_state[port] & (UINT64_C(1) << (uint16_t)joykey) + ) + ret |= ( 1 << i); } + return ret; } @@ -155,12 +179,6 @@ static void ps4_joypad_get_buttons(unsigned port_num, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t ps4_joypad_axis(unsigned port_num, uint32_t joyaxis) -{ - /* TODO/FIXME - implement */ - return 0; -} - static void ps4_joypad_poll(void) { unsigned player; @@ -206,20 +224,16 @@ static bool ps4_joypad_query_pad(unsigned pad) } static bool ps4_joypad_rumble(unsigned pad, - enum retro_rumble_effect effect, uint16_t strength) -{ - return false; -} + enum retro_rumble_effect effect, uint16_t strength) { return false; } -static void ps4_joypad_destroy(void) -{ -} +static void ps4_joypad_destroy(void) { } input_device_driver_t ps4_joypad = { ps4_joypad_init, ps4_joypad_query_pad, ps4_joypad_destroy, ps4_joypad_button, + ps4_joypad_state, ps4_joypad_get_buttons, ps4_joypad_axis, ps4_joypad_poll, diff --git a/input/drivers_joypad/psp_joypad.c b/input/drivers_joypad/psp_joypad.c index aa23a87c7d..ea18ac971c 100644 --- a/input/drivers_joypad/psp_joypad.c +++ b/input/drivers_joypad/psp_joypad.c @@ -87,16 +87,11 @@ static bool psp_joypad_init(void *data) #if defined(VITA) if (!sceCtrlIsMultiControllerSupported()) - { psp2_model = SCE_KERNEL_MODEL_VITA; - } else if(sceCtrlIsMultiControllerSupported() > 0) - { + else if(sceCtrlIsMultiControllerSupported() > 0) psp2_model = SCE_KERNEL_MODEL_VITATV; - } if (psp2_model != SCE_KERNEL_MODEL_VITATV) - { players_count = 1; - } if (sceKernelGetModelForCDialog() != SCE_KERNEL_MODEL_VITATV) { sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START); @@ -119,41 +114,30 @@ static bool psp_joypad_init(void *data) return true; } -static int16_t psp_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t psp_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (port_num >= DEFAULT_MAX_PADS) + if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (pad_state[port_num] & (UINT64_C(1) << i)) - ret |= (1 << i); - } - return ret; + return pad_state[port] & (UINT64_C(1) << joykey); } -static void psp_joypad_get_buttons(unsigned port_num, input_bits_t *state) +static void psp_joypad_get_buttons(unsigned port, input_bits_t *state) { - if (port_num < DEFAULT_MAX_PADS) + if (port < DEFAULT_MAX_PADS) { - BITS_COPY16_PTR( state, pad_state[port_num] ); + BITS_COPY16_PTR( state, pad_state[port] ); } else BIT256_CLEAR_ALL_PTR(state); } -static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t psp_joypad_axis_state(unsigned port, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - if (port_num >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -168,16 +152,16 @@ static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis) switch (axis) { case 0: - val = analog_state[port_num][0][0]; + val = analog_state[port][0][0]; break; case 1: - val = analog_state[port_num][0][1]; + val = analog_state[port][0][1]; break; case 2: - val = analog_state[port_num][1][0]; + val = analog_state[port][1][0]; break; case 3: - val = analog_state[port_num][1][1]; + val = analog_state[port][1][1]; break; } @@ -189,6 +173,45 @@ static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t psp_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (port >= DEFAULT_MAX_PADS) + return 0; + return psp_joypad_axis_state(port, joyaxis); +} + +static int16_t dinput_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && (pad_state[port] & (UINT64_C(1) << (uint16_t)joykey)) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(psp_joypad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void psp_joypad_poll(void) { unsigned player; @@ -399,6 +422,7 @@ input_device_driver_t psp_joypad = { psp_joypad_query_pad, psp_joypad_destroy, psp_joypad_button, + psp_joypad_state, psp_joypad_get_buttons, psp_joypad_axis, psp_joypad_poll, diff --git a/input/drivers_joypad/qnx_joypad.c b/input/drivers_joypad/qnx_joypad.c index a304f1caf7..bccd4842ef 100644 --- a/input/drivers_joypad/qnx_joypad.c +++ b/input/drivers_joypad/qnx_joypad.c @@ -29,8 +29,6 @@ static bool qnx_joypad_init(void *data) { unsigned autoconf_pad; - (void)data; - for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++) input_autoconfigure_connect( qnx_joypad_name(autoconf_pad), @@ -44,39 +42,30 @@ static bool qnx_joypad_init(void *data) return true; } -static int16_t qnx_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t qnx_joypad_button(unsigned port, uint16_t joykey) { qnx_input_device_t* controller = NULL; qnx_input_t *qnx = (qnx_input_t*)input_driver_get_data(); - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (!qnx || port_num >= DEFAULT_MAX_PADS) + if (!qnx || port >= DEFAULT_MAX_PADS) return 0; - controller = (qnx_input_device_t*)&qnx->devices[port_num]; + controller = (qnx_input_device_t*)&qnx->devices[port]; - for (; i < end; i++) - { - if (i <= 19) - if ((controller->buttons & (1 << i)) != 0) - ret |= (1 << i); - } - return ret; + if (joykey <= 19) + return ((controller->buttons & (1 << joykey)) != 0); + return 0; } -static int16_t qnx_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t qnx_joypad_axis_state( + qnx_input_t *qnx, + qnx_input_device_t *controller, + unsigned port, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - qnx_input_t *qnx = (qnx_input_t*)input_driver_get_data(); - - if (!qnx || port_num >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -88,9 +77,6 @@ static int16_t qnx_joypad_axis(unsigned port_num, uint32_t joyaxis) is_pos = true; } - qnx_input_device_t* controller = NULL; - controller = (qnx_input_device_t*)&qnx->devices[port_num]; - switch (axis) { case 0: @@ -115,24 +101,66 @@ static int16_t qnx_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } -static void qnx_joypad_poll(void) +static int16_t qnx_joypad_axis(unsigned port, uint32_t joyaxis) { + qnx_input_t *qnx = (qnx_input_t*)input_driver_get_data(); + qnx_input_device_t* controller = NULL; + if (!qnx || port >= DEFAULT_MAX_PADS) + return 0; + controller = (qnx_input_device_t*)&qnx->devices[port]; + return qnx_joypad_axis_state(qnx, controller, port, joyaxis); } +static int16_t qnx_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + qnx_input_t *qnx = (qnx_input_t*)input_driver_get_data(); + qnx_input_device_t* controller = NULL; + if (!qnx || port >= DEFAULT_MAX_PADS) + return 0; + controller = (qnx_input_device_t*)&qnx->devices[port]; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && (joykey <= 19) + && ((controller->buttons & (1 << (uint16_t)joykey)) != 0) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(qnx_joypad_axis_state(qnx, controller, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + +static void qnx_joypad_poll(void) { } + static bool qnx_joypad_query_pad(unsigned pad) { return (pad < MAX_USERS); } -static void qnx_joypad_destroy(void) -{ -} +static void qnx_joypad_destroy(void) { } input_device_driver_t qnx_joypad = { qnx_joypad_init, qnx_joypad_query_pad, qnx_joypad_destroy, qnx_joypad_button, + qnx_joypad_state, NULL, qnx_joypad_axis, qnx_joypad_poll, diff --git a/input/drivers_joypad/rwebpad_joypad.c b/input/drivers_joypad/rwebpad_joypad.c index 4907304f20..4b067a6c0e 100644 --- a/input/drivers_joypad/rwebpad_joypad.c +++ b/input/drivers_joypad/rwebpad_joypad.c @@ -99,26 +99,19 @@ static const char *rwebpad_joypad_name(unsigned pad) return ""; } -static int16_t rwebpad_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t rwebpad_joypad_button(unsigned port, uint16_t joykey) { EmscriptenGamepadEvent gamepad_state; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; EMSCRIPTEN_RESULT r = emscripten_get_gamepad_status( - port_num, &gamepad_state); + port, &gamepad_state); if (port >= DEFAULT_MAX_PADS) return 0; if (r != EMSCRIPTEN_RESULT_SUCCESS) return 0; - for (; i < end; i++) - { - if (i < gamepad_state.numButtons) - if (gamepad_state.digitalButton[i]) - ret |= (1 << i); - } - return ret; + if (joykey < gamepad_state.numButtons) + return gamepad_state.digitalButton[joykey]; + return 0; } static void rwebpad_joypad_get_buttons(unsigned port_num, input_bits_t *state) @@ -141,34 +134,77 @@ static void rwebpad_joypad_get_buttons(unsigned port_num, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t rwebpad_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t rwebpad_joypad_axis_state( + EmscriptenGamepadEvent *gamepad_state, + unsigned port, uint32_t joyaxis) { - EmscriptenGamepadEvent gamepad_state; int16_t val = 0; - EMSCRIPTEN_RESULT r = emscripten_get_gamepad_status(port_num, &gamepad_state); - - if (r == EMSCRIPTEN_RESULT_SUCCESS) + if (AXIS_NEG_GET(joyaxis) < gamepad_state->numAxes) { - if (AXIS_NEG_GET(joyaxis) < gamepad_state.numAxes) - { - val = CLAMPDOUBLE(gamepad_state.axis[AXIS_NEG_GET(joyaxis)]) * 0x7FFF; - if (val > 0) - val = 0; - } - else if (AXIS_POS_GET(joyaxis) < gamepad_state.numAxes) - { - val = CLAMPDOUBLE(gamepad_state.axis[AXIS_POS_GET(joyaxis)]) * 0x7FFF; - if (val < 0) - val = 0; - } + val = CLAMPDOUBLE(gamepad_state->axis[AXIS_NEG_GET(joyaxis)]) * 0x7FFF; + if (val > 0) + val = 0; + } + else if (AXIS_POS_GET(joyaxis) < gamepad_state->numAxes) + { + val = CLAMPDOUBLE(gamepad_state->axis[AXIS_POS_GET(joyaxis)]) * 0x7FFF; + if (val < 0) + val = 0; } return val; } +static int16_t rwebpad_joypad_axis(unsigned port, uint32_t joyaxis) +{ + EmscriptenGamepadEvent gamepad_state; + EMSCRIPTEN_RESULT r = emscripten_get_gamepad_status(port, &gamepad_state); + if (r != EMSCRIPTEN_RESULT_SUCCESS) + return 0; + return rwebpad_joypad_axis_state(&gamepad_state, port, joyaxis); +} + +static int16_t rwebpad_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + EmscriptenGamepadEvent gamepad_state; + int16_t ret = 0; + EMSCRIPTEN_RESULT r = emscripten_get_gamepad_status( + port, &gamepad_state); + if (r != EMSCRIPTEN_RESULT_SUCCESS) + return 0; + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && (joykey < gamepad_state.numButtons) + && gamepad_state.digitalButton[(uint16_t)joykey] + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(rwebpad_joypad_axis_state( + &gamepad_state, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void rwebpad_joypad_poll(void) { - (void)emscripten_sample_gamepad_data(); + emscripten_sample_gamepad_data(); } static bool rwebpad_joypad_query_pad(unsigned pad) @@ -191,6 +227,7 @@ input_device_driver_t rwebpad_joypad = { rwebpad_joypad_query_pad, rwebpad_joypad_destroy, rwebpad_joypad_button, + rwebpad_joypad_state, rwebpad_joypad_get_buttons, rwebpad_joypad_axis, rwebpad_joypad_poll, diff --git a/input/drivers_joypad/sdl_joypad.c b/input/drivers_joypad/sdl_joypad.c index ae826e78a6..739fa325e6 100644 --- a/input/drivers_joypad/sdl_joypad.c +++ b/input/drivers_joypad/sdl_joypad.c @@ -295,76 +295,65 @@ error: #endif } +static int16_t sdl_joypad_button_state( + sdl_joypad_t *pad, + unsigned port, uint16_t joykey) +{ + unsigned hat_dir = GET_HAT_DIR(joykey); + /* Check hat. */ + if (hat_dir) + { + uint8_t dir; + uint16_t hat = GET_HAT(joykey); + + if (hat >= pad->num_hats) + return 0; + + dir = sdl_pad_get_hat(pad, hat); + + switch (hat_dir) + { + case HAT_UP_MASK: + return (dir & SDL_HAT_UP); + case HAT_DOWN_MASK: + return (dir & SDL_HAT_DOWN); + case HAT_LEFT_MASK: + return (dir & SDL_HAT_LEFT); + case HAT_RIGHT_MASK: + return (dir & SDL_HAT_RIGHT); + default: + break; + } + /* hat requested and no hat button down */ + } + else if (joykey < pad->num_buttons) + return sdl_pad_get_button(pad, joykey); + return 0; +} + static int16_t sdl_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; sdl_joypad_t *pad = (sdl_joypad_t*)&sdl_pads[port]; if (!pad || !pad->joypad) return 0; if (port >= DEFAULT_MAX_PADS) return 0; - - for (; i < end; i++) - { - unsigned hat_dir = GET_HAT_DIR(i); - /* Check hat. */ - if (hat_dir) - { - uint8_t dir; - uint16_t hat = GET_HAT(i); - - if (hat >= pad->num_hats) - continue; - - dir = sdl_pad_get_hat(pad, hat); - - switch (hat_dir) - { - case HAT_UP_MASK: - if (dir & SDL_HAT_UP) - ret |= (1 << i); - break; - case HAT_DOWN_MASK: - if (dir & SDL_HAT_DOWN) - ret |= (1 << i); - break; - case HAT_LEFT_MASK: - if (dir & SDL_HAT_LEFT) - ret |= (1 << i); - break; - case HAT_RIGHT_MASK: - if (dir & SDL_HAT_RIGHT) - ret |= (1 << i); - break; - default: - break; - } - /* hat requested and no hat button down */ - } - else if (i < pad->num_buttons) - if (sdl_pad_get_button(pad, i)) - ret |= (1 << i); - } - - return ret; + return sdl_joypad_button_state(pad, port, joykey); } -static int16_t sdl_joypad_axis(unsigned port, uint32_t joyaxis) +static int16_t sdl_joypad_axis_state( + sdl_joypad_t *pad, + unsigned port, uint32_t joyaxis) { int16_t val = 0; - sdl_joypad_t *pad = (sdl_joypad_t*)&sdl_pads[port]; - if (!pad->joypad) - return false; - if (AXIS_NEG_GET(joyaxis) < pad->num_axes) { val = sdl_pad_get_axis(pad, AXIS_NEG_GET(joyaxis)); if (val > 0) val = 0; - else if (val < -0x7fff) /* -0x8000 can cause trouble if we later abs() it. */ + /* -0x8000 can cause trouble if we later abs() it. */ + else if (val < -0x7fff) val = -0x7fff; } else if (AXIS_POS_GET(joyaxis) < pad->num_axes) @@ -378,6 +367,49 @@ static int16_t sdl_joypad_axis(unsigned port, uint32_t joyaxis) return val; } +static int16_t sdl_joypad_axis(unsigned port, uint32_t joyaxis) +{ + sdl_joypad_t *pad = (sdl_joypad_t*)&sdl_pads[port]; + if (!pad || !pad->joypad) + return false; + return sdl_joypad_axis_state(pad, port, joyaxis); +} + +static int16_t sdl_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + sdl_joypad_t *pad = (sdl_joypad_t*)&sdl_pads[port]; + + if (!pad || !pad->joypad) + return 0; + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && sdl_joypad_button_state(pad, port, (uint16_t)joykey) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(sdl_joypad_axis_state(pad, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void sdl_joypad_poll(void) { #ifdef HAVE_SDL2 @@ -470,6 +502,7 @@ input_device_driver_t sdl_joypad = { sdl_joypad_query_pad, sdl_joypad_destroy, sdl_joypad_button, + sdl_joypad_state, NULL, sdl_joypad_axis, sdl_joypad_poll, diff --git a/input/drivers_joypad/switch_joypad.c b/input/drivers_joypad/switch_joypad.c index 6e98af6bb2..5511b19877 100644 --- a/input/drivers_joypad/switch_joypad.c +++ b/input/drivers_joypad/switch_joypad.c @@ -16,12 +16,14 @@ #include "../../retroarch.h" #include "../../command.h" +/* TODO/FIXME - weird header include */ #include "string.h" -static uint16_t pad_state[DEFAULT_MAX_PADS]; -static int16_t analog_state[DEFAULT_MAX_PADS][2][2]; extern uint64_t lifecycle_state; +/* TODO/FIXME - static globals */ +static uint16_t pad_state[DEFAULT_MAX_PADS]; +static int16_t analog_state[DEFAULT_MAX_PADS][2][2]; #ifdef HAVE_LIBNX static u32 vibration_handles[DEFAULT_MAX_PADS][2]; static u32 vibration_handleheld[2]; @@ -85,17 +87,9 @@ static bool switch_joypad_init(void *data) static int16_t switch_joypad_button(unsigned port_num, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; if (port_num >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (pad_state[port_num] & (1 << i)) - ret |= (1 << i); - } - return ret; + return (pad_state[port_num] & (1 << joykey)); } static void switch_joypad_get_buttons(unsigned port_num, input_bits_t *state) @@ -110,18 +104,13 @@ static void switch_joypad_get_buttons(unsigned port_num, input_bits_t *state) } } -static int16_t switch_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t switch_joypad_axis_state(unsigned port, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; -#if 0 - /* TODO/FIXME - implement */ - if (port_num >= DEFAULT_MAX_PADS) { } -#endif - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -136,16 +125,16 @@ static int16_t switch_joypad_axis(unsigned port_num, uint32_t joyaxis) switch(axis) { case 0: - val = analog_state[port_num][0][0]; + val = analog_state[port][0][0]; break; case 1: - val = analog_state[port_num][0][1]; + val = analog_state[port][0][1]; break; case 2: - val = analog_state[port_num][1][0]; + val = analog_state[port][1][0]; break; case 3: - val = analog_state[port_num][1][1]; + val = analog_state[port][1][1]; break; } @@ -157,6 +146,45 @@ static int16_t switch_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t switch_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (port >= DEFAULT_MAX_PADS) + return 0; + return switch_joypad_axis_state(port, joyaxis); +} + +static int16_t switch_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && (pad_state[port] & (1 << (uint16_t)joykey)) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(switch_joypad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static bool switch_joypad_query_pad(unsigned pad) { return pad < DEFAULT_MAX_PADS && pad_state[pad]; @@ -397,6 +425,7 @@ input_device_driver_t switch_joypad = { switch_joypad_query_pad, switch_joypad_destroy, switch_joypad_button, + switch_joypad_state, switch_joypad_get_buttons, switch_joypad_axis, switch_joypad_poll, diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index c898db85c7..30023a270c 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -590,53 +590,45 @@ error: return false; } +static int16_t udev_joypad_button_state( + const struct udev_joypad *pad, + unsigned port, uint16_t joykey) +{ + unsigned hat_dir = GET_HAT_DIR(joykey); + + if (hat_dir) + { + unsigned h = GET_HAT(joykey); + if (h < NUM_HATS) + { + switch (hat_dir) + { + case HAT_LEFT_MASK: + return (pad->hats[h][0] < 0); + case HAT_RIGHT_MASK: + return (pad->hats[h][0] > 0); + case HAT_UP_MASK: + return (pad->hats[h][1] < 0); + case HAT_DOWN_MASK: + return (pad->hats[h][1] > 0); + default: + break; + } + } + /* hat requested and no hat button down */ + } + else if (joykey < UDEV_NUM_BUTTONS) + return (BIT64_GET(pad->buttons, joykey)); + return 0; +} + static int16_t udev_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; const struct udev_joypad *pad = (const struct udev_joypad*) &udev_pads[port]; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - unsigned hat_dir = GET_HAT_DIR(i); - - if (hat_dir) - { - unsigned h = GET_HAT(i); - if (h < NUM_HATS) - { - switch (hat_dir) - { - case HAT_LEFT_MASK: - if (pad->hats[h][0] < 0) - ret |= (1 << i); - break; - case HAT_RIGHT_MASK: - if (pad->hats[h][0] > 0) - ret |= (1 << i); - break; - case HAT_UP_MASK: - if (pad->hats[h][1] < 0) - ret |= (1 << i); - break; - case HAT_DOWN_MASK: - if (pad->hats[h][1] > 0) - ret |= (1 << i); - break; - default: - break; - } - } - /* hat requested and no hat button down */ - } - else if (i < UDEV_NUM_BUTTONS) - if (BIT64_GET(pad->buttons, i)) - ret |= (1 << i); - } - return ret; + return udev_joypad_button_state(pad, port, joykey); } static void udev_joypad_get_buttons(unsigned port, input_bits_t *state) @@ -652,17 +644,18 @@ static void udev_joypad_get_buttons(unsigned port, input_bits_t *state) BIT256_CLEAR_ALL_PTR(state); } -static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) +static int16_t udev_joypad_axis( + const struct udev_joypad *pad, + unsigned port, uint32_t joyaxis) { int16_t val = 0; - const struct udev_joypad *pad = (const struct udev_joypad*) - &udev_pads[port]; - if (AXIS_NEG_GET(joyaxis) < NUM_AXES) { val = pad->axes[AXIS_NEG_GET(joyaxis)]; /* Deal with analog triggers that report -32767 to 32767 */ - if (((AXIS_NEG_GET(joyaxis) == ABS_Z) || (AXIS_NEG_GET(joyaxis) == ABS_RZ)) + if (( + (AXIS_NEG_GET(joyaxis) == ABS_Z) || + (AXIS_NEG_GET(joyaxis) == ABS_RZ)) && (pad->neg_trigger[AXIS_NEG_GET(joyaxis)])) val = (val + 0x7fff) / 2; if (val > 0) @@ -672,7 +665,9 @@ static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) { val = pad->axes[AXIS_POS_GET(joyaxis)]; /* Deal with analog triggers that report -32767 to 32767 */ - if (((AXIS_POS_GET(joyaxis) == ABS_Z) || (AXIS_POS_GET(joyaxis) == ABS_RZ)) + if (( + (AXIS_POS_GET(joyaxis) == ABS_Z) || + (AXIS_POS_GET(joyaxis) == ABS_RZ)) && (pad->neg_trigger[AXIS_POS_GET(joyaxis)])) val = (val + 0x7fff) / 2; if (val < 0) @@ -682,6 +677,47 @@ static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) return val; } +static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) +{ + const struct udev_joypad *pad = (const struct udev_joypad*) + &udev_pads[port]; + return udev_joypad_axis_state(pad, port, joyaxis); +} + +static int16_t udev_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + const struct udev_joypad *pad = (const struct udev_joypad*) + &udev_pads[port]; + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && udev_joypad_button_state(pad, port, (uint16_t)joykey) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(udev_joypad_axis_state(pad, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static bool udev_joypad_query_pad(unsigned pad) { return pad < MAX_USERS && udev_pads[pad].fd >= 0; @@ -700,6 +736,7 @@ input_device_driver_t udev_joypad = { udev_joypad_query_pad, udev_joypad_destroy, udev_joypad_button, + udev_joypad_state, udev_joypad_get_buttons, udev_joypad_axis, udev_joypad_poll, diff --git a/input/drivers_joypad/wiiu/hidpad_driver.c b/input/drivers_joypad/wiiu/hidpad_driver.c index e48611ebbb..1f7790857e 100644 --- a/input/drivers_joypad/wiiu/hidpad_driver.c +++ b/input/drivers_joypad/wiiu/hidpad_driver.c @@ -46,9 +46,9 @@ static bool hidpad_init(void *data) return true; } -static bool hidpad_query_pad(unsigned pad) +static bool hidpad_query_pad(unsigned port) { - return hidpad_ready && pad < MAX_USERS; + return hidpad_ready && port < MAX_USERS; } static void hidpad_destroy(void) @@ -58,43 +58,66 @@ static void hidpad_destroy(void) hid_deinit(&hid_instance); } -static int16_t hidpad_button(unsigned pad, uint16_t joykey) +static int16_t hidpad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (!hidpad_query_pad(pad)) + if (!hidpad_query_pad(port)) return 0; - for (; i < end; i++) + return (HID_BUTTON(port, joykey)); +} + +static void hidpad_get_buttons(unsigned port, input_bits_t *state) +{ + if (!hidpad_query_pad(port)) + BIT256_CLEAR_ALL_PTR(state); + + HID_GET_BUTTONS(port, state); +} + +static int16_t hidpad_axis(unsigned port, uint32_t axis) +{ + if (!hidpad_query_pad(port)) + return 0; + return HID_AXIS(port, axis); +} + +static int16_t hidpad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (!hidpad_query_pad(port)) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { - if (HID_BUTTON(pad, i)) + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && HID_BUTTON(port, (uint16_t)joykey) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(HID_AXIS(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) ret |= (1 << i); } + return ret; } -static void hidpad_get_buttons(unsigned pad, input_bits_t *state) +static const char *hidpad_name(unsigned port) { - if (!hidpad_query_pad(pad)) - BIT256_CLEAR_ALL_PTR(state); - - HID_GET_BUTTONS(pad, state); -} - -static int16_t hidpad_axis(unsigned pad, uint32_t axis) -{ - if (!hidpad_query_pad(pad)) - return 0; - - return HID_AXIS(pad, axis); -} - -static const char *hidpad_name(unsigned pad) -{ - if (!hidpad_query_pad(pad)) + if (!hidpad_query_pad(port)) return "N/A"; - return HID_PAD_NAME(pad); + return HID_PAD_NAME(port); } input_device_driver_t hidpad_driver = @@ -103,6 +126,7 @@ input_device_driver_t hidpad_driver = hidpad_query_pad, hidpad_destroy, hidpad_button, + hidpad_state, hidpad_get_buttons, hidpad_axis, hidpad_poll, diff --git a/input/drivers_joypad/wiiu/kpad_driver.c b/input/drivers_joypad/wiiu/kpad_driver.c index f616fa9fa0..52ffc3d036 100644 --- a/input/drivers_joypad/wiiu/kpad_driver.c +++ b/input/drivers_joypad/wiiu/kpad_driver.c @@ -22,6 +22,9 @@ #include "../../include/wiiu/input.h" +#define WIIU_PRO_BUTTON_MASK 0x3FC0000; +#define CLASSIC_BUTTON_MASK 0xFF0000; + /* Forward declarations */ static void kpad_poll(void); static void kpad_deregister(unsigned channel); @@ -38,7 +41,7 @@ struct _wiimote_state /* it would be nice to use designated initializers here, * but those are only in C99 and newer. Oh well. */ -wiimote_state wiimotes[WIIU_WIIMOTE_CHANNELS] = { +wiimote_state wiimotes[WIIU_WIIMOTE_CHANNELS] = { { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE }, { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE }, { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE }, @@ -46,15 +49,16 @@ wiimote_state wiimotes[WIIU_WIIMOTE_CHANNELS] = { }; /* static global variables */ -static bool kpad_ready = false; -static int channel_slot_map[] = { -1, -1, -1, -1 }; +static bool kpad_ready = false; +static int channel_slot_map[] = { -1, -1, -1, -1 }; +static int poll_failures[WIIU_WIIMOTE_CHANNELS] = { 0, 0, 0, 0 }; static int to_wiimote_channel(unsigned pad) { unsigned i; for(i = 0; i < WIIU_WIIMOTE_CHANNELS; i++) - if(channel_slot_map[i] == pad) + if (channel_slot_map[i] == pad) return i; return -1; @@ -63,7 +67,7 @@ static int to_wiimote_channel(unsigned pad) static int get_slot_for_channel(unsigned channel) { int slot = pad_connection_find_vacant_pad(hid_instance.pad_list); - if(slot >= 0) + if (slot >= 0) { channel_slot_map[channel] = slot; hid_instance.pad_list[slot].connected = true; @@ -92,43 +96,35 @@ static void kpad_destroy(void) kpad_ready = false; } -static int16_t kpad_button(unsigned pad, uint16_t joykey) +static int16_t kpad_button(unsigned port, uint16_t joykey) { int channel; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (!kpad_query_pad(pad)) + if (!kpad_query_pad(port)) return 0; - channel = to_wiimote_channel(pad); - if(channel < 0) + channel = to_wiimote_channel(port); + if (channel < 0) return 0; - for (; i < end; i++) - { - if (wiimotes[channel].button_state - & (UINT64_C(1) << i)) - ret |= (1 << i); - } - return ret; + return (wiimotes[channel].button_state + & (UINT64_C(1) << joykey)); } -static void kpad_get_buttons(unsigned pad, input_bits_t *state) +static void kpad_get_buttons(unsigned port, input_bits_t *state) { - int channel = to_wiimote_channel(pad); + int channel = to_wiimote_channel(port); - if (!kpad_query_pad(pad) || channel < 0) + if (!kpad_query_pad(port) || channel < 0) BIT256_CLEAR_ALL_PTR(state); else BITS_COPY16_PTR(state, wiimotes[channel].button_state); } -static int16_t kpad_axis(unsigned pad, uint32_t axis) +static int16_t kpad_axis(unsigned port, uint32_t axis) { axis_data data; - int channel = to_wiimote_channel(pad); + int channel = to_wiimote_channel(port); - if (!kpad_query_pad(pad) || channel < 0) + if (!kpad_query_pad(port) || channel < 0) return 0; pad_functions.read_axis_data(axis, &data); @@ -137,6 +133,35 @@ static int16_t kpad_axis(unsigned pad, uint32_t axis) data.is_negative); } +static int16_t kpad_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && kpad_button( + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(kpad_axis(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void kpad_register(unsigned channel, uint8_t device_type) { if (wiimotes[channel].type != device_type) @@ -146,7 +171,7 @@ static void kpad_register(unsigned channel, uint8_t device_type) kpad_deregister(channel); slot = get_slot_for_channel(channel); - if(slot < 0) + if (slot < 0) { RARCH_ERR("Couldn't get a slot for this remote.\n"); return; @@ -157,9 +182,6 @@ static void kpad_register(unsigned channel, uint8_t device_type) } } -#define WIIU_PRO_BUTTON_MASK 0x3FC0000; -#define CLASSIC_BUTTON_MASK 0xFF0000; - static void kpad_poll_one_channel(unsigned channel, KPADData *kpad) { kpad_register(channel, kpad->device_type); @@ -201,7 +223,7 @@ static void kpad_deregister(unsigned channel) { int slot = channel_slot_map[channel]; - if(slot >= 0) + if (slot >= 0) { input_autoconfigure_disconnect(slot, kpad_driver.name(slot)); wiimotes[channel].type = WIIMOTE_TYPE_NONE; @@ -210,8 +232,6 @@ static void kpad_deregister(unsigned channel) } } -static int poll_failures[WIIU_WIIMOTE_CHANNELS] = { 0, 0, 0, 0 }; - static void kpad_poll(void) { unsigned channel; @@ -229,7 +249,7 @@ static void kpad_poll(void) if (result == 0) { poll_failures[channel]++; - if(poll_failures[channel] > 5) + if (poll_failures[channel] > 5) kpad_deregister(channel); continue; } @@ -272,6 +292,7 @@ input_device_driver_t kpad_driver = kpad_query_pad, kpad_destroy, kpad_button, + kpad_state, kpad_get_buttons, kpad_axis, kpad_poll, diff --git a/input/drivers_joypad/wiiu/wpad_driver.c b/input/drivers_joypad/wiiu/wpad_driver.c index 84767d01a1..c6e418dec9 100644 --- a/input/drivers_joypad/wiiu/wpad_driver.c +++ b/input/drivers_joypad/wiiu/wpad_driver.c @@ -268,49 +268,35 @@ static bool wpad_init(void *data) return true; } -static bool wpad_query_pad(unsigned pad) +static bool wpad_query_pad(unsigned port) { - return pad < MAX_USERS && (to_gamepad_channel(pad) != WPAD_INVALID_CHANNEL); + return port < MAX_USERS && (to_gamepad_channel(port) != WPAD_INVALID_CHANNEL); } -static void wpad_destroy(void) -{ +static void wpad_destroy(void) { } -} - -static int16_t wpad_button(unsigned pad, uint16_t joykey) +static int16_t wpad_button(unsigned port, uint16_t joykey) { VPADChan channel; - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - - if (!wpad_query_pad(pad)) + if (!wpad_query_pad(port)) return 0; - - channel = to_gamepad_channel(pad); + channel = to_gamepad_channel(port); if (channel < 0) return 0; - - for (; i < end; i++) - { - if (gamepads[channel].button_state & (UINT64_C(1) << i)) - ret |= (1 << i); - } - return ret; + return (gamepads[channel].button_state & (UINT64_C(1) << joykey)); } -static void wpad_get_buttons(unsigned pad, input_bits_t *state) +static void wpad_get_buttons(unsigned port, input_bits_t *state) { VPADChan channel; - if (!wpad_query_pad(pad)) + if (!wpad_query_pad(port)) { BIT256_CLEAR_ALL_PTR(state); return; } - channel = to_gamepad_channel(pad); + channel = to_gamepad_channel(port); if (channel < 0) { BIT256_CLEAR_ALL_PTR(state); @@ -320,15 +306,15 @@ static void wpad_get_buttons(unsigned pad, input_bits_t *state) BITS_COPY32_PTR(state, gamepads[channel].button_state); } -static int16_t wpad_axis(unsigned pad, uint32_t axis) +static int16_t wpad_axis(unsigned port, uint32_t axis) { axis_data data; VPADChan channel; - if (!wpad_query_pad(pad)) + if (!wpad_query_pad(port)) return 0; - channel = to_gamepad_channel(pad); + channel = to_gamepad_channel(port); if (channel < 0) return 0; @@ -336,7 +322,36 @@ static int16_t wpad_axis(unsigned pad, uint32_t axis) return pad_functions.get_axis_value(data.axis, gamepads[channel].analog_state, data.is_negative); } -static const char *wpad_name(unsigned pad) +static int16_t wpad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && wpad_button( + port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(wpad_axis_state(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + +static const char *wpad_name(unsigned port) { return PAD_NAME_WIIU_GAMEPAD; } @@ -347,6 +362,7 @@ input_device_driver_t wpad_driver = wpad_query_pad, wpad_destroy, wpad_button, + wpad_state, wpad_get_buttons, wpad_axis, wpad_poll, diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 243d7edb31..e5eada6620 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -18,9 +18,10 @@ #include "wiiu_dbg.h" -static input_device_driver_t *pad_drivers[MAX_USERS]; extern pad_connection_listener_t wiiu_pad_connection_listener; +/* TODO/FIXME - static globals */ +static input_device_driver_t *pad_drivers[MAX_USERS]; static bool ready = false; static bool wiiu_joypad_init(void* data) @@ -60,37 +61,61 @@ static void wiiu_joypad_destroy(void) #endif } -static int16_t wiiu_joypad_button(unsigned pad, uint16_t joykey) +static int16_t wiiu_joypad_button(unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; - if (!wiiu_joypad_query_pad(pad)) + if (!wiiu_joypad_query_pad(port)) return 0; if (port >= DEFAULT_MAX_PADS) return 0; - for (; i < end; i++) - { - if (pad_drivers[pad]->button(pad, i)) - ret |= (1 << i); - } - return ret; + return (pad_drivers[port]->button(port, joykey)); } -static void wiiu_joypad_get_buttons(unsigned pad, input_bits_t *state) +static void wiiu_joypad_get_buttons(unsigned port, input_bits_t *state) { - if (!wiiu_joypad_query_pad(pad)) + if (!wiiu_joypad_query_pad(port)) return; - - pad_drivers[pad]->get_buttons(pad, state); + pad_drivers[port]->get_buttons(port, state); } -static int16_t wiiu_joypad_axis(unsigned pad, uint32_t joyaxis) +static int16_t wiiu_joypad_axis(unsigned port, uint32_t joyaxis) { - if (!wiiu_joypad_query_pad(pad)) + if (!wiiu_joypad_query_pad(port)) + return 0; + return pad_drivers[port]->axis(port, joyaxis); +} + +static int16_t wiiu_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + + if (!wiiu_joypad_query_pad(port)) + return 0; + if (port >= DEFAULT_MAX_PADS) return 0; - return pad_drivers[pad]->axis(pad, joyaxis); + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && (pad_drivers[port]->button(port, (uint16_t)joykey)) + ) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(pad_drivers[port]->axis(port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; } static void wiiu_joypad_poll(void) @@ -123,6 +148,7 @@ input_device_driver_t wiiu_joypad = wiiu_joypad_query_pad, wiiu_joypad_destroy, wiiu_joypad_button, + wiiu_joypad_state, wiiu_joypad_get_buttons, wiiu_joypad_axis, wiiu_joypad_poll, diff --git a/input/drivers_joypad/xdk_joypad.c b/input/drivers_joypad/xdk_joypad.c index 92c4e92304..ee3b468174 100644 --- a/input/drivers_joypad/xdk_joypad.c +++ b/input/drivers_joypad/xdk_joypad.c @@ -90,122 +90,84 @@ static const uint16_t button_index_to_bitmap_code[] = { }; #endif -static int16_t xdk_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t xdk_joypad_button_state(XINPUT_GAMEPAD *pad, + unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t i = joykey; - uint16_t end = joykey + 1; + uint16_t btn_word = pad->wButtons; + unsigned hat_dir = GET_HAT_DIR(joykey); - if (port_num >= DEFAULT_MAX_PADS) - return 0; - - for (; i < end; i++) + if (hat_dir) { - uint16_t btn_word = g_xinput_states[port_num].xstate.Gamepad.wButtons; - unsigned hat_dir = GET_HAT_DIR(i); - - if (hat_dir) + switch (hat_dir) { - switch (hat_dir) - { - case HAT_UP_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_UP) - ret |= (1 << i); - break; - case HAT_DOWN_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_DOWN) - ret |= (1 << i); - break; - case HAT_LEFT_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_LEFT) - ret |= (1 << i); - break; - case HAT_RIGHT_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_RIGHT) - ret |= (1 << i); - break; - default: - break; - } - /* hat requested and no hat button down */ - } - else - { -#ifdef _XBOX1 - switch (i) - { - case RETRO_DEVICE_ID_JOYPAD_A: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_B] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_B: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_A] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_Y: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_X] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_X: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_Y] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_START: - return (g_xinput_states[port_num].xstate.Gamepad.wButtons & XINPUT_GAMEPAD_START); - break; - case RETRO_DEVICE_ID_JOYPAD_SELECT: - if (g_xinput_states[port_num].xstate.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_L3: - if (g_xinput_states[port_num].xstate.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_R3: - if (g_xinput_states[port_num].xstate.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_L2: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_WHITE] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_R2: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_BLACK] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_L: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - case RETRO_DEVICE_ID_JOYPAD_R: - if (g_xinput_states[port_num].xstate.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] > XINPUT_GAMEPAD_MAX_CROSSTALK) - ret |= (1 << i); - break; - default: - break; - } -#else - if (i < 10) - if (btn_word & button_index_to_bitmap_code[i]) - ret |= (1 << i); -#endif + case HAT_UP_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_UP); + case HAT_DOWN_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_DOWN); + case HAT_LEFT_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_LEFT); + case HAT_RIGHT_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_RIGHT); + default: + break; } + /* hat requested and no hat button down */ } - - return ret; + else + { +#ifdef _XBOX1 + switch (joykey) + { + case RETRO_DEVICE_ID_JOYPAD_A: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_B] > XINPUT_GAMEPAD_MAX_CROSSTALK); + case RETRO_DEVICE_ID_JOYPAD_B: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_A] > XINPUT_GAMEPAD_MAX_CROSSTALK); + case RETRO_DEVICE_ID_JOYPAD_Y: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_X] > XINPUT_GAMEPAD_MAX_CROSSTALK); + case RETRO_DEVICE_ID_JOYPAD_X: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_Y] > XINPUT_GAMEPAD_MAX_CROSSTALK) + case RETRO_DEVICE_ID_JOYPAD_START: + return (pad->wButtons & XINPUT_GAMEPAD_START); + case RETRO_DEVICE_ID_JOYPAD_SELECT: + return (pad->wButtons & XINPUT_GAMEPAD_BACK); + case RETRO_DEVICE_ID_JOYPAD_L3: + return (pad->wButtons & XINPUT_GAMEPAD_LEFT_THUMB); + case RETRO_DEVICE_ID_JOYPAD_R3: + return (pad->wButtons & XINPUT_GAMEPAD_RIGHT_THUMB); + case RETRO_DEVICE_ID_JOYPAD_L2: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_WHITE] > XINPUT_GAMEPAD_MAX_CROSSTALK); + case RETRO_DEVICE_ID_JOYPAD_R2: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_BLACK] > XINPUT_GAMEPAD_MAX_CROSSTALK); + case RETRO_DEVICE_ID_JOYPAD_L: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] > XINPUT_GAMEPAD_MAX_CROSSTALK); + case RETRO_DEVICE_ID_JOYPAD_R: + return (pad->bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] > XINPUT_GAMEPAD_MAX_CROSSTALK); + default: + break; + } +#else + if (joykey < 10) + return (btn_word & button_index_to_bitmap_code[joykey]); +#endif + } + return 0; } -static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t xdk_joypad_button(unsigned port, uint16_t joykey) +{ + XINPUT_GAMEPAD *pad = &(g_xinput_states[port].xstate.Gamepad); + if (port >= DEFAULT_MAX_PADS) + return 0; + return xdk_joypad_button_state(pad, port, joykey); +} + +static int16_t xdk_joypad_axis_state(XINPUT_GAMEPAD *pad, + unsigned port, uint32_t joyaxis) { int val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - XINPUT_GAMEPAD *pad = NULL; - - if (port_num >= DEFAULT_MAX_PADS) - return 0; - if (AXIS_NEG_GET(joyaxis) <= 3) { axis = AXIS_NEG_GET(joyaxis); @@ -217,7 +179,6 @@ static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) is_pos = true; } - pad = &(g_xinput_states[port_num].xstate.Gamepad); switch (axis) { @@ -257,6 +218,47 @@ static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) return val; } +static int16_t xdk_joypad_axis(unsigned port, uint32_t joyaxis) +{ + XINPUT_GAMEPAD *pad = &(g_xinput_states[port].xstate.Gamepad); + if (port >= DEFAULT_MAX_PADS) + return 0; + return xdk_joypad_axis_state(pad, port, joyaxis); +} + +static int16_t xdk_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + XINPUT_GAMEPAD *pad = &(g_xinput_states[port].xstate.Gamepad); + + if (port >= DEFAULT_MAX_PADS) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && xdk_joypad_button_state( + pad, port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(xdk_joypad_axis_state(pad, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void xdk_joypad_poll(void) { unsigned port; @@ -364,6 +366,7 @@ input_device_driver_t xdk_joypad = { xdk_joypad_query_pad, xdk_joypad_destroy, xdk_joypad_button, + xdk_joypad_state, NULL, xdk_joypad_axis, xdk_joypad_poll, diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index fea7b629c3..9cf7ca1f3e 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -422,78 +422,54 @@ static const uint16_t button_index_to_bitmap_code[] = { XINPUT_GAMEPAD_GUIDE }; -static int16_t xinput_joypad_button(unsigned port_num, uint16_t joykey) +static int16_t xinput_joypad_button_state( + unsigned xuser, unsigned port, uint16_t joykey) { - int16_t ret = 0; - uint16_t btn_word = 0; - unsigned hat_dir = 0; - int xuser = pad_index_to_xuser_index(port_num); - uint16_t i = joykey; - uint16_t end = joykey + 1; + uint16_t btn_word = g_xinput_states[xuser].xstate.Gamepad.wButtons; + unsigned hat_dir = GET_HAT_DIR(joykey); -#ifdef HAVE_DINPUT - if (xuser == -1) - return dinput_joypad.button(port_num, joykey); -#endif - - if (!(g_xinput_states[xuser].connected)) - return 0; - - for (; i < end; i++) + if (hat_dir) { - btn_word = g_xinput_states[xuser].xstate.Gamepad.wButtons; - hat_dir = GET_HAT_DIR(i); - - if (hat_dir) + switch (hat_dir) { - switch (hat_dir) - { - case HAT_UP_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_UP) - ret |= (1 << i); - break; - case HAT_DOWN_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_DOWN) - ret |= (1 << i); - break; - case HAT_LEFT_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_LEFT) - ret |= (1 << i); - break; - case HAT_RIGHT_MASK: - if (btn_word & XINPUT_GAMEPAD_DPAD_RIGHT) - ret |= (1 << i); - break; - default: - break; - } - /* hat requested and no hat button down */ + case HAT_UP_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_UP); + case HAT_DOWN_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_DOWN); + case HAT_LEFT_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_LEFT); + case HAT_RIGHT_MASK: + return (btn_word & XINPUT_GAMEPAD_DPAD_RIGHT); + default: + break; } - else if (i < g_xinput_num_buttons) - if (btn_word & button_index_to_bitmap_code[i]) - ret |= (1 << i); + /* hat requested and no hat button down */ } - - return ret; + else if (joykey < g_xinput_num_buttons) + return (btn_word & button_index_to_bitmap_code[joykey]); + return 0; } -static int16_t xinput_joypad_axis (unsigned port_num, uint32_t joyaxis) +static int16_t xinput_joypad_button(unsigned port, uint16_t joykey) +{ + int xuser = pad_index_to_xuser_index(port); +#ifdef HAVE_DINPUT + if (xuser == -1) + return dinput_joypad.button(port, joykey); +#endif + if (!(g_xinput_states[xuser].connected)) + return 0; + return xinput_joypad_button_state(xuser, port, joykey); +} + +static int16_t xinput_joypad_axis_state( + XINPUT_GAMEPAD *pad, + unsigned port, uint32_t joyaxis) { int16_t val = 0; int axis = -1; bool is_neg = false; bool is_pos = false; - XINPUT_GAMEPAD* pad = NULL; - int xuser = pad_index_to_xuser_index(port_num); - -#ifdef HAVE_DINPUT - if (xuser == -1) - return dinput_joypad.axis(port_num, joyaxis); -#endif - - if (!(g_xinput_states[xuser].connected)) - return 0; - /* triggers (axes 4,5) cannot be negative */ if (AXIS_NEG_GET(joyaxis) <= 3) { @@ -506,8 +482,6 @@ static int16_t xinput_joypad_axis (unsigned port_num, uint32_t joyaxis) is_pos = true; } - pad = &(g_xinput_states[xuser].xstate.Gamepad); - switch (axis) { case 0: @@ -542,6 +516,56 @@ static int16_t xinput_joypad_axis (unsigned port_num, uint32_t joyaxis) return val; } +static int16_t xinput_joypad_axis(unsigned port, uint32_t joyaxis) +{ + int xuser = pad_index_to_xuser_index(port); + XINPUT_GAMEPAD *pad = &(g_xinput_states[xuser].xstate.Gamepad); +#ifdef HAVE_DINPUT + if (xuser == -1) + return dinput_joypad.axis(port, joyaxis); +#endif + if (!(g_xinput_states[xuser].connected)) + return 0; + return xinput_joypad_axis_state(pad, port, joyaxis); +} + +static int16_t xinput_joypad_state_func( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + unsigned i; + int16_t ret = 0; + int xuser = pad_index_to_xuser_index(port); + XINPUT_GAMEPAD *pad = &(g_xinput_states[xuser].xstate.Gamepad); +#ifdef HAVE_DINPUT + if (xuser == -1) + return dinput_joypad.state(joypad_info, binds, port); +#endif + if (!(g_xinput_states[xuser].connected)) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + if ( + (uint16_t)joykey != NO_BTN + && xinput_joypad_button_state( + xuser, port, (uint16_t)joykey)) + ret |= ( 1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(xinput_joypad_axis_state(pad, port, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + static void xinput_joypad_poll(void) { unsigned i; @@ -620,6 +644,7 @@ input_device_driver_t xinput_joypad = { xinput_joypad_query_pad, xinput_joypad_destroy, xinput_joypad_button, + xinput_joypad_state_func, NULL, xinput_joypad_axis, xinput_joypad_poll, diff --git a/input/input_driver.h b/input/input_driver.h index ee02e02d0f..45af484140 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -206,6 +206,8 @@ struct rarch_joypad_driver bool (*query_pad)(unsigned); void (*destroy)(void); int16_t (*button)(unsigned, uint16_t); + int16_t (*state)(rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, unsigned port); void (*get_buttons)(unsigned, input_bits_t *); int16_t (*axis)(unsigned, uint32_t); void (*poll)(void); diff --git a/retroarch.c b/retroarch.c index 9350f38150..7def7b3ad7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -785,6 +785,7 @@ static input_device_driver_t null_joypad = { NULL, /* query_pad */ NULL, /* destroy */ NULL, /* button */ + NULL, /* state */ NULL, /* get_buttons */ NULL, /* axis */ NULL, /* poll */