From f5f3ff97a5b4ae2c432222ba29325e6ffba756f7 Mon Sep 17 00:00:00 2001 From: mattmenke Date: Tue, 31 Mar 2009 08:15:38 +0000 Subject: [PATCH] LilyPad: Fixed a bug in list of bindings when go to config screen after running Pcsx2 for a bit, and some devices enabled on the config screen were not enabled in game (Either due to focus issues, or, more probably, due to mouse API not being disabled, but not running with mouse focus). Also bug fix for cursor clipping rectangle not being reset after window resize. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@870 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/LilyPad/Config.cpp | 93 +++++++++++++++++----------- plugins/LilyPad/LilyPad.cpp | 24 +++++-- plugins/LilyPad/LilyPad.rc | 8 +-- plugins/LilyPad/RawInput.cpp | 13 ++-- plugins/LilyPad/WindowsMessaging.cpp | 20 ++---- plugins/LilyPad/WindowsMouse.cpp | 31 ++++++++++ plugins/LilyPad/WindowsMouse.h | 12 +++- 7 files changed, 133 insertions(+), 68 deletions(-) diff --git a/plugins/LilyPad/Config.cpp b/plugins/LilyPad/Config.cpp index 2aa289c00e..d5ff4edfbe 100644 --- a/plugins/LilyPad/Config.cpp +++ b/plugins/LilyPad/Config.cpp @@ -1502,6 +1502,18 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l return 0; } +// Returns 0 if pad doesn't exist due to mtap settings, as a convenience. +int GetPadString(wchar_t *string, unsigned int port, unsigned int slot) { + if (!slot) { + wsprintfW(string, L"Pad %i", port+1); + } + else { + wsprintfW(string, L"Pad %i-%i", port+1, slot+1); + if (!config.multitap[port]) return 0; + } + return 1; +} + void UpdatePadPages() { HPROPSHEETPAGE pages[10]; int count = 0; @@ -1511,13 +1523,7 @@ void UpdatePadPages() { for (int slot=0; slot<4; slot++) { if (config.padConfigs[port][slot].type == DisabledPad) continue; wchar_t title[20]; - if (!slot) { - wsprintfW(title, L"Pad %i", port+1); - } - else { - if (!config.multitap[port]) continue; - wsprintfW(title, L"Pad %i-%i", port+1, slot+1); - } + if (!GetPadString(title, port, slot)) continue; PROPSHEETPAGE psp; ZeroMemory(&psp, sizeof(psp)); @@ -1570,16 +1576,11 @@ void UpdatePadList(HWND hWnd) { int slot; int port; int index = 0; - wchar_t *strings[] = {L"Disabled", L"Dualshock 2", L"Guitar"}; + wchar_t *padTypes[] = {L"Disabled", L"Dualshock 2", L"Guitar"}; for (port=0; port<2; port++) { for (slot = 0; slot<4; slot++) { - wchar_t text[100]; - if (!slot) - wsprintf(text, L"Pad %i", port+1); - else { - if (!config.multitap[port]) continue; - wsprintf(text, L"Pad %i-%i", port+1, slot+1); - } + wchar_t text[20]; + if (!GetPadString(text, port, slot)) continue; LVITEM item; item.iItem = index; item.iSubItem = 0; @@ -1594,7 +1595,7 @@ void UpdatePadList(HWND hWnd) { item.iSubItem = 1; if (2 < (unsigned int)config.padConfigs[port][slot].type) config.padConfigs[port][slot].type = Dualshock2Pad; - item.pszText = strings[config.padConfigs[port][slot].type]; + item.pszText = padTypes[config.padConfigs[port][slot].type]; ListView_SetItem(hWndList, &item); item.iSubItem = 2; @@ -1845,37 +1846,41 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); int port1, slot1, port2, slot2; if (!ListIndexToPortAndSlot(index, &port1, &slot1)) break; - //HMENU hMenu = CreateMenu(); HMENU hMenu = CreatePopupMenu(); if (!hMenu) break; + MENUITEMINFOW info; for (port2=1; port2>=0; port2--) { for (slot2 = 3; slot2>=0; slot2--) { - if (port2 == port1 && slot2 == slot1) continue; - wchar_t text[100]; - if (!slot2) - wsprintf(text, L"Swap with Pad %i", port2+1); - else { - if (!config.multitap[port2]) continue; - wsprintf(text, L"Swap with Pad %i-%i", port2+1, slot2+1); - } - MENUITEMINFOW info; - memset(&info, 0, sizeof(info)); + wchar_t text[40]; + wchar_t pad[20]; + if (!GetPadString(pad, port2, slot2)) continue; info.cbSize = sizeof(info); info.fMask = MIIM_STRING | MIIM_ID; - info.wID = 0x10000 + port2+2*slot2; info.dwTypeData = text; - info.cch = wcslen(text); - InsertMenuItemW(hMenu, 0, 1, &info); + if (port2 == port1 && slot2 == slot1) { + int index = GetMenuItemCount(hMenu); + wsprintfW(text, L"Clear %s Bindings", pad); + info.wID = -1; + InsertMenuItemW(hMenu, index, 1, &info); + info.fMask = MIIM_TYPE; + info.fType = MFT_SEPARATOR; + InsertMenuItemW(hMenu, index, 1, &info); + } + else { + info.wID = port2+2*slot2; + wsprintfW(text, L"Swap with %s", pad); + InsertMenuItemW(hMenu, 0, 1, &info); + } } } POINT pos; GetCursorPos(&pos); - int res = TrackPopupMenuEx(hMenu, TPM_NONOTIFY|TPM_RETURNCMD, pos.x, pos.y, hWndProp, 0); + short res = TrackPopupMenuEx(hMenu, TPM_NONOTIFY|TPM_RETURNCMD, pos.x, pos.y, hWndProp, 0); DestroyMenu(hMenu); + if (!res) break; if (res > 0) { - slot2 = res - 0x10000; - port2 = slot2&1; - slot2 >>= 1; + slot2 = res / 2; + port2 = res&1; PadConfig padCfgTemp = config.padConfigs[port1][slot1]; config.padConfigs[port1][slot1] = config.padConfigs[port2][slot2]; config.padConfigs[port2][slot2] = padCfgTemp; @@ -1884,10 +1889,20 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L dm->devices[i]->pads[port1][slot1] = dm->devices[i]->pads[port2][slot2]; dm->devices[i]->pads[port2][slot2] = bindings; } - UpdatePadPages(); - UpdatePadList(hWnd); - PropSheet_Changed(hWndProp, hWnd); } + else { + for (int i=0; inumDevices; i++) { + free(dm->devices[i]->pads[port1][slot1].bindings); + for (int j=0; jdevices[i]->pads[port1][slot1].numFFBindings; j++) { + free(dm->devices[i]->pads[port1][slot1].ffBindings[j].axes); + } + free(dm->devices[i]->pads[port1][slot1].ffBindings); + memset(&dm->devices[i]->pads[port1][slot1], 0, sizeof(dm->devices[i]->pads[port1][slot1])); + } + } + UpdatePadPages(); + UpdatePadList(hWnd); + PropSheet_Changed(hWndProp, hWnd); } } } @@ -1906,6 +1921,10 @@ int CALLBACK PropSheetProc(HWND hWnd, UINT msg, LPARAM lParam) { void CALLBACK PADconfigure() { // Can end up here without PadConfigure() being called first. LoadSettings(); + // Can also end up here after running emulator a bit, and possibly + // disabling some devices due to focus changes, or releasing mouse. + RefreshEnabledDevices(0); + memset(hWnds, 0, sizeof(hWnds)); PROPSHEETPAGE psp; diff --git a/plugins/LilyPad/LilyPad.cpp b/plugins/LilyPad/LilyPad.cpp index 635e8b3ab7..f4b3801f0b 100644 --- a/plugins/LilyPad/LilyPad.cpp +++ b/plugins/LilyPad/LilyPad.cpp @@ -909,6 +909,11 @@ u8 CALLBACK PADstartPoll(int port) { } } +inline int IsDualshock2(u8 port, u8 slot) { + return config.padConfigs[query.port][query.slot].type == Dualshock2Pad || + (config.padConfigs[query.port][query.slot].type == GuitarPad && config.GH2); +} + u8 CALLBACK PADpoll(u8 value) { DEBUG_IN(value); if (query.lastByte+1 >= query.numBytes) { @@ -1038,9 +1043,14 @@ u8 CALLBACK PADpoll(u8 value) { break; // QUERY_MODEL_AND_MODE case 0x45: - if (config.padConfigs[query.port][query.slot].type != GuitarPad || config.GH2) SET_FINAL_RESULT(queryModelDS2) - else SET_FINAL_RESULT(queryModelDS1); - query.response[5] = pad->mode != MODE_DIGITAL; + if (IsDualshock2(query.port, query.slot)) { + SET_FINAL_RESULT(queryModelDS2) + } + else { + SET_FINAL_RESULT(queryModelDS1); + } + // Not digital mode. + query.response[5] = (pad->mode & 0xF) != 1; break; // QUERY_ACT case 0x46: @@ -1062,7 +1072,12 @@ u8 CALLBACK PADpoll(u8 value) { break; // SET_DS2_NATIVE_MODE case 0x4F: - SET_RESULT(setNativeMode); + if (IsDualshock2(query.port, query.slot)) { + SET_RESULT(setNativeMode); + } + else { + SET_FINAL_RESULT(setNativeMode); + } break; default: query.numBytes = 0; @@ -1140,6 +1155,7 @@ u8 CALLBACK PADpoll(u8 value) { pad->vibrate[query.lastByte-2] = value; } break; + // SET_DS2_NATIVE_MODE case 0x4F: if (query.lastByte == 3 || query.lastByte == 4) { pad->umask[query.lastByte-3] = value; diff --git a/plugins/LilyPad/LilyPad.rc b/plugins/LilyPad/LilyPad.rc index 9fd6224740..8c3b7ada71 100644 --- a/plugins/LilyPad/LilyPad.rc +++ b/plugins/LilyPad/LilyPad.rc @@ -226,15 +226,15 @@ BEGIN GROUPBOX "Pads",IDC_STATIC,7,140,410,67 CONTROL "Port 1 Multitap",IDC_MULTITAP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,152,63,10 CONTROL "Port 2 Multitap",IDC_MULTITAP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,164,63,10 - CONTROL "",IDC_PAD_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_TABSTOP,81,152,183,48,WS_EX_CLIENTEDGE - COMBOBOX IDC_PAD_TYPE,270,153,140,41,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_PAD_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_TABSTOP,81,151,183,50,WS_EX_CLIENTEDGE + COMBOBOX IDC_PAD_TYPE,270,152,140,41,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP CONTROL "Use analog mode whenever possible",IDC_ANALOG_START1, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,170,132,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,169,132,10 GROUPBOX "Device Diagnostics",IDC_STATIC,7,211,201,99 CONTROL "",IDC_LIST,"SysListView32",LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,15,224,185,61,WS_EX_CLIENTEDGE PUSHBUTTON "Test Device",ID_TEST,86,289,57,15 PUSHBUTTON "Refresh",ID_REFRESH,152,289,48,15 - GROUPBOX "Miscellaneous",IDC_STATIC,216,211,201,35 + GROUPBOX "Miscellaneous",IDC_STATIC,216,211,201,34 CONTROL "Use GS thread (Recommended)",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,221,116,10 CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,232,80,10 CONTROL "Local volume control",IDC_VISTA_VOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,221,77,10 diff --git a/plugins/LilyPad/RawInput.cpp b/plugins/LilyPad/RawInput.cpp index 32d299a09d..0fbde4513f 100644 --- a/plugins/LilyPad/RawInput.cpp +++ b/plugins/LilyPad/RawInput.cpp @@ -111,8 +111,6 @@ public: } }; -static POINT rawOrigCursorPos; - class RawInputMouse : public WindowsMouse { public: HANDLE hDevice; @@ -135,8 +133,7 @@ public: // EatWndProc fail. In all other cases, no unmatched initialization/cleanup // lines. if (!rawMouseActivatedCount++) { - GetCursorPos(&rawOrigCursorPos); - ShowCursor(0); + GetMouseCapture(hWnd); if (!rawKeyboardActivatedCount && !EatWndProc(hWnd, RawInputWndProc)) { Deactivate(); return 0; @@ -157,9 +154,8 @@ public: active = 0; rawMouseActivatedCount --; if (!rawMouseActivatedCount) { - ShowCursor(1); ReleaseRawMice(); - SetCursorPos(rawOrigCursorPos.x, rawOrigCursorPos.y); + ReleaseMouseCapture(); if (!rawKeyboardActivatedCount) { ReleaseExtraProc(RawInputWndProc); } @@ -225,6 +221,11 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls); } } + else if (uMsg == WM_SIZE && rawMouseActivatedCount) { + // Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt. + WindowsMouse::WindowResized(hWnd); + } + return CONTINUE_BLISSFULLY; } diff --git a/plugins/LilyPad/WindowsMessaging.cpp b/plugins/LilyPad/WindowsMessaging.cpp index dd36b70eb3..c85783e430 100644 --- a/plugins/LilyPad/WindowsMessaging.cpp +++ b/plugins/LilyPad/WindowsMessaging.cpp @@ -79,20 +79,10 @@ public: Deactivate(); return 0; } + GetMouseCapture(hWnd); - SetCapture(hWnd); - ShowCursor(0); - - GetCursorPos(&origCursorPos); active = 1; - RECT r; - GetWindowRect(hWnd, &r); - ClipCursor(&r); - center.x = (r.left + r.right)/2; - center.y = (r.top + r.bottom)/2; - SetCursorPos(center.x, center.y); - wmm = this; AllocState(); @@ -102,10 +92,7 @@ public: void Deactivate() { FreeState(); if (active) { - ClipCursor(0); - ReleaseCapture(); - ShowCursor(1); - SetCursorPos(origCursorPos.x, origCursorPos.y); + ReleaseMouseCapture(); if (!wmk) ReleaseExtraProc(WindowsMessagingWndProc); active = 0; @@ -179,6 +166,9 @@ ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, wmm->UpdateAxis(3, ((int)wParam>>16)/WHEEL_DELTA); return NO_WND_PROC; } + else if (uMsg == WM_SIZE && wmm->active) { + WindowsMouse::WindowResized(hWnd); + } // Taken care of elsewhere. When binding, killing focus means stop reading input. // When running PCSX2, I release all mouse and keyboard input elsewhere. /*else if (uMsg == WM_KILLFOCUS) { diff --git a/plugins/LilyPad/WindowsMouse.cpp b/plugins/LilyPad/WindowsMouse.cpp index 72a951f925..6d2e4db653 100644 --- a/plugins/LilyPad/WindowsMouse.cpp +++ b/plugins/LilyPad/WindowsMouse.cpp @@ -2,6 +2,9 @@ #include "VKey.h" #include "WindowsMouse.h" +POINT WindowsMouse::origCursorPos; +POINT WindowsMouse::center; + WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) : Device(api, MOUSE, displayName, instanceID, deviceID) { int i; @@ -41,4 +44,32 @@ void WindowsMouse::UpdateAxis(unsigned int axis, int delta) { physicalControlState[5+axis] += (delta<<(16 - 3*(axis < 2))); } +void WindowsMouse::WindowResized(HWND hWnd) { + RECT r; + GetWindowRect(hWnd, &r); + ClipCursor(&r); + center.x = (r.left + r.right)/2; + center.y = (r.top + r.bottom)/2; + SetCursorPos(center.x, center.y); +} +void WindowsMouse::GetMouseCapture(HWND hWnd) { + SetCapture(hWnd); + ShowCursor(0); + + GetCursorPos(&origCursorPos); + + RECT r; + GetWindowRect(hWnd, &r); + ClipCursor(&r); + center.x = (r.left + r.right)/2; + center.y = (r.top + r.bottom)/2; + SetCursorPos(center.x, center.y); +} + +void WindowsMouse::ReleaseMouseCapture() { + ClipCursor(0); + ReleaseCapture(); + ShowCursor(1); + SetCursorPos(origCursorPos.x, origCursorPos.y); +} diff --git a/plugins/LilyPad/WindowsMouse.h b/plugins/LilyPad/WindowsMouse.h index b3085c5bb9..5fa5772c4a 100644 --- a/plugins/LilyPad/WindowsMouse.h +++ b/plugins/LilyPad/WindowsMouse.h @@ -3,8 +3,16 @@ // Shared functionality for WM and RAW keyboards. class WindowsMouse : public Device { public: - POINT origCursorPos; - POINT center; + // Used by GetMouseCapture()/ReleaseMouseCapture() + // Static because can have multiple raw mice active at once, + // and only get/release capture once. + static POINT origCursorPos; + static POINT center; + + static void GetMouseCapture(HWND hWnd); + static void WindowResized(HWND hWnd); + static void ReleaseMouseCapture(); + // hWheel variable lets me display no horizontal wheel for raw input, just to make it clear // that it's not supported. WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID=0, wchar_t *deviceID=0);