TINSEL: Add playTime to saved game and display it
Also bumps the saved game format version to 3. I changed the order of how the data is saved so that the playtime could be read in without skipping as much data. This is because querySaveMetaInfos only needs the metafields where as saveload::DoRestore() needs more of the header. A crash was happening when trying to delete a saved game from the launcher. It is because the engine is not initalized. I assign a dummy value to resolve the issue. Loading saved games from previous versions works. When an old version saved game is loaded it will start with zero playtime. Old saved games are shown as not having playtime data.
This commit is contained in:
parent
5cf3b75deb
commit
f06cf65479
2 changed files with 29 additions and 15 deletions
|
@ -113,6 +113,7 @@ bool TinselMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||||
(f == kSupportsDeleteSave) ||
|
(f == kSupportsDeleteSave) ||
|
||||||
(f == kSimpleSavesNames) ||
|
(f == kSimpleSavesNames) ||
|
||||||
(f == kSavesSupportMetaInfo) ||
|
(f == kSavesSupportMetaInfo) ||
|
||||||
|
(f == kSavesSupportPlayTime) ||
|
||||||
(f == kSavesSupportCreationDate);
|
(f == kSavesSupportCreationDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,16 +135,7 @@ bool Tinsel::TinselEngine::hasFeature(EngineFeature f) const {
|
||||||
|
|
||||||
SaveStateDescriptor TinselMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
|
SaveStateDescriptor TinselMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
|
||||||
Common::String fileName;
|
Common::String fileName;
|
||||||
if (slot < 0)
|
fileName = Common::String::format("%s.%03u", target, slot);
|
||||||
return SaveStateDescriptor();
|
|
||||||
else if (slot < 10)
|
|
||||||
fileName = Common::String::format("%s.00%d", target, slot);
|
|
||||||
else if (slot < 100)
|
|
||||||
fileName = Common::String::format("%s.0%d", target, slot);
|
|
||||||
else if (slot < 1000)
|
|
||||||
fileName = Common::String::format("%s.%d", target, slot);
|
|
||||||
else
|
|
||||||
warning("Too many slots!");
|
|
||||||
|
|
||||||
Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
|
Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
|
||||||
|
|
||||||
|
@ -153,7 +145,7 @@ SaveStateDescriptor TinselMetaEngine::querySaveMetaInfos(const char *target, int
|
||||||
|
|
||||||
file->readUint32LE(); // skip id
|
file->readUint32LE(); // skip id
|
||||||
file->readUint32LE(); // skip size
|
file->readUint32LE(); // skip size
|
||||||
file->readUint32LE(); // skip version
|
uint32 ver = file->readUint32LE();
|
||||||
char saveDesc[Tinsel::SG_DESC_LEN];
|
char saveDesc[Tinsel::SG_DESC_LEN];
|
||||||
file->read(saveDesc, sizeof(saveDesc));
|
file->read(saveDesc, sizeof(saveDesc));
|
||||||
|
|
||||||
|
@ -165,9 +157,16 @@ SaveStateDescriptor TinselMetaEngine::querySaveMetaInfos(const char *target, int
|
||||||
int8 tm_mday = file->readSByte();
|
int8 tm_mday = file->readSByte();
|
||||||
int8 tm_hour = file->readSByte();
|
int8 tm_hour = file->readSByte();
|
||||||
int8 tm_min = file->readSByte();
|
int8 tm_min = file->readSByte();
|
||||||
|
file->readSByte(); // skip secs
|
||||||
|
|
||||||
desc.setSaveDate(1900+tm_year, tm_mon, tm_mday);
|
desc.setSaveDate(1900+tm_year, tm_mon, tm_mday);
|
||||||
desc.setSaveTime(tm_hour, tm_min);
|
desc.setSaveTime(tm_hour, tm_min);
|
||||||
|
|
||||||
|
if (ver >= 3) {
|
||||||
|
uint32 playTime = file->readUint32LE(); // playTime in seconds
|
||||||
|
desc.setPlayTime(playTime);
|
||||||
|
}
|
||||||
|
|
||||||
delete file;
|
delete file;
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace Tinsel {
|
||||||
* only saves/loads those which are valid for the version of the savegame
|
* only saves/loads those which are valid for the version of the savegame
|
||||||
* which is being loaded/saved currently.
|
* which is being loaded/saved currently.
|
||||||
*/
|
*/
|
||||||
#define CURRENT_VER 2
|
#define CURRENT_VER 3
|
||||||
|
|
||||||
//----------------- GLOBAL GLOBAL DATA --------------------
|
//----------------- GLOBAL GLOBAL DATA --------------------
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ struct SaveGameHeader {
|
||||||
uint32 ver;
|
uint32 ver;
|
||||||
char desc[SG_DESC_LEN];
|
char desc[SG_DESC_LEN];
|
||||||
TimeDate dateTime;
|
TimeDate dateTime;
|
||||||
|
uint32 playTime;
|
||||||
bool scnFlag;
|
bool scnFlag;
|
||||||
byte language;
|
byte language;
|
||||||
uint16 numInterpreters; // Savegame version 2 or later only
|
uint16 numInterpreters; // Savegame version 2 or later only
|
||||||
|
@ -94,7 +95,7 @@ struct SaveGameHeader {
|
||||||
enum {
|
enum {
|
||||||
DW1_SAVEGAME_ID = 0x44575399, // = 'DWSc' = "DiscWorld 1 ScummVM"
|
DW1_SAVEGAME_ID = 0x44575399, // = 'DWSc' = "DiscWorld 1 ScummVM"
|
||||||
DW2_SAVEGAME_ID = 0x44573253, // = 'DW2S' = "DiscWorld 2 ScummVM"
|
DW2_SAVEGAME_ID = 0x44573253, // = 'DW2S' = "DiscWorld 2 ScummVM"
|
||||||
SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7 + 1 + 1 + 2
|
SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7 + 4 + 1 + 1 + 2
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SAVEGAME_ID (TinselV2 ? (uint32)DW2_SAVEGAME_ID : (uint32)DW1_SAVEGAME_ID)
|
#define SAVEGAME_ID (TinselV2 ? (uint32)DW2_SAVEGAME_ID : (uint32)DW1_SAVEGAME_ID)
|
||||||
|
@ -152,6 +153,11 @@ static bool syncSaveGameHeader(Common::Serializer &s, SaveGameHeader &hdr) {
|
||||||
|
|
||||||
syncTime(s, hdr.dateTime);
|
syncTime(s, hdr.dateTime);
|
||||||
|
|
||||||
|
if (hdr.ver >= 3)
|
||||||
|
s.syncAsUint32LE(hdr.playTime);
|
||||||
|
else
|
||||||
|
hdr.playTime = 0;
|
||||||
|
|
||||||
int tmp = hdr.size - s.bytesSynced();
|
int tmp = hdr.size - s.bytesSynced();
|
||||||
|
|
||||||
// NOTE: We can't use SAVEGAME_ID here when attempting to remove a saved game from the launcher,
|
// NOTE: We can't use SAVEGAME_ID here when attempting to remove a saved game from the launcher,
|
||||||
|
@ -184,7 +190,10 @@ static bool syncSaveGameHeader(Common::Serializer &s, SaveGameHeader &hdr) {
|
||||||
hdr.numInterpreters = NUM_INTERPRET;
|
hdr.numInterpreters = NUM_INTERPRET;
|
||||||
s.syncAsUint16LE(hdr.numInterpreters);
|
s.syncAsUint16LE(hdr.numInterpreters);
|
||||||
} else {
|
} else {
|
||||||
hdr.numInterpreters = (TinselV2 ? 70 : 64) - 20;
|
if(_vm) // See comment above about bug #3387551
|
||||||
|
hdr.numInterpreters = (TinselV2 ? 70 : 64) - 20;
|
||||||
|
else
|
||||||
|
hdr.numInterpreters = 50; // This value doesn't matter since the saved game is being deleted.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip over any extra bytes
|
// Skip over any extra bytes
|
||||||
|
@ -495,6 +504,11 @@ static bool DoRestore() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hdr.ver >= 3)
|
||||||
|
_vm->setTotalPlayTime(hdr.playTime);
|
||||||
|
else
|
||||||
|
_vm->setTotalPlayTime(0);
|
||||||
|
|
||||||
// Load in the data. For older savegame versions, we potentially need to load the data twice, once
|
// Load in the data. For older savegame versions, we potentially need to load the data twice, once
|
||||||
// for pre 1.5 savegames, and if that fails, a second time for 1.5 savegames
|
// for pre 1.5 savegames, and if that fails, a second time for 1.5 savegames
|
||||||
int numInterpreters = hdr.numInterpreters;
|
int numInterpreters = hdr.numInterpreters;
|
||||||
|
@ -589,6 +603,7 @@ static void DoSave() {
|
||||||
memset(hdr.desc, 0, SG_DESC_LEN);
|
memset(hdr.desc, 0, SG_DESC_LEN);
|
||||||
Common::strlcpy(hdr.desc, g_SaveSceneDesc, SG_DESC_LEN);
|
Common::strlcpy(hdr.desc, g_SaveSceneDesc, SG_DESC_LEN);
|
||||||
g_system->getTimeAndDate(hdr.dateTime);
|
g_system->getTimeAndDate(hdr.dateTime);
|
||||||
|
hdr.playTime = _vm->getTotalPlayTime();
|
||||||
hdr.scnFlag = _vm->getFeatures() & GF_SCNFILES;
|
hdr.scnFlag = _vm->getFeatures() & GF_SCNFILES;
|
||||||
hdr.language = _vm->_config->_language;
|
hdr.language = _vm->_config->_language;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue