From 2629269212b9a5946e11cadf6abead7856b5fe58 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Thu, 15 Sep 2016 21:08:44 -0500 Subject: SCI32: Emulate Shivers 1 game score metadata --- engines/sci/engine/kfile.cpp | 60 +++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) (limited to 'engines/sci/engine/kfile.cpp') diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index b6fbd45562..33ddd1f6f8 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -328,50 +328,42 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { } #ifdef ENABLE_SCI32 - // Shivers is trying to store savegame descriptions and current spots in - // separate .SG files, which are hardcoded in the scripts. - // Essentially, there is a normal save file, created by the executable - // and an extra hardcoded save file, created by the game scripts, probably - // because they didn't want to modify the save/load code to add the extra - // information. - // Each slot in the book then has two strings, the save description and a - // description of the current spot that the player is at. - // For now, we don't allow the creation of these files, which means that - // all the spot descriptions next to each slot description will be empty. - // Until a viable solution is found to handle these - // extra files and until the spot description strings are initialized - // correctly, we resort to virtual files in order to make the load screen - // useable. Without this code it is unusable, as the extra information is - // always saved to 0.SG for some reason, but on restore the correct file is - // used. Perhaps the virtual ID is not taken into account when saving. - // - // Future TODO: maintain spot descriptions and show them too, ideally without - // having to return to this logic of extra hardcoded files. + // 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")) { if (mode == _K_FILE_MODE_OPEN_OR_CREATE || mode == _K_FILE_MODE_CREATE) { - // Game scripts are trying to create a file with the save - // description, stop them here + // Suppress creation of the SG 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 slotNumber; - sscanf(name.c_str(), "%d.SG", &slotNumber); - - Common::Array saves; - listSavegames(saves); - int savegameNr = findSavegame(saves, slotNumber); - assert(savegameNr >= 0); + int saveNo; + sscanf(name.c_str(), "%d.SG", &saveNo); + + SavegameDesc save; + fillSavegameDesc(g_sci->getSavegameName(saveNo), &save); + Common::String score; + const uint16 lowScore = save.score & 0xFFFF; + const uint16 highScore = save.score >> 16; + + if (!highScore) { + score = Common::String::format("%u", lowScore); + } else { + score = Common::String::format("%u%03u", highScore, lowScore); + } - int size = strlen(saves[savegameNr].name) + 2; - char *buf = (char *)malloc(size); - strcpy(buf, saves[savegameNr].name); - buf[size - 1] = 0; // Spot description (empty) + const uint nameLength = strlen(save.name); + const uint size = nameLength + /* \r\n */ 2 + score.size(); + char *buffer = (char *)malloc(size); + memcpy(buffer, save.name, nameLength); + buffer[nameLength] = '\r'; + buffer[nameLength + 1] = '\n'; + memcpy(buffer + nameLength + 2, score.c_str(), score.size()); - uint handle = findFreeFileHandle(s); + const uint handle = findFreeFileHandle(s); - s->_fileHandles[handle]._in = new Common::MemoryReadStream((byte *)buf, size, DisposeAfterUse::YES); + s->_fileHandles[handle]._in = new Common::MemoryReadStream((byte *)buffer, size, DisposeAfterUse::YES); s->_fileHandles[handle]._out = nullptr; s->_fileHandles[handle]._name = ""; -- cgit v1.2.3