Qt: Delay attaching SIO driver until a second player is connected

This commit is contained in:
Vicki Pfau 2024-09-12 02:13:38 -07:00
parent 7fa572e3ff
commit 5db42e83c9
2 changed files with 29 additions and 11 deletions

View File

@ -201,7 +201,8 @@ bool MultiplayerController::attachGame(CoreController* controller) {
interrupters.append(p.controller); interrupters.append(p.controller);
} }
if (attached() == 0) { bool doDelayedAttach = false;
if (m_platform == mPLATFORM_NONE) {
switch (controller->platform()) { switch (controller->platform()) {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
case mPLATFORM_GBA: case mPLATFORM_GBA:
@ -242,8 +243,6 @@ bool MultiplayerController::attachGame(CoreController* controller) {
return false; return false;
} }
GBA* gba = static_cast<GBA*>(thread->core->board);
GBASIOLockstepDriver* node = new GBASIOLockstepDriver; GBASIOLockstepDriver* node = new GBASIOLockstepDriver;
LockstepUser* user = new LockstepUser; LockstepUser* user = new LockstepUser;
mLockstepThreadUserInit(user, thread); mLockstepThreadUserInit(user, thread);
@ -262,10 +261,11 @@ bool MultiplayerController::attachGame(CoreController* controller) {
}; };
GBASIOLockstepDriverCreate(node, &user->d); GBASIOLockstepDriverCreate(node, &user->d);
GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, node);
player.node.gba = node; player.node.gba = node;
GBASIOSetDriver(&gba->sio, &node->d); if (m_pids.size()) {
doDelayedAttach = true;
}
break; break;
} }
#endif #endif
@ -281,6 +281,7 @@ bool MultiplayerController::attachGame(CoreController* controller) {
GBSIOLockstepNodeCreate(node); GBSIOLockstepNodeCreate(node);
GBSIOLockstepAttachNode(&m_gbLockstep, node); GBSIOLockstepAttachNode(&m_gbLockstep, node);
player.node.gb = node; player.node.gb = node;
player.attached = true;
GBSIOSetDriver(&gb->sio, &node->d); GBSIOSetDriver(&gb->sio, &node->d);
break; break;
@ -320,6 +321,19 @@ bool MultiplayerController::attachGame(CoreController* controller) {
++m_nextPid; ++m_nextPid;
fixOrder(); fixOrder();
if (doDelayedAttach) {
for (auto pid: m_players) {
Player& player = m_pids.find(pid).value();
if (player.attached) {
continue;
}
GBA* gba = static_cast<GBA*>(player.controller->thread()->core->board);
GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, player.node.gba);
GBASIOSetDriver(&gba->sio, &player.node.gba->d);
player.attached = true;
}
}
emit gameAttached(); emit gameAttached();
return true; return true;
} }
@ -354,13 +368,16 @@ void MultiplayerController::detachGame(CoreController* controller) {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
case mPLATFORM_GBA: { case mPLATFORM_GBA: {
GBA* gba = static_cast<GBA*>(thread->core->board); GBA* gba = static_cast<GBA*>(thread->core->board);
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.driver); Player& p = m_pids.find(pid).value();
GBASIOSetDriver(&gba->sio, nullptr); GBASIODriver* node = gba->sio.driver;
if (node) { if (node == &p.node.gba->d) {
GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, node); GBASIOSetDriver(&gba->sio, nullptr);
delete node->user;
delete node;
} }
if (p.attached) {
GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, p.node.gba);
}
delete p.node.gba->user;
delete p.node.gba;
break; break;
} }
#endif #endif

View File

@ -64,6 +64,7 @@ private:
unsigned waitMask = 0; unsigned waitMask = 0;
int saveId = 1; int saveId = 1;
int preferredId = 0; int preferredId = 0;
bool attached = false;
}; };
struct LockstepUser : mLockstepThreadUser { struct LockstepUser : mLockstepThreadUser {
MultiplayerController* controller; MultiplayerController* controller;