GBA SIO: Start adding new SIO callbacks for revamped API

This commit is contained in:
Vicki Pfau 2024-05-16 15:11:19 -07:00
parent 4cfa9c6545
commit 451da0f8a4
6 changed files with 123 additions and 5 deletions

View File

@ -110,8 +110,13 @@ struct GBASIODriver {
bool (*init)(struct GBASIODriver* driver);
void (*deinit)(struct GBASIODriver* driver);
void (*reset)(struct GBASIODriver* driver);
bool (*load)(struct GBASIODriver* driver);
bool (*unload)(struct GBASIODriver* driver);
void (*setMode)(struct GBASIODriver* driver, enum GBASIOMode mode);
bool (*handlesMode)(struct GBASIODriver* driver, enum GBASIOMode mode);
int (*connectedDevices)(struct GBASIODriver* driver);
int (*deviceId)(struct GBASIODriver* driver);
uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value);
};

View File

@ -35,6 +35,8 @@ enum {
static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver);
static uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver);
static void _battlechipTransfer(struct GBASIOBattlechipGate* gate);
static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate);
@ -45,6 +47,10 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
gate->d.load = GBASIOBattlechipGateLoad;
gate->d.unload = NULL;
gate->d.writeRegister = GBASIOBattlechipGateWriteRegister;
gate->d.setMode = NULL;
gate->d.handlesMode = GBASIOBattlechipGateHandlesMode;
gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices;
gate->d.deviceId = NULL;
gate->event.context = gate;
gate->event.callback = _battlechipTransferEvent;
@ -82,6 +88,22 @@ uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t
return value;
}
static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
UNUSED(driver);
switch (mode) {
case GBA_SIO_NORMAL_32:
case GBA_SIO_MULTI:
return true;
default:
return false;
}
}
static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) {
UNUSED(driver);
return 1;
}
void _battlechipTransfer(struct GBASIOBattlechipGate* gate) {
int32_t cycles;
if (gate->d.p->mode == GBA_SIO_NORMAL_32) {

View File

@ -103,6 +103,15 @@ void GBASIOReset(struct GBASIO* sio) {
if (sio->activeDriver && sio->activeDriver->unload) {
sio->activeDriver->unload(sio->activeDriver);
}
if (sio->drivers.multiplayer && sio->drivers.multiplayer->reset) {
sio->drivers.multiplayer->reset(sio->drivers.multiplayer);
}
if (sio->drivers.joybus && sio->drivers.joybus->reset) {
sio->drivers.joybus->reset(sio->drivers.joybus);
}
if (sio->drivers.normal && sio->drivers.normal->reset) {
sio->drivers.normal->reset(sio->drivers.normal);
}
sio->rcnt = RCNT_INITIAL;
sio->siocnt = 0;
sio->mode = -1;

View File

@ -14,6 +14,8 @@
static uint16_t _gbpRead(struct mKeyCallback*);
static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static int _gbpSioConnectedDevices(struct GBASIODriver* driver);
static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate);
static const uint8_t _logoPalette[] = {
@ -43,11 +45,15 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) {
gbp->callback.d.readKeys = _gbpRead;
gbp->callback.d.requireOpposingDirections = true;
gbp->callback.p = gbp;
gbp->d.init = 0;
gbp->d.deinit = 0;
gbp->d.load = 0;
gbp->d.unload = 0;
gbp->d.init = NULL;
gbp->d.deinit = NULL;
gbp->d.load = NULL;
gbp->d.unload = NULL;
gbp->d.writeRegister = _gbpSioWriteRegister;
gbp->d.setMode = NULL;
gbp->d.handlesMode = _gbpSioHandlesMode;
gbp->d.connectedDevices = _gbpSioConnectedDevices;
gbp->d.deviceId = NULL;
gbp->event.context = gbp;
gbp->event.name = "GBA SIO Game Boy Player";
gbp->event.callback = _gbpSioProcessEvents;
@ -125,6 +131,16 @@ uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uin
return value;
}
static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
UNUSED(driver);
return mode == GBA_SIO_NORMAL_32;
}
static int _gbpSioConnectedDevices(struct GBASIODriver* driver) {
UNUSED(driver);
return 1;
}
void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
UNUSED(timing);
UNUSED(cyclesLate);

View File

@ -9,6 +9,8 @@
#include <mgba/internal/gba/io.h>
static uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value);
static bool GBASIOJOYHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static int GBASIOJOYConnectedDevices(struct GBASIODriver* driver);
void GBASIOJOYCreate(struct GBASIODriver* sio) {
sio->init = NULL;
@ -16,6 +18,10 @@ void GBASIOJOYCreate(struct GBASIODriver* sio) {
sio->load = NULL;
sio->unload = NULL;
sio->writeRegister = GBASIOJOYWriteRegister;
sio->setMode = NULL;
sio->handlesMode = GBASIOJOYHandlesMode;
sio->connectedDevices = GBASIOJOYConnectedDevices;
sio->deviceId = NULL;
}
uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value) {
@ -41,6 +47,16 @@ uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint
return value;
}
static bool GBASIOJOYHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
UNUSED(driver);
return mode == GBA_SIO_JOYBUS;
}
static int GBASIOJOYConnectedDevices(struct GBASIODriver* driver) {
UNUSED(driver);
return 1;
}
int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) {
switch (command) {
case JOY_RESET:

View File

@ -15,6 +15,10 @@ static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver);
static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver);
static bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver);
static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver);
static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver);
static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver);
static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate);
@ -38,7 +42,11 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) {
node->d.deinit = GBASIOLockstepNodeDeinit;
node->d.load = GBASIOLockstepNodeLoad;
node->d.unload = GBASIOLockstepNodeUnload;
node->d.writeRegister = 0;
node->d.setMode = GBASIOLockstepNodeSetMode;
node->d.handlesMode = GBASIOLockstepNodeHandlesMode;
node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices;
node->d.deviceId = GBASIOLockstepNodeDeviceId;
node->d.writeRegister = NULL;
}
bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) {
@ -186,6 +194,48 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) {
return true;
}
static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;
mLockstepLock(&node->p->d);
node->mode = mode;
mLockstepUnlock(&node->p->d);
}
static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
UNUSED(driver);
switch (mode) {
case GBA_SIO_NORMAL_8:
case GBA_SIO_NORMAL_32:
case GBA_SIO_MULTI:
return true;
default:
return false;
}
}
static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver) {
struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;
int attached = 0;
switch (node->mode) {
case GBA_SIO_NORMAL_8:
case GBA_SIO_NORMAL_32:
ATOMIC_LOAD(attached, node->p->attachedNormal);
break;
case GBA_SIO_MULTI:
ATOMIC_LOAD(attached, node->p->attachedMulti);
break;
default:
break;
}
return attached - 1;
}
static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver) {
struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;
return node->id;
}
static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) {
struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;