Skip to content

Commit

Permalink
ADL: Refactor string handling
Browse files Browse the repository at this point in the history
  • Loading branch information
waltervn committed Mar 9, 2016
1 parent ac79cb0 commit fd8a5f4
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 108 deletions.
29 changes: 13 additions & 16 deletions engines/adl/adl.cpp
Expand Up @@ -109,7 +109,7 @@ Common::Error AdlEngine::run() {
break;

if (!doOneCommand(_roomCommands, verb, noun))
printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
printMessage(_messageIds.dontUnderstand);
}

if (_isRestoring) {
Expand Down Expand Up @@ -156,8 +156,9 @@ Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) con
return str;
}

Common::String AdlEngine::getEngineString(int str) const {
return _strings[str];
Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint offset, byte until) const {
stream.seek(offset);
return readString(stream, until);
}

void AdlEngine::wordWrap(Common::String &str) const {
Expand All @@ -184,10 +185,6 @@ void AdlEngine::printMessage(uint idx, bool wait) const {
delay(14 * 166018 / 1000);
}

void AdlEngine::printEngineMessage(EngineMessage msg) const {
printMessage(getEngineMessage(msg));
}

void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
while (1) {
Command command;
Expand Down Expand Up @@ -232,7 +229,7 @@ void AdlEngine::takeItem(byte noun) {
continue;

if (item->state == IDI_ITEM_DOESNT_MOVE) {
printEngineMessage(IDI_MSG_ITEM_DOESNT_MOVE);
printMessage(_messageIds.itemDoesntMove);
return;
}

Expand All @@ -251,7 +248,7 @@ void AdlEngine::takeItem(byte noun) {
}
}

printEngineMessage(IDI_MSG_ITEM_NOT_HERE);
printMessage(_messageIds.itemNotHere);
}

void AdlEngine::dropItem(byte noun) {
Expand All @@ -266,7 +263,7 @@ void AdlEngine::dropItem(byte noun) {
return;
}

printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
printMessage(_messageIds.dontUnderstand);
}

#define ARG(N) (command.script[offset + (N)])
Expand Down Expand Up @@ -339,7 +336,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
_isRestoring = false;
break;
case IDO_ACT_RESTART: {
_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
_display->printString(_strings.playAgain);

// We allow restoring via GMM here
_canRestoreNow = true;
Expand All @@ -360,7 +357,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
// Fall-through
}
case IDO_ACT_QUIT:
printEngineMessage(IDI_MSG_THANKS_FOR_PLAYING);
printMessage(_messageIds.thanksForPlaying);
quitGame();
return;
case IDO_ACT_PLACE_ITEM:
Expand All @@ -386,7 +383,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
byte room = curRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];

if (room == 0) {
printEngineMessage(IDI_MSG_CANT_GO_THERE);
printMessage(_messageIds.cantGoThere);
return;
}

Expand Down Expand Up @@ -856,7 +853,7 @@ Common::String AdlEngine::getWord(const Common::String &line, uint &index) const

