diff options
-rw-r--r-- | common/ini-file.cpp | 4 | ||||
-rw-r--r-- | common/ini-file.h | 4 | ||||
-rw-r--r-- | engines/scumm/he/animation_he.cpp | 6 | ||||
-rw-r--r-- | engines/scumm/he/animation_he.h | 8 | ||||
-rw-r--r-- | engines/scumm/he/intern_he.h | 15 | ||||
-rw-r--r-- | engines/scumm/he/logic/football.cpp | 19 | ||||
-rw-r--r-- | engines/scumm/he/script_v100he.cpp | 7 | ||||
-rw-r--r-- | engines/scumm/he/script_v60he.cpp | 276 | ||||
-rw-r--r-- | engines/scumm/he/script_v72he.cpp | 66 | ||||
-rw-r--r-- | engines/scumm/he/script_v80he.cpp | 49 | ||||
-rw-r--r-- | engines/scumm/he/script_v90he.cpp | 5 | ||||
-rw-r--r-- | engines/scumm/he/wiz_he.cpp | 31 | ||||
-rw-r--r-- | engines/scumm/saveload.cpp | 42 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 6 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 10 |
15 files changed, 329 insertions, 219 deletions
diff --git a/common/ini-file.cpp b/common/ini-file.cpp index be5247dcfb..9de0b38e93 100644 --- a/common/ini-file.cpp +++ b/common/ini-file.cpp @@ -53,7 +53,7 @@ bool INIFile::loadFromFile(const String &filename) { return false; } -bool INIFile::loadFromSaveFile(const char *filename) { +bool INIFile::loadFromSaveFile(const String &filename) { assert(g_system); SaveFileManager *saveFileMan = g_system->getSavefileManager(); SeekableReadStream *loadFile; @@ -181,7 +181,7 @@ bool INIFile::saveToFile(const String &filename) { return false; } -bool INIFile::saveToSaveFile(const char *filename) { +bool INIFile::saveToSaveFile(const String &filename) { assert(g_system); SaveFileManager *saveFileMan = g_system->getSavefileManager(); WriteStream *saveFile; diff --git a/common/ini-file.h b/common/ini-file.h index 1d94ce7bdc..a1505fe468 100644 --- a/common/ini-file.h +++ b/common/ini-file.h @@ -94,10 +94,10 @@ public: void clear(); bool loadFromFile(const String &filename); - bool loadFromSaveFile(const char *filename); + bool loadFromSaveFile(const String &filename); bool loadFromStream(SeekableReadStream &stream); bool saveToFile(const String &filename); - bool saveToSaveFile(const char *filename); + bool saveToSaveFile(const String &filename); bool saveToStream(WriteStream &stream); bool hasSection(const String §ion) const; diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp index d01b456c8b..c736c6a04c 100644 --- a/engines/scumm/he/animation_he.cpp +++ b/engines/scumm/he/animation_he.cpp @@ -57,7 +57,7 @@ int MoviePlayer::getImageNum() { return _wizResNum; } -int MoviePlayer::load(const char *filename, int flags, int image) { +int MoviePlayer::load(const Common::String &filename, int flags, int image) { if (_video->isVideoLoaded()) _video->close(); @@ -65,13 +65,13 @@ int MoviePlayer::load(const char *filename, int flags, int image) { _video->setDefaultHighColorFormat(g_system->getScreenFormat()); if (!_video->loadFile(filename)) { - warning("Failed to load video file %s", filename); + warning("Failed to load video file %s", filename.c_str()); return -1; } _video->start(); - debug(1, "Playing video %s", filename); + debug(1, "Playing video %s", filename.c_str()); if (flags & 2) _vm->_wiz->createWizEmptyImage(image, 0, 0, _video->getWidth(), _video->getHeight()); diff --git a/engines/scumm/he/animation_he.h b/engines/scumm/he/animation_he.h index e17c1b9a39..48234b8072 100644 --- a/engines/scumm/he/animation_he.h +++ b/engines/scumm/he/animation_he.h @@ -25,8 +25,12 @@ #include "audio/mixer.h" +namespace Common { +class String; +} + namespace Video { - class VideoDecoder; +class VideoDecoder; } namespace Scumm { @@ -39,7 +43,7 @@ public: ~MoviePlayer(); int getImageNum(); - int load(const char *filename, int flags, int image = 0); + int load(const Common::String &filename, int flags, int image = 0); void copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch); void handleNextFrame(); diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index a674288775..067f508d2c 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -81,10 +81,23 @@ protected: int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2); void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2); - int convertFilePath(byte *dst, int dstSize); virtual void decodeParseString(int a, int b); void swapObjects(int object1, int object2); + Common::String convertFilePath(const byte *src); + Common::String convertSavePath(const byte *src); + Common::String convertSavePathOld(const byte *src); + + Common::SeekableReadStream *openFileForReading(const byte *fileName); + Common::SeekableReadStream *openSaveFileForReading(const byte *fileName); + Common::WriteStream *openSaveFileForWriting(const byte *fileName); + Common::WriteStream *openSaveFileForAppending(const byte *fileName); + void deleteSaveFile(const byte *fileName); + void renameSaveFile(const byte *from, const byte *to); + + Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName); + Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName); + /* HE version 60 script opcodes */ void o60_setState(); void o60_roomOps(); diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp index ea990ca86b..215fdf0179 100644 --- a/engines/scumm/he/logic/football.cpp +++ b/engines/scumm/he/logic/football.cpp @@ -449,25 +449,26 @@ int LogicHEfootball2002::initScreenTranslations() { int LogicHEfootball2002::getPlaybookFiles(int32 *args) { // Get the pattern and then skip over the directory prefix ("*\" or "*:") - Common::String pattern = (const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2; + // Also prepend the target name + Common::String targetName = _vm->getTargetName(); + Common::String basePattern = ((const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2); + Common::String pattern = targetName + '-' + basePattern; // Prepare a buffer to hold the file names - char buffer[1000]; - buffer[0] = 0; + Common::String output; // Get the list of file names that match the pattern and iterate over it Common::StringArray fileList = _vm->getSaveFileManager()->listSavefiles(pattern); - for (uint32 i = 0; i < fileList.size() && strlen(buffer) < 970; i++) { + for (uint32 i = 0; i < fileList.size(); i++) { // Isolate the base part of the filename and concatenate it to our buffer - Common::String fileName = Common::String(fileList[i].c_str(), fileList[i].size() - (pattern.size() - 1)); - strcat(buffer, fileName.c_str()); - strcat(buffer, ">"); // names separated by '>' + Common::String fileName(fileList[i].c_str() + targetName.size() + 1, fileList[i].size() - (basePattern.size() - 1) - (targetName.size() + 1)); + output += fileName + '>'; // names separated by '>' } // Now store the result in an array - int array = _vm->setupStringArray(strlen(buffer)); - strcpy((char *)_vm->getStringAddress(array), buffer); + int array = _vm->setupStringArray(output.size()); + strcpy((char *)_vm->getStringAddress(array), output.c_str()); // And store the array index in variable 108 writeScummVar(108, array); diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index 987f74957c..c26e3f57ea 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -1642,7 +1642,7 @@ void ScummEngine_v100he::o100_roomOps() { copyScriptString((byte *)buffer, sizeof(buffer)); - _saveLoadFileName = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); + _saveLoadFileName = (char *)buffer; debug(1, "o100_roomOps: case 137: filename %s", _saveLoadFileName.c_str()); _saveLoadFlag = pop(); @@ -2263,11 +2263,10 @@ void ScummEngine_v100he::o100_videoOps() { if (_videoParams.flags == 0) _videoParams.flags = 4; - const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename)); if (_videoParams.flags == 2) { - VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum); + VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags, _videoParams.wizResNum); } else { - VAR(119) = _moviePlay->load(filename, _videoParams.flags); + VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags); } } else if (_videoParams.status == 19) { // Stop video diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp index bbd8725904..4901d47c51 100644 --- a/engines/scumm/he/script_v60he.cpp +++ b/engines/scumm/he/script_v60he.cpp @@ -90,59 +90,214 @@ void ScummEngine_v60he::setupOpcodes() { _opcodes[0xed].setProc(0, 0); } -int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) { - debug(1, "convertFilePath: original filePath is %s", dst); - - int len = resStrLen(dst); - - // Switch all \ to / for portablity - for (int i = 0; i < len; i++) - if (dst[i] == '\\') - dst[i] = '/'; - - if (_game.platform == Common::kPlatformMacintosh) { - // Remove : prefix in HE71 games - if (dst[0] == ':') { - len -= 1; - memmove(dst, dst + 1, len); - dst[len] = 0; +Common::String ScummEngine_v60he::convertFilePath(const byte *src) { + debug(2, "convertFilePath in: '%s'", (char *)src); + + int srcSize = resStrLen(src); + int start = 0; + + if (srcSize > 2) { + if (src[0] == ':') { // Game Data Path (Macintosh) + // The default game data path is set to ':' by ScummVM + start = 1; + } else if (src[0] == '.' && src[1] == '\\') { // Game Data Path (Windows) + // The default game data path is set to '.\\' by ScummVM + start = 2; + } else if (src[0] == '*' && src[1] == '\\') { // Save Game Path (Windows HE72 - HE100) + // The default save game path is set to '*\\' by ScummVM + start = 2; + } else if (src[0] == '*' && src[1] == ':') { // Save Game Path (Macintosh HE72 - HE100) + // The default save game path is set to '*:' by ScummVM + start = 2; + } else if (src[0] == 'c' && src[1] == ':') { // Save Game Path (HE60 - HE71) + // The default save path is game path (DOS) or 'c:\\hegames\\' (Windows) + for (start = srcSize; start != 0; start--) + if (src[start - 1] == '\\') + break; + } else if (src[0] == 'u' && src[1] == 's') { // Save Game Path (Moonbase Commander) + // The default save path is 'user\\' + start = 5; } + } - // Switch all : to / for portablity - for (int i = 0; i < len; i++) { - if (dst[i] == ':') - dst[i] = '/'; - } + Common::String dst; + + for (int i = start; i < srcSize; i++) { + // Convert path separators + if (src[i] == '\\' || src[i] == ':') + dst += '/'; + else + dst += src[i]; } - // Strip path - int r = 0; - if (dst[len - 3] == 's' && dst[len - 2] == 'g') { // Save Game File - // Change filename prefix to target name, for save game files. - const char c = dst[len - 1]; - snprintf((char *)dst, dstSize, "%s.sg%c", _targetName.c_str(), c); - } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path - // The default game data path is set to './' by ScummVM - r = 2; - } else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (Windows HE72 - HE100) - // The default save game path is set to '*/' by ScummVM - r = 2; - } else if (dst[0] == '*' && dst[1] == ':') { // Save Game Path (Macintosh HE72 - HE100) - // The default save game path is set to ':/' by ScummVM - r = 2; - } else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71) - // The default save path is game path (DOS) or 'c:/hegames/' (Windows) - for (r = len; r != 0; r--) { - if (dst[r - 1] == '/') - break; + // Sanity check + if (dst.lastChar() == '/') + dst.deleteLastChar(); + + debug(2, "convertFilePath out: '%s'", dst.c_str()); + + return dst; +} + +Common::String ScummEngine_v60he::convertSavePath(const byte *src) { + debug(2, "convertSavePath in: '%s'", (char *)src); + + Common::String filePath = convertFilePath(src); + + // Strip us down to only the file + for (int32 i = filePath.size() - 1; i >= 0; i--) { + if (filePath[i] == '/') { + filePath = Common::String(filePath.c_str() + i + 1); + break; } - } else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander) + } + + // Prepend the target name + filePath = _targetName + '-' + filePath; + + debug(2, "convertSavePath out: '%s'", filePath.c_str()); + + return filePath; +} + +Common::String ScummEngine_v60he::convertSavePathOld(const byte *src) { + // This is provided solely for loading older saved games. + // No new saves should go through this function. + + int srcSize = resStrLen(src); + + // Old hacky target name insertion + // (This breaks the soccer and football games) + if (src[srcSize - 3] == 's' && src[srcSize - 2] == 'g') + return _targetName + ".sg" + (char)src[srcSize - 1]; + + if (src[0] == 'u' && src[1] == 's') { + // Save Game Path (Moonbase Commander) // The default save path is 'user/' - r = 5; + return (char *)src + 5; + } else if (src[0] == '*' && (src[1] == '\\' || src[1] == ':')) { + // Save Game Path (HE72 - HE100) + // The default save game path is set to '*\\' by ScummVM for Windows + // and '*:' for Macintosh + return (char *)src + 2; + } else if (src[0] == 'c' && src[1] == ':') { + // The default save path is game path (DOS) or 'c:\\hegames\\' (Windows) + for (int i = srcSize; i > 0; i--) + if (src[i] == '\\') + return (char *)src + i + 1; + } + + // Can't reach here + return ""; +} + +Common::SeekableReadStream *ScummEngine_v60he::openFileForReading(const byte *fileName) { + Common::SeekableReadStream *saveFile = openSaveFileForReading(fileName); + + if (saveFile) + return saveFile; + + return SearchMan.createReadStreamForMember(convertFilePath(fileName)); +} + +Common::SeekableReadStream *ScummEngine_v60he::openSaveFileForReading(const byte *fileName) { + Common::SeekableReadStream *file = _saveFileMan->openForLoading(convertSavePath(fileName)); + + if (file) + return file; + + return _saveFileMan->openForLoading(convertSavePathOld(fileName)); +} + +Common::WriteStream *ScummEngine_v60he::openSaveFileForWriting(const byte *fileName) { + return _saveFileMan->openForSaving(convertSavePath(fileName)); +} + +void ScummEngine_v60he::deleteSaveFile(const byte *fileName) { + Common::String convertedName = convertSavePath(fileName); + + if (!_saveFileMan->listSavefiles(convertedName).empty()) { + _saveFileMan->removeSavefile(convertedName); + return; } - debug(1, "convertFilePath: converted filePath is %s", dst + r); - return r; + convertedName = convertSavePathOld(fileName); + + if (!_saveFileMan->listSavefiles(convertedName).empty()) + _saveFileMan->removeSavefile(convertedName); +} + +void ScummEngine_v60he::renameSaveFile(const byte *from, const byte *to) { + Common::String toName = convertSavePath(to); + + if (_saveFileMan->renameSavefile(convertSavePathOld(from), toName)) + return; + + _saveFileMan->renameSavefile(convertSavePath(from), toName); +} + +Common::WriteStream *ScummEngine_v60he::openSaveFileForAppending(const byte *fileName) { + Common::SeekableReadStream *initialFile = openSaveFileForReading(fileName); + byte *initialData = 0; + uint32 initialDataSize = 0; + + if (initialFile) { + initialDataSize = initialFile->size(); + + if (initialDataSize > 0) { + initialData = new byte[initialDataSize]; + initialFile->read(initialData, initialDataSize); + } + + delete initialFile; + } + + Common::WriteStream *output = openSaveFileForWriting(fileName); + + if (!output) { + delete[] initialData; + return false; + } + + if (initialData) { + output->write(initialData, initialDataSize); + delete[] initialData; + } + + return output; +} + +Common::SeekableReadStream *ScummEngine_v60he::openSaveFileForReading(int slot, bool compat, Common::String &fileName) { + if (slot == 255) { + // HACK: Allow custom filenames for save game system in HE Games + fileName = convertSavePath((const byte *)_saveLoadFileName.c_str()); + + Common::SeekableReadStream *stream = _saveFileMan->openForLoading(fileName); + if (stream) + return stream; + + Common::String oldFileName = convertSavePathOld((const byte *)_saveLoadFileName.c_str()); + stream = _saveFileMan->openForLoading(oldFileName); + + if (stream) { + fileName = oldFileName; + return stream; + } + + return 0; + } + + return ScummEngine::openSaveFileForReading(slot, compat, fileName); +} + +Common::WriteStream *ScummEngine_v60he::openSaveFileForWriting(int slot, bool compat, Common::String &fileName) { + if (slot == 255) { + // HACK: Allow custom filenames for save game system in HE Games + fileName = convertSavePath((const byte *)_saveLoadFileName.c_str()); + return _saveFileMan->openForSaving(fileName); + } + + return ScummEngine::openSaveFileForWriting(slot, compat, fileName); } void ScummEngine_v60he::o60_setState() { @@ -284,7 +439,7 @@ void ScummEngine_v60he::o60_roomOps() { len = resStrLen(_scriptPointer); _scriptPointer += len + 1; - _saveLoadFileName = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); + _saveLoadFileName = (char *)buffer; debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName.c_str()); _saveLoadFlag = pop(); @@ -692,14 +847,12 @@ void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b) { void ScummEngine_v60he::o60_openFile() { int mode, len, slot, i; byte buffer[100]; - const char *filename; convertMessageToString(_scriptPointer, buffer, sizeof(buffer)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; - filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); - debug(1, "Final filename to %s", filename); + debug(1, "Trying to open file '%s'", (char *)buffer); mode = pop(); slot = -1; @@ -713,14 +866,10 @@ void ScummEngine_v60he::o60_openFile() { if (slot != -1) { switch (mode) { case 1: - // TODO / FIXME: Consider using listSavefiles to avoid unneccessary openForLoading calls - _hInFileTable[slot] = _saveFileMan->openForLoading(filename); - if (_hInFileTable[slot] == 0) { - _hInFileTable[slot] = SearchMan.createReadStreamForMember(filename); - } + _hInFileTable[slot] = openFileForReading(buffer); break; case 2: - _hOutFileTable[slot] = _saveFileMan->openForSaving(filename); + _hOutFileTable[slot] = openSaveFileForWriting(buffer); break; default: error("o60_openFile(): wrong open file mode %d", mode); @@ -750,25 +899,19 @@ void ScummEngine_v60he::o60_closeFile() { void ScummEngine_v60he::o60_deleteFile() { int len; byte buffer[100]; - const char *filename; convertMessageToString(_scriptPointer, buffer, sizeof(buffer)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; - filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); - - debug(1, "o60_deleteFile (\"%s\")", filename); + debug(1, "o60_deleteFile (\"%s\")", (char *)buffer); - if (!_saveFileMan->listSavefiles(filename).empty()) { - _saveFileMan->removeSavefile(filename); - } + deleteSaveFile(buffer); } void ScummEngine_v60he::o60_rename() { int len; byte buffer1[100], buffer2[100]; - const char *newFilename, *oldFilename; convertMessageToString(_scriptPointer, buffer1, sizeof(buffer1)); len = resStrLen(_scriptPointer); @@ -778,12 +921,9 @@ void ScummEngine_v60he::o60_rename() { len = resStrLen(_scriptPointer); _scriptPointer += len + 1; - oldFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1)); - newFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2)); - - debug(1, "o60_rename (\"%s\" to \"%s\")", oldFilename, newFilename); + debug(1, "o60_rename (\"%s\" to \"%s\")", (char *)buffer1, (char *)buffer2); - _saveFileMan->renameSavefile(oldFilename, newFilename); + renameSaveFile(buffer1, buffer2); } int ScummEngine_v60he::readFileToArray(int slot, int32 size) { diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index 42bf9a4bb6..cfa2be7275 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -710,7 +710,7 @@ void ScummEngine_v72he::o72_roomOps() { copyScriptString((byte *)buffer, sizeof(buffer)); - _saveLoadFileName = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); + _saveLoadFileName = (char *)buffer; debug(1, "o72_roomOps: case 221: filename %s", _saveLoadFileName.c_str()); _saveLoadFlag = pop(); @@ -1390,10 +1390,7 @@ void ScummEngine_v72he::o72_openFile() { mode = pop(); copyScriptString(buffer, sizeof(buffer)); - debug(1, "Original filename %s", buffer); - - const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); - debug(1, "Final filename to %s", filename); + debug(1, "Trying to open file '%s'", (char *)buffer); slot = -1; for (i = 1; i < 17; i++) { @@ -1406,48 +1403,17 @@ void ScummEngine_v72he::o72_openFile() { if (slot != -1) { switch (mode) { case 1: // Read mode - if (!_saveFileMan->listSavefiles(filename).empty()) { - _hInFileTable[slot] = _saveFileMan->openForLoading(filename); - } else { - _hInFileTable[slot] = SearchMan.createReadStreamForMember(filename); - } + _hInFileTable[slot] = openFileForReading(buffer); break; case 2: // Write mode - if (!strchr(filename, '/')) { - _hOutFileTable[slot] = _saveFileMan->openForSaving(filename); + if (!strchr((char *)buffer, '/')) { + _hOutFileTable[slot] = openSaveFileForWriting(buffer); } break; - case 6: { // Append mode - if (strchr(filename, '/')) - break; - - // First check if the file already exists - Common::InSaveFile *initialState = 0; - if (!_saveFileMan->listSavefiles(filename).empty()) - initialState = _saveFileMan->openForLoading(filename); - else - initialState = SearchMan.createReadStreamForMember(filename); - - // Read in the data from the initial file - uint32 initialSize = 0; - byte *initialData = 0; - if (initialState) { - initialSize = initialState->size(); - initialData = new byte[initialSize]; - initialState->read(initialData, initialSize); - delete initialState; - } - - // Attempt to open a save file - _hOutFileTable[slot] = _saveFileMan->openForSaving(filename); - - // Begin us off with the data from the previous file - if (_hOutFileTable[slot] && initialData) { - _hOutFileTable[slot]->write(initialData, initialSize); - delete[] initialData; - } - - } break; + case 6: // Append mode + if (!strchr((char *)buffer, '/')) + _hOutFileTable[slot] = openSaveFileForAppending(buffer); + break; default: error("o72_openFile(): wrong open file mode %d", mode); } @@ -1565,13 +1531,10 @@ void ScummEngine_v72he::o72_deleteFile() { byte buffer[256]; copyScriptString(buffer, sizeof(buffer)); - const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); - debug(1, "o72_deleteFile(%s)", filename); + debug(1, "o72_deleteFile(%s)", (char *)buffer); - if (!_saveFileMan->listSavefiles(filename).empty()) { - _saveFileMan->removeSavefile(filename); - } + deleteSaveFile(buffer); } void ScummEngine_v72he::o72_rename() { @@ -1580,12 +1543,9 @@ void ScummEngine_v72he::o72_rename() { copyScriptString(buffer1, sizeof(buffer1)); copyScriptString(buffer2, sizeof(buffer2)); - const char *newFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1)); - const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2)); - - _saveFileMan->renameSavefile(oldFilename, newFilename); + debug(1, "o72_rename(%s to %s)", (char *)buffer2, (char *)buffer1); - debug(1, "o72_rename(%s to %s)", oldFilename, newFilename); + renameSaveFile(buffer2, buffer1); } void ScummEngine_v72he::o72_getPixel() { diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp index ae43d714ad..7a8f230fc0 100644 --- a/engines/scumm/he/script_v80he.cpp +++ b/engines/scumm/he/script_v80he.cpp @@ -89,14 +89,8 @@ void ScummEngine_v80he::o80_getFileSize() { byte buffer[256]; copyScriptString(buffer, sizeof(buffer)); - const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); - Common::SeekableReadStream *f = 0; - if (!_saveFileMan->listSavefiles(filename).empty()) { - f = _saveFileMan->openForLoading(filename); - } else { - f = SearchMan.createReadStreamForMember(filename); - } + Common::SeekableReadStream *f = openFileForReading(buffer); if (!f) { push(-1); @@ -143,14 +137,12 @@ void ScummEngine_v80he::o80_readConfigFile() { byte option[128], section[128], filename[256]; byte *data; Common::String entry; - int len, r; + int len; copyScriptString(option, sizeof(option)); copyScriptString(section, sizeof(section)); copyScriptString(filename, sizeof(filename)); - r = convertFilePath(filename, sizeof(filename)); - if (_game.id == GID_TREASUREHUNT) { // WORKAROUND: Remove invalid characters if (!strcmp((char *)section, "Blue'sTreasureHunt-Disc1")) @@ -159,13 +151,13 @@ void ScummEngine_v80he::o80_readConfigFile() { memcpy(section, "BluesTreasureHunt-Disc2\0", 24); } - if (!strcmp((const char *)filename, "map (i)")) { + if (!strcmp((const char *)filename, ":map (i)")) { // Mac resource fork config file // (as used by only mustard mac for map data?) Common::MacResManager resFork; - if (!resFork.open((const char *)filename) || !resFork.hasResFork()) - error("Could not open '%s'", filename); + if (!resFork.open("map (i)") || !resFork.hasResFork()) + error("Could not open 'map (i)'"); Common::String prefResName = Common::String::format("Pref:%s.%s", (const char *)section, (const char *)option); Common::SeekableReadStream *res = resFork.getResource(prefResName); @@ -180,13 +172,14 @@ void ScummEngine_v80he::o80_readConfigFile() { } } else { // Normal Windows INI files - Common::INIFile confFile; - if (!strcmp((char *)filename + r, "map.ini")) - confFile.loadFromFile((const char *)filename + r); - else - confFile.loadFromSaveFile((const char *)filename + r); + Common::SeekableReadStream *stream = openFileForReading(filename); - confFile.getKey((const char *)option, (const char *)section, entry); + if (stream) { + Common::INIFile iniFile; + iniFile.loadFromStream(*stream); + iniFile.getKey((const char *)option, (const char *)section, entry); + delete stream; + } } byte subOp = fetchScriptByte(); @@ -216,7 +209,7 @@ void ScummEngine_v80he::o80_readConfigFile() { void ScummEngine_v80he::o80_writeConfigFile() { byte filename[256], section[256], option[256], string[1024]; - int r, value; + int value; byte subOp = fetchScriptByte(); @@ -240,8 +233,6 @@ void ScummEngine_v80he::o80_writeConfigFile() { error("o80_writeConfigFile: default type %d", subOp); } - r = convertFilePath(filename, sizeof(filename)); - if (_game.id == GID_TREASUREHUNT) { // WORKAROUND: Remove invalid characters if (!strcmp((char *)section, "Blue'sTreasureHunt-Disc1")) @@ -250,10 +241,16 @@ void ScummEngine_v80he::o80_writeConfigFile() { memcpy(section, "BluesTreasureHunt-Disc2\0", 24); } - Common::INIFile ConfFile; - ConfFile.loadFromSaveFile((const char *)filename + r); - ConfFile.setKey((char *)option, (char *)section, (char *)string); - ConfFile.saveToSaveFile((const char *)filename + r); + Common::INIFile iniFile; + Common::SeekableReadStream *iniStream = openSaveFileForReading(filename); + + if (iniStream) { + iniFile.loadFromStream(*iniStream); + delete iniStream; + } + + iniFile.setKey((char *)option, (char *)section, (char *)string); + iniFile.saveToSaveFile(convertSavePath(filename)); debug(1,"o80_writeConfigFile: Filename %s Section %s Option %s String %s", filename, section, option, string); } diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index 1ea9960a18..f844c51cc6 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -1429,11 +1429,10 @@ void ScummEngine_v90he::o90_videoOps() { if (_videoParams.flags == 0) _videoParams.flags = 4; - const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename)); if (_videoParams.flags & 2) { - VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum); + VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags, _videoParams.wizResNum); } else { - VAR(119) = _moviePlay->load(filename, _videoParams.flags); + VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags); } } else if (_videoParams.status == 165) { // Stop video diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index ca360803bd..b3511648bd 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -2355,8 +2355,6 @@ void Wiz::remapWizImagePal(const WizParameters *params) { } void Wiz::processWizImage(const WizParameters *params) { - byte buffer[260]; - debug(3, "processWizImage: processMode %d", params->processMode); switch (params->processMode) { case 0: @@ -2370,15 +2368,7 @@ void Wiz::processWizImage(const WizParameters *params) { break; case 3: if (params->processFlags & kWPFUseFile) { - Common::SeekableReadStream *f = NULL; - memcpy(buffer, params->filename, 260); - const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer)); - - if (!_vm->_saveFileMan->listSavefiles(filename).empty()) { - f = _vm->_saveFileMan->openForLoading(filename); - } else { - f = SearchMan.createReadStreamForMember(filename); - } + Common::SeekableReadStream *f = _vm->openFileForReading(params->filename); if (f) { uint32 id = f->readUint32BE(); @@ -2388,7 +2378,7 @@ void Wiz::processWizImage(const WizParameters *params) { byte *p = _vm->_res->createResource(rtImage, params->img.resNum, size); if (f->read(p, size) != size) { _vm->_res->nukeResource(rtImage, params->img.resNum); - error("i/o error when reading '%s'", filename); + error("i/o error when reading '%s'", params->filename); _vm->VAR(_vm->VAR_GAME_LOADED) = -2; _vm->VAR(119) = -2; } else { @@ -2404,16 +2394,12 @@ void Wiz::processWizImage(const WizParameters *params) { } else { _vm->VAR(_vm->VAR_GAME_LOADED) = -3; _vm->VAR(119) = -3; - debug(0, "Unable to open for read '%s'", filename); + debug(0, "Unable to open for read '%s'", params->filename); } } break; case 4: if (params->processFlags & kWPFUseFile) { - Common::OutSaveFile *f; - memcpy(buffer, params->filename, 260); - const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer)); - switch (params->fileWriteMode) { case 2: _vm->VAR(119) = -1; @@ -2421,15 +2407,17 @@ void Wiz::processWizImage(const WizParameters *params) { case 1: // TODO Write image to file break; - case 0: - if (!(f = _vm->_saveFileMan->openForSaving(filename))) { - debug(0, "Unable to open for write '%s'", filename); + case 0: { + Common::WriteStream *f = _vm->openSaveFileForWriting(params->filename); + + if (!f) { + debug(0, "Unable to open for write '%s'", params->filename); _vm->VAR(119) = -3; } else { byte *p = _vm->getResourceAddress(rtImage, params->img.resNum); uint32 size = READ_BE_UINT32(p + 4); if (f->write(p, size) != size) { - error("i/o error when writing '%s'", filename); + error("i/o error when writing '%s'", params->filename); _vm->VAR(119) = -2; } else { _vm->VAR(119) = 0; @@ -2438,6 +2426,7 @@ void Wiz::processWizImage(const WizParameters *params) { delete f; } break; + } default: error("processWizImage: processMode 4 unhandled fileWriteMode %d", params->fileWriteMode); } diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 5197e07819..848e288589 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -148,7 +148,17 @@ void ScummEngine::requestLoad(int slot) { _saveLoadFlag = 2; // 2 for load } -static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) { +Common::SeekableReadStream *ScummEngine::openSaveFileForReading(int slot, bool compat, Common::String &fileName) { + fileName = makeSavegameName(slot, compat); + return _saveFileMan->openForLoading(fileName); +} + +Common::WriteStream *ScummEngine::openSaveFileForWriting(int slot, bool compat, Common::String &fileName) { + fileName = makeSavegameName(slot, compat); + return _saveFileMan->openForSaving(fileName); +} + +static bool saveSaveGameHeader(Common::WriteStream *out, SaveGameHeader &hdr) { hdr.type = MKTAG('S','C','V','M'); hdr.size = 0; hdr.ver = CURRENT_VER; @@ -160,7 +170,7 @@ static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) { return true; } -bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) { +bool ScummEngine::saveState(Common::WriteStream *out, bool writeHeader) { SaveGameHeader hdr; if (writeHeader) { @@ -177,20 +187,13 @@ bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) { return true; } -bool ScummEngine::saveState(int slot, bool compat) { +bool ScummEngine::saveState(int slot, bool compat, Common::String &filename) { bool saveFailed; - Common::String filename; - Common::OutSaveFile *out; pauseEngine(true); - if (_saveLoadSlot == 255) { - // Allow custom filenames for save game system in HE Games - filename = _saveLoadFileName; - } else { - filename = makeSavegameName(slot, compat); - } - if (!(out = _saveFileMan->openForSaving(filename))) + Common::WriteStream *out = openSaveFileForWriting(slot, compat, filename); + if (!out) return false; saveFailed = false; @@ -307,18 +310,17 @@ static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &h } bool ScummEngine::loadState(int slot, bool compat) { + // Wrapper around the other variant Common::String filename; - Common::SeekableReadStream *in; + return loadState(slot, compat, filename); +} + +bool ScummEngine::loadState(int slot, bool compat, Common::String &filename) { SaveGameHeader hdr; int sb, sh; - if (_saveLoadSlot == 255) { - // Allow custom filenames for save game system in HE Games - filename = _saveLoadFileName; - } else { - filename = makeSavegameName(slot, compat); - } - if (!(in = _saveFileMan->openForLoading(filename))) + Common::SeekableReadStream *in = openSaveFileForReading(slot, compat, filename); + if (!in) return false; if (!loadSaveGameHeader(in, hdr)) { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index cc8665e450..39fbae8147 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -2307,15 +2307,16 @@ void ScummEngine::scummLoop_handleSaveLoad() { if (_game.version == 8 && _saveTemporaryState) VAR(VAR_GAME_LOADED) = 0; + Common::String filename; if (_saveLoadFlag == 1) { - success = saveState(_saveLoadSlot, _saveTemporaryState); + success = saveState(_saveLoadSlot, _saveTemporaryState, filename); if (!success) errMsg = _("Failed to save game state to file:\n\n%s"); if (success && _saveTemporaryState && VAR_GAME_LOADED != 0xFF && _game.version <= 7) VAR(VAR_GAME_LOADED) = 201; } else { - success = loadState(_saveLoadSlot, _saveTemporaryState); + success = loadState(_saveLoadSlot, _saveTemporaryState, filename); if (!success) errMsg = _("Failed to load game state from file:\n\n%s"); @@ -2323,7 +2324,6 @@ void ScummEngine::scummLoop_handleSaveLoad() { VAR(VAR_GAME_LOADED) = (_game.version == 8) ? 1 : 203; } - Common::String filename = makeSavegameName(_saveLoadSlot, _saveTemporaryState); if (!success) { displayMessage(0, errMsg, filename.c_str()); } else if (_saveLoadFlag == 1 && _saveLoadSlot != 0 && !_saveTemporaryState) { diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index f192a1e256..7d3a01b895 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -595,14 +595,18 @@ protected: Common::String _saveLoadFileName; Common::String _saveLoadDescription; - bool saveState(Common::OutSaveFile *out, bool writeHeader = true); - bool saveState(int slot, bool compat); + bool saveState(Common::WriteStream *out, bool writeHeader = true); + bool saveState(int slot, bool compat, Common::String &fileName); bool loadState(int slot, bool compat); + bool loadState(int slot, bool compat, Common::String &fileName); virtual void saveOrLoad(Serializer *s); void saveResource(Serializer *ser, ResType type, ResId idx); void loadResource(Serializer *ser, ResType type, ResId idx); void loadResourceOLD(Serializer *ser, ResType type, ResId idx); // "Obsolete" + virtual Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName); + virtual Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName); + Common::String makeSavegameName(int slot, bool temporary) const { return makeSavegameName(_targetName, slot, temporary); } @@ -618,6 +622,8 @@ public: void requestSave(int slot, const Common::String &name); void requestLoad(int slot); + Common::String getTargetName() const { return _targetName; } + // thumbnail + info stuff public: static bool querySaveMetaInfos(const char *target, int slot, int heversion, Common::String &desc, Graphics::Surface *&thumbnail, SaveStateMetaInfos *&timeInfos); |