aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
authorNicola Mettifogo2007-08-14 18:58:47 +0000
committerNicola Mettifogo2007-08-14 18:58:47 +0000
commit32164ff210015297b55c27b97614a35d96bd3dd0 (patch)
tree4429f5299ad40cc262ccc59653067a5cf3fe5ab7 /engines/parallaction
parentd02441a372cc63979468cf0daeec0e638f35f4d6 (diff)
downloadscummvm-rg350-32164ff210015297b55c27b97614a35d96bd3dd0.tar.gz
scummvm-rg350-32164ff210015297b55c27b97614a35d96bd3dd0.tar.bz2
scummvm-rg350-32164ff210015297b55c27b97614a35d96bd3dd0.zip
Defined new Table for location scripts level-0 statements, and changed parseLocation to use a function pointer array instead of a big switch statement.
svn-id: r28620
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/location.cpp217
-rw-r--r--engines/parallaction/parallaction.cpp23
-rw-r--r--engines/parallaction/parallaction.h28
-rw-r--r--engines/parallaction/staticres.cpp18
4 files changed, 199 insertions, 87 deletions
diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp
index 8dce3e1225..4359b69e2a 100644
--- a/engines/parallaction/location.cpp
+++ b/engines/parallaction/location.cpp
@@ -33,10 +33,127 @@
namespace Parallaction {
+DECLARE_LOCATION_PARSER(invalid) {
+ error("unknown keyword '%s' in location '%s'", _tokens[0], _locParseCtxt.filename);
+}
+
+DECLARE_LOCATION_PARSER(endlocation) {
+ _locParseCtxt.end = true;
+}
+
+
+DECLARE_LOCATION_PARSER(location) {
+ // The parameter for location is 'location.mask'.
+ // If mask is not present, then it is assumed
+ // that path & mask are encoded in the background
+ // bitmap, otherwise a separate .msk file exists.
+
+ char *mask = strchr(_tokens[1], '.');
+ if (mask) {
+ mask[0] = '\0';
+ mask++;
+ }
+
+ strcpy(_location._name, _tokens[1]);
+ switchBackground(_location._name, mask);
+
+ if (_tokens[2][0] != '\0') {
+ _char._ani._left = atoi(_tokens[2]);
+ _char._ani._top = atoi(_tokens[3]);
+ }
+
+ if (_tokens[4][0] != '\0') {
+ _char._ani._frame = atoi(_tokens[4]);
+ }
+}
+
+
+DECLARE_LOCATION_PARSER(disk) {
+ _disk->selectArchive(_tokens[1]);
+}
+
+
+DECLARE_LOCATION_PARSER(nodes) {
+ parseWalkNodes(*_locParseCtxt.script, _location._walkNodes);
+}
+
+
+DECLARE_LOCATION_PARSER(zone) {
+ parseZone(*_locParseCtxt.script, _zones, _tokens[1]);
+}
+
+
+DECLARE_LOCATION_PARSER(animation) {
+ parseAnimation(*_locParseCtxt.script, _animations, _tokens[1]);
+}
+
+
+DECLARE_LOCATION_PARSER(localflags) {
+ int _si = 1; // _localFlagNames[0] = 'visited'
+ while (_tokens[_si][0] != '\0') {
+ _localFlagNames->addData(_tokens[_si]);
+ _si++;
+ }
+}
+
+
+DECLARE_LOCATION_PARSER(commands) {
+ parseCommands(*_locParseCtxt.script, _location._commands);
+}
+
+
+DECLARE_LOCATION_PARSER(acommands) {
+ parseCommands(*_locParseCtxt.script, _location._aCommands);
+}
+
+
+DECLARE_LOCATION_PARSER(flags) {
+ if ((_localFlags[_currentLocationIndex] & kFlagsVisited) == 0) {
+ // only for 1st visit
+ _localFlags[_currentLocationIndex] = 0;
+ int _si = 1;
+
+ do {
+ byte _al = _localFlagNames->lookup(_tokens[_si]);
+ _localFlags[_currentLocationIndex] |= 1 << (_al - 1);
+
+ _si++;
+ if (scumm_stricmp(_tokens[_si], "|")) break;
+ _si++;
+ } while (true);
+ }
+}
+
+
+DECLARE_LOCATION_PARSER(comment) {
+ _location._comment = parseComment(*_locParseCtxt.script);
+}
+
+
+DECLARE_LOCATION_PARSER(endcomment) {
+ _location._endComment = parseComment(*_locParseCtxt.script);
+}
+
+
+DECLARE_LOCATION_PARSER(sound) {
+ if (getPlatform() == Common::kPlatformAmiga) {
+ strcpy(_locationSound, _tokens[1]);
+ _hasLocationSound = true;
+ }
+}
+
+
+DECLARE_LOCATION_PARSER(music) {
+ if (getPlatform() == Common::kPlatformAmiga)
+ _soundMan->setMusicFile(_tokens[1]);
+}
+
+
+
+
void Parallaction::parseLocation(const char *filename) {
debugC(1, kDebugLocation, "parseLocation('%s')", filename);
- uint16 _si = 1;
_gfx->setFont(_labelFont);
Script *script = _disk->loadLocation(filename);
@@ -67,95 +184,21 @@ void Parallaction::parseLocation(const char *filename) {
_localFlags[_currentLocationIndex] |= kFlagsVisited; // 'visited'
}
+ _locParseCtxt.end = false;;
+ _locParseCtxt.script = script;
+ _locParseCtxt.filename = filename;
fillBuffers(*script, true);
- while (scumm_stricmp(_tokens[0], "ENDLOCATION")) {
-
- printf("inst = %s\n", _tokens[0]);
-
- if (!scumm_stricmp(_tokens[0], "LOCATION")) {
- // The parameter for location is 'location.mask'.
- // If mask is not present, then it is assumed
- // that path & mask are encoded in the background
- // bitmap, otherwise a separate .msk file exists.
-
- char *mask = strchr(_tokens[1], '.');
- if (mask) {
- mask[0] = '\0';
- mask++;
- }
-
- strcpy(_location._name, _tokens[1]);
- switchBackground(_location._name, mask);
-
- if (_tokens[2][0] != '\0') {
- _char._ani._left = atoi(_tokens[2]);
- _char._ani._top = atoi(_tokens[3]);
- }
-
- if (_tokens[4][0] != '\0') {
- _char._ani._frame = atoi(_tokens[4]);
- }
- } else
- if (!scumm_stricmp(_tokens[0], "DISK")) {
- _disk->selectArchive(_tokens[1]);
- } else
- if (!scumm_stricmp(_tokens[0], "NODES")) {
- parseWalkNodes(*script, _location._walkNodes);
- } else
- if (!scumm_stricmp(_tokens[0], "ZONE")) {
- parseZone(*script, _zones, _tokens[1]);
- } else
- if (!scumm_stricmp(_tokens[0], "ANIMATION")) {
- parseAnimation(*script, _animations, _tokens[1]);
- } else
- if (!scumm_stricmp(_tokens[0], "LOCALFLAGS")) {
- _si = 1; // _localFlagNames[0] = 'visited'
- while (_tokens[_si][0] != '\0') {
- _localFlagNames->addData(_tokens[_si]);
- _si++;
- }
- } else
- if (!scumm_stricmp(_tokens[0], "COMMANDS")) {
- parseCommands(*script, _location._commands);
- } else
- if (!scumm_stricmp(_tokens[0], "ACOMMANDS")) {
- parseCommands(*script, _location._aCommands);
- } else
- if (!scumm_stricmp(_tokens[0], "FLAGS")) {
- if ((_localFlags[_currentLocationIndex] & kFlagsVisited) == 0) {
- // only for 1st visit
- _localFlags[_currentLocationIndex] = 0;
- _si = 1;
-
- do {
- byte _al = _localFlagNames->lookup(_tokens[_si]);
- _localFlags[_currentLocationIndex] |= 1 << (_al - 1);
-
- _si++;
- if (scumm_stricmp(_tokens[_si], "|")) break;
- _si++;
- } while (true);
- }
- } else
- if (!scumm_stricmp(_tokens[0], "COMMENT")) {
- _location._comment = parseComment(*script);
- } else
- if (!scumm_stricmp(_tokens[0], "ENDCOMMENT")) {
- _location._endComment = parseComment(*script);
- } else
- if (!scumm_stricmp(_tokens[0], "SOUND")) {
- if (getPlatform() == Common::kPlatformAmiga) {
- strcpy(_locationSound, _tokens[1]);
- _hasLocationSound = true;
- }
- } else
- if (!scumm_stricmp(_tokens[0], "MUSIC")) {
- if (getPlatform() == Common::kPlatformAmiga)
- _soundMan->setMusicFile(_tokens[1]);
- } else
- error("unknown keyword '%s' in location '%s'", _tokens[0], filename);
+ int index;
+ while (true) {
+
+ index = _locationStmt->lookup(_tokens[0]);
+
+ (this->*_locationParsers[index])();
+
+ if (_locParseCtxt.end)
+ break;
fillBuffers(*script, true);
}
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 2a53eb11a2..367b470a10 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -132,6 +132,7 @@ Parallaction::~Parallaction() {
delete _instructionNames;
delete _zoneTypeNames;
delete _zoneFlagNames;
+ delete _locationStmt;
_animations.remove(&_char._ani);
@@ -944,6 +945,28 @@ void Parallaction::initOpcodes() {
_commandOpcodes = op3;
+
+ static const Opcode op4[] = {
+ LOCATION_PARSER(invalid),
+ LOCATION_PARSER(endlocation),
+ LOCATION_PARSER(location),
+ LOCATION_PARSER(disk),
+ LOCATION_PARSER(nodes),
+ LOCATION_PARSER(zone),
+ LOCATION_PARSER(animation),
+ LOCATION_PARSER(localflags),
+ LOCATION_PARSER(commands),
+ LOCATION_PARSER(acommands),
+ LOCATION_PARSER(flags),
+ LOCATION_PARSER(comment),
+ LOCATION_PARSER(endcomment),
+ LOCATION_PARSER(sound),
+ LOCATION_PARSER(music)
+ };
+
+ _locationParsers = op4;
+
+
}
} // namespace Parallaction
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 7c53f74215..c7d6f5529b 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -312,6 +312,9 @@ struct BackgroundInfo {
#define DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(op) void instOp_##op()
#define INSTRUCTION_OPCODE(op) &Parallaction::instOp_##op
+#define DECLARE_LOCATION_PARSER(sig) void Parallaction::locParse_##sig()
+#define DECLARE_UNQUALIFIED_LOCATION_PARSER(sig) void locParse_##sig()
+#define LOCATION_PARSER(sig) &Parallaction::locParse_##sig
class Parallaction : public Engine {
friend class Debugger;
@@ -425,6 +428,30 @@ public:
void parseLocation(const char *filename);
+ const Opcode *_locationParsers;
+
+ struct {
+ const char *filename;
+ bool end;
+ Script *script;
+ } _locParseCtxt;
+
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(invalid);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(endlocation);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(location);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(disk);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(nodes);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(zone);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(animation);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(localflags);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(commands);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(acommands);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(flags);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(comment);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(endcomment);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(sound);
+ DECLARE_UNQUALIFIED_LOCATION_PARSER(music);
+
void changeCursor(int32 index);
void showCursor(bool visible);
void changeCharacter(const char *name);
@@ -468,6 +495,7 @@ public:
Table *_callableNames;
Table *_instructionNames;
Table *_localFlagNames;
+ Table *_locationStmt;
diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp
index a9b19de448..fe7c91160f 100644
--- a/engines/parallaction/staticres.cpp
+++ b/engines/parallaction/staticres.cpp
@@ -330,6 +330,23 @@ const char *_callableNamesRes_ns[] = {
"TestResult"
};
+const char *_locationStmtRes_ns[] = {
+ "endlocation",
+ "location",
+ "disk",
+ "nodes",
+ "zone",
+ "animation",
+ "localflags",
+ "commands",
+ "acommands",
+ "flags",
+ "comment",
+ "endcomment",
+ "sound",
+ "music"
+};
+
const char *_zoneTypeNamesRes_br[] = {
"examine",
"door",
@@ -564,6 +581,7 @@ void Parallaction_ns::initResources() {
_zoneFlagNames = new Table(ARRAYSIZE(_zoneFlagNamesRes_ns), _zoneFlagNamesRes_ns);
_zoneTypeNames = new Table(ARRAYSIZE(_zoneTypeNamesRes_ns), _zoneTypeNamesRes_ns);
_commandsNames = new Table(ARRAYSIZE(_commandsNamesRes_ns), _commandsNamesRes_ns);
+ _locationStmt = new Table(ARRAYSIZE(_locationStmtRes_ns), _locationStmtRes_ns);
_localFlagNames = new Table(120);
_localFlagNames->addData("visited");