diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 7a67e976a0..c72b7c0dbc 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -118,9 +118,9 @@ BOOL CALLBACK DinputDevice::DevicesCallback( return DIENUM_CONTINUE; } -void DinputDevice::getDevices() +void DinputDevice::getDevices(bool refresh) { - if (devices.empty()) + if (devices.empty() || refresh) { getPDI()->EnumDevices(DI8DEVCLASS_GAMECTRL, &DinputDevice::DevicesCallback, NULL, DIEDFL_ATTACHEDONLY); } @@ -149,7 +149,7 @@ DinputDevice::DinputDevice(int devnum) { return; } - getDevices(); + getDevices(false); if ( (devnum >= (int)devices.size()) || FAILED(getPDI()->CreateDevice(devices.at(devnum).guidInstance, &pJoystick, NULL))) { return; @@ -368,9 +368,6 @@ void DinputDevice::ApplyButtons(DIJOYSTATE2 &state) { size_t DinputDevice::getNumPads() { - if (devices.empty()) - { - getDevices(); - } + getDevices(true); return devices.size(); } diff --git a/Windows/DinputDevice.h b/Windows/DinputDevice.h index 5e94e424eb..366805c856 100644 --- a/Windows/DinputDevice.h +++ b/Windows/DinputDevice.h @@ -43,7 +43,7 @@ private: //GUIDs of the plugged in devices. This function will only search for devices //if none have been found yet and will only list plugged in devices //also, it excludes the devices that are compatible with XInput - static void getDevices(); + static void getDevices(bool refresh); //callback for the WinAPI to call static BOOL CALLBACK DevicesCallback( LPCDIDEVICEINSTANCE lpddi, diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 59cb44a2c0..adc7b67769 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -77,7 +77,7 @@ static BOOL PostDialogMessage(Dialog *dialog, UINT message, WPARAM wParam = 0, L } WindowsHost::WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindow) - : gfx_(nullptr), hInstance_(hInstance), + : hInstance_(hInstance), mainWindow_(mainWindow), displayWindow_(displayWindow) { @@ -87,8 +87,8 @@ WindowsHost::WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindo //add first XInput device to respond input.push_back(std::shared_ptr(new XinputDevice())); //find all connected DInput devices of class GamePad - size_t numDInputDevs = DinputDevice::getNumPads(); - for (size_t i = 0; i < numDInputDevs; i++) { + numDinputDevices_ = DinputDevice::getNumPads(); + for (size_t i = 0; i < numDinputDevices_; i++) { input.push_back(std::shared_ptr(new DinputDevice(static_cast(i)))); } keyboard = std::shared_ptr(new KeyboardDevice()); @@ -205,31 +205,44 @@ void WindowsHost::SetDebugMode(bool mode) { } void WindowsHost::PollControllers() { + static int checkCounter = 0; + static const int CHECK_FREQUENCY = 71; + if (checkCounter++ > CHECK_FREQUENCY) { + size_t newCount = DinputDevice::getNumPads(); + if (newCount > numDinputDevices_) { + INFO_LOG(SYSTEM, "New controller device detected"); + for (size_t i = numDinputDevices_; i < newCount; i++) { + input.push_back(std::shared_ptr(new DinputDevice(static_cast(i)))); + } + numDinputDevices_ = newCount; + } + + checkCounter = 0; + } + bool doPad = true; - for (auto iter = this->input.begin(); iter != this->input.end(); iter++) - { - auto device = *iter; + for (const auto &device : input) { if (!doPad && device->IsPad()) continue; if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD) doPad = false; } - float scaleFactor_x = g_dpi_scale_x * 0.1 * g_Config.fMouseSensitivity; - float scaleFactor_y = g_dpi_scale_y * 0.1 * g_Config.fMouseSensitivity; - - float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor_x)); - float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor_y)); - AxisInput axisX, axisY; - axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X; - axisX.deviceId = DEVICE_ID_MOUSE; - axisX.value = mx; - axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y; - axisY.deviceId = DEVICE_ID_MOUSE; - axisY.value = my; - // Disabled by default, needs a workaround to map to psp keys. - if (g_Config.bMouseControl){ + if (g_Config.bMouseControl) { + float scaleFactor_x = g_dpi_scale_x * 0.1 * g_Config.fMouseSensitivity; + float scaleFactor_y = g_dpi_scale_y * 0.1 * g_Config.fMouseSensitivity; + + float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor_x)); + float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor_y)); + AxisInput axisX, axisY; + axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X; + axisX.deviceId = DEVICE_ID_MOUSE; + axisX.value = mx; + axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y; + axisY.deviceId = DEVICE_ID_MOUSE; + axisY.value = my; + if (GetUIState() == UISTATE_INGAME || g_Config.bMapMouse) { if (fabsf(mx) > 0.01f) NativeAxis(axisX); if (fabsf(my) > 0.01f) NativeAxis(axisY); diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index ed3ffeefbd..623543d3cc 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -74,7 +74,8 @@ private: HINSTANCE hInstance_; HWND displayWindow_; HWND mainWindow_; - GraphicsContext *gfx_; + GraphicsContext *gfx_ = nullptr; + size_t numDinputDevices_ = 0; std::list> input; };