[Scummvm-cvs-logs] scummvm master -> e4f08a4644c5a59b8e02b3702eef436e52e2d994

bluegr md5 at scummvm.org
Wed Jun 13 21:57:44 CEST 2012


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:
e4f08a4644 SCI: Fix the loading screen and the loading functionality in Shivers


Commit: e4f08a4644c5a59b8e02b3702eef436e52e2d994
    https://github.com/scummvm/scummvm/commit/e4f08a4644c5a59b8e02b3702eef436e52e2d994
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-06-13T12:56:43-07:00

Commit Message:
SCI: Fix the loading screen and the loading functionality in Shivers

Shivers uses extra special hardcoded save files together with the normal
ones that are used to store slot names and spot descriptions. The scheme
is a bit odd, and since the names of the extra save files are hardcoded,
this scheme is problematic to use. We skip the creation of these files
altogether and use virtual files instead, which means that the
(broken) spot descriptions won't be visible next to each save
description. This isn't a major issue for now, and it's left as a future
TODO to implement this feature in a cleaner way, and not with extra save
files. This scheme fixes the slot descriptions in the loading screen.
Also, kCD(1) has been implemented, which fixes loading of the save
states themselves

Changed paths:
    engines/sci/engine/file.cpp
    engines/sci/engine/file.h
    engines/sci/engine/kfile.cpp



diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index 66f54d6..3470d23 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -346,6 +346,12 @@ VirtualIndexFile::VirtualIndexFile(Common::String fileName) : _fileName(fileName
 	delete inFile;
 }
 
+VirtualIndexFile::VirtualIndexFile(uint32 initialSize) : _changed(false) {
+	_bufferSize = initialSize;
+	_buffer = new char[_bufferSize];
+	_ptr = _buffer;
+}
+
 VirtualIndexFile::~VirtualIndexFile() {
 	close();
 
@@ -430,7 +436,7 @@ bool VirtualIndexFile::seek(int32 offset, int whence) {
 }
 
 void VirtualIndexFile::close() {
-	if (_changed) {
+	if (_changed && !_fileName.empty()) {
 		Common::WriteStream *outFile = g_sci->getSaveFileManager()->openForSaving(_fileName);
 		outFile->write(_buffer, _bufferSize);
 		delete outFile;
diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h
index 896dcd2..1c8e302 100644
--- a/engines/sci/engine/file.h
+++ b/engines/sci/engine/file.h
@@ -115,6 +115,7 @@ private:
 class VirtualIndexFile {
 public:
 	VirtualIndexFile(Common::String fileName);
+	VirtualIndexFile(uint32 initialSize);
 	~VirtualIndexFile();
 
 	uint32 read(char *buffer, uint32 size);
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 445a019..7a2f161 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -199,6 +199,9 @@ reg_t kCD(EngineState *s, int argc, reg_t *argv) {
 	case 0:
 		// Return whether the contents of disc argv[1] is available.
 		return TRUE_REG;
+	case 1:
+		// Return the current CD number
+		return make_reg(0, 1);
 	default:
 		warning("CD(%d)", argv[0].toUint16());
 	}
@@ -219,21 +222,6 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
 reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
 	Common::String name = s->_segMan->getString(argv[0]);
 
-#ifdef ENABLE_SCI32
-	if (name == PHANTASMAGORIA_SAVEGAME_INDEX) {
-		if (s->_virtualIndexFile) {
-			return make_reg(0, VIRTUALFILE_HANDLE);
-		} else {
-			Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH);
-			Common::String wrappedName = g_sci->wrapFilename(englishName);
-			if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) {
-				s->_virtualIndexFile = new VirtualIndexFile(wrappedName);
-				return make_reg(0, VIRTUALFILE_HANDLE);
-			}
-		}
-	}
-#endif
-
 	// SCI32 can call K_FILEIO_OPEN with only one argument. It seems to
 	// just be checking if it exists.
 	int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16();
@@ -261,6 +249,73 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
 	}
 	debugC(kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode);
 
+#ifdef ENABLE_SCI32
+	if (name == PHANTASMAGORIA_SAVEGAME_INDEX) {
+		if (s->_virtualIndexFile) {
+			return make_reg(0, VIRTUALFILE_HANDLE);
+		} else {
+			Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH);
+			Common::String wrappedName = g_sci->wrapFilename(englishName);
+			if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) {
+				s->_virtualIndexFile = new VirtualIndexFile(wrappedName);
+				return make_reg(0, VIRTUALFILE_HANDLE);
+			}
+		}
+	}
+
+	// Shivers is trying to store savegame descriptions and current spots in
+	// separate .SG files, which are hardcoded in the scripts.
+	// Essentially, there is a normal save file, created by the executable
+	// and an extra hardcoded save file, created by the game scripts, probably
+	// because they didn't want to modify the save/load code to add the extra
+	// information.
+	// Each slot in the book then has two strings, the save description and a
+	// description of the current spot that the player is at. Currently, the
+	// spot strings are always empty (probably related to the unimplemented
+	// kString subop 14, which gets called right before this call).
+	// For now, we don't allow the creation of these files, which means that
+	// all the spot descriptions next to each slot description will be empty
+	// (they are empty anyway). Until a viable solution is found to handle these
+	// extra files and until the spot description strings are initialized
+	// correctly, we resort to virtual files in order to make the load screen
+	// useable. Without this code it is unusable, as the extra information is
+	// always saved to 0.SG for some reason, but on restore the correct file is
+	// used. Perhaps the virtual ID is not taken into account when saving.
+	//
+	// Future TODO: maintain spot descriptions and show them too, ideally without
+	// having to return to this logic of extra hardcoded files.
+	if (g_sci->getGameId() == GID_SHIVERS && name.hasSuffix(".SG")) {
+		if (mode == _K_FILE_MODE_OPEN_OR_CREATE || mode == _K_FILE_MODE_CREATE) {
+			// Game scripts are trying to create a file with the save
+			// description, stop them here
+			debugC(kDebugLevelFile, "Not creating unused file %s", name.c_str());
+			return SIGNAL_REG;
+		} else if (mode == _K_FILE_MODE_OPEN_OR_FAIL) {
+			// Create a virtual file containing the save game description
+			// and slot number, as the game scripts expect.
+			int slotNumber;
+			sscanf(name.c_str(), "%d.SG", &slotNumber);
+
+			Common::Array<SavegameDesc> saves;
+			listSavegames(saves);
+			int savegameNr = findSavegame(saves, slotNumber - SAVEGAMEID_OFFICIALRANGE_START);
+
+			if (!s->_virtualIndexFile) {
+				// Make the virtual file buffer big enough to avoid having it grow dynamically.
+				// 50 bytes should be more than enough.
+				s->_virtualIndexFile = new VirtualIndexFile(50);
+			}
+
+			s->_virtualIndexFile->seek(0, SEEK_SET);
+			s->_virtualIndexFile->write(saves[savegameNr].name, strlen(saves[savegameNr].name));
+			s->_virtualIndexFile->write("\0", 1);
+			s->_virtualIndexFile->write("\0", 1);	// Spot description (empty)
+			s->_virtualIndexFile->seek(0, SEEK_SET);
+			return make_reg(0, VIRTUALFILE_HANDLE);
+		}
+	}
+#endif
+
 	// QFG import rooms get a virtual filelisting instead of an actual one
 	if (g_sci->inQfGImportRoom()) {
 		// We need to find out what the user actually selected, "savedHeroes" is






More information about the Scummvm-git-logs mailing list