ASYLUM: implement saving/loading via the GMM
This commit is contained in:
parent
1dcf364a00
commit
0d1e2da0b0
5 changed files with 176 additions and 97 deletions
|
@ -113,10 +113,6 @@ AsylumEngine::~AsylumEngine() {
|
|||
_gameDescription = NULL;
|
||||
}
|
||||
|
||||
bool AsylumEngine::hasFeature(EngineFeature f) const {
|
||||
return (f == kSupportsReturnToLauncher);
|
||||
}
|
||||
|
||||
Common::Error AsylumEngine::run() {
|
||||
// Initialize the graphics
|
||||
initGraphics(640, 480);
|
||||
|
@ -641,6 +637,34 @@ void AsylumEngine::checkAchievements() {
|
|||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Save/Load
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool AsylumEngine::canLoadGameStateCurrently() {
|
||||
return _handler == _scene || _handler == _menu;
|
||||
}
|
||||
|
||||
bool AsylumEngine::canSaveGameStateCurrently() {
|
||||
return _handler == _scene;
|
||||
}
|
||||
|
||||
Common::Error AsylumEngine::loadGameState(int slot) {
|
||||
savegame()->loadList();
|
||||
savegame()->setIndex(slot);
|
||||
startGame(savegame()->getScenePack(), AsylumEngine::kStartGameLoad);
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error AsylumEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
|
||||
savegame()->loadList();
|
||||
savegame()->setIndex(slot);
|
||||
savegame()->setName(slot, desc);
|
||||
savegame()->save(true);
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Misc
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -194,6 +194,12 @@ public:
|
|||
bool isAltDemo() { return Common::File::exists("asylum.dat"); }
|
||||
Common::Language getLanguage() { return _gameDescription->language; }
|
||||
|
||||
// Save/Load
|
||||
bool canLoadGameStateCurrently();
|
||||
Common::Error loadGameState(int slot);
|
||||
bool canSaveGameStateCurrently();
|
||||
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false);
|
||||
|
||||
private:
|
||||
const ADGameDescription *_gameDescription;
|
||||
|
||||
|
|
|
@ -20,15 +20,19 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "backends/keymapper/action.h"
|
||||
#include "backends/keymapper/keymap.h"
|
||||
|
||||
#include "common/achievements.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/translation.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
#include "asylum/system/savegame.h"
|
||||
|
||||
#include "asylum/asylum.h"
|
||||
#include "asylum/shared.h"
|
||||
|
||||
|
@ -42,14 +46,50 @@ public:
|
|||
return "Sanitarium (c) ASC Games";
|
||||
}
|
||||
|
||||
bool hasFeature(MetaEngineFeature f) const override;
|
||||
int getMaximumSaveSlot() const override { return 25; }
|
||||
SaveStateList listSaves(const char *target) const override;
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override;
|
||||
Common::KeymapArray initKeymaps(const char *target) const override;
|
||||
const Common::AchievementDescriptionList *getAchievementDescriptionList() const override;
|
||||
};
|
||||
|
||||
bool AsylumMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||
return false;
|
||||
bool Asylum::AsylumEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsReturnToLauncher) ||
|
||||
(f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
SaveStateList AsylumMetaEngine::listSaves(const char *target) const {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
Common::StringArray filenames;
|
||||
Common::String pattern(getSavegameFilePattern(target));
|
||||
|
||||
filenames = saveFileMan->listSavefiles(pattern);
|
||||
|
||||
SaveStateList saveList;
|
||||
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
|
||||
// Obtain the last 3 digits of the filename, since they correspond to the save slot
|
||||
int slotNum = atoi(file->c_str() + file->size() - 3);
|
||||
|
||||
if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
|
||||
SaveStateDescriptor desc = querySaveMetaInfos(target, slotNum);
|
||||
if (desc.getSaveSlot() == -1) {
|
||||
Common::InSaveFile *in(saveFileMan->openForLoading(*file));
|
||||
if (in && in->size()) {
|
||||
(void)(uint32)Asylum::Savegame::read(in, "Chapter");
|
||||
desc.setSaveSlot(slotNum);
|
||||
desc.setDescription(Asylum::Savegame::read(in, 45, "Game Name"));
|
||||
}
|
||||
}
|
||||
|
||||
saveList.push_back(desc);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort saves based on slot number.
|
||||
Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
|
||||
return saveList;
|
||||
}
|
||||
|
||||
Common::Error AsylumMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
|
|
|
@ -45,8 +45,6 @@ namespace Asylum {
|
|||
#define SAVEGAME_VERSION_SIZE 11
|
||||
#define SAVEGAME_NAME_SIZE 45
|
||||
|
||||
#define SAVEGAME_NAME "asylum"
|
||||
|
||||
#define SAVEGAME_QUICKSLOT 24
|
||||
|
||||
#define SAVEGAME_MOVIES "asylum.movies"
|
||||
|
@ -134,11 +132,11 @@ bool Savegame::quickLoad() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Savegame::save() {
|
||||
void Savegame::save(bool appendExtended) {
|
||||
// Original creates a folder to hold saved games and checks for disk space, we can skip that
|
||||
getCursor()->hide();
|
||||
|
||||
if (saveData(getFilename(_index), _names[_index], getWorld()->chapter)) {
|
||||
if (saveData(getFilename(_index), _names[_index], getWorld()->chapter, appendExtended)) {
|
||||
_savegames[_index] = true;
|
||||
|
||||
getMenu()->setDword455C78(true);
|
||||
|
@ -216,7 +214,7 @@ Common::String Savegame::getFilename(uint32 index) const {
|
|||
if (index > SAVEGAME_COUNT - 1)
|
||||
error("[Savegame::getFilename] Invalid savegame index (was:%d, valid: [0-24])", index);
|
||||
|
||||
return Common::String::format("%s%02d.sav", SAVEGAME_NAME, index);
|
||||
return _vm->getSaveStateName(index);
|
||||
}
|
||||
|
||||
bool Savegame::isSavegamePresent(Common::String filename) const {
|
||||
|
@ -296,7 +294,7 @@ bool Savegame::loadData(Common::String filename) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Savegame::saveData(Common::String filename, Common::String name, ChapterIndex chapter) {
|
||||
bool Savegame::saveData(Common::String filename, Common::String name, ChapterIndex chapter, bool appendExtended) {
|
||||
Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(filename);
|
||||
if (!file)
|
||||
return false;
|
||||
|
@ -315,12 +313,17 @@ bool Savegame::saveData(Common::String filename, Common::String name, ChapterInd
|
|||
|
||||
write(file, _vm->getTick(), "Time");
|
||||
|
||||
if (appendExtended)
|
||||
_vm->getMetaEngine()->appendExtendedSaveToStream(file, _vm->getTotalPlayTime() / 1000, name, false);
|
||||
else
|
||||
file->writeUint32LE(0);
|
||||
|
||||
delete file;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Savegame::seek(Common::InSaveFile *file, uint32 offset, Common::String description) const {
|
||||
void Savegame::seek(Common::InSaveFile *file, uint32 offset, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Seeking to offset: %s", description.c_str());
|
||||
|
||||
if (offset == 0)
|
||||
|
@ -337,7 +340,7 @@ void Savegame::seek(Common::InSaveFile *file, uint32 offset, Common::String desc
|
|||
}
|
||||
}
|
||||
|
||||
uint32 Savegame::read(Common::InSaveFile *file, Common::String description) const {
|
||||
uint32 Savegame::read(Common::InSaveFile *file, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Reading %s", description.c_str());
|
||||
|
||||
uint32 size = file->readUint32LE();
|
||||
|
@ -349,7 +352,7 @@ uint32 Savegame::read(Common::InSaveFile *file, Common::String description) cons
|
|||
return file->readUint32LE();
|
||||
}
|
||||
|
||||
Common::String Savegame::read(Common::InSaveFile *file, uint32 strLength, Common::String description) const {
|
||||
Common::String Savegame::read(Common::InSaveFile *file, uint32 strLength, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Reading %s (of length %d)", description.c_str(), strLength);
|
||||
|
||||
/*uint32 size =*/ file->readUint32LE();
|
||||
|
@ -369,7 +372,7 @@ Common::String Savegame::read(Common::InSaveFile *file, uint32 strLength, Common
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Savegame::read(Common::InSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) const {
|
||||
void Savegame::read(Common::InSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Reading %s (%d block(s) of size %d)", description.c_str(), size, count);
|
||||
|
||||
uint32 fileSize = file->readUint32LE();
|
||||
|
@ -387,7 +390,7 @@ void Savegame::read(Common::InSaveFile *file, Common::Serializable *data, uint32
|
|||
data->saveLoadWithSerializer(ser);
|
||||
}
|
||||
|
||||
void Savegame::write(Common::OutSaveFile *file, uint32 val, Common::String description) const {
|
||||
void Savegame::write(Common::OutSaveFile *file, uint32 val, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Writing %s: %d", description.c_str(), val);
|
||||
|
||||
file->writeUint32LE(4);
|
||||
|
@ -396,7 +399,7 @@ void Savegame::write(Common::OutSaveFile *file, uint32 val, Common::String descr
|
|||
file->writeUint32LE(val);
|
||||
}
|
||||
|
||||
void Savegame::write(Common::OutSaveFile *file, Common::String val, uint32 strLength, Common::String description) const {
|
||||
void Savegame::write(Common::OutSaveFile *file, Common::String val, uint32 strLength, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Writing %s (of length %d): %s", description.c_str(), strLength, val.c_str());
|
||||
|
||||
if (val.size() > strLength)
|
||||
|
@ -414,7 +417,7 @@ void Savegame::write(Common::OutSaveFile *file, Common::String val, uint32 strLe
|
|||
}
|
||||
}
|
||||
|
||||
void Savegame::write(Common::OutSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) const {
|
||||
void Savegame::write(Common::OutSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) {
|
||||
debugC(kDebugLevelSavegame, "[Savegame] Writing %s (%d block(s) of size %d)", description.c_str(), size, count);
|
||||
|
||||
file->writeUint32LE(size);
|
||||
|
|
|
@ -69,9 +69,11 @@ public:
|
|||
/**
|
||||
* Saves a game
|
||||
*
|
||||
* @param appendExtended Append the extended savegame header to the stream.
|
||||
*
|
||||
* @return true if it succeeds, false if it fails.
|
||||
*/
|
||||
void save();
|
||||
void save(bool appendExtended = false);
|
||||
|
||||
/**
|
||||
* Quick saves a game
|
||||
|
@ -85,6 +87,80 @@ public:
|
|||
*/
|
||||
void remove();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Static methods
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Seeks to a specific place in the file
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param offset Offset index of the info into the file
|
||||
* @param description The description.
|
||||
*/
|
||||
static void seek(Common::InSaveFile *file, uint32 offset, Common::String description);
|
||||
|
||||
/**
|
||||
* Reads data from a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param description The description.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
static uint32 read(Common::InSaveFile *file, Common::String description);
|
||||
|
||||
/**
|
||||
* Reads data from a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param strLength Length of the string.
|
||||
* @param description The description.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
static Common::String read(Common::InSaveFile *file, uint32 strLength, Common::String description);
|
||||
|
||||
/**
|
||||
* Reads data from a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param [in,out] data If non-null, the data.
|
||||
* @param size The size.
|
||||
* @param count Number of.
|
||||
* @param description The description.
|
||||
*/
|
||||
static void read(Common::InSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description);
|
||||
|
||||
/**
|
||||
* Writes data to a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param val The value
|
||||
* @param description The description.
|
||||
*/
|
||||
static void write(Common::OutSaveFile *file, uint32 val, Common::String description);
|
||||
|
||||
/**
|
||||
* Writes data to a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param val The string
|
||||
* @param strLength The size of the string.
|
||||
* @param description The description.
|
||||
*/
|
||||
static void write(Common::OutSaveFile *file, Common::String val, uint32 strLength, Common::String description);
|
||||
|
||||
/**
|
||||
* Writes data to a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param [in,out] data If non-null, the data.
|
||||
* @param size The size.
|
||||
* @param count Number of.
|
||||
* @param description The description.
|
||||
*/
|
||||
static void write(Common::OutSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Movies
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -179,81 +255,11 @@ private:
|
|||
* @param filename Filename of the file.
|
||||
* @param name The name.
|
||||
* @param chapter The chapter.
|
||||
* @param appendExtended Append the extended savegame header to the stream.
|
||||
*
|
||||
* @return true if it succeeds, false if it fails.
|
||||
*/
|
||||
bool saveData(Common::String filename, Common::String name, ChapterIndex chapter);
|
||||
|
||||
/**
|
||||
* Seeks to a specific place in the file
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param offset Offset index of the info into the file
|
||||
* @param description The description.
|
||||
*/
|
||||
void seek(Common::InSaveFile *file, uint32 offset, Common::String description) const;
|
||||
|
||||
/**
|
||||
* Reads data from a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param description The description.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
uint32 read(Common::InSaveFile *file, Common::String description) const;
|
||||
|
||||
/**
|
||||
* Reads data from a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param strLength Length of the string.
|
||||
* @param description The description.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
Common::String read(Common::InSaveFile *file, uint32 strLength, Common::String description) const;
|
||||
|
||||
/**
|
||||
* Reads data from a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param [in,out] data If non-null, the data.
|
||||
* @param size The size.
|
||||
* @param count Number of.
|
||||
* @param description The description.
|
||||
*/
|
||||
void read(Common::InSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) const;
|
||||
|
||||
/**
|
||||
* Writes data to a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param val The value
|
||||
* @param description The description.
|
||||
*/
|
||||
void write(Common::OutSaveFile *file, uint32 val, Common::String description) const;
|
||||
|
||||
/**
|
||||
* Writes data to a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param val The string
|
||||
* @param strLength The size of the string.
|
||||
* @param description The description.
|
||||
*/
|
||||
void write(Common::OutSaveFile *file, Common::String val, uint32 strLength, Common::String description) const;
|
||||
|
||||
/**
|
||||
* Writes data to a file.
|
||||
*
|
||||
* @param [in,out] file If non-null, the file.
|
||||
* @param [in,out] data If non-null, the data.
|
||||
* @param size The size.
|
||||
* @param count Number of.
|
||||
* @param description The description.
|
||||
*/
|
||||
void write(Common::OutSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) const;
|
||||
bool saveData(Common::String filename, Common::String name, ChapterIndex chapter, bool appendExtended = false);
|
||||
};
|
||||
|
||||
} // End of namespace Asylum
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue