Skip to content

Commit

Permalink
clear opposite wip (#1626)
Browse files Browse the repository at this point in the history
  • Loading branch information
barbudreadmon authored Jan 4, 2024
1 parent 30c6654 commit c3531b7
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 64 deletions.
29 changes: 29 additions & 0 deletions src/burn/devices/joyprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,33 @@ struct HoldCoin {
}
};

template <int N>
struct ClearOpposite {
UINT8 prev[N<<1];

void reset() {
memset(&prev, 0, sizeof(prev));
}

void scan() {
SCAN_VAR(prev);
}

void checkbit(UINT8 n, UINT8 &inp, UINT8 bit) {
// When opposites become pressed simultaneously,
// remove the previously stored direction if it exists,
// cancel each other direction otherwise
if ((inp & bit) == bit)
inp &= (prev[n] ? (inp ^ prev[n]) : ~bit);
// Store direction anytime it's pressed without its opposite
else if (inp & bit)
prev[n] = inp & bit;
}

void check(UINT8 num, UINT8 &inp, UINT8 bit1, UINT8 bit2) {
checkbit((num<<1) , inp, bit1);
checkbit((num<<1)+1, inp, bit2);
}
};

#endif
2 changes: 2 additions & 0 deletions src/burn/drv/capcom/cps.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ extern INT32 Port6SoundWrite;
extern INT32 CpsBootlegEEPROM;
extern INT32 Cps2Turbo;

extern ClearOpposite<8> clear_opposite;

extern UINT8* CpsEncZRom;

INT32 CpsRwInit();
Expand Down
2 changes: 2 additions & 0 deletions src/burn/drv/capcom/cps_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ static INT32 DrvReset()

nCpsCyclesExtra = 0;

clear_opposite.reset();

if (((Cps == 2) && !Cps2DisableQSnd) || Cps1Qs == 1) { // Sound init (QSound)
QsndReset();
}
Expand Down
30 changes: 12 additions & 18 deletions src/burn/drv/capcom/cps_rw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ INT32 Port6SoundWrite = 0;
INT32 CpsBootlegEEPROM = 0;
INT32 Cps2Turbo = 0;

ClearOpposite<8> clear_opposite;

CpsRWSoundCommandCallback CpsRWSoundCommandCallbackFunction = NULL;

static INT32 nCalc[2] = {0, 0};
Expand Down Expand Up @@ -88,6 +90,8 @@ void CpsRwScan()
SCAN_VAR(nPrevInp001);
}

clear_opposite.scan();

SCAN_VAR(n664001);
SCAN_VAR(nCalc);
SCAN_VAR(nRasterLine);
Expand Down Expand Up @@ -559,16 +563,6 @@ INT32 CpsRwExit()
return 0;
}

inline static void StopOpposite(UINT8* pInput)
{
if ((*pInput & 0x03) == 0x03) {
*pInput &= ~0x03;
}
if ((*pInput & 0x0C) == 0x0C) {
*pInput &= ~0x0C;
}
}

INT32 CpsRwGetInp()
{
// Compile separate buttons into Inpxxx
Expand Down Expand Up @@ -645,8 +639,8 @@ INT32 CpsRwGetInp()
CpsPaddle1 += CpsInpPaddle1 / 0x80; // add +-8 maximum to paddle-accumulator
}

StopOpposite(&Inp000);
StopOpposite(&Inp001);
clear_opposite.check(0, Inp000, 0x0c, 0x03);
clear_opposite.check(1, Inp001, 0x0c, 0x03);

