GBA SIO: Remove driver sets and driver load/unload concepts

This commit is contained in:
Vicki Pfau 2024-09-10 03:19:02 -07:00
parent f2bbf8e66c
commit 0823797671
12 changed files with 77 additions and 199 deletions

View File

@ -111,8 +111,6 @@ 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);
uint32_t (*driverId)(const struct GBASIODriver* renderer);
bool (*loadState)(struct GBASIODriver* renderer, const void* state, size_t size);
void (*saveState)(struct GBASIODriver* renderer, void** state, size_t* size);

View File

@ -62,18 +62,11 @@ DECL_BIT(GBASIORegisterRCNT, SdDirection, 5);
DECL_BIT(GBASIORegisterRCNT, SiDirection, 6);
DECL_BIT(GBASIORegisterRCNT, SoDirection, 7);
struct GBASIODriverSet {
struct GBASIODriver* normal;
struct GBASIODriver* multiplayer;
struct GBASIODriver* joybus;
};
struct GBASIO {
struct GBA* p;
enum GBASIOMode mode;
struct GBASIODriverSet drivers;
struct GBASIODriver* activeDriver;
struct GBASIODriver* driver;
uint16_t rcnt;
uint16_t siocnt;
@ -86,8 +79,7 @@ void GBASIOInit(struct GBASIO* sio);
void GBASIODeinit(struct GBASIO* sio);
void GBASIOReset(struct GBASIO* sio);
void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers);
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode);
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver);
void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value);
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value);

View File

@ -527,7 +527,7 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer
uint32_t when;
LOAD_32(when, 0, &state->hw.sioNextEvent);
if (hw->devices & HW_GB_PLAYER) {
GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32);
GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d);
}
if ((hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) && when < 0x20000) {
mTimingSchedule(&hw->p->timing, &hw->p->sio.completeEvent, when);

View File

@ -848,15 +848,15 @@ static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdat
ok = false;
}
}
if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->loadState &&
if (gba->sio.driver && gba->sio.driver->driverId && gba->sio.driver->loadState &&
mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item)) {
if ((uint32_t) item.size > sizeof(uint32_t)) {
uint32_t type;
LOAD_32(type, 0, item.data);
if (type == gba->sio.activeDriver->driverId(gba->sio.activeDriver)) {
ok = gba->sio.activeDriver->loadState(gba->sio.activeDriver,
(void*) ((uintptr_t) item.data + sizeof(uint32_t)),
item.size - sizeof(type)) && ok;
if (type == gba->sio.driver->driverId(gba->sio.driver)) {
ok = gba->sio.driver->loadState(gba->sio.driver,
(void*) ((uintptr_t) item.data + sizeof(uint32_t)),
item.size - sizeof(type)) && ok;
}
} else if (item.data) {
ok = false;
@ -886,14 +886,14 @@ static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* ext
}
size = 0;
if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->saveState) {
gba->sio.activeDriver->saveState(gba->sio.activeDriver, &buffer, &size);
if (gba->sio.driver && gba->sio.driver->driverId && gba->sio.driver->saveState) {
gba->sio.driver->saveState(gba->sio.driver, &buffer, &size);
if (size > 0 && buffer) {
struct mStateExtdataItem item;
item.size = size + sizeof(uint32_t);
item.data = malloc(item.size);
item.clean = free;
uint32_t type = gba->sio.activeDriver->driverId(gba->sio.activeDriver);
uint32_t type = gba->sio.driver->driverId(gba->sio.driver);
STORE_32(type, 0, item.data);
memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size);
mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item);
@ -963,8 +963,7 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) {
gba->luminanceSource = periph;
break;
case mPERIPH_GBA_BATTLECHIP_GATE:
GBASIOSetDriver(&gba->sio, periph, GBA_SIO_MULTI);
GBASIOSetDriver(&gba->sio, periph, GBA_SIO_NORMAL_32);
GBASIOSetDriver(&gba->sio, periph);
break;
default:
return;

View File

@ -33,7 +33,7 @@ enum {
BATTLECHIP_CONTINUE = 0xFFFF,
};
static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver);
static bool GBASIOBattlechipGateInit(struct GBASIODriver* driver);
static uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value);
static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver);
@ -41,7 +41,7 @@ static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, u
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
memset(&gate->d, 0, sizeof(gate->d));
gate->d.load = GBASIOBattlechipGateLoad;
gate->d.init = GBASIOBattlechipGateInit;
gate->d.writeSIOCNT = GBASIOBattlechipGateWriteSIOCNT;
gate->d.handlesMode = GBASIOBattlechipGateHandlesMode;
gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices;
@ -51,7 +51,7 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE;
}
bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) {
bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) {
struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver;
gate->state = BATTLECHIP_STATE_SYNC;
gate->data[0] = 0x00FE;

View File

@ -263,8 +263,8 @@ void GBAReset(struct ARMCore* cpu) {
// GB Player SIO control should not be engaged before detection, even if we already know it's GBP
gba->memory.hw.devices &= ~HW_GB_PLAYER;
if (gba->sio.drivers.normal == &gba->sio.gbp.d) {
GBASIOSetDriver(&gba->sio, NULL, GBA_SIO_NORMAL_32);
if (gba->sio.driver == &gba->sio.gbp.d) {
GBASIOSetDriver(&gba->sio, NULL);
}
bool isELF = false;

View File

@ -20,20 +20,6 @@ static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = {
static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate);
static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) {
switch (mode) {
case GBA_SIO_NORMAL_8:
case GBA_SIO_NORMAL_32:
return sio->drivers.normal;
case GBA_SIO_MULTI:
return sio->drivers.multiplayer;
case GBA_SIO_JOYBUS:
return sio->drivers.joybus;
default:
return 0;
}
}
static const char* _modeName(enum GBASIOMode mode) {
switch (mode) {
case GBA_SIO_NORMAL_8:
@ -60,31 +46,19 @@ static void _switchMode(struct GBASIO* sio) {
newMode = (enum GBASIOMode) (mode & 0xC);
}
if (newMode != sio->mode) {
struct GBASIODriver* driver = _lookupDriver(sio, newMode);
if (sio->mode != (enum GBASIOMode) -1) {
mLOG(GBA_SIO, DEBUG, "Switching mode from %s to %s", _modeName(sio->mode), _modeName(newMode));
}
if (driver != sio->activeDriver || (driver && !driver->setMode)) {
if (sio->activeDriver && sio->activeDriver->unload) {
sio->activeDriver->unload(sio->activeDriver);
}
sio->mode = newMode;
sio->activeDriver = driver;
if (sio->activeDriver && sio->activeDriver->load) {
sio->activeDriver->load(sio->activeDriver);
}
} else {
sio->mode = newMode;
if (sio->activeDriver && sio->activeDriver->setMode) {
sio->activeDriver->setMode(sio->activeDriver, newMode);
}
sio->mode = newMode;
if (sio->driver && sio->driver->setMode) {
sio->driver->setMode(sio->driver, newMode);
}
int id = 0;
switch (newMode) {
case GBA_SIO_MULTI:
if (sio->activeDriver && sio->activeDriver->deviceId) {
id = sio->activeDriver->deviceId(sio->activeDriver);
if (sio->driver && sio->driver->deviceId) {
id = sio->driver->deviceId(sio->driver);
}
sio->rcnt = GBASIORegisterRCNTSetSi(sio->rcnt, !!id);
break;
@ -96,10 +70,7 @@ static void _switchMode(struct GBASIO* sio) {
}
void GBASIOInit(struct GBASIO* sio) {
sio->drivers.normal = NULL;
sio->drivers.multiplayer = NULL;
sio->drivers.joybus = NULL;
sio->activeDriver = NULL;
sio->driver = NULL;
sio->completeEvent.context = sio;
sio->completeEvent.name = "GBA SIO Complete";
@ -113,73 +84,28 @@ void GBASIOInit(struct GBASIO* sio) {
}
void GBASIODeinit(struct GBASIO* sio) {
if (sio->activeDriver && sio->activeDriver->unload) {
sio->activeDriver->unload(sio->activeDriver);
}
if (sio->drivers.multiplayer && sio->drivers.multiplayer->deinit) {
sio->drivers.multiplayer->deinit(sio->drivers.multiplayer);
}
if (sio->drivers.joybus && sio->drivers.joybus->deinit) {
sio->drivers.joybus->deinit(sio->drivers.joybus);
}
if (sio->drivers.normal && sio->drivers.normal->deinit) {
sio->drivers.normal->deinit(sio->drivers.normal);
if (sio->driver && sio->driver->deinit) {
sio->driver->deinit(sio->driver);
}
}
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);
if (sio->driver && sio->driver->reset) {
sio->driver->reset(sio->driver);
}
sio->rcnt = RCNT_INITIAL;
sio->siocnt = 0;
sio->mode = -1;
sio->activeDriver = NULL;
_switchMode(sio);
GBASIOPlayerReset(&sio->gbp);
}
void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers) {
GBASIOSetDriver(sio, drivers->normal, GBA_SIO_NORMAL_8);
GBASIOSetDriver(sio, drivers->multiplayer, GBA_SIO_MULTI);
GBASIOSetDriver(sio, drivers->joybus, GBA_SIO_JOYBUS);
}
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode) {
struct GBASIODriver** driverLoc;
switch (mode) {
case GBA_SIO_NORMAL_8:
case GBA_SIO_NORMAL_32:
driverLoc = &sio->drivers.normal;
break;
case GBA_SIO_MULTI:
driverLoc = &sio->drivers.multiplayer;
break;
case GBA_SIO_JOYBUS:
driverLoc = &sio->drivers.joybus;
break;
default:
mLOG(GBA_SIO, ERROR, "Setting an unsupported SIO driver: %x", mode);
return;
}
if (*driverLoc) {
if ((*driverLoc)->unload) {
(*driverLoc)->unload(*driverLoc);
}
if ((*driverLoc)->deinit) {
(*driverLoc)->deinit(*driverLoc);
}
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver) {
if (sio->driver && sio->driver->deinit) {
sio->driver->deinit(sio->driver);
}
sio->driver = driver;
if (driver) {
driver->p = sio;
@ -191,26 +117,19 @@ void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASI
}
}
}
if (sio->activeDriver == *driverLoc) {
sio->activeDriver = driver;
if (driver && driver->load) {
driver->load(driver);
}
}
*driverLoc = driver;
}
void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
sio->rcnt &= 0x1FF;
sio->rcnt |= value & 0xC000;
_switchMode(sio);
if (sio->activeDriver && sio->activeDriver->writeRCNT) {
if (sio->driver && sio->driver->writeRCNT) {
switch (sio->mode) {
case GBA_SIO_GPIO:
sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01FF) | (sio->rcnt & 0xC000);
sio->rcnt = (sio->driver->writeRCNT(sio->driver, value) & 0x01FF) | (sio->rcnt & 0xC000);
break;
default:
sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01F0) | (sio->rcnt & 0xC00F);
sio->rcnt = (sio->driver->writeRCNT(sio->driver, value) & 0x01F0) | (sio->rcnt & 0xC00F);
}
} else if (sio->mode == GBA_SIO_GPIO) {
sio->rcnt &= 0xC000;
@ -222,15 +141,15 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
}
static void _startTransfer(struct GBASIO* sio) {
if (sio->activeDriver && sio->activeDriver->start) {
if (!sio->activeDriver->start(sio->activeDriver)) {
if (sio->driver && sio->driver->start) {
if (!sio->driver->start(sio->driver)) {
// Transfer completion is handled internally to the driver
return;
}
}
int connected = 0;
if (sio->activeDriver && sio->activeDriver->connectedDevices) {
connected = sio->activeDriver->connectedDevices(sio->activeDriver);
if (sio->driver && sio->driver->connectedDevices) {
connected = sio->driver->connectedDevices(sio->driver);
}
mTimingDeschedule(&sio->p->timing, &sio->completeEvent);
mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio->mode, sio->siocnt, connected));
@ -244,14 +163,14 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
int id = 0;
int connected = 0;
bool handled = false;
if (sio->activeDriver) {
handled = sio->activeDriver->handlesMode(sio->activeDriver, sio->mode);
if (sio->driver) {
handled = sio->driver->handlesMode(sio->driver, sio->mode);
if (handled) {
if (sio->activeDriver->deviceId) {
id = sio->activeDriver->deviceId(sio->activeDriver);
if (sio->driver->deviceId) {
id = sio->driver->deviceId(sio->driver);
}
connected = sio->activeDriver->connectedDevices(sio->activeDriver);
handled = !!sio->activeDriver->writeSIOCNT;
connected = sio->driver->connectedDevices(sio->driver);
handled = !!sio->driver->writeSIOCNT;
}
}
@ -304,7 +223,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
break;
}
if (handled) {
value = sio->activeDriver->writeSIOCNT(sio->activeDriver, value);
value = sio->driver->writeSIOCNT(sio->driver, value);
} else {
// Dummy drivers
switch (sio->mode) {
@ -325,8 +244,8 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value) {
int id = 0;
if (sio->activeDriver && sio->activeDriver->deviceId) {
id = sio->activeDriver->deviceId(sio->activeDriver);
if (sio->driver && sio->driver->deviceId) {
id = sio->driver->deviceId(sio->driver);
}
bool handled = true;
@ -455,8 +374,8 @@ int32_t GBASIOTransferCycles(enum GBASIOMode mode, uint16_t siocnt, int connecte
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) {
int id = 0;
if (sio->activeDriver && sio->activeDriver->deviceId) {
id = sio->activeDriver->deviceId(sio->activeDriver);
if (sio->driver && sio->driver->deviceId) {
id = sio->driver->deviceId(sio->driver);
}
sio->p->memory.io[GBA_REG(SIOMULTI0)] = data[0];
sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1];
@ -500,20 +419,20 @@ static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate)
} data = {0};
switch (sio->mode) {
case GBA_SIO_MULTI:
if (sio->activeDriver && sio->activeDriver->finishMultiplayer) {
sio->activeDriver->finishMultiplayer(sio->activeDriver, data.multi);
if (sio->driver && sio->driver->finishMultiplayer) {
sio->driver->finishMultiplayer(sio->driver, data.multi);
}
GBASIOMultiplayerFinishTransfer(sio, data.multi, cyclesLate);
break;
case GBA_SIO_NORMAL_8:
if (sio->activeDriver && sio->activeDriver->finishNormal8) {
data.normal8 = sio->activeDriver->finishNormal8(sio->activeDriver);
if (sio->driver && sio->driver->finishNormal8) {
data.normal8 = sio->driver->finishNormal8(sio->driver);
}
GBASIONormal8FinishTransfer(sio, data.normal8, cyclesLate);
break;
case GBA_SIO_NORMAL_32:
if (sio->activeDriver && sio->activeDriver->finishNormal32) {
data.normal32 = sio->activeDriver->finishNormal32(sio->activeDriver);
if (sio->driver && sio->driver->finishNormal32) {
data.normal32 = sio->driver->finishNormal32(sio->driver);
}
GBASIONormal32FinishTransfer(sio, data.normal32, cyclesLate);
break;

View File

@ -23,8 +23,8 @@ enum {
};
static bool GBASIODolphinInit(struct GBASIODriver* driver);
static bool GBASIODolphinLoad(struct GBASIODriver* driver);
static bool GBASIODolphinUnload(struct GBASIODriver* driver);
static void GBASIODolphinReset(struct GBASIODriver* driver);
static void GBASIODolphinSetMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
static int GBASIODolphinConnectedDevices(struct GBASIODriver* driver);
static void GBASIODolphinProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate);
@ -35,8 +35,8 @@ static void _flush(struct GBASIODolphin* dol);
void GBASIODolphinCreate(struct GBASIODolphin* dol) {
memset(&dol->d, 0, sizeof(dol->d));
dol->d.init = GBASIODolphinInit;
dol->d.load = GBASIODolphinLoad;
dol->d.unload = GBASIODolphinUnload;
dol->d.reset = GBASIODolphinReset;
dol->d.setMode = GBASIODolphinSetMode;
dol->d.handlesMode = GBASIODolphinHandlesMode;
dol->d.connectedDevices = GBASIODolphinConnectedDevices;
dol->event.context = dol;
@ -98,26 +98,23 @@ bool GBASIODolphinConnect(struct GBASIODolphin* dol, const struct Address* addre
static bool GBASIODolphinInit(struct GBASIODriver* driver) {
struct GBASIODolphin* dol = (struct GBASIODolphin*) driver;
dol->active = false;
dol->clockSlice = 0;
dol->state = WAIT_FOR_FIRST_CLOCK;
_flush(dol);
GBASIODolphinReset(driver);
return true;
}
static bool GBASIODolphinLoad(struct GBASIODriver* driver) {
static void GBASIODolphinReset(struct GBASIODriver* driver) {
struct GBASIODolphin* dol = (struct GBASIODolphin*) driver;
dol->active = true;
dol->active = false;
_flush(dol);
mTimingDeschedule(&dol->d.p->p->timing, &dol->event);
mTimingSchedule(&dol->d.p->p->timing, &dol->event, 0);
return true;
}
static bool GBASIODolphinUnload(struct GBASIODriver* driver) {
static void GBASIODolphinSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
struct GBASIODolphin* dol = (struct GBASIODolphin*) driver;
dol->active = false;
return true;
dol->active = mode == GBA_SIO_JOYBUS;
}
static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {

View File

@ -55,8 +55,8 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) {
}
void GBASIOPlayerReset(struct GBASIOPlayer* gbp) {
if (gbp->p->sio.drivers.normal == &gbp->d) {
GBASIOSetDriver(&gbp->p->sio, NULL, GBA_SIO_NORMAL_32);
if (gbp->p->sio.driver == &gbp->d) {
GBASIOSetDriver(&gbp->p->sio, NULL);
}
}
@ -88,7 +88,7 @@ void GBASIOPlayerUpdate(struct GBA* gba) {
gba->sio.gbp.oldCallback = gba->keyCallback;
gba->keyCallback = &gba->sio.gbp.callback.d;
// TODO: Check if the SIO driver is actually used first
GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, GBA_SIO_NORMAL_32);
GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d);
}
}

View File

@ -79,8 +79,6 @@ static_assert(sizeof(struct GBASIOLockstepSerializedState) == 0x1F0, "GBA lockst
static bool GBASIOLockstepDriverInit(struct GBASIODriver* driver);
static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver);
static void GBASIOLockstepDriverReset(struct GBASIODriver* driver);
static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver);
static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver);
static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver);
static bool GBASIOLockstepDriverLoadState(struct GBASIODriver* driver, const void* state, size_t size);
static void GBASIOLockstepDriverSaveState(struct GBASIODriver* driver, void** state, size_t* size);
@ -119,8 +117,6 @@ void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver* driver, struct mLoc
driver->d.init = GBASIOLockstepDriverInit;
driver->d.deinit = GBASIOLockstepDriverDeinit;
driver->d.reset = GBASIOLockstepDriverReset;
driver->d.load = GBASIOLockstepDriverLoad;
driver->d.unload = GBASIOLockstepDriverUnload;
driver->d.driverId = GBASIOLockstepDriverId;
driver->d.loadState = GBASIOLockstepDriverLoadState;
driver->d.saveState = GBASIOLockstepDriverSaveState;
@ -220,27 +216,6 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) {
mTimingSchedule(&lockstep->d.p->p->timing, &lockstep->event, nextEvent);
}
static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver) {
struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver;
if (lockstep->lockstepId) {
struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator;
MutexLock(&coordinator->mutex);
struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId);
_setReady(coordinator, player, 0, coordinator->transferMode);
MutexUnlock(&coordinator->mutex);
GBASIOLockstepDriverSetMode(driver, driver->p->mode);
}
return true;
}
static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver) {
struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver;
if (lockstep->lockstepId) {
GBASIOLockstepDriverSetMode(driver, -1);
}
return true;
}
static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver) {
UNUSED(driver);
return DRIVER_ID;

View File

@ -424,7 +424,7 @@ bool CoreController::attachDolphin(const Address& address) {
}
if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) {
GBA* gba = static_cast<GBA*>(m_threadContext.core->board);
GBASIOSetDriver(&gba->sio, &m_dolphin.d, GBA_SIO_JOYBUS);
GBASIOSetDriver(&gba->sio, &m_dolphin.d);
return true;
}
return false;
@ -433,7 +433,8 @@ bool CoreController::attachDolphin(const Address& address) {
void CoreController::detachDolphin() {
if (platform() == mPLATFORM_GBA) {
GBA* gba = static_cast<GBA*>(m_threadContext.core->board);
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_JOYBUS);
// TODO: Reattach to multiplayer controller
GBASIOSetDriver(&gba->sio, nullptr);
}
GBASIODolphinDestroy(&m_dolphin);
}

View File

@ -265,9 +265,7 @@ bool MultiplayerController::attachGame(CoreController* controller) {
GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, node);
player.node.gba = node;
GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_MULTI);
GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_8);
GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_32);
GBASIOSetDriver(&gba->sio, &node->d);
break;
}
#endif
@ -356,10 +354,8 @@ void MultiplayerController::detachGame(CoreController* controller) {
#ifdef M_CORE_GBA
case mPLATFORM_GBA: {
GBA* gba = static_cast<GBA*>(thread->core->board);
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.drivers.multiplayer);
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_MULTI);
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_8);
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_32);
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.driver);
GBASIOSetDriver(&gba->sio, nullptr);
if (node) {
GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, node);
delete node->user;
@ -485,12 +481,13 @@ void MultiplayerController::fixOrder() {
switch (m_platform) {
#ifdef M_CORE_GBA
case mPLATFORM_GBA:
for (int pid : m_pids.keys()) {
// TODO: fix
/*for (int pid : m_pids.keys()) {
Player& p = m_pids.find(pid).value();
GBA* gba = static_cast<GBA*>(p.controller->thread()->core->board);
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.drivers.multiplayer);
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.driver);
m_players[node->d.deviceId(&node->d)] = pid;
}
}*/
break;
#endif
#ifdef M_CORE_GB