mirror of https://github.com/PCSX2/pcsx2.git
LilyPad: Small/large motor defaults should work for most devices, when creating new effect bindings.
Keyboard queue fixed up a bit, mainly to favor escape down when PCSX2 is dying. Fix for ignore bindings being swapped with the swap pad bindings buttons. Updated version number, thinking of releasing soon. No known bugs, not that much more to do. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@929 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
1250953ff0
commit
76b52a97a1
|
@ -451,16 +451,16 @@ void SIO_CommandWrite(u8 value,int way) {
|
|||
break;
|
||||
case 0x21:
|
||||
// Set pad slot.
|
||||
sio.mtapst = 0x21;
|
||||
sio.mtapst = value;
|
||||
sio.bufcount = 6; // No idea why this is 6, saved from old code.
|
||||
break;
|
||||
case 0x22:
|
||||
// Set memcard slot.
|
||||
sio.mtapst = 0x22;
|
||||
sio.mtapst = value;
|
||||
sio.bufcount = 6; // No idea why this is 6, saved from old code.
|
||||
break;
|
||||
}
|
||||
// Commented out values are from original code. Break multitap in bios.
|
||||
// Commented out values are from original code. They break multitap in bios.
|
||||
sio.buf[sio.bufcount-1]=0;//'+';
|
||||
sio.buf[sio.bufcount]=0;//'Z';
|
||||
return;
|
||||
|
@ -554,6 +554,7 @@ void InitializeSIO(u8 value)
|
|||
int port = sio.GetMultitapPort();
|
||||
if (!IsMtapPresent(port))
|
||||
{
|
||||
// If "unplug" multitap mid game, set active slots to 0.
|
||||
sio.activePadSlot[port] = 0;
|
||||
sio.activeMemcardSlot[port] = 0;
|
||||
}
|
||||
|
|
|
@ -1404,18 +1404,59 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
|||
if (i >= 0) {
|
||||
unsigned int index = (unsigned int)SendMessage(GetDlgItem(hWnd, IDC_FORCEFEEDBACK), CB_GETITEMDATA, i, 0);
|
||||
if (index < (unsigned int) dm->numDevices) {
|
||||
Device *dev = dm->devices[index];
|
||||
ForceFeedbackBinding *b;
|
||||
int count = CreateEffectBinding(dm->devices[index], 0, port, slot, cmd-ID_BIG_MOTOR, &b);
|
||||
int count = CreateEffectBinding(dev, 0, port, slot, cmd-ID_BIG_MOTOR, &b);
|
||||
if (b) {
|
||||
for (int j=0; j<2 && j <dm->devices[index]->numFFAxes; j++) {
|
||||
b->axes[j].force = BASE_SENSITIVITY;
|
||||
int needSet = 1;
|
||||
if (dev->api == XINPUT && dev->numFFAxes == 2) {
|
||||
needSet = 0;
|
||||
if (cmd == ID_BIG_MOTOR) {
|
||||
b->axes[0].force = BASE_SENSITIVITY;
|
||||
}
|
||||
else {
|
||||
b->axes[1].force = BASE_SENSITIVITY;
|
||||
}
|
||||
}
|
||||
else if (dev->api == DI) {
|
||||
int bigIndex=0, littleIndex=0;
|
||||
int constantEffect = 0, squareEffect = 0;
|
||||
int j;
|
||||
for (j=0; j<dev->numFFAxes; j++) {
|
||||
// DI object instance. 0 is x-axis, 1 is y-axis.
|
||||
int instance = (dev->ffAxes[j].id>>8)&0xFFFF;
|
||||
if (instance == 0) {
|
||||
bigIndex = j;
|
||||
}
|
||||
else if (instance == 1) {
|
||||
littleIndex = j;
|
||||
}
|
||||
}
|
||||
for (j=0; j<dev->numFFEffectTypes; j++) {
|
||||
if (!wcsicmp(L"13541C20-8E33-11D0-9AD0-00A0C9A06E35", dev->ffEffectTypes[j].effectID)) constantEffect = j;
|
||||
if (!wcsicmp(L"13541C22-8E33-11D0-9AD0-00A0C9A06E35", dev->ffEffectTypes[j].effectID)) squareEffect = j;
|
||||
}
|
||||
needSet = 0;
|
||||
if (cmd == ID_BIG_MOTOR) {
|
||||
b->axes[bigIndex].force = BASE_SENSITIVITY;
|
||||
b->axes[littleIndex].force = 1;
|
||||
b->effectIndex = constantEffect;
|
||||
}
|
||||
else {
|
||||
b->axes[bigIndex].force = 1;
|
||||
b->axes[littleIndex].force = BASE_SENSITIVITY;
|
||||
b->effectIndex = squareEffect;
|
||||
}
|
||||
}
|
||||
if (needSet) {
|
||||
for (int j=0; j<2 && j <dev->numFFAxes; j++) {
|
||||
b->axes[j].force = BASE_SENSITIVITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count >= 0) {
|
||||
PropSheet_Changed(hWndProp, hWnd);
|
||||
UnselectAll(hWndList);
|
||||
ListView_SetItemState(hWndList, count, LVIS_SELECTED, LVIS_SELECTED);
|
||||
}
|
||||
PropSheet_Changed(hWndProp, hWnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1886,6 +1927,7 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
|
|||
config.padConfigs[port1][slot1] = config.padConfigs[port2][slot2];
|
||||
config.padConfigs[port2][slot2] = padCfgTemp;
|
||||
for (int i=0; i<dm->numDevices; i++) {
|
||||
if (dm->devices[i]->type == IGNORE) continue;
|
||||
PadBindings bindings = dm->devices[i]->pads[port1][slot1];
|
||||
dm->devices[i]->pads[port1][slot1] = dm->devices[i]->pads[port2][slot2];
|
||||
dm->devices[i]->pads[port2][slot2] = bindings;
|
||||
|
@ -1893,6 +1935,7 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
|
|||
}
|
||||
else {
|
||||
for (int i=0; i<dm->numDevices; i++) {
|
||||
if (dm->devices[i]->type == IGNORE) continue;
|
||||
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);
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
// This is undoubtedly completely unnecessary.
|
||||
#include "KeyboardQueue.h"
|
||||
|
||||
static int numQueuedEvents = 0;
|
||||
static keyEvent queuedEvents[20];
|
||||
|
||||
// What MS calls a single process Mutex. Faster, supposedly.
|
||||
// More importantly, can be abbreviated, amusingly, as cSection.
|
||||
static CRITICAL_SECTION cSection;
|
||||
static int csInitialized = 0;
|
||||
static u8 csInitialized = 0;
|
||||
|
||||
#define EVENT_QUEUE_LEN 16
|
||||
// Actually points one beyond the last queued event.
|
||||
static u8 lastQueuedEvent = 0;
|
||||
static u8 nextQueuedEvent = 0;
|
||||
static keyEvent queuedEvents[EVENT_QUEUE_LEN];
|
||||
|
||||
void QueueKeyEvent(int key, int event) {
|
||||
if (!csInitialized) {
|
||||
|
@ -15,50 +18,42 @@ void QueueKeyEvent(int key, int event) {
|
|||
InitializeCriticalSection(&cSection);
|
||||
}
|
||||
EnterCriticalSection(&cSection);
|
||||
if (numQueuedEvents >= 15) {
|
||||
// Generally shouldn't happen.
|
||||
for (int i=0; i<15; i++) {
|
||||
queuedEvents[i] = queuedEvents[i+5];
|
||||
}
|
||||
numQueuedEvents = 15;
|
||||
|
||||
// Don't queue events if escape is on top of queue. This is just for safety
|
||||
// purposes when a game is killing the emulator for whatever reason.
|
||||
if (nextQueuedEvent == lastQueuedEvent ||
|
||||
queuedEvents[nextQueuedEvent].key != VK_ESCAPE ||
|
||||
queuedEvents[nextQueuedEvent].evt != KEYPRESS) {
|
||||
// Clear queue on escape down, bringing escape to front. May do something
|
||||
// with shift/ctrl/alt and F-keys, later.
|
||||
if (event == KEYPRESS && key == VK_ESCAPE) {
|
||||
nextQueuedEvent = lastQueuedEvent;
|
||||
}
|
||||
|
||||
queuedEvents[lastQueuedEvent].key = key;
|
||||
queuedEvents[lastQueuedEvent].evt = event;
|
||||
|
||||
lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
// If queue wrapped around, remove last element.
|
||||
if (nextQueuedEvent == lastQueuedEvent) {
|
||||
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
}
|
||||
}
|
||||
int index = numQueuedEvents;
|
||||
// Move escape to top of queue. May do something
|
||||
// with shift/ctrl/alt and F-keys, later.
|
||||
if (event == KEYPRESS && key == VK_ESCAPE) {
|
||||
while (index) {
|
||||
queuedEvents[index-1] = queuedEvents[index];
|
||||
index--;
|
||||
}
|
||||
}
|
||||
queuedEvents[index].key = key;
|
||||
queuedEvents[index].evt = event;
|
||||
numQueuedEvents ++;
|
||||
LeaveCriticalSection(&cSection);
|
||||
}
|
||||
|
||||
int GetQueuedKeyEvent(keyEvent *event) {
|
||||
int out = 0;
|
||||
if (numQueuedEvents) {
|
||||
EnterCriticalSection(&cSection);
|
||||
// Shouldn't be 0, but just in case...
|
||||
if (numQueuedEvents) {
|
||||
*event = queuedEvents[0];
|
||||
numQueuedEvents--;
|
||||
out = 1;
|
||||
for (int i=0; i<numQueuedEvents; i++) {
|
||||
queuedEvents[i] = queuedEvents[i+1];
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&cSection);
|
||||
}
|
||||
return out;
|
||||
if (lastQueuedEvent == nextQueuedEvent) return 0;
|
||||
|
||||
EnterCriticalSection(&cSection);
|
||||
*event = queuedEvents[nextQueuedEvent];
|
||||
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
LeaveCriticalSection(&cSection);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ClearKeyQueue() {
|
||||
if (numQueuedEvents) {
|
||||
numQueuedEvents = 0;
|
||||
}
|
||||
lastQueuedEvent = nextQueuedEvent;
|
||||
if (csInitialized) {
|
||||
DeleteCriticalSection(&cSection);
|
||||
csInitialized = 0;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#endif
|
||||
|
||||
// LilyPad version.
|
||||
#define VERSION ((0<<8) | 9 | (11<<24))
|
||||
#define VERSION ((0<<8) | 10 | (0<<24))
|
||||
|
||||
// Used to prevent reading input and cleaning up input devices at the same time.
|
||||
// Only an issue when not reading input in GS thread and disabling devices due to
|
||||
|
@ -115,7 +115,7 @@ struct ButtonSum {
|
|||
Stick sticks[3];
|
||||
};
|
||||
|
||||
|
||||
// Freeze data, for a single pad.
|
||||
struct PadFreezeData {
|
||||
// Digital / Analog / DS2 Native
|
||||
u8 mode;
|
||||
|
@ -168,6 +168,12 @@ u8 Cap (int i) {
|
|||
return (u8) i;
|
||||
}
|
||||
|
||||
inline void ReleaseModifierKeys() {
|
||||
QueueKeyEvent(VK_SHIFT, KEYRELEASE);
|
||||
QueueKeyEvent(VK_MENU, KEYRELEASE);
|
||||
QueueKeyEvent(VK_CONTROL, KEYRELEASE);
|
||||
}
|
||||
|
||||
// RefreshEnabledDevices() enables everything that can potentially
|
||||
// be bound to, as well as the "Ignore keyboard" device.
|
||||
//
|
||||
|
@ -677,9 +683,7 @@ s32 CALLBACK PADinit(u32 flags) {
|
|||
query.numBytes = 0;
|
||||
ClearKeyQueue();
|
||||
// Just in case, when resuming emulation.
|
||||
QueueKeyEvent(VK_SHIFT, KEYRELEASE);
|
||||
QueueKeyEvent(VK_MENU, KEYRELEASE);
|
||||
QueueKeyEvent(VK_CONTROL, KEYRELEASE);
|
||||
ReleaseModifierKeys();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -756,9 +760,7 @@ ExtraWndProcResult HackWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
case WM_ACTIVATEAPP:
|
||||
// Release any buttons PCSX2 may think are down when
|
||||
// losing/gaining focus.
|
||||
QueueKeyEvent(VK_SHIFT, KEYRELEASE);
|
||||
QueueKeyEvent(VK_MENU, KEYRELEASE);
|
||||
QueueKeyEvent(VK_CONTROL, KEYRELEASE);
|
||||
ReleaseModifierKeys();
|
||||
|
||||
// Need to do this when not reading input from gs thread.
|
||||
// Checking for that case not worth the effort.
|
||||
|
@ -1227,12 +1229,14 @@ DWORD WINAPI RenameWindowThreadProc(void *lpParameter) {
|
|||
}
|
||||
|
||||
keyEvent* CALLBACK PADkeyEvent() {
|
||||
// If running both pads, ignore every other call. So if two keys pressed in same interval...
|
||||
static char eventCount = 0;
|
||||
eventCount++;
|
||||
if (eventCount < openCount) {
|
||||
return 0;
|
||||
}
|
||||
eventCount = 0;
|
||||
|
||||
if (!config.GSThreadUpdates) {
|
||||
Update(2, 0);
|
||||
}
|
||||
|
@ -1327,7 +1331,7 @@ s32 CALLBACK PADfreeze(int mode, freezeData *data) {
|
|||
break;
|
||||
}
|
||||
|
||||
// Note sure if the cast is strictly necessary, but feel safest with it there...
|
||||
// Not sure if the cast is strictly necessary, but feel safest with it there...
|
||||
*(PadFreezeData*)&pads[port][slot] = pdata.padData[slot];
|
||||
}
|
||||
if (pdata.slot < 4)
|
||||
|
|
|
@ -150,11 +150,10 @@ public:
|
|||
}
|
||||
|
||||
void Deactivate() {
|
||||
if (xInputVibration.wLeftMotorSpeed || xInputVibration.wRightMotorSpeed) {
|
||||
memset(&xInputVibration, 0, sizeof(xInputVibration));
|
||||
pXInputSetState(index, &xInputVibration);
|
||||
}
|
||||
memset(&xInputVibration, 0, sizeof(xInputVibration));
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
pXInputSetState(index, &xInputVibration);
|
||||
|
||||
FreeState();
|
||||
if (active) {
|
||||
if (!--xInputActiveCount) {
|
||||
|
@ -195,7 +194,7 @@ void EnumXInputDevices() {
|
|||
pXInputEnable(1);
|
||||
for (i=0; i<4; i++) {
|
||||
XINPUT_STATE state;
|
||||
if (ERROR_SUCCESS == pXInputGetState(i, &state)) {
|
||||
if (!i || ERROR_SUCCESS == pXInputGetState(i, &state)) {
|
||||
wsprintfW(temp, L"XInput Pad %i", i);
|
||||
dm->AddDevice(new XInputDevice(i, temp));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue