GBA: Add flag to allow opposing inputs in key callbacks (fixes #2334)

This commit is contained in:
Vicki Pfau 2021-11-10 13:12:55 -08:00
parent d2bf28b871
commit 858267da3f
4 changed files with 11 additions and 4 deletions

View File

@ -195,6 +195,7 @@ struct mAVStream {
struct mKeyCallback { struct mKeyCallback {
uint16_t (*readKeys)(struct mKeyCallback*); uint16_t (*readKeys)(struct mKeyCallback*);
bool requireOpposingDirections;
}; };
enum mPeripheral { enum mPeripheral {

View File

@ -23,6 +23,8 @@ struct GBASIOPlayer {
int txPosition; int txPosition;
struct mTimingEvent event; struct mTimingEvent event;
struct GBASIOPlayerKeyCallback callback; struct GBASIOPlayerKeyCallback callback;
bool oldOpposingDirections;
struct mKeyCallback* oldCallback;
}; };
void GBASIOPlayerInit(struct GBASIOPlayer* gbp); void GBASIOPlayerInit(struct GBASIOPlayer* gbp);

View File

@ -743,11 +743,15 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
callbacks->keysRead(callbacks->context); callbacks->keysRead(callbacks->context);
} }
} }
bool allowOpposingDirections = gba->allowOpposingDirections;
if (gba->keyCallback) { if (gba->keyCallback) {
gba->keysActive = gba->keyCallback->readKeys(gba->keyCallback); gba->keysActive = gba->keyCallback->readKeys(gba->keyCallback);
if (!allowOpposingDirections) {
allowOpposingDirections = gba->keyCallback->requireOpposingDirections;
}
} }
uint16_t input = gba->keysActive; uint16_t input = gba->keysActive;
if (!gba->allowOpposingDirections) { if (!allowOpposingDirections) {
unsigned rl = input & 0x030; unsigned rl = input & 0x030;
unsigned ud = input & 0x0C0; unsigned ud = input & 0x0C0;
input &= 0x30F; input &= 0x30F;

View File

@ -41,6 +41,7 @@ static const uint32_t _gbpTxData[] = {
void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { void GBASIOPlayerInit(struct GBASIOPlayer* gbp) {
gbp->callback.d.readKeys = _gbpRead; gbp->callback.d.readKeys = _gbpRead;
gbp->callback.d.requireOpposingDirections = true;
gbp->callback.p = gbp; gbp->callback.p = gbp;
gbp->d.init = 0; gbp->d.init = 0;
gbp->d.deinit = 0; gbp->d.deinit = 0;
@ -72,10 +73,8 @@ void GBASIOPlayerUpdate(struct GBA* gba) {
if (GBASIOPlayerCheckScreen(&gba->video)) { if (GBASIOPlayerCheckScreen(&gba->video)) {
++gba->sio.gbp.inputsPosted; ++gba->sio.gbp.inputsPosted;
gba->sio.gbp.inputsPosted %= 3; gba->sio.gbp.inputsPosted %= 3;
gba->keyCallback = &gba->sio.gbp.callback.d;
} else { } else {
// TODO: Save and restore gba->keyCallback = gba->sio.gbp.oldCallback;
gba->keyCallback = 0;
} }
gba->sio.gbp.txPosition = 0; gba->sio.gbp.txPosition = 0;
return; return;
@ -86,6 +85,7 @@ void GBASIOPlayerUpdate(struct GBA* gba) {
if (GBASIOPlayerCheckScreen(&gba->video)) { if (GBASIOPlayerCheckScreen(&gba->video)) {
gba->memory.hw.devices |= HW_GB_PLAYER; gba->memory.hw.devices |= HW_GB_PLAYER;
gba->sio.gbp.inputsPosted = 0; gba->sio.gbp.inputsPosted = 0;
gba->sio.gbp.oldCallback = gba->keyCallback;
gba->keyCallback = &gba->sio.gbp.callback.d; gba->keyCallback = &gba->sio.gbp.callback.d;
// TODO: Check if the SIO driver is actually used first // TODO: Check if the SIO driver is actually used first
GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, SIO_NORMAL_32); GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, SIO_NORMAL_32);