xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine &machine, UINT index, wininput_module &module) { xinput_joystick_device *devinfo; XINPUT_CAPABILITIES caps = { 0 }; if (FAILED(XInputGetCapabilities(index, 0, &caps))) { // If we can't get the capabilities skip this device return nullptr; } char device_name[16]; snprintf(device_name, sizeof(device_name), "XInput Player %u", index + 1); // allocate the device object devinfo = module.devicelist()->create_device1<xinput_joystick_device>(machine, device_name, module, shared_from_this()); // Set the player ID devinfo->xinput_state.player_index = index; // Assign the caps we captured earlier devinfo->xinput_state.caps = caps; return devinfo; }
//------------------------------------------------ // ctor //------------------------------------------------ InputXInput::InputXInput( HINSTANCE hInstance ) : InputDevice( hInstance ) , padID_( -1 ) , timeFFB_( 0 ) , isConnect_( false ) , isGeneratingFFB_( false ) { // XInput有効にする XInputEnable( TRUE ); // PADに管理用IDを振る padID_ = InputXInput::padCnt_; // パッドの数を更新 ++padCnt_; // XInputの能力を取得 XINPUT_CAPABILITIES capability; DWORD result = XInputGetCapabilities( padID_, XINPUT_FLAG_GAMEPAD, &capability ); // 使用の可否を更新 SetEnable( result == ERROR_SUCCESS ); // 振動をON SetEnableFFB( true ); }
//----------------------------------------------------------------------------- // Name: XBInput_CreateGamepads() // Desc: Creates the gamepad devices //----------------------------------------------------------------------------- HRESULT XBInput_CreateGamepads( XBGAMEPAD** ppGamepads ) { // Get a mask of all currently available devices DWORD dwDeviceMask = XGetDevices( XDEVICE_TYPE_GAMEPAD ); // Open the devices for( DWORD i=0; i < XGetPortCount(); i++ ) { ZeroMemory( &g_InputStates[i], sizeof(XINPUT_STATE) ); ZeroMemory( &g_Gamepads[i], sizeof(XBGAMEPAD) ); if( dwDeviceMask & (1<<i) ) { // Get a handle to the device g_Gamepads[i].hDevice = XInputOpen( XDEVICE_TYPE_GAMEPAD, i, XDEVICE_NO_SLOT, NULL ); // Store capabilities of the device XInputGetCapabilities( g_Gamepads[i].hDevice, &g_Gamepads[i].caps ); } } // Created devices are kept global, but for those who prefer member // variables, they can get a pointer to the gamepads returned. if( ppGamepads ) (*ppGamepads) = g_Gamepads; return S_OK; }
virtual void OnUpdate() { IInput *pInput = m_pInput; XINPUT_CAPABILITIES caps; while (!m_bQuit) { { for (DWORD i = 0; i < 4; ++i) { DWORD r = XInputGetCapabilities(i, XINPUT_FLAG_GAMEPAD, &caps); g_bConnected[i] = r == ERROR_SUCCESS; } } Sleep(1000); } }
// Gamepad navigation mapping static void ImGui_ImplWin32_UpdateGamepads() { ImGuiIO& io = ImGui::GetIO(); memset(io.NavInputs, 0, sizeof(io.NavInputs)); if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) return; // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. if (g_WantUpdateHasGamepad) { XINPUT_CAPABILITIES caps; g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); g_WantUpdateHasGamepad = false; } XINPUT_STATE xinput_state; io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) { const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; io.BackendFlags |= ImGuiBackendFlags_HasGamepad; #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); #undef MAP_BUTTON #undef MAP_ANALOG } }
int Input::DetectDevices(ControllerType types[]) { int numControllers = 1; types[0] = KEYBOARD_AND_MOUSE; // detect XInput gamepads for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) { XINPUT_CAPABILITIES capabilities; ZeroMemory(&capabilities, sizeof capabilities); DWORD result = XInputGetCapabilities(i, 0, &capabilities); if(result != ERROR_SUCCESS) continue; types[numControllers++] = GAMEPAD_XINPUT; } return numControllers; }
Input::Input(void) { quit = false; debug = false; placeWaypoint = false; XINPUT_CAPABILITIES cap; if (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &cap) == ERROR_SUCCESS) { controllerAvailable = true; } else { controllerAvailable = false; } intention.reset(); }
//----------------------------------------------------------------------------- // Name: XBInput_GetInput() // Desc: Processes input from the gamepads //----------------------------------------------------------------------------- VOID XBInput_GetInput( XBGAMEPAD* pGamepads ) { if( NULL == pGamepads ) pGamepads = g_Gamepads; // TCR 3-21 Controller Discovery // Get status about gamepad insertions and removals. Note that, in order to // not miss devices, we will check for removed device BEFORE checking for // insertions DWORD dwInsertions, dwRemovals; XGetDeviceChanges( XDEVICE_TYPE_GAMEPAD, &dwInsertions, &dwRemovals ); // Loop through all gamepads for( DWORD i=0; i < XGetPortCount(); i++ ) { // Handle removed devices. pGamepads[i].bRemoved = ( dwRemovals & (1<<i) ) ? TRUE : FALSE; if( pGamepads[i].bRemoved ) { // if the controller was removed after XGetDeviceChanges but before // XInputOpen, the device handle will be NULL if( pGamepads[i].hDevice ) XInputClose( pGamepads[i].hDevice ); pGamepads[i].hDevice = NULL; pGamepads[i].Feedback.Rumble.wLeftMotorSpeed = 0; pGamepads[i].Feedback.Rumble.wRightMotorSpeed = 0; } // Handle inserted devices pGamepads[i].bInserted = ( dwInsertions & (1<<i) ) ? TRUE : FALSE; if( pGamepads[i].bInserted ) { // TCR 1-14 Device Types pGamepads[i].hDevice = XInputOpen( XDEVICE_TYPE_GAMEPAD, i, XDEVICE_NO_SLOT, NULL ); // if the controller is removed after XGetDeviceChanges but before // XInputOpen, the device handle will be NULL if( pGamepads[i].hDevice ) XInputGetCapabilities( pGamepads[i].hDevice, &pGamepads[i].caps ); } // If we have a valid device, poll it's state and track button changes if( pGamepads[i].hDevice ) { // Read the input state XInputGetState( pGamepads[i].hDevice, &g_InputStates[i] ); // Copy gamepad to local structure memcpy( &pGamepads[i], &g_InputStates[i].Gamepad, sizeof(XINPUT_GAMEPAD) ); // Put Xbox device input for the gamepad into our custom format FLOAT fX1 = (pGamepads[i].sThumbLX+0.5f)/32767.5f; pGamepads[i].fX1 = ( fX1 >= 0.0f ? 1.0f : -1.0f ) * max( 0.0f, (fabsf(fX1)-XBINPUT_DEADZONE)/(1.0f-XBINPUT_DEADZONE) ); FLOAT fY1 = (pGamepads[i].sThumbLY+0.5f)/32767.5f; pGamepads[i].fY1 = ( fY1 >= 0.0f ? 1.0f : -1.0f ) * max( 0.0f, (fabsf(fY1)-XBINPUT_DEADZONE)/(1.0f-XBINPUT_DEADZONE) ); FLOAT fX2 = (pGamepads[i].sThumbRX+0.5f)/32767.5f; pGamepads[i].fX2 = ( fX2 >= 0.0f ? 1.0f : -1.0f ) * max( 0.0f, (fabsf(fX2)-XBINPUT_DEADZONE)/(1.0f-XBINPUT_DEADZONE) ); FLOAT fY2 = (pGamepads[i].sThumbRY+0.5f)/32767.5f; pGamepads[i].fY2 = ( fY2 >= 0.0f ? 1.0f : -1.0f ) * max( 0.0f, (fabsf(fY2)-XBINPUT_DEADZONE)/(1.0f-XBINPUT_DEADZONE) ); // Get the boolean buttons that have been pressed since the last // call. Each button is represented by one bit. pGamepads[i].wPressedButtons = ( pGamepads[i].wLastButtons ^ pGamepads[i].wButtons ) & pGamepads[i].wButtons; pGamepads[i].wLastButtons = pGamepads[i].wButtons; // Get the analog buttons that have been pressed or released since // the last call. for( DWORD b=0; b<8; b++ ) { // Turn the 8-bit polled value into a boolean value BOOL bPressed = ( pGamepads[i].bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK ); if( bPressed ) pGamepads[i].bPressedAnalogButtons[b] = !pGamepads[i].bLastAnalogButtons[b]; else pGamepads[i].bPressedAnalogButtons[b] = FALSE; // Store the current state for the next time pGamepads[i].bLastAnalogButtons[b] = bPressed; } } } }
// Returns TRUE if quitting, FALSE otherwise bool Input::update() { XINPUT_CAPABILITIES cap; if (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &cap) != ERROR_SUCCESS) { controllerAvailable = false; return quit; } else { controllerAvailable = true; } XINPUT_STATE state; HRESULT res = XInputGetState(0, &state); intention.reset(); if (SUCCEEDED(res))// && (state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { XINPUT_GAMEPAD gamepad = state.Gamepad; if(gamepad.wButtons & XINPUT_GAMEPAD_A){ intention.aPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_B){ intention.bPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_X){ intention.xPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_Y){ intention.yPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER){ intention.rbumpPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER){ intention.lbumpPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_START){ intention.startPressed = true; } if(gamepad.wButtons & XINPUT_GAMEPAD_BACK){ intention.selectPressed = true; } if (gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) { intention.rightTrig = gamepad.bRightTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD; } else { intention.rightTrig = 0; } if (gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) { intention.leftTrig = gamepad.bLeftTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD; } else { intention.leftTrig = 0; } if (gamepad.sThumbRX > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { intention.rightStickX = gamepad.sThumbRX - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; } else if (gamepad.sThumbRX < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { intention.rightStickX = gamepad.sThumbRX + XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; } else { intention.rightStickX = 0; } if (gamepad.sThumbRY > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { intention.rightStickY = gamepad.sThumbRY - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; } else if (gamepad.sThumbRY < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { intention.rightStickY = gamepad.sThumbRY + XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; } else { intention.rightStickY = 0; } if (gamepad.sThumbLX > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { intention.leftStickX = gamepad.sThumbLX - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; } else if (gamepad.sThumbLX < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { intention.leftStickX = gamepad.sThumbLX + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; } else { intention.leftStickX = 0; } if (gamepad.sThumbLY > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { intention.leftStickY = gamepad.sThumbLY - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; } else if (gamepad.sThumbLY < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { intention.leftStickY = gamepad.sThumbLY + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; } else { intention.leftStickY = 0; } // Compute acceleration and steering (between -1.0 and 1.0) intention.acceleration = intention.leftStickY / (float) (THUMBSTICK_MAX - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); intention.cameraX = intention.rightStickX / (float) (THUMBSTICK_MAX - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); intention.cameraY = intention.rightStickY / (float) (THUMBSTICK_MAX - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); /*Vibrating the controller: XINPUT_VIBRATION Vibration; Vibration.wLeftMotorSpeed = 50000; Vibration.wRightMotorSpeed = 50000; XInputSetState(0, &Vibration); */ // Process input based off controller's current state } return quit; }