aboutsummaryrefslogtreecommitdiff
path: root/engines/mads
diff options
context:
space:
mode:
authorPaul Gilbert2014-04-26 09:08:46 -0400
committerPaul Gilbert2014-04-26 09:08:46 -0400
commitbae0a6590a4ba843ef51f4cc67875c578863f5b2 (patch)
tree4200d9c0f26d7f5a19c43b3dbdd56a0baaf384b5 /engines/mads
parent44fd705fdf39ea0a0b96fbd1f19e31334a3d2113 (diff)
downloadscummvm-rg350-bae0a6590a4ba843ef51f4cc67875c578863f5b2.tar.gz
scummvm-rg350-bae0a6590a4ba843ef51f4cc67875c578863f5b2.tar.bz2
scummvm-rg350-bae0a6590a4ba843ef51f4cc67875c578863f5b2.zip
MADS: Implemented savegame header read/writes
Diffstat (limited to 'engines/mads')
-rw-r--r--engines/mads/detection.cpp7
-rw-r--r--engines/mads/game.cpp122
-rw-r--r--engines/mads/game.h36
-rw-r--r--engines/mads/mads.cpp8
-rw-r--r--engines/mads/mads.h6
5 files changed, 164 insertions, 15 deletions
diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp
index 015859f827..b8e75b4393 100644
--- a/engines/mads/detection.cpp
+++ b/engines/mads/detection.cpp
@@ -31,6 +31,7 @@
#include "common/system.h"
#include "graphics/colormasks.h"
#include "graphics/surface.h"
+#include "mads/game.h"
#define MAX_SAVES 99
@@ -124,6 +125,7 @@ SaveStateList MADSMetaEngine::listSaves(const char *target) const {
Common::StringArray filenames;
Common::String saveDesc;
Common::String pattern = Common::String::format("%s.0??", target);
+ MADS::MADSSavegameHeader header;
filenames = saveFileMan->listSavefiles(pattern);
sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order
@@ -137,6 +139,11 @@ SaveStateList MADSMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
+ MADS::Game::readSavegameHeader(in, header);
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+
+ header._thumbnail->free();
+ delete header._thumbnail;
delete in;
}
}
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 9c124aa6a6..50c3ccd916 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -21,8 +21,12 @@
*/
#include "common/scummsys.h"
+#include "common/config-manager.h"
#include "common/memstream.h"
#include "common/serializer.h"
+#include "graphics/palette.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
#include "mads/mads.h"
#include "mads/compression.h"
#include "mads/game.h"
@@ -46,6 +50,7 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm),
_scene(vm), _screenObjects(vm), _player(vm) {
_sectionNumber = _priorSectionNumber = 0;
_difficulty = DIFFICULTY_HARD;
+ _loadGameSlot = -1;
_serializer = nullptr;
_statusFlag = 0;
_sectionHandler = nullptr;
@@ -81,22 +86,33 @@ Game::~Game() {
void Game::run() {
initialiseGlobals();
+ // If requested, load a savegame instead of showing the intro
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 999)
+ _loadGameSlot = saveSlot;
+ }
+
_statusFlag = true;
- int protectionResult = checkCopyProtection();
- switch (protectionResult) {
- case PROTECTION_FAIL:
- // Copy protection failed
- _scene._nextSceneId = 804;
- break;
- case PROTECTION_ESCAPE:
- // User escaped out of copy protection dialog
- _vm->quitGame();
- break;
- default:
- // Copy protection check succeeded
- _scene._nextSceneId = 103;
- _scene._priorSceneId = 102;
- break;
+ int protectionResult = -1;
+
+ if (_loadGameSlot == -1) {
+ protectionResult = checkCopyProtection();
+ switch (protectionResult) {
+ case PROTECTION_FAIL:
+ // Copy protection failed
+ _scene._nextSceneId = 804;
+ break;
+ case PROTECTION_ESCAPE:
+ // User escaped out of copy protection dialog
+ _vm->quitGame();
+ break;
+ default:
+ // Copy protection check succeeded
+ _scene._nextSceneId = 103;
+ _scene._priorSceneId = 102;
+ break;
+ }
}
// Get the initial starting time for the first scene
@@ -422,4 +438,80 @@ void Game::synchronize(Common::Serializer &s, bool phase1) {
}
}
+void Game::loadGame(int slotNumber) {
+
+}
+
+void Game::saveGame(int slotNumber, const Common::String &saveName) {
+
+}
+
+const char *const SAVEGAME_STR = "MADS";
+#define SAVEGAME_STR_SIZE 4
+
+bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header) {
+ char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
+ header._thumbnail = NULL;
+
+ // Validate the header Id
+ in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
+ if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE))
+ return false;
+
+ header._version = in->readByte();
+ if (header._version > MADS_SAVEGAME_VERSION)
+ return false;
+
+ // Read in the string
+ header._saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
+
+ // Get the thumbnail
+ header._thumbnail = Graphics::loadThumbnail(*in);
+ if (!header._thumbnail)
+ return false;
+
+ // Read in save date/time
+ header._year = in->readSint16LE();
+ header._month = in->readSint16LE();
+ header._day = in->readSint16LE();
+ header._hour = in->readSint16LE();
+ header._minute = in->readSint16LE();
+ header._totalFrames = in->readUint32LE();
+
+ return true;
+}
+
+void Game::writeSavegameHeader(Common::OutSaveFile *out, MADSSavegameHeader &header) {
+ // Write out a savegame header
+ out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
+
+ out->writeByte(MADS_SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->write(header._saveName.c_str(), header._saveName.size() + 1);
+
+ // Get the active palette
+ uint8 thumbPalette[256 * 3];
+ g_system->getPaletteManager()->grabPalette(thumbPalette, 0, 256);
+
+ // Create a thumbnail and save it
+ Graphics::Surface *thumb = new Graphics::Surface();
+ ::createThumbnail(thumb, _vm->_screen.getData(), MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, thumbPalette);
+ Graphics::saveThumbnail(*out, *thumb);
+ thumb->free();
+ delete thumb;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ out->writeSint16LE(td.tm_year + 1900);
+ out->writeSint16LE(td.tm_mon + 1);
+ out->writeSint16LE(td.tm_mday);
+ out->writeSint16LE(td.tm_hour);
+ out->writeSint16LE(td.tm_min);
+ out->writeUint32LE(_vm->_events->getFrameCounter());
+}
+
} // End of namespace MADS
diff --git a/engines/mads/game.h b/engines/mads/game.h
index ad40fbdcc0..8334d94256 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -24,6 +24,7 @@
#define MADS_GAME_H
#include "common/scummsys.h"
+#include "common/savefile.h"
#include "common/str-array.h"
#include "common/serializer.h"
#include "mads/scene.h"
@@ -54,6 +55,17 @@ enum ProtectionResult {
PROTECTION_SUCCEED = 0, PROTECTION_FAIL = 1, PROTECTION_ESCAPE = 2
};
+#define MADS_SAVEGAME_VERSION 1
+
+struct MADSSavegameHeader {
+ uint8 _version;
+ Common::String _saveName;
+ Graphics::Surface *_thumbnail;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+};
+
class Game {
private:
/**
@@ -78,6 +90,8 @@ protected:
bool _quoteEmergency;
bool _vocabEmergency;
bool _anyEmergency;
+ int _loadGameSlot;
+ Common::String _saveName;
Common::Serializer *_serializer;
/**
@@ -188,6 +202,28 @@ public:
* Handle a keyboard event
*/
void handleKeypress(const Common::Event &event);
+
+ /**
+ * Starts a savegame loading.
+ * @remarks Due to the way the engine is implemented, loading is done in two
+ * parts, the second part after the specific scene has been loaded
+ */
+ void loadGame(int slotNumber);
+
+ /**
+ * Save the current game
+ */
+ void saveGame(int slotNumber, const Common::String &saveName);
+
+ /**
+ * Write out a savegame header
+ */
+ void writeSavegameHeader(Common::OutSaveFile *out, MADSSavegameHeader &header);
+
+ /**
+ * Read in a savegame header
+ */
+ static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header);
};
} // End of namespace MADS
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index 6f57b1df60..1df41ad3fd 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -130,4 +130,12 @@ bool MADSEngine::canSaveGameStateCurrently() {
&& _dialogs->_pendingDialog == DIALOG_NONE;
}
+/**
+* Support method that generates a savegame name
+* @param slot Slot number
+*/
+Common::String MADSEngine::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
} // End of namespace MADS
diff --git a/engines/mads/mads.h b/engines/mads/mads.h
index f13b3b9008..8a4b7f64d1 100644
--- a/engines/mads/mads.h
+++ b/engines/mads/mads.h
@@ -129,6 +129,12 @@ public:
* Returns true if it is currently okay to save the game
*/
bool canSaveGameStateCurrently();
+
+ /**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+ Common::String generateSaveName(int slot);
};
} // End of namespace MADS