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)
// LilyPad version.
#define VERSION ((0 << 8) | 12 | (0 << 24))
#define VERSION ((0 << 8) | 12 | (1 << 24))
#ifdef __linux__
Display *GSdsp;
@ -178,7 +178,7 @@ struct ButtonSum
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
// a PS2 can set.
@ -187,6 +187,8 @@ struct PadFreezeData
// Digital / Analog / DS2 Native
u8 mode;
u8 previousType;
u8 modeLock;
// In config mode
@ -557,13 +559,11 @@ void Update(unsigned int port, unsigned int slot)
lockStateChanged[port][slot] |= LOCK_DIRECTION;
} else if (cmd == 0x0D) {
lockStateChanged[port][slot] |= LOCK_BOTH;
} else if (cmd == 0x28) {
if (!pads[port][slot].modeLock) {
if (pads[port][slot].mode != MODE_DIGITAL)
pads[port][slot].mode = MODE_DIGITAL;
else
pads[port][slot].mode = MODE_ANALOG;
}
} else if (cmd == 0x28 && !pads[port][slot].modeLock && padtype == Dualshock2Pad) {
if (pads[port][slot].mode == MODE_ANALOG)
pads[port][slot].mode = MODE_DIGITAL;
else if (pads[port][slot].mode == MODE_DIGITAL)
pads[port][slot].mode = MODE_ANALOG;
}
}
}
@ -794,12 +794,17 @@ void ResetPad(int port, int slot)
pads[port][slot].mode = MODE_NEGCON;
else
pads[port][slot].mode = MODE_DIGITAL;
pads[port][slot].umask[0] = pads[port][slot].umask[1] = 0xFF;
// Sets up vibrate variable.
ResetVibrate(port, slot);
pads[port][slot].initialized = 1;
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].lockedSum, 0, sizeof(pads[port][slot].lockedSum));
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];
}
int i;
Pad *pad = &pads[query.port][query.slot];
int padtype = config.padConfigs[query.port][query.slot].type;
if (query.lastByte == 0) {
query.lastByte++;
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.
if (!pad->config && value != 0x42 && value != 0x43) {
if ((!pad->config && value != 0x42 && value != 0x43) || (padtype == neGconPad && (value < 0x40 || value > 0x45))) {
query.numBytes = 0;
query.queryDone = 1;
DEBUG_OUT(0xF3);
@ -1217,8 +1227,8 @@ u8 CALLBACK PADpoll(u8 value)
switch (value) {
// CONFIG_MODE
case 0x43:
if (pad->config) {
if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) {
if (pad->config && padtype != neGconPad) {
if (pad->mode == MODE_DIGITAL && padtype == Dualshock2Pad && config.padConfigs[query.port][query.slot].autoAnalog) {
pad->mode = MODE_ANALOG;
}
// In config mode. Might not actually be leaving it.
@ -1233,7 +1243,6 @@ u8 CALLBACK PADpoll(u8 value)
Update(query.port, query.slot);
ButtonSum *sum = &pad->sum;
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype == MousePad) {
u8 b1 = 0xFC;
if (sum->buttons[9] > 0) // Left button
@ -1275,10 +1284,10 @@ u8 CALLBACK PADpoll(u8 value)
}
u8 b1 = 0xFF, b2 = 0xFF;
for (i = 0; i < 4; i++) {
for (int i = 0; i < 4; 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;
}
@ -1288,7 +1297,7 @@ u8 CALLBACK PADpoll(u8 value)
// 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;
}
@ -1307,7 +1316,7 @@ u8 CALLBACK PADpoll(u8 value)
query.response[8] = Cap((sum->sticks[1].vert + 255) / 2); // Left stick: up & down
query.numBytes = 9;
if (pad->mode != MODE_ANALOG) {
if (pad->mode != MODE_ANALOG && !pad->config) {
// Good idea? No clue.
//query.response[3] &= pad->mask[0];
//query.response[4] &= pad->mask[1];
@ -1331,7 +1340,6 @@ u8 CALLBACK PADpoll(u8 value)
}
}
}
query.lastByte = 1;
DEBUG_OUT(pad->mode);
return pad->mode;
@ -1342,7 +1350,7 @@ u8 CALLBACK PADpoll(u8 value)
// QUERY_DS2_ANALOG_MODE
case 0x41:
// 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[6] = 0x00;
} else {
@ -1363,7 +1371,7 @@ u8 CALLBACK PADpoll(u8 value)
// QUERY_MODEL_AND_MODE
case 0x45:
if (IsDualshock2(query.port, query.slot)) {
SET_FINAL_RESULT(queryModelDS2)
SET_FINAL_RESULT(queryModelDS2);
} else {
SET_FINAL_RESULT(queryModelDS1);
}
@ -1407,7 +1415,7 @@ u8 CALLBACK PADpoll(u8 value)
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.
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]);
return query.response[query.lastByte];
}
@ -1424,18 +1432,12 @@ u8 CALLBACK PADpoll(u8 value)
case 0x43:
if (query.lastByte == 3) {
query.queryDone = 1;
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype != neGconPad && padtype != MousePad) {
pad->config = value;
} else if (pad->config != 0) {
pad->config = 0;
}
pad->config = value;
}
break;
// SET_MODE_AND_LOCK
case 0x44:
if (query.lastByte == 3 && value < 2) {
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype == MousePad) {
pad->mode = MODE_PS1_MOUSE;
} else if (padtype == neGconPad) {
@ -1449,7 +1451,7 @@ u8 CALLBACK PADpoll(u8 value)
pad->modeLock = 3;
} else {
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;
}
}