LilyPad: Add neGcon support

Adds neGcon as a new pad type.

For use with several PS1 and PS2 games like the Ridge Racer and Ace
Combat series.
This commit is contained in:
FlatOutPS2 2016-12-30 19:58:24 +01:00
parent 8038ce1aa9
commit f8a79e5d40
7 changed files with 186 additions and 11 deletions

View File

@ -39,7 +39,8 @@ const wchar_t *padTypes[] = {
L"Dualshock 2",
L"Guitar",
L"Pop'n Music controller",
L"PS1 Mouse"};
L"PS1 Mouse",
L"neGcon"};
// Hacks or configurations which PCSX2 needs with a specific value
void PCSX2_overrideConfig(GeneralConfig &config_in_out)
@ -496,7 +497,7 @@ void SelChanged(int port, int slot)
}
}
for (i = IDC_DPAD; i <= IDC_DEVICE_SELECT; i++) {
for (i = IDC_DPAD; i <= IDC_FACE_ANALOG; i++) {
hWndTemp = GetDlgItem(hWnd, i);
if (hWndTemp)
ShowWindow(hWndTemp, !ffb && !b);
@ -2017,6 +2018,8 @@ void UpdatePadPages()
psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_POPN);
else if (config.padConfigs[port][slot].type == MousePad)
psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_PS1_MOUSE);
else if (config.padConfigs[port][slot].type == neGconPad)
psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_NEGCON);
else
psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG);

View File

@ -103,6 +103,19 @@ Binding 49=0x01020013, 0, 33, 3000, 0, 0, 13172, 4
Binding 50=0x02020013, 0, 35, 3000, 0, 0, 13172, 4
Binding 51=0x01020014, 0, 32, 3000, 0, 0, 13172, 4
Binding 52=0x02020014, 0, 34, 3000, 0, 0, 13172, 4
Binding 53=0x00200000, 0, 20, 65536, 0, 0, 1, 5
Binding 54=0x00200001, 0, 22, 65536, 0, 0, 1, 5
Binding 55=0x00200002, 0, 23, 65536, 0, 0, 1, 5
Binding 56=0x00200003, 0, 21, 65536, 0, 0, 1, 5
Binding 57=0x00200004, 0, 19, 65536, 0, 0, 1, 5
Binding 58=0x00200008, 0, 26, 65536, 0, 0, 1, 5
Binding 59=0x00200009, 0, 27, 65536, 0, 0, 1, 5
Binding 60=0x0020000C, 0, 30, 65536, 0, 0, 1, 5
Binding 61=0x0020000D, 0, 29, 65536, 0, 0, 1, 5
Binding 62=0x0020000E, 0, 31, 65536, 0, 0, 1, 5
Binding 63=0x0020000F, 0, 28, 65536, 0, 0, 1, 5
Binding 64=0x01020013, 0, 33, 87183, 0, 0, 13172, 5
Binding 65=0x02020013, 0, 35, 87183, 0, 0, 13172, 5
FF Binding 0=Constant 0, 0, 0, 1, 0, 65536, 1, 0
FF Binding 1=Constant 0, 1, 0, 1, 0, 0, 1, 65536
[Device 1]
@ -163,6 +176,19 @@ Binding 49=0x01020013, 1, 33, 3000, 0, 0, 13172, 4
Binding 50=0x02020013, 1, 35, 3000, 0, 0, 13172, 4
Binding 51=0x01020014, 1, 32, 3000, 0, 0, 13172, 4
Binding 52=0x02020014, 1, 34, 3000, 0, 0, 13172, 4
Binding 53=0x00200000, 1, 20, 65536, 0, 0, 1, 5
Binding 54=0x00200001, 1, 22, 65536, 0, 0, 1, 5
Binding 55=0x00200002, 1, 23, 65536, 0, 0, 1, 5
Binding 56=0x00200003, 1, 21, 65536, 0, 0, 1, 5
Binding 57=0x00200004, 1, 19, 65536, 0, 0, 1, 5
Binding 58=0x00200008, 1, 26, 65536, 0, 0, 1, 5
Binding 59=0x00200009, 1, 27, 65536, 0, 0, 1, 5
Binding 60=0x0020000C, 1, 30, 65536, 0, 0, 1, 5
Binding 61=0x0020000D, 1, 29, 65536, 0, 0, 1, 5
Binding 62=0x0020000E, 1, 31, 65536, 0, 0, 1, 5
Binding 63=0x0020000F, 1, 28, 65536, 0, 0, 1, 5
Binding 64=0x01020013, 1, 33, 87183, 0, 0, 13172, 5
Binding 65=0x02020013, 1, 35, 87183, 0, 0, 13172, 5
FF Binding 0=Constant 1, 0, 0, 1, 0, 65536, 1, 0
FF Binding 1=Constant 1, 1, 0, 1, 0, 0, 1, 65536
[Device 12]

