From 87a230f550fe3bbd39e9993fc266daffc0a69081 Mon Sep 17 00:00:00 2001 From: mattmenke Date: Tue, 17 Feb 2009 04:54:46 +0000 Subject: [PATCH] Fixed a pair of bugs with flipped controls and sensitivity > 1. "Ignore keyboard" removed from device list. Removed some unnecessary mouse capture code for mouse raw input. Renamed some options to be more user friendly. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@515 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/LilyPad/Config.cpp | 2 +- plugins/LilyPad/DirectInput.cpp | 2 +- plugins/LilyPad/InputManager.cpp | 12 +-- plugins/LilyPad/KeyboardHook.cpp | 2 - plugins/LilyPad/LilyPad.cpp | 116 ++++++++++++-------------- plugins/LilyPad/LilyPad.rc | 16 ++-- plugins/LilyPad/LilyPad_VC2008.vcproj | 88 +++++++++---------- plugins/LilyPad/RawInput.cpp | 10 +-- plugins/LilyPad/WindowsMessaging.cpp | 7 +- 9 files changed, 116 insertions(+), 139 deletions(-) diff --git a/plugins/LilyPad/Config.cpp b/plugins/LilyPad/Config.cpp index 7b27e454b7..fd50be56cc 100644 --- a/plugins/LilyPad/Config.cpp +++ b/plugins/LilyPad/Config.cpp @@ -148,7 +148,7 @@ void RefreshEnabledDevicesAndDisplay(int updateDeviceList = 0, HWND hWnd = 0, in item.iSubItem = 0; item.mask = LVIF_TEXT | LVIF_PARAM; for (int j=0; jnumDevices; j++) { - if (dm->devices[j]->enabled) { + if (dm->devices[j]->enabled && dm->devices[j]->api != IGNORE_KEYBOARD) { item.lParam = j; item.pszText = dm->devices[j]->displayName; if (count > 0) { diff --git a/plugins/LilyPad/DirectInput.cpp b/plugins/LilyPad/DirectInput.cpp index 8da9fad2c3..2af73a3abd 100644 --- a/plugins/LilyPad/DirectInput.cpp +++ b/plugins/LilyPad/DirectInput.cpp @@ -152,7 +152,7 @@ public: int Activate(void *d) { int i, j; - if (active) Deactivate(); + Deactivate(); InitInfo *info = (InitInfo*)d; // Note: Have to use hWndTop to properly hide cursor for mouse device. if (type == OTHER) { diff --git a/plugins/LilyPad/InputManager.cpp b/plugins/LilyPad/InputManager.cpp index 83eda2b3e3..f3eb83bbce 100644 --- a/plugins/LilyPad/InputManager.cpp +++ b/plugins/LilyPad/InputManager.cpp @@ -183,16 +183,8 @@ void Device::CalcVirtualState() { double angle = val * (3.141592653589793/18000.0); double East = sin(angle); double South = -cos(angle); - double fabsSouth = fabs(South); - double fabsEast = fabs(East); // Normalize so greatest direction is 1. - double mul; - if (fabsSouth > fabsEast) { - mul = FULLY_DOWN / fabsSouth; - } - else { - mul = FULLY_DOWN / fabsEast; - } + double mul = FULLY_DOWN / max(fabs(South), fabs(East)); iEast = (int) floor(East * mul + 0.5); iSouth = (int) floor(South * mul + 0.5); } @@ -300,10 +292,10 @@ wchar_t *Device::GetVirtualControlName(VirtualControl *control) { uid &= 0xFF000000; int len = (int)wcslen(baseName); if (len > 99) len = 99; - if (uid && len > 89) len = 89; memcpy(temp, baseName, len*sizeof(wchar_t)); temp[len] = 0; if (uid) { + if (len > 95) len = 95; wchar_t *out = temp+len; if (uid == UID_AXIS_POS) { wcscpy(out, L" +"); diff --git a/plugins/LilyPad/KeyboardHook.cpp b/plugins/LilyPad/KeyboardHook.cpp index 66a17a9a9e..28599fa96c 100644 --- a/plugins/LilyPad/KeyboardHook.cpp +++ b/plugins/LilyPad/KeyboardHook.cpp @@ -31,8 +31,6 @@ public: } int Update() { - //if (!GetKeyboardState(buttonState)) return 0; - for (int i=0; i<=4; i++) virtualControlState[i] = 0; // So I'll bind to left/right control/shift instead of generic ones. virtualControlState[VK_SHIFT] = 0; virtualControlState[VK_CONTROL] = 0; diff --git a/plugins/LilyPad/LilyPad.cpp b/plugins/LilyPad/LilyPad.cpp index 297450bee5..25754f5237 100644 --- a/plugins/LilyPad/LilyPad.cpp +++ b/plugins/LilyPad/LilyPad.cpp @@ -166,17 +166,20 @@ void UpdateEnabledDevices(int updateList = 0) { if (dev->type == KEYBOARD) { if (!activeWindow) dm->DisableDevice(i); } - // Keep for cursor hiding consistency. + // Keep for cursor hiding consistency, unless unfocused. + // miceEnabled tracks state of mouse enable/disable button, not if mouse API is set to disabled. else if (dev->type == MOUSE) { if (!miceEnabled || !activeWindow) dm->DisableDevice(i); } else if (!activeWindow && !config.background) dm->DisableDevice(i); else { - int needDevice = 0; + int numActiveBindings = 0; for (int pad=0; pad<2; pad++) { - needDevice |= (padsEnabled[pad] && dev->pads[pad].numBindings+dev->pads[pad].numFFBindings); + if (padsEnabled[pad]) { + numActiveBindings += dev->pads[pad].numBindings + dev->pads[pad].numFFBindings; + } } - if (!needDevice) + if (!numActiveBindings) dm->DisableDevice(i); } } @@ -190,7 +193,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, void* lpvReserved) { } else if (fdwReason == DLL_PROCESS_DETACH) { DeleteCriticalSection(&readInputCriticalSection); - activeWindow = 0; while (openCount) PADclose(); PADshutdown(); @@ -224,7 +226,7 @@ void AddForce(ButtonSum *sum, u8 cmd, int delta = 255) { else if (cmd < 0x20) { sum->buttons[cmd-0x10-4] += delta; } - else if (cmd < 0x24) { + else if (cmd < 0x28) { if (cmd == 32) { sum->sticks[2].vert -= delta; } @@ -254,13 +256,13 @@ void AddForce(ButtonSum *sum, u8 cmd, int delta = 255) { } } -void ProcessButtonBinding(Binding *b, ButtonSum *sum, unsigned int value) { +void ProcessButtonBinding(Binding *b, ButtonSum *sum, int value) { int sensitivity = b->sensitivity; if (sensitivity < 0) { sensitivity = -sensitivity; value = (1<<16)-value; } - if (value) { + if (value > 0) { AddForce(sum, b->command, (int)((((sensitivity*(255*(__int64)value)) + BASE_SENSITIVITY/2)/BASE_SENSITIVITY + FULLY_DOWN/2)/FULLY_DOWN)); } } @@ -302,8 +304,8 @@ void CALLBACK PADupdate(int pad) { } void Update(int pad) { - if ((unsigned int)pad > 2 /* || safeShutdown//*/) return; - if (summed[pad]) { + if ((unsigned int)pad > 2) return; + if (summed[pad] > 0) { summed[pad]--; return; } @@ -410,7 +412,6 @@ void Update(int pad) { } if (pads[currentPad].mode == 0x41) { - //if (activeConfigs[currentPad] && pads[currentPad].mode == 0x41 && activeConfigs[currentPad]->analogDigitals) { s[currentPad].sticks[0].horiz += s[currentPad].sticks[1].horiz + s[currentPad].sticks[2].horiz; @@ -422,12 +423,14 @@ void Update(int pad) { CapSum(&s[currentPad]); if (lockStateChanged[currentPad]) { if (lockStateChanged[currentPad] & LOCK_BOTH) { - if (pads[currentPad].lockedState != (LOCK_DIRECTION | LOCK_BUTTONS)) - // enable the one that's not enabled. + if (pads[currentPad].lockedState != (LOCK_DIRECTION | LOCK_BUTTONS)) { + // Enable the one that's not enabled. lockStateChanged[currentPad] ^= pads[currentPad].lockedState^(LOCK_DIRECTION | LOCK_BUTTONS); - else + } + else { // Disable both lockStateChanged[currentPad] ^= LOCK_DIRECTION | LOCK_BUTTONS; + } } if (lockStateChanged[currentPad] & LOCK_DIRECTION) { if (pads[currentPad].lockedState & LOCK_DIRECTION) { @@ -560,7 +563,8 @@ s32 CALLBACK PADinit(u32 flags) { // Note to self: Has to be a define for the sizeof() to work right. -// Note to self 2: All are the same size, anyways, except for full DS2 response and digital mode response. +// Note to self 2: All are the same size, anyways, except for longer full DS2 response +// and shorter digital mode response. #define SET_RESULT(a) { \ memcpy(query.response+2, a, sizeof(a)); \ query.numBytes = 2+sizeof(a); \ @@ -610,28 +614,20 @@ ExtraWndProcResult HackWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara switch (uMsg) { case WM_SETTEXT: if (config.saveStateTitle) { - wchar_t *text; + wchar_t text[200]; int len; if (IsWindowUnicode(hWnd)) { - text = wcsdup((wchar_t*) lParam); + len = wcslen((wchar_t*) lParam); + if (len < sizeof(text)/sizeof(wchar_t)) wcscpy(text, (wchar_t*) lParam); } else { - char *ascii = (char*) lParam; - len = (int)strlen(ascii)+1; - text = (wchar_t*) calloc(len, sizeof(wchar_t)); - MultiByteToWideChar(CP_ACP, 0, ascii, -1, text, len); + len = MultiByteToWideChar(CP_ACP, 0, (char*) lParam, -1, text, sizeof(text)/sizeof(wchar_t)); } - if (!wcsstr(text, L"State")) { - int len = wcslen(text); - if (len < 150) { - wchar_t newTitle[200]; - wsprintfW(newTitle, L"%s | State %i", text, saveStateIndex); - free(text); - SetWindowText(hWnd, newTitle); - return NO_WND_PROC; - } + if (len > 0 && len < 150 && !wcsstr(text, L" | State ")) { + wsprintfW(text+len, L" | State %i", saveStateIndex); + SetWindowText(hWnd, text); + return NO_WND_PROC; } - free(text); } break; case WM_DEVICECHANGE: @@ -727,9 +723,14 @@ s32 CALLBACK PADopen(void *pDsp) { query.lastByte = 1; query.numBytes = 0; + // I'd really rather use this line, but GetActiveWindow() does not have complete specs. + // It *seems* to return null when no window from this thread has focus, but the + // Microsoft specs seem to imply it returns the window from this thread that would have focus, + // if any window did (topmost in this thread?). Which isn't what I want, and doesn't seem + // to be what it actually does. + // activeWindow = GetActiveWindow() == hWnd; - if (GetAncestor(hWnd, GA_ROOT) == GetAncestor(GetForegroundWindow(), GA_ROOT)) - activeWindow = 1; + activeWindow = (GetAncestor(hWnd, GA_ROOT) == GetAncestor(GetForegroundWindow(), GA_ROOT)); UpdateEnabledDevices(); return 0; } @@ -746,7 +747,7 @@ void CALLBACK PADclose() { u8 CALLBACK PADstartPoll(int pad) { DEBUG_NEW_SET(); pad--; - if (pad == !(!pad)) { + if ((unsigned int)pad <= 1) { query.queryDone = 0; query.pad = pad; query.numBytes = 2; @@ -810,9 +811,6 @@ u8 CALLBACK PADpoll(u8 value) { // Not sure about this. Forces wammy to be from 0 to 0x7F. // if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0; } - if (sum->sticks[0].vert) { - sum=sum; - } b1 -= ((sum->sticks[0].vert<=-128) << 4); b1 -= ((sum->sticks[0].horiz>=128) << 5); b1 -= ((sum->sticks[0].vert>=128) << 6); @@ -973,16 +971,14 @@ u8 CALLBACK PADpoll(u8 value) { break; // VIBRATION_TOGGLE case 0x4D: - { - if (query.lastByte>=3) { - if (value == 0) { - pad->vibrateI[0] = (u8)query.lastByte; - } - else if (value == 1) { - pad->vibrateI[1] = (u8)query.lastByte; - } - pad->vibrate[query.lastByte-2] = value; + if (query.lastByte>=3) { + if (value == 0) { + pad->vibrateI[0] = (u8)query.lastByte; } + else if (value == 1) { + pad->vibrateI[1] = (u8)query.lastByte; + } + pad->vibrate[query.lastByte-2] = value; } break; case 0x4F: @@ -1008,8 +1004,6 @@ u8 CALLBACK PADpoll(u8 value) { DEBUG_OUT(query.response[query.lastByte]); return query.response[query.lastByte]; } - DEBUG_OUT(0); - return 0; } // returns: 1 if supports pad1 @@ -1019,8 +1013,6 @@ u32 CALLBACK PADquery() { return 3; } -// extended funcs - //void CALLBACK PADgsDriverInfo(GSdriverInfo *info) { //} @@ -1041,16 +1033,17 @@ s32 CALLBACK PADtest() { return 0; } -DWORD CALLBACK HideWindow(void *) { - ShowWindow(hWnd, 0); - return 0; -} - -// For escape fillscreen hack. +// For escape fullscreen hack. This doesn't work when called from another thread, for some reason. +// That includes a new thread, independent of GS and PCSX2 thread, so use this to make sure it's +// called from the right spot. ExtraWndProcResult KillFullScreenProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - // Double check to prevent infinite recursion. - if (IsWindowMaximized(hWnd)) { + // Prevent infinite recursion. Could also just remove this function from the list, + // but CONTINUE_BLISSFULLY_AND_RELEASE_PROC is a safer way to do that. + static int inFunction = 0; + if (!inFunction) { + inFunction = 1; ShowWindow(hWnd, 0); + inFunction = 0; } return CONTINUE_BLISSFULLY_AND_RELEASE_PROC; } @@ -1083,12 +1076,11 @@ keyEvent* CALLBACK PADkeyEvent() { } if (ev.key == VK_F2 && ev.event == KEYPRESS) { - if (shiftDown) - saveStateIndex--; - else - saveStateIndex++; + saveStateIndex += 1 - 2*shiftDown; saveStateIndex = (saveStateIndex+10)%10; if (config.saveStateTitle) { + // GSDX only checks its window's message queue at certain points or something, so + // have to do this in another thread to prevent lockup. HANDLE hThread = CreateThread(0, 0, RenameWindowThreadProc, 0, 0, 0); if (hThread) CloseHandle(hThread); } diff --git a/plugins/LilyPad/LilyPad.rc b/plugins/LilyPad/LilyPad.rc index 122c4868ca..b0ca7a966a 100644 --- a/plugins/LilyPad/LilyPad.rc +++ b/plugins/LilyPad/LilyPad.rc @@ -227,7 +227,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN GROUPBOX "Input APIs",IDC_STATIC,7,6,410,131 GROUPBOX "Keyboard API",IDC_STATIC,16,16,192,61 - CONTROL "Windows messaging",IDC_KB_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,23,28,112,10 + CONTROL "Windows messaging (Recommended)",IDC_KB_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,23,28,134,10 CONTROL "Raw input (XP and later only)",IDC_KB_RAW,"Button",BS_AUTORADIOBUTTON,23,40,112,10 CONTROL "DirectInput",IDC_KB_DI,"Button",BS_AUTORADIOBUTTON,23,52,112,10 CONTROL "Disable (Intended for use with other pad plugins)",IDC_KB_DISABLE, @@ -262,15 +262,15 @@ BEGIN PUSHBUTTON "Test Device",ID_TEST,86,289,57,15 PUSHBUTTON "Refresh",ID_REFRESH,152,289,48,15 GROUPBOX "Hacks",IDC_STATIC,216,211,201,73 - CONTROL "Send escape on close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,223,113,10 - CONTROL "Exit emulator on close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,235,86,10 - CONTROL "Hide on fullscreen escape",IDC_ESCAPE_FULLSCREEN_HACK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,247,97,10 + CONTROL "Send escape on window close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,223,113,10 + CONTROL "Exit emulator on window close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,235,112,10 + CONTROL "Safe fullscreen exit on escape",IDC_ESCAPE_FULLSCREEN_HACK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,247,112,10 CONTROL "Always hide cursor",IDC_FORCE_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,259,71,10 CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,271,80,10 - CONTROL "Guitar Hero 2 Hack",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,333,223,76,10 - CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,333,235,62,10 - CONTROL "Save state in title",IDC_SAVE_STATE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,333,247,72,10 + CONTROL "Guitar Hero 2 Hack",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,223,76,10 + CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,235,62,10 + CONTROL "Save state # in title",IDC_SAVE_STATE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,247,79,10 GROUPBOX "Debugging",IDC_STATIC,216,285,79,25 CONTROL "Enable logging",IDC_DEBUG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,296,63,10 PUSHBUTTON "Save",ID_SAVE,369,295,48,15 diff --git a/plugins/LilyPad/LilyPad_VC2008.vcproj b/plugins/LilyPad/LilyPad_VC2008.vcproj index 2a45118b6f..11378ba97c 100644 --- a/plugins/LilyPad/LilyPad_VC2008.vcproj +++ b/plugins/LilyPad/LilyPad_VC2008.vcproj @@ -542,50 +542,6 @@ RelativePath="resource.h" > - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/plugins/LilyPad/RawInput.cpp b/plugins/LilyPad/RawInput.cpp index 181736635b..32d299a09d 100644 --- a/plugins/LilyPad/RawInput.cpp +++ b/plugins/LilyPad/RawInput.cpp @@ -112,7 +112,6 @@ public: }; static POINT rawOrigCursorPos; -static POINT rawCenter; class RawInputMouse : public WindowsMouse { public: @@ -146,12 +145,6 @@ public: Deactivate(); return 0; } - RECT r; - // No need to clip cursor, since I seem to have complete control of buttons. - GetWindowRect(hWnd, &r); - rawCenter.x = (r.left + r.right)/2; - rawCenter.y = (r.top + r.bottom)/2; - SetCursorPos(rawCenter.x, rawCenter.y); } AllocState(); @@ -213,13 +206,12 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l button++; buttons >>= 2; } - if (in.data.mouse.usButtonFlags & 0x400) { + if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData)/WHEEL_DELTA); } if (in.data.mouse.lLastX || in.data.mouse.lLastY) { rim->UpdateAxis(0, in.data.mouse.lLastX); rim->UpdateAxis(1, in.data.mouse.lLastY); - SetCursorPos(rawCenter.x, rawCenter.y); } } } diff --git a/plugins/LilyPad/WindowsMessaging.cpp b/plugins/LilyPad/WindowsMessaging.cpp index fc8d26c2e5..dd36b70eb3 100644 --- a/plugins/LilyPad/WindowsMessaging.cpp +++ b/plugins/LilyPad/WindowsMessaging.cpp @@ -85,6 +85,7 @@ public: GetCursorPos(&origCursorPos); active = 1; + RECT r; GetWindowRect(hWnd, &r); ClipCursor(&r); @@ -137,6 +138,7 @@ ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, return NO_WND_PROC; } else if (uMsg == WM_ACTIVATE) { + // Not really needed, but doesn't hurt. memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls); } } @@ -177,8 +179,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_KILLFOCUS) { + // 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) { wmm->Deactivate(); }//*/ }