1153 lines
34 KiB
C++
1153 lines
34 KiB
C++
/* Residual - A 3D game interpreter
|
|
*
|
|
* Residual is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the AUTHORS
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*
|
|
*/
|
|
|
|
#include "engines/myst3/myst3.h"
|
|
#include "engines/myst3/script.h"
|
|
#include "engines/myst3/hotspot.h"
|
|
#include "engines/myst3/variables.h"
|
|
|
|
namespace Myst3 {
|
|
|
|
Script::Script(Myst3Engine *vm):
|
|
_vm(vm) {
|
|
#define OPCODE(op, x) _commands.push_back(Command(op, &Script::x, #x))
|
|
|
|
OPCODE(4, nodeCubeInit);
|
|
OPCODE(6, nodeCubeInitIndex);
|
|
OPCODE(7, nodeFrameInit);
|
|
OPCODE(8, nodeFrameInitCond);
|
|
OPCODE(9, nodeFrameInitIndex);
|
|
OPCODE(11, stopWholeScript);
|
|
OPCODE(17, movieInitLooping);
|
|
OPCODE(18, movieInitCondLooping);
|
|
OPCODE(19, movieInitCond);
|
|
OPCODE(20, movieInitPreloadLooping);
|
|
OPCODE(21, movieInitCondPreloadLooping);
|
|
OPCODE(22, movieInitCondPreload);
|
|
OPCODE(23, movieInitFrameVar);
|
|
OPCODE(24, movieInitFrameVarPreload);
|
|
OPCODE(25, movieInitOverrridePosition);
|
|
OPCODE(26, movieInitScriptedPosition);
|
|
OPCODE(35, sunspotAdd);
|
|
OPCODE(49, varSetZero);
|
|
OPCODE(50, varSetOne);
|
|
OPCODE(51, varSetTwo);
|
|
OPCODE(52, varSetOneHundred);
|
|
OPCODE(53, varSetValue);
|
|
OPCODE(54, varToggle);
|
|
OPCODE(55, varSetOneIfZero);
|
|
OPCODE(67, varRemoveBits);
|
|
OPCODE(68, varToggleBits);
|
|
OPCODE(69, varCopy);
|
|
OPCODE(70, varSetBitsFromVar);
|
|
OPCODE(71, varSetBits);
|
|
OPCODE(72, varApplyMask);
|
|
OPCODE(73, varSwap);
|
|
OPCODE(74, varIncrement);
|
|
OPCODE(75, varIncrementMax);
|
|
OPCODE(76, varIncrementMaxLooping);
|
|
OPCODE(77, varAddValueMaxLooping);
|
|
OPCODE(78, varDecrement);
|
|
OPCODE(79, varDecrementMin);
|
|
OPCODE(80, varAddValueMax);
|
|
OPCODE(81, varSubValueMin);
|
|
OPCODE(82, varZeroRange);
|
|
OPCODE(83, varCopyRange);
|
|
OPCODE(84, varSetRange);
|
|
OPCODE(85, varIncrementMaxTen);
|
|
OPCODE(86, varAddValue);
|
|
OPCODE(87, varArrayAddValue);
|
|
OPCODE(88, varAddVarValue);
|
|
OPCODE(89, varSubValue);
|
|
OPCODE(90, varSubVarValue);
|
|
OPCODE(91, varModValue);
|
|
OPCODE(92, varMultValue);
|
|
OPCODE(93, varMultVarValue);
|
|
OPCODE(94, varDivValue);
|
|
OPCODE(95, varDivVarValue);
|
|
OPCODE(97, varMinValue);
|
|
OPCODE(98, varClipValue);
|
|
OPCODE(99, varClipChangeBound);
|
|
OPCODE(100, varAbsoluteSubValue);
|
|
OPCODE(101, varAbsoluteSubVar);
|
|
OPCODE(102, varRatioToPercents);
|
|
OPCODE(103, varRotateValue3);
|
|
OPCODE(104, ifElse);
|
|
OPCODE(105, ifCondition);
|
|
OPCODE(106, ifCond1AndCond2);
|
|
OPCODE(107, ifCond1OrCond2);
|
|
OPCODE(108, ifOneVarSetInRange);
|
|
OPCODE(109, ifVarEqualsValue);
|
|
OPCODE(110, ifVarNotEqualsValue);
|
|
OPCODE(111, ifVar1EqualsVar2);
|
|
OPCODE(112, ifVar1NotEqualsVar2);
|
|
OPCODE(113, ifVarSupEqValue);
|
|
OPCODE(114, ifVarInfEqValue);
|
|
OPCODE(115, ifVarInRange);
|
|
OPCODE(116, ifVarNotInRange);
|
|
OPCODE(117, ifVar1SupEqVar2);
|
|
OPCODE(118, ifVar1SupVar2);
|
|
OPCODE(119, ifVar1InfEqVar2);
|
|
OPCODE(120, ifVarHasAllBitsSet);
|
|
OPCODE(121, ifVarHasNoBitsSet);
|
|
OPCODE(122, ifVarHasSomeBitsSet);
|
|
OPCODE(138, goToNode);
|
|
OPCODE(139, goToRoomNode);
|
|
OPCODE(176, runScriptForVar);
|
|
OPCODE(177, runScriptForVarEachXFrames);
|
|
OPCODE(178, runScriptForVarStartVar);
|
|
OPCODE(179, runScriptForVarStartVarEachXFrames);
|
|
OPCODE(180, runScriptForVarEndVar);
|
|
OPCODE(181, runScriptForVarEndVarEachXFrames);
|
|
OPCODE(182, runScriptForVarStartEndVar);
|
|
OPCODE(183, runScriptForVarStartEndVarEachXFrames);
|
|
OPCODE(184, drawFramesForVar);
|
|
OPCODE(185, drawFramesForVarEachTwoFrames);
|
|
OPCODE(186, drawFramesForVarStartEndVarEachTwoFrames);
|
|
OPCODE(187, runScript);
|
|
|
|
#undef OPCODE
|
|
}
|
|
|
|
Script::~Script() {
|
|
}
|
|
|
|
bool Script::run(const Common::Array<Opcode> *script) {
|
|
debugC(kDebugScript, "Script start %p", (void *) script);
|
|
|
|
Context c;
|
|
c.result = true;
|
|
c.endScript = false;
|
|
c.script = script;
|
|
c.op = script->begin();
|
|
|
|
while (c.op != script->end()) {
|
|
runOp(c, *c.op);
|
|
|
|
if (c.endScript || c.op == script->end())
|
|
break;
|
|
|
|
c.op++;
|
|
}
|
|
|
|
debugC(kDebugScript, "Script stop %p ", (void *) script);
|
|
|
|
return c.result;
|
|
}
|
|
|
|
void Script::runOp(Context &c, const Opcode &op) {
|
|
bool ranOpcode = false;
|
|
|
|
for (uint16 i = 0; i < _commands.size(); i++)
|
|
if (_commands[i].op == op.op) {
|
|
(this->*(_commands[i].proc)) (c, op);
|
|
ranOpcode = true;
|
|
break;
|
|
}
|
|
|
|
if (!ranOpcode)
|
|
warning("Trying to run invalid opcode %d", op.op);
|
|
}
|
|
|
|
const Common::String Script::describeCommand(uint16 op) {
|
|
for (uint16 i = 0; i < _commands.size(); i++)
|
|
if (_commands[i].op == op)
|
|
return Common::String::format("%d, %s", op, _commands[i].desc);
|
|
|
|
return Common::String::format("%d", op);
|
|
}
|
|
|
|
void Script::nodeCubeInit(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Node cube init %d", cmd.op, cmd.args[0]);
|
|
|
|
uint16 nodeId = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadNodeCubeFaces(nodeId);
|
|
// TODO: Load rects
|
|
}
|
|
|
|
void Script::nodeCubeInitIndex(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Node cube init indexed %d",
|
|
cmd.op, cmd.args[0]);
|
|
|
|
uint16 var = _vm->_vars->get(cmd.args[0]);
|
|
|
|
if (var >= cmd.args.size() - 1)
|
|
error("Opcode %d, invalid index %d", cmd.op, var);
|
|
|
|
uint16 value = cmd.args[var + 1];
|
|
|
|
uint16 nodeId = _vm->_vars->valueOrVarValue(value);
|
|
_vm->loadNodeCubeFaces(nodeId);
|
|
// TODO: Load rects
|
|
}
|
|
|
|
void Script::nodeFrameInit(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Node frame init %d", cmd.op, cmd.args[0]);
|
|
|
|
uint16 nodeId = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadNodeFrame(nodeId);
|
|
// TODO: Load rects
|
|
}
|
|
|
|
void Script::nodeFrameInitCond(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Node frame init condition %d ? %d : %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
uint16 value;
|
|
if (_vm->_vars->evaluate(cmd.args[0]))
|
|
value = cmd.args[1];
|
|
else
|
|
value = cmd.args[2];
|
|
|
|
uint16 nodeId = _vm->_vars->valueOrVarValue(value);
|
|
_vm->loadNodeFrame(nodeId);
|
|
// TODO: Load rects
|
|
}
|
|
|
|
void Script::nodeFrameInitIndex(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Node frame init indexed %d",
|
|
cmd.op, cmd.args[0]);
|
|
|
|
uint16 var = _vm->_vars->get(cmd.args[0]);
|
|
|
|
if (var >= cmd.args.size() - 1)
|
|
error("Opcode %d, invalid index %d", cmd.op, var);
|
|
|
|
uint16 value = cmd.args[var + 1];
|
|
|
|
uint16 nodeId = _vm->_vars->valueOrVarValue(value);
|
|
_vm->loadNodeFrame(nodeId);
|
|
// TODO: Load rects
|
|
}
|
|
|
|
void Script::stopWholeScript(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Stop whole script", cmd.op);
|
|
|
|
c.result = false;
|
|
c.endScript = true;
|
|
}
|
|
|
|
void Script::movieInitLooping(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Init movie %d, looping", cmd.op, cmd.args[0]);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, 1, false, true);
|
|
}
|
|
|
|
void Script::movieInitCondLooping(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Init movie %d with condition %d, looping", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, cmd.args[1], false, true);
|
|
}
|
|
|
|
void Script::movieInitCond(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Init movie %d with condition %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, cmd.args[1], true, false);
|
|
}
|
|
|
|
void Script::movieInitPreloadLooping(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Preload movie %d, looping", cmd.op, cmd.args[0]);
|
|
|
|
_vm->_vars->setMoviePreloadToMemory(true);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, 1, false, true);
|
|
}
|
|
|
|
void Script::movieInitCondPreloadLooping(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d, looping", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->_vars->setMoviePreloadToMemory(true);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, cmd.args[1], false, true);
|
|
}
|
|
|
|
void Script::movieInitCondPreload(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->_vars->setMoviePreloadToMemory(true);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, cmd.args[1], true, false);
|
|
}
|
|
|
|
void Script::movieInitFrameVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Init movie %d with next frame var %d",
|
|
cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->_vars->setMovieScriptDriven(true);
|
|
_vm->_vars->setMovieNextFrameGetVar(cmd.args[1]);
|
|
|
|
uint32 condition = _vm->_vars->getMovieOverrideCondition();
|
|
_vm->_vars->setMovieOverrideCondition(0);
|
|
|
|
if (!condition)
|
|
condition = 1;
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, condition, false, true);
|
|
}
|
|
|
|
void Script::movieInitFrameVarPreload(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Preload movie %d with next frame var %d",
|
|
cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->_vars->setMoviePreloadToMemory(true);
|
|
_vm->_vars->setMovieScriptDriven(true);
|
|
_vm->_vars->setMovieNextFrameGetVar(cmd.args[1]);
|
|
|
|
uint32 condition = _vm->_vars->getMovieOverrideCondition();
|
|
_vm->_vars->setMovieOverrideCondition(0);
|
|
|
|
if (!condition)
|
|
condition = 1;
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, condition, false, true);
|
|
}
|
|
|
|
void Script::movieInitOverrridePosition(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d and position U %d V %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
_vm->_vars->setMoviePreloadToMemory(true);
|
|
_vm->_vars->setMovieScriptDriven(true);
|
|
_vm->_vars->setMovieOverridePosition(true);
|
|
_vm->_vars->setMovieOverridePosU(cmd.args[2]);
|
|
_vm->_vars->setMovieOverridePosV(cmd.args[3]);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, cmd.args[1], false, true);
|
|
}
|
|
|
|
void Script::movieInitScriptedPosition(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Preload movie %d with position U-var %d V-var %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
_vm->_vars->setMoviePreloadToMemory(true);
|
|
_vm->_vars->setMovieScriptDriven(true);
|
|
_vm->_vars->setMovieUVar(cmd.args[1]);
|
|
_vm->_vars->setMovieUVar(cmd.args[2]);
|
|
|
|
uint16 movieid = _vm->_vars->valueOrVarValue(cmd.args[0]);
|
|
_vm->loadMovie(movieid, 1, false, true);
|
|
}
|
|
|
|
void Script::sunspotAdd(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
warning("Unimplemented opcode %d", cmd.op);
|
|
}
|
|
|
|
void Script::varSetZero(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var value %d := 0", cmd.op, cmd.args[0]);
|
|
|
|
_vm->_vars->set(cmd.args[0], 0);
|
|
}
|
|
|
|
void Script::varSetOne(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var value %d := 1", cmd.op, cmd.args[0]);
|
|
|
|
_vm->_vars->set(cmd.args[0], 1);
|
|
}
|
|
|
|
void Script::varSetTwo(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var value %d := 2", cmd.op, cmd.args[0]);
|
|
|
|
_vm->_vars->set(cmd.args[0], 2);
|
|
}
|
|
|
|
void Script::varSetOneHundred(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var value %d := 100", cmd.op, cmd.args[0]);
|
|
|
|
_vm->_vars->set(cmd.args[0], 100);
|
|
}
|
|
|
|
void Script::varSetValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var value %d := %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->_vars->set(cmd.args[0], cmd.args[1]);
|
|
}
|
|
|
|
void Script::varToggle(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Toggle var %d", cmd.op, cmd.args[0]);
|
|
|
|
_vm->_vars->set(cmd.args[0], _vm->_vars->get(cmd.args[0]) == 0);
|
|
}
|
|
|
|
void Script::varSetOneIfZero(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var %d to one if zero", cmd.op, cmd.args[0]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
if (!value)
|
|
_vm->_vars->set(cmd.args[0], 1);
|
|
}
|
|
|
|
void Script::varRemoveBits(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Remove bits %d from var %d", cmd.op, cmd.args[1], cmd.args[0]);
|
|
|
|
uint32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value &= ~cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varToggleBits(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Toggle bits %d from var %d", cmd.op, cmd.args[1], cmd.args[0]);
|
|
|
|
uint32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value ^= cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varCopy(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Copy var %d to var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->_vars->set(cmd.args[1], _vm->_vars->get(cmd.args[0]));
|
|
}
|
|
|
|
void Script::varSetBitsFromVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set bits from var %d on var %d", cmd.op, cmd.args[1], cmd.args[0]);
|
|
|
|
uint32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value |= _vm->_vars->get(cmd.args[1]);
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varSetBits(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set bits %d on var %d", cmd.op, cmd.args[1], cmd.args[0]);
|
|
|
|
uint32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value |= cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varApplyMask(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Apply mask %d on var %d", cmd.op, cmd.args[1], cmd.args[0]);
|
|
|
|
uint32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value &= cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varSwap(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Swap var %d and var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
_vm->_vars->set(cmd.args[0], _vm->_vars->get(cmd.args[1]));
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varIncrement(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Increment var %d", cmd.op, cmd.args[0]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value++;
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varIncrementMax(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Increment var %d with max value %d",
|
|
cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value++;
|
|
|
|
if (value > cmd.args[1])
|
|
value = cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varIncrementMaxLooping(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Increment var %d in range [%d, %d]",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value++;
|
|
|
|
if (value > cmd.args[2])
|
|
value = cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varAddValueMaxLooping(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Add %d to var %d in range [%d, %d]",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
|
|
value += cmd.args[0];
|
|
|
|
if (value > cmd.args[3])
|
|
value = cmd.args[2];
|
|
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varDecrement(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Decrement var %d", cmd.op, cmd.args[0]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value--;
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varDecrementMin(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Decrement var %d with min value %d",
|
|
cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value--;
|
|
|
|
if (value < cmd.args[1])
|
|
value = cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varAddValueMax(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Add value %d to var %d with max value %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
|
|
value += cmd.args[0];
|
|
|
|
if (value > cmd.args[2])
|
|
value = cmd.args[2];
|
|
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varSubValueMin(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Substract value %d from var %d with min value %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
|
|
value -= cmd.args[0];
|
|
|
|
if (value < cmd.args[2])
|
|
value = cmd.args[2];
|
|
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varZeroRange(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set vars from %d to %d to zero", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (cmd.args[0] > cmd.args[1])
|
|
error("Opcode %d, Incorrect range, %d -> %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
for (uint i = cmd.args[0]; i <= cmd.args[1]; i++)
|
|
_vm->_vars->set(i, 0);
|
|
}
|
|
|
|
void Script::varCopyRange(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Copy vars from %d to %d, length: %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
if (cmd.args[2] <= 0)
|
|
return;
|
|
|
|
for (uint i = 0; i < cmd.args[2]; i++)
|
|
_vm->_vars->set(cmd.args[1] + i, _vm->_vars->get(cmd.args[0] + i));
|
|
}
|
|
|
|
void Script::varSetRange(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set vars from %d to %d to val %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
if (cmd.args[0] > cmd.args[1])
|
|
error("Opcode %d, Incorrect range, %d -> %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
for (uint i = cmd.args[0]; i <= cmd.args[1]; i++)
|
|
_vm->_vars->set(i, cmd.args[2]);
|
|
}
|
|
|
|
void Script::varIncrementMaxTen(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Increment var %d max 10", cmd.op, cmd.args[0]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value++;
|
|
|
|
if (value == 10)
|
|
value = 1;
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varAddValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Add value %d to var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
value += cmd.args[0];
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varArrayAddValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Add value %d to array base var %d item var %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1] + _vm->_vars->get(cmd.args[2]));
|
|
value += cmd.args[0];
|
|
_vm->_vars->set(cmd.args[1] + _vm->_vars->get(cmd.args[2]), value);
|
|
}
|
|
|
|
void Script::varAddVarValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Add var %d value to var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
value += _vm->_vars->get(cmd.args[0]);
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varSubValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Substract value %d to var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
value -= cmd.args[0];
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varSubVarValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Substract var %d value to var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[1]);
|
|
value -= _vm->_vars->get(cmd.args[0]);
|
|
_vm->_vars->set(cmd.args[1], value);
|
|
}
|
|
|
|
void Script::varModValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Apply modulo %d to var %d", cmd.op, cmd.args[1], cmd.args[0]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
value %= cmd.args[1];
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varMultValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Multiply var %d by value %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
value *= cmd.args[1];
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varMultVarValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Multiply var %d by var %d value", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
value *= _vm->_vars->get(cmd.args[1]);
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varDivValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Divide var %d by value %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
value /= cmd.args[1];
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varDivVarValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Divide var %d by var %d value", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
value /= _vm->_vars->get(cmd.args[1]);
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varMinValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Set var %d to min between %d and var value", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
if (value > cmd.args[1])
|
|
value = cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varClipValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Clip var %d value between %d and %d", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value = CLIP<int32>(value, cmd.args[1], cmd.args[2]);
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varClipChangeBound(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Clip var %d value between %d and %d changing bounds", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
if (value < cmd.args[1])
|
|
value = cmd.args[2];
|
|
|
|
if (value > cmd.args[2])
|
|
value = cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varAbsoluteSubValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Take absolute value of var %d and substract %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value = abs(value) - cmd.args[1];
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varAbsoluteSubVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Take absolute value of var %d and substract var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value = abs(value) - _vm->_vars->get(cmd.args[1]);
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::varRatioToPercents(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Convert var %d to percents (max value %d, tare weight %d)",
|
|
cmd.op, cmd.args[0], cmd.args[2], cmd.args[1]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
value = 100 * (cmd.args[2] - abs(value) - _vm->_vars->get(cmd.args[1])) / cmd.args[2];
|
|
value = MIN(0, value);
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
|
|
void Script::varRotateValue3(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Var take next value, var %d values %d %d %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
|
|
if (value == cmd.args[1]) {
|
|
value = cmd.args[2];
|
|
} else if (value == cmd.args[2]) {
|
|
value = cmd.args[3];
|
|
} else {
|
|
value = cmd.args[1];
|
|
}
|
|
|
|
_vm->_vars->set(cmd.args[0], value);
|
|
}
|
|
|
|
void Script::ifElse(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Else", cmd.op);
|
|
|
|
c.result = true;
|
|
c.endScript = true;
|
|
}
|
|
|
|
void Script::goToElse(Context &c) {
|
|
|
|
// Go to next command until an else statement is met
|
|
do {
|
|
c.op++;
|
|
} while (c.op != c.script->end()
|
|
&& c.op->op != 104);
|
|
}
|
|
|
|
void Script::ifCondition(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If condition %d", cmd.op, cmd.args[0]);
|
|
|
|
if (_vm->_vars->evaluate(cmd.args[0]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifCond1AndCond2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If cond %d and cond %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->evaluate(cmd.args[0])
|
|
&& _vm->_vars->evaluate(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifCond1OrCond2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If cond %d or cond %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->evaluate(cmd.args[0])
|
|
|| _vm->_vars->evaluate(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifOneVarSetInRange(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If one var set int range %d %d",
|
|
cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
uint16 var = cmd.args[0];
|
|
uint16 end = cmd.args[1];
|
|
|
|
if (end > var) {
|
|
goToElse(c);
|
|
return;
|
|
}
|
|
|
|
bool result = false;
|
|
|
|
do {
|
|
result |= _vm->_vars->get(var);
|
|
var++;
|
|
} while (var <= end);
|
|
|
|
if (result)
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarEqualsValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d equals value %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) == cmd.args[1])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarNotEqualsValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d not equals value %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) != cmd.args[1])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVar1EqualsVar2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d equals var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) == _vm->_vars->get(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVar1NotEqualsVar2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d not equals var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) != _vm->_vars->get(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarSupEqValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d >= value %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) >= cmd.args[1])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarInfEqValue(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d <= value %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) <= cmd.args[1])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarInRange(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d in range %d %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
if(value >= cmd.args[1] && value <= cmd.args[2])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarNotInRange(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d not in range %d %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
int32 value = _vm->_vars->get(cmd.args[0]);
|
|
if(value < cmd.args[1] && value > cmd.args[2])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVar1SupEqVar2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d >= var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) >= _vm->_vars->get(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVar1SupVar2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d > var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) > _vm->_vars->get(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVar1InfEqVar2(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d <= var %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if (_vm->_vars->get(cmd.args[0]) <= _vm->_vars->get(cmd.args[1]))
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarHasAllBitsSet(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d & val %d == val %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[1]);
|
|
|
|
if ((_vm->_vars->get(cmd.args[0]) & cmd.args[1]) == cmd.args[1])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarHasNoBitsSet(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d & val %d == 0",
|
|
cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
if ((_vm->_vars->get(cmd.args[0]) & cmd.args[1]) == 0)
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::ifVarHasSomeBitsSet(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: If var %d & val %d == val %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
if ((_vm->_vars->get(cmd.args[0]) & cmd.args[1]) == cmd.args[2])
|
|
return;
|
|
|
|
goToElse(c);
|
|
}
|
|
|
|
void Script::goToNode(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Go to node %d", cmd.op, cmd.args[0]);
|
|
|
|
_vm->goToNode(cmd.args[0]);
|
|
}
|
|
|
|
void Script::goToRoomNode(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Go to room %d, node %d", cmd.op, cmd.args[0], cmd.args[1]);
|
|
|
|
_vm->goToNode(cmd.args[1], cmd.args[0]);
|
|
}
|
|
|
|
void Script::runScriptForVarDrawFramesHelper(uint16 var, int32 startValue, int32 endValue, uint16 script, int32 numFrames) {
|
|
if (numFrames < 0) {
|
|
numFrames = -numFrames;
|
|
uint startFrame = _vm->getFrameCount();
|
|
uint currentFrame = startFrame;
|
|
uint endFrame = startFrame + numFrames;
|
|
uint numValues = abs(endValue - startValue);
|
|
|
|
if (startFrame < endFrame) {
|
|
int currentValue = -9999;
|
|
while (1) {
|
|
int nextValue = numValues * (currentFrame - startFrame) / numFrames;
|
|
if (currentValue != nextValue) {
|
|
currentValue = nextValue;
|
|
|
|
int16 varValue;
|
|
if (endValue > startValue)
|
|
varValue = startValue + currentValue;
|
|
else
|
|
varValue = startValue - currentValue;
|
|
|
|
_vm->_vars->set(var, varValue);
|
|
|
|
if (script) {
|
|
_vm->runScriptsFromNode(script);
|
|
}
|
|
}
|
|
|
|
_vm->drawFrame();
|
|
currentFrame = _vm->getFrameCount();
|
|
|
|
if (currentFrame > endFrame)
|
|
break;
|
|
}
|
|
}
|
|
|
|
_vm->_vars->set(var, endValue);
|
|
} else {
|
|
int currentValue = startValue;
|
|
uint endFrame = 0;
|
|
|
|
bool positiveDirection = endValue > startValue;
|
|
|
|
while (1) {
|
|
if ((positiveDirection && (currentValue >= endValue))
|
|
|| (!positiveDirection && (currentValue <= startValue)))
|
|
break;
|
|
|
|
_vm->_vars->set(var, currentValue);
|
|
|
|
if (script)
|
|
_vm->runScriptsFromNode(script);
|
|
|
|
for (uint i = _vm->getFrameCount(); i < endFrame; i = _vm->getFrameCount())
|
|
_vm->drawFrame();
|
|
|
|
endFrame = _vm->getFrameCount() + numFrames;
|
|
|
|
currentValue += positiveDirection ? 1 : -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Script::runScriptForVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from %d to %d, run script %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], 0);
|
|
}
|
|
|
|
void Script::runScriptForVarEachXFrames(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from %d to %d, run script %d every %d frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], (int16) cmd.args[4]);
|
|
}
|
|
|
|
void Script::runScriptForVarStartVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from var %d value to %d, run script %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], _vm->_vars->get(cmd.args[1]), cmd.args[2], cmd.args[3], 0);
|
|
}
|
|
|
|
void Script::runScriptForVarStartVarEachXFrames(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from var %d value to %d, run script %d every %d frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], _vm->_vars->get(cmd.args[1]), cmd.args[2], cmd.args[3], (int16) cmd.args[4]);
|
|
}
|
|
|
|
void Script::runScriptForVarEndVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from %d to var %d value, run script %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], cmd.args[1], _vm->_vars->get(cmd.args[2]), cmd.args[3], 0);
|
|
}
|
|
|
|
void Script::runScriptForVarEndVarEachXFrames(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value, run script %d every %d frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], cmd.args[1], _vm->_vars->get(cmd.args[2]), cmd.args[3], (int16) cmd.args[4]);
|
|
}
|
|
|
|
void Script::runScriptForVarStartEndVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value, run script %d",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], _vm->_vars->get(cmd.args[1]), _vm->_vars->get(cmd.args[2]), cmd.args[3], 0);
|
|
}
|
|
|
|
void Script::runScriptForVarStartEndVarEachXFrames(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value, run script %d every %d frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], _vm->_vars->get(cmd.args[1]), _vm->_vars->get(cmd.args[2]), cmd.args[3], (int16) cmd.args[4]);
|
|
}
|
|
|
|
void Script::drawFramesForVar(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from %d to %d, every %d frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], cmd.args[1], cmd.args[2], 0, -((int16) cmd.args[3]));
|
|
}
|
|
|
|
void Script::drawFramesForVarEachTwoFrames(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from %d to %d draw 2 frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
uint numFrames = 2 * (-1 - abs(cmd.args[2] - cmd.args[1]));
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], cmd.args[1], cmd.args[2], 0, numFrames);
|
|
}
|
|
|
|
void Script::drawFramesForVarStartEndVarEachTwoFrames(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value draw 2 frames",
|
|
cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
|
|
|
uint numFrames = 2 * (-1 - abs(cmd.args[2] - cmd.args[1]));
|
|
|
|
runScriptForVarDrawFramesHelper(cmd.args[0], _vm->_vars->get(cmd.args[1]), _vm->_vars->get(cmd.args[2]), 0, numFrames);
|
|
}
|
|
|
|
void Script::runScript(Context &c, const Opcode &cmd) {
|
|
debugC(kDebugScript, "Opcode %d: Run scripts from node %d", cmd.op, cmd.args[0]);
|
|
|
|
_vm->runScriptsFromNode(cmd.args[0]);
|
|
}
|
|
|
|
} /* namespace Myst3 */
|