PINK: add saving/loading of game.

It's bugged, but playable
This commit is contained in:
whiterandrek 2018-05-25 20:50:02 +03:00 committed by Eugene Sandulenko
parent d6b1b9396e
commit 4f13df4828
4 changed files with 112 additions and 12 deletions

View File

@ -46,14 +46,50 @@ public:
return "Pink Panther Engine (C) Wanderlust Interactive";
}
//virtual bool hasFeature(MetaEngineFeature f) const;
//virtual int getMaximumSaveSlot() const { return 0; }
//virtual SaveStateList listSaves(const char *target) const;
//virtual void removeSaveState(const char *target, int slot) const;
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 PinkMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSupportsListSaves) ||
(f == kSupportsDeleteSave) ||
(f == kSupportsLoadingDuringStartup) ||
(f == kSimpleSavesNames);
}
SaveStateList PinkMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::String pattern = Common::String::format("%s.s##", target);
Common::StringArray filenames = saveFileMan->listSavefiles(pattern);
SaveStateList saveList;
for (Common::StringArray::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 <= getMaximumSaveSlot()) {
Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file));
if (in) {
SaveStateDescriptor desc;
desc.setSaveSlot(slotNum);
saveList.push_back(desc);
}
}
}
// Sort saves based on slot number.
Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
return saveList;
}
void PinkMetaEngine::removeSaveState(const char *target, int slot) const {
g_system->getSavefileManager()->removeSavefile(Pink::generateSaveName(slot, target));
}
bool PinkMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc)
*engine = new Pink::PinkEngine(syst, desc);

View File

@ -39,7 +39,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO1(GUIO_NONE)
},
{
@ -52,7 +52,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO1(GUIO_NONE)
},
AD_TABLE_END_MARKER

View File

@ -88,7 +88,10 @@ Common::Error PinkEngine::init() {
_orb.loadGame(this);
initModule(_modules[0]->getName(), kLoadingNewGame, "");
if (ConfMan.hasKey("save_slot")) {
loadGameState(ConfMan.getInt("save_slot"));
}
else initModule(_modules[0]->getName(), "", nullptr);
return Common::kNoError;
}
@ -140,7 +143,7 @@ void PinkEngine::load(Archive &archive) {
_modules.deserialize(archive);
}
void PinkEngine::initModule(const Common::String &moduleName, bool isLoadingFromSave, const Common::String &pageName) {
void PinkEngine::initModule(const Common::String &moduleName, const Common::String &pageName, Archive *saveFile) {
if (_module) {
for (uint i = 0; i < _modules.size(); ++i) {
if (_module == _modules[i]) {
@ -158,7 +161,9 @@ void PinkEngine::initModule(const Common::String &moduleName, bool isLoadingFrom
if (_modules[i]->getName() == moduleName) {
loadModule(i);
_module = static_cast<Module*>(_modules[i]);
_module->init(isLoadingFromSave, pageName);
if (saveFile)
_module->loadState(*saveFile);
_module->init( saveFile ? kLoadingSave : kLoadingNewGame, pageName);
break;
}
}
@ -167,7 +172,7 @@ void PinkEngine::initModule(const Common::String &moduleName, bool isLoadingFrom
void PinkEngine::changeScene(GamePage *page) {
setCursor(kLoadingCursor);
if (!_nextModule.empty() && _nextModule.compareTo(_module->getName())) {
initModule(_nextModule, kLoadingNewGame, _nextPage);
initModule(_nextModule, _nextPage, nullptr);
} else {
assert(!_nextPage.empty());
_module->changePage(_nextPage);
@ -241,4 +246,53 @@ void PinkEngine::setCursor(uint cursorIndex) {
cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
}
Common::Error PinkEngine::loadGameState(int slot) {
Common::SeekableReadStream *stream = _saveFileMan->openForLoading(generateSaveName(slot, _desc.gameId));
if (!stream)
return Common::kNoGameDataFoundError;
Archive archive(stream);
_variables.deserialize(archive);
_nextModule = archive.readString();
_nextPage = archive.readString();
initModule(archive.readString(), "", &archive);
return Common::kNoError;
}
bool PinkEngine::canLoadGameStateCurrently() {
return true;
}
Common::Error PinkEngine::saveGameState(int slot, const Common::String &desc) {
Common::WriteStream *stream = _saveFileMan->openForSaving(generateSaveName(slot, _desc.gameId));
if (!stream)
return Common::kUnknownError;
Archive archive(stream);
_variables.serialize(archive);
archive.writeString(_nextModule);
archive.writeString(_nextPage);
archive.writeString(_module->getName());
_module->saveState(archive);
delete stream;
return Common::kNoError;
}
bool PinkEngine::canSaveGameStateCurrently() {
return true;
}
bool PinkEngine::hasFeature(Engine::EngineFeature f) const {
return f == kSupportsLoadingDuringRuntime ||
f == kSupportsSavingDuringRuntime;
}
Common::String generateSaveName(int slot, const char *gameId) {
return Common::String::format("%s.s%02d", gameId, slot);
}
}

View File

@ -87,8 +87,16 @@ public:
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
virtual Common::Error loadGameState(int slot);
virtual bool canLoadGameStateCurrently();
virtual Common::Error saveGameState(int slot, const Common::String &desc);
virtual bool canSaveGameStateCurrently();
void load(Archive &archive);
void initModule(const Common::String &moduleName, bool isLoadingFromSave, const Common::String &pageName);
void initModule(const Common::String &moduleName, const Common::String &pageName, Archive *saveFile);
void changeScene(GamePage *page);
OrbFile *getOrb() { return &_orb; }
@ -125,11 +133,13 @@ private:
Module *_module;
Array<NamedObject *> _modules;
Common::StringMap _variables;
StringMap _variables;
const ADGameDescription _desc;
};
Common::String generateSaveName(int slot, const char *gameId);
} // End of namespace Pink
#endif