aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2016-12-18 17:42:07 -0600
committerColin Snover2016-12-18 19:03:30 -0600
commitdf38f24c77bac3b1a8958a1bac301d82a43c35c4 (patch)
treec71af0eb7f7bc4e9926f816e353ded6608f5488c
parent0015f397428d2f59e393801aa03b9c9b2c84a443 (diff)
downloadscummvm-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.cpp25
-rw-r--r--engines/sci/engine/file.h2
-rw-r--r--engines/sci/engine/kfile.cpp4
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