Avoid a crash when changing the device type at runtime in the input gui
This commit is contained in:
parent
f750b2e4f2
commit
cd362b6383
|
@ -206,6 +206,19 @@ void InputDeviceManager::UpdateDevices(int port, bool ack)
|
|||
dev->SetPort(usb_port, false);
|
||||
}
|
||||
if (type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
||||
if (type != to_underlying(g_XboxControllerHostBridge[port].XboxType)) {
|
||||
// this will happen when the user changes the type of an existing xbox device type connected to a port
|
||||
if (g_XboxControllerHostBridge[port].bPendingRemoval == false) {
|
||||
g_XboxControllerHostBridge[port].bPendingRemoval = true;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
DestructHleInputDevice(port);
|
||||
if (!ConstructHleInputDevice(type, port)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
BindHostDevice(port, usb_port, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,6 @@ void DestructHleInputDevice(int Port)
|
|||
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::DEVICE_INVALID;
|
||||
g_XboxControllerHostBridge[Port].XboxPort = PORT_INVALID;
|
||||
while (g_XboxControllerHostBridge[Port].bIoInProgress) {}
|
||||
std::memset(&InState[Port], 0, g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize);
|
||||
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
|
||||
g_XboxControllerHostBridge[Port].bSignaled = false;
|
||||
g_XboxControllerHostBridge[Port].bIoInProgress = false;
|
||||
|
@ -185,6 +184,7 @@ void DestructHleInputDevice(int Port)
|
|||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = 0;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = 0;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
|
||||
std::memset(&InState[Port], 0, sizeof(CXBX_XINPUT_IN_STATE));
|
||||
|
||||
g_bIsDevicesEmulating = false;
|
||||
}
|
||||
|
@ -298,25 +298,22 @@ void UpdateConnectedDeviceState(xbox::PXPP_DEVICE_TYPE DeviceType) {
|
|||
|
||||
int Port, PortMask;
|
||||
for (Port = PORT_1, PortMask = 1; Port <= PORT_4; Port++, PortMask <<= 1) {
|
||||
if (DeviceType == g_XboxControllerHostBridge[Port].XboxType) {
|
||||
if (!g_XboxControllerHostBridge[Port].bPendingRemoval) {
|
||||
DeviceType->CurrentConnected |= PortMask;
|
||||
}
|
||||
else {
|
||||
if (!g_XboxControllerHostBridge[Port].bSignaled) {
|
||||
g_XboxControllerHostBridge[Port].bSignaled = true;
|
||||
SDL_Event DeviceRemoveEvent;
|
||||
SDL_memset(&DeviceRemoveEvent, 0, sizeof(SDL_Event));
|
||||
DeviceRemoveEvent.type = Sdl::DeviceRemoveAck_t;
|
||||
DeviceRemoveEvent.user.data1 = new int(Port);
|
||||
SDL_PushEvent(&DeviceRemoveEvent);
|
||||
}
|
||||
DeviceType->CurrentConnected &= ~PortMask;
|
||||
}
|
||||
if (DeviceType == g_XboxControllerHostBridge[Port].XboxType && !g_XboxControllerHostBridge[Port].bPendingRemoval) {
|
||||
DeviceType->CurrentConnected |= PortMask;
|
||||
}
|
||||
else {
|
||||
DeviceType->CurrentConnected &= ~PortMask;
|
||||
}
|
||||
|
||||
if (static_cast<uint8_t>(g_XboxControllerHostBridge[Port].bPendingRemoval) &
|
||||
~(static_cast<uint8_t>(g_XboxControllerHostBridge[Port].bSignaled))) {
|
||||
g_XboxControllerHostBridge[Port].bSignaled = true;
|
||||
SDL_Event DeviceRemoveEvent;
|
||||
SDL_memset(&DeviceRemoveEvent, 0, sizeof(SDL_Event));
|
||||
DeviceRemoveEvent.type = Sdl::DeviceRemoveAck_t;
|
||||
DeviceRemoveEvent.user.data1 = new int(Port);
|
||||
SDL_PushEvent(&DeviceRemoveEvent);
|
||||
}
|
||||
}
|
||||
DeviceType->ChangeConnected = DeviceType->PreviousConnected ^ DeviceType->CurrentConnected;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ static INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPara
|
|||
LRESULT CALLBACK WindowsCtrlSubProcNumericFilter(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
||||
HWND g_ChildWnd = NULL;
|
||||
static bool g_bHasOptChanges = false;
|
||||
static bool g_bHasInputChanges[4] = { false, false, false, false };
|
||||
|
||||
|
||||
void SyncInputSettings(int port_num, int dev_type, bool is_opt)
|
||||
|
@ -143,8 +144,12 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
std::to_string(g_Settings->m_input_general.MoWheelRange).c_str()));
|
||||
}
|
||||
|
||||
// Reset option changes flag
|
||||
// Reset option/input changes flag
|
||||
g_bHasOptChanges = false;
|
||||
g_bHasInputChanges[0] = false;
|
||||
g_bHasInputChanges[1] = false;
|
||||
g_bHasInputChanges[2] = false;
|
||||
g_bHasInputChanges[3] = false;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -152,9 +157,19 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
{
|
||||
if (g_bHasOptChanges) {
|
||||
UpdateInputOpt(hWndDlg);
|
||||
g_InputDeviceManager.UpdateOpt(true);
|
||||
SyncInputSettings(0, 0, true);
|
||||
}
|
||||
|
||||
for (int port = PORT_1; port <= PORT_4; port++) {
|
||||
if (g_bHasInputChanges[port]) {
|
||||
HWND hHandle = GetDlgItem(hWndDlg, IDC_DEVICE_PORT1 + port);
|
||||
int DeviceType = SendMessage(hHandle, CB_GETITEMDATA, SendMessage(hHandle, CB_GETCURSEL, 0, 0), 0);
|
||||
g_Settings->m_input_port[port].Type = DeviceType;
|
||||
SyncInputSettings(port, DeviceType, false);
|
||||
}
|
||||
}
|
||||
|
||||
g_InputDeviceManager.Shutdown();
|
||||
g_ChildWnd = NULL;
|
||||
EndDialog(hWndDlg, wParam);
|
||||
|
@ -182,11 +197,6 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
assert(DeviceType > to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID) &&
|
||||
DeviceType < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX));
|
||||
|
||||
if (g_bHasOptChanges) {
|
||||
UpdateInputOpt(hWndDlg);
|
||||
g_InputDeviceManager.UpdateOpt(true);
|
||||
}
|
||||
|
||||
switch (DeviceType)
|
||||
{
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
|
||||
|
@ -206,8 +216,7 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
break;
|
||||
}
|
||||
|
||||
// Also inform the kernel process if it exists
|
||||
SyncInputSettings(port, DeviceType, false);
|
||||
g_bHasInputChanges[port] = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -234,10 +243,7 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
EnableWindow(GetDlgItem(hWndDlg, IDC_CONFIGURE_PORT1 + port), TRUE);
|
||||
}
|
||||
|
||||
g_Settings->m_input_port[port].Type = dev_type;
|
||||
|
||||
// Also inform the kernel process if it exists
|
||||
SyncInputSettings(port, dev_type, false);
|
||||
g_bHasInputChanges[port] = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue