mirror of
https://github.com/libretro/pcsx2.git
synced 2024-12-23 18:24:53 +00:00
LilyPad: Fixed a potential threading issue when read input in gs thread is disabled. Odds of the issue being a problem, while perhaps significantly greater than 1/<number of atoms in the universe>, weren't too high.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1025 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
457b78e70e
commit
256d32037c
@ -840,9 +840,7 @@ int LoadSettings(int force, wchar_t *file) {
|
||||
}
|
||||
|
||||
if (config.debug) {
|
||||
HANDLE hFile = CreateFileA("logs\\padLog.txt", GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
|
||||
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
|
||||
else CreateDirectory(L"logs", 0);
|
||||
CreateDirectory(L"logs", 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1472,7 +1470,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
||||
if (GetBinding(port, slot, selIndex, dev, b, ffb)) {
|
||||
selected = 0xFF;
|
||||
InitInfo info = {0, hWndProp, hWnd, GetDlgItem(hWnd, cmd)};
|
||||
EatWndProc(info.hWndButton, DoNothingWndProc);
|
||||
EatWndProc(info.hWndButton, DoNothingWndProc, 0);
|
||||
for (int i=0; i<dm->numDevices; i++) {
|
||||
if (dm->devices[i] != dev) {
|
||||
dm->DisableDevice(i);
|
||||
@ -1507,7 +1505,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
||||
}
|
||||
|
||||
InitInfo info = {selected==0x7F, hWndProp, hWnd, GetDlgItem(hWnd, cmd)};
|
||||
EatWndProc(info.hWndButton, DoNothingWndProc);
|
||||
EatWndProc(info.hWndButton, DoNothingWndProc, 0);
|
||||
int w = timeGetTime();
|
||||
dm->Update(&info);
|
||||
dm->PostRead();
|
||||
|
@ -56,9 +56,7 @@ Device::Device(DeviceAPI api, DeviceType d, const wchar_t *displayName, const wc
|
||||
void Device::FreeState() {
|
||||
if (virtualControlState) free(virtualControlState);
|
||||
virtualControlState = 0;
|
||||
if (oldVirtualControlState) free(oldVirtualControlState);
|
||||
oldVirtualControlState = 0;
|
||||
if (physicalControlState) free(physicalControlState);
|
||||
physicalControlState = 0;
|
||||
}
|
||||
|
||||
@ -127,9 +125,9 @@ void Device::AddFFAxis(const wchar_t *displayName, int id) {
|
||||
|
||||
void Device::AllocState() {
|
||||
FreeState();
|
||||
virtualControlState = (int*) calloc(numVirtualControls, sizeof(int));
|
||||
oldVirtualControlState = (int*) calloc(numVirtualControls, sizeof(int));
|
||||
physicalControlState = (int*) calloc(numPhysicalControls, sizeof(int));
|
||||
virtualControlState = (int*) calloc(numVirtualControls + numVirtualControls + numPhysicalControls, sizeof(int));
|
||||
oldVirtualControlState = virtualControlState + numVirtualControls;
|
||||
physicalControlState = oldVirtualControlState + numVirtualControls;
|
||||
}
|
||||
|
||||
void Device::FlipState() {
|
||||
@ -213,6 +211,9 @@ VirtualControl *Device::GetVirtualControl(unsigned int uid) {
|
||||
}
|
||||
|
||||
VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlIndex) {
|
||||
// Not really necessary, as always call AllocState when activated, but doesn't hurt.
|
||||
FreeState();
|
||||
|
||||
if (numVirtualControls % 16 == 0) {
|
||||
virtualControls = (VirtualControl*) realloc(virtualControls, sizeof(VirtualControl)*(numVirtualControls+16));
|
||||
}
|
||||
@ -226,7 +227,9 @@ VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlI
|
||||
}
|
||||
|
||||
PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name) {
|
||||
// Not really necessary, as always call AllocState when activated, but doesn't hurt.
|
||||
FreeState();
|
||||
|
||||
if (numPhysicalControls % 16 == 0) {
|
||||
physicalControls = (PhysicalControl*) realloc(physicalControls, sizeof(PhysicalControl)*(numPhysicalControls+16));
|
||||
}
|
||||
|
@ -43,9 +43,9 @@ public:
|
||||
InitInfo *info = (InitInfo*) d;
|
||||
binding = info->bindingIgnore;
|
||||
if (info->hWndButton)
|
||||
EatWndProc(info->hWndButton, StartHooksWndProc);
|
||||
EatWndProc(info->hWndButton, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
else
|
||||
EatWndProc(info->hWnd, StartHooksWndProc);
|
||||
EatWndProc(info->hWnd, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
InitState();
|
||||
ikhd = this;
|
||||
active = 1;
|
||||
|
@ -63,6 +63,17 @@ int IsWindowMaximized (HWND hWnd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DEBUG_TEXT_OUT(const char *text) {
|
||||
if (config.debug) {
|
||||
HANDLE hFile = CreateFileA("logs\\padLog.txt", FILE_APPEND_DATA, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0);
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
DWORD junk;
|
||||
WriteFile(hFile, text, strlen(text), &junk, 0);
|
||||
CloseHandle(hFile);;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DEBUG_NEW_SET() {
|
||||
if (config.debug && bufSize>1) {
|
||||
HANDLE hFile = CreateFileA("logs\\padLog.txt", FILE_APPEND_DATA, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0);
|
||||
@ -600,6 +611,7 @@ char* CALLBACK PS2EgetLibName(void) {
|
||||
//}
|
||||
|
||||
void CALLBACK PADshutdown() {
|
||||
DEBUG_TEXT_OUT("LilyPad shutdown.\n\n");
|
||||
for (int i=0; i<8; i++)
|
||||
pads[i&1][i>>1].initialized = 0;
|
||||
portInitialized[0] = portInitialized[1] = 0;
|
||||
@ -664,9 +676,10 @@ s32 CALLBACK PADinit(u32 flags) {
|
||||
}
|
||||
int port = (flags & 3);
|
||||
if (port == 3) {
|
||||
if (PADinit(1)) return -1;
|
||||
if (PADinit(1) == -1) return -1;
|
||||
return PADinit(2);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
||||
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
|
||||
@ -686,6 +699,8 @@ s32 CALLBACK PADinit(u32 flags) {
|
||||
ClearKeyQueue();
|
||||
// Just in case, when resuming emulation.
|
||||
ReleaseModifierKeys();
|
||||
|
||||
DEBUG_TEXT_OUT("LilyPad initialized\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -806,6 +821,7 @@ DWORD WINAPI MaximizeWindowThreadProc(void *lpParameter) {
|
||||
|
||||
s32 CALLBACK PADopen(void *pDsp) {
|
||||
if (openCount++) return 0;
|
||||
DEBUG_TEXT_OUT("LilyPad opened\n\n");
|
||||
|
||||
// Not really needed, shouldn't do anything.
|
||||
if (LoadSettings()) return -1;
|
||||
@ -825,12 +841,12 @@ s32 CALLBACK PADopen(void *pDsp) {
|
||||
hWnd = GetParent (hWnd);
|
||||
// Implements most hacks, as well as enabling/disabling mouse
|
||||
// capture when focus changes.
|
||||
if (!EatWndProc(hWnd, HackWndProc)) {
|
||||
if (!EatWndProc(hWnd, HackWndProc, 0)) {
|
||||
openCount = 0;
|
||||
return -1;
|
||||
}
|
||||
if (config.forceHide) {
|
||||
EatWndProc(hWnd, HideCursorProc);
|
||||
EatWndProc(hWnd, HideCursorProc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -864,6 +880,8 @@ s32 CALLBACK PADopen(void *pDsp) {
|
||||
|
||||
void CALLBACK PADclose() {
|
||||
if (openCount && !--openCount) {
|
||||
DEBUG_TEXT_OUT("LilyPad closed\n\n");
|
||||
deviceUpdateQueued = 0;
|
||||
dm->ReleaseInput();
|
||||
ReleaseEatenProc();
|
||||
hWnd = 0;
|
||||
@ -1011,6 +1029,7 @@ u8 CALLBACK PADpoll(u8 value) {
|
||||
break;
|
||||
// QUERY_DS2_ANALOG_MODE
|
||||
case 0x41:
|
||||
// Right? Wrong? No clue.
|
||||
if (pad->mode == MODE_DIGITAL) {
|
||||
queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0;
|
||||
queryMaskMode[6] = 0x00;
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
}
|
||||
active = 1;
|
||||
if (!rawKeyboardActivatedCount++) {
|
||||
if (!rawMouseActivatedCount && !EatWndProc(hWnd, RawInputWndProc)) {
|
||||
if (!rawMouseActivatedCount && !EatWndProc(hWnd, RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
@ -134,7 +134,7 @@ public:
|
||||
// lines.
|
||||
if (!rawMouseActivatedCount++) {
|
||||
GetMouseCapture(hWnd);
|
||||
if (!rawKeyboardActivatedCount && !EatWndProc(hWnd, RawInputWndProc)) {
|
||||
if (!rawKeyboardActivatedCount && !EatWndProc(hWnd, RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
@ -234,15 +234,14 @@ int InitializeRawInput() {
|
||||
if (RawInputFailed) return 0;
|
||||
if (!pGetRawInputDeviceList) {
|
||||
HMODULE user32 = LoadLibrary(L"user32.dll");
|
||||
if (user32) {
|
||||
if (!(pRegisterRawInputDevices = (_RegisterRawInputDevices) GetProcAddress(user32, "RegisterRawInputDevices")) ||
|
||||
!(pGetRawInputDeviceInfo = (_GetRawInputDeviceInfo) GetProcAddress(user32, "GetRawInputDeviceInfoW")) ||
|
||||
!(pGetRawInputData = (_GetRawInputData) GetProcAddress(user32, "GetRawInputData")) ||
|
||||
!(pGetRawInputDeviceList = (_GetRawInputDeviceList) GetProcAddress(user32, "GetRawInputDeviceList"))) {
|
||||
FreeLibrary(user32);
|
||||
RawInputFailed = 1;
|
||||
return 0;
|
||||
}
|
||||
if (!user32 ||
|
||||
!(pRegisterRawInputDevices = (_RegisterRawInputDevices) GetProcAddress(user32, "RegisterRawInputDevices")) ||
|
||||
!(pGetRawInputDeviceInfo = (_GetRawInputDeviceInfo) GetProcAddress(user32, "GetRawInputDeviceInfoW")) ||
|
||||
!(pGetRawInputData = (_GetRawInputData) GetProcAddress(user32, "GetRawInputData")) ||
|
||||
!(pGetRawInputDeviceList = (_GetRawInputDeviceList) GetProcAddress(user32, "GetRawInputDeviceList"))) {
|
||||
FreeLibrary(user32);
|
||||
RawInputFailed = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -288,7 +287,7 @@ void EnumRawInputDevices() {
|
||||
|
||||
wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID+3);
|
||||
if (temp) *temp = 0;
|
||||
displayName[0] = 0;
|
||||
int haveDescription = 0;
|
||||
HKEY hKey;
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey)) {
|
||||
DWORD type;
|
||||
@ -300,16 +299,17 @@ void EnumRawInputDevices() {
|
||||
else temp2++;
|
||||
// Could do without this, but more effort than it's worth.
|
||||
wcscpy(keyName, temp2);
|
||||
haveDescription = 1;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
if (list[i].dwType == RIM_TYPEKEYBOARD) {
|
||||
if (!displayName[0]) wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
|
||||
if (!haveDescription) wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
|
||||
else wsprintfW(displayName, L"Raw KB: %s", keyName);
|
||||
dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID));
|
||||
}
|
||||
else if (list[i].dwType == RIM_TYPEMOUSE) {
|
||||
if (!displayName[0]) wsprintfW(displayName, L"Raw Mouse %i", mouseCount++);
|
||||
if (!haveDescription) wsprintfW(displayName, L"Raw Mouse %i", mouseCount++);
|
||||
else wsprintfW(displayName, L"Raw MS: %s", keyName);
|
||||
dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID));
|
||||
}
|
||||
|
@ -28,9 +28,8 @@ public:
|
||||
HWND hWnd = info->hWnd;
|
||||
if (info->hWndButton) {
|
||||
hWnd = info->hWndButton;
|
||||
// hWndDlg = info->hWnd;
|
||||
}
|
||||
if (!wmm && !EatWndProc(hWnd, WindowsMessagingWndProc)) {
|
||||
if (!wmm && !EatWndProc(hWnd, WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
@ -43,14 +42,13 @@ public:
|
||||
}
|
||||
|
||||
void Deactivate() {
|
||||
FreeState();
|
||||
if (active) {
|
||||
if (!wmm)
|
||||
ReleaseExtraProc(WindowsMessagingWndProc);
|
||||
active = 0;
|
||||
wmk = 0;
|
||||
active = 0;
|
||||
FreeState();
|
||||
}
|
||||
// hWndDlg = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -75,7 +73,7 @@ public:
|
||||
hWnd = info->hWndButton;
|
||||
}
|
||||
|
||||
if (!wmk && !EatWndProc(hWnd, WindowsMessagingWndProc)) {
|
||||
if (!wmk && !EatWndProc(hWnd, WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
@ -90,13 +88,13 @@ public:
|
||||
}
|
||||
|
||||
void Deactivate() {
|
||||
FreeState();
|
||||
if (active) {
|
||||
ReleaseMouseCapture();
|
||||
if (!wmk)
|
||||
ReleaseExtraProc(WindowsMessagingWndProc);
|
||||
active = 0;
|
||||
ReleaseMouseCapture();
|
||||
wmm = 0;
|
||||
active = 0;
|
||||
FreeState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -2,7 +2,13 @@
|
||||
|
||||
static HWND hWndEaten = 0;
|
||||
static WNDPROC eatenWndProc = 0;
|
||||
static ExtraWndProc* extraProcs = 0;
|
||||
|
||||
struct ExtraWndProcInfo {
|
||||
ExtraWndProc proc;
|
||||
DWORD flags;
|
||||
};
|
||||
|
||||
static ExtraWndProcInfo* extraProcs = 0;
|
||||
static int numExtraProcs = 0;
|
||||
|
||||
void ReleaseExtraProc(ExtraWndProc proc) {
|
||||
@ -13,7 +19,7 @@ void ReleaseExtraProc(ExtraWndProc proc) {
|
||||
if (hMutex) WaitForSingleObject(hMutex, 100);
|
||||
|
||||
for (int i=0; i<numExtraProcs; i++) {
|
||||
if (extraProcs[i] == proc) {
|
||||
if (extraProcs[i].proc == proc) {
|
||||
extraProcs[i] = extraProcs[--numExtraProcs];
|
||||
break;
|
||||
}
|
||||
@ -35,9 +41,10 @@ void ReleaseExtraProc(ExtraWndProc proc) {
|
||||
}
|
||||
|
||||
void ReleaseEatenProc() {
|
||||
while (numExtraProcs) ReleaseExtraProc(extraProcs[0]);
|
||||
while (numExtraProcs) ReleaseExtraProc(extraProcs[0].proc);
|
||||
}
|
||||
|
||||
extern int deviceUpdateQueued;
|
||||
LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
ExtraWndProcResult res = CONTINUE_BLISSFULLY;
|
||||
LRESULT out = 0;
|
||||
@ -45,16 +52,23 @@ LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
|
||||
if (uMsg == WM_GETDLGCODE) {
|
||||
return DLGC_WANTALLKEYS | CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
for (int i=0; i<numExtraProcs; i++) {
|
||||
ExtraWndProcResult res2 = extraProcs[i](hWnd, uMsg, wParam, lParam, &out);
|
||||
// Note: Second bit of deviceUpdateQueued is only set when I receive a device change
|
||||
// notification, which is handled in the GS thread in one of the extraProcs, so this
|
||||
// is all I need to prevent bad things from happening while updating devices. No mutex needed.
|
||||
if ((deviceUpdateQueued&2) && (extraProcs[i].flags & EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) continue;
|
||||
|
||||
ExtraWndProcResult res2 = extraProcs[i].proc(hWnd, uMsg, wParam, lParam, &out);
|
||||
if (res2 != res) {
|
||||
if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC) {
|
||||
ReleaseExtraProc(extraProcs[i]);
|
||||
ReleaseExtraProc(extraProcs[i].proc);
|
||||
i--;
|
||||
}
|
||||
else if (res2 > res) res = res2;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != NO_WND_PROC) {
|
||||
if (out == WM_DESTROY) {
|
||||
ReleaseEatenProc();
|
||||
@ -68,7 +82,7 @@ LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
|
||||
|
||||
int EatWndProc(HWND hWnd, ExtraWndProc proc) {
|
||||
int EatWndProc(HWND hWnd, ExtraWndProc proc, DWORD flags) {
|
||||
// Probably isn't needed, but just in case...
|
||||
// Creating and destroying the mutex adds some inefficiency,
|
||||
// but this function is only called on emulation start and on focus/unfocus.
|
||||
@ -83,8 +97,10 @@ int EatWndProc(HWND hWnd, ExtraWndProc proc) {
|
||||
hWndEaten = hWnd;
|
||||
}
|
||||
if (hWndEaten == hWnd) {
|
||||
extraProcs = (ExtraWndProc*) realloc(extraProcs, sizeof(ExtraWndProc)*(numExtraProcs+1));
|
||||
extraProcs[numExtraProcs++] = proc;
|
||||
extraProcs = (ExtraWndProcInfo*) realloc(extraProcs, sizeof(ExtraWndProcInfo)*(numExtraProcs+1));
|
||||
extraProcs[numExtraProcs].proc = proc;
|
||||
extraProcs[numExtraProcs].flags = flags;
|
||||
numExtraProcs++;
|
||||
}
|
||||
|
||||
if (hMutex) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "Global.h"
|
||||
|
||||
#define EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES 1
|
||||
|
||||
/* Need this to let window be subclassed multiple times but still clean up nicely.
|
||||
*/
|
||||
enum ExtraWndProcResult {
|
||||
@ -11,7 +13,7 @@ enum ExtraWndProcResult {
|
||||
};
|
||||
|
||||
typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *out);
|
||||
int EatWndProc(HWND hWnd, ExtraWndProc proc);
|
||||
int EatWndProc(HWND hWnd, ExtraWndProc proc, DWORD flags);
|
||||
|
||||
void ReleaseExtraProc(ExtraWndProc proc);
|
||||
void ReleaseEatenProc();
|
||||
|
Loading…
Reference in New Issue
Block a user