LilyPad: Improve analog/pressure sensitive detection

Improves detection of analog or pressure sensitive support, which previously made some games unable to detect the correct mode.
This commit is contained in:
FlatOutPS2 2017-02-01 12:23:14 +01:00 committed by Jonathan Li
parent a3efc77255
commit 3075ec2203
1 changed files with 32 additions and 30 deletions

View File

@ -42,7 +42,7 @@
#define FORCE_UPDATE_LPARAM ((LPARAM)0x89437437) #define FORCE_UPDATE_LPARAM ((LPARAM)0x89437437)
// LilyPad version. // LilyPad version.
#define VERSION ((0 << 8) | 12 | (0 << 24)) #define VERSION ((0 << 8) | 12 | (1 << 24))
#ifdef __linux__ #ifdef __linux__
Display *GSdsp; Display *GSdsp;
@ -178,7 +178,7 @@ struct ButtonSum
Stick sticks[2]; Stick sticks[2];
}; };
#define PAD_SAVE_STATE_VERSION 4 #define PAD_SAVE_STATE_VERSION 5
// Freeze data, for a single pad. Basically has all pad state that // Freeze data, for a single pad. Basically has all pad state that
// a PS2 can set. // a PS2 can set.
@ -187,6 +187,8 @@ struct PadFreezeData
// Digital / Analog / DS2 Native // Digital / Analog / DS2 Native
u8 mode; u8 mode;
u8 previousType;
u8 modeLock; u8 modeLock;
// In config mode // In config mode
@ -557,13 +559,11 @@ void Update(unsigned int port, unsigned int slot)
lockStateChanged[port][slot] |= LOCK_DIRECTION; lockStateChanged[port][slot] |= LOCK_DIRECTION;
} else if (cmd == 0x0D) { } else if (cmd == 0x0D) {
lockStateChanged[port][slot] |= LOCK_BOTH; lockStateChanged[port][slot] |= LOCK_BOTH;
} else if (cmd == 0x28) { } else if (cmd == 0x28 && !pads[port][slot].modeLock && padtype == Dualshock2Pad) {
if (!pads[port][slot].modeLock) { if (pads[port][slot].mode == MODE_ANALOG)
if (pads[port][slot].mode != MODE_DIGITAL) pads[port][slot].mode = MODE_DIGITAL;
pads[port][slot].mode = MODE_DIGITAL; else if (pads[port][slot].mode == MODE_DIGITAL)
else pads[port][slot].mode = MODE_ANALOG;
pads[port][slot].mode = MODE_ANALOG;
}
} }
} }
} }
@ -794,12 +794,17 @@ void ResetPad(int port, int slot)
pads[port][slot].mode = MODE_NEGCON; pads[port][slot].mode = MODE_NEGCON;
else else
pads[port][slot].mode = MODE_DIGITAL; pads[port][slot].mode = MODE_DIGITAL;
pads[port][slot].umask[0] = pads[port][slot].umask[1] = 0xFF; pads[port][slot].umask[0] = pads[port][slot].umask[1] = 0xFF;
// Sets up vibrate variable. // Sets up vibrate variable.
ResetVibrate(port, slot); ResetVibrate(port, slot);
pads[port][slot].initialized = 1; pads[port][slot].initialized = 1;
pads[port][slot].enabled = enabled; pads[port][slot].enabled = enabled;
pads[port][slot].previousType = config.padConfigs[port][slot].type;
pads[port][slot].config = 0;
} }
@ -1116,6 +1121,10 @@ s32 CALLBACK PADopen(void *pDsp)
memset(&pads[port][slot].sum, 0, sizeof(pads[port][slot].sum)); memset(&pads[port][slot].sum, 0, sizeof(pads[port][slot].sum));
memset(&pads[port][slot].lockedSum, 0, sizeof(pads[port][slot].lockedSum)); memset(&pads[port][slot].lockedSum, 0, sizeof(pads[port][slot].lockedSum));
pads[port][slot].lockedState = 0; pads[port][slot].lockedState = 0;
if (config.padConfigs[port][slot].type != pads[port][slot].previousType) {
ResetPad(port, slot);
}
} }
} }
@ -1201,14 +1210,15 @@ u8 CALLBACK PADpoll(u8 value)
return query.response[++query.lastByte]; return query.response[++query.lastByte];
} }
int i;
Pad *pad = &pads[query.port][query.slot]; Pad *pad = &pads[query.port][query.slot];
int padtype = config.padConfigs[query.port][query.slot].type;
if (query.lastByte == 0) { if (query.lastByte == 0) {
query.lastByte++; query.lastByte++;
query.currentCommand = value; query.currentCommand = value;
// Only the 0x42(read input and vibration) and 0x43(enter or exit config mode) command cases work outside of config mode, the other cases will be avoided. // Only the 0x42(read input and vibration) and 0x43(enter or exit config mode) command cases work outside of config mode, the other cases will be avoided.
if (!pad->config && value != 0x42 && value != 0x43) { if ((!pad->config && value != 0x42 && value != 0x43) || (padtype == neGconPad && (value < 0x40 || value > 0x45))) {
query.numBytes = 0; query.numBytes = 0;
query.queryDone = 1; query.queryDone = 1;
DEBUG_OUT(0xF3); DEBUG_OUT(0xF3);
@ -1217,8 +1227,8 @@ u8 CALLBACK PADpoll(u8 value)
switch (value) { switch (value) {
// CONFIG_MODE // CONFIG_MODE
case 0x43: case 0x43:
if (pad->config) { if (pad->config && padtype != neGconPad) {
if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) { if (pad->mode == MODE_DIGITAL && padtype == Dualshock2Pad && config.padConfigs[query.port][query.slot].autoAnalog) {
pad->mode = MODE_ANALOG; pad->mode = MODE_ANALOG;
} }
// In config mode. Might not actually be leaving it. // In config mode. Might not actually be leaving it.
@ -1233,7 +1243,6 @@ u8 CALLBACK PADpoll(u8 value)
Update(query.port, query.slot); Update(query.port, query.slot);
ButtonSum *sum = &pad->sum; ButtonSum *sum = &pad->sum;
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype == MousePad) { if (padtype == MousePad) {
u8 b1 = 0xFC; u8 b1 = 0xFC;
if (sum->buttons[9] > 0) // Left button if (sum->buttons[9] > 0) // Left button
@ -1275,10 +1284,10 @@ u8 CALLBACK PADpoll(u8 value)
} }
u8 b1 = 0xFF, b2 = 0xFF; u8 b1 = 0xFF, b2 = 0xFF;
for (i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
b1 -= (sum->buttons[i] > 0) << i; b1 -= (sum->buttons[i] > 0) << i;
} }
for (i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
b2 -= (sum->buttons[i + 4] > 0) << i; b2 -= (sum->buttons[i + 4] > 0) << i;
} }
@ -1288,7 +1297,7 @@ u8 CALLBACK PADpoll(u8 value)
// if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0; // if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0;
} }
for (i = 4; i < 8; i++) { for (int i = 4; i < 8; i++) {
b1 -= (sum->buttons[i + 8] > 0) << i; b1 -= (sum->buttons[i + 8] > 0) << i;
} }
@ -1307,7 +1316,7 @@ u8 CALLBACK PADpoll(u8 value)
query.response[8] = Cap((sum->sticks[1].vert + 255) / 2); // Left stick: up & down query.response[8] = Cap((sum->sticks[1].vert + 255) / 2); // Left stick: up & down
query.numBytes = 9; query.numBytes = 9;
if (pad->mode != MODE_ANALOG) { if (pad->mode != MODE_ANALOG && !pad->config) {
// Good idea? No clue. // Good idea? No clue.
//query.response[3] &= pad->mask[0]; //query.response[3] &= pad->mask[0];
//query.response[4] &= pad->mask[1]; //query.response[4] &= pad->mask[1];
@ -1331,7 +1340,6 @@ u8 CALLBACK PADpoll(u8 value)
} }
} }
} }
query.lastByte = 1; query.lastByte = 1;
DEBUG_OUT(pad->mode); DEBUG_OUT(pad->mode);
return pad->mode; return pad->mode;
@ -1342,7 +1350,7 @@ u8 CALLBACK PADpoll(u8 value)
// QUERY_DS2_ANALOG_MODE // QUERY_DS2_ANALOG_MODE
case 0x41: case 0x41:
// Right? Wrong? No clue. // Right? Wrong? No clue.
if (pad->mode == MODE_DIGITAL || pad->mode == MODE_PS1_MOUSE) { if (pad->mode == MODE_PS1_MOUSE || pad->mode == MODE_NEGCON) {
queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0; queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0;
queryMaskMode[6] = 0x00; queryMaskMode[6] = 0x00;
} else { } else {
@ -1363,7 +1371,7 @@ u8 CALLBACK PADpoll(u8 value)
// QUERY_MODEL_AND_MODE // QUERY_MODEL_AND_MODE
case 0x45: case 0x45:
if (IsDualshock2(query.port, query.slot)) { if (IsDualshock2(query.port, query.slot)) {
SET_FINAL_RESULT(queryModelDS2) SET_FINAL_RESULT(queryModelDS2);
} else { } else {
SET_FINAL_RESULT(queryModelDS1); SET_FINAL_RESULT(queryModelDS1);
} }
@ -1407,7 +1415,7 @@ u8 CALLBACK PADpoll(u8 value)
query.lastByte++; query.lastByte++;
// Only the 0x42(read input and vibration) and 0x43(enter or exit config mode) command cases work outside of config mode, the other cases will be avoided. // Only the 0x42(read input and vibration) and 0x43(enter or exit config mode) command cases work outside of config mode, the other cases will be avoided.
if (!pad->config && query.currentCommand != 0x42 && query.currentCommand != 0x43) { if ((!pad->config && query.currentCommand != 0x42 && query.currentCommand != 0x43) || (padtype == neGconPad && (query.currentCommand < 0x40 || query.currentCommand > 0x45))) {
DEBUG_OUT(query.response[query.lastByte]); DEBUG_OUT(query.response[query.lastByte]);
return query.response[query.lastByte]; return query.response[query.lastByte];
} }
@ -1424,18 +1432,12 @@ u8 CALLBACK PADpoll(u8 value)
case 0x43: case 0x43:
if (query.lastByte == 3) { if (query.lastByte == 3) {
query.queryDone = 1; query.queryDone = 1;
int padtype = config.padConfigs[query.port][query.slot].type; pad->config = value;
if (padtype != neGconPad && padtype != MousePad) {
pad->config = value;
} else if (pad->config != 0) {
pad->config = 0;
}
} }
break; break;
// SET_MODE_AND_LOCK // SET_MODE_AND_LOCK
case 0x44: case 0x44:
if (query.lastByte == 3 && value < 2) { if (query.lastByte == 3 && value < 2) {
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype == MousePad) { if (padtype == MousePad) {
pad->mode = MODE_PS1_MOUSE; pad->mode = MODE_PS1_MOUSE;
} else if (padtype == neGconPad) { } else if (padtype == neGconPad) {
@ -1449,7 +1451,7 @@ u8 CALLBACK PADpoll(u8 value)
pad->modeLock = 3; pad->modeLock = 3;
} else { } else {
pad->modeLock = 0; pad->modeLock = 0;
if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) { if (pad->mode == MODE_DIGITAL && padtype == Dualshock2Pad && config.padConfigs[query.port][query.slot].autoAnalog) {
pad->mode = MODE_ANALOG; pad->mode = MODE_ANALOG;
} }
} }