aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorColin Snover2016-09-21 12:10:06 -0500
committerColin Snover2016-09-29 19:39:16 -0500
commit0c9d423497073f351e670431fe7680edcebfd67a (patch)
tree327f90322f807ae9c11406720b0a69bbde235034 /engines/sci/engine
parentaa720ca9cd035912a422ece64111d80346b4f477 (diff)
downloadscummvm-rg350-0c9d423497073f351e670431fe7680edcebfd67a.tar.gz
scummvm-rg350-0c9d423497073f351e670431fe7680edcebfd67a.tar.bz2
scummvm-rg350-0c9d423497073f351e670431fe7680edcebfd67a.zip
SCI32: Emulate MGDX ego view metadata
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/file.cpp6
-rw-r--r--engines/sci/engine/file.h8
-rw-r--r--engines/sci/engine/kfile.cpp40
-rw-r--r--engines/sci/engine/savegame.cpp9
-rw-r--r--engines/sci/engine/savegame.h8
5 files changed, 60 insertions, 11 deletions
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index be3fb332ac..717efcb404 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -335,7 +335,11 @@ bool fillSavegameDesc(const Common::String &filename, SavegameDesc *desc) {
desc->time = meta.saveTime;
desc->version = meta.version;
desc->gameVersion = meta.gameVersion;
- desc->score = meta.score;
+ if (g_sci->getGameId() == GID_SHIVERS) {
+ desc->score = meta.score;
+ } else if (g_sci->getGameId() == GID_MOTHERGOOSEHIRES) {
+ desc->avatarId = meta.avatarId;
+ }
if (meta.name.lastChar() == '\n')
meta.name.deleteLastChar();
diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h
index b960058346..7d2461fd7a 100644
--- a/engines/sci/engine/file.h
+++ b/engines/sci/engine/file.h
@@ -65,8 +65,12 @@ struct SavegameDesc {
char name[SCI_MAX_SAVENAME_LENGTH];
Common::String gameVersion;
#ifdef ENABLE_SCI32
- // Used by Shivers 1
- uint32 score;
+ union {
+ // Used by Shivers 1
+ uint32 score;
+ // Used by MGDX
+ uint8 avatarId;
+ };
#endif
};
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 596ff5e65a..e983922024 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -308,9 +308,9 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
unwrapFilename = false;
}
- // Shivers stores the name and score of save games in separate %d.SG files,
- // which are used by the save/load screen
if (g_sci->getGameId() == GID_SHIVERS && name.hasSuffix(".SG")) {
+ // Shivers stores the name and score of save games in separate %d.SG
+ // files, which are used by the save/load screen
if (mode == _K_FILE_MODE_OPEN_OR_CREATE || mode == _K_FILE_MODE_CREATE) {
// Suppress creation of the SG file, since it is not necessary
debugC(kDebugLevelFile, "Not creating unused file %s", name.c_str());
@@ -350,9 +350,41 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, handle);
}
- }
+ } else if (g_sci->getGameId() == GID_MOTHERGOOSEHIRES && name.hasSuffix(".DTA")) {
+ // MGDX stores the name and avatar ID in separate %d.DTA files, which
+ // are used by the save/load screen
+ if (mode == _K_FILE_MODE_OPEN_OR_CREATE || mode == _K_FILE_MODE_CREATE) {
+ // Suppress creation of the DTA file, since it is not necessary
+ 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 saveNo;
+ sscanf(name.c_str(), "%d.DTA", &saveNo);
+ saveNo += kSaveIdShift;
+
+ SavegameDesc save;
+ fillSavegameDesc(g_sci->getSavegameName(saveNo), &save);
+
+ const Common::String avatarId = Common::String::format("%02d", save.avatarId);
+ const uint nameLength = strlen(save.name);
+ const uint size = nameLength + /* \r\n */ 2 + avatarId.size() + 1;
+ char *buffer = (char *)malloc(size);
+ memcpy(buffer, save.name, nameLength);
+ buffer[nameLength] = '\r';
+ buffer[nameLength + 1] = '\n';
+ memcpy(buffer + nameLength + 2, avatarId.c_str(), avatarId.size() + 1);
+
+ const uint handle = findFreeFileHandle(s);
- if (g_sci->getGameId() == GID_KQ7) {
+ s->_fileHandles[handle]._in = new Common::MemoryReadStream((byte *)buffer, size, DisposeAfterUse::YES);
+ s->_fileHandles[handle]._out = nullptr;
+ s->_fileHandles[handle]._name = "";
+
+ return make_reg(0, handle);
+ }
+ } else if (g_sci->getGameId() == GID_KQ7) {
// KQ7 creates a temp.tmp file to perform an atomic rewrite of the
// catalogue, but since we do not create catalogues for most SCI32
// games, ignore the write
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 74493fcfde..aee11ef998 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -331,11 +331,16 @@ static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj)
s.syncAsUint32LE(obj.playTime);
}
+ // Some games require additional metadata to display the load screen
+ // correctly
if (s.getVersion() >= 38) {
if (s.isSaving()) {
- obj.score = g_sci->getEngineState()->variables[VAR_GLOBAL][kScore].toUint16();
+ const reg_t *globals = g_sci->getEngineState()->variables[VAR_GLOBAL];
if (g_sci->getGameId() == GID_SHIVERS) {
- obj.score |= g_sci->getEngineState()->variables[VAR_GLOBAL][kShivers1Score].toUint16() << 16;
+ obj.score = globals[kScore].toUint16();
+ obj.score |= globals[kShivers1Score].toUint16() << 16;
+ } else if (g_sci->getGameId() == GID_MOTHERGOOSEHIRES) {
+ obj.avatarId = readSelectorValue(g_sci->getEngineState()->_segMan, globals[kEgo], SELECTOR(view));
}
}
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 01f92ed342..627fc64118 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -78,8 +78,12 @@ struct SavegameMetadata {
uint16 gameObjectOffset;
uint16 script0Size;
#ifdef ENABLE_SCI32
- // Used by Shivers 1
- uint32 score;
+ union {
+ // Used by Shivers 1
+ uint32 score;
+ // Used by MGDX
+ uint8 avatarId;
+ };
#endif
};