aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2009-04-18 10:16:08 +0000
committerPaul Gilbert2009-04-18 10:16:08 +0000
commit15252ad83c49c0246fabb24856c02fb6bb81ced5 (patch)
treed71dab6a10a2ba14e92b69ea8c6b860efaadffba /engines
parent0b2e06e4a4225a6ede1be4e9f6c09fe2cd4caf16 (diff)
downloadscummvm-rg350-15252ad83c49c0246fabb24856c02fb6bb81ced5.tar.gz
scummvm-rg350-15252ad83c49c0246fabb24856c02fb6bb81ced5.tar.bz2
scummvm-rg350-15252ad83c49c0246fabb24856c02fb6bb81ced5.zip
Added support for the global menu save/loading, and changed the savegame format to store the savegame name and thumbnail
svn-id: r39979
Diffstat (limited to 'engines')
-rw-r--r--engines/cruise/cruise.cpp32
-rw-r--r--engines/cruise/cruise.h11
-rw-r--r--engines/cruise/cruise_main.cpp14
-rw-r--r--engines/cruise/detection.cpp65
-rw-r--r--engines/cruise/function.cpp4
-rw-r--r--engines/cruise/menu.cpp4
-rw-r--r--engines/cruise/saveload.cpp113
-rw-r--r--engines/cruise/saveload.h14
-rw-r--r--engines/cruise/vars.cpp2
-rw-r--r--engines/cruise/vars.h2
10 files changed, 210 insertions, 51 deletions
diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
index 283817d2a4..ed8cf5f47b 100644
--- a/engines/cruise/cruise.cpp
+++ b/engines/cruise/cruise.cpp
@@ -74,6 +74,13 @@ CruiseEngine::~CruiseEngine() {
freeSystem();
}
+bool CruiseEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
Common::Error CruiseEngine::run() {
// Initialize backend
initGraphics(320, 200, false);
@@ -156,8 +163,8 @@ bool CruiseEngine::loadLanguageStrings() {
return true;
}
-void CruiseEngine::pauseEngineIntern(bool pause) {
- Engine::pauseEngineIntern(pause);
+void CruiseEngine::pauseEngine(bool pause) {
+ Engine::pauseEngine(pause);
if (pause) {
// Draw the 'Paused' message
@@ -174,5 +181,26 @@ void CruiseEngine::pauseEngineIntern(bool pause) {
}
}
+Common::Error CruiseEngine::loadGameState(int slot) {
+ return loadSavegameData(slot);
+}
+
+bool CruiseEngine::canLoadGameStateCurrently() {
+ return playerMenuEnabled != 0;
+}
+
+Common::Error CruiseEngine::saveGameState(int slot, const char *desc) {
+ return saveSavegameData(slot, desc);
+}
+
+bool CruiseEngine::canSaveGameStateCurrently() {
+ return (playerMenuEnabled != 0) && (userEnabled != 0);
+}
+
+const char *CruiseEngine::getSavegameFile(int saveGameIdx) {
+ static char buffer[20];
+ sprintf(buffer, "cruise.s%02d", saveGameIdx);
+ return buffer;
+}
} // End of namespace Cruise
diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h
index 987d283df1..41d10f2b1d 100644
--- a/engines/cruise/cruise.h
+++ b/engines/cruise/cruise.h
@@ -30,6 +30,7 @@
#include "common/util.h"
#include "engines/engine.h"
+#include "engines/game.h"
#include "cruise/cruise_main.h"
#include "cruise/debugger.h"
@@ -79,6 +80,7 @@ protected:
public:
CruiseEngine(OSystem * syst, const CRUISEGameDescription *gameDesc);
virtual ~ CruiseEngine();
+ virtual bool hasFeature(EngineFeature f) const;
int getGameType() const;
uint32 getFeatures() const;
@@ -89,11 +91,14 @@ public:
bool mt32() const { return _mt32; }
bool adlib() const { return _adlib; }
virtual GUI::Debugger *getDebugger() { return _debugger; }
- virtual void pauseEngineIntern(bool pause);
+ virtual void pauseEngine(bool pause);
const char *langString(LangStringId langId) { return _langStrings[(int)langId].c_str(); }
- bool loadSaveDirectory(void);
- void makeSystemMenu(void);
+ static const char *getSavegameFile(int saveGameIdx);
+ virtual Common::Error loadGameState(int slot);
+ virtual bool canLoadGameStateCurrently();
+ virtual Common::Error saveGameState(int slot, const char *desc);
+ virtual bool canSaveGameStateCurrently();
const CRUISEGameDescription *_gameDescription;
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index 21e99948b8..91398f1e6b 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -23,6 +23,7 @@
*
*/
+#include "common/config-manager.h"
#include "common/endian.h"
#include "common/events.h"
#include "common/system.h" // for g_system->getEventManager()
@@ -34,6 +35,7 @@
namespace Cruise {
+static int playerDontAskQuit;
unsigned int timer = 0;
gfxEntryStruct* linkedMsgList = NULL;
@@ -1583,8 +1585,9 @@ void manageEvents() {
currentMouseY = event.mouse.y;
break;
case Common::EVENT_QUIT:
- g_system->quit();
- break;
+ case Common::EVENT_RTL:
+ playerDontAskQuit = 1;
+ return;
case Common::EVENT_KEYUP:
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
@@ -1724,7 +1727,7 @@ void CruiseEngine::mainLoop(void) {
initAllData();
- int playerDontAskQuit = 1;
+ playerDontAskQuit = 0;
int quitValue2 = 1;
int quitValue = 0;
@@ -1739,6 +1742,7 @@ void CruiseEngine::mainLoop(void) {
currentTick = g_system->getMillis();
manageEvents();
+ if (playerDontAskQuit) break;
if (_vm->getDebugger()->isAttached())
_vm->getDebugger()->onFrame();
@@ -1753,6 +1757,8 @@ void CruiseEngine::mainLoop(void) {
_vm->getDebugger()->onFrame();
}
}
+ if (playerDontAskQuit)
+ break;
lastTick = g_system->getMillis();
@@ -1763,6 +1769,8 @@ void CruiseEngine::mainLoop(void) {
// readKeyboard();
playerDontAskQuit = processInput();
+ if (playerDontAskQuit)
+ break;
if (enableUser) {
userEnabled = 1;
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index d467bf7710..791b6006fc 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -30,6 +30,7 @@
#include "engines/advancedDetector.h"
#include "cruise/cruise.h"
+#include "cruise/saveload.h"
namespace Cruise {
@@ -177,9 +178,72 @@ public:
return "Cruise for a Corpse (C) Delphine Software";
}
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual int getMaximumSaveSlot() const { return 99; };
+ virtual SaveStateList listSaves(const char *target) const;
+ virtual void removeSaveState(const char *target, int slot) const;
+ virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
};
+bool CruiseMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+SaveStateList CruiseMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ Common::String pattern("cruise.s??");
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 0 && slotNum <= 99) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ Cruise::CruiseSavegameHeader header;
+ Cruise::readSavegameHeader(in, header);
+ saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
+ if (header.thumbnail) delete header.thumbnail;
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+void CruiseMetaEngine::removeSaveState(const char *target, int slot) const {
+ g_system->getSavefileManager()->removeSavefile(Cruise::CruiseEngine::getSavegameFile(slot));
+}
+
+SaveStateDescriptor CruiseMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(
+ Cruise::CruiseEngine::getSavegameFile(slot));
+ assert(f);
+
+ Cruise::CruiseSavegameHeader header;
+ Cruise::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header.saveName);
+ desc.setDeletableFlag(true);
+ desc.setWriteProtectedFlag(false);
+ desc.setThumbnail(header.thumbnail);
+
+ return desc;
+}
+
bool CruiseMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
const Cruise::CRUISEGameDescription *gd = (const Cruise::CRUISEGameDescription *)desc;
if (gd) {
@@ -188,6 +252,7 @@ bool CruiseMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGa
return gd != 0;
}
+
#if PLUGIN_ENABLED_DYNAMIC(CRUISE)
REGISTER_PLUGIN_DYNAMIC(CRUISE, PLUGIN_TYPE_ENGINE, CruiseMetaEngine);
#else
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index 2c87fa2599..3f65d61790 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -451,8 +451,8 @@ int16 Op_KillMenu(void) {
}
int16 Op_UserMenu(void) {
- int oldValue = entrerMenuJoueur;
- entrerMenuJoueur = popVar();
+ int oldValue = playerMenuEnabled;
+ playerMenuEnabled = popVar();
return oldValue;
}
diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp
index 04cc3d3751..f3b9df49a9 100644
--- a/engines/cruise/menu.cpp
+++ b/engines/cruise/menu.cpp
@@ -205,7 +205,7 @@ int playerMenu(int menuX, int menuY) {
int retourMenu;
//int restartGame = 0;
- if (entrerMenuJoueur && displayOn) {
+ if (playerMenuEnabled && displayOn) {
if (remdo) {
_vm->music().removeSong();
freeStuff2();
@@ -255,7 +255,7 @@ int playerMenu(int menuX, int menuY) {
case 3: // select save drive
break;
case 4: // save
- saveSavegameData(0);
+ saveSavegameData(0, "Default Save");
break;
case 5: // load
loadSavegameData(0);
diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp
index 8d9b321955..da25e353b8 100644
--- a/engines/cruise/saveload.cpp
+++ b/engines/cruise/saveload.cpp
@@ -30,6 +30,9 @@
#include "common/savefile.h"
#include "common/system.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+
namespace Cruise {
struct overlayRestoreTemporary {
@@ -41,6 +44,53 @@ struct overlayRestoreTemporary {
overlayRestoreTemporary ovlRestoreData[90];
+bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) {
+ char saveIdentBuffer[6];
+ header.thumbnail = NULL;
+
+ // Validate the header Id
+ in->read(saveIdentBuffer, 6);
+ if (strcmp(saveIdentBuffer, "SVMCR"))
+ return false;
+
+ header.version = in->readByte();
+ if (header.version != CRUISE_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 = new Graphics::Surface();
+ if (!Graphics::loadThumbnail(*in, *header.thumbnail)) {
+ delete header.thumbnail;
+ header.thumbnail = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+void writeSavegameHeader(Common::OutSaveFile *out, CruiseSavegameHeader &header) {
+ // Write out a savegame header
+ char saveIdentBuffer[6];
+ strcpy(saveIdentBuffer, "SVMCR");
+ out->write(saveIdentBuffer, 6);
+
+ out->writeByte(CRUISE_SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->write(header.saveName.c_str(), header.saveName.size() + 1);
+
+ // Create a thumbnail and save it
+ Graphics::Surface *thumb = new Graphics::Surface();
+ ::createThumbnail(thumb, globalScreen, 320, 200, workpal);
+ Graphics::saveThumbnail(*out, *thumb);
+ delete thumb;
+}
+
static void syncPalette(Common::Serializer &s, uint8 *p) {
// This is different from the original, where palette entries are 2 bytes each
s.syncBytes(p, NBCOLORS * 3);
@@ -92,7 +142,7 @@ static void syncBasicInfo(Common::Serializer &s) {
s.syncAsSint16LE(var48);
s.syncAsSint16LE(flagCt);
s.syncAsSint16LE(var41);
- s.syncAsSint16LE(entrerMenuJoueur);
+ s.syncAsSint16LE(playerMenuEnabled);
}
static void syncBackgroundTable(Common::Serializer &s) {
@@ -716,68 +766,61 @@ void initVars(void) {
menuDown = 0;
buttonDown = 0;
var41 = 0;
- entrerMenuJoueur = 0;
+ playerMenuEnabled = 0;
PCFadeFlag = 0;
}
-int saveSavegameData(int saveGameIdx) {
- char buffer[256];
-
- sprintf(buffer, "CR.%d", saveGameIdx);
-
+Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName) {
+ const char *filename = _vm->getSavegameFile(saveGameIdx);
Common::SaveFileManager *saveMan = g_system->getSavefileManager();
- Common::OutSaveFile *f = saveMan->openForSaving(buffer);
+ Common::OutSaveFile *f = saveMan->openForSaving(filename);
if (f == NULL)
- return 0;
+ return Common::kNoGameDataFoundError;
- // Write out a savegame header
- char saveIdentBuffer[6];
- strcpy(saveIdentBuffer, "SAVPC");
- f->write(saveIdentBuffer, 6);
+ // Save the savegame header
+ CruiseSavegameHeader header;
+ header.saveName = saveName;
+ writeSavegameHeader(f, header);
- if (!f->ioFailed()) {
+ if (f->ioFailed()) {
+ delete f;
+ saveMan->removeSavefile(filename);
+ return Common::kWritingFailed;
+ } else {
+ // Create the remainder of the savegame
Common::Serializer s(NULL, f);
-
DoSync(s);
f->finalize();
delete f;
- return 1;
-
- } else {
- delete f;
- saveMan->removeSavefile(buffer);
- return 0;
+ return Common::kNoError;
}
}
-int loadSavegameData(int saveGameIdx) {
- char buffer[256];
- char saveIdentBuffer[6];
+Common::Error loadSavegameData(int saveGameIdx) {
int lowMemorySave;
+ Common::String saveName;
cellStruct *currentcellHead;
- sprintf(buffer, "CR.%d", saveGameIdx);
-
Common::SaveFileManager *saveMan = g_system->getSavefileManager();
- Common::InSaveFile *f = saveMan->openForLoading(buffer);
+ Common::InSaveFile *f = saveMan->openForLoading(_vm->getSavegameFile(saveGameIdx));
if (f == NULL) {
printInfoBlackBox("Savegame not found...");
waitForPlayerInput();
- return -1;
+ return Common::kNoGameDataFoundError;
}
printInfoBlackBox("Loading in progress...");
- f->read(saveIdentBuffer, 6);
- if (strcmp(saveIdentBuffer, "SAVPC")) {
- delete f;
- return -1;
- }
-
initVars();
+ // Skip over the savegame header
+ CruiseSavegameHeader header;
+ readSavegameHeader(f, header);
+ if (header.thumbnail) delete header.thumbnail;
+
+ // Synchronise the remaining data of the savegame
Common::Serializer s(f, NULL);
DoSync(s);
@@ -903,7 +946,7 @@ int loadSavegameData(int saveGameIdx) {
mainDraw(1);
flipScreen();
- return (0);
+ return Common::kNoError;
}
} // End of namespace Cruise
diff --git a/engines/cruise/saveload.h b/engines/cruise/saveload.h
index 11c8269b3c..96433bdee9 100644
--- a/engines/cruise/saveload.h
+++ b/engines/cruise/saveload.h
@@ -27,11 +27,21 @@
#define CRUISE_SAVELOAD_H
#include "common/scummsys.h"
+#include "graphics/surface.h"
namespace Cruise {
-int saveSavegameData(int saveGameIdx);
-int loadSavegameData(int saveGameIdx);
+#define CRUISE_SAVEGAME_VERSION 1
+
+struct CruiseSavegameHeader {
+ uint8 version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+};
+
+Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName);
+Common::Error loadSavegameData(int saveGameIdx);
+bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header);
} // End of namespace Cruise
diff --git a/engines/cruise/vars.cpp b/engines/cruise/vars.cpp
index f3165f8cef..3ea591ed43 100644
--- a/engines/cruise/vars.cpp
+++ b/engines/cruise/vars.cpp
@@ -131,7 +131,7 @@ bool animationStart;
int16 autoOvl;
int16 var39;
-int16 entrerMenuJoueur;
+int16 playerMenuEnabled = 0;
int16 var41;
int16 var42;
int16 var45;
diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h
index a6d9e87613..cd0929e212 100644
--- a/engines/cruise/vars.h
+++ b/engines/cruise/vars.h
@@ -233,7 +233,7 @@ extern bool animationStart;
extern int16 autoOvl;
extern int16 var39;
-extern int16 entrerMenuJoueur;
+extern int16 playerMenuEnabled;
extern int16 var39;
extern int16 var41;
extern int16 var42;