From 9c608fcacbfe099f5c23fd457dfe139380e71bf5 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Sun, 26 Aug 2007 09:01:19 +0000 Subject: Implemented more opcodes. svn-id: r28746 --- engines/parallaction/objects.h | 11 ++++- engines/parallaction/parallaction.cpp | 42 +++++++++++----- engines/parallaction/parallaction.h | 25 ++++++++-- engines/parallaction/parallaction_br.cpp | 4 +- engines/parallaction/parser_br.cpp | 84 +++++++++++++++++++++++++++++++- engines/parallaction/parser_ns.cpp | 16 +++--- engines/parallaction/staticres.cpp | 6 +-- 7 files changed, 154 insertions(+), 34 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 9ec906f458..cc6e8e0fc6 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -71,7 +71,13 @@ enum ZoneFlags { kFlagsLooping = 0x100, // Animation: script is to be executed repeatedly kFlagsAdded = 0x200, // NEVER USED in Nippon Safes kFlagsCharacter = 0x400, // - kFlagsNoWalk = 0x800 // Zone: character doesn't need to walk towards object to interact + kFlagsNoWalk = 0x800, // Zone: character doesn't need to walk towards object to interact + + // BRA specific + kFlagsYourself = 0x1000, + kFlagsScaled = 0x2000, + kFlagsSelfuse = 0x4000, + kFlagsAnimLinked = 0x2000000 }; @@ -275,7 +281,10 @@ struct Zone { CommandList _commands; Common::Point _moveTo; + // BRA specific uint _index; + char *_linkedName; + Animation *_linkedAnim; Zone(); virtual ~Zone(); diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 7d150e8813..9bdf90f287 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -123,7 +123,7 @@ Parallaction::~Parallaction() { delete _globalTable; delete _callableNames; - + delete _localFlagNames; delete _zoneTypeNames; delete _zoneFlagNames; @@ -170,7 +170,7 @@ int Parallaction::init() { strcpy(_characterName1, "null"); strcpy(_characterName, "dough"); - memset(_locationNames, 0, 120*32); + memset(_locationNames, 0, NUM_LOCATIONS * 32); initInventory(); // needs to be pushed into subclass @@ -772,8 +772,7 @@ Table::~Table() { if (!_disposeMemory) return; - for (uint32 i = 0; i < _used; i++) - free(_data[i]); + clear(); free(_data); @@ -797,6 +796,28 @@ uint16 Table::lookup(const char* s) { return notFound; } +void Table::clear() { + for (uint32 i = 0; i < _used; i++) + free(_data[i]); + + _used = 0; +} + +FixedTable::FixedTable(uint32 size, uint32 fixed) : Table(size), _numFixed(fixed) { +} + +FixedTable::~FixedTable() { + _numFixed = 0; +} + +void FixedTable::clear() { + for (uint32 i = _numFixed; i < _used; i++) { + free(_data[i]); + _used--; + } +} + + void Parallaction::pushParserTables(OpcodeSet *opcodes, Table *statements) { _opcodes.push(_currentOpcodes); _statements.push(_currentStatements); @@ -816,6 +837,9 @@ void Parallaction::parseStatement() { assert(_currentOpcodes != 0); _lookup = _currentStatements->lookup(_tokens[0]); + + debugC(9, kDebugLocation, "parseStatement: %s (lookup = %i)", _tokens[0], _lookup); + (*(*_currentOpcodes)[_lookup])(); } @@ -887,15 +911,7 @@ void Parallaction::freeLocation() { _soundMan->stopSfx(2); _soundMan->stopSfx(3); - if (_localFlagNames) - delete _localFlagNames; - - // HACK: prevents leakage. A routine like this - // should allocate memory at all, though. - if ((_engineFlags & kEngineQuit) == 0) { - _localFlagNames = new Table(NUM_LOCATIONS); - _localFlagNames->addData("visited"); - } + _localFlagNames->clear(); _location._walkNodes.clear(); diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index cc91d4bdf7..5685d28b8f 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -264,6 +264,7 @@ struct Character { class Table { +protected: char **_data; uint16 _size; uint16 _used; @@ -273,15 +274,25 @@ public: Table(uint32 size); Table(uint32 size, const char** data); - ~Table(); + virtual ~Table(); enum { notFound = 0 }; - void addData(const char* s); + virtual void addData(const char* s); + virtual void clear(); + virtual uint16 lookup(const char* s); +}; + +class FixedTable : public Table { + + uint16 _numFixed; - uint16 lookup(const char* s); +public: + FixedTable(uint32 size, uint32 fixed); + ~FixedTable(); + void clear(); }; struct BackgroundInfo { @@ -951,7 +962,13 @@ private: DECLARE_UNQUALIFIED_COMMAND_OPCODE(ret); DECLARE_UNQUALIFIED_COMMAND_OPCODE(onsave); DECLARE_UNQUALIFIED_COMMAND_OPCODE(offsave); - + DECLARE_UNQUALIFIED_ZONE_PARSER(limits); + DECLARE_UNQUALIFIED_ZONE_PARSER(moveto); + DECLARE_UNQUALIFIED_ZONE_PARSER(type); + DECLARE_UNQUALIFIED_ANIM_PARSER(file); + DECLARE_UNQUALIFIED_ANIM_PARSER(position); + DECLARE_UNQUALIFIED_ANIM_PARSER(moveto); + DECLARE_UNQUALIFIED_ANIM_PARSER(endanimation); DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(on); DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(off); diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 31b2793090..e09a48dd9d 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -84,9 +84,9 @@ int Parallaction_br::init() { initResources(); initFonts(); initCursors(); -/* initOpcodes(); + initOpcodes(); initParsers(); -*/ + _part = -1; Parallaction::init(); diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 2e51c99851..bf33471e1f 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -154,7 +154,7 @@ DECLARE_LOCATION_PARSER(animation) { DECLARE_LOCATION_PARSER(localflags) { - int _si = 1; // _localFlagNames[0] = 'visited' + int _si = 1; while (_tokens[_si][0] != '\0') { _localFlagNames->addData(_tokens[_si]); _si++; @@ -453,6 +453,88 @@ DECLARE_COMMAND_PARSER(unary) { } +DECLARE_ZONE_PARSER(limits) { + if (isalpha(_tokens[1][1])) { + _locParseCtxt.z->_flags |= kFlagsAnimLinked; + _locParseCtxt.z->_linkedAnim = findAnimation(_tokens[1]); + _locParseCtxt.z->_linkedName = strdup(_tokens[1]); + } else { + _locParseCtxt.z->_left = atoi(_tokens[1]); + _locParseCtxt.z->_top = atoi(_tokens[2]); + _locParseCtxt.z->_right = atoi(_tokens[3]); + _locParseCtxt.z->_bottom = atoi(_tokens[4]); + } +} + + +DECLARE_ZONE_PARSER(moveto) { + _locParseCtxt.z->_moveTo.x = atoi(_tokens[1]); + _locParseCtxt.z->_moveTo.y = atoi(_tokens[2]); +// _locParseCtxt.z->_moveTo.z = atoi(_tokens[3]); +} + + +DECLARE_ZONE_PARSER(type) { + if (_tokens[2][0] != '\0') { + _locParseCtxt.z->_type = (4 + _objectsNames->lookup(_tokens[2])) << 16; + } + int16 _si = _zoneTypeNames->lookup(_tokens[1]); + if (_si != Table::notFound) { + _locParseCtxt.z->_type |= 1 << (_si - 1); + parseZoneTypeBlock(*_locParseCtxt.script, _locParseCtxt.z); + +// if (_locParseCtxt.z->_type & kZoneHear) { +// _soundMan->sfxCommand(START...); +// } + } + + popParserTables(); +} + + +DECLARE_ANIM_PARSER(file) { + _locParseCtxt.a->_cnv = _disk->loadFrames(_tokens[1]); +} + + +DECLARE_ANIM_PARSER(position) { + _locParseCtxt.a->_left = atoi(_tokens[1]); + _locParseCtxt.a->_top = atoi(_tokens[2]); + _locParseCtxt.a->_z = atoi(_tokens[3]); + _locParseCtxt.a->_frame = atoi(_tokens[4]); +} + + +DECLARE_ANIM_PARSER(moveto) { + _locParseCtxt.a->_moveTo.x = atoi(_tokens[1]); + _locParseCtxt.a->_moveTo.y = atoi(_tokens[2]); +// _locParseCtxt.a->_moveTo.z = atoi(_tokens[3]); +} + + +DECLARE_ANIM_PARSER(endanimation) { + + if (_locParseCtxt.a->_cnv) { + _locParseCtxt.a->_right = _locParseCtxt.a->width(); + _locParseCtxt.a->_bottom = _locParseCtxt.a->height(); + } + + _locParseCtxt.a->_oldPos.x = -1000; + _locParseCtxt.a->_oldPos.y = -1000; + + _locParseCtxt.a->_flags |= 0x1000000; + + popParserTables(); +} + + + + + + + + + DECLARE_INSTRUCTION_PARSER(zone) { _instParseCtxt.inst->_z = findZone(_tokens[1]); diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index e3ee3157fb..f60479a2c9 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -174,7 +174,6 @@ Animation *Parallaction_ns::parseAnimation(Script& script, AnimationList &list, list.push_front(a); _locParseCtxt.a = a; - _locParseCtxt.end = false; _locParseCtxt.script = &script; pushParserTables(&_locationAnimParsers, _locationAnimStmt); @@ -607,7 +606,7 @@ void Parallaction_ns::createCommand(uint id) { void Parallaction_ns::parseCommands(Script &script, CommandList& list) { _locParseCtxt.list = &list; - _locParseCtxt.end = false; + _locParseCtxt.endcommands = false; _locParseCtxt.script = &script; pushParserTables(&_commandParsers, _commandsNames); @@ -804,7 +803,7 @@ DECLARE_LOCATION_PARSER(animation) { DECLARE_LOCATION_PARSER(localflags) { - int _si = 1; // _localFlagNames[0] = 'visited' + int _si = 1; while (_tokens[_si][0] != '\0') { _localFlagNames->addData(_tokens[_si]); _si++; @@ -869,9 +868,10 @@ DECLARE_LOCATION_PARSER(redundant) { void Parallaction_ns::parseLocation(const char *filename) { - debugC(1, kDebugLocation, "parseLocation('%s')", filename); + debugC(5, kDebugLocation, "parseLocation('%s')", filename); allocateLocationSlot(filename); + printf("got location slot #%i for %s\n", _currentLocationIndex, filename); Script *script = _disk->loadLocation(filename); @@ -885,15 +885,10 @@ void Parallaction_ns::parseLocation(const char *filename) { _locParseCtxt.filename = filename; pushParserTables(&_locationParsers, _locationStmt); - do { - fillBuffers(*script, true); - parseStatement(); - } while (!_locParseCtxt.end); - popParserTables(); delete script; @@ -911,6 +906,8 @@ void Parallaction_ns::parseLocation(const char *filename) { if ((*it)->_scriptName) loadProgram(*it, (*it)->_scriptName); } + + debugC(5, kDebugLocation, "parseLocation('%s') done", filename); return; } @@ -1156,7 +1153,6 @@ void Parallaction_ns::parseZone(Script &script, ZoneList &list, char *name) { z->_label._text = strdup(name); _locParseCtxt.z = z; - _locParseCtxt.end = false; _locParseCtxt.script = &script; list.push_front(z); diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp index ddc71d8e85..8fa1b9f5e4 100644 --- a/engines/parallaction/staticres.cpp +++ b/engines/parallaction/staticres.cpp @@ -657,7 +657,7 @@ void Parallaction_ns::initResources() { _locationZoneStmt = new Table(ARRAYSIZE(_locationZoneStmtRes_ns), _locationZoneStmtRes_ns); _locationAnimStmt = new Table(ARRAYSIZE(_locationAnimStmtRes_ns), _locationAnimStmtRes_ns); - _localFlagNames = new Table(NUM_LOCATIONS); + _localFlagNames = new FixedTable(NUM_LOCATIONS, 1); _localFlagNames->addData("visited"); if (getPlatform() == Common::kPlatformPC) { @@ -687,9 +687,9 @@ void Parallaction_br::initResources() { _locationZoneStmt = new Table(ARRAYSIZE(_locationZoneStmtRes_br), _locationZoneStmtRes_br); _locationAnimStmt = new Table(ARRAYSIZE(_locationAnimStmtRes_br), _locationAnimStmtRes_br); - // TODO: make sure there are 120 max locations in Big Red Adventure - _localFlagNames = new Table(NUM_LOCATIONS); + _localFlagNames = new FixedTable(NUM_LOCATIONS, 2); _localFlagNames->addData("visited"); + _localFlagNames->addData("testtrue"); if (getPlatform() == Common::kPlatformPC) { _callables = _dosCallables; -- cgit v1.2.3