mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-18 07:53:12 +00:00
Added support for the global menu save/loading, and changed the savegame format to store the savegame name and thumbnail
svn-id: r39979
This commit is contained in:
parent
0b2e06e4a4
commit
15252ad83c
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -451,8 +451,8 @@ int16 Op_KillMenu(void) {
|
||||
}
|
||||
|
||||
int16 Op_UserMenu(void) {
|
||||
int oldValue = entrerMenuJoueur;
|
||||
entrerMenuJoueur = popVar();
|
||||
int oldValue = playerMenuEnabled;
|
||||
playerMenuEnabled = popVar();
|
||||
|
||||
return oldValue;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -131,7 +131,7 @@ bool animationStart;
|
||||
|
||||
int16 autoOvl;
|
||||
int16 var39;
|
||||
int16 entrerMenuJoueur;
|
||||
int16 playerMenuEnabled = 0;
|
||||
int16 var41;
|
||||
int16 var42;
|
||||
int16 var45;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user