Step 2: add SOCD scenes to the menu options

This commit is contained in:
taoenwen 2025-07-04 02:57:25 +08:00
parent 20a9a17b1d
commit ac660af894
13 changed files with 252 additions and 33 deletions

View File

@ -2,6 +2,8 @@
#include "burnint.h"
#include "joyprocess.h"
INT32 nSocd[6] = { 2,2,2,2,2,2 }; // 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)
{ // limitations: 4 players max., processes 8-bit inputs only!

View File

@ -29,6 +29,9 @@ void CompileInput(UINT8 **input, void *output, INT32 num, INT32 bits, UINT32 *in
// for analog pedals, allows a mapped digital button to work
#define INPUT_MIGHTBEDIGITAL 0x04
// joyprocess.cpp
extern INT32 nSocd[6];
// Need something else / looking for:
// analog dial, paddle & trackball, use BurnTrackball device (burn_gun.h)
// lightgun, use BurnGun device (also burn_gun.h)
@ -161,11 +164,11 @@ struct ClearOpposite {
// 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 &= (inp ^ prev_a[n]);
if (mask_a == val_a) 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) inp &= (inp ^ prev_b[n]);
if (mask_b == val_b) inp &= ~prev_b[n];
else if (mask_b) prev_b[n] = mask_b;
neu(n, inp, val_a, val_b);
@ -175,8 +178,15 @@ struct ClearOpposite {
void lie(UINT8 n, T& inp, T val_a, T val_b) {
lif(n, inp, val_a, val_b);
const T inp_u = (1 << 0), inp_d = (1 << 1), inp_l = (1 << 2), inp_r = (1 << 3);
const T inp_ud = (inp_u | inp_d), inp_lr = (inp_l & inp_r);
const T val = (val_a < val_b) ? val_a : val_b;
INT32 i;
for (i = 0; i < 8; i++) {
if (val & (1 << i)) break; // Find up
}
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))) ||
@ -198,11 +208,11 @@ struct ClearOpposite {
// 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];
if (mask_a == val_a) inp &= (~val_a) | prev_a[n];
else if (mask_a) prev_a[n] = mask_a;
const T mask_b = inp & val_b;
if (mask_b == val_b) inp &= ~val_b | prev_b[n];
if (mask_b == val_b) inp &= (~val_b) | prev_b[n];
else if (mask_b) prev_b[n] = mask_b;
neu(n, inp, val_a, val_b);
@ -210,10 +220,50 @@ struct ClearOpposite {
// SOCD - Up Priority (Up-override Down)
void uod(UINT8 n, T& inp, T val_a, T val_b) {
const T val_u = (inp & 1); // up = 0x01
const T val = (val_a < val_b) ? val_a : val_b;
INT32 i;
for (i = 0; i < 8; 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 (val_u) inp |= val_u;
if (inp_u) inp |= inp_u;
neu(n, inp, val_a, val_b);
}
// 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 i;
for (i = 0; i < 8; i++) {
if (val & (1 << i)) break; // Find up
}
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);
}
@ -221,14 +271,19 @@ struct ClearOpposite {
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)
switch (socd) {
case 0: neu((num), inp, val1, val2); break;
case 1: lif((num), inp, val1, val2); break;
case 2: lie((num), inp, val1, val2); break;
case 3: fip((num), inp, val1, val2); break;
case 4: uod((num), inp, val1, val2); break;
default: break;
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;
}
#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);
clear_opposite.check(1, Inp001, 0x0c, 0x03);
clear_opposite.check(0, Inp000, 0x0c, 0x03, nSocd[0]);
clear_opposite.check(1, Inp001, 0x0c, 0x03, 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);
clear_opposite.check(2, Inp011, 0x0c, 0x03, nSocd[2]);
if (nMaxPlayers == 4) {
clear_opposite.check(3, Inp010, 0x0c, 0x03);
clear_opposite.check(3, Inp010, 0x0c, 0x03, nSocd[3]);
}
} else {
clear_opposite.check(4, Inp177, 0x0c, 0x03);
clear_opposite.check(4, Inp177, 0x0c, 0x03, nSocd[2]);
if (nMaxPlayers == 4) {
clear_opposite.check(5, Inp179, 0x0c, 0x03);
clear_opposite.check(5, Inp179, 0x0c, 0x03, nSocd[3]);
}
if (Cps1Qs) {
clear_opposite.check(6, Inpc001, 0x0c, 0x03);
clear_opposite.check(6, Inpc001, 0x0c, 0x03, nSocd[2]);
if (nMaxPlayers == 4) {
clear_opposite.check(7, Inpc003, 0x0c, 0x03);
clear_opposite.check(7, Inpc003, 0x0c, 0x03, nSocd[3]);
}
}
}

View File

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

View File

@ -2127,8 +2127,8 @@ INT32 cps3Frame()
}
// Clear Opposites
clear_opposite.check(0, Cps3Input[0], 0x0003, 0x000c);
clear_opposite.check(1, Cps3Input[0], 0x0300, 0x0c00);
clear_opposite.check(0, Cps3Input[0], 0x0003, 0x000c, nSocd[0]);
clear_opposite.check(1, Cps3Input[0], 0x0300, 0x0c00, nSocd[1]);
Sh2NewFrame();