void AdlEngine::getInput(uint &verb, uint &noun) {
while (1) {
_display->printString(getEngineString(IDI_STR_ENTER_COMMAND));
_display->printString(_strings.enterCommand);
Common::String line = getLine();

if (shouldQuit() || _isRestoring)
Expand All @@ -866,7 +863,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
Common::String verbStr = getWord(line, index);

if (!_verbs.contains(verbStr)) {
Common::String err = getEngineString(IDI_STR_VERB_ERROR);
Common::String err = _strings.verbError;
for (uint i = 0; i < verbStr.size(); ++i)
err.setChar(verbStr[i], i + 19);
_display->printString(err);
Expand All @@ -878,7 +875,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
Common::String nounStr = getWord(line, index);

if (!_nouns.contains(nounStr)) {
Common::String err = getEngineString(IDI_STR_NOUN_ERROR);
Common::String err = _strings.nounError;
for (uint i = 0; i < verbStr.size(); ++i)
err.setChar(verbStr[i], i + 19);
for (uint i = 0; i < nounStr.size(); ++i)
Expand Down
42 changes: 18 additions & 24 deletions engines/adl/adl.h
Expand Up @@ -44,25 +44,6 @@ struct StringOffset {
uint offset;
};

// Messages used outside of scripts
enum EngineMessage {
IDI_MSG_CANT_GO_THERE,
IDI_MSG_DONT_UNDERSTAND,
IDI_MSG_ITEM_DOESNT_MOVE,
IDI_MSG_ITEM_NOT_HERE,
IDI_MSG_THANKS_FOR_PLAYING
};

// Strings embedded in the executable
enum EngineString {
IDI_STR_ENTER_COMMAND,
IDI_STR_VERB_ERROR,
IDI_STR_NOUN_ERROR,
IDI_STR_PLAY_AGAIN,

IDI_STR_TOTAL
};

// Conditional opcodes
#define IDO_CND_ITEM_IN_ROOM 0x03
#define IDO_CND_MOVES_GE 0x05
Expand Down Expand Up @@ -162,6 +143,7 @@ class AdlEngine : public Engine {
AdlEngine(OSystem *syst, const AdlGameDescription *gd);

Common::String readString(Common::ReadStream &stream, byte until = 0) const;
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;

virtual void printMessage(uint idx, bool wait = true) const;
void printASCIIString(const Common::String &str) const;
Expand All @@ -176,8 +158,6 @@ class AdlEngine : public Engine {
Display *_display;
Parser *_parser;

// Strings inside executable
Common::Array<Common::String> _strings;
// Message strings in data file
Common::Array<Common::String> _messages;
// Picture data
Expand All @@ -194,6 +174,23 @@ class AdlEngine : public Engine {
WordMap _verbs;
WordMap _nouns;

struct {
Common::String enterCommand;
Common::String dontHaveIt;
Common::String gettingDark;
Common::String verbError;
Common::String nounError;
Common::String playAgain;
} _strings;

struct {
uint cantGoThere;
uint dontUnderstand;
uint itemDoesntMove;
uint itemNotHere;
uint thanksForPlaying;
} _messageIds;

// Game state
State _state;

Expand All @@ -202,7 +199,6 @@ class AdlEngine : public Engine {
virtual void loadData() = 0;
virtual void initState() = 0;
virtual void restartGame() = 0;
virtual uint getEngineMessage(EngineMessage msg) const = 0;
virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;

// Engine
Expand All @@ -214,8 +210,6 @@ class AdlEngine : public Engine {
bool canSaveGameStateCurrently() const;

// Text output
Common::String getEngineString(int str) const;
void printEngineMessage(EngineMessage) const;
void wordWrap(Common::String &str) const;

// Text input
Expand Down
92 changes: 35 additions & 57 deletions engines/adl/hires1.cpp
Expand Up @@ -31,19 +31,6 @@

namespace Adl {

// Offsets for strings inside executable
static const StringOffset stringOffsets[] = {
{ IDI_STR_ENTER_COMMAND, 0x5bbc },
{ IDI_STR_VERB_ERROR, 0x5b4f },
{ IDI_STR_NOUN_ERROR, 0x5b8e },
{ IDI_STR_PLAY_AGAIN, 0x5f1e },
{ IDI_HR1_STR_CANT_GO_THERE, 0x6c0a },
{ IDI_HR1_STR_DONT_HAVE_IT, 0x6c31 },
{ IDI_HR1_STR_DONT_UNDERSTAND, 0x6c51 },
{ IDI_HR1_STR_GETTING_DARK, 0x6c7c },
{ IDI_HR1_STR_PRESS_RETURN, 0x5f68 }
};

void HiRes1Engine::runIntro() const {
Common::File file;

Expand All @@ -67,20 +54,16 @@ void HiRes1Engine::runIntro() const {

Common::String str;

basic.seek(IDI_HR1_OFS_PD_TEXT_0);
str = readString(basic, '"');
str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_0, '"');
printASCIIString(str + '\r');

basic.seek(IDI_HR1_OFS_PD_TEXT_1);
str = readString(basic, '"');
str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_1, '"');
printASCIIString(str + "\r\r");

basic.seek(IDI_HR1_OFS_PD_TEXT_2);
str = readString(basic, '"');
str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_2, '"');
printASCIIString(str + "\r\r");

basic.seek(IDI_HR1_OFS_PD_TEXT_3);
str = readString(basic, '"');
str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_3, '"');
printASCIIString(str + '\r');

inputKey();
Expand All @@ -89,8 +72,7 @@ void HiRes1Engine::runIntro() const {

_display->setMode(DISPLAY_MODE_MIXED);

file.seek(IDI_HR1_OFS_GAME_OR_HELP);
str = readString(file);
str = readStringAt(file, IDI_HR1_OFS_GAME_OR_HELP);

bool instructions = false;

Expand Down Expand Up @@ -256,7 +238,7 @@ void HiRes1Engine::initState() {

void HiRes1Engine::restartGame() {
initState();
_display->printString(_strings[IDI_HR1_STR_PRESS_RETURN]);
_display->printString(_gameStrings.pressReturn);
inputString(); // Missing in the original
printASCIIString("\r\r\r\r\r");
}
Expand All @@ -275,12 +257,27 @@ void HiRes1Engine::loadData() {
if (!f.open(IDS_HR1_EXE_1))
error("Failed to open file '" IDS_HR1_EXE_1 "'");

// Load strings from executable
_strings.resize(IDI_HR1_STR_TOTAL);
for (uint idx = 0; idx < IDI_HR1_STR_TOTAL; ++idx) {
f.seek(stringOffsets[idx].offset);
_strings[stringOffsets[idx].stringIdx] = readString(f);
}
// Some messages have overrides inside the executable
_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(f, IDI_HR1_OFS_STR_CANT_GO_THERE);
_messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(f, IDI_HR1_OFS_STR_DONT_HAVE_IT);
_messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(f, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
_messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(f, IDI_HR1_OFS_STR_GETTING_DARK);

// Load other strings from executable
_strings.enterCommand = readStringAt(f, IDI_HR1_OFS_STR_ENTER_COMMAND);
_strings.dontHaveIt = readStringAt(f, IDI_HR1_OFS_STR_DONT_HAVE_IT);
_strings.gettingDark = readStringAt(f, IDI_HR1_OFS_STR_GETTING_DARK);
_strings.verbError = readStringAt(f, IDI_HR1_OFS_STR_VERB_ERROR);
_strings.nounError = readStringAt(f, IDI_HR1_OFS_STR_NOUN_ERROR);
_strings.playAgain = readStringAt(f, IDI_HR1_OFS_STR_PLAY_AGAIN);
_gameStrings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);

// Set message IDs
_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
_messageIds.dontUnderstand = IDI_HR1_MSG_DONT_UNDERSTAND;
_messageIds.itemDoesntMove = IDI_HR1_MSG_ITEM_DOESNT_MOVE;
_messageIds.itemNotHere = IDI_HR1_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING;

// Load picture data from executable
f.seek(IDI_HR1_OFS_PICS);
Expand Down Expand Up @@ -335,43 +332,24 @@ void HiRes1Engine::loadData() {
}

void HiRes1Engine::printMessage(uint idx, bool wait) const {
// Hardcoded overrides that don't wait after printing
// Note: strings may differ slightly from the ones in MESSAGES
// Messages with hardcoded overrides don't delay after printing.
// It's unclear if this is a bug or not. In some cases the result
// is that these strings will scroll past the four-line text window
// before the user gets a chance to read them.
// NOTE: later games seem to wait for a key when the text window
// overflows and don't use delays. It might be better to use
// that system for this game as well.
switch (idx) {
case IDI_HR1_MSG_CANT_GO_THERE:
_display->printString(_strings[IDI_HR1_STR_CANT_GO_THERE]);
return;
case IDI_HR1_MSG_DONT_HAVE_IT:
_display->printString(_strings[IDI_HR1_STR_DONT_HAVE_IT]);
return;
case IDI_HR1_MSG_DONT_UNDERSTAND:
_display->printString(_strings[IDI_HR1_STR_DONT_UNDERSTAND]);
return;
case IDI_HR1_MSG_GETTING_DARK:
_display->printString(_strings[IDI_HR1_STR_GETTING_DARK]);
return;
wait = false;
}

AdlEngine::printMessage(idx, wait);
}

uint HiRes1Engine::getEngineMessage(EngineMessage msg) const {
switch (msg) {
case IDI_MSG_CANT_GO_THERE:
return IDI_HR1_MSG_CANT_GO_THERE;
case IDI_MSG_DONT_UNDERSTAND:
return IDI_HR1_MSG_DONT_UNDERSTAND;
case IDI_MSG_ITEM_DOESNT_MOVE:
return IDI_HR1_MSG_ITEM_DOESNT_MOVE;
case IDI_MSG_ITEM_NOT_HERE:
return IDI_HR1_MSG_ITEM_NOT_HERE;
case IDI_MSG_THANKS_FOR_PLAYING:
return IDI_HR1_MSG_THANKS_FOR_PLAYING;
default:
error("Cannot find engine message %i", msg);
}
}

void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
// This draws a four-connected line

Expand Down
24 changes: 13 additions & 11 deletions engines/adl/hires1.h
Expand Up @@ -52,16 +52,15 @@ namespace Adl {
#define IDI_HR1_MSG_DONT_HAVE_IT 127
#define IDI_HR1_MSG_GETTING_DARK 7

// Strings embedded in the executable
enum {
IDI_HR1_STR_CANT_GO_THERE = IDI_STR_TOTAL,
IDI_HR1_STR_DONT_HAVE_IT,
IDI_HR1_STR_DONT_UNDERSTAND,
IDI_HR1_STR_GETTING_DARK,
IDI_HR1_STR_PRESS_RETURN,

IDI_HR1_STR_TOTAL
};
#define IDI_HR1_OFS_STR_ENTER_COMMAND 0x5bbc
#define IDI_HR1_OFS_STR_VERB_ERROR 0x5b4f
#define IDI_HR1_OFS_STR_NOUN_ERROR 0x5b8e
#define IDI_HR1_OFS_STR_PLAY_AGAIN 0x5f1e
#define IDI_HR1_OFS_STR_CANT_GO_THERE 0x6c0a
#define IDI_HR1_OFS_STR_DONT_HAVE_IT 0x6c31
#define IDI_HR1_OFS_STR_DONT_UNDERSTAND 0x6c51
#define IDI_HR1_OFS_STR_GETTING_DARK 0x6c7c
#define IDI_HR1_OFS_STR_PRESS_RETURN 0x5f68

#define IDI_HR1_OFS_PD_TEXT_0 0x005d
#define IDI_HR1_OFS_PD_TEXT_1 0x012b
Expand Down Expand Up @@ -96,12 +95,15 @@ class HiRes1Engine : public AdlEngine {
void loadData();
void initState();
void restartGame();
uint getEngineMessage(EngineMessage msg) const;
void drawPic(byte pic, Common::Point pos) const;
void printMessage(uint idx, bool wait = true) const;

void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;

struct {
Common::String pressReturn;
} _gameStrings;
};

} // End of namespace Adl
Expand Down

0 comments on commit fd8a5f4

Please sign in to comment.