aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/core
diff options
context:
space:
mode:
authorPaul Gilbert2016-06-25 23:07:44 -0400
committerPaul Gilbert2016-07-15 19:25:03 -0400
commit04afc633794035cfcc0cb7030113d7750a7dbae3 (patch)
tree13eb89371f23cd0f28a7745a08c64b84b842dbb9 /engines/titanic/core
parent507924b39d0beb50bacb05f3ad15f66fc113f3a9 (diff)
downloadscummvm-rg350-04afc633794035cfcc0cb7030113d7750a7dbae3.tar.gz
scummvm-rg350-04afc633794035cfcc0cb7030113d7750a7dbae3.tar.bz2
scummvm-rg350-04afc633794035cfcc0cb7030113d7750a7dbae3.zip
TITANIC: Adding savegame header load/save methods
Diffstat (limited to 'engines/titanic/core')
-rw-r--r--engines/titanic/core/project_item.cpp128
-rw-r--r--engines/titanic/core/project_item.h35
2 files changed, 161 insertions, 2 deletions
diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp
index 7546f20936..c6a5c2eb61 100644
--- a/engines/titanic/core/project_item.cpp
+++ b/engines/titanic/core/project_item.cpp
@@ -22,6 +22,8 @@
#include "common/file.h"
#include "common/savefile.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
#include "titanic/game_manager.h"
#include "titanic/titanic.h"
#include "titanic/core/dont_save_file_item.h"
@@ -32,6 +34,13 @@
namespace Titanic {
+#define CURRENT_SAVEGAME_VERSION 1
+#define MAX_SAVEGAME_SLOTS 99
+#define MINIMUM_SAVEGAME_VERSION 1
+
+static const char *const SAVEGAME_STR = "TNIC";
+#define SAVEGAME_STR_SIZE 4
+
void CFileListItem::save(SimpleFile *file, int indent) const {
file->writeNumberLine(0, indent);
file->writeQuotedLine(_name, indent);
@@ -158,6 +167,11 @@ void CProjectItem::loadGame(int slotId) {
file.open(newFile);
}
+ // Load the savegame header in
+ TitanicSavegameHeader header;
+ readSavegameHeader(&file, header);
+ delete header._thumbnail;
+
// Load the contents in
CProjectItem *newProject = loadData(&file);
file.IsClassStart();
@@ -183,7 +197,7 @@ void CProjectItem::loadGame(int slotId) {
postLoad();
}
-void CProjectItem::saveGame(int slotId) {
+void CProjectItem::saveGame(int slotId, const CString &desc) {
CompressedFile file;
Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(
Common::String::format("slot%d.gam", slotId));
@@ -192,6 +206,11 @@ void CProjectItem::saveGame(int slotId) {
// Signal the game is being saved
preSave();
+ // Write out the savegame header
+ TitanicSavegameHeader header;
+ header._saveName = desc;
+ writeSavegameHeader(&file, header);
+
// Save the contents out
saveData(&file, this);
@@ -411,4 +430,111 @@ CViewItem *CProjectItem::findView(int roomNumber, int nodeNumber, int viewNumber
return nullptr;
}
+SaveStateList CProjectItem::getSavegameList(const Common::String &target) {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String saveDesc;
+ Common::String pattern = Common::String::format("%s.0??", target.c_str());
+ TitanicSavegameHeader header;
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ const char *ext = strrchr(file->c_str(), '.');
+ int slot = ext ? atoi(ext + 1) : -1;
+
+ if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) {
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
+
+ if (in) {
+ SimpleFile f;
+ f.open(in);
+ if (!readSavegameHeader(&f, header))
+ continue;
+
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+
+ header._thumbnail->free();
+ delete header._thumbnail;
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) {
+ char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
+ header._thumbnail = nullptr;
+
+ // Validate the header Id
+ file->unsafeRead(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
+ if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE)) {
+ file->seek(-SAVEGAME_STR_SIZE, SEEK_CUR);
+ header._saveName = "Unnamed";
+ return true;
+ }
+
+ header._version = file->readByte();
+ if (header._version < MINIMUM_SAVEGAME_VERSION || header._version > CURRENT_SAVEGAME_VERSION)
+ return false;
+
+ // Read in the string
+ header._saveName.clear();
+ char ch;
+ while ((ch = (char)file->readByte()) != '\0') header._saveName += ch;
+
+ // Get the thumbnail
+ header._thumbnail = Graphics::loadThumbnail(*file);
+ if (!header._thumbnail)
+ return false;
+
+ // Read in save date/time
+ header._year = file->readUint16LE();
+ header._month = file->readUint16LE();
+ header._day = file->readUint16LE();
+ header._hour = file->readUint16LE();
+ header._minute = file->readUint16LE();
+ header._totalFrames = file->readUint32LE();
+
+ return true;
+}
+
+void CProjectItem::writeSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) {
+ // Write out a savegame header
+ file->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
+
+ file->writeByte(CURRENT_SAVEGAME_VERSION);
+
+ // Write savegame name
+ file->write(header._saveName.c_str(), header._saveName.size());
+ file->writeByte('\0');
+
+ // Create a thumbnail of the screen and save it out
+ Graphics::Surface *thumb = createThumbnail();
+ Graphics::saveThumbnail(*file, *thumb);
+ thumb->free();
+ delete thumb;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ file->writeUint16LE(td.tm_year + 1900);
+ file->writeUint16LE(td.tm_mon + 1);
+ file->writeUint16LE(td.tm_mday);
+ file->writeUint16LE(td.tm_hour);
+ file->writeUint16LE(td.tm_min);
+ file->writeUint16LE(g_vm->_events->getFrameCounter());
+}
+
+Graphics::Surface *CProjectItem::createThumbnail() {
+ Graphics::Surface *thumb = new Graphics::Surface();
+
+ ::createThumbnailFromScreen(thumb);
+ return thumb;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/core/project_item.h b/engines/titanic/core/project_item.h
index 0807460852..213fa9d638 100644
--- a/engines/titanic/core/project_item.h
+++ b/engines/titanic/core/project_item.h
@@ -24,6 +24,9 @@
#define TITANIC_PROJECT_ITEM_H
#include "common/scummsys.h"
+#include "common/str.h"
+#include "engines/savestate.h"
+#include "graphics/surface.h"
#include "titanic/support/simple_file.h"
#include "titanic/core/dont_save_file_item.h"
#include "titanic/core/file_item.h"
@@ -32,6 +35,16 @@
namespace Titanic {
+struct TitanicSavegameHeader {
+ uint8 _version;
+ CString _saveName;
+ Graphics::Surface *_thumbnail;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+};
+
+
class CGameManager;
class CPetControl;
class CViewItem;
@@ -117,6 +130,26 @@ private:
* Save project data to the passed file
*/
void saveData(SimpleFile *file, CTreeItem *item) const;
+
+ /**
+ * Creates a thumbnail for the current on-screen contents
+ */
+ static Graphics::Surface *createThumbnail();
+public:
+ /**
+ * Load a list of savegames
+ */
+ static SaveStateList getSavegameList(const Common::String &target);
+
+ /**
+ * Write out the header information for a savegame
+ */
+ static void writeSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header);
+
+ /**
+ * Read in the header information for a savegame
+ */
+ static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header);
public:
CLASSDEF
CProjectItem();
@@ -159,7 +192,7 @@ public:
/**
* Save the entire project data to a given savegame slot
*/
- void saveGame(int slotId);
+ void saveGame(int slotId, const CString &desc);
/**
* Clear any currently loaded project