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
This commit is contained in:
mattmenke 2009-03-31 08:15:38 +00:00
parent 8b3c30d2ce
commit f5f3ff97a5
7 changed files with 133 additions and 68 deletions

View File

@ -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);
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,13 +1889,23 @@ 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;
}
}
else {
for (int i=0; i<dm->numDevices; i++) {
free(dm->devices[i]->pads[port1][slot1].bindings);
for (int j=0; j<dm->devices[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);
}
}
}
}
break;
default:
break;
@ -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;

View File

@ -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:
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;

View File

@ -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

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);