From 32164ff210015297b55c27b97614a35d96bd3dd0 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Tue, 14 Aug 2007 18:58:47 +0000 Subject: 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 --- engines/parallaction/location.cpp | 217 ++++++++++++++++++++-------------- engines/parallaction/parallaction.cpp | 23 ++++ engines/parallaction/parallaction.h | 28 +++++ engines/parallaction/staticres.cpp | 18 +++ 4 files changed, 199 insertions(+), 87 deletions(-) (limited to 'engines/parallaction') 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"); -- cgit v1.2.3