Add an option to disable SOCD.

- To handle different input values, add parameters for up, down, left, and right.
- When SOCD is disabled, the original input control logic takes over
This commit is contained in:
taoenwen 2025-07-08 17:02:46 +08:00
parent 55db9b531e
commit cb66f03701
17 changed files with 176 additions and 225 deletions

View File

@ -2,7 +2,7 @@
#include "burnint.h"
#include "joyprocess.h"
INT32 nSocd[6] = { 2,2,2,2,2,2 }; // Last Input Priority (8 Way)
INT32 nSocd[6] = { 3,3,3,3,3,3 }; // Last Input Priority (8 Way)
// Digital Processing
void ProcessJoystick(UINT8 *input, INT8 playernum, INT8 up_bit, INT8 down_bit, INT8 left_bit, INT8 right_bit, UINT8 flags)

View File

@ -116,171 +116,128 @@ struct HoldCoin {
}
};
// Take over and handle logic in the opposite input direction in advance when necessary
// When SOCD is disabled, control is transferred to the default frame control
template <int N, typename T>
struct ClearOpposite {
// T prev[N << 2];
T prev[N], prev_a[N], prev_b[N];
T prev[N], prev_ud[N], prev_lr[N];
void reset() {
memset(&prev, 0, sizeof(prev));
memset(&prev_a, 0, sizeof(prev_a));
memset(&prev_b, 0, sizeof(prev_b));
memset(&prev, 0, sizeof(prev));
memset(&prev_ud, 0, sizeof(prev_ud));
memset(&prev_lr, 0, sizeof(prev_lr));
}
void scan() {
SCAN_VAR(prev);
SCAN_VAR(prev_a);
SCAN_VAR(prev_b);
SCAN_VAR(prev_ud);
SCAN_VAR(prev_lr);
}
#if 0
void checkval(UINT8 n, T &inp, T val_a, T val_b) {
// When opposites become pressed simultaneously, and a 3rd direction isn't pressed
// remove the previously stored direction if it exists, cancel both otherwise
if ((inp & val_a) == val_a)
inp &= (prev[n] && (inp & val_b) == 0 ? (inp ^ prev[n]) : ~val_a);
// Store direction anytime it's pressed without its opposite
else if (inp & val_a)
prev[n] = inp & val_a;
}
#endif
// Insert the positive direction into the two fast-switching oblique directions
void interp(UINT8 n, T& inp, T val_a, T val_b) {
if (((inp | prev[n]) & val_a) == val_a) inp &= ~val_a;
if (((inp | prev[n]) & val_b) == val_b) inp &= ~val_b;
void interp(UINT8 n, T& inp, const T val_ud, const T val_lr) {
if (((inp | prev[n]) & val_ud) == val_ud) inp &= ~val_ud;
if (((inp | prev[n]) & val_lr) == val_lr) inp &= ~val_lr;
prev[n] = inp;
}
// SOCD - Simultaneous Neutral
void neu(UINT8 n, T& inp, T val_a, T val_b) {
if ((inp & val_a) == val_a) inp &= ~val_a;
if ((inp & val_b) == val_b) inp &= ~val_b;
// Oppose simultaneous input from left and right or up and down
void oppoxy(UINT8 n, T& inp, const T val_ud, const T val_lr) {
if ((inp & val_ud) == val_ud) inp &= ~val_ud;
if ((inp & val_lr) == val_lr) inp &= ~val_lr;
}
interp(n, inp, val_a, val_b);
// SOCD - Simultaneous Neutral
void neu(UINT8 n, T& inp, const T val_u, const T val_d, const T val_l, const T val_r) {
const T val_ud = val_u | val_d, val_lr = val_l | val_r;
oppoxy(n, inp, val_ud, val_lr);
interp(n, inp, val_ud, val_lr);
}
// SOCD - Last Input Priority (4 Way)
void lif(UINT8 n, T& inp, T val_a, T val_b) {
const T mask_a = inp & val_a;
if (mask_a == val_a) inp &= ~prev_a[n];
else if (mask_a) prev_a[n] = mask_a;
void lif(UINT8 n, T& inp, const T val_u, const T val_d, const T val_l, const T val_r) {
const T val_ud = val_u | val_d, val_lr = val_l | val_r;
const T inp_lr = inp & val_lr;
if (inp_lr == val_lr) inp &= ~prev_lr[n];
else if (inp_lr) prev_lr[n] = inp_lr;
const T mask_b = inp & val_b;
if (mask_b == val_b) inp &= ~prev_b[n];
else if (mask_b) prev_b[n] = mask_b;
const T inp_ud = inp & val_ud;
if (inp_ud == val_ud) inp &= ~prev_ud[n];
else if (inp_ud) prev_ud[n] = inp_ud;
neu(n, inp, val_a, val_b);
neu(n, inp, val_u, val_d, val_l, val_r);
}
// SOCD - Last Input Priority (8 Way)
void lie(UINT8 n, T& inp, T val_a, T val_b) {
lif(n, inp, val_a, val_b);
void lie(UINT8 n, T& inp, const T val_u, const T val_d, const T val_l, const T val_r) {
const T prev_state = prev[n];
lif(n, inp, val_u, val_d, val_l, val_r);
const T val = (val_a < val_b) ? val_a : val_b;
INT32 nBit = sizeof(val) * 8, i;
for (i = 0; i < nBit; i++) {
if (val & (1 << i)) break; // Find up
const T val_ud = (val_u | val_d), val_lr = (val_l | val_r);
const T inp_e = (inp & (val_ud | val_lr)), prev_e = (prev_state & (val_ud | val_lr));
if (((inp_e == (val_d | val_l)) && (prev_e == (val_d | val_r))) ||
((inp_e == (val_d | val_r)) && (prev_e == (val_d | val_l))) ||
((inp_e == (val_u | val_l)) && (prev_e == (val_u | val_r))) ||
((inp_e == (val_u | val_r)) && (prev_e == (val_u | val_l)))) {
inp &= ~val_lr;
}
const T inp_u = (1 << i), inp_d = (inp_u << 1), inp_l = (inp_u << 2), inp_r = (inp_u << 3);
const T inp_ud = (inp_u | inp_d), inp_lr = (inp_l | inp_r);
const T inp_e = (inp & (inp_ud | inp_lr)), prev_e = (prev[n] & (inp_ud | inp_lr));
if (((inp_e == (inp_d | inp_l)) && (prev_e == (inp_d | inp_r))) ||
((inp_e == (inp_d | inp_r)) && (prev_e == (inp_d | inp_l))) ||
((inp_e == (inp_u | inp_l)) && (prev_e == (inp_u | inp_r))) ||
((inp_e == (inp_u | inp_r)) && (prev_e == (inp_u | inp_l)))) {
inp &= ~inp_lr;
if (((inp_e == (val_d | val_l)) && (prev_e == (val_u | val_l))) ||
((inp_e == (val_d | val_r)) && (prev_e == (val_u | val_r))) ||
((inp_e == (val_u | val_l)) && (prev_e == (val_d | val_l))) ||
((inp_e == (val_u | val_r)) && (prev_e == (val_d | val_r)))) {
inp &= ~val_ud;
}
if (((inp_e == (inp_d | inp_l)) && (prev_e == (inp_u | inp_l))) ||
((inp_e == (inp_d | inp_r)) && (prev_e == (inp_u | inp_r))) ||
((inp_e == (inp_u | inp_l)) && (prev_e == (inp_d | inp_l))) ||
((inp_e == (inp_u | inp_r)) && (prev_e == (inp_d | inp_r)))) {
inp &= ~inp_ud;
}
prev[n] = inp;
}
// SOCD - First Input Priority
void fip(UINT8 n, T& inp, T val_a, T val_b) {
const T mask_a = inp & val_a;
if (mask_a == val_a) inp &= (~val_a) | prev_a[n];
else if (mask_a) prev_a[n] = mask_a;
void fip(UINT8 n, T& inp, const T val_u, const T val_d, const T val_l, const T val_r) {
const T val_ud = (val_u | val_d), val_lr = (val_l | val_r);
const T inp_lr = inp & val_lr;
if (inp_lr == val_lr) inp &= (~val_lr) | prev_lr[n];
else if (inp_lr) prev_lr[n] = inp_lr;
const T mask_b = inp & val_b;
if (mask_b == val_b) inp &= (~val_b) | prev_b[n];
else if (mask_b) prev_b[n] = mask_b;
const T inp_ud = inp & val_ud;
if (inp_ud == val_ud) inp &= (~val_ud) | prev_ud[n];
else if (inp_ud) prev_ud[n] = inp_ud;
neu(n, inp, val_a, val_b);
neu(n, inp, val_u, val_d, val_l, val_r);
}
// SOCD - Up Priority (Up-override Down)
void uod(UINT8 n, T& inp, T val_a, T val_b) {
const T val = (val_a < val_b) ? val_a : val_b;
INT32 nBit = sizeof(val) * 8, i;
void uod(UINT8 n, T& inp, const T val_u, const T val_d, const T val_l, const T val_r) {
const T val_ud = (val_u | val_d), val_lr = (val_l | val_r), inp_u = inp & val_u;
oppoxy(n, inp, val_ud, val_lr);
if (inp_u) inp |= inp_u;
for (i = 0; i < nBit; i++) {
if (val & (1 << i)) break; // Find up
}
const T inp_u = (inp & (1 << i));
if ((inp & val_a) == val_a) inp &= ~val_a;
if ((inp & val_b) == val_b) inp &= ~val_b;
if (inp_u) inp |= inp_u;
neu(n, inp, val_a, val_b);
neu(n, inp, val_u, val_d, val_l, val_r);
}
// SOCD - Down Priority (Left/Right Last Input Priority)
void dlr(UINT8 n, T& inp, T val_a, T val_b) {
const T val = (val_a < val_b) ? val_a : val_b;
INT32 nBit = sizeof(val) * 8, i;
void dlr(UINT8 n, T& inp, const T val_u, const T val_d, const T val_l, const T val_r) {
const T val_ud = (val_u | val_d), val_lr = (val_l | val_r), inp_d = (inp & val_d);
const T inp_lr = inp & val_lr;
if (inp_lr == val_lr) inp &= ~prev_lr[n];
else if (inp_lr) prev_lr[n] = inp_lr;
for (i = 0; i < nBit; i++) {
if (val & (1 << i)) break; // Find up
}
const T inp_ud = inp & val_ud;
if (inp_ud == val_ud) inp &= (~val_ud) | inp_d;
i++;
const T inp_d = (inp & (1 << i));
const T mask_a = inp & val_a;
if (mask_a == val_a) {
if (inp_d && (val_a & (1 << i)))
inp &= (~val_a) | (1 << i);
else
inp &= ~prev_a[n];
}
else if (mask_a) prev_a[n] = mask_a;
const T mask_b = inp & val_b;
if (mask_b == val_b) {
if (inp_d && (val_b & (1 << i)))
inp &= (~val_b) | (1 << i);
else
inp &= ~prev_b[n];
}
else if (mask_b) prev_b[n] = mask_b;
neu(n, inp, val_a, val_b);
neu(n, inp, val_u, val_d, val_l, val_r);
}
void check(UINT8 num, T& inp, T val1, T val2, INT32 socd = 2) {
// checkval((num << 1), inp, val1, val2);
// checkval((num << 1) + 1, inp, val2, val1);
#define DISPATCH_SOCD(x) x(num, inp, val1, val2)
void check(UINT8 num, T& inp, const T val_u, const T val_d, const T val_l, const T val_r, INT32 socd = 2) {
#define DISPATCH_SOCD(x) x(num, inp, val_u, val_d, val_l, val_r)
switch (socd) {
case 0: DISPATCH_SOCD(neu); break;
case 1: DISPATCH_SOCD(lif); break;
case 2: DISPATCH_SOCD(lie); break;
case 3: DISPATCH_SOCD(fip); break;
case 4: DISPATCH_SOCD(uod); break;
case 5: DISPATCH_SOCD(dlr); break;
default: break;
case 1: DISPATCH_SOCD(neu); break;
case 2: DISPATCH_SOCD(lif); break;
case 3: DISPATCH_SOCD(lie); break;
case 4: DISPATCH_SOCD(fip); break;
case 5: DISPATCH_SOCD(uod); break;
case 6: DISPATCH_SOCD(dlr); break;
default: break; // Disable SOCD
}
#undef DISPATCH_SOCD

View File

@ -686,8 +686,8 @@ INT32 CpsRwGetInp()
CpsPaddle1 += CpsInpPaddle1 / 0x80; // add +-8 maximum to paddle-accumulator
}
clear_opposite.check(0, Inp000, 0x0c, 0x03, nSocd[0]);
clear_opposite.check(1, Inp001, 0x0c, 0x03, nSocd[1]);
clear_opposite.check(0, Inp000, 0x08, 0x04, 0x02, 0x01, nSocd[0]);
clear_opposite.check(1, Inp001, 0x08, 0x04, 0x02, 0x01, nSocd[1]);
// Ghouls uses a 4-way stick
if (Ghouls) {
@ -718,19 +718,19 @@ INT32 CpsRwGetInp()
if (nMaxPlayers > 2) {
if (Cps == 2) {
clear_opposite.check(2, Inp011, 0x0c, 0x03, nSocd[2]);
clear_opposite.check(2, Inp011, 0x08, 0x04, 0x02, 0x01, nSocd[2]);
if (nMaxPlayers == 4) {
clear_opposite.check(3, Inp010, 0x0c, 0x03, nSocd[3]);
clear_opposite.check(3, Inp010, 0x08, 0x04, 0x02, 0x01, nSocd[3]);
}
} else {
clear_opposite.check(4, Inp177, 0x0c, 0x03, nSocd[2]);
clear_opposite.check(2, Inp177, 0x08, 0x04, 0x02, 0x01, nSocd[2]);
if (nMaxPlayers == 4) {
clear_opposite.check(5, Inp179, 0x0c, 0x03, nSocd[3]);
clear_opposite.check(3, Inp179, 0x08, 0x04, 0x02, 0x01, nSocd[3]);
}
if (Cps1Qs) {
clear_opposite.check(6, Inpc001, 0x0c, 0x03, nSocd[2]);
clear_opposite.check(2, Inpc001, 0x08, 0x04, 0x02, 0x01, nSocd[2]);
if (nMaxPlayers == 4) {
clear_opposite.check(7, Inpc003, 0x0c, 0x03, nSocd[3]);
clear_opposite.check(3, Inpc003, 0x08, 0x04, 0x02, 0x01, nSocd[3]);
}
}
}

View File

@ -503,8 +503,9 @@ static INT32 DrvFrame()
DrvInput[0] |= (DrvJoy1[i] & 1) << i;
DrvInput[1] |= (DrvJoy2[i] & 1) << i;
}
clear_opposite.check(0, DrvInput[0], 0x0003, 0x000c, nSocd[0]);
clear_opposite.check(1, DrvInput[1], 0x0003, 0x000c, nSocd[1]);
for (INT32 i = 0; i < 2; i++) {
clear_opposite.check(i, DrvInput[i], 0x0001, 0x0002, 0x0004, 0x0008, nSocd[i]);
}
SekNewFrame();
ZetNewFrame();

View File

@ -2127,8 +2127,8 @@ INT32 cps3Frame()
}
// Clear Opposites
clear_opposite.check(0, Cps3Input[0], 0x0003, 0x000c, nSocd[0]);
clear_opposite.check(1, Cps3Input[0], 0x0300, 0x0c00, nSocd[1]);
clear_opposite.check(0, Cps3Input[0], 0x0001, 0x0002, 0x0004, 0x0008, nSocd[0]);
clear_opposite.check(1, Cps3Input[0], 0x0100, 0x0200, 0x0400, 0x0800, nSocd[1]);
Sh2NewFrame();

View File

@ -4920,12 +4920,9 @@ INT32 MegadriveFrame()
JoyPad->pad[3] |= (MegadriveJoy4[i] & 1) << i;
JoyPad->pad[4] |= (MegadriveJoy5[i] & 1) << i;
}
clear_opposite.check(0, JoyPad->pad[0], 0x0c, 0x03, nSocd[0]);
clear_opposite.check(1, JoyPad->pad[1], 0x0c, 0x03, nSocd[1]);
clear_opposite.check(2, JoyPad->pad[2], 0x0c, 0x03, nSocd[2]);
clear_opposite.check(3, JoyPad->pad[3], 0x0c, 0x03, nSocd[3]);
clear_opposite.check(4, JoyPad->pad[4], 0x0c, 0x03, nSocd[4]);
for (INT32 i = 0; i < 5; i++) {
clear_opposite.check(i, JoyPad->pad[i], 0x01, 0x02, 0x04, 0x08, nSocd[i]);
}
SekCyclesNewFrame(); // for sound sync
ZetNewFrame();

View File

@ -4546,8 +4546,8 @@ static void NeoStandardInputs(INT32 nBank)
NeoInput[10] |= (NeoButton3[i] & 1) << i;
NeoInput[11] |= (NeoButton4[i] & 1) << i;
}
clear_opposite.check(2, NeoInput[ 8], 0x0c, 0x03, nSocd[2]);
clear_opposite.check(3, NeoInput[ 9], 0x0c, 0x03, nSocd[3]);
clear_opposite.check(2, NeoInput[8], 0x01, 0x02, 0x04, 0x08, nSocd[2]);
clear_opposite.check(3, NeoInput[9], 0x01, 0x02, 0x04, 0x08, nSocd[3]);
if (NeoDiag[1]) {
NeoInput[13] |= 0x80;
@ -4563,8 +4563,8 @@ static void NeoStandardInputs(INT32 nBank)
NeoInput[ 2] |= (NeoButton1[i] & 1) << i;
NeoInput[ 3] |= (NeoButton2[i] & 1) << i;
}
clear_opposite.check(0, NeoInput[ 0], 0x0c, 0x03, nSocd[0]);
clear_opposite.check(1, NeoInput[ 1], 0x0c, 0x03, nSocd[1]);
clear_opposite.check(0, NeoInput[0], 0x01, 0x02, 0x04, 0x08, nSocd[0]);
clear_opposite.check(1, NeoInput[1], 0x01, 0x02, 0x04, 0x08, nSocd[1]);
if (NeoDiag[0]) {
NeoInput[ 5] |= 0x80;
}

View File

@ -11382,7 +11382,6 @@ INT32 NESDraw()
return 0;
}
#if 0
static void clear_opposites(UINT8 &inpt)
{
// some games will straight-up crash or go berzerk if up+down or left+right
@ -11395,7 +11394,6 @@ static void clear_opposites(UINT8 &inpt)
if ((inpt & ( (1 << 6) | (1 << 7) )) == ((1 << 6) | (1 << 7)) )
inpt &= ~((1 << 6) | (1 << 7)); // left + right pressed, cancel both
}
#endif
#define DEBUG_CYC 0
@ -11431,16 +11429,12 @@ INT32 NESFrame()
DrvInputs[2] ^= (NESJoy3[i] & 1) << i;
DrvInputs[3] ^= (NESJoy4[i] & 1) << i;
}
#if 0
clear_opposites(DrvInputs[0]);
clear_opposites(DrvInputs[1]);
clear_opposites(DrvInputs[2]);
clear_opposites(DrvInputs[3]);
#endif
clear_opposite.check(0, DrvInputs[0], 0x30, 0xc0, nSocd[0]);
clear_opposite.check(1, DrvInputs[1], 0x30, 0xc0, nSocd[1]);
clear_opposite.check(2, DrvInputs[2], 0x30, 0xc0, nSocd[2]);
clear_opposite.check(3, DrvInputs[3], 0x30, 0xc0, nSocd[3]);
for (INT32 i = 0; i < 4; i++) {
if ((0 == nSocd[i]) || (nSocd[i] > 6))
clear_opposites(DrvInputs[i]);
else
clear_opposite.check(i, DrvInputs[i], 0x10, 0x20, 0x40, 0x80, nSocd[i]);
}
if (NESMode & (USE_ZAPPER | VS_ZAPPER)) {
BurnGunMakeInputs(0, ZapperX, ZapperY);

View File

@ -650,37 +650,23 @@ INT32 PCEDraw()
static void PCECompileInputs()
{
// memset (PCEInputs, 0xff, 5 * sizeof(UINT16));
memset(PCEInputs, 0x00, 5 * sizeof(UINT16));
memset(PCEInputs, 0xff, 5 * sizeof(UINT16));
for (INT32 i = 0; i < 12; i++) {
/*
PCEInputs[0] ^= (PCEJoy1[i] & 1) << i;
PCEInputs[1] ^= (PCEJoy2[i] & 1) << i;
PCEInputs[2] ^= (PCEJoy3[i] & 1) << i;
PCEInputs[3] ^= (PCEJoy4[i] & 1) << i;
PCEInputs[4] ^= (PCEJoy5[i] & 1) << i;
*/
PCEInputs[0] |= (PCEJoy1[i] & 1) << i;
PCEInputs[1] |= (PCEJoy2[i] & 1) << i;
PCEInputs[2] |= (PCEJoy3[i] & 1) << i;
PCEInputs[3] |= (PCEJoy4[i] & 1) << i;
PCEInputs[4] |= (PCEJoy5[i] & 1) << i;
}
#define PCEBITSWAP16(u16) (u16 = (((u16) & ~0xe0) | ((((u16) >> 5) & 1) << 7) | ((((u16) >> 7) & 1) << 6) | ((((u16) >> 6) & 1) << 5))) // msvc ...
#define PCERESTORE16(u16) (u16 = (((u16) & ~0xe0) | ((((u16) >> 7) & 1) << 5) | ((((u16) >> 6) & 1) << 7) | ((((u16) >> 5) & 1) << 6))) // must be u16 = ...
for (INT32 i = 0; i < 5; i++) {
PCEBITSWAP16(PCEInputs[i]);
clear_opposite.check(i, PCEInputs[i], 0x00c0, 0x0030, nSocd[i]);
PCERESTORE16(PCEInputs[i]);
if ((0 == nSocd[i]) || (nSocd[i] > 6)) continue;
PCEInputs[i] = ~PCEInputs[i];
clear_opposite.check(i, PCEInputs[i], 0x10, 0x40, 0x80, 0x20, nSocd[i]);
PCEInputs[i] = ~PCEInputs[i];
}
#undef PCEBITSWAP16
#undef PCERESTORE16
if ((last_dip ^ PCEDips[2]) & 0x80) {
bprintf(0, _T("Sound core switched to: %s\n"), (PCEDips[2] & 0x80) ? _T("HQ") : _T("LQ"));
c6280_set_renderer(PCEDips[2] & 0x80);

View File

@ -1099,15 +1099,11 @@ INT32 pgmFrame()
PgmInput[5] |= (PgmBtn2[i] & 1) << i;
}
// clear opposites
// clear opposites & hold coin
for (INT32 i = 0; i < 4; i++) {
clear_opposite.check(i, PgmInput[i], 0x06, 0x18, nSocd[i]);
clear_opposite.check(i, PgmInput[i], 0x02, 0x4, 0x08, 0x10, nSocd[i]);
hold_coin.check(i, PgmInput[4], 1 << i, 7);
}
hold_coin.check(0, PgmInput[4], 1, 7);
hold_coin.check(1, PgmInput[4], 2, 7);
hold_coin.check(2, PgmInput[4], 4, 7);
hold_coin.check(3, PgmInput[4], 8, 7);
}
SekNewFrame();

View File

@ -483,8 +483,9 @@ static INT32 DrvFrame()
DrvInput[0] |= ((snesInputPort0[i] & 1) << i);
DrvInput[1] |= ((snesInputPort1[i] & 1) << i);
}
clear_opposite.check(0, DrvInput[0], 0x0030, 0x00c0, nSocd[0]);
clear_opposite.check(1, DrvInput[1], 0x0030, 0x00c0, nSocd[1]);
for (INT32 i = 0; i < 2; i++) {
clear_opposite.check(i, DrvInput[i], 0x0010, 0x0020, 0x0040, 0x0080, nSocd[i]);
}
for (INT32 i = 0; i < 12; i++) {
if ((DrvDips[1] & 0x01) == 0) {

View File

@ -1267,6 +1267,7 @@ BEGIN
BEGIN
POPUP "Player 1"
BEGIN
MENUITEM "P1 Disable SOCD", MENU_INPUT_P1_DISABLE
MENUITEM "P1 SOCD-N", MENU_INPUT_P1_SOCDN
MENUITEM "P1 SOCD-L (4 Way)", MENU_INPUT_P1_SOCDLF
MENUITEM "P1 SOCD-L (8 Way)", MENU_INPUT_P1_SOCDLE
@ -1276,6 +1277,7 @@ BEGIN
END
POPUP "Player 2"
BEGIN
MENUITEM "P2 Disable SOCD", MENU_INPUT_P2_DISABLE
MENUITEM "P2 SOCD-N", MENU_INPUT_P2_SOCDN
MENUITEM "P2 SOCD-L (4 Way)", MENU_INPUT_P2_SOCDLF
MENUITEM "P2 SOCD-L (8 Way)", MENU_INPUT_P2_SOCDLE
@ -1285,6 +1287,7 @@ BEGIN
END
POPUP "Player 3"
BEGIN
MENUITEM "P3 Disable SOCD", MENU_INPUT_P3_DISABLE
MENUITEM "P3 SOCD-N", MENU_INPUT_P3_SOCDN
MENUITEM "P3 SOCD-L (4 Way)", MENU_INPUT_P3_SOCDLF
MENUITEM "P3 SOCD-L (8 Way)", MENU_INPUT_P3_SOCDLE
@ -1294,6 +1297,7 @@ BEGIN
END
POPUP "Player 4"
BEGIN
MENUITEM "P4 Disable SOCD", MENU_INPUT_P4_DISABLE
MENUITEM "P4 SOCD-N", MENU_INPUT_P4_SOCDN
MENUITEM "P4 SOCD-L (4 Way)", MENU_INPUT_P4_SOCDLF
MENUITEM "P4 SOCD-L (8 Way)", MENU_INPUT_P4_SOCDLE
@ -1303,6 +1307,7 @@ BEGIN
END
POPUP "Player 5"
BEGIN
MENUITEM "P5 Disable SOCD", MENU_INPUT_P5_DISABLE
MENUITEM "P5 SOCD-N", MENU_INPUT_P5_SOCDN
MENUITEM "P5 SOCD-L (4 Way)", MENU_INPUT_P5_SOCDLF
MENUITEM "P5 SOCD-L (8 Way)", MENU_INPUT_P5_SOCDLE
@ -1312,6 +1317,7 @@ BEGIN
END
POPUP "Player 6"
BEGIN
MENUITEM "P6 Disable SOCD", MENU_INPUT_P6_DISABLE
MENUITEM "P6 SOCD-N", MENU_INPUT_P6_SOCDN
MENUITEM "P6 SOCD-L (4 Way)", MENU_INPUT_P6_SOCDLF
MENUITEM "P6 SOCD-L (8 Way)", MENU_INPUT_P6_SOCDLE

View File

@ -537,7 +537,6 @@ int ConfigAppLoad()
}
fclose(h);
LookupSubDirThreads();
return 0;
}

View File

@ -787,6 +787,7 @@ static int AppInit()
// Load config for the application
ConfigAppLoad();
LookupSubDirThreads();
#if defined (FBNEO_DEBUG)
OpenDebugLog();

View File

@ -1269,10 +1269,10 @@ void MenuUpdate()
CheckMenuRadioItem(hMenu, MENU_INPUT_REWIND_128MB, MENU_INPUT_REWIND_1GB, var, MF_BYCOMMAND);
// SOCD
const INT32 nPlayer = sizeof(nSocd) / sizeof(nSocd[0]), nCount = (MENU_INPUT_P6_SOCDDL - MENU_INPUT_P1_SOCDN + 1) / nPlayer;
const INT32 nPlayer = sizeof(nSocd) / sizeof(nSocd[0]), nCount = (MENU_INPUT_P6_SOCDDL - MENU_INPUT_P1_DISABLE + 1) / nPlayer;
for (INT32 i = 0; i < nPlayer; i++) {
var = MENU_INPUT_P1_SOCDN + i * nCount + nSocd[i];
const INT32 startId = MENU_INPUT_P1_SOCDN + i * nCount, endId = startId + nCount - 1;
var = MENU_INPUT_P1_DISABLE + i * nCount + nSocd[i];
const INT32 startId = MENU_INPUT_P1_DISABLE + i * nCount, endId = startId + nCount - 1;
CheckMenuRadioItem(hMenu, startId, endId, var, MF_BYCOMMAND);
}

View File

@ -823,43 +823,50 @@
#define MENU_CLRMAME_PRO_XML_CHANNELF_ONLY 10740
#define MENU_QUICKSCANGAMELIST 10741
#define MENU_INPUT_P1_SOCDN 10750
#define MENU_INPUT_P1_SOCDLF 10751
#define MENU_INPUT_P1_SOCDLE 10752
#define MENU_INPUT_P1_SOCDF 10753
#define MENU_INPUT_P1_SOCDU 10754
#define MENU_INPUT_P1_SOCDDL 10755
#define MENU_INPUT_P2_SOCDN 10756
#define MENU_INPUT_P2_SOCDLF 10757
#define MENU_INPUT_P2_SOCDLE 10758
#define MENU_INPUT_P2_SOCDF 10759
#define MENU_INPUT_P2_SOCDU 10760
#define MENU_INPUT_P2_SOCDDL 10761
#define MENU_INPUT_P3_SOCDN 10762
#define MENU_INPUT_P3_SOCDLF 10763
#define MENU_INPUT_P3_SOCDLE 10764
#define MENU_INPUT_P3_SOCDF 10765
#define MENU_INPUT_P3_SOCDU 10766
#define MENU_INPUT_P3_SOCDDL 10767
#define MENU_INPUT_P4_SOCDN 10768
#define MENU_INPUT_P4_SOCDLF 10769
#define MENU_INPUT_P4_SOCDLE 10770
#define MENU_INPUT_P4_SOCDF 10771
#define MENU_INPUT_P4_SOCDU 10772
#define MENU_INPUT_P4_SOCDDL 10773
#define MENU_INPUT_P5_SOCDN 10774
#define MENU_INPUT_P5_SOCDLF 10775
#define MENU_INPUT_P5_SOCDLE 10776
#define MENU_INPUT_P5_SOCDF 10777
#define MENU_INPUT_P5_SOCDU 10778
#define MENU_INPUT_P5_SOCDDL 10779
#define MENU_INPUT_P6_SOCDN 10780
#define MENU_INPUT_P6_SOCDLF 10781
#define MENU_INPUT_P6_SOCDLE 10782
#define MENU_INPUT_P6_SOCDF 10783
#define MENU_INPUT_P6_SOCDU 10784
#define MENU_INPUT_P6_SOCDDL 10785
#define MENU_INPUT_ALL_DEFAULT 10786
#define MENU_INPUT_P1_DISABLE 10750
#define MENU_INPUT_P1_SOCDN 10751
#define MENU_INPUT_P1_SOCDLF 10752
#define MENU_INPUT_P1_SOCDLE 10753
#define MENU_INPUT_P1_SOCDF 10754
#define MENU_INPUT_P1_SOCDU 10755
#define MENU_INPUT_P1_SOCDDL 10756
#define MENU_INPUT_P2_DISABLE 10757
#define MENU_INPUT_P2_SOCDN 10758
#define MENU_INPUT_P2_SOCDLF 10759
#define MENU_INPUT_P2_SOCDLE 10760
#define MENU_INPUT_P2_SOCDF 10761
#define MENU_INPUT_P2_SOCDU 10762
#define MENU_INPUT_P2_SOCDDL 10763
#define MENU_INPUT_P3_DISABLE 10764
#define MENU_INPUT_P3_SOCDN 10765
#define MENU_INPUT_P3_SOCDLF 10766
#define MENU_INPUT_P3_SOCDLE 10767
#define MENU_INPUT_P3_SOCDF 10768
#define MENU_INPUT_P3_SOCDU 10769
#define MENU_INPUT_P3_SOCDDL 10770
#define MENU_INPUT_P4_DISABLE 10771
#define MENU_INPUT_P4_SOCDN 10772
#define MENU_INPUT_P4_SOCDLF 10773
#define MENU_INPUT_P4_SOCDLE 10774
#define MENU_INPUT_P4_SOCDF 10775
#define MENU_INPUT_P4_SOCDU 10776
#define MENU_INPUT_P4_SOCDDL 10777
#define MENU_INPUT_P5_DISABLE 10778
#define MENU_INPUT_P5_SOCDN 10779
#define MENU_INPUT_P5_SOCDLF 10780
#define MENU_INPUT_P5_SOCDLE 10781
#define MENU_INPUT_P5_SOCDF 10782
#define MENU_INPUT_P5_SOCDU 10783
#define MENU_INPUT_P5_SOCDDL 10784
#define MENU_INPUT_P6_DISABLE 10785
#define MENU_INPUT_P6_SOCDN 10786
#define MENU_INPUT_P6_SOCDLF 10787
#define MENU_INPUT_P6_SOCDLE 10788
#define MENU_INPUT_P6_SOCDF 10789
#define MENU_INPUT_P6_SOCDU 10790
#define MENU_INPUT_P6_SOCDDL 10791
#define MENU_INPUT_ALL_DEFAULT 10792
#define MENU_BASIC_NORMAL 11001
#define MENU_BASIC_SCAN 11002

View File

@ -2560,43 +2560,49 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify)
SetPriorityClass(GetCurrentProcess(), nAppProcessPriority);
break;
case MENU_INPUT_P1_DISABLE:
case MENU_INPUT_P1_SOCDN:
case MENU_INPUT_P1_SOCDLF:
case MENU_INPUT_P1_SOCDLE:
case MENU_INPUT_P1_SOCDF:
case MENU_INPUT_P1_SOCDU:
case MENU_INPUT_P1_SOCDDL:
case MENU_INPUT_P2_DISABLE:
case MENU_INPUT_P2_SOCDN:
case MENU_INPUT_P2_SOCDLF:
case MENU_INPUT_P2_SOCDLE:
case MENU_INPUT_P2_SOCDF:
case MENU_INPUT_P2_SOCDU:
case MENU_INPUT_P2_SOCDDL:
case MENU_INPUT_P3_DISABLE:
case MENU_INPUT_P3_SOCDN:
case MENU_INPUT_P3_SOCDLF:
case MENU_INPUT_P3_SOCDLE:
case MENU_INPUT_P3_SOCDF:
case MENU_INPUT_P3_SOCDU:
case MENU_INPUT_P3_SOCDDL:
case MENU_INPUT_P4_DISABLE:
case MENU_INPUT_P4_SOCDN:
case MENU_INPUT_P4_SOCDLF:
case MENU_INPUT_P4_SOCDLE:
case MENU_INPUT_P4_SOCDF:
case MENU_INPUT_P4_SOCDU:
case MENU_INPUT_P4_SOCDDL:
case MENU_INPUT_P5_DISABLE:
case MENU_INPUT_P5_SOCDN:
case MENU_INPUT_P5_SOCDLF:
case MENU_INPUT_P5_SOCDLE:
case MENU_INPUT_P5_SOCDF:
case MENU_INPUT_P5_SOCDU:
case MENU_INPUT_P5_SOCDDL:
case MENU_INPUT_P6_DISABLE:
case MENU_INPUT_P6_SOCDN:
case MENU_INPUT_P6_SOCDLF:
case MENU_INPUT_P6_SOCDLE:
case MENU_INPUT_P6_SOCDF:
case MENU_INPUT_P6_SOCDU:
case MENU_INPUT_P6_SOCDDL: {
const INT32 nOffset = id - MENU_INPUT_P1_SOCDN, nCount = (MENU_INPUT_P6_SOCDDL - MENU_INPUT_P1_SOCDN + 1) / (sizeof(nSocd) / sizeof(nSocd[0]));
const INT32 nOffset = id - MENU_INPUT_P1_DISABLE, nCount = (MENU_INPUT_P6_SOCDDL - MENU_INPUT_P1_DISABLE + 1) / (sizeof(nSocd) / sizeof(nSocd[0]));
nSocd[nOffset / nCount] = nOffset % nCount;
break;
}
@ -2604,7 +2610,7 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify)
case MENU_INPUT_ALL_DEFAULT: {
const INT32 nCount = sizeof(nSocd) / sizeof(nSocd[0]);
for (INT32 i = 0; i < nCount; i++) {
nSocd[i] = 2;
nSocd[i] = 3;
}
break;
}