diff options
author | Walter van Niftrik | 2016-02-29 16:50:24 +0100 |
---|---|---|
committer | Walter van Niftrik | 2016-03-09 10:03:13 +0100 |
commit | ba54955bffec15ed95aa1ca1ec955aecaa315478 (patch) | |
tree | bef5045606854df11ac257158d1feea8abc14484 | |
parent | 9928e51bd73985f48c8378308a278fff433eaae1 (diff) | |
download | scummvm-rg350-ba54955bffec15ed95aa1ca1ec955aecaa315478.tar.gz scummvm-rg350-ba54955bffec15ed95aa1ca1ec955aecaa315478.tar.bz2 scummvm-rg350-ba54955bffec15ed95aa1ca1ec955aecaa315478.zip |
ADL: Add loading from launcher
-rw-r--r-- | engines/adl/adl.cpp | 30 | ||||
-rw-r--r-- | engines/adl/adl.h | 5 | ||||
-rw-r--r-- | engines/adl/detection.cpp | 57 | ||||
-rw-r--r-- | engines/adl/display.cpp | 4 | ||||
-rw-r--r-- | engines/adl/display.h | 1 | ||||
-rw-r--r-- | engines/adl/hires1.cpp | 60 | ||||
-rw-r--r-- | engines/adl/hires1.h | 1 |
7 files changed, 128 insertions, 30 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index be9067881f..ab05c40b69 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -70,6 +70,16 @@ Common::Error AdlEngine::run() { _display = new Display(); _parser = new Parser(*this, *_display); + int saveSlot = ConfMan.getInt("save_slot"); + if (saveSlot >= 0) { + if (!loadState(saveSlot)) + error("Failed to load save game from slot %i", saveSlot); + _display->setCursorPos(Common::Point(0, 23)); + } else { + runIntro(); + initState(); + } + runGame(); return Common::kNoError; @@ -455,7 +465,7 @@ void AdlEngine::showRoom() { printMessage(curRoom().description, false); } -bool AdlEngine::saveState(uint slot) { +bool AdlEngine::saveState(uint slot, const Common::String *description) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName); @@ -464,9 +474,21 @@ bool AdlEngine::saveState(uint slot) { return false; } - outFile->writeUint32BE(getTag()); + outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':')); outFile->writeByte(SAVEGAME_VERSION); + char name[SAVEGAME_NAME_LEN] = { }; + + if (description) + strncpy(name, description->c_str(), sizeof(name) - 1); + else { + Common::String defaultName("Save "); + defaultName += 'A' + slot; + strncpy(name, defaultName.c_str(), sizeof(name) - 1); + } + + outFile->write(name, sizeof(name)); + outFile->writeByte(_state.room); outFile->writeByte(_state.moves); outFile->writeByte(_state.isDark); @@ -511,7 +533,7 @@ bool AdlEngine::loadState(uint slot) { return false; } - if (inFile->readUint32BE() != getTag()) { + if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { warning("No header found in '%s'", fileName.c_str()); delete inFile; return false; @@ -526,6 +548,8 @@ bool AdlEngine::loadState(uint slot) { initState(); + inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR); + _state.room = inFile->readByte(); _state.moves = inFile->readByte(); _state.isDark = inFile->readByte(); diff --git a/engines/adl/adl.h b/engines/adl/adl.h index b7fd3dc410..9955b0d79a 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -38,6 +38,7 @@ class SeekableReadStream; namespace Adl { #define SAVEGAME_VERSION 0 +#define SAVEGAME_NAME_LEN 32 class Display; class Parser; @@ -176,11 +177,11 @@ public: virtual Common::String getEngineString(int str); protected: + virtual void runIntro() { } virtual void runGame() = 0; virtual void initState() = 0; virtual void restartGame() = 0; virtual uint getEngineMessage(EngineMessage msg) = 0; - virtual uint32 getTag() = 0; Common::String readString(Common::ReadStream &stream, byte until = 0); void printStrings(Common::SeekableReadStream &stream, int count = 1); virtual void printMessage(uint idx, bool wait = true); @@ -218,7 +219,7 @@ protected: private: void printEngineMessage(EngineMessage); - bool saveState(uint slot); + bool saveState(uint slot, const Common::String *description = nullptr); bool loadState(uint slot); Common::String getTargetName() { return _targetName; } }; diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp index 9fadb9d3d7..5fe469d20f 100644 --- a/engines/adl/detection.cpp +++ b/engines/adl/detection.cpp @@ -20,6 +20,9 @@ * */ +#include "common/system.h" +#include "common/savefile.h" + #include "engines/advancedDetector.h" #include "adl/adl.h" @@ -69,9 +72,63 @@ public: return "Copyright (C) Sierra On-Line"; } + bool hasFeature(MetaEngineFeature f) const; + int getMaximumSaveSlot() const { return 15; } + SaveStateList listSaves(const char *target) const; + bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const; }; +bool AdlMetaEngine::hasFeature(MetaEngineFeature f) const { + switch(f) { + case kSupportsListSaves: + case kSupportsLoadingDuringStartup: + return true; + default: + return false; + } +} + +SaveStateList AdlMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##"); + + SaveStateList saveList; + for (uint i = 0; i < files.size(); ++i) { + const Common::String &fileName = files[i]; + Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName); + if (!inFile) { + warning("Cannot open save file %s", fileName.c_str()); + continue; + } + + if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { + warning("No header found in '%s'", fileName.c_str()); + delete inFile; + continue; + } + + byte saveVersion = inFile->readByte(); + if (saveVersion != SAVEGAME_VERSION) { + warning("Save game version %i not supported in '%s'", saveVersion, fileName.c_str()); + delete inFile; + continue; + } + + char name[SAVEGAME_NAME_LEN] = { }; + inFile->read(name, sizeof(name) - 1); + delete inFile; + + int slotNum = atoi(fileName.c_str() + fileName.size() - 2); + SaveStateDescriptor sd(slotNum, name); + saveList.push_back(sd); + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; +} + bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const { if (gd) *engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd); diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp index 05e7c2e67c..ffb98c4a1b 100644 --- a/engines/adl/display.cpp +++ b/engines/adl/display.cpp @@ -585,4 +585,8 @@ void Display::home() { _cursorPos = 0; } +void Display::setCursorPos(Common::Point pos) { + _cursorPos = pos.y * 40 + pos.x; +} + } // End of namespace Adl diff --git a/engines/adl/display.h b/engines/adl/display.h index 229446f447..91d8b0ec97 100644 --- a/engines/adl/display.h +++ b/engines/adl/display.h @@ -64,6 +64,7 @@ public: void drawLine(Common::Point p1, Common::Point p2, byte color); void clear(byte color); void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f); + void setCursorPos(Common::Point pos); private: enum { diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp index 45a011ad63..ba6f19a8e4 100644 --- a/engines/adl/hires1.cpp +++ b/engines/adl/hires1.cpp @@ -136,6 +136,8 @@ void HiRes1Engine::runIntro() { file.seek(IDI_HR1_OFS_GAME_OR_HELP); str = readString(file); + bool instructions = false; + while (1) { _display->printString(str); Common::String s = _display->inputString(); @@ -146,28 +148,47 @@ void HiRes1Engine::runIntro() { if (s.empty()) continue; - if ((byte)s[0] == ('I' | 0x80)) + if (s[0] == APPLECHAR('I')) { + instructions = true; break; - else if ((byte)s[0] == ('G' | 0x80)) - return; + } else if (s[0] == APPLECHAR('G')) { + break; + } }; - _display->setMode(Display::kModeText); - file.seek(IDI_HR1_OFS_INTRO_TEXT); + if (instructions) { + _display->setMode(Display::kModeText); + file.seek(IDI_HR1_OFS_INTRO_TEXT); - const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 }; + const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 }; - uint page = 0; - while (pages[page] != 0) { - _display->home(); - printStrings(file, pages[page++]); - _display->inputString(); + uint page = 0; + while (pages[page] != 0) { + _display->home(); + printStrings(file, pages[page++]); + _display->inputString(); - if (g_engine->shouldQuit()) - return; + if (g_engine->shouldQuit()) + return; - file.seek(9, SEEK_CUR); + file.seek(9, SEEK_CUR); + } } + + _display->printASCIIString("\r"); + + file.close(); + + _display->setMode(Display::kModeMixed); + + if (!file.open("ADVENTURE")) + error("Failed to open file"); + + // Title screen shown during loading + file.seek(0x1800); + _display->loadFrameBuffer(file); + _display->decodeFrameBuffer(); + _display->delay(2000); } void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) { @@ -278,8 +299,7 @@ void HiRes1Engine::restartGame() { } void HiRes1Engine::runGame() { - runIntro(); - _display->printASCIIString("\r"); + _display->setMode(Display::kModeMixed); Common::File f; @@ -291,8 +311,6 @@ void HiRes1Engine::runGame() { f.close(); - initState(); - if (!f.open("ADVENTURE")) error("Failed to open file"); @@ -345,12 +363,6 @@ void HiRes1Engine::runGame() { _lineArt.push_back(lineArt); } - // Title screen shown during loading - f.seek(0x1800); - _display->loadFrameBuffer(f); - _display->decodeFrameBuffer(); - _display->delay(2000); - f.seek(0x3800); _parser->loadVerbs(f); diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h index 247625cba7..897327cdbf 100644 --- a/engines/adl/hires1.h +++ b/engines/adl/hires1.h @@ -52,7 +52,6 @@ private: void restartGame(); void printMessage(uint idx, bool wait = true); uint getEngineMessage(EngineMessage msg); - uint32 getTag() { return MKTAG('H', 'R', 'A', '1'); } void initState(); void runIntro(); |