diff --git a/input/xdk_xinput_input.c b/input/xdk_xinput_input.c index 383e252de2..cc206a7fc3 100644 --- a/input/xdk_xinput_input.c +++ b/input/xdk_xinput_input.c @@ -29,14 +29,6 @@ typedef struct xdk_input { - uint64_t pad_state[MAX_PADS]; - int16_t analog_state[MAX_PADS][2][2]; -#ifdef _XBOX1 - HANDLE gamepads[MAX_PADS]; - DWORD dwDeviceMask; - bool bInserted[MAX_PADS]; - bool bRemoved[MAX_PADS]; -#endif const rarch_joypad_driver_t *joypad; } xdk_input_t; @@ -44,119 +36,8 @@ static void xdk_input_poll(void *data) { xdk_input_t *xdk = (xdk_input_t*)data; -#if defined(_XBOX1) - unsigned int dwInsertions, dwRemovals; - XGetDeviceChanges(XDEVICE_TYPE_GAMEPAD, - reinterpret_cast(&dwInsertions), - reinterpret_cast(&dwRemovals)); -#endif - - for (unsigned port = 0; port < MAX_PADS; port++) - { -#ifdef _XBOX1 - XINPUT_CAPABILITIES caps[MAX_PADS]; - (void)caps; - - /* handle removed devices. */ - xdk->bRemoved[port] = (dwRemovals & (1 << port)) ? true : false; - - if(xdk->bRemoved[port]) - { - /* if the controller was removed after - * XGetDeviceChanges but before - * XInputOpen, the device handle will be NULL. */ - if(xdk->gamepads[port]) - XInputClose(xdk->gamepads[port]); - - xdk->gamepads[port] = 0; - xdk->pad_state[port] = 0; - } - - /* handle inserted devices. */ - xdk->bInserted[port] = (dwInsertions & (1 << port)) ? true : false; - - if(xdk->bInserted[port]) - { - XINPUT_POLLING_PARAMETERS m_pollingParameters; - m_pollingParameters.fAutoPoll = FALSE; - m_pollingParameters.fInterruptOut = TRUE; - m_pollingParameters.bInputInterval = 8; - m_pollingParameters.bOutputInterval = 8; - xdk->gamepads[port] = XInputOpen(XDEVICE_TYPE_GAMEPAD, port, - XDEVICE_NO_SLOT, NULL); - } - - if (!xdk->gamepads[port]) - continue; - - /* if the controller is removed after - * XGetDeviceChanges but before XInputOpen, - * the device handle will be NULL. */ -#endif - - XINPUT_STATE state_tmp; - -#if defined(_XBOX1) - if (XInputPoll(xdk->gamepads[port]) != ERROR_SUCCESS) - continue; - - if (XInputGetState(xdk->gamepads[port], &state_tmp) != ERROR_SUCCESS) - continue; -#elif defined(_XBOX360) - if (XInputGetState(port, &state_tmp) == ERROR_DEVICE_NOT_CONNECTED) - continue; -#endif - - uint64_t *state_cur = &xdk->pad_state[port]; - - *state_cur = 0; - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_START) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_START) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0); - -#if defined(_XBOX1) - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_B]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_A) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_A]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_B) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_Y]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_X) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_X]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_Y) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_WHITE]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L2) : 0); - *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_BLACK]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R2) : 0); -#elif defined(_XBOX360) - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_A) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_B) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_X) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_Y) : 0); - *state_cur |= ((state_tmp.Gamepad.bLeftTrigger > 128) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L) : 0); - *state_cur |= ((state_tmp.Gamepad.bRightTrigger > 128) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L2) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R2) : 0); -#endif - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L3) : 0); - *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R3) : 0); - - xdk->analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = state_tmp.Gamepad.sThumbLX; - xdk->analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = state_tmp.Gamepad.sThumbLY; - xdk->analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = state_tmp.Gamepad.sThumbRX; - xdk->analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = state_tmp.Gamepad.sThumbRY; - - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - if (xdk->analog_state[port][i][j] == -0x8000) - xdk->analog_state[port][i][j] = -0x7fff; - } - - uint64_t *state_p1 = &xdk->pad_state[0]; - uint64_t *lifecycle_state = &g_extern.lifecycle_state; - - *lifecycle_state &= ~((1ULL << RARCH_MENU_TOGGLE)); - - if((*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_L3)) && (*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R3))) - *lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE); + if (xdk && xdk->joypad) + xdk->joypad->poll(); } static int16_t xdk_input_state(void *data, const struct retro_keybind **binds, @@ -174,9 +55,9 @@ static int16_t xdk_input_state(void *data, const struct retro_keybind **binds, return input_joypad_pressed(xdk->joypad, port, binds[port], id); case RETRO_DEVICE_ANALOG: return input_joypad_analog(xdk->joypad, port, index, id, binds[port]); - default: - return 0; } + + return 0; } static void xdk_input_free_input(void *data) @@ -198,26 +79,8 @@ static void *xdk_input_init(void) if (!xdk) return NULL; -#ifdef _XBOX1 - XInitDevices(0, NULL); - - xdk->dwDeviceMask = XGetDevices(XDEVICE_TYPE_GAMEPAD); - - /* Check the device status. */ - switch(XGetDeviceEnumerationStatus()) - { - case XDEVICE_ENUMERATION_IDLE: - RARCH_LOG("Input state status: XDEVICE_ENUMERATION_IDLE\n"); - break; - case XDEVICE_ENUMERATION_BUSY: - RARCH_LOG("Input state status: XDEVICE_ENUMERATION_BUSY\n"); - break; - } - - while(XGetDeviceEnumerationStatus() == XDEVICE_ENUMERATION_BUSY) {} -#endif - xdk->joypad = input_joypad_init_driver(g_settings.input.joypad_driver); + return xdk; } @@ -230,12 +93,9 @@ static bool xdk_input_key_pressed(void *data, int key) static uint64_t xdk_input_get_capabilities(void *data) { - uint64_t caps = 0; + (void)data; - caps |= (1 << RETRO_DEVICE_JOYPAD); - caps |= (1 << RETRO_DEVICE_ANALOG); - - return caps; + return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); } /* FIXME - are we sure about treating low frequency motor as the @@ -276,7 +136,9 @@ static bool xdk_input_set_rumble(void *data, unsigned port, static const rarch_joypad_driver_t *xdk_input_get_joypad_driver(void *data) { xdk_input_t *xdk = (xdk_input_t*)data; - return xdk->joypad; + if (xdk) + return xdk->joypad; + return NULL; } input_driver_t input_xinput = { diff --git a/input/xdk_xinput_input_joypad.c b/input/xdk_xinput_input_joypad.c index 1232040422..f6c99fd786 100644 --- a/input/xdk_xinput_input_joypad.c +++ b/input/xdk_xinput_input_joypad.c @@ -14,6 +14,15 @@ * If not, see . */ +static uint64_t pad_state[MAX_PADS]; +static int16_t analog_state[MAX_PADS][2][2]; +#ifdef _XBOX1 +static HANDLE gamepads[MAX_PADS]; +static DWORD dwDeviceMask; +static bool bInserted[MAX_PADS]; +static bool bRemoved[MAX_PADS]; +#endif + static const char* const XBOX_CONTROLLER_NAMES[4] = { "XInput Controller (Player 1)", @@ -31,6 +40,25 @@ static bool xdk_joypad_init(void) { unsigned autoconf_pad; +#ifdef _XBOX1 + XInitDevices(0, NULL); + + dwDeviceMask = XGetDevices(XDEVICE_TYPE_GAMEPAD); + + /* Check the device status. */ + switch(XGetDeviceEnumerationStatus()) + { + case XDEVICE_ENUMERATION_IDLE: + RARCH_LOG("Input state status: XDEVICE_ENUMERATION_IDLE\n"); + break; + case XDEVICE_ENUMERATION_BUSY: + RARCH_LOG("Input state status: XDEVICE_ENUMERATION_BUSY\n"); + break; + } + + while(XGetDeviceEnumerationStatus() == XDEVICE_ENUMERATION_BUSY) {} +#endif + for (autoconf_pad = 0; autoconf_pad < MAX_PLAYERS; autoconf_pad++) { strlcpy(g_settings.input.device_names[autoconf_pad], @@ -47,28 +75,23 @@ static bool xdk_joypad_init(void) return true; } -static bool xdk_joypad_button(unsigned port_num, uint16_t joykey) +static bool xdk_joypad_button(unsigned port, uint16_t joykey) { xdk_input_t *xdk = (xdk_input_t*)driver.input_data; - if (port_num >= MAX_PADS) + if (port >= MAX_PADS) return false; - return xdk->pad_state[port_num] & (1ULL << joykey); + return xdk->pad_state[port] & (1ULL << joykey); } -static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) +static int16_t xdk_joypad_axis(unsigned port, uint32_t joyaxis) { - xdk_input_t *xdk = (xdk_input_t*)driver.input_data; - if (joyaxis == AXIS_NONE || port_num >= MAX_PADS) + int val = 0, axis = -1; + bool is_neg = false, is_pos = false; + if (joyaxis == AXIS_NONE || port >= MAX_PADS) return 0; - int val = 0; - - int axis = -1; - bool is_neg = false; - bool is_pos = false; - if (AXIS_NEG_GET(joyaxis) < 4) { axis = AXIS_NEG_GET(joyaxis); @@ -83,16 +106,16 @@ static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) switch (axis) { case 0: - val = xdk->analog_state[port_num][0][0]; + val = analog_state[port][0][0]; break; case 1: - val = xdk->analog_state[port_num][0][1]; + val = analog_state[port][0][1]; break; case 2: - val = xdk->analog_state[port_num][1][0]; + val = analog_state[port][1][0]; break; case 3: - val = xdk->analog_state[port_num][1][1]; + val = analog_state[port][1][1]; break; } @@ -107,12 +130,126 @@ static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) static void xdk_joypad_poll(void) { + uint64_t *state_p1, *lifecycle_state; +#if defined(_XBOX1) + unsigned int dwInsertions, dwRemovals, port; + + XGetDeviceChanges(XDEVICE_TYPE_GAMEPAD, + reinterpret_cast(&dwInsertions), + reinterpret_cast(&dwRemovals)); +#endif + + for (port = 0; port < MAX_PADS; port++) + { +#ifdef _XBOX1 + XINPUT_CAPABILITIES caps[MAX_PADS]; + (void)caps; + + /* handle removed devices. */ + bRemoved[port] = (dwRemovals & (1 << port)) ? true : false; + + if(bRemoved[port]) + { + /* if the controller was removed after + * XGetDeviceChanges but before + * XInputOpen, the device handle will be NULL. */ + if(gamepads[port]) + XInputClose(gamepads[port]); + + gamepads[port] = 0; + pad_state[port] = 0; + } + + /* handle inserted devices. */ + bInserted[port] = (dwInsertions & (1 << port)) ? true : false; + + if(bInserted[port]) + { + XINPUT_POLLING_PARAMETERS m_pollingParameters; + m_pollingParameters.fAutoPoll = FALSE; + m_pollingParameters.fInterruptOut = TRUE; + m_pollingParameters.bInputInterval = 8; + m_pollingParameters.bOutputInterval = 8; + gamepads[port] = XInputOpen(XDEVICE_TYPE_GAMEPAD, port, + XDEVICE_NO_SLOT, NULL); + } + + if (!gamepads[port]) + continue; + + /* if the controller is removed after + * XGetDeviceChanges but before XInputOpen, + * the device handle will be NULL. */ +#endif + + XINPUT_STATE state_tmp; + +#if defined(_XBOX1) + if (XInputPoll(gamepads[port]) != ERROR_SUCCESS) + continue; + + if (XInputGetState(gamepads[port], &state_tmp) != ERROR_SUCCESS) + continue; +#elif defined(_XBOX360) + if (XInputGetState(port, &state_tmp) == ERROR_DEVICE_NOT_CONNECTED) + continue; +#endif + + uint64_t *state_cur = &pad_state[port]; + + *state_cur = 0; + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_START) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_START) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0); + +#if defined(_XBOX1) + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_B]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_A) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_A]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_B) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_Y]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_X) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_X]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_Y) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_WHITE]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L2) : 0); + *state_cur |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_BLACK]) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R2) : 0); +#elif defined(_XBOX360) + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_A) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_B) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_X) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_Y) : 0); + *state_cur |= ((state_tmp.Gamepad.bLeftTrigger > 128) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L) : 0); + *state_cur |= ((state_tmp.Gamepad.bRightTrigger > 128) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L2) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R2) : 0); +#endif + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_L3) : 0); + *state_cur |= ((state_tmp.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_R3) : 0); + + analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = state_tmp.Gamepad.sThumbLX; + analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = state_tmp.Gamepad.sThumbLY; + analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = state_tmp.Gamepad.sThumbRX; + analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = state_tmp.Gamepad.sThumbRY; + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + if (analog_state[port][i][j] == -0x8000) + analog_state[port][i][j] = -0x7fff; + } + + state_p1 = &pad_state[0]; + lifecycle_state = &g_extern.lifecycle_state; + + *lifecycle_state &= ~((1ULL << RARCH_MENU_TOGGLE)); + + if((*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_L3)) && (*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R3))) + *lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE); } static bool xdk_joypad_query_pad(unsigned pad) { - xdk_input_t *xdk = (xdk_input_t*)driver.input_data; - return pad < MAX_PLAYERS && xdk->pad_state[pad]; + return pad < MAX_PLAYERS && pad_state[pad]; } static void xdk_joypad_destroy(void)