[Scummvm-cvs-logs] SF.net SVN: scummvm: [28711] scummvm/trunk/engines/parallaction
peres001 at users.sourceforge.net
peres001 at users.sourceforge.net
Fri Aug 24 22:14:51 CEST 2007
Revision: 28711
http://scummvm.svn.sourceforge.net/scummvm/?rev=28711&view=rev
Author: peres001
Date: 2007-08-24 13:14:51 -0700 (Fri, 24 Aug 2007)
Log Message:
-----------
First step in restructuring engine code:
- code has been consolidated in fewer files
- new table-driven parsers/execution
- some functions has been pushed down the engine hierarchy
- Parallaction_br now inherits from Parallaction_ns
Modified Paths:
--------------
scummvm/trunk/engines/parallaction/dialogue.cpp
scummvm/trunk/engines/parallaction/disk_br.cpp
scummvm/trunk/engines/parallaction/font.cpp
scummvm/trunk/engines/parallaction/inventory.cpp
scummvm/trunk/engines/parallaction/module.mk
scummvm/trunk/engines/parallaction/parallaction.cpp
scummvm/trunk/engines/parallaction/parallaction.h
scummvm/trunk/engines/parallaction/parallaction_br.cpp
scummvm/trunk/engines/parallaction/parallaction_ns.cpp
scummvm/trunk/engines/parallaction/parser.cpp
scummvm/trunk/engines/parallaction/parser.h
scummvm/trunk/engines/parallaction/staticres.cpp
Added Paths:
-----------
scummvm/trunk/engines/parallaction/exec_ns.cpp
scummvm/trunk/engines/parallaction/objects.cpp
scummvm/trunk/engines/parallaction/objects.h
scummvm/trunk/engines/parallaction/parser_ns.cpp
Removed Paths:
-------------
scummvm/trunk/engines/parallaction/animation.cpp
scummvm/trunk/engines/parallaction/commands.cpp
scummvm/trunk/engines/parallaction/commands.h
scummvm/trunk/engines/parallaction/location.cpp
scummvm/trunk/engines/parallaction/zone.cpp
scummvm/trunk/engines/parallaction/zone.h
Deleted: scummvm/trunk/engines/parallaction/animation.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/animation.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/animation.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,769 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "parallaction/parallaction.h"
-
-
-namespace Parallaction {
-
-
-#define INST_ON 1
-#define INST_OFF 2
-#define INST_X 3
-#define INST_Y 4
-#define INST_Z 5
-#define INST_F 6
-#define INST_LOOP 7
-#define INST_ENDLOOP 8
-#define INST_SHOW 9
-#define INST_INC 10
-#define INST_DEC 11
-#define INST_SET 12
-#define INST_PUT 13
-#define INST_CALL 14
-#define INST_WAIT 15
-#define INST_START 16
-#define INST_SOUND 17
-#define INST_MOVE 18
-#define INST_END 19
-
-
-void wrapLocalVar(LocalVariable *local);
-
-
-#define NUM_LOCALS 10
-
-uint16 _numLocals = 0;
-char _localNames[NUM_LOCALS][10];
-
-Animation *Parallaction::findAnimation(const char *name) {
-
- for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++)
- if (!scumm_stricmp((*it)->_label._text, name)) return *it;
-
- return NULL;
-}
-
-DECLARE_ANIM_PARSER(invalid) {
- error("unknown statement '%s' in animation %s", _tokens[0], _locAnimParseCtxt.a->_label._text);
-}
-
-
-DECLARE_ANIM_PARSER(script) {
- _locAnimParseCtxt.a->_scriptName = strdup(_tokens[1]);
-}
-
-
-DECLARE_ANIM_PARSER(commands) {
- parseCommands(*_locAnimParseCtxt.script, _locAnimParseCtxt.a->_commands);
-}
-
-
-DECLARE_ANIM_PARSER(type) {
- if (_tokens[2][0] != '\0') {
- _locAnimParseCtxt.a->_type = ((4 + _objectsNames->lookup(_tokens[2])) << 16) & 0xFFFF0000;
- }
- int16 _si = _zoneTypeNames->lookup(_tokens[1]);
- if (_si != Table::notFound) {
- _locAnimParseCtxt.a->_type |= 1 << (_si-1);
- if (((_locAnimParseCtxt.a->_type & 0xFFFF) != kZoneNone) && ((_locAnimParseCtxt.a->_type & 0xFFFF) != kZoneCommand)) {
- parseZoneTypeBlock(*_locAnimParseCtxt.script, _locAnimParseCtxt.a);
- }
- }
-
- _locAnimParseCtxt.a->_oldPos.x = -1000;
- _locAnimParseCtxt.a->_oldPos.y = -1000;
-
- _locAnimParseCtxt.a->_flags |= 0x1000000;
-
- popParserTables();
-}
-
-
-DECLARE_ANIM_PARSER(label) {
- renderLabel(&_locAnimParseCtxt.a->_label._cnv, _tokens[1]);
-}
-
-
-DECLARE_ANIM_PARSER(flags) {
- uint16 _si = 1;
-
- do {
- byte _al = _zoneFlagNames->lookup(_tokens[_si]);
- _si++;
- _locAnimParseCtxt.a->_flags |= 1 << (_al - 1);
- } while (!scumm_stricmp(_tokens[_si++], "|"));
-}
-
-
-DECLARE_ANIM_PARSER(file) {
- char vC8[200];
- strcpy(vC8, _tokens[1]);
- if (_engineFlags & kEngineTransformedDonna) {
- if (!scumm_stricmp(_tokens[1], "donnap") || !scumm_stricmp(_tokens[1], "donnapa")) {
- strcat(vC8, "tras");
- }
- }
- _locAnimParseCtxt.a->_cnv = _disk->loadFrames(vC8);
-}
-
-
-DECLARE_ANIM_PARSER(position) {
- _locAnimParseCtxt.a->_left = atoi(_tokens[1]);
- _locAnimParseCtxt.a->_top = atoi(_tokens[2]);
- _locAnimParseCtxt.a->_z = atoi(_tokens[3]);
-}
-
-
-DECLARE_ANIM_PARSER(moveto) {
- _locAnimParseCtxt.a->_moveTo.x = atoi(_tokens[1]);
- _locAnimParseCtxt.a->_moveTo.y = atoi(_tokens[2]);
-}
-
-
-DECLARE_ANIM_PARSER(endanimation) {
-
- _locAnimParseCtxt.a->_oldPos.x = -1000;
- _locAnimParseCtxt.a->_oldPos.y = -1000;
-
- _locAnimParseCtxt.a->_flags |= 0x1000000;
-
- popParserTables();
-}
-
-Animation *Parallaction::parseAnimation(Script& script, AnimationList &list, char *name) {
-// printf("parseAnimation(%s)\n", name);
-
- Animation *a = new Animation;
-
- a->_label._text = strdup(name);
-
- list.push_front(a);
-
- _locAnimParseCtxt.a = a;
- _locAnimParseCtxt.end = false;
- _locAnimParseCtxt.script = &script;
-
- pushParserTables(_locationAnimParsers, _locationAnimStmt);
-
- return a;
-}
-
-
-void Parallaction::freeAnimations() {
- _animations.clear();
- return;
-}
-
-
-
-void jobDisplayAnimations(void *parm, Job *j) {
-// printf("jobDisplayAnimations()...\n");
-
- Graphics::Surface v14;
-
- uint16 _si = 0;
-
- for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
-
- Animation *v18 = *it;
-
- if ((v18->_flags & kFlagsActive) && ((v18->_flags & kFlagsRemove) == 0)) {
- v14.w = v18->width();
- v14.h = v18->height();
-
- int16 frame = CLIP((int)v18->_frame, 0, v18->getFrameNum()-1);
-
- v14.pixels = v18->getFrameData(frame);
-
- if (v18->_flags & kFlagsNoMasked)
- _si = 3;
- else
- _si = _vm->_gfx->queryMask(v18->_top + v18->height());
-
- debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, f:%i/%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14.w, v14.h,
- frame, v18->getFrameNum(), v14.pixels);
- _vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack);
-
- }
-
- if (((v18->_flags & kFlagsActive) == 0) && (v18->_flags & kFlagsRemove)) {
- v18->_flags &= ~kFlagsRemove;
- v18->_oldPos.x = -1000;
- }
-
- if ((v18->_flags & kFlagsActive) && (v18->_flags & kFlagsRemove)) {
- v18->_flags &= ~kFlagsActive;
- v18->_flags |= kFlagsRemove;
- }
-
- }
-
-// printf("done\n");
-
- return;
-}
-
-
-void jobEraseAnimations(void *arg_0, Job *j) {
- debugC(3, kDebugJobs, "jobEraseAnimations");
-
- for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
-
- Animation *a = *it;
-
- if (((a->_flags & kFlagsActive) == 0) && ((a->_flags & kFlagsRemove) == 0)) continue;
-
- Common::Rect r(a->width(), a->height());
- r.moveTo(a->_oldPos);
- _vm->_gfx->restoreBackground(r);
-
- if (arg_0) {
- a->_oldPos.x = a->_left;
- a->_oldPos.y = a->_top;
- }
-
- }
-
-// printf("done\n");
-
- return;
-}
-
-
-void Parallaction::loadProgram(Animation *a, char *filename) {
-// printf("loadProgram(%s)\n", filename);
-
- Script *script = _disk->loadScript(filename);
-
- _numLocals = 0;
-
- fillBuffers(*script);
-
- a->_program = new Program;
-
- Instruction *vCC = new Instruction;
-
- while (scumm_stricmp(_tokens[0], "endscript")) {
- parseScriptLine(vCC, a, a->_program->_locals);
- a->_program->_instructions.push_back(vCC);
- vCC = new Instruction;
- fillBuffers(*script);
- }
-
- // TODO: use List<>::end() to detect the end of the program
- vCC->_index = INST_END;
- a->_program->_instructions.push_back(vCC);
- a->_program->_ip = a->_program->_instructions.begin();
-
- delete script;
-
- return;
-}
-
-int16 findLocal(const char* name, LocalVariable *locals) {
- for (uint16 _si = 0; _si < NUM_LOCALS; _si++) {
- if (!scumm_stricmp(name, _localNames[_si]))
- return _si;
- }
-
- return -1;
-}
-
-int16 addLocal(const char *name, LocalVariable *locals, int16 value = 0, int16 min = -10000, int16 max = 10000) {
- assert(_numLocals < NUM_LOCALS);
-
- strcpy(_localNames[_numLocals], name);
- locals[_numLocals]._value = value;
-
- locals[_numLocals]._min = min;
- locals[_numLocals]._max = max;
-
- return _numLocals++;
-}
-
-
-DECLARE_INSTRUCTION_PARSER(animation) {
- if (!scumm_stricmp(_tokens[1], _instParseCtxt.a->_label._text)) {
- _instParseCtxt.inst->_opBase._a = _instParseCtxt.a;
- } else {
- _instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]);
- }
-}
-
-
-DECLARE_INSTRUCTION_PARSER(loop) {
- _instParseCtxt.inst->_opBase._loopCounter = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(x) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_left;
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(y) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_top;
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(z) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_z;
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(f) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_frame;
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(inc) {
- if (!scumm_stricmp(_tokens[1], "X")) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_left;
- } else
- if (!scumm_stricmp(_tokens[1], "Y")) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_top;
- } else
- if (!scumm_stricmp(_tokens[1], "Z")) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_z;
- } else
- if (!scumm_stricmp(_tokens[1], "F")) {
- _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_frame;
- } else {
- _instParseCtxt.inst->_flags |= kInstUsesLocal;
- _instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
- }
-
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
-
- if (!scumm_stricmp(_tokens[3], "mod")) {
- _instParseCtxt.inst->_flags |= kInstMod;
- }
-}
-
-
-DECLARE_INSTRUCTION_PARSER(set) {
- // WORKAROUND: At least one script (balzo.script) in Amiga versions didn't declare
- // local variables before using them, thus leading to crashes. The line launching the
- // script was commented out on Dos version. This workaround enables the engine
- // to dynamically add a local variable when it is encountered the first time in
- // the script, so should fix any other occurrence as well.
- if (findLocal(_tokens[1], _instParseCtxt.locals) == -1) {
- addLocal(_tokens[1], _instParseCtxt.locals);
- }
-
- _instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
- _instParseCtxt.inst->_flags |= kInstUsesLocal;
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(move) {
- _instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(put) {
- if (!scumm_stricmp(_tokens[1], _instParseCtxt.a->_label._text)) {
- _instParseCtxt.inst->_opBase._a = _instParseCtxt.a;
- } else {
- _instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]);
- }
-
- _instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
- _instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[3], _instParseCtxt.locals, _instParseCtxt.a);
- if (!scumm_stricmp(_tokens[4], "masked")) {
- _instParseCtxt.inst->_flags |= kInstMaskedPut;
- }
-}
-
-
-DECLARE_INSTRUCTION_PARSER(call) {
- int index = _callableNames->lookup(_tokens[1]);
- if (index == Table::notFound)
- error("unknown callable '%s'", _tokens[1]);
- _instParseCtxt.inst->_opBase._index = index - 1;
-}
-
-
-DECLARE_INSTRUCTION_PARSER(sound) {
- _instParseCtxt.inst->_opBase._z = findZone(_tokens[1]);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(null) {
-
-}
-
-
-DECLARE_INSTRUCTION_PARSER(defLocal) {
- int16 val = atoi(_tokens[2]);
- int16 index;
-
- if (_tokens[3][0] != '\0') {
- index = addLocal(_tokens[0], _instParseCtxt.locals, val, atoi(_tokens[3]), atoi(_tokens[4]));
- } else {
- index = addLocal(_tokens[0], _instParseCtxt.locals, val);
- }
-
- _instParseCtxt.inst->_opA._local = &_instParseCtxt.locals[index];
- _instParseCtxt.inst->_opB._value = _instParseCtxt.locals[index]._value;
-
- _instParseCtxt.inst->_flags = kInstUsesLiteral | kInstUsesLocal;
- _instParseCtxt.inst->_index = INST_SET;
-}
-
-
-
-
-void Parallaction::parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals) {
-// printf("parseScriptLine()\n");
-
- if (_tokens[0][1] == '.') {
- _tokens[0][1] = '\0';
- a = findAnimation(&_tokens[0][2]);
- }
-
- if (_tokens[1][1] == '.') {
- _tokens[1][1] = '\0';
- a = findAnimation(&_tokens[1][2]);
- }
-
- int16 _si = _instructionNames->lookup(_tokens[0]);
- inst->_index = _si;
-
- _instParseCtxt.a = a;
- _instParseCtxt.inst = inst;
- _instParseCtxt.locals = locals;
-
- (this->*_instructionParsers[inst->_index])();
-
- return;
-}
-
-LValue Parallaction::getLValue(Instruction *inst, char *str, LocalVariable *locals, Animation *a) {
-
- LValue v;
-
- v._pvalue = 0; // should stop compiler from complaining
-
- if (isdigit(str[0]) || str[0] == '-') {
- inst->_flags |= kInstUsesLiteral;
- v._value = atoi(str);
- return v;
- }
-
- int index = findLocal(str, locals);
- if (index != -1) {
- v._local = &locals[index];
- return v;
- }
-
- if (str[1] == '.') {
- a = findAnimation(&str[2]);
- }
-
- if (str[0] == 'X') {
- v._pvalue = &a->_left;
- } else
- if (str[0] == 'Y') {
- v._pvalue = &a->_top;
- } else
- if (str[0] == 'Z') {
- v._pvalue = &a->_z;
- } else
- if (str[0] == 'F') {
- v._pvalue = &a->_frame;
- }
-
- return v;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(on) {
- (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive;
- (*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(off) {
- (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsRemove;
-// v1C = (*_instRunCtxt.inst)->_opBase;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(loop) {
- if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) {
- _instRunCtxt.a->_program->_loopCounter = (*_instRunCtxt.inst)->_opBase._loopCounter._value;
- } else {
- _instRunCtxt.a->_program->_loopCounter = *(*_instRunCtxt.inst)->_opBase._loopCounter._pvalue;
- }
- _instRunCtxt.a->_program->_loopStart = _instRunCtxt.inst;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(endloop) {
- if (--_instRunCtxt.a->_program->_loopCounter > 0) {
- _instRunCtxt.inst = _instRunCtxt.a->_program->_loopStart;
- }
-}
-
-DECLARE_INSTRUCTION_OPCODE(inc) {
- int16 _si = 0;
- int16 _ax = 0, _bx = 0;
- if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) {
- _si = (*_instRunCtxt.inst)->_opB._value;
- } else {
- _si = *(*_instRunCtxt.inst)->_opB._pvalue;
- }
- if ((*_instRunCtxt.inst)->_flags & kInstMod) { // mod
- _bx = (_si > 0 ? _si : -_si);
- if (_instRunCtxt.modCounter % _bx != 0) return;
-
- _si = (_si > 0 ? 1 : -1);
- }
- if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) { // local
- if ((*_instRunCtxt.inst)->_index == INST_INC) _ax = _si;
- else _ax = -_si;
-
- (*_instRunCtxt.inst)->_opA._local->_value += _ax;
- wrapLocalVar((*_instRunCtxt.inst)->_opA._local);
- return;
- }
-
- // built-in variable (x, y, z, f)
- if ((*_instRunCtxt.inst)->_index == INST_INC) _ax = _si;
- else _ax = -_si;
- *(*_instRunCtxt.inst)->_opA._pvalue += _ax;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(set) {
- int16 _si;
- if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) {
- _si = (*_instRunCtxt.inst)->_opB._value;
- } else {
- _si = *(*_instRunCtxt.inst)->_opB._pvalue;
- }
-
- if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) {
- (*_instRunCtxt.inst)->_opA._local->_value = _si;
- } else {
- *(*_instRunCtxt.inst)->_opA._pvalue = _si;
- }
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(put) {
- Graphics::Surface v18;
- v18.w = (*_instRunCtxt.inst)->_opBase._a->width();
- v18.h = (*_instRunCtxt.inst)->_opBase._a->height();
- v18.pixels = (*_instRunCtxt.inst)->_opBase._a->getFrameData((*_instRunCtxt.inst)->_opBase._a->_frame);
-
- if ((*_instRunCtxt.inst)->_flags & kInstMaskedPut) {
- uint16 _si = _gfx->queryMask((*_instRunCtxt.inst)->_opB._value);
- _gfx->blitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, _si, Gfx::kBitBack);
- _gfx->blitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, _si, Gfx::kBit2);
- } else {
- _gfx->flatBlitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, Gfx::kBitBack);
- _gfx->flatBlitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, Gfx::kBit2);
- }
-}
-
-DECLARE_INSTRUCTION_OPCODE(null) {
-
-}
-
-DECLARE_INSTRUCTION_OPCODE(invalid) {
- error("Can't execute invalid opcode %i", (*_instRunCtxt.inst)->_index);
-}
-
-DECLARE_INSTRUCTION_OPCODE(call) {
- callFunction((*_instRunCtxt.inst)->_opBase._index, 0);
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(wait) {
- if (_engineFlags & kEngineWalking)
- _instRunCtxt.suspend = true;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(start) {
-// v1C = (*_instRunCtxt.inst)->_opBase;
- (*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(sound) {
- _activeZone = (*_instRunCtxt.inst)->_opBase._z;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(move) {
- WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue);
- addJob(&jobWalk, v4, kPriority19 );
- _engineFlags |= kEngineWalking;
-}
-
-DECLARE_INSTRUCTION_OPCODE(end) {
- if ((_instRunCtxt.a->_flags & kFlagsLooping) == 0) {
- _instRunCtxt.a->_flags &= ~kFlagsActing;
- runCommands(_instRunCtxt.a->_commands, _instRunCtxt.a);
- }
- _instRunCtxt.a->_program->_ip = _instRunCtxt.a->_program->_instructions.begin();
-
- _instRunCtxt.suspend = true;
-}
-
-
-
-void jobRunScripts(void *parm, Job *j) {
- debugC(3, kDebugJobs, "jobRunScripts");
-
- static uint16 modCounter = 0;
-
- for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
-
- Animation *a = *it;
-
- if (a->_flags & kFlagsCharacter) a->_z = a->_top + a->height();
-
- if ((a->_flags & kFlagsActing) == 0) continue;
- InstructionList::iterator inst = a->_program->_ip;
-
- while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) {
-
- debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _vm->_instructionNamesRes[(*inst)->_index - 1]);
-
- _vm->_instRunCtxt.inst = inst;
- _vm->_instRunCtxt.a = a;
- _vm->_instRunCtxt.modCounter = modCounter;
- _vm->_instRunCtxt.suspend = false;
-
- (_vm->*(_vm->_instructionOpcodes)[(*inst)->_index])();
-
- inst = _vm->_instRunCtxt.inst; // handles endloop correctly
-
- if (_vm->_instRunCtxt.suspend)
- goto label1;
-
- inst++;
- }
-
- a->_program->_ip = ++inst;
-
-label1:
- if (a->_flags & kFlagsCharacter)
- a->_z = a->_top + a->height();
- }
-
- _vm->sortAnimations();
- modCounter++;
-
- return;
-}
-
-void wrapLocalVar(LocalVariable *local) {
-// printf("wrapLocalVar(v: %i, min: %i, max: %i)\n", local->_value, local->_min, local->_max);
-
- if (local->_value >= local->_max)
- local->_value = local->_min;
- if (local->_value < local->_min)
- local->_value = local->_max - 1;
-
- return;
-}
-
-int compareAnimationZ(const AnimationPointer &a1, const AnimationPointer &a2) {
- if (a1->_z == a2->_z) return 0;
- return (a1->_z < a2->_z ? -1 : 1);
-}
-
-
-void Parallaction::sortAnimations() {
- _char._ani._z = _char._ani.height() + _char._ani._top;
- _animations.sort(compareAnimationZ);
- return;
-}
-
-Animation::Animation() {
- _cnv = NULL;
- _program = NULL;
- _scriptName = 0;
- _frame = 0;
- _z = 0;
-}
-
-Animation::~Animation() {
- if (_program)
- delete _program;
-
- if (_scriptName)
- free(_scriptName);
-
- if (_cnv)
- delete _cnv;
-}
-
-uint16 Animation::width() const {
- if (!_cnv) return 0;
- return _cnv->_width;
-}
-
-uint16 Animation::height() const {
- if (!_cnv) return 0;
- return _cnv->_height;
-}
-
-uint16 Animation::getFrameNum() const {
- if (!_cnv) return 0;
- return _cnv->_count;
-}
-
-byte* Animation::getFrameData(uint32 index) const {
- if (!_cnv) return NULL;
- return _cnv->getFramePtr(index);
-}
-
-
-Program::Program() {
- _loopCounter = 0;
- _locals = new LocalVariable[10];
-}
-
-Program::~Program() {
- delete[] _locals;
-}
-
-
-} // namespace Parallaction
Deleted: scummvm/trunk/engines/parallaction/commands.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/commands.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/commands.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,421 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "parallaction/parallaction.h"
-
-
-namespace Parallaction {
-
-#define CMD_SET 1
-#define CMD_CLEAR 2
-#define CMD_START 3
-#define CMD_SPEAK 4
-#define CMD_GET 5
-#define CMD_LOCATION 6
-#define CMD_OPEN 7
-#define CMD_CLOSE 8
-#define CMD_ON 9
-#define CMD_OFF 10
-#define CMD_CALL 11
-#define CMD_TOGGLE 12
-#define CMD_DROP 13
-#define CMD_QUIT 14
-#define CMD_MOVE 15
-#define CMD_STOP 16
-
-DECLARE_COMMAND_PARSER(flags) {
- createCommand(_lookup);
-
- if (_globalTable->lookup(_tokens[1]) == Table::notFound) {
- do {
- char _al = _localFlagNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
- _cmdParseCtxt.cmd->u._flags |= 1 << (_al - 1);
- } while (!scumm_stricmp(_tokens[_cmdParseCtxt.nextToken++], "|"));
- _cmdParseCtxt.nextToken--;
- } else {
- _cmdParseCtxt.cmd->u._flags |= kFlagsGlobal;
- do {
- char _al = _globalTable->lookup(_tokens[1]);
- _cmdParseCtxt.nextToken++;
- _cmdParseCtxt.cmd->u._flags |= 1 << (_al - 1);
- } while (!scumm_stricmp(_tokens[_cmdParseCtxt.nextToken++], "|"));
- _cmdParseCtxt.nextToken--;
- }
-
- parseCommandFlags();
- addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(animation) {
- createCommand(_lookup);
-
- _cmdParseCtxt.cmd->u._animation = findAnimation(_tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
- if (_cmdParseCtxt.cmd->u._animation == NULL) {
- strcpy(_forwardedAnimationNames[_numForwards], _tokens[_cmdParseCtxt.nextToken-1]);
- _forwardedCommands[_numForwards] = _cmdParseCtxt.cmd;
- _numForwards++;
- }
-
- parseCommandFlags();
- addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(zone) {
- createCommand(_lookup);
-
- _cmdParseCtxt.cmd->u._zone = findZone(_tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
-
- parseCommandFlags();
- addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(location) {
- createCommand(_lookup);
-
- _cmdParseCtxt.cmd->u._string = (char*)malloc(strlen(_tokens[_cmdParseCtxt.nextToken])+1);
- strcpy(_cmdParseCtxt.cmd->u._string, _tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
-
- parseCommandFlags();
- addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(drop) {
- createCommand(_lookup);
-
- _cmdParseCtxt.cmd->u._object = _objectsNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
-
- parseCommandFlags();
- addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(call) {
- createCommand(_lookup);
-
- _cmdParseCtxt.cmd->u._callable = _callableNames->lookup(_tokens[_cmdParseCtxt.nextToken]) - 1;
- _cmdParseCtxt.nextToken++;
-
- parseCommandFlags();
- addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(null) {
-}
-
-
-DECLARE_COMMAND_PARSER(move) {
- createCommand(_lookup);
-
- _cmdParseCtxt.cmd->u._move._x = atoi(_tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
- _cmdParseCtxt.cmd->u._move._y = atoi(_tokens[_cmdParseCtxt.nextToken]);
- _cmdParseCtxt.nextToken++;
-
- parseCommandFlags();
- addCommand();
-}
-
-DECLARE_COMMAND_PARSER(invalid) {
- error("Can't parse unknown command '%s'", _tokens[0]);
-}
-
-DECLARE_COMMAND_PARSER(endcommands) {
- popParserTables();
-}
-
-void Parallaction::parseCommandFlags() {
-
- int _si = _cmdParseCtxt.nextToken;
- Command *cmd = _cmdParseCtxt.cmd;
-
- if (!scumm_stricmp(_tokens[_si], "flags")) {
- _si++;
-
- do {
- if (!scumm_stricmp(_tokens[_si], "exit") || !scumm_stricmp(_tokens[_si], "exittrap")) {
- cmd->_flagsOn |= kFlagsExit;
- } else
- if (!scumm_stricmp(_tokens[_si], "enter") || !scumm_stricmp(_tokens[_si], "entertrap")) {
- cmd->_flagsOn |= kFlagsEnter;
- } else
- if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
- byte _al = _localFlagNames->lookup(&_tokens[_si][2]);
- cmd->_flagsOff |= 1 << (_al - 1);
- } else {
- byte _al = _localFlagNames->lookup(_tokens[_si]);
- cmd->_flagsOn |= 1 << (_al - 1);
- }
-
- _si++;
-
- } while (!scumm_stricmp(_tokens[_si++], "|"));
-
- }
-
- if (!scumm_stricmp(_tokens[_si], "gflags")) {
- _si++;
- cmd->_flagsOn |= kFlagsGlobal;
-
- do {
- if (!scumm_stricmp(_tokens[_si], "exit")) {
- cmd->_flagsOn |= kFlagsExit;
- } else
- if (!scumm_stricmp(_tokens[_si], "enter")) {
- cmd->_flagsOn |= kFlagsEnter;
- } else
- if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
- byte _al = _globalTable->lookup(&_tokens[_si][2]);
- cmd->_flagsOff |= 1 << (_al - 1);
- } else {
- byte _al = _globalTable->lookup(_tokens[_si]);
- cmd->_flagsOn |= 1 << (_al - 1);
- }
-
- _si++;
-
- } while (!scumm_stricmp(_tokens[_si++], "|"));
-
- }
-
- _si = _cmdParseCtxt.nextToken;
-
-}
-
-void Parallaction::addCommand() {
-
- // FIXME: implement a proper parseCommands for BRA
- if (getGameType() == GType_BRA)
- delete _cmdParseCtxt.cmd;
- else
- _cmdParseCtxt.list->push_front(_cmdParseCtxt.cmd); // NOTE: command lists are written backwards in scripts
-
-}
-
-void Parallaction::createCommand(uint id) {
-
- _cmdParseCtxt.nextToken = 1;
- _cmdParseCtxt.cmd = new Command;
- _cmdParseCtxt.cmd->_id = id;
-
-}
-
-void Parallaction::parseCommands(Script &script, CommandList& list) {
-
- _cmdParseCtxt.list = &list;
- _cmdParseCtxt.end = false;
-
- pushParserTables(_commandParsers, _commandsNames);
-
-}
-
-DECLARE_COMMAND_OPCODE(invalid) {
- error("Can't execute invalid command '%i'", _cmdRunCtxt.cmd->_id);
-}
-
-DECLARE_COMMAND_OPCODE(set) {
- if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
- _cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
- _commandFlags |= _cmdRunCtxt.cmd->u._flags;
- } else {
- _localFlags[_currentLocationIndex] |= _cmdRunCtxt.cmd->u._flags;
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(clear) {
- if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
- _cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
- _commandFlags &= ~_cmdRunCtxt.cmd->u._flags;
- } else {
- _localFlags[_currentLocationIndex] &= ~_cmdRunCtxt.cmd->u._flags;
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(start) {
- _cmdRunCtxt.cmd->u._animation->_flags |= kFlagsActing;
-}
-
-
-DECLARE_COMMAND_OPCODE(speak) {
- _activeZone = _cmdRunCtxt.cmd->u._zone;
-}
-
-
-DECLARE_COMMAND_OPCODE(get) {
- _cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsFixed;
- if (!runZone(_cmdRunCtxt.cmd->u._zone)) {
- runCommands(_cmdRunCtxt.cmd->u._zone->_commands);
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(location) {
- strcpy(_location._name, _cmdRunCtxt.cmd->u._string);
- _engineFlags |= kEngineChangeLocation;
-}
-
-
-DECLARE_COMMAND_OPCODE(open) {
- _cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsClosed;
- if (_cmdRunCtxt.cmd->u._zone->u.door->_cnv) {
- addJob(&jobToggleDoor, (void*)_cmdRunCtxt.cmd->u._zone, kPriority18 );
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(close) {
- _cmdRunCtxt.cmd->u._zone->_flags |= kFlagsClosed;
- if (_cmdRunCtxt.cmd->u._zone->u.door->_cnv) {
- addJob(&jobToggleDoor, (void*)_cmdRunCtxt.cmd->u._zone, kPriority18 );
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(on) {
- // WORKAROUND: the original DOS-based engine didn't check u->_zone before dereferencing
- // the pointer to get structure members, thus leading to crashes in systems with memory
- // protection.
- // As a side note, the overwritten address is the 5th entry in the DOS interrupt table
- // (print screen handler): this suggests that a system would hang when the print screen
- // key is pressed after playing Nippon Safes, provided that this code path is taken.
- if (_cmdRunCtxt.cmd->u._zone != NULL) {
- _cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsRemove;
- _cmdRunCtxt.cmd->u._zone->_flags |= kFlagsActive;
- if ((_cmdRunCtxt.cmd->u._zone->_type & 0xFFFF) == kZoneGet) {
- addJob(&jobDisplayDroppedItem, _cmdRunCtxt.cmd->u._zone, kPriority17 );
- }
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(off) {
- _cmdRunCtxt.cmd->u._zone->_flags |= kFlagsRemove;
-}
-
-
-DECLARE_COMMAND_OPCODE(call) {
- callFunction(_cmdRunCtxt.cmd->u._callable, _cmdRunCtxt.z);
-}
-
-
-DECLARE_COMMAND_OPCODE(toggle) {
- if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
- _cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
- _commandFlags ^= _cmdRunCtxt.cmd->u._flags;
- } else {
- _localFlags[_currentLocationIndex] ^= _cmdRunCtxt.cmd->u._flags;
- }
-}
-
-
-DECLARE_COMMAND_OPCODE(drop){
- dropItem( _cmdRunCtxt.cmd->u._object );
-}
-
-
-DECLARE_COMMAND_OPCODE(quit) {
- _engineFlags |= kEngineQuit;
-}
-
-
-DECLARE_COMMAND_OPCODE(move) {
- if ((_char._ani._flags & kFlagsRemove) || (_char._ani._flags & kFlagsActive) == 0) {
- return;
- }
-
- WalkNodeList *vC = _char._builder.buildPath(_cmdRunCtxt.cmd->u._move._x, _cmdRunCtxt.cmd->u._move._y);
-
- addJob(&jobWalk, vC, kPriority19 );
- _engineFlags |= kEngineWalking;
-}
-
-
-DECLARE_COMMAND_OPCODE(stop) {
- _cmdRunCtxt.cmd->u._animation->_flags &= ~kFlagsActing;
-}
-
-
-
-
-void Parallaction::runCommands(CommandList& list, Zone *z) {
- debugC(1, kDebugLocation, "runCommands");
-
- CommandList::iterator it = list.begin();
- for ( ; it != list.end(); it++) {
-
- Command *cmd = *it;
- uint32 v8 = _localFlags[_currentLocationIndex];
-
- if (_engineFlags & kEngineQuit)
- break;
-
- if (cmd->_flagsOn & kFlagsGlobal) {
- v8 = _commandFlags | kFlagsGlobal;
- }
-
- if ((cmd->_flagsOn & v8) != cmd->_flagsOn) continue;
- if ((cmd->_flagsOff & ~v8) != cmd->_flagsOff) continue;
-
- debugC(1, kDebugLocation, "runCommands: %s (on: %x, off: %x)", _commandsNamesRes[cmd->_id-1], cmd->_flagsOn, cmd->_flagsOff);
-
- _cmdRunCtxt.z = z;
- _cmdRunCtxt.cmd = cmd;
-
- (this->*_commandOpcodes[cmd->_id])();
- }
-
- debugC(1, kDebugLocation, "runCommands completed");
-
- return;
-
-}
-
-Command::Command() {
- _id = 0;
- _flagsOn = 0;
- _flagsOff = 0;
-}
-
-Command::~Command() {
-
-}
-
-} // namespace Parallaction
-
-
-
Deleted: scummvm/trunk/engines/parallaction/commands.h
===================================================================
--- scummvm/trunk/engines/parallaction/commands.h 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/commands.h 2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,92 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PARALLACTION_COMMANDS_H
-#define PARALLACTION_COMMANDS_H
-
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-
-#include "parallaction/defs.h"
-
-namespace Parallaction {
-
-enum CommandFlags {
- kFlagsVisited = 1,
- kFlagsExit = 0x10000000,
- kFlagsEnter = 0x20000000,
- kFlagsGlobal = 0x40000000
-};
-
-struct Zone;
-struct Animation;
-
-
-// TODO: turn this into a struct
-struct CommandData {
- uint32 _flags;
- Animation * _animation;
- Zone* _zone;
- char* _string;
- uint16 _callable;
- uint16 _object;
- struct {
- int16 _x;
- int16 _y;
- } _move;
-
- CommandData() {
- _flags = 0;
- _animation = 0;
- _zone = 0;
- _string = 0;
- _callable = 0;
- _object = 0;
- _move._x = 0;
- _move._y = 0;
- }
-
- ~CommandData() {
- if (_string)
- free(_string);
- }
-};
-
-struct Command {
- uint16 _id;
- CommandData u;
- uint32 _flagsOn;
- uint32 _flagsOff;
-
- Command();
- ~Command();
-};
-
-typedef ManagedList<Command*> CommandList;
-
-} // namespace Parallaction
-
-#endif
Modified: scummvm/trunk/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/dialogue.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/dialogue.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -56,132 +56,6 @@
-Dialogue *Parallaction::parseDialogue(Script &script) {
-// printf("parseDialogue()\n");
- uint16 numQuestions = 0;
-
- Dialogue *dialogue = new Dialogue;
-
- Table forwards(20);
-
- fillBuffers(script, true);
-
- while (scumm_stricmp(_tokens[0], "enddialogue")) {
- if (scumm_stricmp(_tokens[0], "Question")) continue;
-
- Question *question = new Question;
- dialogue->_questions[numQuestions] = question;
-
- forwards.addData(_tokens[1]);
-
- question->_text = parseDialogueString(script);
-
- fillBuffers(script, true);
- question->_mood = atoi(_tokens[0]);
-
- uint16 numAnswers = 0;
-
- fillBuffers(script, true);
- while (scumm_stricmp(_tokens[0], "endquestion")) { // parse answers
-
- Answer *answer = new Answer;
- question->_answers[numAnswers] = answer;
-
- if (_tokens[1][0]) {
-
- Table* flagNames;
- uint16 token;
-
- if (!scumm_stricmp(_tokens[1], "global")) {
- token = 2;
- flagNames = _globalTable;
- answer->_yesFlags |= kFlagsGlobal;
- } else {
- token = 1;
- flagNames = _localFlagNames;
- }
-
- do {
-
- if (!scumm_strnicmp(_tokens[token], "no", 2)) {
- byte _al = flagNames->lookup(_tokens[token]+2);
- answer->_noFlags |= 1 << (_al - 1);
- } else {
- byte _al = flagNames->lookup(_tokens[token]);
- answer->_yesFlags |= 1 << (_al - 1);
- }
-
- token++;
-
- } while (!scumm_stricmp(_tokens[token++], "|"));
-
- }
-
- answer->_text = parseDialogueString(script);
-
- fillBuffers(script, true);
- answer->_mood = atoi(_tokens[0]);
- answer->_following._name = parseDialogueString(script);
-
- fillBuffers(script, true);
- if (!scumm_stricmp(_tokens[0], "commands")) {
- parseCommands(script, answer->_commands);
- fillBuffers(script, true);
- }
-
- numAnswers++;
- }
-
- fillBuffers(script, true);
- numQuestions++;
-
- }
-
- // link questions
- byte v50[20];
- memset(v50, 0, 20);
-
- for (uint16 i = 0; i < numQuestions; i++) {
- Question *question = dialogue->_questions[i];
-
- for (uint16 j = 0; j < NUM_ANSWERS; j++) {
- Answer *answer = question->_answers[j];
- if (answer == 0) continue;
-
- int16 index = forwards.lookup(answer->_following._name);
- free(answer->_following._name);
-
- if (index == Table::notFound)
- answer->_following._question = 0;
- else
- answer->_following._question = dialogue->_questions[index - 1];
-
-
- }
- }
-
- return dialogue;
-}
-
-
-char *Parallaction::parseDialogueString(Script &script) {
-
- char vC8[200];
- char *vD0 = NULL;
- do {
-
- vD0 = script.readLine(vC8, 200);
- if (vD0 == 0) return NULL;
-
- vD0 = Common::ltrim(vD0);
-
- } while (strlen(vD0) == 0);
-
- vD0[strlen(vD0)-1] = '\0'; // deletes the trailing '0xA'
- // this is critical for Gfx::displayWrappedString to work properly
- return strdup(vD0);
-}
-
class DialogueManager {
Parallaction *_vm;
@@ -502,34 +376,5 @@
return;
}
-Answer::Answer() {
- _text = NULL;
- _mood = 0;
- _following._question = NULL;
- _noFlags = 0;
- _yesFlags = 0;
-}
-Answer::~Answer() {
- if (_text)
- free(_text);
-}
-
-Question::Question() {
- _text = NULL;
- _mood = 0;
-
- for (uint32 i = 0; i < NUM_ANSWERS; i++)
- _answers[i] = NULL;
-
-}
-
-Question::~Question() {
-
- for (uint32 i = 0; i < NUM_ANSWERS; i++)
- if (_answers[i]) delete _answers[i];
-
- free(_text);
-}
-
} // namespace Parallaction
Modified: scummvm/trunk/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_br.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/disk_br.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -102,7 +102,15 @@
Script* DosDisk_br::loadScript(const char* name) {
debugC(5, kDebugDisk, "DosDisk_br::loadScript");
- return 0;
+
+ Common::File *stream = new Common::File;
+
+ char path[PATH_LEN];
+ sprintf(path, "%s/scripts/%s.scr", _partPath, name);
+ if (!stream->open(path))
+ errorFileNotFound(path);
+
+ return new Script(stream, true);
}
// there are no Head resources in Big Red Adventure
@@ -275,7 +283,7 @@
stream.close();
- return 0;
+ return t;
}
Common::SeekableReadStream* DosDisk_br::loadMusic(const char* name) {
Added: scummvm/trunk/engines/parallaction/exec_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/exec_ns.cpp (rev 0)
+++ scummvm/trunk/engines/parallaction/exec_ns.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -0,0 +1,857 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "parallaction/parallaction.h"
+#include "parallaction/sound.h"
+
+
+namespace Parallaction {
+
+#define INST_ON 1
+#define INST_OFF 2
+#define INST_X 3
+#define INST_Y 4
+#define INST_Z 5
+#define INST_F 6
+#define INST_LOOP 7
+#define INST_ENDLOOP 8
+#define INST_SHOW 9
+#define INST_INC 10
+#define INST_DEC 11
+#define INST_SET 12
+#define INST_PUT 13
+#define INST_CALL 14
+#define INST_WAIT 15
+#define INST_START 16
+#define INST_SOUND 17
+#define INST_MOVE 18
+#define INST_END 19
+
+
+typedef OpcodeImpl<Parallaction_ns> OpcodeV1;
+#define COMMAND_OPCODE(op) OpcodeV1(this, &Parallaction_ns::cmdOp_##op)
+#define DECLARE_COMMAND_OPCODE(op) void Parallaction_ns::cmdOp_##op()
+
+#define INSTRUCTION_OPCODE(op) OpcodeV1(this, &Parallaction_ns::instOp_##op)
+#define DECLARE_INSTRUCTION_OPCODE(op) void Parallaction_ns::instOp_##op()
+
+
+
+
+DECLARE_INSTRUCTION_OPCODE(on) {
+ (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive;
+ (*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(off) {
+ (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsRemove;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(loop) {
+ if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) {
+ _instRunCtxt.a->_program->_loopCounter = (*_instRunCtxt.inst)->_opBase._loopCounter._value;
+ } else {
+ _instRunCtxt.a->_program->_loopCounter = *(*_instRunCtxt.inst)->_opBase._loopCounter._pvalue;
+ }
+ _instRunCtxt.a->_program->_loopStart = _instRunCtxt.inst;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(endloop) {
+ if (--_instRunCtxt.a->_program->_loopCounter > 0) {
+ _instRunCtxt.inst = _instRunCtxt.a->_program->_loopStart;
+ }
+}
+
+DECLARE_INSTRUCTION_OPCODE(inc) {
+ int16 _si = 0;
+ int16 _ax = 0, _bx = 0;
+ if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) {
+ _si = (*_instRunCtxt.inst)->_opB._value;
+ } else {
+ _si = *(*_instRunCtxt.inst)->_opB._pvalue;
+ }
+ if ((*_instRunCtxt.inst)->_flags & kInstMod) { // mod
+ _bx = (_si > 0 ? _si : -_si);
+ if (_instRunCtxt.modCounter % _bx != 0) return;
+
+ _si = (_si > 0 ? 1 : -1);
+ }
+ if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) { // local
+ if ((*_instRunCtxt.inst)->_index == INST_INC) _ax = _si;
+ else _ax = -_si;
+
+ (*_instRunCtxt.inst)->_opA._local->_value += _ax;
+ wrapLocalVar((*_instRunCtxt.inst)->_opA._local);
+ return;
+ }
+
+ // built-in variable (x, y, z, f)
+ if ((*_instRunCtxt.inst)->_index == INST_INC) _ax = _si;
+ else _ax = -_si;
+ *(*_instRunCtxt.inst)->_opA._pvalue += _ax;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(set) {
+ int16 _si;
+ if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) {
+ _si = (*_instRunCtxt.inst)->_opB._value;
+ } else {
+ _si = *(*_instRunCtxt.inst)->_opB._pvalue;
+ }
+
+ if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) {
+ (*_instRunCtxt.inst)->_opA._local->_value = _si;
+ } else {
+ *(*_instRunCtxt.inst)->_opA._pvalue = _si;
+ }
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(put) {
+ Graphics::Surface v18;
+ v18.w = (*_instRunCtxt.inst)->_opBase._a->width();
+ v18.h = (*_instRunCtxt.inst)->_opBase._a->height();
+ v18.pixels = (*_instRunCtxt.inst)->_opBase._a->getFrameData((*_instRunCtxt.inst)->_opBase._a->_frame);
+
+ if ((*_instRunCtxt.inst)->_flags & kInstMaskedPut) {
+ uint16 _si = _gfx->queryMask((*_instRunCtxt.inst)->_opB._value);
+ _gfx->blitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, _si, Gfx::kBitBack);
+ _gfx->blitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, _si, Gfx::kBit2);
+ } else {
+ _gfx->flatBlitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, Gfx::kBitBack);
+ _gfx->flatBlitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, Gfx::kBit2);
+ }
+}
+
+DECLARE_INSTRUCTION_OPCODE(null) {
+
+}
+
+DECLARE_INSTRUCTION_OPCODE(invalid) {
+ error("Can't execute invalid opcode %i", (*_instRunCtxt.inst)->_index);
+}
+
+DECLARE_INSTRUCTION_OPCODE(call) {
+ callFunction((*_instRunCtxt.inst)->_opBase._index, 0);
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(wait) {
+ if (_engineFlags & kEngineWalking)
+ _instRunCtxt.suspend = true;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(start) {
+ (*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(sound) {
+ _activeZone = (*_instRunCtxt.inst)->_opBase._z;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(move) {
+ WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue);
+ addJob(&jobWalk, v4, kPriority19 );
+ _engineFlags |= kEngineWalking;
+}
+
+DECLARE_INSTRUCTION_OPCODE(end) {
+ if ((_instRunCtxt.a->_flags & kFlagsLooping) == 0) {
+ _instRunCtxt.a->_flags &= ~kFlagsActing;
+ runCommands(_instRunCtxt.a->_commands, _instRunCtxt.a);
+ }
+ _instRunCtxt.a->_program->_ip = _instRunCtxt.a->_program->_instructions.begin();
+
+ _instRunCtxt.suspend = true;
+}
+
+
+
+void Parallaction_ns::wrapLocalVar(LocalVariable *local) {
+
+ if (local->_value >= local->_max)
+ local->_value = local->_min;
+ if (local->_value < local->_min)
+ local->_value = local->_max - 1;
+
+ return;
+}
+
+
+DECLARE_COMMAND_OPCODE(invalid) {
+ error("Can't execute invalid command '%i'", _cmdRunCtxt.cmd->_id);
+}
+
+DECLARE_COMMAND_OPCODE(set) {
+ if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
+ _cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
+ _commandFlags |= _cmdRunCtxt.cmd->u._flags;
+ } else {
+ _localFlags[_currentLocationIndex] |= _cmdRunCtxt.cmd->u._flags;
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(clear) {
+ if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
+ _cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
+ _commandFlags &= ~_cmdRunCtxt.cmd->u._flags;
+ } else {
+ _localFlags[_currentLocationIndex] &= ~_cmdRunCtxt.cmd->u._flags;
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(start) {
+ _cmdRunCtxt.cmd->u._animation->_flags |= kFlagsActing;
+}
+
+
+DECLARE_COMMAND_OPCODE(speak) {
+ _activeZone = _cmdRunCtxt.cmd->u._zone;
+}
+
+
+DECLARE_COMMAND_OPCODE(get) {
+ _cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsFixed;
+ if (!runZone(_cmdRunCtxt.cmd->u._zone)) {
+ runCommands(_cmdRunCtxt.cmd->u._zone->_commands);
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(location) {
+ strcpy(_location._name, _cmdRunCtxt.cmd->u._string);
+ _engineFlags |= kEngineChangeLocation;
+}
+
+
+DECLARE_COMMAND_OPCODE(open) {
+ _cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsClosed;
+ if (_cmdRunCtxt.cmd->u._zone->u.door->_cnv) {
+ addJob(&jobToggleDoor, (void*)_cmdRunCtxt.cmd->u._zone, kPriority18 );
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(close) {
+ _cmdRunCtxt.cmd->u._zone->_flags |= kFlagsClosed;
+ if (_cmdRunCtxt.cmd->u._zone->u.door->_cnv) {
+ addJob(&jobToggleDoor, (void*)_cmdRunCtxt.cmd->u._zone, kPriority18 );
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(on) {
+ // WORKAROUND: the original DOS-based engine didn't check u->_zone before dereferencing
+ // the pointer to get structure members, thus leading to crashes in systems with memory
+ // protection.
+ // As a side note, the overwritten address is the 5th entry in the DOS interrupt table
+ // (print screen handler): this suggests that a system would hang when the print screen
+ // key is pressed after playing Nippon Safes, provided that this code path is taken.
+ if (_cmdRunCtxt.cmd->u._zone != NULL) {
+ _cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsRemove;
+ _cmdRunCtxt.cmd->u._zone->_flags |= kFlagsActive;
+ if ((_cmdRunCtxt.cmd->u._zone->_type & 0xFFFF) == kZoneGet) {
+ addJob(&jobDisplayDroppedItem, _cmdRunCtxt.cmd->u._zone, kPriority17 );
+ }
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(off) {
+ _cmdRunCtxt.cmd->u._zone->_flags |= kFlagsRemove;
+}
+
+
+DECLARE_COMMAND_OPCODE(call) {
+ callFunction(_cmdRunCtxt.cmd->u._callable, _cmdRunCtxt.z);
+}
+
+
+DECLARE_COMMAND_OPCODE(toggle) {
+ if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
+ _cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
+ _commandFlags ^= _cmdRunCtxt.cmd->u._flags;
+ } else {
+ _localFlags[_currentLocationIndex] ^= _cmdRunCtxt.cmd->u._flags;
+ }
+}
+
+
+DECLARE_COMMAND_OPCODE(drop){
+ dropItem( _cmdRunCtxt.cmd->u._object );
+}
+
+
+DECLARE_COMMAND_OPCODE(quit) {
+ _engineFlags |= kEngineQuit;
+}
+
+
+DECLARE_COMMAND_OPCODE(move) {
+ if ((_char._ani._flags & kFlagsRemove) || (_char._ani._flags & kFlagsActive) == 0) {
+ return;
+ }
+
+ WalkNodeList *vC = _char._builder.buildPath(_cmdRunCtxt.cmd->u._move.x, _cmdRunCtxt.cmd->u._move.y);
+
+ addJob(&jobWalk, vC, kPriority19 );
+ _engineFlags |= kEngineWalking;
+}
+
+
+DECLARE_COMMAND_OPCODE(stop) {
+ _cmdRunCtxt.cmd->u._animation->_flags &= ~kFlagsActing;
+}
+
+
+void jobDisplayAnimations(void *parm, Job *j) {
+
+ Graphics::Surface v14;
+
+ uint16 _si = 0;
+
+ for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+
+ Animation *v18 = *it;
+
+ if ((v18->_flags & kFlagsActive) && ((v18->_flags & kFlagsRemove) == 0)) {
+ v14.w = v18->width();
+ v14.h = v18->height();
+
+ int16 frame = CLIP((int)v18->_frame, 0, v18->getFrameNum()-1);
+
+ v14.pixels = v18->getFrameData(frame);
+
+ if (v18->_flags & kFlagsNoMasked)
+ _si = 3;
+ else
+ _si = _vm->_gfx->queryMask(v18->_top + v18->height());
+
+ debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, f:%i/%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14.w, v14.h,
+ frame, v18->getFrameNum(), v14.pixels);
+ _vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack);
+
+ }
+
+ if (((v18->_flags & kFlagsActive) == 0) && (v18->_flags & kFlagsRemove)) {
+ v18->_flags &= ~kFlagsRemove;
+ v18->_oldPos.x = -1000;
+ }
+
+ if ((v18->_flags & kFlagsActive) && (v18->_flags & kFlagsRemove)) {
+ v18->_flags &= ~kFlagsActive;
+ v18->_flags |= kFlagsRemove;
+ }
+
+ }
+
+// printf("done\n");
+
+ return;
+}
+
+
+void jobEraseAnimations(void *arg_0, Job *j) {
+ debugC(3, kDebugJobs, "jobEraseAnimations");
+
+ for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+
+ Animation *a = *it;
+
+ if (((a->_flags & kFlagsActive) == 0) && ((a->_flags & kFlagsRemove) == 0)) continue;
+
+ Common::Rect r(a->width(), a->height());
+ r.moveTo(a->_oldPos);
+ _vm->_gfx->restoreBackground(r);
+
+ if (arg_0) {
+ a->_oldPos.x = a->_left;
+ a->_oldPos.y = a->_top;
+ }
+
+ }
+
+ return;
+}
+
+
+void jobRunScripts(void *parm, Job *j) {
+ debugC(3, kDebugJobs, "jobRunScripts");
+
+ static uint16 modCounter = 0;
+
+ for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+
+ Animation *a = *it;
+
+ if (a->_flags & kFlagsCharacter)
+ a->_z = a->_top + a->height();
+
+ if ((a->_flags & kFlagsActing) == 0)
+ continue;
+
+ InstructionList::iterator inst = a->_program->_ip;
+ while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) {
+
+ debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _vm->_instructionNamesRes[(*inst)->_index - 1]);
+
+ _vm->_instRunCtxt.inst = inst;
+ _vm->_instRunCtxt.a = a;
+ _vm->_instRunCtxt.modCounter = modCounter;
+ _vm->_instRunCtxt.suspend = false;
+
+ (*_vm->_instructionOpcodes[(*inst)->_index])();
+
+ inst = _vm->_instRunCtxt.inst; // handles endloop correctly
+
+ if (_vm->_instRunCtxt.suspend)
+ goto label1;
+
+ inst++;
+ }
+
+ a->_program->_ip = ++inst;
+
+label1:
+ if (a->_flags & kFlagsCharacter)
+ a->_z = a->_top + a->height();
+ }
+
+ _vm->sortAnimations();
+ modCounter++;
+
+ return;
+}
+
+
+void Parallaction::runCommands(CommandList& list, Zone *z) {
+ debugC(1, kDebugLocation, "runCommands");
+
+ CommandList::iterator it = list.begin();
+ for ( ; it != list.end(); it++) {
+
+ Command *cmd = *it;
+ uint32 v8 = _localFlags[_currentLocationIndex];
+
+ if (_engineFlags & kEngineQuit)
+ break;
+
+ if (cmd->_flagsOn & kFlagsGlobal) {
+ v8 = _commandFlags | kFlagsGlobal;
+ }
+
+ if ((cmd->_flagsOn & v8) != cmd->_flagsOn) continue;
+ if ((cmd->_flagsOff & ~v8) != cmd->_flagsOff) continue;
+
+ debugC(1, kDebugLocation, "runCommands[%i]: %s (on: %x, off: %x)", cmd->_id, _commandsNamesRes[cmd->_id-1], cmd->_flagsOn, cmd->_flagsOff);
+
+ _cmdRunCtxt.z = z;
+ _cmdRunCtxt.cmd = cmd;
+
+ (*_commandOpcodes[cmd->_id])();
+ }
+
+ debugC(1, kDebugLocation, "runCommands completed");
+
+ return;
+
+}
+
+
+
+
+// displays character head commenting an examined object
+//
+// works on the frontbuffer
+//
+void Parallaction::displayCharacterComment(ExamineData *data) {
+ if (data->_description == NULL) return;
+
+ // NOTE: saving visible screen before displaying comment allows
+ // to restore the exact situation after the comment is deleted.
+ // This means animations are restored in the exact position as
+ // they were, thus avoiding clipping effect as signalled in
+ // BUG item #1762614.
+ _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
+
+ _gfx->setFont(_dialogueFont);
+ _gfx->flatBlitCnv(_char._talk, 0, 190, 80, Gfx::kBitFront);
+
+ int16 v26, v28;
+ _gfx->getStringExtent(data->_description, 130, &v28, &v26);
+ Common::Rect r(v28, v26);
+ r.moveTo(140, 10);
+ _gfx->drawBalloon(r, 0);
+ _gfx->displayWrappedString(data->_description, 140, 10, 0, 130);
+
+ waitUntilLeftClick();
+
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+ _gfx->updateScreen();
+
+ return;
+}
+
+//
+// ZONE TYPE: EXAMINE
+//
+
+// display detail view of an item (and eventually comments)
+//
+// works on the frontbuffer
+//
+
+void Parallaction::displayItemComment(ExamineData *data) {
+
+ if (data->_description == NULL) return;
+
+ _gfx->setHalfbriteMode(true);
+
+ char v68[PATH_LEN];
+ strcpy(v68, data->_filename);
+ data->_cnv = _disk->loadStatic(v68);
+ _gfx->flatBlitCnv(data->_cnv, 140, (_screenHeight - data->_cnv->h)/2, Gfx::kBitFront);
+ delete data->_cnv;
+
+ int16 v6A = 0, v6C = 0;
+
+ _gfx->setFont(_dialogueFont);
+ _gfx->getStringExtent(data->_description, 130, &v6C, &v6A);
+ Common::Rect r(v6C, v6A);
+ r.moveTo(0, 90);
+ _gfx->drawBalloon(r, 0);
+ _gfx->flatBlitCnv(_char._head, 100, 152, Gfx::kBitFront);
+ _gfx->displayWrappedString(data->_description, 0, 90, 0, 130);
+
+ jobEraseAnimations((void*)1, NULL);
+ _gfx->updateScreen();
+
+ waitUntilLeftClick();
+
+ _gfx->setHalfbriteMode(false);
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+ _gfx->updateScreen();
+
+ return;
+}
+
+
+
+uint16 Parallaction::runZone(Zone *z) {
+ debugC(3, kDebugLocation, "runZone (%s)", z->_label._text);
+
+ uint16 subtype = z->_type & 0xFFFF;
+
+ debugC(3, kDebugLocation, "type = %x, object = %x", subtype, (z->_type & 0xFFFF0000) >> 16);
+ switch(subtype) {
+
+ case kZoneExamine:
+ if (z->u.examine->_filename) {
+ displayItemComment(z->u.examine);
+ } else {
+ displayCharacterComment(z->u.examine);
+ }
+ break;
+
+ case kZoneGet:
+ if (z->_flags & kFlagsFixed) break;
+ if (pickupItem(z) != 0) {
+ return 1;
+ }
+ z->_flags |= kFlagsRemove;
+ break;
+
+ case kZoneDoor:
+ if (z->_flags & kFlagsLocked) break;
+ z->_flags ^= kFlagsClosed;
+ if (z->u.door->_cnv == NULL) break;
+ addJob(&jobToggleDoor, z, kPriority18 );
+ break;
+
+ case kZoneHear:
+ _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60);
+ break;
+
+ case kZoneSpeak:
+ runDialogue(z->u.speak);
+ break;
+
+ }
+
+ debugC(3, kDebugLocation, "runZone completed");
+
+ return 0;
+}
+
+//
+// ZONE TYPE: DOOR
+//
+void jobToggleDoor(void *parm, Job *j) {
+
+ static byte count = 0;
+
+ Zone *z = (Zone*)parm;
+
+ if (z->u.door->_cnv) {
+ Common::Rect r(z->_left, z->_top, z->_left+z->u.door->_cnv->_width, z->_top+z->u.door->_cnv->_height);
+
+ uint16 _ax = (z->_flags & kFlagsClosed ? 1 : 0);
+ _vm->_gfx->restoreDoorBackground(r, z->u.door->_cnv->getFramePtr(_ax), z->u.door->_background);
+
+ _ax = (z->_flags & kFlagsClosed ? 0 : 1);
+ _vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
+ _vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBit2);
+ }
+
+ count++;
+ if (count == 2) {
+ j->_finished = 1;
+ count = 0;
+ }
+
+ return;
+}
+
+
+
+//
+// ZONE TYPE: GET
+//
+
+int16 Parallaction::pickupItem(Zone *z) {
+ int r = addInventoryItem(z->u.get->_icon);
+ if (r == 0)
+ addJob(&jobRemovePickedItem, z, kPriority17 );
+
+ return r;
+}
+
+void jobRemovePickedItem(void *parm, Job *j) {
+
+ Zone *z = (Zone*)parm;
+
+ static uint16 count = 0;
+
+ if (z->u.get->_cnv) {
+ Common::Rect r(z->_left, z->_top, z->_left + z->u.get->_cnv->w, z->_top + z->u.get->_cnv->h);
+
+ _vm->_gfx->restoreGetBackground(r, z->u.get->_backup);
+ }
+
+ count++;
+ if (count == 2) {
+ count = 0;
+ j->_finished = 1;
+ }
+
+ return;
+}
+
+void jobDisplayDroppedItem(void *parm, Job *j) {
+// printf("jobDisplayDroppedItem...");
+
+ Zone *z = (Zone*)parm;
+
+ if (z->u.get->_cnv) {
+ if (j->_count == 0) {
+ _vm->_gfx->backupGetBackground(z->u.get, z->_left, z->_top);
+ }
+
+ _vm->_gfx->flatBlitCnv(z->u.get->_cnv, z->_left, z->_top, Gfx::kBitBack);
+ _vm->_gfx->flatBlitCnv(z->u.get->_cnv, z->_left, z->_top, Gfx::kBit2);
+ }
+
+ j->_count++;
+ if (j->_count == 2) {
+ j->_count = 0;
+ j->_finished = 1;
+ }
+
+// printf("done");
+
+ return;
+}
+
+
+
+
+Zone *Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
+// printf("hitZone(%i, %i, %i)", type, x, y);
+
+ uint16 _di = y;
+ uint16 _si = x;
+
+ for (ZoneList::iterator it = _zones.begin(); it != _zones.end(); it++) {
+// printf("Zone name: %s", z->_name);
+
+ Zone *z = *it;
+
+ if (z->_flags & kFlagsRemove) continue;
+
+ Common::Rect r;
+ z->getRect(r);
+ r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
+ r.bottom++;
+
+ r.grow(-1); // allows some tolerance for mouse click
+
+ if (!r.contains(_si, _di)) {
+
+ // out of Zone, so look for special values
+ if ((z->_left == -2) || (z->_left == -3)) {
+
+ // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
+ // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
+ // but we need to check it separately here. The same workaround is applied in freeZones.
+ if ((((z->_type & 0xFFFF) == kZoneMerge) && (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1)))) ||
+ (((z->_type & 0xFFFF) == kZoneGet) && ((_si == z->u.get->_icon) || (_di == z->u.get->_icon)))) {
+
+ // special Zone
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return z;
+ if (z->_type == type)
+ return z;
+ if ((z->_type & 0xFFFF0000) == type)
+ return z;
+
+ }
+ }
+
+ if (z->_left != -1)
+ continue;
+ if (_si < _char._ani._left)
+ continue;
+ if (_si > (_char._ani._left + _char._ani.width()))
+ continue;
+ if (_di < _char._ani._top)
+ continue;
+ if (_di > (_char._ani._top + _char._ani.height()))
+ continue;
+
+ }
+
+ // normal Zone
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return z;
+ if (z->_type == type)
+ return z;
+ if ((z->_type & 0xFFFF0000) == type)
+ return z;
+
+ }
+
+
+ int16 _a, _b, _c, _d, _e, _f;
+ for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++) {
+
+ Animation *a = *it;
+
+ _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
+ _e = ((_si >= a->_left + a->width()) || (_si <= a->_left)) ? 0 : 1; // _e: horizontal range
+ _f = ((_di >= a->_top + a->height()) || (_di <= a->_top)) ? 0 : 1; // _f: vertical range
+
+ _b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character)
+ _c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object
+ _d = ((a->_type & 0xFFFF0000) != type) ? 0 : 1; // _d: Animation is an object of the same type
+
+ if ((_a != 0 && _e != 0 && _f != 0) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
+
+ return a;
+
+ }
+
+ }
+
+ return NULL;
+}
+
+
+void Parallaction_ns::initOpcodes() {
+
+ static const OpcodeV1 op1[] = {
+ INSTRUCTION_OPCODE(invalid),
+ INSTRUCTION_OPCODE(on),
+ INSTRUCTION_OPCODE(off),
+ INSTRUCTION_OPCODE(set), // x
+ INSTRUCTION_OPCODE(set), // y
+ INSTRUCTION_OPCODE(set), // z
+ INSTRUCTION_OPCODE(set), // f
+ INSTRUCTION_OPCODE(loop),
+ INSTRUCTION_OPCODE(endloop),
+ INSTRUCTION_OPCODE(null),
+ INSTRUCTION_OPCODE(inc),
+ INSTRUCTION_OPCODE(inc), // dec
+ INSTRUCTION_OPCODE(set),
+ INSTRUCTION_OPCODE(put),
+ INSTRUCTION_OPCODE(call),
+ INSTRUCTION_OPCODE(wait),
+ INSTRUCTION_OPCODE(start),
+ INSTRUCTION_OPCODE(sound),
+ INSTRUCTION_OPCODE(move),
+ INSTRUCTION_OPCODE(end)
+ };
+
+ uint i;
+ for (i = 0; i < ARRAYSIZE(op1); i++)
+ _instructionOpcodes.push_back(&op1[i]);
+
+ static const OpcodeV1 op3[] = {
+ COMMAND_OPCODE(invalid),
+ COMMAND_OPCODE(set),
+ COMMAND_OPCODE(clear),
+ COMMAND_OPCODE(start),
+ COMMAND_OPCODE(speak),
+ COMMAND_OPCODE(get),
+ COMMAND_OPCODE(location),
+ COMMAND_OPCODE(open),
+ COMMAND_OPCODE(close),
+ COMMAND_OPCODE(on),
+ COMMAND_OPCODE(off),
+ COMMAND_OPCODE(call),
+ COMMAND_OPCODE(toggle),
+ COMMAND_OPCODE(drop),
+ COMMAND_OPCODE(quit),
+ COMMAND_OPCODE(move),
+ COMMAND_OPCODE(stop)
+ };
+
+ for (i = 0; i < ARRAYSIZE(op3); i++)
+ _commandOpcodes.push_back(&op3[i]);
+
+}
+
+
+
+} // namespace Parallaction
Property changes on: scummvm/trunk/engines/parallaction/exec_ns.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Modified: scummvm/trunk/engines/parallaction/font.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/font.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/font.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -571,7 +571,7 @@
}
Font *DosDisk_br::createFont(const char *name, Common::ReadStream &stream) {
- printf("DosDisk_br::createFont(%s)\n", name);
+// printf("DosDisk_br::createFont(%s)\n", name);
return new BraFont(stream);
}
Modified: scummvm/trunk/engines/parallaction/inventory.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/inventory.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/inventory.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -157,7 +157,7 @@
bool found = false;
for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS - 1; slot++) {
- if (v + INVENTORY_FIRST_ITEM == _inventory[slot]._index) {
+ if (v == _inventory[slot]._index) {
found = true;
}
Deleted: scummvm/trunk/engines/parallaction/location.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/location.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/location.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,567 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/system.h"
-
-#include "parallaction/parallaction.h"
-#include "parallaction/sound.h"
-
-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]);
-}
-
-DECLARE_LOCATION_PARSER(redundant) {
- warning("redundant '%s' line found in script '%s'", _tokens[0], _locParseCtxt.filename);
-}
-
-
-void Parallaction::parseLocation(const char *filename) {
- debugC(1, kDebugLocation, "parseLocation('%s')", filename);
-
- allocateLocationSlot(filename);
-
- Script *script = _disk->loadLocation(filename);
-
- // TODO: the following two lines are specific to Nippon Safes
- // and should be moved into something like 'initializeParsing()'
- _gfx->setFont(_labelFont);
- _hasLocationSound = false;
-
- _locParseCtxt.end = false;
- _locParseCtxt.script = script;
- _locParseCtxt.filename = filename;
-
- pushParserTables(_locationParsers, _locationStmt);
-
- do {
-
- fillBuffers(*script, true);
-
- parseStatement();
-
- } while (!_locParseCtxt.end);
-
- popParserTables();
-
- delete script;
-
- finalizeLocationParsing();
-
- return;
-}
-
-void Parallaction::allocateLocationSlot(const char *name) {
- // WORKAROUND: the original code erroneously incremented
- // _currentLocationIndex, thus producing inconsistent
- // savegames. This workaround modified the following loop
- // and if-statement, so the code exactly matches the one
- // in Big Red Adventure.
- _currentLocationIndex = -1;
- uint16 _di = 0;
- while (_locationNames[_di][0] != '\0') {
- if (!scumm_stricmp(_locationNames[_di], name)) {
- _currentLocationIndex = _di;
- }
- _di++;
- }
-
- if (_di == 120)
- error("No more location slots available. Please report this immediately to ScummVM team.");
-
- if (_currentLocationIndex == -1) {
- strcpy(_locationNames[_numLocations], name);
- _currentLocationIndex = _numLocations;
-
- _numLocations++;
- _locationNames[_numLocations][0] = '\0';
- _localFlags[_numLocations] = 0;
- } else {
- _localFlags[_currentLocationIndex] |= kFlagsVisited; // 'visited'
- }
-}
-
-void Parallaction::finalizeLocationParsing() {
-
- // this resolves any forward references in the script
- for (uint16 _si = 0; _forwardedCommands[_si]; _si++) {
- _forwardedCommands[_si]->u._animation = findAnimation(_forwardedAnimationNames[_si]);
- _forwardedCommands[_si] = NULL;
- }
- _numForwards = 0;
-
- // this loads animation scripts
- AnimationList::iterator it = _animations.begin();
- for ( ; it != _animations.end(); it++) {
- if ((*it)->_scriptName)
- loadProgram(*it, (*it)->_scriptName);
- }
-
- return;
-}
-
-
-void Parallaction::freeLocation() {
- debugC(7, kDebugLocation, "freeLocation");
-
- _soundMan->stopSfx(0);
- _soundMan->stopSfx(1);
- _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(120);
- _localFlagNames->addData("visited");
- }
-
- _location._walkNodes.clear();
-
- freeZones();
- freeAnimations();
-
- if (_location._comment) {
- free(_location._comment);
- }
- _location._comment = NULL;
-
- _location._commands.clear();
- _location._aCommands.clear();
-
- return;
-}
-
-
-
-void Parallaction::parseWalkNodes(Script& script, WalkNodeList &list) {
-
- fillBuffers(script, true);
- while (scumm_stricmp(_tokens[0], "ENDNODES")) {
-
- if (!scumm_stricmp(_tokens[0], "COORD")) {
-
- WalkNode *v4 = new WalkNode(
- atoi(_tokens[1]) - _char._ani.width()/2,
- atoi(_tokens[2]) - _char._ani.height()
- );
-
- list.push_front(v4);
- }
-
- fillBuffers(script, true);
- }
-
- return;
-
-}
-
-void Parallaction::freeBackground() {
-
- if (!_backgroundInfo)
- return;
-
- _backgroundInfo->bg.free();
- _backgroundInfo->mask.free();
- _backgroundInfo->path.free();
-
- _pathBuffer = 0;
-
-}
-
-void Parallaction::setBackground(const char* name, const char* mask, const char* path) {
-
- _disk->loadScenery(*_backgroundInfo, name, mask, path);
-
- _gfx->setPalette(_backgroundInfo->palette);
- _gfx->_palette.clone(_backgroundInfo->palette);
- _gfx->setBackground(&_backgroundInfo->bg);
-
- if (_backgroundInfo->mask.data)
- _gfx->setMask(&_backgroundInfo->mask);
-
- if (_backgroundInfo->path.data)
- _pathBuffer = &_backgroundInfo->path;
-
- return;
-}
-
-void Parallaction::showLocationComment(const char *text, bool end) {
-
- _gfx->setFont(_dialogueFont);
-
- int16 w, h;
- _gfx->getStringExtent(const_cast<char*>(text), 130, &w, &h);
-
- Common::Rect r(w + (end ? 5 : 10), h + 5);
- r.moveTo(5, 5);
-
- _gfx->floodFill(Gfx::kBitFront, r, 0);
- r.grow(-2);
- _gfx->floodFill(Gfx::kBitFront, r, 1);
- _gfx->displayWrappedString(const_cast<char*>(text), 3, 5, 0, 130);
-
- _gfx->updateScreen();
-
- return;
-}
-
-void Parallaction::switchBackground(const char* background, const char* mask) {
-// printf("switchBackground(%s)", name);
-
- Palette pal;
-
- uint16 v2 = 0;
- if (!scumm_stricmp(background, "final")) {
- _gfx->clearScreen(Gfx::kBitBack);
- for (uint16 _si = 0; _si <= 32; _si++) {
- pal.setEntry(_si, v2, v2, v2);
- v2 += 4;
- }
-
- g_system->delayMillis(20);
- _gfx->setPalette(pal);
- _gfx->updateScreen();
- }
-
- setBackground(background, mask, mask);
-
- return;
-}
-
-extern Zone *_hoverZone;
-extern Job *_jDrawLabel;
-extern Job *_jEraseLabel;
-
-void Parallaction::showSlide(const char *name) {
-
- BackgroundInfo info;
-
- _disk->loadSlide(info, name);
-
- // TODO: avoid using screen buffers for displaying slides. Using a generic buffer
- // allows for positioning of graphics as needed by Big Red Adventure.
- // The main problem lies with menu, which relies on multiple buffers, mainly because
- // it is crappy code.
- _gfx->setBackground(&info.bg);
- _gfx->setPalette(info.palette);
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
-
- info.bg.free();
- info.mask.free();
- info.path.free();
-
- return;
-}
-
-/*
- changeLocation handles transitions between locations, and is able to display slides
- between one and the other. The input parameter 'location' exists in some flavours:
-
- 1 - [S].slide.[L]{.[C]}
- 2 - [L]{.[C]}
-
- where:
-
- [S] is the slide to be shown
- [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
- [C] is the character to be selected, and is optional
-
- The routine tells one form from the other by searching for the '.slide.'
-
- NOTE: there exists one script in which [L] is not used in the case 1, but its use
- is commented out, and would definitely crash the current implementation.
-*/
-void Parallaction::changeLocation(char *location) {
- debugC(1, kDebugLocation, "changeLocation(%s)", location);
-
- _soundMan->playLocationMusic(location);
-
- // WORKAROUND: this if-statement has been added to avoid crashes caused by
- // execution of label jobs after a location switch. The other workaround in
- // Parallaction::runGame should have been rendered useless by this one.
- if (_jDrawLabel != NULL) {
- removeJob(_jDrawLabel);
- removeJob(_jEraseLabel);
- _jDrawLabel = NULL;
- _jEraseLabel = NULL;
- }
-
-
- _hoverZone = NULL;
- if (_engineFlags & kEngineBlockInput) {
- changeCursor( kCursorArrow );
- }
-
- _animations.remove(&_char._ani);
-
- freeLocation();
- char buf[100];
- strcpy(buf, location);
-
- Common::StringList list;
- char *tok = strtok(location, ".");
- while (tok) {
- list.push_back(tok);
- tok = strtok(NULL, ".");
- }
-
- if (list.size() < 1 || list.size() > 4)
- error("changeLocation: ill-formed location string '%s'", location);
-
- if (list.size() > 1) {
- if (list[1] == "slide") {
- showSlide(list[0].c_str());
- _gfx->setFont(_menuFont);
- _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
- _gfx->updateScreen();
- waitUntilLeftClick();
-
- list.remove_at(0); // removes slide name
- list.remove_at(0); // removes 'slide'
- }
-
- // list is now only [L].{[C]} (see above comment)
- if (list.size() == 2) {
- changeCharacter(list[1].c_str());
- strcpy(_characterName, list[1].c_str());
- }
- }
-
- _animations.push_front(&_char._ani);
-
- strcpy(_saveData1, list[0].c_str());
- parseLocation(list[0].c_str());
-
- _char._ani._oldPos.x = -1000;
- _char._ani._oldPos.y = -1000;
-
- _char._ani.field_50 = 0;
- if (_location._startPosition.x != -1000) {
- _char._ani._left = _location._startPosition.x;
- _char._ani._top = _location._startPosition.y;
- _char._ani._frame = _location._startFrame;
- _location._startPosition.y = -1000;
- _location._startPosition.x = -1000;
- }
-
-
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
- _gfx->setBlackPalette();
- _gfx->updateScreen();
-
- if (_location._commands.size() > 0) {
- runCommands(_location._commands);
- runJobs();
- _gfx->swapBuffers();
- runJobs();
- _gfx->swapBuffers();
- }
-
- if (_location._comment) {
- doLocationEnterTransition();
- }
-
- runJobs();
- _gfx->swapBuffers();
-
- _gfx->setPalette(_gfx->_palette);
- if (_location._aCommands.size() > 0) {
- runCommands(_location._aCommands);
- }
-
- if (_hasLocationSound)
- _soundMan->playSfx(_locationSound, 0, true);
-
- debugC(1, kDebugLocation, "changeLocation() done");
-
- return;
-
-}
-
-// displays transition before a new location
-//
-// clears screen (in white??)
-// shows location comment (if any)
-// waits for mouse click
-// fades towards game palette
-//
-void Parallaction::doLocationEnterTransition() {
- debugC(1, kDebugLocation, "doLocationEnterTransition");
-
- if (_localFlags[_currentLocationIndex] & kFlagsVisited) {
- debugC(3, kDebugLocation, "skipping location transition");
- return; // visited
- }
-
- Palette pal(_gfx->_palette);
- pal.makeGrayscale();
- _gfx->setPalette(pal);
-
- jobRunScripts(NULL, NULL);
- jobEraseAnimations(NULL, NULL);
- jobDisplayAnimations(NULL, NULL);
-
- _gfx->swapBuffers();
- _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
-
- showLocationComment(_location._comment, false);
- waitUntilLeftClick();
-
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront );
-
- // fades maximum intensity palette towards approximation of main palette
- for (uint16 _si = 0; _si<6; _si++) {
- pal.fadeTo(_gfx->_palette, 4);
- _gfx->setPalette(pal);
- waitTime( 1 );
- _gfx->updateScreen();
- }
-
- debugC(1, kDebugLocation, "doLocationEnterTransition completed");
-
- return;
-}
-
-} // namespace Parallaction
Modified: scummvm/trunk/engines/parallaction/module.mk
===================================================================
--- scummvm/trunk/engines/parallaction/module.mk 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/module.mk 2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,29 +1,28 @@
MODULE := engines/parallaction
MODULE_OBJS := \
- animation.o \
callables_br.o \
callables_ns.o \
- commands.o \
debug.o \
detection.o \
dialogue.o \
disk_br.o \
disk_ns.o \
+ exec_ns.o \
font.o \
graphics.o \
inventory.o \
- location.o \
menu.o \
- parser.o \
+ objects.o \
parallaction.o \
parallaction_br.o \
parallaction_ns.o \
+ parser.o \
+ parser_ns.o \
saveload.o \
sound.o \
staticres.o \
- walk.o \
- zone.o
+ walk.o
# This module can be built as a plugin
ifdef BUILD_PLUGINS
Added: scummvm/trunk/engines/parallaction/objects.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/objects.cpp (rev 0)
+++ scummvm/trunk/engines/parallaction/objects.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -0,0 +1,215 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "parallaction/objects.h"
+
+namespace Parallaction {
+
+
+
+Command::Command() {
+ _id = 0;
+ _flagsOn = 0;
+ _flagsOff = 0;
+}
+
+Command::~Command() {
+
+}
+
+
+Animation::Animation() {
+ _cnv = NULL;
+ _program = NULL;
+ _scriptName = 0;
+ _frame = 0;
+ _z = 0;
+}
+
+Animation::~Animation() {
+ if (_program)
+ delete _program;
+
+ if (_scriptName)
+ free(_scriptName);
+
+ if (_cnv)
+ delete _cnv;
+}
+
+uint16 Animation::width() const {
+ if (!_cnv) return 0;
+ return _cnv->_width;
+}
+
+uint16 Animation::height() const {
+ if (!_cnv) return 0;
+ return _cnv->_height;
+}
+
+uint16 Animation::getFrameNum() const {
+ if (!_cnv) return 0;
+ return _cnv->_count;
+}
+
+byte* Animation::getFrameData(uint32 index) const {
+ if (!_cnv) return NULL;
+ return _cnv->getFramePtr(index);
+}
+
+
+Program::Program() {
+ _loopCounter = 0;
+ _locals = new LocalVariable[10];
+}
+
+Program::~Program() {
+ delete[] _locals;
+}
+
+
+Zone::Zone() {
+ _left = _top = _right = _bottom = 0;
+
+ _type = 0;
+ _flags = 0;
+}
+
+Zone::~Zone() {
+// printf("~Zone(%s)\n", _label._text);
+
+ _label._cnv.free();
+
+ switch (_type & 0xFFFF) {
+ case kZoneExamine:
+ free(u.examine->_filename);
+ free(u.examine->_description);
+ delete u.examine;
+ break;
+
+ case kZoneDoor:
+ free(u.door->_location);
+ free(u.door->_background);
+ if (u.door->_cnv)
+ delete u.door->_cnv;
+ delete u.door;
+ break;
+
+ case kZoneSpeak:
+ delete u.speak->_dialogue;
+ delete u.speak;
+ break;
+
+ case kZoneGet:
+ free(u.get->_backup);
+ if (u.get->_cnv) {
+ u.get->_cnv->free();
+ delete u.get->_cnv;
+ }
+ delete u.get;
+ break;
+
+ case kZoneHear:
+ delete u.hear;
+ break;
+
+ case kZoneMerge:
+ delete u.merge;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Zone::getRect(Common::Rect& r) const {
+ r.left = _left;
+ r.right = _right;
+ r.top = _top;
+ r.bottom = _bottom;
+}
+
+void Zone::translate(int16 x, int16 y) {
+ _left += x;
+ _right += x;
+ _top += y;
+ _bottom += y;
+}
+
+uint16 Zone::width() const {
+ return _right - _left;
+}
+
+uint16 Zone::height() const {
+ return _bottom - _top;
+}
+
+Label::Label() {
+ _text = NULL;
+}
+
+Label::~Label() {
+ _cnv.free();
+ if (_text)
+ free(_text);
+}
+
+
+Answer::Answer() {
+ _text = NULL;
+ _mood = 0;
+ _following._question = NULL;
+ _noFlags = 0;
+ _yesFlags = 0;
+}
+
+Answer::~Answer() {
+ if (_text)
+ free(_text);
+}
+
+Question::Question() {
+ _text = NULL;
+ _mood = 0;
+
+ for (uint32 i = 0; i < NUM_ANSWERS; i++)
+ _answers[i] = NULL;
+
+}
+
+Question::~Question() {
+
+ for (uint32 i = 0; i < NUM_ANSWERS; i++)
+ if (_answers[i]) delete _answers[i];
+
+ free(_text);
+}
+
+
+
+
+
+} // namespace Parallaction
Property changes on: scummvm/trunk/engines/parallaction/objects.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Added: scummvm/trunk/engines/parallaction/objects.h
===================================================================
--- scummvm/trunk/engines/parallaction/objects.h (rev 0)
+++ scummvm/trunk/engines/parallaction/objects.h 2007-08-24 20:14:51 UTC (rev 28711)
@@ -0,0 +1,405 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef PARALLACTION_ZONE_H
+#define PARALLACTION_ZONE_H
+
+#include "common/list.h"
+
+#include "parallaction/defs.h"
+
+#include "parallaction/graphics.h"
+
+
+namespace Parallaction {
+
+struct Zone;
+struct Animation;
+struct Command;
+struct Question;
+struct Answer;
+struct Instruction;
+struct Program;
+
+enum ZoneTypes {
+ kZoneExamine = 1, // zone displays comment if activated
+ kZoneDoor = 2, // zone activated on click (after some walk if needed)
+ kZoneGet = 4, // for pickable items
+ kZoneMerge = 8, // tags items which can be merged in inventory
+ kZoneTaste = 0x10, // NEVER USED
+ kZoneHear = 0x20, // NEVER USED: they ran out of time before integrating sfx
+ kZoneFeel = 0x40, // NEVER USED
+ kZoneSpeak = 0x80, // tags NPCs the character can talk with
+ kZoneNone = 0x100, // used to prevent parsing on peculiar Animations
+ kZoneTrap = 0x200, // zone activated when character enters
+ kZoneYou = 0x400, // marks the character
+ kZoneCommand = 0x800
+};
+
+
+enum ZoneFlags {
+ kFlagsClosed = 1, // Zone: door is closed / switch is off
+ kFlagsActive = 2, // Zone/Animation: object is visible
+ kFlagsRemove = 4, // Zone/Animation: object is soon to be removed
+ kFlagsActing = 8, // Animation: script execution is active
+ kFlagsLocked = 0x10, // Zone: door or switch cannot be toggled
+ kFlagsFixed = 0x20, // Zone: Zone item cannot be picked up
+ kFlagsNoName = 0x40, // Zone with no name (used to prevent some kEvEnterZone events)
+ kFlagsNoMasked = 0x80, // Animation is to be drawn ignoring z buffer
+ 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
+};
+
+
+enum CommandFlags {
+ kFlagsVisited = 1,
+ kFlagsExit = 0x10000000,
+ kFlagsEnter = 0x20000000,
+ kFlagsGlobal = 0x40000000,
+
+ // BRA specific
+ kFlagsTestTrue = 2
+};
+
+struct CommandData {
+ uint32 _flags;
+ Animation * _animation;
+ Zone* _zone;
+ char* _string;
+ uint16 _callable;
+ uint16 _object;
+ Common::Point _move;
+
+ // BRA specific
+ Common::Point _startPos;
+ Common::Point _startPos2;
+ uint _lvalue;
+ int _rvalue;
+ int _zeta0;
+ int _zeta1;
+ int _zeta2;
+ int _characterId;
+ char* _string2;
+ int _musicCommand;
+ int _musicParm;
+
+
+ CommandData() {
+ memset(this, 0, sizeof(CommandData));
+ }
+
+ ~CommandData() {
+ if (_string)
+ free(_string);
+ if (_string2)
+ free(_string2);
+ }
+};
+
+struct Command {
+ uint16 _id;
+ CommandData u;
+ uint32 _flagsOn;
+ uint32 _flagsOff;
+
+ Command();
+ ~Command();
+};
+
+typedef ManagedList<Command*> CommandList;
+
+
+#define NUM_QUESTIONS 20
+#define NUM_ANSWERS 5
+
+struct Answer {
+ char* _text;
+ uint16 _mood;
+ union {
+ Question* _question;
+ char* _name;
+ } _following;
+ CommandList _commands;
+ uint32 _noFlags;
+ uint32 _yesFlags;
+
+ Answer();
+ ~Answer();
+};
+
+struct Question {
+ char* _text;
+ uint16 _mood;
+ Answer* _answers[NUM_ANSWERS];
+
+ Question();
+ ~Question();
+};
+
+struct Dialogue {
+ Question *_questions[NUM_QUESTIONS];
+};
+
+struct GetData { // size = 24
+ uint32 _icon;
+ Graphics::Surface *_cnv;
+ byte *_backup;
+ uint16 field_14; // unused
+ uint16 field_16; // unused
+
+ GetData() {
+ _icon = 0;
+ _backup = NULL;
+ _cnv = NULL;
+ }
+};
+struct SpeakData { // size = 36
+ char _name[32];
+ Dialogue *_dialogue;
+
+ SpeakData() {
+ _name[0] = '\0';
+ _dialogue = NULL;
+ }
+};
+struct ExamineData { // size = 28
+ Graphics::Surface *_cnv;
+ uint16 _opBase; // unused
+ uint16 field_12; // unused
+ char* _description;
+ char* _filename;
+
+ ExamineData() {
+ _opBase = 0;
+ _description = NULL;
+ _filename = NULL;
+ _cnv = NULL;
+ }
+};
+struct DoorData { // size = 28
+ char* _location;
+ Cnv *_cnv;
+ byte* _background;
+ Common::Point _startPos;
+ uint16 _startFrame;
+
+ DoorData() {
+ _location = NULL;
+ _background = NULL;
+ _startFrame = 0;
+ _cnv = NULL;
+ }
+};
+struct HearData { // size = 20
+ char _name[20];
+ int _channel;
+ int _freq;
+
+ HearData() {
+ _channel = -1;
+ _freq = -1;
+ _name[0] = '\0';
+ }
+};
+struct MergeData { // size = 12
+ uint32 _obj1;
+ uint32 _obj2;
+ uint32 _obj3;
+
+ MergeData() {
+ _obj1 = _obj2 = _obj3 = 0;
+ }
+};
+
+struct TypeData {
+ GetData *get;
+ SpeakData *speak;
+ ExamineData *examine;
+ DoorData *door;
+ HearData *hear;
+ MergeData *merge;
+
+ TypeData() {
+ get = NULL;
+ speak = NULL;
+ examine = NULL;
+ door = NULL;
+ hear = NULL;
+ merge = NULL;
+ }
+};
+
+struct Label {
+ char* _text;
+ Graphics::Surface _cnv;
+
+ Label();
+ ~Label();
+};
+
+struct Zone {
+ int16 _left;
+ int16 _top;
+ int16 _right;
+ int16 _bottom;
+ uint32 _type;
+ uint32 _flags;
+ Label _label;
+ uint16 field_2C; // unused
+ uint16 field_2E; // unused
+ TypeData u;
+ CommandList _commands;
+ Common::Point _moveTo;
+
+ Zone();
+ virtual ~Zone();
+
+ void getRect(Common::Rect& r) const;
+ void translate(int16 x, int16 y);
+ virtual uint16 width() const;
+ virtual uint16 height() const;
+};
+
+typedef Zone* ZonePointer;
+typedef ManagedList<ZonePointer> ZoneList;
+
+struct LocalVariable {
+ int16 _value;
+ int16 _min;
+ int16 _max;
+
+ LocalVariable() {
+ _value = 0;
+ _min = -10000;
+ _max = 10000;
+ }
+};
+
+union ScriptVar {
+ int16 _value;
+ int16* _pvalue;
+ LocalVariable* _local;
+
+ ScriptVar() {
+ _local = NULL;
+ }
+};
+
+enum InstructionFlags {
+ kInstUsesLiteral = 1,
+ kInstUsesLocal = 2,
+ kInstMod = 4,
+ kInstMaskedPut = 8,
+
+ kInstUsesField = 0x10, // this value wasn't originally in NS, but it has been added for completeness
+
+ // BRA specific
+ kInstUnk20 = 0x20,
+ kInstUsesLLocal = 0x40,
+ kInstUsesLField = 0x80,
+ kInstRandom = 0x100
+};
+
+typedef ManagedList<Instruction*> InstructionList;
+
+struct Instruction {
+ uint32 _index;
+ uint32 _flags;
+ struct {
+ Animation *_a;
+ Zone *_z;
+ uint32 _index;
+ ScriptVar _loopCounter;
+ } _opBase;
+ ScriptVar _opA;
+ ScriptVar _opB;
+
+ // BRA specific
+ byte _colors[3];
+ ScriptVar _opC;
+ char *_text;
+ char *_text2;
+ int _y;
+ InstructionList::iterator _endif;
+
+ Instruction() {
+ memset(this, 0, sizeof(Instruction));
+ }
+
+ ~Instruction() {
+ if (_text)
+ free(_text);
+ if (_text2)
+ free(_text2);
+ }
+};
+
+struct Program {
+ LocalVariable *_locals;
+ uint16 _loopCounter;
+
+ InstructionList::iterator _ip;
+ InstructionList::iterator _loopStart;
+ InstructionList _instructions;
+
+ Program();
+ ~Program();
+};
+
+
+
+struct Animation : public Zone {
+
+ Common::Point _oldPos;
+ Program *_program;
+ Cnv *_cnv;
+ char *_scriptName;
+ int16 _frame;
+ uint16 field_50; // unused
+ int16 _z;
+ uint16 field_54; // unused
+ uint16 field_56; // unused
+ uint16 field_58; // unused
+ uint16 field_5A; // unused
+ uint16 field_5C; // unused
+ uint16 field_5E; // unused
+
+ Animation();
+ virtual ~Animation();
+ virtual uint16 width() const;
+ virtual uint16 height() const;
+ uint16 getFrameNum() const;
+ byte* getFrameData(uint32 index) const;
+};
+
+typedef Animation* AnimationPointer;
+typedef ManagedList<AnimationPointer> AnimationList;
+
+
+} // namespace Parallaction
+
+#endif
Property changes on: scummvm/trunk/engines/parallaction/objects.h
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp 2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp 2007-08-24 20:14:51 UTC (rev 28711)
@@ -53,7 +53,6 @@
uint16 _language = 0;
char _slideText[2][40];
uint32 _engineFlags = 0;
-Zone *_activeZone = NULL;
uint16 _score = 1;
@@ -128,11 +127,9 @@
delete _globalTable;
delete _callableNames;
- delete _commandsNames;
- delete _instructionNames;
+
delete _zoneTypeNames;
delete _zoneFlagNames;
- delete _locationStmt;
_animations.remove(&_char._ani);
@@ -168,6 +165,7 @@
_backgroundInfo = 0;
_pathBuffer = 0;
+ _activeZone = 0;
_screenSize = _screenWidth * _screenHeight;
@@ -178,8 +176,6 @@
memset(_locationNames, 0, 120*32);
- initOpcodes();
-
initInventory(); // needs to be pushed into subclass
_animations.push_front(&_char._ani);
@@ -840,7 +836,7 @@
}
-int Table::lookup(const char* s) {
+uint16 Table::lookup(const char* s) {
for (uint16 i = 0; i < _used; i++) {
if (!scumm_stricmp(_data[i], s)) return i + 1;
@@ -849,14 +845,12 @@
return notFound;
}
-void Parallaction::pushParserTables(const Opcode* opcodes, Table *statements) {
-
+void Parallaction::pushParserTables(OpcodeSet *opcodes, Table *statements) {
_opcodes.push(_currentOpcodes);
_statements.push(_currentStatements);
_currentOpcodes = opcodes;
_currentStatements = statements;
-
}
void Parallaction::popParserTables() {
@@ -870,161 +864,427 @@
assert(_currentOpcodes != 0);
_lookup = _currentStatements->lookup(_tokens[0]);
- (this->*(_currentOpcodes[_lookup]))();
+ (*(*_currentOpcodes)[_lookup])();
}
-void Parallaction::initOpcodes() {
- static const Opcode op0[] = {
- INSTRUCTION_PARSER(defLocal), // invalid opcode -> local definition
- INSTRUCTION_PARSER(animation), // on
- INSTRUCTION_PARSER(animation), // off
- INSTRUCTION_PARSER(x),
- INSTRUCTION_PARSER(y),
- INSTRUCTION_PARSER(z),
- INSTRUCTION_PARSER(f),
- INSTRUCTION_PARSER(loop),
- INSTRUCTION_PARSER(null), // endloop
- INSTRUCTION_PARSER(null), // show
- INSTRUCTION_PARSER(inc),
- INSTRUCTION_PARSER(inc), // dec
- INSTRUCTION_PARSER(set),
- INSTRUCTION_PARSER(put),
- INSTRUCTION_PARSER(call),
- INSTRUCTION_PARSER(null), // wait
- INSTRUCTION_PARSER(animation), // start
- INSTRUCTION_PARSER(sound),
- INSTRUCTION_PARSER(move)
- };
- _instructionParsers = op0;
+Animation *Parallaction::findAnimation(const char *name) {
- static const Opcode op1[] = {
- INSTRUCTION_OPCODE(invalid),
- INSTRUCTION_OPCODE(on),
- INSTRUCTION_OPCODE(off),
- INSTRUCTION_OPCODE(set), // x
- INSTRUCTION_OPCODE(set), // y
- INSTRUCTION_OPCODE(set), // z
- INSTRUCTION_OPCODE(set), // f
- INSTRUCTION_OPCODE(loop),
- INSTRUCTION_OPCODE(endloop),
- INSTRUCTION_OPCODE(null),
- INSTRUCTION_OPCODE(inc),
- INSTRUCTION_OPCODE(inc), // dec
- INSTRUCTION_OPCODE(set),
- INSTRUCTION_OPCODE(put),
- INSTRUCTION_OPCODE(call),
- INSTRUCTION_OPCODE(wait),
- INSTRUCTION_OPCODE(start),
- INSTRUCTION_OPCODE(sound),
- INSTRUCTION_OPCODE(move),
- INSTRUCTION_OPCODE(end)
- };
+ for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++)
+ if (!scumm_stricmp((*it)->_label._text, name)) return *it;
- _vm->_instructionOpcodes = op1;
+ return NULL;
+}
- static const Opcode op2[] = {
- COMMAND_PARSER(invalid),
- COMMAND_PARSER(flags), // set
- COMMAND_PARSER(flags), // clear
- COMMAND_PARSER(animation), // start
- COMMAND_PARSER(zone), // speak
- COMMAND_PARSER(zone), // get
- COMMAND_PARSER(location), // location
- COMMAND_PARSER(zone), // open
- COMMAND_PARSER(zone), // close
- COMMAND_PARSER(zone), // on
- COMMAND_PARSER(zone), // off
- COMMAND_PARSER(call), // call
- COMMAND_PARSER(flags), // toggle
- COMMAND_PARSER(drop), // drop
- COMMAND_PARSER(null), // quit
- COMMAND_PARSER(move), // move
- COMMAND_PARSER(animation), // stop
- COMMAND_PARSER(endcommands), // endcommands
- COMMAND_PARSER(endcommands) // endzone
- };
+void Parallaction::freeAnimations() {
+ _animations.clear();
+ return;
+}
- _commandParsers = op2;
+int compareAnimationZ(const AnimationPointer &a1, const AnimationPointer &a2) {
+ if (a1->_z == a2->_z) return 0;
+ return (a1->_z < a2->_z ? -1 : 1);
+}
- static const Opcode op3[] = {
- COMMAND_OPCODE(invalid),
- COMMAND_OPCODE(set),
- COMMAND_OPCODE(clear),
- COMMAND_OPCODE(start),
- COMMAND_OPCODE(speak),
- COMMAND_OPCODE(get),
- COMMAND_OPCODE(location),
- COMMAND_OPCODE(open),
- COMMAND_OPCODE(close),
- COMMAND_OPCODE(on),
- COMMAND_OPCODE(off),
- COMMAND_OPCODE(call),
- COMMAND_OPCODE(toggle),
- COMMAND_OPCODE(drop),
- COMMAND_OPCODE(quit),
- COMMAND_OPCODE(move),
- COMMAND_OPCODE(stop)
- };
+void Parallaction::sortAnimations() {
+ _char._ani._z = _char._ani.height() + _char._ani._top;
+ _animations.sort(compareAnimationZ);
+ return;
+}
- _commandOpcodes = op3;
+void Parallaction::allocateLocationSlot(const char *name) {
+ // WORKAROUND: the original code erroneously incremented
+ // _currentLocationIndex, thus producing inconsistent
+ // savegames. This workaround modified the following loop
+ // and if-statement, so the code exactly matches the one
+ // in Big Red Adventure.
+ _currentLocationIndex = -1;
+ uint16 _di = 0;
+ while (_locationNames[_di][0] != '\0') {
+ if (!scumm_stricmp(_locationNames[_di], name)) {
+ _currentLocationIndex = _di;
+ }
+ _di++;
+ }
- 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),
- LOCATION_PARSER(redundant) // for redundant endanimation
- };
+ if (_di == 120)
+ error("No more location slots available. Please report this immediately to ScummVM team.");
- _locationParsers = op4;
+ if (_currentLocationIndex == -1) {
+ strcpy(_locationNames[_numLocations], name);
+ _currentLocationIndex = _numLocations;
+ _numLocations++;
+ _locationNames[_numLocations][0] = '\0';
+ _localFlags[_numLocations] = 0;
+ } else {
+ _localFlags[_currentLocationIndex] |= kFlagsVisited; // 'visited'
+ }
+}
- static const Opcode op5[] = {
- ZONE_PARSER(invalid),
- ZONE_PARSER(limits),
- ZONE_PARSER(moveto),
- ZONE_PARSER(type),
- ZONE_PARSER(commands),
- ZONE_PARSER(label),
- ZONE_PARSER(flags),
- ZONE_PARSER(endzone)
- };
- _locationZoneParsers = op5;
- static const Opcode op6[] = {
- ANIM_PARSER(invalid),
- ANIM_PARSER(script),
- ANIM_PARSER(commands),
- ANIM_PARSER(type),
- ANIM_PARSER(label),
- ANIM_PARSER(flags),
- ANIM_PARSER(file),
- ANIM_PARSER(position),
- ANIM_PARSER(moveto),
- ANIM_PARSER(endanimation)
- };
+void Parallaction::freeLocation() {
+ debugC(7, kDebugLocation, "freeLocation");
- _locationAnimParsers = op6;
+ _soundMan->stopSfx(0);
+ _soundMan->stopSfx(1);
+ _soundMan->stopSfx(2);
+ _soundMan->stopSfx(3);
- _currentOpcodes = 0;
- _currentStatements = 0;
+ if (_localFlagNames)
+ delete _localFlagNames;
+ // HACK: prevents leakage. A routine like this
+ // should allocate memory at all, though.
+ if ((_engineFlags & kEngineQuit) == 0) {
+ _localFlagNames = new Table(120);
+ _localFlagNames->addData("visited");
+ }
+
+ _location._walkNodes.clear();
+
+ freeZones();
+ freeAnimations();
+
+ if (_location._comment) {
+ free(_location._comment);
+ }
+ _location._comment = NULL;
+
+ _location._commands.clear();
+ _location._aCommands.clear();
+
+ return;
}
+
+
+
+void Parallaction::freeBackground() {
+
+ if (!_backgroundInfo)
+ return;
+
+ _backgroundInfo->bg.free();
+ _backgroundInfo->mask.free();
+ _backgroundInfo->path.free();
+
+ _pathBuffer = 0;
+
+}
+
+void Parallaction::setBackground(const char* name, const char* mask, const char* path) {
+
+ _disk->loadScenery(*_backgroundInfo, name, mask, path);
+
+ _gfx->setPalette(_backgroundInfo->palette);
+ _gfx->_palette.clone(_backgroundInfo->palette);
+ _gfx->setBackground(&_backgroundInfo->bg);
+
+ if (_backgroundInfo->mask.data)
+ _gfx->setMask(&_backgroundInfo->mask);
+
+ if (_backgroundInfo->path.data)
+ _pathBuffer = &_backgroundInfo->path;
+
+ return;
+}
+
+void Parallaction::showLocationComment(const char *text, bool end) {
+
+ _gfx->setFont(_dialogueFont);
+
+ int16 w, h;
+ _gfx->getStringExtent(const_cast<char*>(text), 130, &w, &h);
+
+ Common::Rect r(w + (end ? 5 : 10), h + 5);
+ r.moveTo(5, 5);
+
+ _gfx->floodFill(Gfx::kBitFront, r, 0);
+ r.grow(-2);
+ _gfx->floodFill(Gfx::kBitFront, r, 1);
+ _gfx->displayWrappedString(const_cast<char*>(text), 3, 5, 0, 130);
+
+ _gfx->updateScreen();
+
+ return;
+}
+
+void Parallaction::switchBackground(const char* background, const char* mask) {
+// printf("switchBackground(%s)", name);
+
+ Palette pal;
+
+ uint16 v2 = 0;
+ if (!scumm_stricmp(background, "final")) {
+ _gfx->clearScreen(Gfx::kBitBack);
+ for (uint16 _si = 0; _si <= 32; _si++) {
+ pal.setEntry(_si, v2, v2, v2);
+ v2 += 4;
+ }
+
+ g_system->delayMillis(20);
+ _gfx->setPalette(pal);
+ _gfx->updateScreen();
+ }
+
+ setBackground(background, mask, mask);
+
+ return;
+}
+
+extern Zone *_hoverZone;
+extern Job *_jDrawLabel;
+extern Job *_jEraseLabel;
+
+void Parallaction::showSlide(const char *name) {
+
+ BackgroundInfo info;
+
+ _disk->loadSlide(info, name);
+
+ // TODO: avoid using screen buffers for displaying slides. Using a generic buffer
+ // allows for positioning of graphics as needed by Big Red Adventure.
+ // The main problem lies with menu, which relies on multiple buffers, mainly because
+ // it is crappy code.
+ _gfx->setBackground(&info.bg);
+ _gfx->setPalette(info.palette);
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+
+ info.bg.free();
+ info.mask.free();
+ info.path.free();
+
+ return;
+}
+
+/*
+ changeLocation handles transitions between locations, and is able to display slides
+ between one and the other. The input parameter 'location' exists in some flavours:
+
+ 1 - [S].slide.[L]{.[C]}
+ 2 - [L]{.[C]}
+
+ where:
+
+ [S] is the slide to be shown
+ [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
+ [C] is the character to be selected, and is optional
+
+ The routine tells one form from the other by searching for the '.slide.'
+
+ NOTE: there exists one script in which [L] is not used in the case 1, but its use
+ is commented out, and would definitely crash the current implementation.
+*/
+void Parallaction::changeLocation(char *location) {
+ debugC(1, kDebugLocation, "changeLocation(%s)", location);
+
+ _soundMan->playLocationMusic(location);
+
+ // WORKAROUND: this if-statement has been added to avoid crashes caused by
+ // execution of label jobs after a location switch. The other workaround in
+ // Parallaction::runGame should have been rendered useless by this one.
+ if (_jDrawLabel != NULL) {
+ removeJob(_jDrawLabel);
+ removeJob(_jEraseLabel);
+ _jDrawLabel = NULL;
+ _jEraseLabel = NULL;
+ }
+
+
+ _hoverZone = NULL;
+ if (_engineFlags & kEngineBlockInput) {
+ changeCursor( kCursorArrow );
+ }
+
+ _animations.remove(&_char._ani);
+
+ freeLocation();
+ char buf[100];
+ strcpy(buf, location);
+
+ Common::StringList list;
+ char *tok = strtok(location, ".");
+ while (tok) {
+ list.push_back(tok);
+ tok = strtok(NULL, ".");
+ }
+
+ if (list.size() < 1 || list.size() > 4)
+ error("changeLocation: ill-formed location string '%s'", location);
+
+ if (list.size() > 1) {
+ if (list[1] == "slide") {
+ showSlide(list[0].c_str());
+ _gfx->setFont(_menuFont);
+ _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
+ _gfx->updateScreen();
+ waitUntilLeftClick();
+
+ list.remove_at(0); // removes slide name
+ list.remove_at(0); // removes 'slide'
+ }
+
+ // list is now only [L].{[C]} (see above comment)
+ if (list.size() == 2) {
+ changeCharacter(list[1].c_str());
+ strcpy(_characterName, list[1].c_str());
+ }
+ }
+
+ _animations.push_front(&_char._ani);
+
+ strcpy(_saveData1, list[0].c_str());
+ parseLocation(list[0].c_str());
+
+ _char._ani._oldPos.x = -1000;
+ _char._ani._oldPos.y = -1000;
+
+ _char._ani.field_50 = 0;
+ if (_location._startPosition.x != -1000) {
+ _char._ani._left = _location._startPosition.x;
+ _char._ani._top = _location._startPosition.y;
+ _char._ani._frame = _location._startFrame;
+ _location._startPosition.y = -1000;
+ _location._startPosition.x = -1000;
+ }
+
+
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
+ _gfx->setBlackPalette();
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list