View File

@ -4536,8 +4536,8 @@ INT32 NeoRender()
static void NeoStandardInputs(INT32 nBank)
{
if (nBank) {
NeoInput[ 8] = 0x00; // Player 1
NeoInput[ 9] = 0x00; // Player 2
NeoInput[ 8] = 0x00; // Player 3
NeoInput[ 9] = 0x00; // Player 4
NeoInput[10] = 0x00; // Buttons
NeoInput[11] = 0x00; //
for (INT32 i = 0; i < 8; i++) {
@ -4546,8 +4546,8 @@ static void NeoStandardInputs(INT32 nBank)
NeoInput[10] |= (NeoButton3[i] & 1) << i;
NeoInput[11] |= (NeoButton4[i] & 1) << i;
}
clear_opposite.check(0, NeoInput[ 8], 0x0c, 0x03);
clear_opposite.check(1, NeoInput[ 9], 0x0c, 0x03);
clear_opposite.check(0, NeoInput[ 8], 0x0c, 0x03, nSocd[2]);
clear_opposite.check(1, NeoInput[ 9], 0x0c, 0x03, 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(2, NeoInput[ 0], 0x0c, 0x03);
clear_opposite.check(3, NeoInput[ 1], 0x0c, 0x03);
clear_opposite.check(2, NeoInput[ 0], 0x0c, 0x03, nSocd[0]);
clear_opposite.check(3, NeoInput[ 1], 0x0c, 0x03, nSocd[1]);
if (NeoDiag[0]) {
NeoInput[ 5] |= 0x80;
}

View File

@ -1101,7 +1101,7 @@ INT32 pgmFrame()
// clear opposites
for (INT32 i = 0; i < 4; i++) {
clear_opposite.check(i, PgmInput[i], 0x06, 0x18);
clear_opposite.check(i, PgmInput[i], 0x06, 0x18, nSocd[i]);
}
hold_coin.check(0, PgmInput[4], 1, 7);

View File

@ -25,6 +25,7 @@
#include "title.h"
#include "burn.h"
#include "joyprocess.h"
// ---------------------------------------------------------------------------
// OS dependent functionality

View File

@ -1261,6 +1261,64 @@ BEGIN
MENUITEM "512MB", MENU_INPUT_REWIND_512MB
MENUITEM "768MB", MENU_INPUT_REWIND_768MB
MENUITEM "1GB", MENU_INPUT_REWIND_1GB
END
MENUITEM SEPARATOR
POPUP "SOCD Settings"
BEGIN
POPUP "Player 1"
BEGIN
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
MENUITEM "P1 SOCD-F", MENU_INPUT_P1_SOCDF
MENUITEM "P1 SOCD-U", MENU_INPUT_P1_SOCDU
MENUITEM "P1 SOCD-D+L", MENU_INPUT_P1_SOCDDL
END
POPUP "Player 2"
BEGIN
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
MENUITEM "P2 SOCD-F", MENU_INPUT_P2_SOCDF
MENUITEM "P2 SOCD-U", MENU_INPUT_P2_SOCDU
MENUITEM "P2 SOCD-D+L", MENU_INPUT_P2_SOCDDL
END
POPUP "Player 3"
BEGIN
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
MENUITEM "P3 SOCD-F", MENU_INPUT_P3_SOCDF
MENUITEM "P3 SOCD-U", MENU_INPUT_P3_SOCDU
MENUITEM "P3 SOCD-D+L", MENU_INPUT_P3_SOCDDL
END
POPUP "Player 4"
BEGIN
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
MENUITEM "P4 SOCD-F", MENU_INPUT_P4_SOCDF
MENUITEM "P4 SOCD-U", MENU_INPUT_P4_SOCDU
MENUITEM "P4 SOCD-D+L", MENU_INPUT_P4_SOCDDL
END
POPUP "Player 5"
BEGIN
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
MENUITEM "P5 SOCD-F", MENU_INPUT_P5_SOCDF
MENUITEM "P5 SOCD-U", MENU_INPUT_P5_SOCDU
MENUITEM "P5 SOCD-D+L", MENU_INPUT_P5_SOCDDL
END
POPUP "Player 6"
BEGIN
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
MENUITEM "P6 SOCD-F", MENU_INPUT_P6_SOCDF
MENUITEM "P6 SOCD-U", MENU_INPUT_P6_SOCDU
MENUITEM "P6 SOCD-D+L", MENU_INPUT_P6_SOCDDL
END
END
MENUITEM SEPARATOR
MENUITEM "Map game inputs...\tF5", MENU_INPUT, GRAYED

View File

@ -519,6 +519,14 @@ int ConfigAppLoad()
VAR(nPlayerDefaultControls[3]);
STR(szPlayerDefaultIni[3]);
// SOCD
VAR(nSocd[0]);
VAR(nSocd[1]);
VAR(nSocd[2]);
VAR(nSocd[3]);
VAR(nSocd[4]);
VAR(nSocd[5]);
#undef DRV
#undef PAT
#undef STR
@ -1005,6 +1013,14 @@ int ConfigAppSave()
VAR(nPlayerDefaultControls[3]);
STR(szPlayerDefaultIni[3]);
_ftprintf(h, _T("\n// Index of SOCD settings for each player.\n"));
VAR(nSocd[0]);
VAR(nSocd[1]);
VAR(nSocd[2]);
VAR(nSocd[3]);
VAR(nSocd[4]);
VAR(nSocd[5]);
_ftprintf(h, _T("\n\n\n"));
#undef DRV

View File

@ -1268,6 +1268,15 @@ void MenuUpdate()
if (nRewindMemory == 1024) var = MENU_INPUT_REWIND_1GB;
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;
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;
CheckMenuRadioItem(hMenu, startId, endId, var, MF_BYCOMMAND);
}
MenuUpdateVolume(); // also called in run.cpp by alt+ / alt-
#ifdef BUILD_A68K

View File

@ -823,6 +823,43 @@
#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_BASIC_NORMAL 11001
#define MENU_BASIC_SCAN 11002
#define MENU_SCAN50 11003

View File

@ -2560,6 +2560,47 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify)
SetPriorityClass(GetCurrentProcess(), nAppProcessPriority);
break;
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_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_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_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_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_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]));
nSocd[nOffset / nCount] = nOffset % nCount;
break;
}
case MENU_CLRMAME_PRO_XML:
if (UseDialogs()) {
CreateDatfileWindows(DAT_ARCADE_ONLY);