[Scummvm-cvs-logs] scummvm master -> 7044996cd530d1e0efa6a521be85c07111eb76df
bgK
bastien.bouclet at gmail.com
Mon Feb 22 08:45:46 CET 2016
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:
c3c09a1c83 MOHAWK: MystOptionsDialog should not subclass GUI::OptionsDialog
524d7ec5ec MOHAWK: Center the options dialog
6f56f2efe1 MOHAWK: Add Save, Load and Quit buttons to the Myst Dialog
7044996cd5 MOHAWK: Add support for the ScummVM save metadata features
Commit: c3c09a1c83b24d9c0206d9cbb86a4d6d641232b1
https://github.com/scummvm/scummvm/commit/c3c09a1c83b24d9c0206d9cbb86a4d6d641232b1
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-02-22T08:44:55+01:00
Commit Message:
MOHAWK: MystOptionsDialog should not subclass GUI::OptionsDialog
Changed paths:
engines/mohawk/dialogs.cpp
engines/mohawk/dialogs.h
diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp
index ffc4552..492e610 100644
--- a/engines/mohawk/dialogs.cpp
+++ b/engines/mohawk/dialogs.cpp
@@ -87,7 +87,7 @@ enum {
#ifdef ENABLE_MYST
-MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::OptionsDialog("", 120, 120, 360, 200), _vm(vm) {
+MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::Dialog(120, 120, 360, 200), _vm(vm) {
// I18N: Option for fast scene switching
_zipModeCheckbox = new GUI::CheckboxWidget(this, 15, 10, 300, 15, _("~Z~ip Mode Activated"), 0, kZipCmd);
_transitionsCheckbox = new GUI::CheckboxWidget(this, 15, 30, 300, 15, _("~T~ransitions Enabled"), 0, kTransCmd);
@@ -144,18 +144,22 @@ void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, ui
case kMapCmd:
_vm->_needsShowMap = true;
close();
- break;
+ break;
case kMenuCmd:
_vm->_needsShowDemoMenu = true;
close();
- break;
+ break;
case GUI::kOKCmd:
_vm->_gameState->_globals.zipMode = _zipModeCheckbox->getState();
_vm->_gameState->_globals.transitions = _transitionsCheckbox->getState();
- GUI::OptionsDialog::handleCommand(sender, cmd, data);
+ setResult(1);
+ close();
+ break;
+ case GUI::kCloseCmd:
+ close();
break;
default:
- GUI::OptionsDialog::handleCommand(sender, cmd, data);
+ GUI::Dialog::handleCommand(sender, cmd, data);
}
}
diff --git a/engines/mohawk/dialogs.h b/engines/mohawk/dialogs.h
index 7470cd3..c017cb2 100644
--- a/engines/mohawk/dialogs.h
+++ b/engines/mohawk/dialogs.h
@@ -70,7 +70,7 @@ public:
class MohawkEngine_Myst;
-class MystOptionsDialog : public GUI::OptionsDialog {
+class MystOptionsDialog : public GUI::Dialog {
public:
MystOptionsDialog(MohawkEngine_Myst *vm);
~MystOptionsDialog();
Commit: 524d7ec5ec4e8c88cc37bbb5125383b1e3014cd6
https://github.com/scummvm/scummvm/commit/524d7ec5ec4e8c88cc37bbb5125383b1e3014cd6
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-02-22T08:44:55+01:00
Commit Message:
MOHAWK: Center the options dialog
Changed paths:
engines/mohawk/dialogs.cpp
engines/mohawk/dialogs.h
diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp
index 492e610..73b1a15 100644
--- a/engines/mohawk/dialogs.cpp
+++ b/engines/mohawk/dialogs.cpp
@@ -87,7 +87,7 @@ enum {
#ifdef ENABLE_MYST
-MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::Dialog(120, 120, 360, 200), _vm(vm) {
+MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::Dialog(0, 0, 360, 200), _vm(vm) {
// I18N: Option for fast scene switching
_zipModeCheckbox = new GUI::CheckboxWidget(this, 15, 10, 300, 15, _("~Z~ip Mode Activated"), 0, kZipCmd);
_transitionsCheckbox = new GUI::CheckboxWidget(this, 15, 30, 300, 15, _("~T~ransitions Enabled"), 0, kTransCmd);
@@ -135,6 +135,17 @@ void MystOptionsDialog::open() {
_transitionsCheckbox->setState(_vm->_gameState->_globals.transitions);
}
+void MystOptionsDialog::reflowLayout() {
+ const int screenW = g_system->getOverlayWidth();
+ const int screenH = g_system->getOverlayHeight();
+
+ // Center the dialog
+ _x = (screenW - getWidth()) / 2;
+ _y = (screenH - getHeight()) / 2;
+
+ Dialog::reflowLayout();
+}
+
void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kDropCmd:
diff --git a/engines/mohawk/dialogs.h b/engines/mohawk/dialogs.h
index c017cb2..da89090 100644
--- a/engines/mohawk/dialogs.h
+++ b/engines/mohawk/dialogs.h
@@ -76,6 +76,7 @@ public:
~MystOptionsDialog();
void open();
+ virtual void reflowLayout() override;
virtual void handleCommand(GUI::CommandSender*, uint32, uint32);
private:
MohawkEngine_Myst *_vm;
Commit: 6f56f2efe129e55d7ac5cf35378dd385d3f0547b
https://github.com/scummvm/scummvm/commit/6f56f2efe129e55d7ac5cf35378dd385d3f0547b
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-02-22T08:44:55+01:00
Commit Message:
MOHAWK: Add Save, Load and Quit buttons to the Myst Dialog
So that it is possible to play the game without knowing about the GMM
Changed paths:
engines/mohawk/dialogs.cpp
engines/mohawk/dialogs.h
diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp
index 73b1a15..f8aaf0f 100644
--- a/engines/mohawk/dialogs.cpp
+++ b/engines/mohawk/dialogs.cpp
@@ -24,6 +24,7 @@
#include "mohawk/dialogs.h"
#include "gui/gui-manager.h"
+#include "gui/saveload.h"
#include "gui/ThemeEngine.h"
#include "gui/widget.h"
#include "common/system.h"
@@ -82,35 +83,47 @@ enum {
kWaterCmd = 'WATR',
kDropCmd = 'DROP',
kMapCmd = 'SMAP',
- kMenuCmd = 'MENU'
+ kMenuCmd = 'MENU',
+ kSaveCmd = 'SAVE',
+ kLoadCmd = 'LOAD',
+ kQuitCmd = 'QUIT'
};
#ifdef ENABLE_MYST
MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::Dialog(0, 0, 360, 200), _vm(vm) {
// I18N: Option for fast scene switching
- _zipModeCheckbox = new GUI::CheckboxWidget(this, 15, 10, 300, 15, _("~Z~ip Mode Activated"), 0, kZipCmd);
- _transitionsCheckbox = new GUI::CheckboxWidget(this, 15, 30, 300, 15, _("~T~ransitions Enabled"), 0, kTransCmd);
+ _zipModeCheckbox = new GUI::CheckboxWidget(this, 15, 10, 220, 15, _("~Z~ip Mode Activated"), 0, kZipCmd);
+ _transitionsCheckbox = new GUI::CheckboxWidget(this, 15, 30, 220, 15, _("~T~ransitions Enabled"), 0, kTransCmd);
// I18N: Drop book page
_dropPageButton = new GUI::ButtonWidget(this, 15, 60, 100, 25, _("~D~rop Page"), 0, kDropCmd);
// Myst ME only has maps
if (_vm->getFeatures() & GF_ME)
- _showMapButton = new GUI::ButtonWidget(this, 15, 95, 100, 25, _("~S~how Map"), 0, kMapCmd);
+ _showMapButton = new GUI::ButtonWidget(this, 15, 95, 100, 25, _("Show ~M~ap"), 0, kMapCmd);
else
_showMapButton = 0;
// Myst demo only has a menu
if (_vm->getFeatures() & GF_DEMO)
- _returnToMenuButton = new GUI::ButtonWidget(this, 15, 95, 100, 25, _("~M~ain Menu"), 0, kMenuCmd);
+ _returnToMenuButton = new GUI::ButtonWidget(this, 15, 95, 100, 25, _("Main Men~u~"), 0, kMenuCmd);
else
_returnToMenuButton = 0;
+ _loadButton = new GUI::ButtonWidget(this, 245, 25, 100, 25, _("~L~oad"), 0, kLoadCmd);
+ _saveButton = new GUI::ButtonWidget(this, 245, 60, 100, 25, _("~S~ave"), 0, kSaveCmd);
+ new GUI::ButtonWidget(this, 245, 95, 100, 25, _("~Q~uit"), 0, kQuitCmd);
+
new GUI::ButtonWidget(this, 95, 160, 120, 25, _("~O~K"), 0, GUI::kOKCmd);
new GUI::ButtonWidget(this, 225, 160, 120, 25, _("~C~ancel"), 0, GUI::kCloseCmd);
+
+ _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false);
+ _saveDialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
}
MystOptionsDialog::~MystOptionsDialog() {
+ delete _loadDialog;
+ delete _saveDialog;
}
void MystOptionsDialog::open() {
@@ -133,6 +146,33 @@ void MystOptionsDialog::open() {
_zipModeCheckbox->setState(_vm->_gameState->_globals.zipMode);
_transitionsCheckbox->setState(_vm->_gameState->_globals.transitions);
+
+ _loadButton->setEnabled(_vm->canLoadGameStateCurrently());
+ _saveButton->setEnabled(_vm->canSaveGameStateCurrently());
+}
+
+void MystOptionsDialog::save() {
+ int slot = _saveDialog->runModalWithCurrentTarget();
+
+ if (slot >= 0) {
+ Common::String result(_saveDialog->getResultString());
+ if (result.empty()) {
+ // If the user was lazy and entered no save name, come up with a default name.
+ result = _saveDialog->createDefaultSaveDescription(slot);
+ }
+
+ _vm->saveGameState(slot, result);
+ close();
+ }
+}
+
+void MystOptionsDialog::load() {
+ int slot = _loadDialog->runModalWithCurrentTarget();
+
+ if (slot >= 0) {
+ _vm->loadGameState(slot);
+ close();
+ }
}
void MystOptionsDialog::reflowLayout() {
@@ -160,6 +200,19 @@ void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, ui
_vm->_needsShowDemoMenu = true;
close();
break;
+ case kLoadCmd:
+ load();
+ break;
+ case kSaveCmd:
+ save();
+ break;
+ case kQuitCmd: {
+ Common::Event eventQ;
+ eventQ.type = Common::EVENT_QUIT;
+ g_system->getEventManager()->pushEvent(eventQ);
+ close();
+ }
+ break;
case GUI::kOKCmd:
_vm->_gameState->_globals.zipMode = _zipModeCheckbox->getState();
_vm->_gameState->_globals.transitions = _transitionsCheckbox->getState();
diff --git a/engines/mohawk/dialogs.h b/engines/mohawk/dialogs.h
index da89090..bc25c72 100644
--- a/engines/mohawk/dialogs.h
+++ b/engines/mohawk/dialogs.h
@@ -32,6 +32,10 @@
#include "gui/widget.h"
#include "gui/widgets/list.h"
+namespace GUI {
+class SaveLoadChooser;
+}
+
namespace Mohawk {
class MohawkEngine;
@@ -80,11 +84,22 @@ public:
virtual void handleCommand(GUI::CommandSender*, uint32, uint32);
private:
MohawkEngine_Myst *_vm;
+
GUI::CheckboxWidget *_zipModeCheckbox;
GUI::CheckboxWidget *_transitionsCheckbox;
+
GUI::ButtonWidget *_dropPageButton;
GUI::ButtonWidget *_showMapButton;
GUI::ButtonWidget *_returnToMenuButton;
+
+ GUI::ButtonWidget *_loadButton;
+ GUI::ButtonWidget *_saveButton;
+
+ GUI::SaveLoadChooser *_loadDialog;
+ GUI::SaveLoadChooser *_saveDialog;
+
+ void save();
+ void load();
};
#endif
Commit: 7044996cd530d1e0efa6a521be85c07111eb76df
https://github.com/scummvm/scummvm/commit/7044996cd530d1e0efa6a521be85c07111eb76df
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-02-22T08:44:55+01:00
Commit Message:
MOHAWK: Add support for the ScummVM save metadata features
The metadata is saved in a separate file to keep compatibility with
the original engine saves.
Changed paths:
engines/mohawk/detection.cpp
engines/mohawk/myst.cpp
engines/mohawk/myst_state.cpp
engines/mohawk/myst_state.h
diff --git a/engines/mohawk/detection.cpp b/engines/mohawk/detection.cpp
index 926c296..986b35c 100644
--- a/engines/mohawk/detection.cpp
+++ b/engines/mohawk/detection.cpp
@@ -35,6 +35,7 @@
#ifdef ENABLE_MYST
#include "mohawk/myst.h"
+#include "mohawk/myst_state.h"
#endif
#ifdef ENABLE_RIVEN
@@ -184,13 +185,18 @@ public:
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const { return 999; }
virtual void removeSaveState(const char *target, int slot) const;
+ virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
};
bool MohawkMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSupportsListSaves)
|| (f == kSupportsLoadingDuringStartup)
- || (f == kSupportsDeleteSave);
+ || (f == kSupportsDeleteSave)
+ || (f == kSavesSupportMetaInfo)
+ || (f == kSavesSupportThumbnail)
+ || (f == kSavesSupportCreationDate)
+ || (f == kSavesSupportPlayTime);
}
SaveStateList MohawkMetaEngine::listSaves(const char *target) const {
@@ -198,12 +204,15 @@ SaveStateList MohawkMetaEngine::listSaves(const char *target) const {
SaveStateList saveList;
// Loading games is only supported in Myst/Riven currently.
+#ifdef ENABLE_MYST
if (strstr(target, "myst")) {
- filenames = g_system->getSavefileManager()->listSavefiles("*.mys");
+ filenames = Mohawk::MystGameState::generateSaveGameList();
for (uint32 i = 0; i < filenames.size(); i++)
saveList.push_back(SaveStateDescriptor(i, filenames[i]));
- } else if (strstr(target, "riven")) {
+ } else
+#endif
+ if (strstr(target, "riven")) {
filenames = g_system->getSavefileManager()->listSavefiles("*.rvn");
for (uint32 i = 0; i < filenames.size(); i++)
@@ -215,15 +224,35 @@ SaveStateList MohawkMetaEngine::listSaves(const char *target) const {
void MohawkMetaEngine::removeSaveState(const char *target, int slot) const {
// Removing saved games is only supported in Myst/Riven currently.
+#ifdef ENABLE_MYST
if (strstr(target, "myst")) {
- Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles("*.mys");
- g_system->getSavefileManager()->removeSavefile(filenames[slot].c_str());
- } else if (strstr(target, "riven")) {
+ Common::StringArray filenames = Mohawk::MystGameState::generateSaveGameList();
+ Mohawk::MystGameState::deleteSave(filenames[slot]);
+ } else
+#endif
+ if (strstr(target, "riven")) {
Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles("*.rvn");
g_system->getSavefileManager()->removeSavefile(filenames[slot].c_str());
}
}
+SaveStateDescriptor MohawkMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+#ifdef ENABLE_MYST
+ if (strstr(target, "myst")) {
+ Common::StringArray filenames = Mohawk::MystGameState::generateSaveGameList();
+
+ if (slot >= (int) filenames.size()) {
+ return SaveStateDescriptor();
+ }
+
+ return Mohawk::MystGameState::querySaveMetaInfos(filenames[slot]);
+ } else
+#endif
+ {
+ return SaveStateDescriptor();
+ }
+}
+
bool MohawkMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
const Mohawk::MohawkGameDescription *gd = (const Mohawk::MohawkGameDescription *)desc;
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 852196e..5337a5e 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -236,7 +236,7 @@ Common::Error MohawkEngine_Myst::run() {
// Load game from launcher/command line if requested
if (ConfMan.hasKey("save_slot") && canLoadGameStateCurrently()) {
uint32 gameToLoad = ConfMan.getInt("save_slot");
- Common::StringArray savedGamesList = _gameState->generateSaveGameList();
+ Common::StringArray savedGamesList = MystGameState::generateSaveGameList();
if (gameToLoad > savedGamesList.size())
error ("Could not find saved game");
_gameState->load(savedGamesList[gameToLoad]);
@@ -1066,19 +1066,19 @@ void MohawkEngine_Myst::loadResources() {
}
Common::Error MohawkEngine_Myst::loadGameState(int slot) {
- if (_gameState->load(_gameState->generateSaveGameList()[slot]))
+ if (_gameState->load(MystGameState::generateSaveGameList()[slot]))
return Common::kNoError;
return Common::kUnknownError;
}
Common::Error MohawkEngine_Myst::saveGameState(int slot, const Common::String &desc) {
- Common::StringArray saveList = _gameState->generateSaveGameList();
+ Common::StringArray saveList = MystGameState::generateSaveGameList();
if ((uint)slot < saveList.size())
- _gameState->deleteSave(saveList[slot]);
+ MystGameState::deleteSave(saveList[slot]);
- return _gameState->save(Common::String(desc)) ? Common::kNoError : Common::kUnknownError;
+ return _gameState->save(desc) ? Common::kNoError : Common::kUnknownError;
}
bool MohawkEngine_Myst::canLoadGameStateCurrently() {
diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp
index 9bfbba6..06cd69b 100644
--- a/engines/mohawk/myst_state.cpp
+++ b/engines/mohawk/myst_state.cpp
@@ -26,11 +26,41 @@
#include "common/debug.h"
#include "common/serializer.h"
+#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
+#include "graphics/thumbnail.h"
+
namespace Mohawk {
+MystSaveMetadata::MystSaveMetadata() {
+ saveDay = 0;
+ saveMonth = 0;
+ saveYear = 0;
+ saveHour = 0;
+ saveMinute = 0;
+ totalPlayTime = 0;
+}
+
+bool MystSaveMetadata::sync(Common::Serializer &s) {
+ static const Common::Serializer::Version kCurrentVersion = 1;
+
+ if (!s.syncVersion(kCurrentVersion)) {
+ return false;
+ }
+
+ s.syncAsByte(saveDay);
+ s.syncAsByte(saveMonth);
+ s.syncAsUint16LE(saveYear);
+ s.syncAsByte(saveHour);
+ s.syncAsByte(saveMinute);
+ s.syncString(saveDescription);
+ s.syncAsUint32LE(totalPlayTime);
+
+ return true;
+}
+
MystGameState::MystGameState(MohawkEngine_Myst *vm, Common::SaveFileManager *saveFileMan) : _vm(vm), _saveFileMan(saveFileMan) {
// Most of the variables are zero at game start.
memset(&_globals, 0, sizeof(_globals));
@@ -77,28 +107,15 @@ MystGameState::~MystGameState() {
}
Common::StringArray MystGameState::generateSaveGameList() {
- return _saveFileMan->listSavefiles("*.mys");
+ return g_system->getSavefileManager()->listSavefiles("*.mys");
}
bool MystGameState::load(const Common::String &filename) {
- Common::InSaveFile *loadFile = _saveFileMan->openForLoading(filename);
- if (!loadFile)
- return false;
-
- debugC(kDebugSaveLoad, "Loading game from '%s'", filename.c_str());
-
- // First, let's make sure we're using a saved game file from this version of Myst
- // By checking length of file...
- int32 size = loadFile->size();
- if (size != 664 && size != 601) {
- warning("Incompatible saved game version");
- delete loadFile;
+ if (!loadState(filename)) {
return false;
}
- Common::Serializer s(loadFile, nullptr);
- syncGameState(s, size == 664);
- delete loadFile;
+ loadMetadata(filename);
// Set Channelwood elevator state to down, because we start on the lower level
_channelwood.elevatorState = 0;
@@ -119,15 +136,72 @@ bool MystGameState::load(const Common::String &filename) {
return true;
}
-bool MystGameState::save(const Common::String &fname) {
- Common::String filename(fname);
- // Make sure we have the right extension
- if (!filename.hasSuffix(".mys") && !filename.hasSuffix(".MYS"))
- filename += ".mys";
+bool MystGameState::loadState(const Common::String &filename) {
+ Common::InSaveFile *loadFile = _saveFileMan->openForLoading(filename);
+ if (!loadFile) {
+ return false;
+ }
+
+ debugC(kDebugSaveLoad, "Loading game from '%s'", filename.c_str());
+
+ // First, let's make sure we're using a saved game file from this version of Myst
+ // By checking length of file...
+ int32 size = loadFile->size();
+ if (size != 664 && size != 601) {
+ warning("Incompatible saved game version");
+ delete loadFile;
+ return false;
+ }
+
+ Common::Serializer s(loadFile, nullptr);
+ syncGameState(s, size == 664);
+ delete loadFile;
+
+ return true;
+}
+void MystGameState::loadMetadata(const Common::String &filename) {
+ // Open the metadata file
+ Common::InSaveFile *metadataFile = openMetadataFile(filename);
+ if (!metadataFile) {
+ return;
+ }
+
+ debugC(kDebugSaveLoad, "Loading metadata from '%s'", filename.c_str());
+
+ Common::Serializer m(metadataFile, nullptr);
+
+ // Read the metadata file
+ if (_metadata.sync(m)) {
+ _vm->setTotalPlayTime(_metadata.totalPlayTime);
+ }
+
+ delete metadataFile;
+}
+
+bool MystGameState::save(const Common::String &filename) {
+ // Make sure the description does not have an extension
+ Common::String desc = filename;
+ if (filename.hasSuffix(".mys") || filename.hasSuffix(".MYS")) {
+ desc = removeExtension(filename);
+ }
+
+ if (!saveState(desc)) {
+ return false;
+ }
+
+ updateMetadateForSaving(desc);
+
+ return saveMetadata(desc);
+}
+
+bool MystGameState::saveState(const Common::String &desc) {
+ // Make sure we have the right extension
+ Common::String filename = desc + ".mys";
Common::OutSaveFile *saveFile = _saveFileMan->openForSaving(filename);
- if (!saveFile)
+ if (!saveFile) {
return false;
+ }
debugC(kDebugSaveLoad, "Saving game to '%s'", filename.c_str());
@@ -139,6 +213,88 @@ bool MystGameState::save(const Common::String &fname) {
return true;
}
+void MystGameState::updateMetadateForSaving(const Common::String &desc) {
+ // Update save creation info
+ TimeDate t;
+ g_system->getTimeAndDate(t);
+ _metadata.saveYear = t.tm_year + 1900;
+ _metadata.saveMonth = t.tm_mon + 1;
+ _metadata.saveDay = t.tm_mday;
+ _metadata.saveHour = t.tm_hour;
+ _metadata.saveMinute = t.tm_min;
+ _metadata.saveDescription = desc;
+ _metadata.totalPlayTime = _vm->getTotalPlayTime();
+}
+
+bool MystGameState::saveMetadata(const Common::String &desc) {
+ // Write the metadata to a separate file so that the save files
+ // are still compatible with the original engine
+ Common::String metadataFilename = desc + ".mym";
+ Common::OutSaveFile *metadataFile = _saveFileMan->openForSaving(metadataFilename);
+ if (!metadataFile) {
+ return false;
+ }
+
+ // Save the metadata
+ Common::Serializer m(nullptr, metadataFile);
+ _metadata.sync(m);
+
+ // Append a thumbnail
+ Graphics::saveThumbnail(*metadataFile);
+
+ metadataFile->finalize();
+ delete metadataFile;
+
+ return true;
+}
+
+SaveStateDescriptor MystGameState::querySaveMetaInfos(const Common::String filename) {
+ SaveStateDescriptor desc;
+ desc.setDescription(filename);
+
+ // Open the metadata file
+ Common::InSaveFile *metadataFile = openMetadataFile(filename);
+ if (!metadataFile) {
+ return desc;
+ }
+
+ Common::Serializer m(metadataFile, nullptr);
+
+ // Read the metadata file
+ Mohawk::MystSaveMetadata metadata;
+ if (!metadata.sync(m)) {
+ delete metadataFile;
+ return desc;
+ }
+
+ // Set the save description
+ desc.setDescription(metadata.saveDescription);
+ desc.setSaveDate(metadata.saveYear, metadata.saveMonth, metadata.saveDay);
+ desc.setSaveTime(metadata.saveHour, metadata.saveMinute);
+ desc.setPlayTime(metadata.totalPlayTime);
+ desc.setThumbnail(Graphics::loadThumbnail(*metadataFile));
+
+ delete metadataFile;
+
+ return desc;
+}
+
+Common::InSaveFile *MystGameState::openMetadataFile(const Common::String &filename) {
+ // Remove the extension
+ Common::String baseName = removeExtension(filename);
+
+ // Open the metadata file
+ return g_system->getSavefileManager()->openForLoading(baseName + ".mym");
+}
+
+Common::String MystGameState::removeExtension(const Common::String &filename) {
+ Common::String baseName = filename;
+ for (uint i = 0; i < 4; i++) {
+ baseName.deleteLastChar();
+ }
+ return baseName;
+}
+
void MystGameState::syncGameState(Common::Serializer &s, bool isME) {
// Globals first
s.syncAsUint16LE(_globals.u0);
@@ -317,7 +473,10 @@ void MystGameState::syncGameState(Common::Serializer &s, bool isME) {
void MystGameState::deleteSave(const Common::String &saveName) {
debugC(kDebugSaveLoad, "Deleting save file \'%s\'", saveName.c_str());
- _saveFileMan->removeSavefile(saveName.c_str());
+ Common::String basename = removeExtension(saveName);
+
+ g_system->getSavefileManager()->removeSavefile(saveName);
+ g_system->getSavefileManager()->removeSavefile(basename + ".mym");
}
void MystGameState::addZipDest(uint16 stack, uint16 view) {
diff --git a/engines/mohawk/myst_state.h b/engines/mohawk/myst_state.h
index b07a0f2..50359a5 100644
--- a/engines/mohawk/myst_state.h
+++ b/engines/mohawk/myst_state.h
@@ -27,6 +27,8 @@
#include "common/file.h"
#include "common/str.h"
+#include "engines/savestate.h"
+
namespace Common {
class Serializer;
}
@@ -35,15 +37,33 @@ namespace Mohawk {
class MohawkEngine_Myst;
+struct MystSaveMetadata {
+ uint8 saveDay;
+ uint8 saveMonth;
+ uint16 saveYear;
+
+ uint8 saveHour;
+ uint8 saveMinute;
+
+ uint32 totalPlayTime;
+
+ Common::String saveDescription;
+
+ MystSaveMetadata();
+ bool sync(Common::Serializer &s);
+};
+
class MystGameState {
public:
MystGameState(MohawkEngine_Myst*, Common::SaveFileManager*);
~MystGameState();
- Common::StringArray generateSaveGameList();
- bool load(const Common::String &);
- bool save(const Common::String &);
- void deleteSave(const Common::String &);
+ static Common::StringArray generateSaveGameList();
+ static SaveStateDescriptor querySaveMetaInfos(const Common::String filename);
+
+ bool load(const Common::String &filename);
+ bool save(const Common::String &filename);
+ static void deleteSave(const Common::String &saveName);
void addZipDest(uint16 stack, uint16 view);
bool isReachableZipDest(uint16 stack, uint16 view);
@@ -268,8 +288,17 @@ public:
uint32 generatorDepletionTime;
} _stoneship;
+ MystSaveMetadata _metadata;
+
private:
void syncGameState(Common::Serializer &s, bool isME);
+ static Common::InSaveFile *openMetadataFile(const Common::String &filename);
+ bool loadState(const Common::String &filename);
+ void loadMetadata(const Common::String &filename);
+ bool saveState(const Common::String &desc);
+ void updateMetadateForSaving(const Common::String &desc);
+ bool saveMetadata(const Common::String &desc);
+ static Common::String removeExtension(const Common::String &filename);
// The values in these regions are lists of VIEW resources
// which correspond to visited zip destinations
More information about the Scummvm-git-logs
mailing list