[Scummvm-git-logs] scummvm master -> bb8fa8b481faeec86aab511e6b1408a6aa8fe48b

criezy noreply at scummvm.org
Wed Dec 13 22:04:26 UTC 2023


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
bb8fa8b481 IOS7: Save state to a separate file when closing ScummVM


Commit: bb8fa8b481faeec86aab511e6b1408a6aa8fe48b
    https://github.com/scummvm/scummvm/commit/bb8fa8b481faeec86aab511e6b1408a6aa8fe48b
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2023-12-13T22:04:22Z

Commit Message:
IOS7: Save state to a separate file when closing ScummVM

The state information was saved using ConfMan in the scummvm ini file,
but this could cause corruption of that ini file if the application
was killed while ConfMan was flushed (see bug #14623). To reduce the
risk of losing the config file, we now save the state to a separate
file.

Changed paths:
    backends/platform/ios7/ios7_osys_main.cpp


diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index 0be4d416c9a..33911a90fc3 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -24,6 +24,7 @@
 
 #include <unistd.h>
 #include <string.h>
+#include <stdio.h>
 
 #include <sys/time.h>
 #include <QuartzCore/QuartzCore.h>
@@ -36,6 +37,7 @@
 #include "common/fs.h"
 #include "common/config-manager.h"
 #include "common/translation.h"
+#include "common/formats/ini-file.h"
 
 #include "base/main.h"
 
@@ -275,54 +277,70 @@ void OSystem_iOS7::saveState() {
 	// Clear any previous restore state to avoid having and obsolete one if we don't save it again below.
 	clearState();
 
-	// If there is an engine running and it accepts autosave, do an autosave and add the current
-	// running target to the config file.
-	if (g_engine && g_engine->hasFeature(Engine::kSupportsSavingDuringRuntime) && g_engine->canSaveAutosaveCurrently()) {
+	// If there is an engine running and it both accepts autosave and loading from the launcher (required to restore the state),
+	// do an autosave and save the current running target and autosave slot to a state file.
+	if (g_engine && g_engine->hasFeature(Engine::kSupportsSavingDuringRuntime) && g_engine->canSaveAutosaveCurrently() &&
+		g_engine->getMetaEngine()->hasFeature(MetaEngine::kSupportsLoadingDuringStartup)) {
 		Common::String targetName(ConfMan.getActiveDomainName());
 		int saveSlot = g_engine->getAutosaveSlot();
+		if (saveSlot == -1)
+			return;
 		// Make sure we do not overwrite a user save
 		SaveStateDescriptor desc = g_engine->getMetaEngine()->querySaveMetaInfos(targetName.c_str(), saveSlot);
 		if (desc.getSaveSlot() != -1 && !desc.isAutosave())
 			return;
 
-		// Do the auto-save, and if successful store this it in the config
+		// Do the auto-save, and if successful create the state file with the target and save slot.
 		if (g_engine->saveGameState(saveSlot, _("Autosave"), true).getCode() == Common::kNoError) {
-			ConfMan.set("restore_target", targetName, Common::ConfigManager::kApplicationDomain);
-			ConfMan.setInt("restore_slot", saveSlot, Common::ConfigManager::kApplicationDomain);
-			ConfMan.flushToDisk();
+			Common::INIFile stateFile;
+			stateFile.addSection("state");
+			stateFile.setKey("restore_target", "state", targetName);
+			stateFile.setKey("restore_slot", "state", Common::String::format("%d", saveSlot));
+			stateFile.saveToFile("/scummvm.state");
 		}
 	}
 }
 
 void OSystem_iOS7::restoreState() {
-	Common::String target;
-	int slot = -1;
-	if (ConfMan.hasKey("restore_target", Common::ConfigManager::kApplicationDomain) &&
-		ConfMan.hasKey("restore_slot", Common::ConfigManager::kApplicationDomain)) {
-		target = ConfMan.get("restore_target", Common::ConfigManager::kApplicationDomain);
-		slot = ConfMan.getInt("restore_slot", Common::ConfigManager::kApplicationDomain);
+	// If the g_engine is still running (i.e. the application was not terminated) we don't need to do anything other than clear the saved state.
+	if (g_engine) {
 		clearState();
+		return;
 	}
 
-	// If the g_engine is still running (i.e. the application was not terminated) we don't need to do anything.
-	if (g_engine)
+	// Read the state
+	Common::FSNode node("/scummvm.state");
+	Common::File stateFile;
+	if (!stateFile.open(node))
 		return;
 
-	if (!target.empty() && slot != -1) {
-		ConfMan.setInt("save_slot", slot, Common::ConfigManager::kTransientDomain);
-		ConfMan.setActiveDomain(target);
+	Common::String targetName, slotString;
+	int saveSlot = -1;
+	Common::INIFile stateIniFile;
+	if (stateIniFile.loadFromStream(stateFile) &&
+		stateIniFile.getKey("restore_target", "state", targetName) &&
+		stateIniFile.getKey("restore_slot", "state", slotString) &&
+		!slotString.empty()) {
+		char *errpos;
+		saveSlot = (int)strtol(slotString.c_str(), &errpos, 10);
+		if (slotString.c_str() == errpos)
+			saveSlot = -1;
+	}
+
+	clearState();
+
+	// Reload the state
+	if (!targetName.empty() && saveSlot != -1) {
+		ConfMan.setInt("save_slot", saveSlot, Common::ConfigManager::kTransientDomain);
+		ConfMan.setActiveDomain(targetName);
 		if (GUI::GuiManager::hasInstance())
 			g_gui.exitLoop();
 	}
 }
 
 void OSystem_iOS7::clearState() {
-	if (ConfMan.hasKey("restore_target", Common::ConfigManager::kApplicationDomain) &&
-	ConfMan.hasKey("restore_slot", Common::ConfigManager::kApplicationDomain)) {
-		ConfMan.removeKey("restore_target", Common::ConfigManager::kApplicationDomain);
-		ConfMan.removeKey("restore_slot", Common::ConfigManager::kApplicationDomain);
-		ConfMan.flushToDisk();
-	}
+	Common::String statePath = _chrootBasePath + "/scummvm.state";
+	remove(statePath.c_str());
 }
 
 uint32 OSystem_iOS7::getMillis(bool skipRecord) {




More information about the Scummvm-git-logs mailing list