aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/animation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction/animation.cpp')
-rw-r--r--engines/parallaction/animation.cpp285
1 files changed, 163 insertions, 122 deletions
diff --git a/engines/parallaction/animation.cpp b/engines/parallaction/animation.cpp
index 51a21141da..a308b8feba 100644
--- a/engines/parallaction/animation.cpp
+++ b/engines/parallaction/animation.cpp
@@ -49,7 +49,7 @@ namespace Parallaction {
#define INST_START 16
#define INST_SOUND 17
#define INST_MOVE 18
-#define INST_END 1000
+#define INST_END 19
void wrapLocalVar(LocalVariable *local);
@@ -470,152 +470,193 @@ LValue Parallaction::getLValue(Instruction *inst, char *str, LocalVariable *loca
}
+DECLARE_INSTRUCTION_OPCODE(on) {
+ (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive;
+ (*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove;
+}
-void jobRunScripts(void *parm, Job *j) {
- debugC(3, kDebugJobs, "jobRunScripts");
- static uint16 modCounter = 0;
+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);
+ }
+}
- for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+DECLARE_INSTRUCTION_OPCODE(null) {
- Animation *a = *it;
+}
- if (a->_flags & kFlagsCharacter) a->_z = a->_top + a->height();
+DECLARE_INSTRUCTION_OPCODE(call) {
+ callFunction((*_instRunCtxt.inst)->_opBase._index, 0);
+}
- if ((a->_flags & kFlagsActing) == 0) continue;
- InstructionList::iterator inst = a->_program->_ip;
-// printf("Animation: %s, flags: %x\n", a->_name, a->_flags);
+DECLARE_INSTRUCTION_OPCODE(wait) {
+ if (_engineFlags & kEngineWalking)
+ _instRunCtxt.suspend = true;
+}
- 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]);
+DECLARE_INSTRUCTION_OPCODE(start) {
+// v1C = (*_instRunCtxt.inst)->_opBase;
+ (*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
+}
- switch ((*inst)->_index) {
- case INST_ENDLOOP: // endloop
- if (--a->_program->_loopCounter > 0) {
- inst = a->_program->_loopStart;
- }
- break;
- case INST_OFF: {// off
- (*inst)->_opBase._a->_flags |= kFlagsRemove;
-// v1C = (*inst)->_opBase;
- }
- break;
-
- case INST_ON: // on
- (*inst)->_opBase._a->_flags |= kFlagsActive;
- (*inst)->_opBase._a->_flags &= ~kFlagsRemove;
- break;
-
- case INST_START: // start
-// v1C = (*inst)->_opBase;
- (*inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
- break;
-
- case INST_LOOP: // loop
- if ((*inst)->_flags & kInstUsesLiteral) {
- a->_program->_loopCounter = (*inst)->_opBase._loopCounter._value;
- } else {
- a->_program->_loopCounter = *(*inst)->_opBase._loopCounter._pvalue;
- }
- a->_program->_loopStart = inst;
- break;
-
- case INST_INC: // inc
- case INST_DEC: { // dec
- int16 _si = 0;
- int16 _ax = 0, _bx = 0;
- if ((*inst)->_flags & kInstUsesLiteral) {
- _si = (*inst)->_opB._value;
- } else {
- _si = *(*inst)->_opB._pvalue;
- }
- if ((*inst)->_flags & kInstMod) { // mod
- _bx = (_si > 0 ? _si : -_si);
- if (modCounter % _bx != 0) break;
+DECLARE_INSTRUCTION_OPCODE(sound) {
+ _activeZone = (*_instRunCtxt.inst)->_opBase._z;
+}
- _si = (_si > 0 ? 1 : -1);
- }
- if ((*inst)->_flags & kInstUsesLocal) { // local
- if ((*inst)->_index == INST_INC) _ax = _si;
- else _ax = -_si;
- (*inst)->_opA._local->_value += _ax;
- wrapLocalVar((*inst)->_opA._local);
- break;
- }
+DECLARE_INSTRUCTION_OPCODE(move) {
+ WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue);
+ addJob(&jobWalk, v4, kPriority19 );
+ _engineFlags |= kEngineWalking;
+}
- // built-in variable (x, y, z, f)
- if ((*inst)->_index == INST_INC) _ax = _si;
- else _ax = -_si;
- *(*inst)->_opA._pvalue += _ax;
- }
- break;
+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();
- case INST_MOVE: { // move
- WalkNodeList *v4 = _vm->_char._builder.buildPath(*(*inst)->_opA._pvalue, *(*inst)->_opB._pvalue);
- _vm->addJob(&jobWalk, v4, kPriority19 );
- _engineFlags |= kEngineWalking;
- }
- break;
-
- case INST_PUT: // put
- v18.w = (*inst)->_opBase._a->width();
- v18.h = (*inst)->_opBase._a->height();
- v18.pixels = (*inst)->_opBase._a->getFrameData((*inst)->_opBase._a->_frame);
-
- if ((*inst)->_flags & kInstMaskedPut) {
- uint16 _si = _vm->_gfx->queryMask((*inst)->_opB._value);
- _vm->_gfx->blitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, _si, Gfx::kBitBack);
- _vm->_gfx->blitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, _si, Gfx::kBit2);
- } else {
- _vm->_gfx->flatBlitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, Gfx::kBitBack);
- _vm->_gfx->flatBlitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, Gfx::kBit2);
- }
- break;
+ _instRunCtxt.suspend = true;
+}
- case INST_END: // exit
- if ((a->_flags & kFlagsLooping) == 0) {
- a->_flags &= ~kFlagsActing;
- _vm->runCommands(a->_commands, a);
- }
- a->_program->_ip = a->_program->_instructions.begin();
- goto label1;
- case INST_CALL: // call
- _vm->callFunction((*inst)->_opBase._index, 0);
- break;
+void jobRunScripts(void *parm, Job *j) {
+ debugC(3, kDebugJobs, "jobRunScripts");
- case INST_WAIT: // wait
- if (_engineFlags & kEngineWalking) goto label1;
- break;
+ static uint16 modCounter = 0;
- case INST_SOUND: // sound
- _activeZone = (*inst)->_opBase._z;
- break;
+ static const Parallaction::Opcode opcodes[] = {
+ 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)
+ };
+
+ _vm->_instructionOpcodes = opcodes;
- default: { // INST_SET, INST_X, INST_Y, INST_Z, INST_F
- int16 _si;
- if ((*inst)->_flags & kInstUsesLiteral) {
- _si = (*inst)->_opB._value;
- } else {
- _si = *(*inst)->_opB._pvalue;
- }
+ for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
- if ((*inst)->_flags & kInstUsesLocal) {
- (*inst)->_opA._local->_value = _si;
- } else {
- *(*inst)->_opA._pvalue = _si;
- }
- }
- break;
+ 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 - 1])();
+
+ inst = _vm->_instRunCtxt.inst; // handles endloop correctly
+
+ if (_vm->_instRunCtxt.suspend)
+ goto label1;
inst++;
}