SSSPSX: Updated to v1.7, fixed savestate/freeze callback bug that caused the public version to crash in 0.9.6 betas.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2379 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-12-22 03:08:16 +00:00
parent 74c73295f4
commit 203979c16b
6 changed files with 104 additions and 81 deletions

View File

@ -16,7 +16,7 @@
static const unsigned char version = 0x0002; static const unsigned char version = 0x0002;
static const unsigned char revision = 1; static const unsigned char revision = 1;
static const unsigned char build = 6; static const unsigned char build = 7;
static const unsigned char buildfix = 1; static const unsigned char buildfix = 1;
HMODULE hInstance; HMODULE hInstance;
@ -40,6 +40,13 @@ struct EnterScopedSection
}; };
static struct
{
keyEvent ev;
u8 state[2][256];
} save;
static struct static struct
{ {
Config config; Config config;
@ -98,17 +105,15 @@ static bool ReleaseDirectInput (void)
int index = 4; int index = 4;
while (index--) while (index--)
{ {
if (global.pDEffect[index][0]) int index2 = 2;
while (index2--)
{ {
global.pDEffect[index][0]->Unload(); if (global.pDEffect[index][index2])
global.pDEffect[index][0]->Release(); {
global.pDEffect[index][0] = NULL; global.pDEffect[index][index2]->Unload();
} global.pDEffect[index][index2]->Release();
if (global.pDEffect[index][1]) global.pDEffect[index][index2] = NULL;
{ }
global.pDEffect[index][1]->Unload();
global.pDEffect[index][1]->Release();
global.pDEffect[index][1] = NULL;
} }
if (global.pDDevice[index]) if (global.pDDevice[index])
{ {
@ -235,18 +240,10 @@ static bool SetDeviceForceS (int pad, DWORD force)
InitDirectInput(); InitDirectInput();
if (global.pDEffect[pad][0]) if (global.pDEffect[pad][0])
{ {
if ( force == 0) {
if (FAILED (global.pDEffect[pad][0]->Stop())) {
AcquireDevice (global.pDDevice[pad]);
if (FAILED (global.pDEffect[pad][0]->Stop()))
return ReleaseDirectInput();
}
return TRUE;
}
LONG rglDirection[2] = { 0, 0 }; LONG rglDirection[2] = { 0, 0 };
DIPERIODIC per; DIPERIODIC per;
rglDirection[0] = force; rglDirection[0] = 0;
rglDirection[1] = force; rglDirection[1] = 1;
per.dwMagnitude = force; per.dwMagnitude = force;
per.dwPeriod = (DWORD) (0.01 * DI_SECONDS); per.dwPeriod = (DWORD) (0.01 * DI_SECONDS);
per.lOffset = 0; per.lOffset = 0;
@ -261,6 +258,14 @@ static bool SetDeviceForceS (int pad, DWORD force)
eff.lpvTypeSpecificParams = &per; eff.lpvTypeSpecificParams = &per;
if (FAILED (global.pDEffect[pad][0]->SetParameters (&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START))) if (FAILED (global.pDEffect[pad][0]->SetParameters (&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START)))
return ReleaseDirectInput(); return ReleaseDirectInput();
if (FAILED (global.pDEffect[pad][0]->Stop()))
{
AcquireDevice (global.pDDevice[pad]);
if (FAILED (global.pDEffect[pad][0]->Stop()))
return ReleaseDirectInput();
}
if (force == 0)
return TRUE;
if (FAILED (global.pDEffect[pad][0]->Start (1, 0))) if (FAILED (global.pDEffect[pad][0]->Start (1, 0)))
{ {
AcquireDevice (global.pDDevice[pad]); AcquireDevice (global.pDDevice[pad]);
@ -277,18 +282,10 @@ static bool SetDeviceForceB (int pad, DWORD force)
InitDirectInput(); InitDirectInput();
if (global.pDEffect[pad][1]) if (global.pDEffect[pad][1])
{ {
if ( force == 0) {
if (FAILED (global.pDEffect[pad][1]->Stop())) {
AcquireDevice (global.pDDevice[pad]);
if (FAILED (global.pDEffect[pad][1]->Stop()))
return ReleaseDirectInput();
}
return TRUE;
}
LONG rglDirection[2] = { 0, 0 }; LONG rglDirection[2] = { 0, 0 };
DICONSTANTFORCE cf; DICONSTANTFORCE cf;
rglDirection[0] = force; rglDirection[0] = 1;
rglDirection[1] = force; rglDirection[1] = 0;
cf.lMagnitude = force; cf.lMagnitude = force;
DIEFFECT eff; DIEFFECT eff;
eff.dwSize = sizeof (DIEFFECT); eff.dwSize = sizeof (DIEFFECT);
@ -300,6 +297,14 @@ static bool SetDeviceForceB (int pad, DWORD force)
eff.lpvTypeSpecificParams = &cf; eff.lpvTypeSpecificParams = &cf;
if (FAILED (global.pDEffect[pad][1]->SetParameters (&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START))) if (FAILED (global.pDEffect[pad][1]->SetParameters (&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START)))
return ReleaseDirectInput(); return ReleaseDirectInput();
if (FAILED (global.pDEffect[pad][1]->Stop()))
{
AcquireDevice (global.pDDevice[pad]);
if (FAILED (global.pDEffect[pad][1]->Stop()))
return ReleaseDirectInput();
}
if (force == 0)
return TRUE;
if (FAILED (global.pDEffect[pad][1]->Start (1, 0))) if (FAILED (global.pDEffect[pad][1]->Start (1, 0)))
{ {
AcquireDevice (global.pDDevice[pad]); AcquireDevice (global.pDDevice[pad]);
@ -450,7 +455,7 @@ static void UpdateState (const int pad)
} }
else else
{ {
const int joypad = ((key & 0xfff) / 100); const int joypad = ((key & 0xfff) / 0x100);
if (flag_joypad[joypad] == FALSE) if (flag_joypad[joypad] == FALSE)
{ {
flag_joypad[joypad] = TRUE; flag_joypad[joypad] = TRUE;
@ -485,7 +490,7 @@ static void UpdateState (const int pad)
} }
/* Small Motor */ /* Small Motor */
const int vib0 = global.padVibF[pad][0] ? 10000 : 0; const int vib0 = global.padVibF[pad][0] ? 2000 : 0;
if ((global.padVibF[pad][2] != vib0) && (global.padVibC[pad] >= 0)) if ((global.padVibF[pad][2] != vib0) && (global.padVibC[pad] >= 0))
{ {
global.padVibF[pad][2] = vib0; global.padVibF[pad][2] = vib0;
@ -852,21 +857,21 @@ static u8 get_analog (const int key)
static u8 get_pressure (const DWORD now, const DWORD press) static u8 get_pressure (const DWORD now, const DWORD press)
{ {
/*if (press == 0) if (press == 0)
return 0; return 0;
return (u8)((now - press > 2550) ? 255 : (now - press) / 10);*/ return (u8)((now - press > 2550) ? 255 : (now - press) / 10);
return 255;
} }
// Should be called from the thread that owns our hwnd, but older versions of PCSX2
// don't always follow that rule. Supposedly DInput is happiest called from the
// thread that owns the hwnd, but on the other hand it doesn't really seem to care
// in practice. So a basic mutex lock should do the trick.
void CALLBACK PADupdate (int pad) void CALLBACK PADupdate (int pad)
{ {
EnterScopedSection scoped_lock( update_lock ); // PADupdate should be called by the emulator from the thread that owns our hwnd, but
UpdateState( 0 ); // older versions of PCSX2 don't always follow that rule. I suspect this call was
UpdateState( 1 ); // added to the PAD api because supposedly DInput is happiest called from the thread
// that owns the hwnd (although it doesn't seem to care in practice).
// [TODO] SSSPSX really should do all it's DInput pooling/updating here, instead of
// in PADpoll, just for the sake of obeying thread affinity suggested guidelines.
// I'm not quite sure how to do that and still have it work though. --air
} }
// Called from the context of the EE thread. // Called from the context of the EE thread.
@ -892,11 +897,11 @@ u8 CALLBACK PADpoll (const u8 value)
case 0x42: case 0x42:
case 0x43: case 0x43:
{ {
EnterScopedSection scoped_lock( update_lock ); //EnterScopedSection scoped_lock( update_lock );
//if (value == 0x42) UpdateState (pad); if (value == 0x42) UpdateState (pad);
global.cmdLen = 2 + 2 * (global.padID[pad] & 0x0f); global.cmdLen = 2 + 2 * (global.padID[pad] & 0x0f);
buf[1] = global.padModeC[pad] ? 0x00 : 0x5a; buf[1] = global.padModeC[pad] ? 0x00 : 0x5a;
*(u16*)&buf[2] = global.padStat[pad]; (u16&)buf[2] = global.padStat[pad];
if (value == 0x43 && global.padModeE[pad]) if (value == 0x43 && global.padModeE[pad])
{ {
buf[4] = 0; buf[4] = 0;
@ -958,7 +963,7 @@ u8 CALLBACK PADpoll (const u8 value)
return 0xf3; return 0xf3;
case 0x4f: case 0x4f:
{ {
EnterScopedSection scoped_lock( update_lock ); //EnterScopedSection scoped_lock( update_lock );
global.padID[pad] = 0x79; global.padID[pad] = 0x79;
global.padMode2[pad] = 1; global.padMode2[pad] = 1;
global.cmdLen = sizeof (cmd4f); global.cmdLen = sizeof (cmd4f);
@ -968,7 +973,7 @@ u8 CALLBACK PADpoll (const u8 value)
} }
} }
EnterScopedSection scoped_lock( update_lock ); //EnterScopedSection scoped_lock( update_lock );
switch (global.curCmd) switch (global.curCmd)
{ {
@ -1052,7 +1057,7 @@ typedef struct
unsigned char reserved[91]; unsigned char reserved[91];
} PadDataS; } PadDataS;
long PADreadPort1 (PadDataS* pads) long CALLBACK PADreadPort1 (PadDataS* pads)
{ {
memset (pads, 0, sizeof (PadDataS)); memset (pads, 0, sizeof (PadDataS));
if ((global.padID[0] & 0xf0) == 0x40) if ((global.padID[0] & 0xf0) == 0x40)
@ -1069,7 +1074,7 @@ long PADreadPort1 (PadDataS* pads)
return 0; return 0;
} }
long PADreadPort2 (PadDataS* pads) long CALLBACK PADreadPort2 (PadDataS* pads)
{ {
memset (pads, 0, sizeof (PadDataS)); memset (pads, 0, sizeof (PadDataS));
if ((global.padID[1] & 0xf0) == 0x40) if ((global.padID[1] & 0xf0) == 0x40)
@ -1088,19 +1093,18 @@ long PADreadPort2 (PadDataS* pads)
keyEvent* CALLBACK PADkeyEvent (void) keyEvent* CALLBACK PADkeyEvent (void)
{ {
static keyEvent ev;
static u8 state[2][256];
if (n_open) if (n_open)
{ {
memcpy (state[0], state[1], sizeof (state[0])); memcpy (save.state[0], save.state[1], sizeof (save.state[0]));
GetKeyState (state[1]); GetKeyState (save.state[1]);
for (int cnt = 0; cnt < 256; cnt++) for (int cnt = 0; cnt < 256; cnt++)
{ {
if (~state[0][cnt] & state[1][cnt] & 0x80) if ((~save.state[0][cnt] & save.state[1][cnt] & 0x80) ||
(save.state[0][cnt] & ~save.state[1][cnt] & 0x80))
{ {
ev.event = (state[1][cnt] & 0x80) ? 1 : 2; save.ev.evt = (save.state[1][cnt] & 0x80) ? 1 : 2;
ev.key = MapVirtualKey (cnt, 1); save.ev.key = MapVirtualKey (cnt, 1);
return &ev; return &save.ev;
} }
} }
} }
@ -1120,7 +1124,7 @@ void CALLBACK PADconfigure (void)
void CALLBACK PADabout (void) void CALLBACK PADabout (void)
{ {
MessageBox (GetActiveWindow(), "Copyright (C) 2004-2005 Nagisa\nVersion 1.6.1\n\nModified by Jake Stine for PCSX2 0.9.7 compatibility.", MessageBox (GetActiveWindow(), "Copyright (C) 2004-2006 Nagisa\nVersion 1.7.1\n\nModified by Jake Stine for PCSX2 0.9.7 compatibility.",
"SSSPSX PAD plugin", MB_OK | MB_SETFOREGROUND); "SSSPSX PAD plugin", MB_OK | MB_SETFOREGROUND);
} }
@ -1134,16 +1138,33 @@ void CALLBACK PADsetSettingsDir(const char* dir)
s_strIniPath = (dir==NULL) ? "inis/" : dir; s_strIniPath = (dir==NULL) ? "inis/" : dir;
} }
//#ifdef _WIN64 // Returns 0 on success, -1 on error.
s32 CALLBACK PADfreeze (int mode, freezeData *data)
{
switch (mode)
{
case FREEZE_SIZE:
data->size = 0;
break;
case FREEZE_LOAD:
break;
case FREEZE_SAVE:
break;
}
return 0;
}
BOOL APIENTRY DllMain(HMODULE hInst, DWORD dwReason, LPVOID lpReserved) BOOL APIENTRY DllMain(HMODULE hInst, DWORD dwReason, LPVOID lpReserved)
{ {
hInstance = hInst; hInstance = hInst;
return TRUE; return TRUE;
} }
//#else
BOOL APIENTRY EntryPoint (HMODULE hInst, DWORD dwReason, LPVOID lpReserved) BOOL APIENTRY EntryPoint (HMODULE hInst, DWORD dwReason, LPVOID lpReserved)
{ {
hInstance = hInst; hInstance = hInst;
return TRUE; return TRUE;
} }
//#endif

View File

@ -20,4 +20,5 @@ EXPORTS
PADconfigure @17 PADconfigure @17
PADtest @18 PADtest @18
PADabout @19 PADabout @19
PADsetSettingsDir @20 ;PADfreeze @20
PADsetSettingsDir @21

View File

@ -20,6 +20,7 @@
#define __PAD_H__ #define __PAD_H__
#include "PadSSSPSXres.h" #include "PadSSSPSXres.h"
#include "PS2Edefs.h"
typedef __int8 s8; typedef __int8 s8;
typedef __int16 s16; typedef __int16 s16;
@ -31,15 +32,10 @@ typedef unsigned __int16 u16;
typedef unsigned __int32 u32; typedef unsigned __int32 u32;
typedef unsigned __int64 u64; typedef unsigned __int64 u64;
typedef struct
{
u32 key;
u32 event;
} keyEvent;
typedef struct typedef struct
{ {
u32 keys[2][21]; u32 keys[2][21];
} Config; } Config;
#endif #endif

View File

@ -27,18 +27,18 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
// TEXTINCLUDE // TEXTINCLUDE
// //
1 TEXTINCLUDE 1 TEXTINCLUDE
BEGIN BEGIN
"PadSSSPSXres.h\0" "PadSSSPSXres.h\0"
END END
2 TEXTINCLUDE 2 TEXTINCLUDE
BEGIN BEGIN
"#include ""afxres.h""\r\n" "#include ""afxres.h""\r\n"
"\0" "\0"
END END
3 TEXTINCLUDE 3 TEXTINCLUDE
BEGIN BEGIN
"\r\n" "\r\n"
"\0" "\0"
@ -83,22 +83,22 @@ BEGIN
EDITTEXT IDC_EMODE,186,78,72,12,ES_READONLY | NOT WS_TABSTOP, EDITTEXT IDC_EMODE,186,78,72,12,ES_READONLY | NOT WS_TABSTOP,
WS_EX_TRANSPARENT WS_EX_TRANSPARENT
PUSHBUTTON "R2",IDC_BR2,318,24,72,12,NOT WS_TABSTOP PUSHBUTTON "R2",IDC_BR2,318,24,72,12,NOT WS_TABSTOP
EDITTEXT IDC_ER2,318,36,72,12,ES_AUTOHSCROLL | ES_READONLY | NOT EDITTEXT IDC_ER2,318,36,72,12,ES_AUTOHSCROLL | ES_READONLY | NOT
WS_TABSTOP WS_TABSTOP
PUSHBUTTON "R1",IDC_BR1,318,48,72,12,NOT WS_TABSTOP PUSHBUTTON "R1",IDC_BR1,318,48,72,12,NOT WS_TABSTOP
EDITTEXT IDC_ER1,318,60,72,12,ES_AUTOHSCROLL | ES_READONLY | NOT EDITTEXT IDC_ER1,318,60,72,12,ES_AUTOHSCROLL | ES_READONLY | NOT
WS_TABSTOP WS_TABSTOP
PUSHBUTTON "Triangle",IDC_BTRIANGLE,318,78,72,12,NOT WS_TABSTOP PUSHBUTTON "Triangle",IDC_BTRIANGLE,318,78,72,12,NOT WS_TABSTOP
EDITTEXT IDC_ETRIANGLE,318,90,72,12,ES_AUTOHSCROLL | ES_READONLY | EDITTEXT IDC_ETRIANGLE,318,90,72,12,ES_AUTOHSCROLL | ES_READONLY |
NOT WS_TABSTOP NOT WS_TABSTOP
PUSHBUTTON "Square",IDC_BSQUARE,276,102,72,12,NOT WS_TABSTOP PUSHBUTTON "Square",IDC_BSQUARE,276,102,72,12,NOT WS_TABSTOP
EDITTEXT IDC_ESQUARE,276,114,72,12,ES_AUTOHSCROLL | ES_READONLY | EDITTEXT IDC_ESQUARE,276,114,72,12,ES_AUTOHSCROLL | ES_READONLY |
NOT WS_TABSTOP NOT WS_TABSTOP
PUSHBUTTON "Circle",IDC_BCIRCLE,360,102,72,12,NOT WS_TABSTOP PUSHBUTTON "Circle",IDC_BCIRCLE,360,102,72,12,NOT WS_TABSTOP
EDITTEXT IDC_ECIRCLE,360,114,72,12,ES_AUTOHSCROLL | ES_READONLY | EDITTEXT IDC_ECIRCLE,360,114,72,12,ES_AUTOHSCROLL | ES_READONLY |
NOT WS_TABSTOP NOT WS_TABSTOP
PUSHBUTTON "Cross",IDC_BCROSS,318,126,72,12,NOT WS_TABSTOP PUSHBUTTON "Cross",IDC_BCROSS,318,126,72,12,NOT WS_TABSTOP
EDITTEXT IDC_ECROSS,318,138,72,12,ES_AUTOHSCROLL | ES_READONLY | EDITTEXT IDC_ECROSS,318,138,72,12,ES_AUTOHSCROLL | ES_READONLY |
NOT WS_TABSTOP NOT WS_TABSTOP
PUSHBUTTON "L3",IDC_BL3,144,132,72,12,NOT WS_TABSTOP PUSHBUTTON "L3",IDC_BL3,144,132,72,12,NOT WS_TABSTOP
EDITTEXT IDC_EL3,144,144,72,12,ES_READONLY | NOT WS_TABSTOP EDITTEXT IDC_EL3,144,144,72,12,ES_READONLY | NOT WS_TABSTOP
@ -125,7 +125,7 @@ END
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO GUIDELINES DESIGNINFO
BEGIN BEGIN
IDD_DIALOG1, DIALOG IDD_DIALOG1, DIALOG
BEGIN BEGIN

View File

@ -55,7 +55,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="user32.lib kernel32.lib dxguid.lib dinput8.lib"
OutputFile="$(OutDir)\$(ProjectName)-dbg.dll" OutputFile="$(OutDir)\$(ProjectName)-dbg.dll"
ModuleDefinitionFile="PadSSSPSX.def" ModuleDefinitionFile="PadSSSPSX.def"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"

View File

@ -1,6 +1,6 @@
SSSPSX Pad - An Open Source Pad plugin for PSX and PS2 emulators SSSPSX Pad - An Open Source Pad plugin for PSX and PS2 emulators
Author: Nagisa Author: Nagisa
Homepage: http://www.asahi-net.or.jp/~bz7t-skmt/ Homepage: (defunct)
Overview: Overview:
-Small executable program -Small executable program
@ -46,3 +46,8 @@ v1.4: -Added timeout on settings dialog.If the countdown ends, the key will be s
-Changed "ESC" key action on settings dialog.If you press the "ESC" key, the setting will keep the previous one. -Changed "ESC" key action on settings dialog.If you press the "ESC" key, the setting will keep the previous one.
-Fixed silly bug. (dont ask me about it). -Fixed silly bug. (dont ask me about it).
v1.5: -Fixed 0x4D packet. v1.5: -Fixed 0x4D packet.
v1.6: -I don't remember.
v1.7: -Changed to DirectInput9.
-Fixed PADreadPort1/PADreadPort2 API.
-Fixed the confusion about PAD1/PAD2 settings.
-Added x64 DLL.