Qt: Handle multiple save game files for disparate games separately (fixes #2887)

This commit is contained in:
Vicki Pfau 2023-07-17 21:34:37 -07:00
parent 4b38883b6a
commit 1e68020d1c
4 changed files with 58 additions and 10 deletions

View File

@ -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)

View File

@ -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) {

View File

@ -276,6 +276,32 @@ bool MultiplayerController::attachGame(CoreController* controller) {
return false;
}
QPair<QString, QString> 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<QString, QString> 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;

View File

@ -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<int, Player> m_pids;
QList<int> m_players;
QMutex m_lock;
QHash<QPair<QString, QString>, int> m_claimed;
};
}