[Scummvm-git-logs] scummvm master -> b1ace1a01c15f4964cc91df7fead81e362e24424
csnover
csnover at users.noreply.github.com
Sun May 14 05:53:39 CEST 2017
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
262ef4de61 SCI32: Fix crash at end of Torin
1911b19e15 SCI32: Make sure all save game validity checks are in kCheckSaveGame32
f44d8b6da6 SCI: Dispose uncached volume file streams
b1ace1a01c SCI: Suppress resource warnings when running fallback detection
Commit: 262ef4de61727ebe6ede497f871ef858253c9956
https://github.com/scummvm/scummvm/commit/262ef4de61727ebe6ede497f871ef858253c9956
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-05-13T22:46:13-05:00
Commit Message:
SCI32: Fix crash at end of Torin
This "fix" is more of a hack, in the interest of making the game
completable. The root cause is a combination of two problems in
the game scripts:
1. Blink::init expects to receive either 0 or 2 arguments, but
it assumes that if it received *any* arguments, it must have
received 2 arguments. This assumption is wrong, though,
because--
2. soTorinWhoAreYou::changeState(0) calls
poPecandEyes::setCycle(Blink) without including a second
argument (the blink speed).
This ends up with the second parameter being some garbage, and
that garbage gets sent to kRandom which then complains about
receiving garbage.
The correct fix for this would be to fix soTorinWhoAreYou (in
script 51400) to pass a second argument to setCycle, but there are
not enough obvious spare bytes for a quick and easy patch, so this
workaround will have to do for now.
Fixes Trac#9779.
Changed paths:
engines/sci/engine/kernel_tables.h
engines/sci/engine/workarounds.cpp
engines/sci/engine/workarounds.h
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index de9f662..a0e7ccf 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -768,7 +768,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(Portrait), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
{ MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL },
{ MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL },
- { MAP_CALL(Random), SIG_EVERYWHERE, "(i)(i)", NULL, NULL },
+ { MAP_CALL(Random), SIG_EVERYWHERE, "(i)(i)", NULL, kRandom_workarounds },
{ MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, kReadNumber_workarounds },
{ MAP_CALL(RemapColors), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, NULL },
#ifdef ENABLE_SCI32
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index c951404..9301fe6 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -781,6 +781,13 @@ const SciWorkaroundEntry kPlatform32_workarounds[] = {
};
// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
+const SciWorkaroundEntry kRandom_workarounds[] = {
+ { GID_TORIN, 51400, 64928, 0, "Blink", "init", NULL, -1, { WORKAROUND_FAKE, 0 } }, // at the end of the game, during the cutscene after touching the collar on Lycentia; Trac#9779
+ { GID_TORIN, 51400, 64928, 0, "Blink", "cycleDone", NULL, -1, { WORKAROUND_FAKE, 0 } }, // at the end of the game, during the cutscene after touching the collar on Lycentia; Trac#9779
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kReadNumber_workarounds[] = {
{ GID_CNICK_LAURABOW,100, 101, 0, "dominoes.opt", "doit", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #6425
{ GID_HOYLE3, 100, 101, 0, "dominoes.opt", "doit", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #6425
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 08a9fa6..5b716fd 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -92,6 +92,7 @@ extern const SciWorkaroundEntry kPalVarySetVary_workarounds[];
extern const SciWorkaroundEntry kPalVarySetPercent_workarounds[];
extern const SciWorkaroundEntry kPalVaryMergeStart_workarounds[];
extern const SciWorkaroundEntry kPlatform32_workarounds[];
+extern const SciWorkaroundEntry kRandom_workarounds[];
extern const SciWorkaroundEntry kReadNumber_workarounds[];
extern const SciWorkaroundEntry kResCheck_workarounds[];
extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[];
Commit: 1911b19e154b4e946d29dbf143b18cb6c9e4b660
https://github.com/scummvm/scummvm/commit/1911b19e154b4e946d29dbf143b18cb6c9e4b660
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-05-13T22:46:25-05:00
Commit Message:
SCI32: Make sure all save game validity checks are in kCheckSaveGame32
Save game metadata validity checks in SCI32 should all exist within
kCheckSaveGame32 since this allows most games to recover
successfully from an attempt to load an invalid save game. If
gamestate_restore fails, the game will usually crash because the
engine is left in an inconsistent state (game scripts have cleaned
up objects in preparation for a game load that is no longer
happening).
Changed paths:
engines/sci/engine/file.cpp
engines/sci/engine/file.h
engines/sci/engine/kfile.cpp
engines/sci/engine/savegame.cpp
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index 91cf189..2128433 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -357,6 +357,8 @@ bool fillSavegameDesc(const Common::String &filename, SavegameDesc *desc) {
desc->time = meta.saveTime;
desc->version = meta.version;
desc->gameVersion = meta.gameVersion;
+ desc->script0Size = meta.script0Size;
+ desc->gameObjectOffset = meta.gameObjectOffset;
#ifdef ENABLE_SCI32
if (g_sci->getGameId() == GID_SHIVERS) {
desc->lowScore = meta.lowScore;
diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h
index 1c9a092..fee628a 100644
--- a/engines/sci/engine/file.h
+++ b/engines/sci/engine/file.h
@@ -64,6 +64,8 @@ struct SavegameDesc {
int version;
char name[SCI_MAX_SAVENAME_LENGTH];
Common::String gameVersion;
+ uint32 script0Size;
+ uint32 gameObjectOffset;
#ifdef ENABLE_SCI32
// Used by Shivers 1
uint16 lowScore;
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index e386b13..fd6fab6 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -1328,6 +1328,21 @@ reg_t kCheckSaveGame32(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
}
+ if (save.gameObjectOffset > 0 && save.script0Size > 0) {
+ Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false);
+ assert(script0);
+
+ if (save.script0Size != script0->size()) {
+ warning("Save game was created for a game with a script 0 size of %u, but the current game script 0 size is %u", save.script0Size, script0->size());
+ return NULL_REG;
+ }
+
+ if (save.gameObjectOffset != g_sci->getGameObject().getOffset()) {
+ warning("Save game was created for a game with the main game object at offset %u, but the current main game object offset is %u", save.gameObjectOffset, g_sci->getGameObject().getOffset());
+ return NULL_REG;
+ }
+ }
+
return TRUE_REG;
}
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 5172de3..dce6430 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -1257,26 +1257,29 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
return;
}
- if ((meta.version < MINIMUM_SAVEGAME_VERSION) || (meta.version > CURRENT_SAVEGAME_VERSION)) {
- if (meta.version < MINIMUM_SAVEGAME_VERSION) {
- showScummVMDialog(_("The format of this saved game is obsolete, unable to load it"));
- } else {
- Common::String msg = Common::String::format(_("Savegame version is %d, maximum supported is %0d"), meta.version, CURRENT_SAVEGAME_VERSION);
- showScummVMDialog(msg);
- }
-
- s->r_acc = TRUE_REG; // signal failure
- return;
- }
-
- if (meta.gameObjectOffset > 0 && meta.script0Size > 0) {
- Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false);
- if (script0->size() != meta.script0Size || g_sci->getGameObject().getOffset() != meta.gameObjectOffset) {
- showScummVMDialog(_("This saved game was created with a different version of the game, unable to load it"));
+ // In SCI32 these checks are all in kCheckSaveGame32
+ if (getSciVersion() < SCI_VERSION_2) {
+ if ((meta.version < MINIMUM_SAVEGAME_VERSION) || (meta.version > CURRENT_SAVEGAME_VERSION)) {
+ if (meta.version < MINIMUM_SAVEGAME_VERSION) {
+ showScummVMDialog(_("The format of this saved game is obsolete, unable to load it"));
+ } else {
+ Common::String msg = Common::String::format(_("Savegame version is %d, maximum supported is %0d"), meta.version, CURRENT_SAVEGAME_VERSION);
+ showScummVMDialog(msg);
+ }
s->r_acc = TRUE_REG; // signal failure
return;
}
+
+ if (meta.gameObjectOffset > 0 && meta.script0Size > 0) {
+ Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false);
+ if (script0->size() != meta.script0Size || g_sci->getGameObject().getOffset() != meta.gameObjectOffset) {
+ showScummVMDialog(_("This saved game was created with a different version of the game, unable to load it"));
+
+ s->r_acc = TRUE_REG; // signal failure
+ return;
+ }
+ }
}
// We don't need the thumbnail here, so just read it and discard it
Commit: f44d8b6da69a1444c76fcbce28a834f2368ddf35
https://github.com/scummvm/scummvm/commit/f44d8b6da69a1444c76fcbce28a834f2368ddf35
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-05-13T22:46:25-05:00
Commit Message:
SCI: Dispose uncached volume file streams
The stream returned by a call to ResourceManager::getVolumeFile
either MUST (when returning an I/O stream from a Common::FSNode)
or must NOT (when returning a Common::File *) be deleted by the
caller, depending upon some internal implementation details of
ResourceSource that should never have been exposed to callers.
FSNode streams that should have been deleted were not being
deleted all the time, which leaked and eventually caused ScummVM
to run out of FDs.
This commit improves this situation by shielding callers from
these internal details by centralizing the destruction logic in
one place, so FSNode read streams stop being leaked and callers
no longer need to know stuff about the internals of the
ResourceSource they are trying to read in order to avoid leaking
or breaking the volume file cache.
Fixes Trac#9782.
Changed paths:
engines/sci/resource.cpp
engines/sci/resource.h
engines/sci/resource_audio.cpp
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 6ee77fd..f1b2a58 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -387,6 +387,24 @@ Common::SeekableReadStream *ResourceManager::getVolumeFile(ResourceSource *sourc
return NULL;
}
+void ResourceManager::disposeVolumeFileStream(Common::SeekableReadStream *fileStream, Sci::ResourceSource *source) {
+#ifdef ENABLE_SCI32
+ ChunkResourceSource *chunkSource = dynamic_cast<ChunkResourceSource *>(source);
+ if (chunkSource != nullptr) {
+ delete fileStream;
+ return;
+ }
+#endif
+
+ if (source->_resourceFile) {
+ delete fileStream;
+ return;
+ }
+
+ // Other volume file streams are cached in _volumeFiles and should only be
+ // deleted from _volumeFiles
+}
+
void ResourceManager::loadResource(Resource *res) {
res->_source->loadResource(this, res);
}
@@ -575,8 +593,7 @@ void ResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
res->unalloc();
}
- if (_resourceFile)
- delete fileStream;
+ resMan->disposeVolumeFileStream(fileStream, this);
}
Resource *ResourceManager::testResource(ResourceId id) {
@@ -2041,6 +2058,7 @@ Resource *ResourceManager::updateResource(ResourceId resId, ResourceSource *src,
if (avSrc != nullptr && !avSrc->relocateMapOffset(offset, size)) {
warning("Compressed volume %s does not contain a valid entry for %s (map offset %u)", src->getLocationName().c_str(), resId.toString().c_str(), offset);
_hasBadResources = true;
+ disposeVolumeFileStream(volumeFile, src);
return res;
}
@@ -2059,6 +2077,7 @@ Resource *ResourceManager::updateResource(ResourceId resId, ResourceSource *src,
_hasBadResources = true;
}
+ disposeVolumeFileStream(volumeFile, src);
return res;
}
@@ -2252,13 +2271,11 @@ ResourceCompression ResourceManager::getViewCompression() {
ResourceCompression compression;
if (res->readResourceInfo(_volVersion, fileStream, szPacked, compression)) {
- if (res->_source->_resourceFile)
- delete fileStream;
+ disposeVolumeFileStream(fileStream, res->_source);
continue;
}
- if (res->_source->_resourceFile)
- delete fileStream;
+ disposeVolumeFileStream(fileStream, res->_source);
if (compression != kCompNone)
return compression;
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 2bbbd42..1a10fb2 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -516,7 +516,13 @@ protected:
*/
const char *versionDescription(ResVersion version) const;
+ /**
+ * All calls to getVolumeFile must be followed with a corresponding
+ * call to disposeVolumeFileStream once the stream is finished being used.
+ * Do NOT call delete directly on returned streams, as they may be cached.
+ */
Common::SeekableReadStream *getVolumeFile(ResourceSource *source);
+ void disposeVolumeFileStream(Common::SeekableReadStream *fileStream, ResourceSource *source);
void loadResource(Resource *res);
void freeOldResources();
bool validateResource(const ResourceId &resourceId, const Common::String &sourceMapLocation, const Common::String &sourceName, const uint32 offset, const uint32 size, const uint32 sourceSize) const;
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 0b00725..7553efa 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -43,7 +43,7 @@ AudioVolumeResourceSource::AudioVolumeResourceSource(ResourceManager *resMan, co
* table for later usage.
*/
- Common::SeekableReadStream *fileStream = getVolumeFile(resMan, 0);
+ Common::SeekableReadStream *fileStream = getVolumeFile(resMan, nullptr);
if (!fileStream)
return;
@@ -75,8 +75,7 @@ AudioVolumeResourceSource::AudioVolumeResourceSource(ResourceManager *resMan, co
lastEntry->size = fileStream->size() - lastEntry->offset;
}
- if (_resourceFile)
- delete fileStream;
+ resMan->disposeVolumeFileStream(fileStream, this);
}
bool Resource::loadFromWaveFile(Common::SeekableReadStream *file) {
@@ -320,6 +319,7 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) {
}
const uint32 srcSize = fileStream->size();
+ disposeVolumeFileStream(fileStream, src);
SciSpan<const byte>::const_iterator ptr = mapRes->cbegin();
@@ -400,6 +400,8 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) {
}
addResource(audioResId, src, offset, size, map->getLocationName());
}
+
+ disposeVolumeFileStream(stream, src);
} else {
bool isEarly = (entrySize != 11);
@@ -928,8 +930,7 @@ void WaveResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
fileStream->seek(res->_fileOffset, SEEK_SET);
res->loadFromWaveFile(fileStream);
- if (_resourceFile)
- delete fileStream;
+ resMan->disposeVolumeFileStream(fileStream, this);
}
void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
@@ -951,8 +952,7 @@ void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource *
else
res->loadFromAudioVolumeSCI11(fileStream);
- if (_resourceFile)
- delete fileStream;
+ resMan->disposeVolumeFileStream(fileStream, this);
}
bool ResourceManager::addAudioSources() {
Commit: b1ace1a01c15f4964cc91df7fead81e362e24424
https://github.com/scummvm/scummvm/commit/b1ace1a01c15f4964cc91df7fead81e362e24424
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-05-13T22:49:40-05:00
Commit Message:
SCI: Suppress resource warnings when running fallback detection
For the moment, only warn about bad resources when a game is
actually starting, since unknown but valid resources being
detected by the fallback detector currently also trigger the
warning.
Changed paths:
engines/sci/detection.cpp
engines/sci/resource.cpp
engines/sci/resource.h
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index cc6bb00..93157b0 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -612,7 +612,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles,
if (!foundResMap && !foundRes000)
return 0;
- ResourceManager resMan;
+ ResourceManager resMan(true);
resMan.addAppropriateSourcesForDetection(fslist);
resMan.init();
// TODO: Add error handling.
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index f1b2a58..068be66 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -809,7 +809,7 @@ void ResourceManager::scanNewSources() {
// (e.g. KQ5 via kDoAudio, MGDX via kSetLanguage), and users really should
// be warned of bad resources in this situation (KQ Collection 1997 has a
// bad copy of KQ5 on CD 1; the working copy is on CD 2)
- if (_hasBadResources) {
+ if (!_detectionMode && _hasBadResources) {
showScummVMDialog(_("Missing or corrupt game resources have been detected. "
"Some game features may not work properly. Please check "
"the console for more information, and verify that your "
@@ -950,8 +950,8 @@ void ResourceManager::freeResourceSources() {
_sources.clear();
}
-ResourceManager::ResourceManager() {
-}
+ResourceManager::ResourceManager(const bool detectionMode) :
+ _detectionMode(detectionMode) {}
void ResourceManager::init() {
_maxMemoryLRU = 256 * 1024; // 256KiB
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 1a10fb2..3239a16 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -319,7 +319,7 @@ public:
/**
* Creates a new SCI resource manager.
*/
- ResourceManager();
+ ResourceManager(const bool detectionMode = false);
~ResourceManager();
@@ -454,6 +454,8 @@ public:
ResourceType convertResType(byte type);
protected:
+ bool _detectionMode;
+
// Maximum number of bytes to allow being allocated for resources
// Note: maxMemory will not be interpreted as a hard limit, only as a restriction
// for resources which are not explicitly locked. However, a warning will be
More information about the Scummvm-git-logs
mailing list