Skip to content

Commit

Permalink
ADL: Add loading from launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
waltervn committed Mar 9, 2016
1 parent 9928e51 commit ba54955
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 30 deletions.
30 changes: 27 additions & 3 deletions engines/adl/adl.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand Down
5 changes: 3 additions & 2 deletions engines/adl/adl.h
Expand Up @@ -38,6 +38,7 @@ class SeekableReadStream;
namespace Adl {

#define SAVEGAME_VERSION 0
#define SAVEGAME_NAME_LEN 32

class Display;
class Parser;
Expand Down Expand Up @@ -176,11 +177,11 @@ class AdlEngine : public Engine {
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);
Expand Down Expand Up @@ -218,7 +219,7 @@ class AdlEngine : public Engine {

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; }
};
Expand Down
57 changes: 57 additions & 0 deletions engines/adl/detection.cpp
Expand Up @@ -20,6 +20,9 @@
*
*/

#include "common/system.h"
#include "common/savefile.h"

#include "engines/advancedDetector.h"

#include "adl/adl.h"
Expand Down Expand Up @@ -69,9 +72,63 @@ class AdlMetaEngine : public AdvancedMetaEngine {
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);
Expand Down
4 changes: 4 additions & 0 deletions engines/adl/display.cpp
Expand Up @@ -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
1 change: 1 addition & 0 deletions engines/adl/display.h
Expand Up @@ -64,6 +64,7 @@ class Display {
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 {
Expand Down
60 changes: 36 additions & 24 deletions engines/adl/hires1.cpp
Expand Up @@ -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();
Expand All @@ -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) {
Expand Down Expand Up @@ -278,8 +299,7 @@ void HiRes1Engine::restartGame() {
}

void HiRes1Engine::runGame() {
runIntro();
_display->printASCIIString("\r");
_display->setMode(Display::kModeMixed);

Common::File f;

Expand All @@ -291,8 +311,6 @@ void HiRes1Engine::runGame() {

f.close();

initState();

if (!f.open("ADVENTURE"))
error("Failed to open file");

Expand Down Expand Up @@ -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);

Expand Down
1 change: 0 additions & 1 deletion engines/adl/hires1.h
Expand Up @@ -52,7 +52,6 @@ class HiRes1Engine : public AdlEngine {
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();
Expand Down

0 comments on commit ba54955

Please sign in to comment.