aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2016-02-29 16:50:24 +0100
committerWalter van Niftrik2016-03-09 10:03:13 +0100
commitba54955bffec15ed95aa1ca1ec955aecaa315478 (patch)
treebef5045606854df11ac257158d1feea8abc14484
parent9928e51bd73985f48c8378308a278fff433eaae1 (diff)
downloadscummvm-rg350-ba54955bffec15ed95aa1ca1ec955aecaa315478.tar.gz
scummvm-rg350-ba54955bffec15ed95aa1ca1ec955aecaa315478.tar.bz2
scummvm-rg350-ba54955bffec15ed95aa1ca1ec955aecaa315478.zip
ADL: Add loading from launcher
-rw-r--r--engines/adl/adl.cpp30
-rw-r--r--engines/adl/adl.h5
-rw-r--r--engines/adl/detection.cpp57
-rw-r--r--engines/adl/display.cpp4
-rw-r--r--engines/adl/display.h1
-rw-r--r--engines/adl/hires1.cpp60
-rw-r--r--engines/adl/hires1.h1
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();