From 1e68020d1c7d149c424d1ca22e755c1234cf4632 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 17 Jul 2023 21:34:37 -0700 Subject: [PATCH] Qt: Handle multiple save game files for disparate games separately (fixes #2887) --- CHANGES | 1 + src/platform/qt/CoreController.cpp | 12 +----- src/platform/qt/MultiplayerController.cpp | 52 +++++++++++++++++++++++ src/platform/qt/MultiplayerController.h | 3 ++ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index cfd866c9d..3a67c7be5 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,7 @@ Misc: - GBA: Improve detection of valid ELF ROMs - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - Qt: Add exporting of SAV + RTC saves from Save Converter to strip RTC data + - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Scripting: Add `callbacks:oneshot` for single-call callbacks 0.10.2: (2023-04-23) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index db29af538..6b21f2c8e 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -878,6 +878,7 @@ void CoreController::replaceGame(const QString& path) { } else { mCoreLoadFile(m_threadContext.core, fname.toUtf8().constData()); } + // TODO: Make sure updating the path is handled properly by everything that calls path() and baseDirectory() updateROMInfo(); } @@ -1256,16 +1257,7 @@ void CoreController::finishFrame() { } void CoreController::updatePlayerSave() { - int savePlayerId = 0; - mCoreConfigGetIntValue(&m_threadContext.core->config, "savePlayerId", &savePlayerId); - if (savePlayerId == 0 || m_multiplayer->attached() > 1) { - if (savePlayerId == m_multiplayer->playerId(this) + 1) { - // Player 1 is using our save, so let's use theirs, at least for now. - savePlayerId = 1; - } else { - savePlayerId = m_multiplayer->playerId(this) + 1; - } - } + int savePlayerId = m_multiplayer->saveId(this); QString saveSuffix; if (savePlayerId < 2) { diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index fb3c0195f..972213f67 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -276,6 +276,32 @@ bool MultiplayerController::attachGame(CoreController* controller) { return false; } + QPair path(controller->path(), controller->baseDirectory()); + int claimed = m_claimed[path]; + + int saveId = 0; + mCoreConfigGetIntValue(&controller->thread()->core->config, "savePlayerId", &saveId); + + if (claimed) { + player.saveId = 0; + for (int i = 0; i < MAX_GBAS; ++i) { + if (claimed & (1 << i)) { + continue; + } + player.saveId = i + 1; + break; + } + if (!player.saveId) { + LOG(QT, ERROR) << "Couldn't find available save ID"; + player.saveId = 1; + } + } else if (saveId) { + player.saveId = saveId; + } else { + player.saveId = 1; + } + m_claimed[path] |= 1 << (player.saveId - 1); + m_pids.insert(m_nextPid, player); ++m_nextPid; fixOrder(); @@ -337,6 +363,18 @@ void MultiplayerController::detachGame(CoreController* controller) { break; } + // TODO: This might change if we replace the ROM--make sure to handle this properly + QPair path(controller->path(), controller->baseDirectory()); + Player& p = m_pids.find(pid).value(); + if (!p.saveId) { + LOG(QT, ERROR) << "Clearing invalid save ID"; + } else { + m_claimed[path] &= ~(1 << (p.saveId - 1)); + if (!m_claimed[path]) { + m_claimed.remove(path); + } + } + m_pids.remove(pid); if (m_pids.size() == 0) { m_platform = mPLATFORM_NONE; @@ -360,6 +398,20 @@ int MultiplayerController::playerId(CoreController* controller) const { return -1; } +int MultiplayerController::saveId(CoreController* controller) const { + for (int i = 0; i < m_players.count(); ++i) { + const Player* p = player(i); + if (!p) { + LOG(QT, ERROR) << tr("Trying to get save ID for a multiplayer player that's not attached"); + return -1; + } + if (p->controller == controller) { + return p->saveId; + } + } + return -1; +} + int MultiplayerController::attached() { int num; num = m_lockstep.attached; diff --git a/src/platform/qt/MultiplayerController.h b/src/platform/qt/MultiplayerController.h index 10cd63c6b..b5582319f 100644 --- a/src/platform/qt/MultiplayerController.h +++ b/src/platform/qt/MultiplayerController.h @@ -40,6 +40,7 @@ public: int attached(); int playerId(CoreController*) const; + int saveId(CoreController*) const; signals: void gameAttached(); @@ -61,6 +62,7 @@ private: int awake = 1; int32_t cyclesPosted = 0; unsigned waitMask = 0; + int saveId = 1; }; Player* player(int id); @@ -82,6 +84,7 @@ private: QHash m_pids; QList m_players; QMutex m_lock; + QHash, int> m_claimed; }; }