diff options
author | Colin Snover | 2016-12-18 17:42:07 -0600 |
---|---|---|
committer | Colin Snover | 2016-12-18 19:03:30 -0600 |
commit | df38f24c77bac3b1a8958a1bac301d82a43c35c4 (patch) | |
tree | c71af0eb7f7bc4e9926f816e353ded6608f5488c | |
parent | 0015f397428d2f59e393801aa03b9c9b2c84a443 (diff) | |
download | scummvm-rg350-df38f24c77bac3b1a8958a1bac301d82a43c35c4.tar.gz scummvm-rg350-df38f24c77bac3b1a8958a1bac301d82a43c35c4.tar.bz2 scummvm-rg350-df38f24c77bac3b1a8958a1bac301d82a43c35c4.zip |
SCI32: Fix handling of rewritable files opened with mode 1
In SSCI, all files opened through kFileIO are writable. Most of
the time this does not matter and the engine can get away with
using read-only streams, but when chase.dat is opened by Phant1
from the retry dialogue during the chase, it needs to be writable
because game code puts a '98' marker in the chase data. If this
write does not occur, the game gets stuck in a loop looking for
the marker.
-rw-r--r-- | engines/sci/engine/file.cpp | 25 | ||||
-rw-r--r-- | engines/sci/engine/file.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/kfile.cpp | 4 |
3 files changed, 20 insertions, 11 deletions
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp index a20fd7886d..da1d00f3bf 100644 --- a/engines/sci/engine/file.cpp +++ b/engines/sci/engine/file.cpp @@ -78,7 +78,7 @@ class SaveFileRewriteStream : public MemoryDynamicRWStream { public: SaveFileRewriteStream(Common::String fileName, Common::SeekableReadStream *inFile, - bool truncate, bool compress); + kFileOpenMode mode, bool compress); virtual ~SaveFileRewriteStream(); virtual uint32 write(const void *dataPtr, uint32 dataSize) { _changed = true; return MemoryDynamicRWStream::write(dataPtr, dataSize); } @@ -93,16 +93,21 @@ protected: SaveFileRewriteStream::SaveFileRewriteStream(Common::String fileName, Common::SeekableReadStream *inFile, - bool truncate, + kFileOpenMode mode, bool compress) : MemoryDynamicRWStream(DisposeAfterUse::YES), _fileName(fileName), _compress(compress) { + const bool truncate = mode == _K_FILE_MODE_CREATE; + const bool seekToEnd = mode == _K_FILE_MODE_OPEN_OR_CREATE; + if (!truncate && inFile) { unsigned int s = inFile->size(); ensureCapacity(s); inFile->read(_data, s); - seek(0, SEEK_END); + if (seekToEnd) { + seek(0, SEEK_END); + } _changed = false; } else { _changed = true; @@ -163,7 +168,7 @@ uint findFreeFileHandle(EngineState *s) { * for reading only. */ -reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) { +reg_t file_open(EngineState *s, const Common::String &filename, kFileOpenMode mode, bool unwrapFilename) { Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH); englishName.toLowercase(); @@ -200,9 +205,8 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u } #ifdef ENABLE_SCI32 - if (mode != _K_FILE_MODE_OPEN_OR_FAIL && ( - (g_sci->getGameId() == GID_PHANTASMAGORIA && (filename == "phantsg.dir" || filename == "chase.dat")) || - (g_sci->getGameId() == GID_PQSWAT && filename == "swat.dat"))) { + if ((g_sci->getGameId() == GID_PHANTASMAGORIA && (filename == "phantsg.dir" || filename == "chase.dat" || filename == "tmp.dat")) || + (g_sci->getGameId() == GID_PQSWAT && filename == "swat.dat")) { debugC(kDebugLevelFile, " -> file_open opening %s for rewriting", wrappedName.c_str()); inFile = saveFileMan->openForLoading(wrappedName); @@ -211,8 +215,13 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u if (!inFile) inFile = SearchMan.createReadStreamForMember(englishName); + if (mode == _K_FILE_MODE_OPEN_OR_FAIL && !inFile) { + debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); + return SIGNAL_REG; + } + SaveFileRewriteStream *stream; - stream = new SaveFileRewriteStream(wrappedName, inFile, mode == _K_FILE_MODE_CREATE, isCompressed); + stream = new SaveFileRewriteStream(wrappedName, inFile, mode, isCompressed); delete inFile; diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h index 0154338f6c..1c9a092063 100644 --- a/engines/sci/engine/file.h +++ b/engines/sci/engine/file.h @@ -28,7 +28,7 @@ namespace Sci { -enum { +enum kFileOpenMode { _K_FILE_MODE_OPEN_OR_CREATE = 0, _K_FILE_MODE_OPEN_OR_FAIL = 1, _K_FILE_MODE_CREATE = 2 diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 3454358afc..796eb08450 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -46,7 +46,7 @@ namespace Sci { -extern reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename); +extern reg_t file_open(EngineState *s, const Common::String &filename, kFileOpenMode mode, bool unwrapFilename); extern FileHandle *getFileFromHandle(EngineState *s, uint handle); extern int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle); extern void listSavegames(Common::Array<SavegameDesc> &saves); @@ -283,7 +283,7 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { return SIGNAL_REG; } - int mode = argv[1].toUint16(); + kFileOpenMode mode = (kFileOpenMode)argv[1].toUint16(); bool unwrapFilename = true; // SQ4 floppy prepends /\ to the filenames |