// Ghouls uses a 4-way stick
if (Ghouls) {
Expand Down Expand Up @@ -677,19 +671,19 @@ INT32 CpsRwGetInp()

if (nMaxPlayers > 2) {
if (Cps == 2) {
StopOpposite(&Inp011);
clear_opposite.check(2, Inp011, 0x0c, 0x03);
if (nMaxPlayers == 4) {
StopOpposite(&Inp010);
clear_opposite.check(3, Inp010, 0x0c, 0x03);
}
} else {
StopOpposite(&Inp177);
clear_opposite.check(4, Inp177, 0x0c, 0x03);
if (nMaxPlayers == 4) {
StopOpposite(&Inp179);
clear_opposite.check(5, Inp179, 0x0c, 0x03);
}
if (Cps1Qs) {
StopOpposite(&Inpc001);
clear_opposite.check(6, Inpc001, 0x0c, 0x03);
if (nMaxPlayers == 4) {
StopOpposite(&Inpc003);
clear_opposite.check(7, Inpc003, 0x0c, 0x03);
}
}
}
Expand Down
46 changes: 8 additions & 38 deletions src/burn/drv/neogeo/neo_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ UINT8 NeoJoy3[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
UINT8 NeoJoy4[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
UINT16 NeoAxis[2] = { 0, 0 };
UINT8 NeoInput[32] = { 0, };
UINT8 NeoInput_previous[32] = { 0, }; // GSC2007
UINT8 NeoDiag[2] = { 0, 0 };
UINT8 NeoDebugDip[2] = { 0, 0 };
UINT8 NeoReset = 0, NeoSystem = 0;
UINT8 NeoCDBios = 0;
static ClearOpposite<4> clear_opposite;

static UINT8 OldDebugDip[2] = { 0, 0 };

Expand Down Expand Up @@ -1540,6 +1540,7 @@ INT32 NeoScan(INT32 nAction, INT32* pnMin)
SCAN_VAR(nInputSelect);

SCAN_OFF(NeoInputBank, NeoInput, nAction);
clear_opposite.scan();

SCAN_VAR(nAnalogAxis);

Expand Down Expand Up @@ -3766,6 +3767,8 @@ static INT32 neogeoReset()

nCyclesExtra[0] = nCyclesExtra[1] = 0;

clear_opposite.reset();

{
SekOpen(0);
ZetOpen(0);
Expand Down Expand Up @@ -4502,44 +4505,11 @@ INT32 NeoRender()
return 0;
}

inline static void NeoClearOpposites(UINT8* nJoystickInputs,UINT8* nJoystickInputs_previous,UINT8* nJoystickInputs_previous_lr,UINT8* nJoystickInputs_previous_ud) // GSC2007 add
{
if((*nJoystickInputs & 0x0C) == 0x0C)
{
*nJoystickInputs &= *nJoystickInputs ^ *nJoystickInputs_previous_lr; //When left and right are pressed simultaneously, remove the interference items in *nJoystickInputs_previous_lr to obtain the actual required corrective input
}
else if(*nJoystickInputs & 0x0C)
{
*nJoystickInputs_previous_lr = *nJoystickInputs & 0x0C; //Only record the input when left and right are NOT pressed simultaneously
}
if((*nJoystickInputs & 0x03) == 0x03)
{
*nJoystickInputs &= *nJoystickInputs ^ *nJoystickInputs_previous_ud; //Same as above
}
else if(*nJoystickInputs & 0x03)
{
*nJoystickInputs_previous_ud = *nJoystickInputs & 0x03; //Same as above
}

//original code
if ((*nJoystickInputs & 0x03) == 0x03)
*nJoystickInputs &= ~0x03;
if ((*nJoystickInputs & 0x0C) == 0x0C)
*nJoystickInputs &= ~0x0C;

if (((*nJoystickInputs | *nJoystickInputs_previous) & 0x0C) == 0x0C)
*nJoystickInputs &= ~0x0C; //When switching left and right, the first frame is mutually exclusive
if (((*nJoystickInputs | *nJoystickInputs_previous) & 0x03) == 0x03)
*nJoystickInputs &= ~0x03; //When switching down and up, the first frame is mutually exclusive
}

static void NeoStandardInputs(INT32 nBank)
{
if (nBank) {
NeoInput[ 8] = 0x00; // Player 1
NeoInput[ 9] = 0x00; // Player 2
NeoInput_previous[ 0] = NeoInput[ 8]; // GSC2007 add
NeoInput_previous[ 3] = NeoInput[ 9]; // GSC2007 add
NeoInput[10] = 0x00; // Buttons
NeoInput[11] = 0x00; //
for (INT32 i = 0; i < 8; i++) {
Expand All @@ -4548,8 +4518,8 @@ static void NeoStandardInputs(INT32 nBank)
NeoInput[10] |= (NeoButton3[i] & 1) << i;
NeoInput[11] |= (NeoButton4[i] & 1) << i;
}
NeoClearOpposites(&NeoInput[ 8],&NeoInput_previous[ 0],&NeoInput_previous[ 1],&NeoInput_previous[ 2]);// GSC2007 add
NeoClearOpposites(&NeoInput[ 9],&NeoInput_previous[ 3],&NeoInput_previous[ 4],&NeoInput_previous[ 5]);// GSC2007 add
clear_opposite.check(0, NeoInput[ 8], 0x0c, 0x03);
clear_opposite.check(1, NeoInput[ 9], 0x0c, 0x03);

if (NeoDiag[1]) {
NeoInput[13] |= 0x80;
Expand All @@ -4565,8 +4535,8 @@ static void NeoStandardInputs(INT32 nBank)
NeoInput[ 2] |= (NeoButton1[i] & 1) << i;
NeoInput[ 3] |= (NeoButton2[i] & 1) << i;
}
NeoClearOpposites(&NeoInput[ 0],&NeoInput_previous[ 6],&NeoInput_previous[ 7],&NeoInput_previous[ 8]);// GSC2007 add
NeoClearOpposites(&NeoInput[ 1],&NeoInput_previous[ 9],&NeoInput_previous[ 10],&NeoInput_previous[ 11]);// GSC2007 add
clear_opposite.check(2, NeoInput[ 0], 0x0c, 0x03);
clear_opposite.check(3, NeoInput[ 1], 0x0c, 0x03);
if (NeoDiag[0]) {
NeoInput[ 5] |= 0x80;
}
Expand Down
14 changes: 6 additions & 8 deletions src/burn/drv/pgm/pgm_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ UINT8 PgmBtn2[8] = {0,0,0,0,0,0,0,0};
UINT8 PgmInput[9] = {0,0,0,0,0,0,0,0,0};
UINT8 PgmReset = 0;
static HoldCoin<4> hold_coin;
static ClearOpposite<4> clear_opposite;

INT32 nPGM68KROMLen = 0;
INT32 nPGMTileROMLen = 0;
Expand Down Expand Up @@ -677,6 +678,7 @@ static INT32 PgmDoReset()
}

hold_coin.reset();
clear_opposite.reset();

nCyclesDone[0] = nCyclesDone[1] = nCyclesDone[2] = 0;

Expand Down Expand Up @@ -1051,14 +1053,9 @@ INT32 pgmFrame()
}

// clear opposites
if ((PgmInput[0] & 0x06) == 0x06) PgmInput[0] &= 0xf9; // up/down
if ((PgmInput[0] & 0x18) == 0x18) PgmInput[0] &= 0xe7; // left/right
if ((PgmInput[1] & 0x06) == 0x06) PgmInput[1] &= 0xf9;
if ((PgmInput[1] & 0x18) == 0x18) PgmInput[1] &= 0xe7;
if ((PgmInput[2] & 0x06) == 0x06) PgmInput[2] &= 0xf9;
if ((PgmInput[2] & 0x18) == 0x18) PgmInput[2] &= 0xe7;
if ((PgmInput[3] & 0x06) == 0x06) PgmInput[3] &= 0xf9;
if ((PgmInput[3] & 0x18) == 0x18) PgmInput[3] &= 0xe7;
for (INT32 i = 0; i < 4; i++) {
clear_opposite.check(i, PgmInput[i], 0x06, 0x18);
}

hold_coin.check(0, PgmInput[4], 1, 7);
hold_coin.check(1, PgmInput[4], 2, 7);
Expand Down Expand Up @@ -1271,6 +1268,7 @@ INT32 pgmScan(INT32 nAction,INT32 *pnMin)
v3021Scan();

hold_coin.scan();
clear_opposite.scan();

SCAN_VAR(nPgmCurrentBios);

Expand Down

3 comments on commit c3531b7

@crashGG
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a long period of testing (kof 94 ~ 02 with 2 frames runahead,doubledr with 1 frame runahead,sf2 with 3 frames runahead) using Retroarch + fbneo core,It seems that no bugs have been found. Maybe this code could promoted to other fighting games.like sfiii3, pwrinst2 etc.

@barbudreadmon
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, i had been wondering about this since i ended up simplifying the code you committed quite a bit (some parts weren't making much sense to me).
Yes, porting this to other drivers should be straightforward, i'll take a look at the ones you mentioned soon.

@barbudreadmon
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cps3 and pwrinst2 done.
I added support for non-UINT8 inputs. I also made it so that the ClearOpposite declaration matches the check function's max value you'll need for num args (previously it felt a bit like a magic number).
I believe you'll be able to implement this yourself if you need it in other drivers ?

Please sign in to comment.