View File

@ -38,6 +38,7 @@ enum PadType {
GuitarPad,
PopnPad,
MousePad,
neGconPad,
numPadTypes // total number of PadTypes. Add new PadType above this line.
};

View File

@ -87,6 +87,7 @@ unsigned char inBuf[50];
// windowThreadId = GetWindowThreadProcessId(hWnd, 0);
#define MODE_PS1_MOUSE 0x12
#define MODE_NEGCON 0x23
#define MODE_DIGITAL 0x41
#define MODE_ANALOG 0x73
#define MODE_DS2_NATIVE 0x79
@ -792,6 +793,8 @@ void ResetPad(int port, int slot)
memset(&pads[port][slot], 0, sizeof(pads[0][0]));
if (config.padConfigs[port][slot].type == MousePad)
pads[port][slot].mode = MODE_PS1_MOUSE;
else if (config.padConfigs[port][slot].type == neGconPad)
pads[port][slot].mode = MODE_NEGCON;
else
pads[port][slot].mode = MODE_DIGITAL;
pads[port][slot].umask[0] = pads[port][slot].umask[1] = 0xFF;
@ -1209,6 +1212,14 @@ u8 CALLBACK PADpoll(u8 value)
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) {
query.numBytes = 0;
query.queryDone = 1;
DEBUG_OUT(0xF3);
return 0xF3;
}
switch (value) {
// CONFIG_MODE
case 0x43:
@ -1228,7 +1239,8 @@ u8 CALLBACK PADpoll(u8 value)
Update(query.port, query.slot);
ButtonSum *sum = &pad->sum;
if (config.padConfigs[query.port][query.slot].type == MousePad) {
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype == MousePad) {
u8 b1 = 0xFC;
if (sum->buttons[9] > 0) // Left button
b1 -= 8;
@ -1241,8 +1253,31 @@ u8 CALLBACK PADpoll(u8 value)
query.response[6] = sum->sticks[1].vert / 2;
query.numBytes = 7;
query.lastByte = 1;
DEBUG_OUT(pad->mode);
return pad->mode;
DEBUG_OUT(MODE_PS1_MOUSE);
return MODE_PS1_MOUSE;
}
if (padtype == neGconPad) {
u8 b1 = 0xFF, b2 = 0xFF;
b1 -= (sum->buttons[3] > 0) << 3; // Start
for (int i = 3; i < 6; i++) {
b2 -= (sum->buttons[i + 4] > 0) << i; // R, A, B
}
for (int i = 4; i < 8; i++) {
b1 -= (sum->buttons[i + 8] > 0) << i; // D-pad Up, Right, Down, Left
}
query.response[3] = b1;
query.response[4] = b2;
query.response[5] = Cap((sum->sticks[1].horiz + 255) / 2); // Swivel
query.response[6] = (unsigned char)sum->buttons[10]; // I
query.response[7] = (unsigned char)sum->buttons[11]; // II
query.response[8] = (unsigned char)sum->buttons[6]; // L
query.numBytes = 9;
query.lastByte = 1;
DEBUG_OUT(MODE_NEGCON);
return MODE_NEGCON;
}
u8 b1 = 0xFF, b2 = 0xFF;
@ -1253,7 +1288,7 @@ u8 CALLBACK PADpoll(u8 value)
b2 -= (sum->buttons[i + 4] > 0) << i;
}
if (config.padConfigs[query.port][query.slot].type == GuitarPad && !config.GH2) {
if (padtype == GuitarPad && !config.GH2) {
sum->buttons[15] = 255;
// Not sure about this. Forces wammy to be from 0 to 0x7F.
// if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0;
@ -1264,7 +1299,7 @@ u8 CALLBACK PADpoll(u8 value)
}
//Left, Right and Down are always pressed on Pop'n Music controller.
if (config.padConfigs[query.port][query.slot].type == PopnPad)
if (padtype == PopnPad)
b1 = b1 & 0x1f;
query.response[3] = b1;
@ -1375,6 +1410,12 @@ u8 CALLBACK PADpoll(u8 value)
return 0xF3;
} else {
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) {
DEBUG_OUT(query.response[query.lastByte]);
return query.response[query.lastByte];
}
switch (query.currentCommand) {
// READ_DATA_AND_VIBRATE
case 0x42:
@ -1388,14 +1429,22 @@ 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;
}
}
break;
// SET_MODE_AND_LOCK
case 0x44:
if (query.lastByte == 3 && value < 2) {
if (value == 0 && config.padConfigs[query.port][query.slot].type == MousePad) {
int padtype = config.padConfigs[query.port][query.slot].type;
if (padtype == MousePad) {
pad->mode = MODE_PS1_MOUSE;
} else if (padtype == neGconPad) {
pad->mode = MODE_NEGCON;
} else {
static const u8 modes[2] = {MODE_DIGITAL, MODE_ANALOG};
pad->mode = modes[value];
@ -1621,7 +1670,7 @@ s32 CALLBACK PADfreeze(int mode, freezeData *data)
for (int slot = 0; slot < 4; slot++) {
u8 mode = pdata.padData[port][slot].mode;
if (mode != MODE_DIGITAL && mode != MODE_ANALOG && mode != MODE_DS2_NATIVE && mode != MODE_PS1_MOUSE) {
if (mode != MODE_DIGITAL && mode != MODE_ANALOG && mode != MODE_DS2_NATIVE && mode != MODE_PS1_MOUSE && mode != MODE_NEGCON) {
break;
}

View File

@ -374,6 +374,91 @@ BEGIN
LTEXT "Off",IDC_SKIP_DEADZONE_OFF,390,83,20,12
END
IDD_CONFIG_NEGCON DIALOGEX 0, 0, 424, 283
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "",IDC_BINDINGS_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,183,285,WS_EX_CLIENTEDGE
// Input bindings:
GROUPBOX "Shoulder buttons",IDC_SHOULDER,220,3,173,31
PUSHBUTTON "Analog L",ID_L1,233,13,34,15
PUSHBUTTON "Digital R",ID_R1,346,13,34,15
GROUPBOX "D-Pad",IDC_DPAD,196,35,108,70
PUSHBUTTON "Up",ID_DPAD_UP,233,46,34,15
PUSHBUTTON "Left",ID_DPAD_LEFT,214,65,34,15
PUSHBUTTON "Right",ID_DPAD_RIGHT,252,65,34,15
PUSHBUTTON "Down",ID_DPAD_DOWN,233,84,34,15
GROUPBOX "Digital Face buttons",IDC_FACE,310,35,108,34
PUSHBUTTON "B",ID_TRIANGLE,327,46,34,15
PUSHBUTTON "A",ID_CIRCLE,367,46,34,15
GROUPBOX "Analog Face buttons",IDC_FACE_ANALOG,310,71,108,34
PUSHBUTTON "II",ID_SQUARE,327,82,34,15
PUSHBUTTON "I",ID_CROSS,367,82,34,15
GROUPBOX "Analog Rotating Section",IDC_LSTICK,255,107,108,31
PUSHBUTTON "Left",ID_LSTICK_LEFT,261,117,30,15
PUSHBUTTON "Right",ID_LSTICK_RIGHT,327,117,30,15
PUSHBUTTON "Start",ID_START,210,109,34,15
PUSHBUTTON "Mouse",ID_MOUSE,210,128,34,15
// Force Feedback bindings:
GROUPBOX "Add Force Feedback Effect",ID_FORCEFEEDBACK_BOX,262,195,155,51
COMBOBOX IDC_FORCEFEEDBACK,269,208,142,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Big Motor",ID_BIG_MOTOR,269,226,64,14
PUSHBUTTON "Small Motor",ID_SMALL_MOTOR,347,226,64,14
// Special bindings and options:
CONTROL "Configure on bind",IDC_CONFIGURE_ON_BIND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,335,250,70,15
COMBOBOX IDC_DEVICE_SELECT,259,250,72,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Lock Input",ID_LOCK_ALL_INPUT,196,196,59,15
PUSHBUTTON "Lock Direction",ID_LOCK_DIRECTION,196,214,59,15
PUSHBUTTON "Lock Buttons",ID_LOCK_BUTTONS,196,232,59,15
PUSHBUTTON "Ignore Key",ID_IGNORE,196,250,59,15
// Force Feedback configuration:
GROUPBOX "",ID_FF,195,9,222,248
COMBOBOX IDC_FF_EFFECT,203,23,206,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_FF_AXIS1,"msctls_trackbar32",WS_TABSTOP,199,43,214,17
CONTROL "Axis 1",IDC_FF_AXIS1_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,63,91,10
CONTROL "Flip",IDC_FF_AXIS1_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,302,63,35,10
EDITTEXT IDC_FF_AXIS1_SCALE,375,63,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS2,"msctls_trackbar32",WS_TABSTOP,199,79,214,17
CONTROL "Axis 2",IDC_FF_AXIS2_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,99,91,10
CONTROL "Flip",IDC_FF_AXIS2_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,302,99,35,10
EDITTEXT IDC_FF_AXIS2_SCALE,375,92,40,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS3,"msctls_trackbar32",WS_TABSTOP,199,115,214,17
CONTROL "Axis 3",IDC_FF_AXIS3_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,135,91,10
CONTROL "Flip",IDC_FF_AXIS3_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,302,135,35,10
EDITTEXT IDC_FF_AXIS3_SCALE,375,135,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS4,"msctls_trackbar32",WS_TABSTOP,199,151,214,17
CONTROL "Axis 4",IDC_FF_AXIS4_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,171,91,10
CONTROL "Flip",IDC_FF_AXIS4_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,302,171,35,10
EDITTEXT IDC_FF_AXIS4_SCALE,375,171,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS5,"msctls_trackbar32",WS_TABSTOP,199,187,214,17
CONTROL "Axis 5",IDC_FF_AXIS5_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,207,91,10
CONTROL "Flip",IDC_FF_AXIS5_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,302,207,35,10
EDITTEXT IDC_FF_AXIS5_SCALE,375,207,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS6,"msctls_trackbar32",WS_TABSTOP,199,223,214,17
CONTROL "Axis 6",IDC_FF_AXIS6_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,243,91,10
CONTROL "Flip",IDC_FF_AXIS6_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,302,243,35,10
EDITTEXT IDC_FF_AXIS6_SCALE,375,243,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
PUSHBUTTON "Back to Controls",ID_CONTROLS,196,261,59,15
PUSHBUTTON "Test",ID_TEST,257,261,59,15
// Input configuration:
GROUPBOX "Configure Binding",ID_SENSITIVITY,195,9,222,98
EDITTEXT IDC_AXIS_DEVICE,202,22,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
COMBOBOX IDC_AXIS_DIRECTION,276,20,70,47,CBS_DROPDOWNLIST | WS_TABSTOP
EDITTEXT IDC_AXIS_CONTROL,349,22,65,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
LTEXT "Sensitivity",IDC_LABEL_SENSITIVITY,202,38,42,8
CONTROL "Turbo",IDC_TURBO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,50,34,10
CONTROL "",IDC_SLIDER_SENSITIVITY,"msctls_trackbar32",WS_TABSTOP,240,38,131,17
EDITTEXT IDC_AXIS_SENSITIVITY,377,36,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "Flip",IDC_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,385,50,27,10
LTEXT "Dead Zone",IDC_LABEL_DEADZONE,202,63,42,8
CONTROL "",IDC_SLIDER_DEADZONE,"msctls_trackbar32",WS_TABSTOP,240,59,131,17
EDITTEXT IDC_AXIS_DEADZONE,377,62,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
LTEXT "Skip Dead Zone",IDC_LABEL_SKIP_DEADZONE,202,80,42,16
CONTROL "",IDC_SLIDER_SKIP_DEADZONE,"msctls_trackbar32",WS_TABSTOP,240,80,131,17
EDITTEXT IDC_AXIS_SKIP_DEADZONE,377,83,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
LTEXT "Off",IDC_SKIP_DEADZONE_OFF,390,83,33,12
END
IDD_GENERAL DIALOGEX 0, 0, 424, 283
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 0, 0, 0x1
@ -481,6 +566,14 @@ BEGIN
BOTTOMMARGIN, 311
END
IDD_CONFIG_NEGCON, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 417
TOPMARGIN, 7
BOTTOMMARGIN, 311
END
IDD_GENERAL, DIALOG
BEGIN
LEFTMARGIN, 7

View File

@ -51,7 +51,8 @@ LPWSTR dialog_message(int ID, bool *updateText)
L"\"Dualshock 2\" emulates the default PS2 controller for use in both PS1 and PS2 games.\n\n"
L"\"Guitar\" emulates a PS2 controller used in the Guitar Hero and Rock Band series of games.\n\n"
L"\"Pop'n Music controller\" emulates a PS2 controller used exclusively in the Japanese Pop'n Music series of games.\n\n"
L"\"PS1 Mouse\" emulates the Playstation Mouse. This controller can only be used in a number of PS1 games like \"Command & Conquer: Red Alert\" and \"Myst\".";
L"\"PS1 Mouse\" emulates the Playstation Mouse. This controller can only be used in a number of PS1 games like \"Command & Conquer: Red Alert\" and \"Myst\".\n\n"
L"\"neGcon\" emulates a controller that can be used in a number of PS1 games and PS2 games like the \"Ridge Racer\" and \"Ace Combat\" series.";
case IDC_ANALOG_START1:
return L"Automatically switch a pad from digital mode to analog mode whenever a pad is set to digital mode, if the pad's mode is not locked."
L"This removes the need for manually enabling analog mode with a press of the analog button for games that support, but do not automatically enable analog mode.\n\n"

View File

@ -14,6 +14,7 @@
#define IDR_INI1 111
#define IDD_CONFIG_POPN 112
#define IDD_CONFIG_PS1_MOUSE 113
#define IDD_CONFIG_NEGCON 114
#define IDC_CLOSE_HACK1 1099
#define IDC_KB_DISABLE 1100
#define IDC_KB_DI 1101
@ -104,6 +105,7 @@
#define ID_FORCEFEEDBACK_BOX 0x111E
#define IDC_CONFIGURE_ON_BIND 0x111F
#define IDC_DEVICE_SELECT 0x1120
#define IDC_FACE_ANALOG 0x1121
#define IDC_BINDINGS_LIST 0x1200
#define ID_SAVE 0x1201
#define ID_LOAD 0x1202