1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "engines/myst3/myst3.h"
24 #include "engines/myst3/script.h"
25 #include "engines/myst3/hotspot.h"
26 #include "engines/myst3/state.h"
27 #include "engines/myst3/cursor.h"
28 #include "engines/myst3/inventory.h"
29 #include "engines/myst3/puzzles.h"
30 #include "engines/myst3/scene.h"
31 #include "engines/myst3/sound.h"
32 #include "engines/myst3/ambient.h"
33
34 #include "common/events.h"
35
36 namespace Myst3 {
37
Script(Myst3Engine * vm)38 Script::Script(Myst3Engine *vm):
39 _vm(vm) {
40 _puzzles = new Puzzles(_vm);
41
42 #define OP(op, x, s) _commands.push_back(Command(op, &Script::x, #x, s))
43
44 // TODO: Implement these remaining opcodes
45 // 5: I'm pretty sure it's useless
46 // 247: quit
47
48 OP( 0, badOpcode, "" );
49 OP( 4, nodeCubeInit, "e" );
50 OP( 6, nodeCubeInitIndex, "veeee" );
51 OP( 7, nodeFrameInit, "e" );
52 OP( 8, nodeFrameInitCond, "cee" );
53 OP( 9, nodeFrameInitIndex, "veeee" );
54 OP( 10, nodeMenuInit, "e" );
55 OP( 11, stopWholeScript, "" );
56 OP( 13, spotItemAdd, "i" );
57 OP( 14, spotItemAddCond, "ic" );
58 OP( 15, spotItemAddCondFade, "ic" );
59 OP( 16, spotItemAddMenu, "iciii" ); // Six args
60 OP( 17, movieInitLooping, "e" );
61 OP( 18, movieInitCondLooping, "ec" );
62 OP( 19, movieInitCond, "ec" );
63 OP( 20, movieInitPreloadLooping, "e" );
64 OP( 21, movieInitCondPreloadLooping, "ec" );
65 OP( 22, movieInitCondPreload, "ec" );
66 OP( 23, movieInitFrameVar, "ev" );
67 OP( 24, movieInitFrameVarPreload, "ev" );
68 OP( 25, movieInitOverrridePosition, "ecii" );
69 OP( 26, movieInitScriptedPosition, "evv" );
70 OP( 27, movieRemove, "e" );
71 OP( 28, movieRemoveAll, "" );
72 OP( 29, movieSetLooping, "i" );
73 OP( 30, movieSetNotLooping, "i" );
74 OP( 31, waterEffectSetSpeed, "i" );
75 OP( 32, waterEffectSetAttenuation, "i" );
76 OP( 33, waterEffectSetWave, "ii" );
77 OP( 34, shakeEffectSet, "ee" );
78 OP( 35, sunspotAdd, "ii" );
79 OP( 36, sunspotAddIntensity, "iii" );
80 OP( 37, sunspotAddVarIntensity, "iiiv" );
81 OP( 38, sunspotAddIntensityColor, "iiii" );
82 OP( 39, sunspotAddVarIntensityColor, "iiiiv" );
83 OP( 40, sunspotAddIntensityRadius, "iiii" );
84 OP( 41, sunspotAddVarIntensityRadius, "iiivi" );
85 OP( 42, sunspotAddIntColorRadius, "iiiii" );
86 OP( 43, sunspotAddVarIntColorRadius, "iiiiv" ); // Six args
87 OP( 44, inventoryAddFront, "vi" );
88 OP( 45, inventoryAddBack, "vi" );
89 OP( 46, inventoryRemove, "v" );
90 OP( 47, inventoryReset, "" );
91 OP( 48, inventoryAddSaavChapter, "v" );
92 OP( 49, varSetZero, "v" );
93 OP( 50, varSetOne, "v" );
94 OP( 51, varSetTwo, "v" );
95 OP( 52, varSetOneHundred, "v" );
96 OP( 53, varSetValue, "vi" );
97 OP( 54, varToggle, "v" );
98 OP( 55, varSetOneIfNotZero, "v" );
99 OP( 56, varOpposite, "v" );
100 OP( 57, varAbsolute, "v" );
101 OP( 58, varDereference, "v" );
102 OP( 59, varReferenceSetZero, "v" );
103 OP( 60, varReferenceSetValue, "vi" );
104 OP( 61, varRandRange, "vii" );
105 OP( 62, polarToRectSimple, "vviii" ); // Seven args
106 OP( 63, polarToRect, "vviii" ); // Ten args
107 OP( 64, varSetDistanceToZone, "viii" );
108 OP( 65, varSetMinDistanceToZone, "viii" );
109 OP( 67, varRemoveBits, "vi" );
110 OP( 68, varToggleBits, "vi" );
111 OP( 69, varCopy, "vv" );
112 OP( 70, varSetBitsFromVar, "vv" );
113 OP( 71, varSetBits, "vi" );
114 OP( 72, varApplyMask, "vi" );
115 OP( 73, varSwap, "vv" );
116 OP( 74, varIncrement, "v" );
117 OP( 75, varIncrementMax, "vi" );
118 OP( 76, varIncrementMaxLooping, "vii" );
119 OP( 77, varAddValueMaxLooping, "ivii" );
120 OP( 78, varDecrement, "v" );
121 OP( 79, varDecrementMin, "vi" );
122 OP( 80, varAddValueMax, "ivi" );
123 OP( 81, varSubValueMin, "ivi" );
124 OP( 82, varZeroRange, "vv" );
125 OP( 83, varCopyRange, "vvi" );
126 OP( 84, varSetRange, "vvi" );
127 OP( 85, varIncrementMaxTen, "v" );
128 OP( 86, varAddValue, "iv" );
129 OP( 87, varArrayAddValue, "ivv" );
130 OP( 88, varAddVarValue, "vv" );
131 OP( 89, varSubValue, "iv" );
132 OP( 90, varSubVarValue, "vv" );
133 OP( 91, varModValue, "vi" );
134 OP( 92, varMultValue, "vi" );
135 OP( 93, varMultVarValue, "vv" );
136 OP( 94, varDivValue, "vi" );
137 OP( 95, varDivVarValue, "vv" );
138 OP( 96, varCrossMultiplication, "viiii" );
139 OP( 97, varMinValue, "vi" );
140 OP( 98, varClipValue, "vii" );
141 OP( 99, varClipChangeBound, "vii" );
142 OP(100, varAbsoluteSubValue, "vi" );
143 OP(101, varAbsoluteSubVar, "vv" );
144 OP(102, varRatioToPercents, "vii" );
145 OP(103, varRotateValue3, "viii" );
146 OP(104, ifElse, "" );
147 OP(105, ifCondition, "c" );
148 OP(106, ifCond1AndCond2, "cc" );
149 OP(107, ifCond1OrCond2, "cc" );
150 OP(108, ifOneVarSetInRange, "vv" );
151 OP(109, ifVarEqualsValue, "vi" );
152 OP(110, ifVarNotEqualsValue, "vi" );
153 OP(111, ifVar1EqualsVar2, "vv" );
154 OP(112, ifVar1NotEqualsVar2, "vv" );
155 OP(113, ifVarSupEqValue, "vi" );
156 OP(114, ifVarInfEqValue, "vi" );
157 OP(115, ifVarInRange, "vii" );
158 OP(116, ifVarNotInRange, "vii" );
159 OP(117, ifVar1SupEqVar2, "vv" );
160 OP(118, ifVar1SupVar2, "vv" );
161 OP(119, ifVar1InfEqVar2, "vv" );
162 OP(120, ifVarHasAllBitsSet, "vi" );
163 OP(121, ifVarHasNoBitsSet, "vi" );
164 OP(122, ifVarHasSomeBitsSet, "vii" );
165 OP(123, ifHeadingInRange, "ii" );
166 OP(124, ifPitchInRange, "ii" );
167 OP(125, ifHeadingPitchInRect, "iiii" );
168 OP(126, ifMouseIsInRect, "iiii" );
169 OP(127, leverDrag, "iiiiv" ); // Six args
170 OP(130, leverDragXY, "vviii" );
171 OP(131, itemDrag, "viiiv" );
172 OP(132, leverDragPositions, "vi" ); // Variable args
173 OP(134, runScriptWhileDragging, "vviiv" ); // Eight args
174 OP(135, chooseNextNode, "cii" );
175 OP(136, goToNodeTransition, "ii" );
176 OP(137, goToNodeTrans2, "i" );
177 OP(138, goToNodeTrans1, "i" );
178 OP(139, goToRoomNode, "ii" );
179 OP(140, zipToNode, "i" );
180 OP(141, zipToRoomNode, "ii" );
181 OP(144, drawTransition, "" );
182 OP(145, reloadNode, "" );
183 OP(146, redrawFrame, "" );
184 OP(147, moviePlay, "e" );
185 OP(148, moviePlaySynchronized, "e" );
186 OP(149, moviePlayFullFrame, "e" );
187 OP(150, moviePlayFullFrameTrans, "e" );
188 OP(151, moviePlayChangeNode, "ee" );
189 OP(152, moviePlayChangeNodeTrans, "ee" );
190 OP(153, lookAt, "ii" );
191 OP(154, lookAtInXFrames, "iii" );
192 OP(155, lookAtMovieStart, "e" );
193 OP(156, lookAtMovieStartInXFrames, "ei" );
194 OP(157, cameraLimitMovement, "iiii" );
195 OP(158, cameraFreeMovement, "" );
196 OP(159, cameraLookAt, "ii" );
197 OP(160, cameraLookAtVar, "v" );
198 OP(161, cameraGetLookAt, "v" );
199 OP(162, lookAtMovieStartImmediate, "e" );
200 OP(163, cameraSetFOV, "e" );
201 OP(164, changeNode, "i" );
202 OP(165, changeNodeRoom, "ii" );
203 OP(166, changeNodeRoomAge, "iii" );
204 OP(168, uselessOpcode, "" );
205 OP(169, drawXTicks, "i" );
206 OP(171, drawWhileCond, "c" );
207 OP(172, whileStart, "c" );
208 OP(173, whileEnd, "" );
209 OP(174, runScriptWhileCond, "ci" );
210 OP(175, runScriptWhileCondEachXFrames, "cii" );
211 OP(176, runScriptForVar, "viii" );
212 OP(177, runScriptForVarEachXFrames, "viiii" );
213 OP(178, runScriptForVarStartVar, "vvii" );
214 OP(179, runScriptForVarStartVarEachXFrames, "vviii" );
215 OP(180, runScriptForVarEndVar, "vivi" );
216 OP(181, runScriptForVarEndVarEachXFrames, "vivii" );
217 OP(182, runScriptForVarStartEndVar, "vvvi" );
218 OP(183, runScriptForVarStartEndVarEachXFrames, "vvvii" );
219 OP(184, drawFramesForVar, "viii" );
220 OP(185, drawFramesForVarEachTwoFrames, "vii" );
221 OP(186, drawFramesForVarStartEndVarEachTwoFrames, "vvv" );
222 OP(187, runScript, "e" );
223 OP(188, runScriptWithVar, "ei" );
224 OP(189, runCommonScript, "i" );
225 OP(190, runCommonScriptWithVar, "ei" );
226 OP(194, runPuzzle1, "i" );
227 OP(195, runPuzzle2, "ii" );
228 OP(196, runPuzzle3, "iii" );
229 OP(197, runPuzzle4, "iiii" );
230 OP(198, ambientLoadNode, "iii" );
231 OP(199, ambientReloadCurrentNode, "e" );
232 OP(200, ambientPlayCurrentNode, "ii" );
233 OP(201, ambientApply, "" );
234 OP(202, ambientApplyWithFadeDelay, "e" );
235 OP(203, soundPlayBadClick, "" );
236 OP(204, soundPlayBlocking, "eeeei" );
237 OP(205, soundPlay, "e" );
238 OP(206, soundPlayVolume, "ee" );
239 OP(207, soundPlayVolumeDirection, "eee" );
240 OP(208, soundPlayVolumeDirectionAtt, "eeee" );
241 OP(209, soundStopEffect, "e" );
242 OP(210, soundFadeOutEffect, "ee" );
243 OP(212, soundPlayLooping, "e" );
244 OP(213, soundPlayFadeInOut, "eeeee" );
245 OP(214, soundChooseNext, "viiee" );
246 OP(215, soundRandomizeNext, "viiee" );
247 OP(216, soundChooseNextAfterOther, "viiee" ); // Seven args
248 OP(217, soundRandomizeNextAfterOther, "viiee" ); // Seven args
249 OP(218, ambientSetFadeOutDelay, "i" );
250 OP(219, ambientAddSound1, "ee" );
251 OP(220, ambientAddSound2, "eei" );
252 OP(222, ambientAddSound3, "eei" );
253 OP(223, ambientAddSound4, "eeii" );
254 OP(224, ambientAddSound5, "eee" );
255 OP(225, ambientSetCue1, "ie" );
256 OP(226, ambientSetCue2, "iei" );
257 OP(227, ambientSetCue3, "ieii" );
258 OP(228, ambientSetCue4, "ie" );
259 OP(229, runAmbientScriptNode, "e" );
260 OP(230, runAmbientScriptNodeRoomAge, "eeee" );
261 OP(231, runSoundScriptNode, "e" );
262 OP(232, runSoundScriptNodeRoom, "ee" );
263 OP(233, runSoundScriptNodeRoomAge, "eee" );
264 OP(234, soundStopMusic, "e" );
265 OP(235, movieSetStartupSound, "e" );
266 OP(236, movieSetStartupSoundVolume, "ee" );
267 OP(237, movieSetStartupSoundVolumeH, "eee" );
268 OP(239, drawOneFrame, "" );
269 OP(240, cursorHide, "" );
270 OP(241, cursorShow, "" );
271 OP(242, cursorSet, "i" );
272 OP(243, cursorLock, "" );
273 OP(244, cursorUnlock, "" );
274 OP(248, dialogOpen, "e" );
275 OP(249, newGame, "" );
276
277 if (_vm->getPlatform() == Common::kPlatformXbox) {
278 // The Xbox version inserted two new opcodes, one at position
279 // 27, the other at position 77, shifting all the other opcodes
280 shiftCommands(77, 1);
281 OP(77, varDecrementMinLooping, "vii" );
282
283 shiftCommands(27, 1);
284 OP(27, movieInitCondScriptedPosition, "ecvv" );
285 }
286
287 #undef OP
288 }
289
~Script()290 Script::~Script() {
291 delete _puzzles;
292 }
293
run(const Common::Array<Opcode> * script)294 bool Script::run(const Common::Array<Opcode> *script) {
295 debugC(kDebugScript, "Script start %p", (const void *) script);
296
297 Context c;
298 c.result = true;
299 c.endScript = false;
300 c.script = script;
301 c.op = script->begin();
302
303 while (c.op != script->end() && !_vm->shouldQuit()) {
304 runOp(c, *c.op);
305
306 if (c.endScript || c.op == script->end())
307 break;
308
309 c.op++;
310 }
311
312 debugC(kDebugScript, "Script stop %p ", (const void *) script);
313
314 return c.result;
315 }
316
findCommand(uint16 op)317 const Script::Command &Script::findCommand(uint16 op) {
318 for (uint16 i = 0; i < _commands.size(); i++)
319 if (_commands[i].op == op)
320 return _commands[i];
321
322 // Return the invalid opcode if not found
323 return findCommand(0);
324 }
325
findCommandByProc(CommandProc proc)326 const Script::Command &Script::findCommandByProc(CommandProc proc) {
327 for (uint16 i = 0; i < _commands.size(); i++)
328 if (_commands[i].proc == proc)
329 return _commands[i];
330
331 // Return the invalid opcode if not found
332 return findCommand(0);
333 }
334
shiftCommands(uint16 base,int32 value)335 void Script::shiftCommands(uint16 base, int32 value) {
336 for (uint16 i = 0; i < _commands.size(); i++)
337 if (_commands[i].op >= base)
338 _commands[i].op += value;
339 }
340
runOp(Context & c,const Opcode & op)341 void Script::runOp(Context &c, const Opcode &op) {
342 const Script::Command &cmd = findCommand(op.op);
343
344 if (cmd.op != 0)
345 (this->*(cmd.proc))(c, op);
346 else
347 debugC(kDebugScript, "Trying to run invalid opcode %d", op.op);
348 }
349
runSingleOp(const Opcode & op)350 void Script::runSingleOp(const Opcode &op) {
351 Context c;
352 runOp(c, op);
353 }
354
describeCommand(uint16 op)355 const Common::String Script::describeCommand(uint16 op) {
356 const Script::Command &cmd = findCommand(op);
357
358 if (cmd.op != 0)
359 return Common::String::format("%d, %s", cmd.op, cmd.desc);
360 else
361 return Common::String::format("%d", op);
362 }
363
describeOpcode(const Opcode & opcode)364 const Common::String Script::describeOpcode(const Opcode &opcode) {
365 const Script::Command &cmd = findCommand(opcode.op);
366
367 Common::String d = Common::String::format(" op %s ( ",
368 describeCommand(opcode.op).c_str());
369
370 for(uint k = 0; k < opcode.args.size(); k++) {
371 if (cmd.op != 0 && k < strlen(cmd.signature))
372 d += describeArgument(cmd.signature[k], opcode.args[k]) + " ";
373 else
374 d += Common::String::format("%d ", opcode.args[k]);
375 }
376
377 d += ")\n";
378
379 return d;
380 }
381
describeArgument(char type,int16 value)382 const Common::String Script::describeArgument(char type, int16 value) {
383 switch (type) {
384 case kVar:
385 return _vm->_state->describeVar(value);
386 case kValue:
387 return Common::String::format("%d", value);
388 case kEvalValue:
389 if (value > 0)
390 return Common::String::format("%d", value);
391 else
392 return _vm->_state->describeVar(-value);
393 case kCondition:
394 return _vm->_state->describeCondition(value);
395 case kUnknown:
396 default:
397 return Common::String::format("unk%d", value);
398 }
399 }
400
badOpcode(Context & c,const Opcode & cmd)401 void Script::badOpcode(Context &c, const Opcode &cmd) {
402 debugC(kDebugScript, "Opcode %d: Invalid opcode", cmd.op);
403
404 error("Trying to run invalid opcode %d", cmd.op);
405 }
406
uselessOpcode(Context & c,const Opcode & cmd)407 void Script::uselessOpcode(Context &c, const Opcode &cmd) {
408 debugC(kDebugScript, "Opcode %d: Useless opcode", cmd.op);
409
410 // List of useless opcodes
411
412 // 167 and 168 form a pair. 168 resets what 167 sets up.
413 // Since 167 is never used, 168 is marked as useless.
414 }
415
416
nodeCubeInit(Context & c,const Opcode & cmd)417 void Script::nodeCubeInit(Context &c, const Opcode &cmd) {
418 debugC(kDebugScript, "Opcode %d: Node cube init %d", cmd.op, cmd.args[0]);
419
420 uint16 nodeId = _vm->_state->valueOrVarValue(cmd.args[0]);
421 _vm->loadNodeCubeFaces(nodeId);
422 }
423
nodeCubeInitIndex(Context & c,const Opcode & cmd)424 void Script::nodeCubeInitIndex(Context &c, const Opcode &cmd) {
425 debugC(kDebugScript, "Opcode %d: Node cube init indexed %d",
426 cmd.op, cmd.args[0]);
427
428 uint16 var = _vm->_state->getVar(cmd.args[0]);
429
430 if (var >= cmd.args.size() - 1)
431 error("Opcode %d, invalid index %d", cmd.op, var);
432
433 uint16 value = cmd.args[var + 1];
434
435 uint16 nodeId = _vm->_state->valueOrVarValue(value);
436 _vm->loadNodeCubeFaces(nodeId);
437 }
438
nodeFrameInit(Context & c,const Opcode & cmd)439 void Script::nodeFrameInit(Context &c, const Opcode &cmd) {
440 debugC(kDebugScript, "Opcode %d: Node frame init %d", cmd.op, cmd.args[0]);
441
442 uint16 nodeId = _vm->_state->valueOrVarValue(cmd.args[0]);
443 _vm->loadNodeFrame(nodeId);
444 }
445
nodeFrameInitCond(Context & c,const Opcode & cmd)446 void Script::nodeFrameInitCond(Context &c, const Opcode &cmd) {
447 debugC(kDebugScript, "Opcode %d: Node frame init condition %d ? %d : %d",
448 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
449
450 uint16 value;
451 if (_vm->_state->evaluate(cmd.args[0]))
452 value = cmd.args[1];
453 else
454 value = cmd.args[2];
455
456 uint16 nodeId = _vm->_state->valueOrVarValue(value);
457 _vm->loadNodeFrame(nodeId);
458 }
459
nodeFrameInitIndex(Context & c,const Opcode & cmd)460 void Script::nodeFrameInitIndex(Context &c, const Opcode &cmd) {
461 debugC(kDebugScript, "Opcode %d: Node frame init indexed %d",
462 cmd.op, cmd.args[0]);
463
464 uint16 var = _vm->_state->getVar(cmd.args[0]);
465
466 if (var >= cmd.args.size() - 1)
467 error("Opcode %d, invalid index %d", cmd.op, var);
468
469 uint16 value = cmd.args[var + 1];
470
471 uint16 nodeId = _vm->_state->valueOrVarValue(value);
472 _vm->loadNodeFrame(nodeId);
473 }
474
nodeMenuInit(Context & c,const Opcode & cmd)475 void Script::nodeMenuInit(Context &c, const Opcode &cmd) {
476 debugC(kDebugScript, "Opcode %d: Node menu init %d", cmd.op, cmd.args[0]);
477
478 uint16 nodeId = _vm->_state->valueOrVarValue(cmd.args[0]);
479 _vm->loadNodeMenu(nodeId);
480 }
481
stopWholeScript(Context & c,const Opcode & cmd)482 void Script::stopWholeScript(Context &c, const Opcode &cmd) {
483 debugC(kDebugScript, "Opcode %d: Stop whole script", cmd.op);
484
485 c.result = false;
486 c.endScript = true;
487 }
488
spotItemAdd(Context & c,const Opcode & cmd)489 void Script::spotItemAdd(Context &c, const Opcode &cmd) {
490 debugC(kDebugScript, "Opcode %d: Draw spotitem %d", cmd.op, cmd.args[0]);
491
492 _vm->addSpotItem(cmd.args[0], 1, false);
493 }
494
spotItemAddCond(Context & c,const Opcode & cmd)495 void Script::spotItemAddCond(Context &c, const Opcode &cmd) {
496 debugC(kDebugScript, "Opcode %d: Add spotitem %d with condition %d", cmd.op, cmd.args[0], cmd.args[1]);
497
498 _vm->addSpotItem(cmd.args[0], cmd.args[1], false);
499 }
500
spotItemAddCondFade(Context & c,const Opcode & cmd)501 void Script::spotItemAddCondFade(Context &c, const Opcode &cmd) {
502 debugC(kDebugScript, "Opcode %d: Add fading spotitem %d for var %d", cmd.op, cmd.args[0], cmd.args[1]);
503
504 _vm->addSpotItem(cmd.args[0], cmd.args[1], true);
505 }
506
spotItemAddMenu(Context & c,const Opcode & cmd)507 void Script::spotItemAddMenu(Context &c, const Opcode &cmd) {
508 debugC(kDebugScript, "Opcode %d: Add menu spotitem %d with condition %d", cmd.op, cmd.args[0], cmd.args[1]);
509
510 Common::Rect rect = Common::Rect(cmd.args[4], cmd.args[5]);
511 rect.translate(cmd.args[2], cmd.args[3]);
512
513 _vm->addMenuSpotItem(cmd.args[0], cmd.args[1], rect);
514 }
515
movieInitLooping(Context & c,const Opcode & cmd)516 void Script::movieInitLooping(Context &c, const Opcode &cmd) {
517 debugC(kDebugScript, "Opcode %d: Init movie %d, looping", cmd.op, cmd.args[0]);
518
519 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
520 _vm->loadMovie(movieid, 1, false, true);
521 }
522
movieInitCondLooping(Context & c,const Opcode & cmd)523 void Script::movieInitCondLooping(Context &c, const Opcode &cmd) {
524 debugC(kDebugScript, "Opcode %d: Init movie %d with condition %d, looping", cmd.op, cmd.args[0], cmd.args[1]);
525
526 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
527 _vm->loadMovie(movieid, cmd.args[1], false, true);
528 }
529
movieInitCond(Context & c,const Opcode & cmd)530 void Script::movieInitCond(Context &c, const Opcode &cmd) {
531 debugC(kDebugScript, "Opcode %d: Init movie %d with condition %d", cmd.op, cmd.args[0], cmd.args[1]);
532
533 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
534 _vm->loadMovie(movieid, cmd.args[1], true, false);
535 }
536
movieInitPreloadLooping(Context & c,const Opcode & cmd)537 void Script::movieInitPreloadLooping(Context &c, const Opcode &cmd) {
538 debugC(kDebugScript, "Opcode %d: Preload movie %d, looping", cmd.op, cmd.args[0]);
539
540 _vm->_state->setMoviePreloadToMemory(true);
541
542 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
543 _vm->loadMovie(movieid, 1, false, true);
544 }
545
movieInitCondPreloadLooping(Context & c,const Opcode & cmd)546 void Script::movieInitCondPreloadLooping(Context &c, const Opcode &cmd) {
547 debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d, looping", cmd.op, cmd.args[0], cmd.args[1]);
548
549 _vm->_state->setMoviePreloadToMemory(true);
550
551 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
552 _vm->loadMovie(movieid, cmd.args[1], false, true);
553 }
554
movieInitCondPreload(Context & c,const Opcode & cmd)555 void Script::movieInitCondPreload(Context &c, const Opcode &cmd) {
556 debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d", cmd.op, cmd.args[0], cmd.args[1]);
557
558 _vm->_state->setMoviePreloadToMemory(true);
559
560 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
561 _vm->loadMovie(movieid, cmd.args[1], true, false);
562 }
563
movieInitFrameVar(Context & c,const Opcode & cmd)564 void Script::movieInitFrameVar(Context &c, const Opcode &cmd) {
565 debugC(kDebugScript, "Opcode %d: Init movie %d with next frame var %d",
566 cmd.op, cmd.args[0], cmd.args[1]);
567
568 _vm->_state->setMovieScriptDriven(true);
569 _vm->_state->setMovieNextFrameGetVar(cmd.args[1]);
570
571 uint32 condition = _vm->_state->getMovieOverrideCondition();
572 _vm->_state->setMovieOverrideCondition(0);
573
574 if (!condition)
575 condition = 1;
576
577 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
578 _vm->loadMovie(movieid, condition, false, true);
579 }
580
movieInitFrameVarPreload(Context & c,const Opcode & cmd)581 void Script::movieInitFrameVarPreload(Context &c, const Opcode &cmd) {
582 debugC(kDebugScript, "Opcode %d: Preload movie %d with next frame var %d",
583 cmd.op, cmd.args[0], cmd.args[1]);
584
585 _vm->_state->setMoviePreloadToMemory(true);
586 _vm->_state->setMovieScriptDriven(true);
587 _vm->_state->setMovieNextFrameGetVar(cmd.args[1]);
588
589 uint32 condition = _vm->_state->getMovieOverrideCondition();
590 _vm->_state->setMovieOverrideCondition(0);
591
592 if (!condition)
593 condition = 1;
594
595 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
596 _vm->loadMovie(movieid, condition, false, true);
597 }
598
movieInitOverrridePosition(Context & c,const Opcode & cmd)599 void Script::movieInitOverrridePosition(Context &c, const Opcode &cmd) {
600 debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d and position U %d V %d",
601 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
602
603 _vm->_state->setMoviePreloadToMemory(true);
604 _vm->_state->setMovieScriptDriven(true);
605 _vm->_state->setMovieOverridePosition(true);
606 _vm->_state->setMovieOverridePosU(cmd.args[2]);
607 _vm->_state->setMovieOverridePosV(cmd.args[3]);
608
609 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
610 _vm->loadMovie(movieid, cmd.args[1], false, true);
611 }
612
movieInitScriptedPosition(Context & c,const Opcode & cmd)613 void Script::movieInitScriptedPosition(Context &c, const Opcode &cmd) {
614 debugC(kDebugScript, "Opcode %d: Preload movie %d with position U-var %d V-var %d",
615 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
616
617 _vm->_state->setMoviePreloadToMemory(true);
618 _vm->_state->setMovieScriptDriven(true);
619 _vm->_state->setMovieUVar(cmd.args[1]);
620 _vm->_state->setMovieVVar(cmd.args[2]);
621
622 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
623 _vm->loadMovie(movieid, 1, false, true);
624 }
625
movieInitCondScriptedPosition(Context & c,const Opcode & cmd)626 void Script::movieInitCondScriptedPosition(Context &c, const Opcode &cmd) {
627 debugC(kDebugScript, "Opcode %d: Preload movie %d with condition %d, position U-var %d V-var %d",
628 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
629
630 _vm->_state->setMoviePreloadToMemory(true);
631 _vm->_state->setMovieScriptDriven(true);
632 _vm->_state->setMovieUVar(cmd.args[2]);
633 _vm->_state->setMovieVVar(cmd.args[3]);
634
635 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
636 _vm->loadMovie(movieid, cmd.args[1], false, true);
637 }
638
movieRemove(Context & c,const Opcode & cmd)639 void Script::movieRemove(Context &c, const Opcode &cmd) {
640 debugC(kDebugScript, "Opcode %d: Remove movie %d ",
641 cmd.op, cmd.args[0]);
642
643 uint16 movieid = _vm->_state->valueOrVarValue(cmd.args[0]);
644 _vm->removeMovie(movieid);
645 }
646
movieRemoveAll(Context & c,const Opcode & cmd)647 void Script::movieRemoveAll(Context &c, const Opcode &cmd) {
648 debugC(kDebugScript, "Opcode %d: Remove all movies",
649 cmd.op);
650
651 _vm->removeMovie(0);
652 }
653
movieSetLooping(Context & c,const Opcode & cmd)654 void Script::movieSetLooping(Context &c, const Opcode &cmd) {
655 debugC(kDebugScript, "Opcode %d: Set movie %d to loop",
656 cmd.op, cmd.args[0]);
657
658 _vm->setMovieLooping(cmd.args[0], true);
659 }
660
movieSetNotLooping(Context & c,const Opcode & cmd)661 void Script::movieSetNotLooping(Context &c, const Opcode &cmd) {
662 debugC(kDebugScript, "Opcode %d: Set movie %d not to loop",
663 cmd.op, cmd.args[0]);
664
665 _vm->setMovieLooping(cmd.args[0], false);
666 }
667
waterEffectSetSpeed(Context & c,const Opcode & cmd)668 void Script::waterEffectSetSpeed(Context &c, const Opcode &cmd) {
669 debugC(kDebugScript, "Opcode %d: Set water effect speed to %d",
670 cmd.op, cmd.args[0]);
671
672 _vm->_state->setWaterEffectSpeed(cmd.args[0]);
673 }
674
waterEffectSetAttenuation(Context & c,const Opcode & cmd)675 void Script::waterEffectSetAttenuation(Context &c, const Opcode &cmd) {
676 debugC(kDebugScript, "Opcode %d: Set water effect attenuation to %d",
677 cmd.op, cmd.args[0]);
678
679 _vm->_state->setWaterEffectAttenuation(cmd.args[0]);
680 }
681
waterEffectSetWave(Context & c,const Opcode & cmd)682 void Script::waterEffectSetWave(Context &c, const Opcode &cmd) {
683 debugC(kDebugScript, "Opcode %d: Set water effect frequency to %d and amplitude to %d",
684 cmd.op, cmd.args[0], cmd.args[1]);
685
686 _vm->_state->setWaterEffectFrequency(cmd.args[0]);
687 _vm->_state->setWaterEffectAmpl(cmd.args[1]);
688 }
689
shakeEffectSet(Context & c,const Opcode & cmd)690 void Script::shakeEffectSet(Context &c, const Opcode &cmd) {
691 debugC(kDebugScript, "Opcode %d: Set shake effect amplitude to %d and period to %d",
692 cmd.op, cmd.args[0], cmd.args[1]);
693
694 uint16 ampl = _vm->_state->valueOrVarValue(cmd.args[0]);
695 uint16 period = _vm->_state->valueOrVarValue(cmd.args[1]);
696
697 _vm->_state->setShakeEffectAmpl(ampl);
698 _vm->_state->setShakeEffectTickPeriod(period);
699 }
700
sunspotAdd(Context & c,const Opcode & cmd)701 void Script::sunspotAdd(Context &c, const Opcode &cmd) {
702 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
703
704 uint16 intensity = _vm->_state->getSunspotIntensity();
705 uint16 color = _vm->_state->getSunspotColor();
706 uint16 radius = _vm->_state->getSunspotRadius();
707
708 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, 1, false, radius);
709 }
710
sunspotAddIntensity(Context & c,const Opcode & cmd)711 void Script::sunspotAddIntensity(Context &c, const Opcode &cmd) {
712 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
713
714 uint16 intensity = cmd.args[2];
715 uint16 color = _vm->_state->getSunspotColor();
716 uint16 radius = _vm->_state->getSunspotRadius();
717
718 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, 1, false, radius);
719 }
720
sunspotAddVarIntensity(Context & c,const Opcode & cmd)721 void Script::sunspotAddVarIntensity(Context &c, const Opcode &cmd) {
722 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
723
724 uint16 intensity = cmd.args[2];
725 uint16 color = _vm->_state->getSunspotColor();
726 uint16 radius = _vm->_state->getSunspotRadius();
727
728 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, cmd.args[3], true, radius);
729 }
730
sunspotAddIntensityColor(Context & c,const Opcode & cmd)731 void Script::sunspotAddIntensityColor(Context &c, const Opcode &cmd) {
732 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
733
734 uint16 intensity = cmd.args[2];
735 uint16 color = cmd.args[3];
736 uint16 radius = _vm->_state->getSunspotRadius();
737
738 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, 1, false, radius);
739 }
740
sunspotAddVarIntensityColor(Context & c,const Opcode & cmd)741 void Script::sunspotAddVarIntensityColor(Context &c, const Opcode &cmd) {
742 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
743
744 uint16 intensity = cmd.args[2];
745 uint16 color = cmd.args[3];
746 uint16 radius = _vm->_state->getSunspotRadius();
747
748 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, cmd.args[4], true, radius);
749 }
750
sunspotAddIntensityRadius(Context & c,const Opcode & cmd)751 void Script::sunspotAddIntensityRadius(Context &c, const Opcode &cmd) {
752 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
753
754 uint16 intensity = cmd.args[2];
755 uint16 color = _vm->_state->getSunspotColor();
756 uint16 radius = cmd.args[3];
757
758 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, 1, false, radius);
759 }
760
sunspotAddVarIntensityRadius(Context & c,const Opcode & cmd)761 void Script::sunspotAddVarIntensityRadius(Context &c, const Opcode &cmd) {
762 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
763
764 uint16 intensity = cmd.args[2];
765 uint16 color = _vm->_state->getSunspotColor();
766 uint16 radius = cmd.args[4];
767
768 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, cmd.args[3], true, radius);
769 }
770
sunspotAddIntColorRadius(Context & c,const Opcode & cmd)771 void Script::sunspotAddIntColorRadius(Context &c, const Opcode &cmd) {
772 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
773
774 uint16 intensity = cmd.args[2];
775 uint16 color = cmd.args[3];
776 uint16 radius = cmd.args[4];
777
778 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, 1, false, radius);
779 }
780
sunspotAddVarIntColorRadius(Context & c,const Opcode & cmd)781 void Script::sunspotAddVarIntColorRadius(Context &c, const Opcode &cmd) {
782 debugC(kDebugScript, "Opcode %d: Add sunspot: pitch %d heading %d", cmd.op, cmd.args[0], cmd.args[1]);
783
784 uint16 intensity = cmd.args[2];
785 uint16 color = cmd.args[3];
786 uint16 radius = cmd.args[5];
787
788 _vm->addSunSpot(cmd.args[0], cmd.args[1], intensity, color, cmd.args[4], true, radius);
789 }
790
inventoryAddFront(Context & c,const Opcode & cmd)791 void Script::inventoryAddFront(Context &c, const Opcode &cmd) {
792 debugC(kDebugScript, "Opcode %d: Inventory add item %d at front", cmd.op, cmd.args[0]);
793
794 _vm->_inventory->addItem(cmd.args[0], false);
795 }
796
inventoryAddBack(Context & c,const Opcode & cmd)797 void Script::inventoryAddBack(Context &c, const Opcode &cmd) {
798 debugC(kDebugScript, "Opcode %d: Inventory add item %d at back", cmd.op, cmd.args[0]);
799
800 _vm->_inventory->addItem(cmd.args[0], true);
801 }
802
inventoryRemove(Context & c,const Opcode & cmd)803 void Script::inventoryRemove(Context &c, const Opcode &cmd) {
804 debugC(kDebugScript, "Opcode %d: Inventory remove item %d", cmd.op, cmd.args[0]);
805
806 _vm->_inventory->removeItem(cmd.args[0]);
807 }
808
inventoryReset(Context & c,const Opcode & cmd)809 void Script::inventoryReset(Context &c, const Opcode &cmd) {
810 debugC(kDebugScript, "Opcode %d: Reset inventory", cmd.op);
811
812 _vm->_inventory->reset();
813 }
814
inventoryAddSaavChapter(Context & c,const Opcode & cmd)815 void Script::inventoryAddSaavChapter(Context &c, const Opcode &cmd) {
816 debugC(kDebugScript, "Opcode %d: Get new Saavedro chapter %d", cmd.op, cmd.args[0]);
817
818 _vm->_inventory->addSaavedroChapter(cmd.args[0]);
819 }
820
varSetZero(Context & c,const Opcode & cmd)821 void Script::varSetZero(Context &c, const Opcode &cmd) {
822 debugC(kDebugScript, "Opcode %d: Set var value %d := 0", cmd.op, cmd.args[0]);
823
824 _vm->_state->setVar(cmd.args[0], 0);
825 }
826
varSetOne(Context & c,const Opcode & cmd)827 void Script::varSetOne(Context &c, const Opcode &cmd) {
828 debugC(kDebugScript, "Opcode %d: Set var value %d := 1", cmd.op, cmd.args[0]);
829
830 _vm->_state->setVar(cmd.args[0], 1);
831 }
832
varSetTwo(Context & c,const Opcode & cmd)833 void Script::varSetTwo(Context &c, const Opcode &cmd) {
834 debugC(kDebugScript, "Opcode %d: Set var value %d := 2", cmd.op, cmd.args[0]);
835
836 _vm->_state->setVar(cmd.args[0], 2);
837 }
838
varSetOneHundred(Context & c,const Opcode & cmd)839 void Script::varSetOneHundred(Context &c, const Opcode &cmd) {
840 debugC(kDebugScript, "Opcode %d: Set var value %d := 100", cmd.op, cmd.args[0]);
841
842 _vm->_state->setVar(cmd.args[0], 100);
843 }
844
varSetValue(Context & c,const Opcode & cmd)845 void Script::varSetValue(Context &c, const Opcode &cmd) {
846 debugC(kDebugScript, "Opcode %d: Set var value %d := %d", cmd.op, cmd.args[0], cmd.args[1]);
847
848 _vm->_state->setVar(cmd.args[0], cmd.args[1]);
849 }
850
varToggle(Context & c,const Opcode & cmd)851 void Script::varToggle(Context &c, const Opcode &cmd) {
852 debugC(kDebugScript, "Opcode %d: Toggle var %d", cmd.op, cmd.args[0]);
853
854 _vm->_state->setVar(cmd.args[0], _vm->_state->getVar(cmd.args[0]) == 0);
855 }
856
varSetOneIfNotZero(Context & c,const Opcode & cmd)857 void Script::varSetOneIfNotZero(Context &c, const Opcode &cmd) {
858 debugC(kDebugScript, "Opcode %d: Set var %d to one if not zero", cmd.op, cmd.args[0]);
859
860 int32 value = _vm->_state->getVar(cmd.args[0]);
861 if (value)
862 _vm->_state->setVar(cmd.args[0], 1);
863 }
864
varOpposite(Context & c,const Opcode & cmd)865 void Script::varOpposite(Context &c, const Opcode &cmd) {
866 debugC(kDebugScript, "Opcode %d: Take the opposite of var %d", cmd.op, cmd.args[0]);
867
868 int32 value = _vm->_state->getVar(cmd.args[0]);
869 _vm->_state->setVar(cmd.args[0], -value);
870 }
871
varAbsolute(Context & c,const Opcode & cmd)872 void Script::varAbsolute(Context &c, const Opcode &cmd) {
873 debugC(kDebugScript, "Opcode %d: Take the absolute value of var %d", cmd.op, cmd.args[0]);
874
875 int32 value = _vm->_state->getVar(cmd.args[0]);
876 _vm->_state->setVar(cmd.args[0], abs(value));
877 }
878
varDereference(Context & c,const Opcode & cmd)879 void Script::varDereference(Context &c, const Opcode &cmd) {
880 debugC(kDebugScript, "Opcode %d: Dereference var %d", cmd.op, cmd.args[0]);
881
882 int32 value = _vm->_state->getVar(cmd.args[0]);
883 _vm->_state->setVar(cmd.args[0], _vm->_state->getVar(value));
884 }
885
varReferenceSetZero(Context & c,const Opcode & cmd)886 void Script::varReferenceSetZero(Context &c, const Opcode &cmd) {
887 debugC(kDebugScript, "Opcode %d: Set to zero the var referenced by var %d", cmd.op, cmd.args[0]);
888
889 int32 value = _vm->_state->getVar(cmd.args[0]);
890 if (!value)
891 return;
892
893 _vm->_state->setVar(value, 0);
894 }
895
varReferenceSetValue(Context & c,const Opcode & cmd)896 void Script::varReferenceSetValue(Context &c, const Opcode &cmd) {
897 debugC(kDebugScript, "Opcode %d: Set to %d the var referenced by var %d", cmd.op, cmd.args[1], cmd.args[0]);
898
899 int32 value = _vm->_state->getVar(cmd.args[0]);
900 if (!value)
901 return;
902
903 _vm->_state->setVar(value, cmd.args[1]);
904 }
905
varRandRange(Context & c,const Opcode & cmd)906 void Script::varRandRange(Context &c, const Opcode &cmd) {
907 debugC(kDebugScript, "Opcode %d: Randomize var %d value between %d and %d", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
908
909 int32 value;
910
911 if (cmd.args[2] - cmd.args[1] > 0)
912 value = _vm->_rnd->getRandomNumberRng(cmd.args[1], cmd.args[2]);
913 else
914 value = cmd.args[1];
915
916 _vm->_state->setVar(cmd.args[0], value);
917 }
918
polarToRectSimple(Context & c,const Opcode & cmd)919 void Script::polarToRectSimple(Context &c, const Opcode &cmd) {
920 debugC(kDebugScript, "Opcode %d: Polar to rect transformation for angle in var %d", cmd.op, cmd.args[5]);
921
922 int32 angleDeg = _vm->_state->getVar(cmd.args[5]);
923 float angleRad = 2 * LOCAL_PI / cmd.args[6] * angleDeg;
924 float angleSin = sin(angleRad);
925 float angleCos = cos(angleRad);
926
927 int32 offsetX = cmd.args[2];
928 int32 offsetY = cmd.args[3];
929
930 float radius;
931 if (cmd.args[4] >= 0)
932 radius = cmd.args[4] - 0.1;
933 else
934 radius = cmd.args[4] * -0.1;
935
936 int32 posX = (int32)(offsetX + radius * angleSin);
937 int32 posY = (int32)(offsetY - radius * angleCos);
938
939 _vm->_state->setVar(cmd.args[0], posX);
940 _vm->_state->setVar(cmd.args[1], posY);
941 }
942
polarToRect(Context & c,const Opcode & cmd)943 void Script::polarToRect(Context &c, const Opcode &cmd) {
944 debugC(kDebugScript, "Opcode %d: Complex polar to rect transformation for angle in var %d", cmd.op, cmd.args[8]);
945
946 int32 angleDeg = _vm->_state->getVar(cmd.args[8]);
947 float angleRad = 2 * LOCAL_PI / cmd.args[9] * angleDeg;
948 float angleSin = sin(angleRad);
949 float angleCos = cos(angleRad);
950
951 float radiusX;
952 float radiusY;
953 if (angleSin < 0)
954 radiusX = cmd.args[4];
955 else
956 radiusX = cmd.args[5];
957 if (angleCos > 0)
958 radiusY = cmd.args[6];
959 else
960 radiusY = cmd.args[7];
961
962 int32 offsetX = cmd.args[2];
963 int32 offsetY = cmd.args[3];
964
965 int32 posX = (int32)(offsetX + (radiusX - 0.1f) * angleSin);
966 int32 posY = (int32)(offsetY - (radiusY - 0.1f) * angleCos);
967
968 _vm->_state->setVar(cmd.args[0], posX);
969 _vm->_state->setVar(cmd.args[1], posY);
970 }
971
varSetDistanceToZone(Context & c,const Opcode & cmd)972 void Script::varSetDistanceToZone(Context &c, const Opcode &cmd) {
973 debugC(kDebugScript, "Opcode %d: Set var %d to distance to point %d %d", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
974
975 float heading = _vm->_state->getLookAtHeading();
976 float pitch = _vm->_state->getLookAtPitch();
977 int16 distance = (int16)(100 * _vm->_scene->distanceToZone(cmd.args[2], cmd.args[1], cmd.args[3], heading, pitch));
978
979 _vm->_state->setVar(cmd.args[0], distance);
980 }
981
varSetMinDistanceToZone(Context & c,const Opcode & cmd)982 void Script::varSetMinDistanceToZone(Context &c, const Opcode &cmd) {
983 debugC(kDebugScript, "Opcode %d: Set var %d to distance to point %d %d if lower", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
984
985 float heading = _vm->_state->getLookAtHeading();
986 float pitch = _vm->_state->getLookAtPitch();
987 int16 distance = (int16)(100 * _vm->_scene->distanceToZone(cmd.args[2], cmd.args[1], cmd.args[3], heading, pitch));
988 if (distance >= _vm->_state->getVar(cmd.args[0]))
989 _vm->_state->setVar(cmd.args[0], distance);
990 }
991
varRemoveBits(Context & c,const Opcode & cmd)992 void Script::varRemoveBits(Context &c, const Opcode &cmd) {
993 debugC(kDebugScript, "Opcode %d: Remove bits %d from var %d", cmd.op, cmd.args[1], cmd.args[0]);
994
995 uint32 value = _vm->_state->getVar(cmd.args[0]);
996
997 value &= ~cmd.args[1];
998
999 _vm->_state->setVar(cmd.args[0], value);
1000 }
1001
varToggleBits(Context & c,const Opcode & cmd)1002 void Script::varToggleBits(Context &c, const Opcode &cmd) {
1003 debugC(kDebugScript, "Opcode %d: Toggle bits %d from var %d", cmd.op, cmd.args[1], cmd.args[0]);
1004
1005 uint32 value = _vm->_state->getVar(cmd.args[0]);
1006
1007 value ^= cmd.args[1];
1008
1009 _vm->_state->setVar(cmd.args[0], value);
1010 }
1011
varCopy(Context & c,const Opcode & cmd)1012 void Script::varCopy(Context &c, const Opcode &cmd) {
1013 debugC(kDebugScript, "Opcode %d: Copy var %d to var %d", cmd.op, cmd.args[0], cmd.args[1]);
1014
1015 _vm->_state->setVar(cmd.args[1], _vm->_state->getVar(cmd.args[0]));
1016 }
1017
varSetBitsFromVar(Context & c,const Opcode & cmd)1018 void Script::varSetBitsFromVar(Context &c, const Opcode &cmd) {
1019 debugC(kDebugScript, "Opcode %d: Set bits from var %d on var %d", cmd.op, cmd.args[0], cmd.args[1]);
1020
1021 uint32 value = _vm->_state->getVar(cmd.args[1]);
1022
1023 value |= _vm->_state->getVar(cmd.args[0]);
1024
1025 _vm->_state->setVar(cmd.args[1], value);
1026 }
1027
varSetBits(Context & c,const Opcode & cmd)1028 void Script::varSetBits(Context &c, const Opcode &cmd) {
1029 debugC(kDebugScript, "Opcode %d: Set bits %d on var %d", cmd.op, cmd.args[1], cmd.args[0]);
1030
1031 uint32 value = _vm->_state->getVar(cmd.args[0]);
1032
1033 value |= cmd.args[1];
1034
1035 _vm->_state->setVar(cmd.args[0], value);
1036 }
1037
varApplyMask(Context & c,const Opcode & cmd)1038 void Script::varApplyMask(Context &c, const Opcode &cmd) {
1039 debugC(kDebugScript, "Opcode %d: Apply mask %d on var %d", cmd.op, cmd.args[1], cmd.args[0]);
1040
1041 uint32 value = _vm->_state->getVar(cmd.args[0]);
1042
1043 value &= cmd.args[1];
1044
1045 _vm->_state->setVar(cmd.args[0], value);
1046 }
1047
varSwap(Context & c,const Opcode & cmd)1048 void Script::varSwap(Context &c, const Opcode &cmd) {
1049 debugC(kDebugScript, "Opcode %d: Swap var %d and var %d", cmd.op, cmd.args[0], cmd.args[1]);
1050
1051 int32 value = _vm->_state->getVar(cmd.args[0]);
1052 _vm->_state->setVar(cmd.args[0], _vm->_state->getVar(cmd.args[1]));
1053 _vm->_state->setVar(cmd.args[1], value);
1054 }
1055
varIncrement(Context & c,const Opcode & cmd)1056 void Script::varIncrement(Context &c, const Opcode &cmd) {
1057 debugC(kDebugScript, "Opcode %d: Increment var %d", cmd.op, cmd.args[0]);
1058
1059 int32 value = _vm->_state->getVar(cmd.args[0]);
1060
1061 value++;
1062
1063 _vm->_state->setVar(cmd.args[0], value);
1064 }
1065
varIncrementMax(Context & c,const Opcode & cmd)1066 void Script::varIncrementMax(Context &c, const Opcode &cmd) {
1067 debugC(kDebugScript, "Opcode %d: Increment var %d with max value %d",
1068 cmd.op, cmd.args[0], cmd.args[1]);
1069
1070 int32 value = _vm->_state->getVar(cmd.args[0]);
1071
1072 value++;
1073
1074 if (value > cmd.args[1])
1075 value = cmd.args[1];
1076
1077 _vm->_state->setVar(cmd.args[0], value);
1078 }
1079
varIncrementMaxLooping(Context & c,const Opcode & cmd)1080 void Script::varIncrementMaxLooping(Context &c, const Opcode &cmd) {
1081 debugC(kDebugScript, "Opcode %d: Increment var %d in range [%d, %d]",
1082 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1083
1084 int32 value = _vm->_state->getVar(cmd.args[0]);
1085
1086 value++;
1087
1088 if (value > cmd.args[2])
1089 value = cmd.args[1];
1090
1091 _vm->_state->setVar(cmd.args[0], value);
1092 }
1093
varAddValueMaxLooping(Context & c,const Opcode & cmd)1094 void Script::varAddValueMaxLooping(Context &c, const Opcode &cmd) {
1095 debugC(kDebugScript, "Opcode %d: Add %d to var %d in range [%d, %d]",
1096 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
1097
1098 int32 value = _vm->_state->getVar(cmd.args[1]);
1099
1100 value += cmd.args[0];
1101
1102 if (value > cmd.args[3])
1103 value = cmd.args[2];
1104
1105 _vm->_state->setVar(cmd.args[1], value);
1106 }
1107
varDecrement(Context & c,const Opcode & cmd)1108 void Script::varDecrement(Context &c, const Opcode &cmd) {
1109 debugC(kDebugScript, "Opcode %d: Decrement var %d", cmd.op, cmd.args[0]);
1110
1111 int32 value = _vm->_state->getVar(cmd.args[0]);
1112
1113 value--;
1114
1115 _vm->_state->setVar(cmd.args[0], value);
1116 }
1117
varDecrementMin(Context & c,const Opcode & cmd)1118 void Script::varDecrementMin(Context &c, const Opcode &cmd) {
1119 debugC(kDebugScript, "Opcode %d: Decrement var %d with min value %d",
1120 cmd.op, cmd.args[0], cmd.args[1]);
1121
1122 int32 value = _vm->_state->getVar(cmd.args[0]);
1123
1124 value--;
1125
1126 if (value < cmd.args[1])
1127 value = cmd.args[1];
1128
1129 _vm->_state->setVar(cmd.args[0], value);
1130 }
1131
varDecrementMinLooping(Context & c,const Opcode & cmd)1132 void Script::varDecrementMinLooping(Context &c, const Opcode &cmd) {
1133 debugC(kDebugScript, "Opcode %d: Decrement var %d in range [%d, %d]",
1134 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1135
1136 int32 value = _vm->_state->getVar(cmd.args[0]);
1137
1138 value--;
1139
1140 if (value < cmd.args[1])
1141 value = cmd.args[2];
1142
1143 _vm->_state->setVar(cmd.args[0], value);
1144 }
1145
varAddValueMax(Context & c,const Opcode & cmd)1146 void Script::varAddValueMax(Context &c, const Opcode &cmd) {
1147 debugC(kDebugScript, "Opcode %d: Add value %d to var %d with max value %d",
1148 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1149
1150 int32 value = _vm->_state->getVar(cmd.args[1]);
1151
1152 value += cmd.args[0];
1153
1154 if (value > cmd.args[2])
1155 value = cmd.args[2];
1156
1157 _vm->_state->setVar(cmd.args[1], value);
1158 }
1159
varSubValueMin(Context & c,const Opcode & cmd)1160 void Script::varSubValueMin(Context &c, const Opcode &cmd) {
1161 debugC(kDebugScript, "Opcode %d: Substract value %d from var %d with min value %d",
1162 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1163
1164 int32 value = _vm->_state->getVar(cmd.args[1]);
1165
1166 value -= cmd.args[0];
1167
1168 if (value < cmd.args[2])
1169 value = cmd.args[2];
1170
1171 _vm->_state->setVar(cmd.args[1], value);
1172 }
1173
varZeroRange(Context & c,const Opcode & cmd)1174 void Script::varZeroRange(Context &c, const Opcode &cmd) {
1175 debugC(kDebugScript, "Opcode %d: Set vars from %d to %d to zero", cmd.op, cmd.args[0], cmd.args[1]);
1176
1177 if (cmd.args[0] > cmd.args[1])
1178 error("Opcode %d, Incorrect range, %d -> %d", cmd.op, cmd.args[0], cmd.args[1]);
1179
1180 for (int16 i = cmd.args[0]; i <= cmd.args[1]; i++)
1181 _vm->_state->setVar(i, 0);
1182 }
1183
varCopyRange(Context & c,const Opcode & cmd)1184 void Script::varCopyRange(Context &c, const Opcode &cmd) {
1185 debugC(kDebugScript, "Opcode %d: Copy vars from %d to %d, length: %d",
1186 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1187
1188 if (cmd.args[2] <= 0)
1189 return;
1190
1191 for (int16 i = 0; i < cmd.args[2]; i++)
1192 _vm->_state->setVar(cmd.args[1] + i, _vm->_state->getVar(cmd.args[0] + i));
1193 }
1194
varSetRange(Context & c,const Opcode & cmd)1195 void Script::varSetRange(Context &c, const Opcode &cmd) {
1196 debugC(kDebugScript, "Opcode %d: Set vars from %d to %d to val %d",
1197 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1198
1199 if (cmd.args[0] > cmd.args[1])
1200 error("Opcode %d, Incorrect range, %d -> %d", cmd.op, cmd.args[0], cmd.args[1]);
1201
1202 for (int16 i = cmd.args[0]; i <= cmd.args[1]; i++)
1203 _vm->_state->setVar(i, cmd.args[2]);
1204 }
1205
varIncrementMaxTen(Context & c,const Opcode & cmd)1206 void Script::varIncrementMaxTen(Context &c, const Opcode &cmd) {
1207 debugC(kDebugScript, "Opcode %d: Increment var %d max 10", cmd.op, cmd.args[0]);
1208
1209 int32 value = _vm->_state->getVar(cmd.args[0]);
1210
1211 value++;
1212
1213 if (value == 10)
1214 value = 1;
1215
1216 _vm->_state->setVar(cmd.args[0], value);
1217 }
1218
varAddValue(Context & c,const Opcode & cmd)1219 void Script::varAddValue(Context &c, const Opcode &cmd) {
1220 debugC(kDebugScript, "Opcode %d: Add value %d to var %d", cmd.op, cmd.args[0], cmd.args[1]);
1221
1222 int32 value = _vm->_state->getVar(cmd.args[1]);
1223 value += cmd.args[0];
1224 _vm->_state->setVar(cmd.args[1], value);
1225 }
1226
varArrayAddValue(Context & c,const Opcode & cmd)1227 void Script::varArrayAddValue(Context &c, const Opcode &cmd) {
1228 debugC(kDebugScript, "Opcode %d: Add value %d to array base var %d item var %d",
1229 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1230
1231 int32 value = _vm->_state->getVar(cmd.args[1] + _vm->_state->getVar(cmd.args[2]));
1232 value += cmd.args[0];
1233 _vm->_state->setVar(cmd.args[1] + _vm->_state->getVar(cmd.args[2]), value);
1234 }
1235
varAddVarValue(Context & c,const Opcode & cmd)1236 void Script::varAddVarValue(Context &c, const Opcode &cmd) {
1237 debugC(kDebugScript, "Opcode %d: Add var %d value to var %d", cmd.op, cmd.args[0], cmd.args[1]);
1238
1239 int32 value = _vm->_state->getVar(cmd.args[1]);
1240 value += _vm->_state->getVar(cmd.args[0]);
1241 _vm->_state->setVar(cmd.args[1], value);
1242 }
1243
varSubValue(Context & c,const Opcode & cmd)1244 void Script::varSubValue(Context &c, const Opcode &cmd) {
1245 debugC(kDebugScript, "Opcode %d: Substract value %d to var %d", cmd.op, cmd.args[0], cmd.args[1]);
1246
1247 int32 value = _vm->_state->getVar(cmd.args[1]);
1248 value -= cmd.args[0];
1249 _vm->_state->setVar(cmd.args[1], value);
1250 }
1251
varSubVarValue(Context & c,const Opcode & cmd)1252 void Script::varSubVarValue(Context &c, const Opcode &cmd) {
1253 debugC(kDebugScript, "Opcode %d: Substract var %d value to var %d", cmd.op, cmd.args[0], cmd.args[1]);
1254
1255 int32 value = _vm->_state->getVar(cmd.args[1]);
1256 value -= _vm->_state->getVar(cmd.args[0]);
1257 _vm->_state->setVar(cmd.args[1], value);
1258 }
1259
varModValue(Context & c,const Opcode & cmd)1260 void Script::varModValue(Context &c, const Opcode &cmd) {
1261 debugC(kDebugScript, "Opcode %d: Apply modulo %d to var %d", cmd.op, cmd.args[1], cmd.args[0]);
1262
1263 int32 value = _vm->_state->getVar(cmd.args[0]);
1264 value %= cmd.args[1];
1265 _vm->_state->setVar(cmd.args[0], value);
1266 }
1267
varMultValue(Context & c,const Opcode & cmd)1268 void Script::varMultValue(Context &c, const Opcode &cmd) {
1269 debugC(kDebugScript, "Opcode %d: Multiply var %d by value %d", cmd.op, cmd.args[0], cmd.args[1]);
1270
1271 int32 value = _vm->_state->getVar(cmd.args[0]);
1272 value *= cmd.args[1];
1273 _vm->_state->setVar(cmd.args[0], value);
1274 }
1275
varMultVarValue(Context & c,const Opcode & cmd)1276 void Script::varMultVarValue(Context &c, const Opcode &cmd) {
1277 debugC(kDebugScript, "Opcode %d: Multiply var %d by var %d value", cmd.op, cmd.args[0], cmd.args[1]);
1278
1279 int32 value = _vm->_state->getVar(cmd.args[0]);
1280 value *= _vm->_state->getVar(cmd.args[1]);
1281 _vm->_state->setVar(cmd.args[0], value);
1282 }
1283
varDivValue(Context & c,const Opcode & cmd)1284 void Script::varDivValue(Context &c, const Opcode &cmd) {
1285 debugC(kDebugScript, "Opcode %d: Divide var %d by value %d", cmd.op, cmd.args[0], cmd.args[1]);
1286
1287 int32 value = _vm->_state->getVar(cmd.args[0]);
1288 value /= cmd.args[1];
1289 _vm->_state->setVar(cmd.args[0], value);
1290 }
1291
varDivVarValue(Context & c,const Opcode & cmd)1292 void Script::varDivVarValue(Context &c, const Opcode &cmd) {
1293 debugC(kDebugScript, "Opcode %d: Divide var %d by var %d value", cmd.op, cmd.args[0], cmd.args[1]);
1294
1295 int32 value = _vm->_state->getVar(cmd.args[0]);
1296 value /= _vm->_state->getVar(cmd.args[1]);
1297 _vm->_state->setVar(cmd.args[0], value);
1298 }
1299
varCrossMultiplication(Context & c,const Opcode & cmd)1300 void Script::varCrossMultiplication(Context &c, const Opcode &cmd) {
1301 debugC(kDebugScript, "Opcode %d: Cross multiply var %d from range %d %d to range %d %d",
1302 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
1303
1304 int32 value = _vm->_state->getVar(cmd.args[0]);
1305
1306 if (value == 0)
1307 return;
1308
1309 int32 temp = abs(value) - cmd.args[1];
1310 temp *= (cmd.args[4] - cmd.args[3]) / (cmd.args[2] - cmd.args[1]);
1311 temp += cmd.args[3];
1312
1313 _vm->_state->setVar(cmd.args[0], value > 0 ? temp : -temp);
1314 }
1315
varMinValue(Context & c,const Opcode & cmd)1316 void Script::varMinValue(Context &c, const Opcode &cmd) {
1317 debugC(kDebugScript, "Opcode %d: Set var %d to min between %d and var value", cmd.op, cmd.args[0], cmd.args[1]);
1318
1319 int32 value = _vm->_state->getVar(cmd.args[0]);
1320
1321 if (value > cmd.args[1])
1322 value = cmd.args[1];
1323
1324 _vm->_state->setVar(cmd.args[0], value);
1325 }
1326
varClipValue(Context & c,const Opcode & cmd)1327 void Script::varClipValue(Context &c, const Opcode &cmd) {
1328 debugC(kDebugScript, "Opcode %d: Clip var %d value between %d and %d", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1329
1330 int32 value = _vm->_state->getVar(cmd.args[0]);
1331
1332 value = CLIP<int32>(value, cmd.args[1], cmd.args[2]);
1333
1334 _vm->_state->setVar(cmd.args[0], value);
1335 }
1336
varClipChangeBound(Context & c,const Opcode & cmd)1337 void Script::varClipChangeBound(Context &c, const Opcode &cmd) {
1338 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]);
1339
1340 int32 value = _vm->_state->getVar(cmd.args[0]);
1341
1342 if (value < cmd.args[1])
1343 value = cmd.args[2];
1344
1345 if (value > cmd.args[2])
1346 value = cmd.args[1];
1347
1348 _vm->_state->setVar(cmd.args[0], value);
1349 }
1350
varAbsoluteSubValue(Context & c,const Opcode & cmd)1351 void Script::varAbsoluteSubValue(Context &c, const Opcode &cmd) {
1352 debugC(kDebugScript, "Opcode %d: Take absolute value of var %d and substract %d", cmd.op, cmd.args[0], cmd.args[1]);
1353
1354 int32 value = _vm->_state->getVar(cmd.args[0]);
1355
1356 value = abs(value) - cmd.args[1];
1357
1358 _vm->_state->setVar(cmd.args[0], value);
1359 }
1360
varAbsoluteSubVar(Context & c,const Opcode & cmd)1361 void Script::varAbsoluteSubVar(Context &c, const Opcode &cmd) {
1362 debugC(kDebugScript, "Opcode %d: Take absolute value of var %d and substract var %d", cmd.op, cmd.args[0], cmd.args[1]);
1363
1364 int32 value = _vm->_state->getVar(cmd.args[0]);
1365
1366 value = abs(value) - _vm->_state->getVar(cmd.args[1]);
1367
1368 _vm->_state->setVar(cmd.args[0], value);
1369 }
1370
varRatioToPercents(Context & c,const Opcode & cmd)1371 void Script::varRatioToPercents(Context &c, const Opcode &cmd) {
1372 debugC(kDebugScript, "Opcode %d: Convert var %d to percents (max value %d, tare weight %d)",
1373 cmd.op, cmd.args[0], cmd.args[2], cmd.args[1]);
1374
1375 int32 value = _vm->_state->getVar(cmd.args[0]);
1376
1377 value = 100 * (cmd.args[2] - abs(value - cmd.args[1])) / cmd.args[2];
1378 value = MAX<int32>(0, value);
1379
1380 _vm->_state->setVar(cmd.args[0], value);
1381 }
1382
1383
varRotateValue3(Context & c,const Opcode & cmd)1384 void Script::varRotateValue3(Context &c, const Opcode &cmd) {
1385 debugC(kDebugScript, "Opcode %d: Var take next value, var %d values %d %d %d",
1386 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
1387
1388 int32 value = _vm->_state->getVar(cmd.args[0]);
1389
1390 if (value == cmd.args[1]) {
1391 value = cmd.args[2];
1392 } else if (value == cmd.args[2]) {
1393 value = cmd.args[3];
1394 } else {
1395 value = cmd.args[1];
1396 }
1397
1398 _vm->_state->setVar(cmd.args[0], value);
1399 }
1400
ifElse(Context & c,const Opcode & cmd)1401 void Script::ifElse(Context &c, const Opcode &cmd) {
1402 debugC(kDebugScript, "Opcode %d: Else", cmd.op);
1403
1404 c.result = true;
1405 c.endScript = true;
1406 }
1407
goToElse(Context & c)1408 void Script::goToElse(Context &c) {
1409 const Command &elseCommand = findCommandByProc(&Script::ifElse);
1410
1411 // Go to next command until an else statement is met
1412 do {
1413 c.op++;
1414 } while (c.op != c.script->end() && c.op->op != elseCommand.op);
1415 }
1416
ifCondition(Context & c,const Opcode & cmd)1417 void Script::ifCondition(Context &c, const Opcode &cmd) {
1418 debugC(kDebugScript, "Opcode %d: If condition %d", cmd.op, cmd.args[0]);
1419
1420 if (_vm->_state->evaluate(cmd.args[0]))
1421 return;
1422
1423 goToElse(c);
1424 }
1425
ifCond1AndCond2(Context & c,const Opcode & cmd)1426 void Script::ifCond1AndCond2(Context &c, const Opcode &cmd) {
1427 debugC(kDebugScript, "Opcode %d: If cond %d and cond %d", cmd.op, cmd.args[0], cmd.args[1]);
1428
1429 if (_vm->_state->evaluate(cmd.args[0])
1430 && _vm->_state->evaluate(cmd.args[1]))
1431 return;
1432
1433 goToElse(c);
1434 }
1435
ifCond1OrCond2(Context & c,const Opcode & cmd)1436 void Script::ifCond1OrCond2(Context &c, const Opcode &cmd) {
1437 debugC(kDebugScript, "Opcode %d: If cond %d or cond %d", cmd.op, cmd.args[0], cmd.args[1]);
1438
1439 if (_vm->_state->evaluate(cmd.args[0])
1440 || _vm->_state->evaluate(cmd.args[1]))
1441 return;
1442
1443 goToElse(c);
1444 }
1445
ifOneVarSetInRange(Context & c,const Opcode & cmd)1446 void Script::ifOneVarSetInRange(Context &c, const Opcode &cmd) {
1447 debugC(kDebugScript, "Opcode %d: If one var set int range %d %d",
1448 cmd.op, cmd.args[0], cmd.args[1]);
1449
1450 uint16 var = cmd.args[0];
1451 uint16 end = cmd.args[1];
1452
1453 if (var > end) {
1454 goToElse(c);
1455 return;
1456 }
1457
1458 bool result = false;
1459
1460 do {
1461 result |= _vm->_state->getVar(var) != 0;
1462 var++;
1463 } while (var <= end);
1464
1465 if (result)
1466 return;
1467
1468 goToElse(c);
1469 }
1470
ifVarEqualsValue(Context & c,const Opcode & cmd)1471 void Script::ifVarEqualsValue(Context &c, const Opcode &cmd) {
1472 debugC(kDebugScript, "Opcode %d: If var %d equals value %d", cmd.op, cmd.args[0], cmd.args[1]);
1473
1474 if (_vm->_state->getVar(cmd.args[0]) == cmd.args[1])
1475 return;
1476
1477 goToElse(c);
1478 }
1479
ifVarNotEqualsValue(Context & c,const Opcode & cmd)1480 void Script::ifVarNotEqualsValue(Context &c, const Opcode &cmd) {
1481 debugC(kDebugScript, "Opcode %d: If var %d not equals value %d", cmd.op, cmd.args[0], cmd.args[1]);
1482
1483 if (_vm->_state->getVar(cmd.args[0]) != cmd.args[1])
1484 return;
1485
1486 goToElse(c);
1487 }
1488
ifVar1EqualsVar2(Context & c,const Opcode & cmd)1489 void Script::ifVar1EqualsVar2(Context &c, const Opcode &cmd) {
1490 debugC(kDebugScript, "Opcode %d: If var %d equals var %d", cmd.op, cmd.args[0], cmd.args[1]);
1491
1492 if (_vm->_state->getVar(cmd.args[0]) == _vm->_state->getVar(cmd.args[1]))
1493 return;
1494
1495 goToElse(c);
1496 }
1497
ifVar1NotEqualsVar2(Context & c,const Opcode & cmd)1498 void Script::ifVar1NotEqualsVar2(Context &c, const Opcode &cmd) {
1499 debugC(kDebugScript, "Opcode %d: If var %d not equals var %d", cmd.op, cmd.args[0], cmd.args[1]);
1500
1501 if (_vm->_state->getVar(cmd.args[0]) != _vm->_state->getVar(cmd.args[1]))
1502 return;
1503
1504 goToElse(c);
1505 }
1506
ifVarSupEqValue(Context & c,const Opcode & cmd)1507 void Script::ifVarSupEqValue(Context &c, const Opcode &cmd) {
1508 debugC(kDebugScript, "Opcode %d: If var %d >= value %d", cmd.op, cmd.args[0], cmd.args[1]);
1509
1510 if (_vm->_state->getVar(cmd.args[0]) >= cmd.args[1])
1511 return;
1512
1513 goToElse(c);
1514 }
1515
ifVarInfEqValue(Context & c,const Opcode & cmd)1516 void Script::ifVarInfEqValue(Context &c, const Opcode &cmd) {
1517 debugC(kDebugScript, "Opcode %d: If var %d <= value %d", cmd.op, cmd.args[0], cmd.args[1]);
1518
1519 if (_vm->_state->getVar(cmd.args[0]) <= cmd.args[1])
1520 return;
1521
1522 goToElse(c);
1523 }
1524
ifVarInRange(Context & c,const Opcode & cmd)1525 void Script::ifVarInRange(Context &c, const Opcode &cmd) {
1526 debugC(kDebugScript, "Opcode %d: If var %d in range %d %d",
1527 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1528
1529 int32 value = _vm->_state->getVar(cmd.args[0]);
1530 if(value >= cmd.args[1] && value <= cmd.args[2])
1531 return;
1532
1533 goToElse(c);
1534 }
1535
ifVarNotInRange(Context & c,const Opcode & cmd)1536 void Script::ifVarNotInRange(Context &c, const Opcode &cmd) {
1537 debugC(kDebugScript, "Opcode %d: If var %d not in range %d %d",
1538 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1539
1540 int32 value = _vm->_state->getVar(cmd.args[0]);
1541 if(value < cmd.args[1] || value > cmd.args[2])
1542 return;
1543
1544 goToElse(c);
1545 }
1546
ifVar1SupEqVar2(Context & c,const Opcode & cmd)1547 void Script::ifVar1SupEqVar2(Context &c, const Opcode &cmd) {
1548 debugC(kDebugScript, "Opcode %d: If var %d >= var %d", cmd.op, cmd.args[0], cmd.args[1]);
1549
1550 if (_vm->_state->getVar(cmd.args[0]) >= _vm->_state->getVar(cmd.args[1]))
1551 return;
1552
1553 goToElse(c);
1554 }
1555
ifVar1SupVar2(Context & c,const Opcode & cmd)1556 void Script::ifVar1SupVar2(Context &c, const Opcode &cmd) {
1557 debugC(kDebugScript, "Opcode %d: If var %d > var %d", cmd.op, cmd.args[0], cmd.args[1]);
1558
1559 if (_vm->_state->getVar(cmd.args[0]) > _vm->_state->getVar(cmd.args[1]))
1560 return;
1561
1562 goToElse(c);
1563 }
1564
ifVar1InfEqVar2(Context & c,const Opcode & cmd)1565 void Script::ifVar1InfEqVar2(Context &c, const Opcode &cmd) {
1566 debugC(kDebugScript, "Opcode %d: If var %d <= var %d", cmd.op, cmd.args[0], cmd.args[1]);
1567
1568 if (_vm->_state->getVar(cmd.args[0]) <= _vm->_state->getVar(cmd.args[1]))
1569 return;
1570
1571 goToElse(c);
1572 }
1573
ifVarHasAllBitsSet(Context & c,const Opcode & cmd)1574 void Script::ifVarHasAllBitsSet(Context &c, const Opcode &cmd) {
1575 debugC(kDebugScript, "Opcode %d: If var %d & val %d == val %d",
1576 cmd.op, cmd.args[0], cmd.args[1], cmd.args[1]);
1577
1578 if ((_vm->_state->getVar(cmd.args[0]) & cmd.args[1]) == cmd.args[1])
1579 return;
1580
1581 goToElse(c);
1582 }
1583
ifVarHasNoBitsSet(Context & c,const Opcode & cmd)1584 void Script::ifVarHasNoBitsSet(Context &c, const Opcode &cmd) {
1585 debugC(kDebugScript, "Opcode %d: If var %d & val %d == 0",
1586 cmd.op, cmd.args[0], cmd.args[1]);
1587
1588 if ((_vm->_state->getVar(cmd.args[0]) & cmd.args[1]) == 0)
1589 return;
1590
1591 goToElse(c);
1592 }
1593
ifVarHasSomeBitsSet(Context & c,const Opcode & cmd)1594 void Script::ifVarHasSomeBitsSet(Context &c, const Opcode &cmd) {
1595 debugC(kDebugScript, "Opcode %d: If var %d & val %d == val %d",
1596 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
1597
1598 if ((_vm->_state->getVar(cmd.args[0]) & cmd.args[1]) == cmd.args[2])
1599 return;
1600
1601 goToElse(c);
1602 }
1603
ifHeadingInRange(Context & c,const Opcode & cmd)1604 void Script::ifHeadingInRange(Context &c, const Opcode &cmd) {
1605 debugC(kDebugScript, "Opcode %d: If heading in range %d -> %d",
1606 cmd.op, cmd.args[0], cmd.args[1]);
1607
1608 float heading = _vm->_state->getLookAtHeading();
1609
1610 if (cmd.args[1] > cmd.args[0]) {
1611 // If heading in range
1612 if (heading > cmd.args[0] && heading < cmd.args[1]) {
1613 return;
1614 }
1615 } else {
1616 // If heading *not* in range
1617 if (heading > cmd.args[0] || heading < cmd.args[1]) {
1618 return;
1619 }
1620 }
1621
1622 goToElse(c);
1623 }
1624
ifPitchInRange(Context & c,const Opcode & cmd)1625 void Script::ifPitchInRange(Context &c, const Opcode &cmd) {
1626 debugC(kDebugScript, "Opcode %d: If pitch in range %d -> %d",
1627 cmd.op, cmd.args[0], cmd.args[1]);
1628
1629 float pitch = _vm->_state->getLookAtPitch();
1630
1631 // If pitch in range
1632 if (pitch > cmd.args[0] && pitch < cmd.args[1])
1633 return;
1634
1635 goToElse(c);
1636 }
1637
ifHeadingPitchInRect(Context & c,const Opcode & cmd)1638 void Script::ifHeadingPitchInRect(Context &c, const Opcode &cmd) {
1639 debugC(kDebugScript, "Opcode %d: If heading in range %d -> %d",
1640 cmd.op, cmd.args[0], cmd.args[1]);
1641
1642 float heading = _vm->_state->getLookAtHeading();
1643 float pitch = _vm->_state->getLookAtPitch();
1644
1645 // If pitch in range
1646 if (pitch <= cmd.args[0] || pitch >= cmd.args[1]) {
1647 goToElse(c);
1648 return;
1649 }
1650
1651 if (cmd.args[3] > cmd.args[2]) {
1652 // If heading in range
1653 if (heading > cmd.args[2] && heading < cmd.args[3])
1654 return;
1655 } else {
1656 // If heading *not* in range
1657 if (heading > cmd.args[2] || heading < cmd.args[3])
1658 return;
1659 }
1660
1661 goToElse(c);
1662 }
1663
ifMouseIsInRect(Context & c,const Opcode & cmd)1664 void Script::ifMouseIsInRect(Context &c, const Opcode &cmd) {
1665 debugC(kDebugScript, "Opcode %d: If mouse in rect l%d t%d w%d h%d",
1666 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
1667
1668 Common::Rect r = Common::Rect(cmd.args[2], cmd.args[3]);
1669 r.translate(cmd.args[0], cmd.args[1]);
1670
1671 Common::Point mouse = _vm->_cursor->getPosition(false);
1672 mouse = _vm->_scene->scalePoint(mouse);
1673
1674 if (r.contains(mouse))
1675 return;
1676
1677 goToElse(c);
1678 }
1679
leverDrag(Context & c,const Opcode & cmd)1680 void Script::leverDrag(Context &c, const Opcode &cmd) {
1681 debugC(kDebugScript, "Opcode %d: Drag lever for var %d with script %d", cmd.op, cmd.args[4], cmd.args[6]);
1682
1683 int16 minPosX = cmd.args[0];
1684 int16 minPosY = cmd.args[1];
1685 int16 maxPosX = cmd.args[2];
1686 int16 maxPosY = cmd.args[3];
1687 int16 var = cmd.args[4];
1688 int16 numPositions = cmd.args[5];
1689 int16 script = cmd.args[6];
1690
1691 _vm->_cursor->changeCursor(2);
1692
1693 int16 previousPosition = -1;
1694 while (true) {
1695 float ratioPosition = 0.0;
1696 // Compute the distance to the minimum lever point
1697 // and divide it by the lever movement amplitude
1698 if (_vm->_state->getViewType() == kCube) {
1699 float pitch, heading;
1700 _vm->_cursor->getDirection(pitch, heading);
1701
1702 float amplitude = sqrt(Math::square(maxPosX - minPosX) + Math::square(maxPosY - minPosY));
1703 float distanceToMin = sqrt(Math::square(pitch - minPosX) + Math::square(heading - minPosY));
1704 float distanceToMax = sqrt(Math::square(pitch - maxPosX) + Math::square(heading - maxPosY));
1705
1706 ratioPosition = distanceToMax < amplitude ? distanceToMin / amplitude : 0.0;
1707 } else {
1708 Common::Point mouse = _vm->_cursor->getPosition(false);
1709 mouse = _vm->_scene->scalePoint(mouse);
1710 int16 amplitude;
1711 int16 pixelPosition;
1712
1713 if (minPosX == maxPosX) {
1714 // Vertical slider
1715 amplitude = maxPosY - minPosY;
1716 pixelPosition = mouse.y - minPosY;
1717 } else {
1718 // Horizontal slider
1719 amplitude = maxPosX - minPosX;
1720 pixelPosition = mouse.x - minPosX;
1721 }
1722
1723 ratioPosition = pixelPosition / (float) amplitude;
1724 }
1725
1726 int16 position = (int16)(ratioPosition * (numPositions + 1));
1727 position = CLIP<int16>(position, 1, numPositions);
1728
1729 if (_vm->_state->getDragLeverLimited()) {
1730 int16 minPosition = _vm->_state->getDragLeverLimitMin();
1731 int16 maxPosition = _vm->_state->getDragLeverLimitMax();
1732 position = CLIP(position, minPosition, maxPosition);
1733 }
1734
1735 // Set new lever position
1736 _vm->_state->setVar(var, position);
1737
1738 // Draw a frame
1739 _vm->processInput(false);
1740 _vm->drawFrame();
1741
1742 bool mousePressed = (_vm->getEventManager()->getButtonState() & Common::EventManager::LBUTTON) != 0;
1743 _vm->_state->setDragEnded(!mousePressed);
1744
1745 if (_vm->_state->getDragLeverSpeed()) {
1746 debugC(kDebugScript, "Interaction with var 58 is missing in opcode 127.");
1747 return;
1748 }
1749
1750 if (script && (position != previousPosition || !mousePressed)) {
1751 _vm->_state->setVar(var, position);
1752 _vm->runScriptsFromNode(abs(script));
1753 }
1754
1755 if (script > 0) {
1756 // In this case the script is executed only if the lever position changed.
1757 // Otherwise it is executed every frame
1758 previousPosition = position;
1759 }
1760
1761 if (!mousePressed || _vm->shouldQuit())
1762 break;
1763 }
1764
1765 _vm->_state->setDragLeverLimited(0);
1766 _vm->_state->setDragLeverSpeed(0);
1767 }
1768
leverDragPositions(Context & c,const Opcode & cmd)1769 void Script::leverDragPositions(Context &c, const Opcode &cmd) {
1770 debugC(kDebugScript, "Opcode %d: Drag lever for var %d with script %d", cmd.op, cmd.args[0], cmd.args[1]);
1771
1772 int16 var = cmd.args[0];
1773 int16 script = cmd.args[1];
1774 uint16 numPositions = (cmd.args.size() - 3) / 3;
1775
1776 if (cmd.args[2 + numPositions * 3] != -1)
1777 error("leverDragPositions no end marker found");
1778
1779 _vm->_cursor->changeCursor(2);
1780
1781 int16 previousPosition = -1;
1782 while (true) {
1783 float pitch, heading;
1784 _vm->_cursor->getDirection(pitch, heading);
1785
1786 float minDistance = 180.0;
1787 int16 position = 0;
1788
1789 // Find the lever position where the distance between the lever
1790 // and the mouse is minimal, by trying every possible position.
1791 for (uint i = 0; i < numPositions; i++) {
1792 float posPitch = cmd.args[2 + i * 3 + 0] * 0.1;
1793 float posHeading = cmd.args[2 + i * 3 + 1] * 0.1;
1794
1795 // Distance between the mouse and the lever
1796 float distance = sqrt(Math::square(pitch - posPitch) + Math::square(heading - posHeading));
1797
1798 if (distance < minDistance) {
1799 minDistance = distance;
1800 position = cmd.args[2 + i * 3 + 2];
1801 }
1802 }
1803
1804 // Set new lever position
1805 _vm->_state->setVar(var, position);
1806
1807 // Draw a frame
1808 _vm->processInput(false);
1809 _vm->drawFrame();
1810
1811 bool mousePressed = _vm->inputValidatePressed();
1812 _vm->_state->setDragEnded(!mousePressed);
1813
1814 if (_vm->_state->getDragLeverSpeed()) {
1815 debugC(kDebugScript, "Interaction with var 58 is missing in opcode 132.");
1816 return;
1817 }
1818
1819 if (script && (position != previousPosition || !mousePressed)) {
1820 _vm->_state->setVar(var, position);
1821 _vm->runScriptsFromNode(abs(script));
1822 }
1823
1824 if (script > 0) {
1825 // In this case the script is executed only if the lever position changed.
1826 // Otherwise it is executed every frame
1827 previousPosition = position;
1828 }
1829
1830 if (!mousePressed || _vm->shouldQuit())
1831 break;
1832 }
1833
1834 _vm->_state->setDragLeverSpeed(0);
1835 }
1836
leverDragXY(Context & c,const Opcode & cmd)1837 void Script::leverDragXY(Context &c, const Opcode &cmd) {
1838 debugC(kDebugScript, "Opcode %d: Drag 2D lever and update X (var %d) and Y (var %d) coordinates, while running script %d", cmd.op, cmd.args[0], cmd.args[1], cmd.args[4]);
1839
1840 uint16 varX = cmd.args[0];
1841 uint16 varY = cmd.args[1];
1842 uint16 scale = cmd.args[2];
1843 uint16 maxLeverPosition = cmd.args[3];
1844 uint16 script = _vm->_state->valueOrVarValue(cmd.args[4]);
1845
1846 Common::Point mouseInit = _vm->_cursor->getPosition(false);
1847 mouseInit = _vm->_scene->scalePoint(mouseInit);
1848
1849 _vm->_cursor->changeCursor(2);
1850
1851 bool mousePressed = true;
1852 do {
1853 Common::Point mouse = _vm->_cursor->getPosition(false);
1854 mouse = _vm->_scene->scalePoint(mouse);
1855 int16 distanceX = (mouseInit.x - mouse.x) / scale;
1856 int16 distanceY = (mouseInit.y - mouse.y) / scale;
1857
1858 distanceX = CLIP<int16>(distanceX, -maxLeverPosition, maxLeverPosition);
1859 distanceY = CLIP<int16>(distanceY, -maxLeverPosition, maxLeverPosition);
1860
1861 // Set lever position variables
1862 _vm->_state->setVar(varX, distanceX);
1863 _vm->_state->setVar(varY, distanceY);
1864
1865 // Draw a frame
1866 _vm->processInput(false);
1867 _vm->drawFrame();
1868
1869 mousePressed = _vm->getEventManager()->getButtonState() & Common::EventManager::LBUTTON;
1870 _vm->_state->setDragEnded(!mousePressed);
1871
1872 // Run script
1873 if (script)
1874 _vm->runScriptsFromNode(script);
1875 } while (mousePressed && !_vm->shouldQuit());
1876 }
1877
itemDrag(Context & c,const Opcode & cmd)1878 void Script::itemDrag(Context &c, const Opcode &cmd) {
1879 debugC(kDebugScript, "Opcode %d: Drag item %d", cmd.op, cmd.args[4]);
1880 _vm->dragItem(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
1881 }
1882
runScriptWhileDragging(Context & c,const Opcode & cmd)1883 void Script::runScriptWhileDragging(Context &c, const Opcode &cmd) {
1884 debugC(kDebugScript, "Opcode %d: While dragging lever, run script %d", cmd.op, cmd.args[7]);
1885
1886 uint16 script = _vm->_state->valueOrVarValue(cmd.args[7]);
1887 uint16 maxDistance = cmd.args[6];
1888 uint16 maxLeverPosition = cmd.args[5];
1889 int16 lastLeverPosition = _vm->_state->getVar(cmd.args[4]);
1890 int16 leverHeight = cmd.args[3];
1891 int16 leverWidth = cmd.args[2];
1892
1893 _vm->_cursor->changeCursor(2);
1894
1895 bool dragWithDirectionKeys = _vm->_state->hasVarDragWithDirectionKeys()
1896 && _vm->_state->getDragWithDirectionKeys();
1897
1898 bool dragging = true;
1899 do {
1900 dragging = _vm->getEventManager()->getButtonState() & Common::EventManager::LBUTTON;
1901 dragging |= _vm->_state->hasVarGamePadActionPressed() && _vm->_state->getGamePadActionPressed();
1902 _vm->_state->setDragEnded(!dragging);
1903
1904 _vm->processInput(false);
1905 _vm->drawFrame();
1906
1907 if (!dragWithDirectionKeys) {
1908 // Distance between the mouse and the lever
1909 Common::Point mouse = _vm->_cursor->getPosition(false);
1910 mouse = _vm->_scene->scalePoint(mouse);
1911 int16 distanceX = mouse.x - leverWidth / 2 - _vm->_state->getVar(cmd.args[0]);
1912 int16 distanceY = mouse.y - leverHeight / 2 - _vm->_state->getVar(cmd.args[1]);
1913 float distance = sqrt((float) distanceX * distanceX + distanceY * distanceY);
1914
1915 uint16 bestPosition = lastLeverPosition;
1916 if (distance > maxDistance) {
1917 _vm->_state->setDragLeverPositionChanged(false);
1918 } else {
1919 // Find the lever position where the distance between the lever
1920 // and the mouse is minimal, by trying every possible position.
1921 float minDistance = 1000;
1922 for (uint i = 0; i < maxLeverPosition; i++) {
1923 _vm->_state->setDragPositionFound(false);
1924
1925 _vm->_state->setVar(cmd.args[4], i);
1926 _vm->runScriptsFromNode(script);
1927
1928 mouse = _vm->_cursor->getPosition(false);
1929 mouse = _vm->_scene->scalePoint(mouse);
1930 distanceX = mouse.x - leverWidth / 2 - _vm->_state->getVar(cmd.args[0]);
1931 distanceY = mouse.y - leverHeight / 2 - _vm->_state->getVar(cmd.args[1]);
1932 distance = sqrt((float) distanceX * distanceX + distanceY * distanceY);
1933
1934 if (distance < minDistance) {
1935 minDistance = distance;
1936 bestPosition = i;
1937 }
1938 }
1939 _vm->_state->setDragLeverPositionChanged(bestPosition != lastLeverPosition);
1940 }
1941
1942 // Set the lever position to the best position
1943 _vm->_state->setDragPositionFound(true);
1944 _vm->_state->setVar(cmd.args[4], bestPosition);
1945 } else {
1946 uint16 previousPosition = _vm->_state->getVar(cmd.args[4]);
1947 uint16 position = previousPosition;
1948
1949 if (_vm->_state->getGamePadLeftPressed()) {
1950 position--;
1951 } else if (_vm->_state->getGamePadRightPressed()) {
1952 position++;
1953 }
1954
1955 position = CLIP<int16>(position, 0, maxLeverPosition);
1956 _vm->_state->setVar(cmd.args[4], position);
1957 _vm->_state->setDragLeverPositionChanged(position != previousPosition);
1958 }
1959
1960 _vm->runScriptsFromNode(script);
1961 _vm->processInput(false);
1962 _vm->drawFrame();
1963 } while (dragging && !_vm->shouldQuit());
1964
1965 if (dragWithDirectionKeys) {
1966 _vm->_state->setDragWithDirectionKeys(false);
1967 }
1968
1969 _vm->_state->setDragPositionFound(false);
1970 }
1971
chooseNextNode(Context & c,const Opcode & cmd)1972 void Script::chooseNextNode(Context &c, const Opcode &cmd) {
1973 debugC(kDebugScript, "Opcode %d: Choose next node using condition %d", cmd.op, cmd.args[0]);
1974
1975 if (_vm->_state->evaluate(cmd.args[0]))
1976 _vm->_state->setLocationNextNode(cmd.args[1]);
1977 else
1978 _vm->_state->setLocationNextNode(cmd.args[2]);
1979 }
1980
goToNodeTransition(Context & c,const Opcode & cmd)1981 void Script::goToNodeTransition(Context &c, const Opcode &cmd) {
1982 debugC(kDebugScript, "Opcode %d: Go to node %d with transition %d", cmd.op, cmd.args[0], cmd.args[1]);
1983
1984 _vm->goToNode(cmd.args[0], static_cast<TransitionType>(cmd.args[1]));
1985 }
1986
goToNodeTrans2(Context & c,const Opcode & cmd)1987 void Script::goToNodeTrans2(Context &c, const Opcode &cmd) {
1988 debugC(kDebugScript, "Opcode %d: Go to node %d", cmd.op, cmd.args[0]);
1989
1990 _vm->goToNode(cmd.args[0], kTransitionNone);
1991 }
1992
goToNodeTrans1(Context & c,const Opcode & cmd)1993 void Script::goToNodeTrans1(Context &c, const Opcode &cmd) {
1994 debugC(kDebugScript, "Opcode %d: Go to node %d", cmd.op, cmd.args[0]);
1995
1996 _vm->goToNode(cmd.args[0], kTransitionFade);
1997 }
1998
goToRoomNode(Context & c,const Opcode & cmd)1999 void Script::goToRoomNode(Context &c, const Opcode &cmd) {
2000 debugC(kDebugScript, "Opcode %d: Go to room %d, node %d", cmd.op, cmd.args[0], cmd.args[1]);
2001
2002 _vm->_state->setLocationNextRoom(cmd.args[0]);
2003 _vm->_state->setLocationNextNode(cmd.args[1]);
2004
2005 _vm->goToNode(0, kTransitionFade);
2006 }
2007
zipToNode(Context & c,const Opcode & cmd)2008 void Script::zipToNode(Context &c, const Opcode &cmd) {
2009 debugC(kDebugScript, "Opcode %d: Zip to node %d", cmd.op, cmd.args[0]);
2010
2011 _vm->goToNode(cmd.args[0], kTransitionZip);
2012 }
2013
zipToRoomNode(Context & c,const Opcode & cmd)2014 void Script::zipToRoomNode(Context &c, const Opcode &cmd) {
2015 debugC(kDebugScript, "Opcode %d: Zip to room %d, node %d", cmd.op, cmd.args[0], cmd.args[1]);
2016
2017 _vm->_state->setLocationNextRoom(cmd.args[0]);
2018 _vm->_state->setLocationNextNode(cmd.args[1]);
2019
2020 _vm->goToNode(0, kTransitionZip);
2021 }
2022
drawTransition(Context & c,const Opcode & cmd)2023 void Script::drawTransition(Context &c, const Opcode &cmd) {
2024 debugC(kDebugScript, "Opcode %d: Draw transition", cmd.op);
2025
2026 _vm->drawTransition(kTransitionFade);
2027 }
2028
reloadNode(Context & c,const Opcode & cmd)2029 void Script::reloadNode(Context &c, const Opcode &cmd) {
2030 debugC(kDebugScript, "Opcode %d: Reload current node", cmd.op);
2031
2032 _vm->loadNode(0);
2033 _vm->drawFrame();
2034 }
2035
redrawFrame(Context & c,const Opcode & cmd)2036 void Script::redrawFrame(Context &c, const Opcode &cmd) {
2037 debugC(kDebugScript, "Opcode %d: Reload current node", cmd.op);
2038
2039 _vm->drawFrame();
2040 }
2041
moviePlay(Context & c,const Opcode & cmd)2042 void Script::moviePlay(Context &c, const Opcode &cmd) {
2043 debugC(kDebugScript, "Opcode %d: Play movie %d", cmd.op, cmd.args[0]);
2044
2045 _vm->playSimpleMovie(_vm->_state->valueOrVarValue(cmd.args[0]));
2046 }
2047
moviePlaySynchronized(Context & c,const Opcode & cmd)2048 void Script::moviePlaySynchronized(Context &c, const Opcode &cmd) {
2049 debugC(kDebugScript, "Opcode %d: Play movie %d, synchronized with framerate", cmd.op, cmd.args[0]);
2050
2051 _vm->_state->setMovieSynchronized(1);
2052 _vm->playSimpleMovie(_vm->_state->valueOrVarValue(cmd.args[0]));
2053 }
2054
cameraLimitMovement(Context & c,const Opcode & cmd)2055 void Script::cameraLimitMovement(Context &c, const Opcode &cmd) {
2056 debugC(kDebugScript, "Opcode %d: Limit camera movement in a rect", cmd.op);
2057
2058 _vm->_state->limitCubeCamera(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2059 }
2060
cameraFreeMovement(Context & c,const Opcode & cmd)2061 void Script::cameraFreeMovement(Context &c, const Opcode &cmd) {
2062 debugC(kDebugScript, "Opcode %d: Free camera movement from rect", cmd.op);
2063
2064 _vm->_state->freeCubeCamera();
2065 }
2066
cameraLookAt(Context & c,const Opcode & cmd)2067 void Script::cameraLookAt(Context &c, const Opcode &cmd) {
2068 debugC(kDebugScript, "Opcode %d: Camera look at %d %d", cmd.op, cmd.args[0], cmd.args[1]);
2069
2070 float pitch = cmd.args[0];
2071 float heading = cmd.args[1];
2072 _vm->_state->lookAt(pitch, heading);
2073 }
2074
cameraLookAtVar(Context & c,const Opcode & cmd)2075 void Script::cameraLookAtVar(Context &c, const Opcode &cmd) {
2076 debugC(kDebugScript, "Opcode %d: Camera look at value of var %d", cmd.op, cmd.args[0]);
2077
2078 float pitch = _vm->_state->getVar(cmd.args[0]) / 1000.0;
2079 float heading = _vm->_state->getVar(cmd.args[0] + 1) / 1000.0;
2080 _vm->_state->lookAt(pitch, heading);
2081 }
2082
cameraGetLookAt(Context & c,const Opcode & cmd)2083 void Script::cameraGetLookAt(Context &c, const Opcode &cmd) {
2084 debugC(kDebugScript, "Opcode %d: Save camera look at to var %d", cmd.op, cmd.args[0]);
2085
2086 float pitch = _vm->_state->getLookAtPitch() * 1000.0;
2087 float heading = _vm->_state->getLookAtHeading() * 1000.0;
2088
2089 _vm->_state->setVar(cmd.args[0],(int32) pitch);
2090 _vm->_state->setVar(cmd.args[0] + 1, (int32)heading);
2091 }
2092
lookAtMovieStartImmediate(Context & c,const Opcode & cmd)2093 void Script::lookAtMovieStartImmediate(Context &c, const Opcode &cmd) {
2094 debugC(kDebugScript, "Opcode %d: Look at movie %d start", cmd.op, cmd.args[0]);
2095
2096 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[0]);
2097
2098 float startPitch, startHeading;
2099 _vm->getMovieLookAt(movieId, true, startPitch, startHeading);
2100 _vm->_state->lookAt(startPitch, startHeading);
2101 }
2102
cameraSetFOV(Context & c,const Opcode & cmd)2103 void Script::cameraSetFOV(Context &c, const Opcode &cmd) {
2104 debugC(kDebugScript, "Opcode %d: Set camera fov %d", cmd.op, cmd.args[0]);
2105
2106 int32 fov = _vm->_state->valueOrVarValue(cmd.args[0]);
2107
2108 _vm->_state->setLookAtFOV(fov);
2109 }
2110
changeNode(Context & c,const Opcode & cmd)2111 void Script::changeNode(Context &c, const Opcode &cmd) {
2112 debugC(kDebugScript, "Opcode %d: Go to node %d", cmd.op, cmd.args[0]);
2113
2114 _vm->loadNode(cmd.args[0]);
2115 }
2116
changeNodeRoom(Context & c,const Opcode & cmd)2117 void Script::changeNodeRoom(Context &c, const Opcode &cmd) {
2118 debugC(kDebugScript, "Opcode %d: Go to node %d room %d", cmd.op, cmd.args[0], cmd.args[1]);
2119
2120 _vm->loadNode(cmd.args[1], cmd.args[0]);
2121 }
2122
changeNodeRoomAge(Context & c,const Opcode & cmd)2123 void Script::changeNodeRoomAge(Context &c, const Opcode &cmd) {
2124 debugC(kDebugScript, "Opcode %d: Go to node %d room %d age %d", cmd.op, cmd.args[2], cmd.args[1], cmd.args[0]);
2125
2126 _vm->loadNode(cmd.args[2], cmd.args[1], cmd.args[0]);
2127 }
2128
drawXTicks(Context & c,const Opcode & cmd)2129 void Script::drawXTicks(Context &c, const Opcode &cmd) {
2130 debugC(kDebugScript, "Opcode %d: Draw %d ticks", cmd.op, cmd.args[0]);
2131
2132 uint32 endTick = _vm->_state->getTickCount() + cmd.args[0];
2133
2134 while (_vm->_state->getTickCount() < endTick && !_vm->shouldQuit()) {
2135 _vm->processInput(false);
2136 _vm->drawFrame();
2137 }
2138 }
2139
drawWhileCond(Context & c,const Opcode & cmd)2140 void Script::drawWhileCond(Context &c, const Opcode &cmd) {
2141 debugC(kDebugScript, "Opcode %d: While condition %d, draw", cmd.op, cmd.args[0]);
2142
2143 while (_vm->_state->evaluate(cmd.args[0]) && !_vm->inputEscapePressed() && !_vm->shouldQuit()) {
2144 _vm->processInput(false);
2145 _vm->drawFrame();
2146 }
2147 }
2148
whileStart(Context & c,const Opcode & cmd)2149 void Script::whileStart(Context &c, const Opcode &cmd) {
2150 const Command &whileEndCommand = findCommandByProc(&Script::whileEnd);
2151
2152 c.whileStart = c.op - 1;
2153
2154 // Check the while condition
2155 if (!_vm->_state->evaluate(cmd.args[0])) {
2156 // Condition is false, go to the next opcode after the end of the while loop
2157 do {
2158 c.op++;
2159 } while (c.op != c.script->end() && c.op->op != whileEndCommand.op);
2160 }
2161
2162 _vm->processInput(false);
2163 _vm->drawFrame();
2164 }
2165
whileEnd(Context & c,const Opcode & cmd)2166 void Script::whileEnd(Context &c, const Opcode &cmd) {
2167 debugC(kDebugScript, "Opcode %d: End of while condition", cmd.op);
2168
2169 // Go to while start
2170 c.op = c.whileStart;
2171 }
2172
runScriptWhileCond(Context & c,const Opcode & cmd)2173 void Script::runScriptWhileCond(Context &c, const Opcode &cmd) {
2174 debugC(kDebugScript, "Opcode %d: While condition %d, run script %d", cmd.op, cmd.args[0], cmd.args[1]);
2175
2176 while (_vm->_state->evaluate(cmd.args[0]) && !_vm->shouldQuit()) {
2177 _vm->runScriptsFromNode(cmd.args[1]);
2178 _vm->processInput(false);
2179 _vm->drawFrame();
2180 }
2181
2182 _vm->processInput(false);
2183 _vm->drawFrame();
2184 }
2185
runScriptWhileCondEachXFrames(Context & c,const Opcode & cmd)2186 void Script::runScriptWhileCondEachXFrames(Context &c, const Opcode &cmd) {
2187 debugC(kDebugScript, "Opcode %d: While condition %d, run script %d each %d frames", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
2188
2189 uint step = cmd.args[2] % 100;
2190
2191 uint firstStep = cmd.args[2];
2192 if (firstStep > 100)
2193 firstStep /= 100;
2194
2195 uint nextScript = _vm->_state->getTickCount() + firstStep;
2196
2197 while (_vm->_state->evaluate(cmd.args[0]) && !_vm->shouldQuit()) {
2198
2199 if (_vm->_state->getTickCount() >= nextScript) {
2200 nextScript = _vm->_state->getTickCount() + step;
2201
2202 _vm->runScriptsFromNode(cmd.args[1]);
2203 }
2204
2205 _vm->processInput(false);
2206 _vm->drawFrame();
2207 }
2208
2209 _vm->processInput(false);
2210 _vm->drawFrame();
2211 }
2212
moviePlayFullFrame(Context & c,const Opcode & cmd)2213 void Script::moviePlayFullFrame(Context &c, const Opcode &cmd) {
2214 debugC(kDebugScript, "Opcode %d: Play movie %d", cmd.op, cmd.args[0]);
2215
2216 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[0]);
2217 _vm->_cursor->setVisible(false);
2218 _vm->playMovieFullFrame(movieId);
2219 _vm->_cursor->setVisible(true);
2220 }
2221
moviePlayFullFrameTrans(Context & c,const Opcode & cmd)2222 void Script::moviePlayFullFrameTrans(Context &c, const Opcode &cmd) {
2223 debugC(kDebugScript, "Opcode %d: Play movie %d with transition", cmd.op, cmd.args[0]);
2224
2225 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[0]);
2226 _vm->_cursor->setVisible(false);
2227 _vm->playMovieFullFrame(movieId);
2228 _vm->_cursor->setVisible(true);
2229
2230 _vm->drawTransition(kTransitionFade);
2231 }
2232
moviePlayChangeNode(Context & c,const Opcode & cmd)2233 void Script::moviePlayChangeNode(Context &c, const Opcode &cmd) {
2234 debugC(kDebugScript, "Opcode %d: Play movie %d, go to node %d", cmd.op, cmd.args[1], cmd.args[0]);
2235
2236 uint16 nodeId = _vm->_state->valueOrVarValue(cmd.args[0]);
2237 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[1]);
2238 _vm->_cursor->setVisible(false);
2239 _vm->playMovieGoToNode(movieId, nodeId);
2240 _vm->_cursor->setVisible(true);
2241 }
2242
moviePlayChangeNodeTrans(Context & c,const Opcode & cmd)2243 void Script::moviePlayChangeNodeTrans(Context &c, const Opcode &cmd) {
2244 debugC(kDebugScript, "Opcode %d: Play movie %d, go to node %d with transition", cmd.op, cmd.args[1], cmd.args[0]);
2245
2246 uint16 nodeId = _vm->_state->valueOrVarValue(cmd.args[0]);
2247 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[1]);
2248 _vm->_cursor->setVisible(false);
2249 _vm->playMovieGoToNode(movieId, nodeId);
2250 _vm->_cursor->setVisible(true);
2251
2252 _vm->drawTransition(kTransitionFade);
2253 }
2254
lookAt(Context & c,const Opcode & cmd)2255 void Script::lookAt(Context &c, const Opcode &cmd) {
2256 debugC(kDebugScript, "Opcode %d: Look at %d, %d", cmd.op, cmd.args[0], cmd.args[1]);
2257
2258 _vm->animateDirectionChange(cmd.args[0], cmd.args[1], 0);
2259 }
2260
lookAtInXFrames(Context & c,const Opcode & cmd)2261 void Script::lookAtInXFrames(Context &c, const Opcode &cmd) {
2262 debugC(kDebugScript, "Opcode %d: Look at %d, %d in %d frames", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
2263
2264 _vm->animateDirectionChange(cmd.args[0], cmd.args[1], cmd.args[2]);
2265 }
2266
lookAtMovieStart(Context & c,const Opcode & cmd)2267 void Script::lookAtMovieStart(Context &c, const Opcode &cmd) {
2268 debugC(kDebugScript, "Opcode %d: Look at movie %d start", cmd.op, cmd.args[0]);
2269
2270 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[0]);
2271
2272 float startPitch, startHeading;
2273 _vm->getMovieLookAt(movieId, true, startPitch, startHeading);
2274 _vm->animateDirectionChange(startPitch, startHeading, 0);
2275 }
2276
lookAtMovieStartInXFrames(Context & c,const Opcode & cmd)2277 void Script::lookAtMovieStartInXFrames(Context &c, const Opcode &cmd) {
2278 debugC(kDebugScript, "Opcode %d: Look at movie %d start in %d frames", cmd.op, cmd.args[0], cmd.args[1]);
2279
2280 uint16 movieId = _vm->_state->valueOrVarValue(cmd.args[0]);
2281
2282 float startPitch, startHeading;
2283 _vm->getMovieLookAt(movieId, true, startPitch, startHeading);
2284 _vm->animateDirectionChange(startPitch, startHeading, cmd.args[1]);
2285 }
2286
runScriptForVarDrawTicksHelper(uint16 var,int32 startValue,int32 endValue,uint16 script,int32 numTicks)2287 void Script::runScriptForVarDrawTicksHelper(uint16 var, int32 startValue, int32 endValue, uint16 script, int32 numTicks) {
2288 if (numTicks < 0) {
2289 numTicks = -numTicks;
2290 uint startTick = _vm->_state->getTickCount();
2291 uint currentTick = startTick;
2292 uint endTick = startTick + numTicks;
2293 uint numValues = abs(endValue - startValue);
2294
2295 if (startTick < endTick) {
2296 int currentValue = -9999;
2297 while (1) {
2298 int nextValue = numValues * (currentTick - startTick) / numTicks;
2299 if (currentValue != nextValue) {
2300 currentValue = nextValue;
2301
2302 int16 varValue;
2303 if (endValue > startValue)
2304 varValue = startValue + currentValue;
2305 else
2306 varValue = startValue - currentValue;
2307
2308 _vm->_state->setVar(var, varValue);
2309
2310 if (script) {
2311 _vm->runScriptsFromNode(script);
2312 }
2313 }
2314
2315 _vm->processInput(false);
2316 _vm->drawFrame();
2317 currentTick = _vm->_state->getTickCount();
2318
2319 if (currentTick > endTick)
2320 break;
2321 }
2322 }
2323
2324 _vm->_state->setVar(var, endValue);
2325 } else {
2326 int currentValue = startValue;
2327 uint endTick = 0;
2328
2329 bool positiveDirection = endValue > startValue;
2330
2331 while (1) {
2332 if ((positiveDirection && (currentValue > endValue))
2333 || (!positiveDirection && (currentValue < endValue)))
2334 break;
2335
2336 _vm->_state->setVar(var, currentValue);
2337
2338 if (script)
2339 _vm->runScriptsFromNode(script);
2340
2341 for (uint i = _vm->_state->getTickCount(); i < endTick; i = _vm->_state->getTickCount()) {
2342 _vm->processInput(false);
2343 _vm->drawFrame();
2344 }
2345
2346 endTick = _vm->_state->getTickCount() + numTicks;
2347
2348 currentValue += positiveDirection ? 1 : -1;
2349 }
2350 }
2351 }
2352
runScriptForVar(Context & c,const Opcode & cmd)2353 void Script::runScriptForVar(Context &c, const Opcode &cmd) {
2354 debugC(kDebugScript, "Opcode %d: For var %d from %d to %d, run script %d",
2355 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2356
2357 runScriptForVarDrawTicksHelper(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], 0);
2358 }
2359
runScriptForVarEachXFrames(Context & c,const Opcode & cmd)2360 void Script::runScriptForVarEachXFrames(Context &c, const Opcode &cmd) {
2361 debugC(kDebugScript, "Opcode %d: For var %d from %d to %d, run script %d every %d frames",
2362 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
2363
2364 runScriptForVarDrawTicksHelper(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
2365 }
2366
runScriptForVarStartVar(Context & c,const Opcode & cmd)2367 void Script::runScriptForVarStartVar(Context &c, const Opcode &cmd) {
2368 debugC(kDebugScript, "Opcode %d: For var %d from var %d value to %d, run script %d",
2369 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2370
2371 runScriptForVarDrawTicksHelper(cmd.args[0], _vm->_state->getVar(cmd.args[1]), cmd.args[2], cmd.args[3], 0);
2372 }
2373
runScriptForVarStartVarEachXFrames(Context & c,const Opcode & cmd)2374 void Script::runScriptForVarStartVarEachXFrames(Context &c, const Opcode &cmd) {
2375 debugC(kDebugScript, "Opcode %d: For var %d from var %d value to %d, run script %d every %d frames",
2376 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
2377
2378 runScriptForVarDrawTicksHelper(cmd.args[0], _vm->_state->getVar(cmd.args[1]), cmd.args[2], cmd.args[3], cmd.args[4]);
2379 }
2380
runScriptForVarEndVar(Context & c,const Opcode & cmd)2381 void Script::runScriptForVarEndVar(Context &c, const Opcode &cmd) {
2382 debugC(kDebugScript, "Opcode %d: For var %d from %d to var %d value, run script %d",
2383 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2384
2385 runScriptForVarDrawTicksHelper(cmd.args[0], cmd.args[1], _vm->_state->getVar(cmd.args[2]), cmd.args[3], 0);
2386 }
2387
runScriptForVarEndVarEachXFrames(Context & c,const Opcode & cmd)2388 void Script::runScriptForVarEndVarEachXFrames(Context &c, const Opcode &cmd) {
2389 debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value, run script %d every %d frames",
2390 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
2391
2392 runScriptForVarDrawTicksHelper(cmd.args[0], cmd.args[1], _vm->_state->getVar(cmd.args[2]), cmd.args[3], cmd.args[4]);
2393 }
2394
runScriptForVarStartEndVar(Context & c,const Opcode & cmd)2395 void Script::runScriptForVarStartEndVar(Context &c, const Opcode &cmd) {
2396 debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value, run script %d",
2397 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2398
2399 runScriptForVarDrawTicksHelper(cmd.args[0], _vm->_state->getVar(cmd.args[1]), _vm->_state->getVar(cmd.args[2]),
2400 cmd.args[3], 0);
2401 }
2402
runScriptForVarStartEndVarEachXFrames(Context & c,const Opcode & cmd)2403 void Script::runScriptForVarStartEndVarEachXFrames(Context &c, const Opcode &cmd) {
2404 debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value, run script %d every %d frames",
2405 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3], cmd.args[4]);
2406
2407 runScriptForVarDrawTicksHelper(cmd.args[0], _vm->_state->getVar(cmd.args[1]), _vm->_state->getVar(cmd.args[2]),
2408 cmd.args[3], cmd.args[4]);
2409 }
2410
drawFramesForVar(Context & c,const Opcode & cmd)2411 void Script::drawFramesForVar(Context &c, const Opcode &cmd) {
2412 debugC(kDebugScript, "Opcode %d: For var %d from %d to %d, every %d frames",
2413 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2414
2415 runScriptForVarDrawTicksHelper(cmd.args[0], cmd.args[1], cmd.args[2], 0, -cmd.args[3]);
2416 }
2417
drawFramesForVarEachTwoFrames(Context & c,const Opcode & cmd)2418 void Script::drawFramesForVarEachTwoFrames(Context &c, const Opcode &cmd) {
2419 debugC(kDebugScript, "Opcode %d: For var %d from %d to %d draw 2 frames",
2420 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
2421
2422 uint numFrames = 2 * (-1 - abs(cmd.args[2] - cmd.args[1]));
2423
2424 runScriptForVarDrawTicksHelper(cmd.args[0], cmd.args[1], cmd.args[2], 0, numFrames);
2425 }
2426
drawFramesForVarStartEndVarEachTwoFrames(Context & c,const Opcode & cmd)2427 void Script::drawFramesForVarStartEndVarEachTwoFrames(Context &c, const Opcode &cmd) {
2428 debugC(kDebugScript, "Opcode %d: For var %d from var %d value to var %d value draw 2 frames",
2429 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
2430
2431 uint numFrames = 2 * (-1 - abs(cmd.args[2] - cmd.args[1]));
2432
2433 runScriptForVarDrawTicksHelper(cmd.args[0], _vm->_state->getVar(cmd.args[1]), _vm->_state->getVar(cmd.args[2]), 0,
2434 numFrames);
2435 }
2436
runScript(Context & c,const Opcode & cmd)2437 void Script::runScript(Context &c, const Opcode &cmd) {
2438 debugC(kDebugScript, "Opcode %d: Run scripts from node %d", cmd.op, cmd.args[0]);
2439
2440 uint16 node = _vm->_state->valueOrVarValue(cmd.args[0]);
2441
2442 _vm->runScriptsFromNode(node, _vm->_state->getLocationRoom());
2443 }
2444
runScriptWithVar(Context & c,const Opcode & cmd)2445 void Script::runScriptWithVar(Context &c, const Opcode &cmd) {
2446 debugC(kDebugScript, "Opcode %d: Run scripts from node %d with var %d", cmd.op, cmd.args[0], cmd.args[1]);
2447
2448 _vm->_state->setVar(26, cmd.args[1]);
2449 uint16 node = _vm->_state->valueOrVarValue(cmd.args[0]);
2450
2451 _vm->runScriptsFromNode(node, _vm->_state->getLocationRoom());
2452 }
2453
runCommonScript(Context & c,const Opcode & cmd)2454 void Script::runCommonScript(Context &c, const Opcode &cmd) {
2455 debugC(kDebugScript, "Opcode %d: Run common script %d", cmd.op, cmd.args[0]);
2456
2457 _vm->runScriptsFromNode(cmd.args[0], 101, 1);
2458 }
2459
runCommonScriptWithVar(Context & c,const Opcode & cmd)2460 void Script::runCommonScriptWithVar(Context &c, const Opcode &cmd) {
2461 debugC(kDebugScript, "Opcode %d: Run common script %d with var %d", cmd.op, cmd.args[0], cmd.args[1]);
2462
2463 _vm->_state->setVar(26, cmd.args[1]);
2464
2465 _vm->runScriptsFromNode(cmd.args[0], 101, 1);
2466 }
2467
runPuzzle1(Context & c,const Opcode & cmd)2468 void Script::runPuzzle1(Context &c, const Opcode &cmd) {
2469 debugC(kDebugScript, "Opcode %d: Run puzzle helper %d", cmd.op, cmd.args[0]);
2470
2471 _puzzles->run(cmd.args[0]);
2472 }
2473
runPuzzle2(Context & c,const Opcode & cmd)2474 void Script::runPuzzle2(Context &c, const Opcode &cmd) {
2475 debugC(kDebugScript, "Opcode %d: Run puzzle helper %d", cmd.op, cmd.args[0]);
2476
2477 _puzzles->run(cmd.args[0], cmd.args[1]);
2478 }
2479
runPuzzle3(Context & c,const Opcode & cmd)2480 void Script::runPuzzle3(Context &c, const Opcode &cmd) {
2481 debugC(kDebugScript, "Opcode %d: Run puzzle helper %d", cmd.op, cmd.args[0]);
2482
2483 _puzzles->run(cmd.args[0], cmd.args[1], cmd.args[2]);
2484 }
2485
runPuzzle4(Context & c,const Opcode & cmd)2486 void Script::runPuzzle4(Context &c, const Opcode &cmd) {
2487 debugC(kDebugScript, "Opcode %d: Run puzzle helper %d", cmd.op, cmd.args[0]);
2488
2489 _puzzles->run(cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2490 }
2491
ambientLoadNode(Context & c,const Opcode & cmd)2492 void Script::ambientLoadNode(Context &c, const Opcode &cmd) {
2493 debugC(kDebugScript, "Opcode %d: Load ambient sounds from node %d %d %d", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
2494
2495 _vm->_ambient->loadNode(cmd.args[2], cmd.args[1], cmd.args[0]);
2496 }
2497
ambientReloadCurrentNode(Context & c,const Opcode & cmd)2498 void Script::ambientReloadCurrentNode(Context &c, const Opcode &cmd) {
2499 debugC(kDebugScript, "Opcode %d: Reload ambient sounds from current node with fade out delay : %d", cmd.op, cmd.args[0]);
2500
2501 _vm->_ambient->loadNode(0, 0, 0);
2502 _vm->_ambient->applySounds(_vm->_state->valueOrVarValue(cmd.args[0]));
2503 }
2504
ambientPlayCurrentNode(Context & c,const Opcode & cmd)2505 void Script::ambientPlayCurrentNode(Context &c, const Opcode &cmd) {
2506 debugC(kDebugScript, "Opcode %d: Play ambient sounds from current node %d %d", cmd.op, cmd.args[0], cmd.args[1]);
2507
2508 _vm->_ambient->playCurrentNode(cmd.args[0], cmd.args[1]);
2509 }
2510
ambientApply(Context & c,const Opcode & cmd)2511 void Script::ambientApply(Context &c, const Opcode &cmd) {
2512 debugC(kDebugScript, "Opcode %d: Apply loadad ambient sounds", cmd.op);
2513
2514 _vm->_ambient->applySounds(1);
2515 }
2516
ambientApplyWithFadeDelay(Context & c,const Opcode & cmd)2517 void Script::ambientApplyWithFadeDelay(Context &c, const Opcode &cmd) {
2518 debugC(kDebugScript, "Opcode %d: Apply loadad ambient sounds with fade out delay : %d", cmd.op, cmd.args[0]);
2519
2520 _vm->_ambient->applySounds(_vm->_state->valueOrVarValue(cmd.args[0]));
2521 }
2522
soundPlayBadClick(Context & c,const Opcode & cmd)2523 void Script::soundPlayBadClick(Context &c, const Opcode &cmd) {
2524 debugC(kDebugScript, "Opcode %d: Play bad click sound", cmd.op);
2525
2526 _vm->_sound->playEffect(697, 5);
2527 }
2528
soundPlayBlocking(Context & c,const Opcode & cmd)2529 void Script::soundPlayBlocking(Context &c, const Opcode &cmd) {
2530 debugC(kDebugScript, "Opcode %d: Play skippable sound %d", cmd.op, cmd.args[0]);
2531
2532 int16 soundId = cmd.args[0];
2533 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2534 int32 heading = _vm->_state->valueOrVarValue(cmd.args[2]);
2535 int32 att = _vm->_state->valueOrVarValue(cmd.args[3]);
2536 bool nonBlocking = _vm->_state->valueOrVarValue(cmd.args[4]);
2537 _vm->_sound->playEffect(soundId, volume, heading, att);
2538
2539 if (nonBlocking || !_vm->_sound->isPlaying(soundId)) {
2540 return;
2541 }
2542
2543 while (_vm->_sound->isPlaying(soundId) && !_vm->inputEscapePressed() && !_vm->shouldQuit()) {
2544 _vm->processInput(false);
2545 _vm->drawFrame();
2546 }
2547 }
2548
soundPlay(Context & c,const Opcode & cmd)2549 void Script::soundPlay(Context &c, const Opcode &cmd) {
2550 debugC(kDebugScript, "Opcode %d: Play sound %d", cmd.op, cmd.args[0]);
2551
2552 _vm->_sound->playEffect(cmd.args[0], 100);
2553 }
2554
soundPlayVolume(Context & c,const Opcode & cmd)2555 void Script::soundPlayVolume(Context &c, const Opcode &cmd) {
2556 debugC(kDebugScript, "Opcode %d: Play sound %d at volume %d", cmd.op, cmd.args[0], cmd.args[1]);
2557
2558 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2559 _vm->_sound->playEffect(cmd.args[0], volume);
2560 }
2561
soundPlayVolumeDirection(Context & c,const Opcode & cmd)2562 void Script::soundPlayVolumeDirection(Context &c, const Opcode &cmd) {
2563 debugC(kDebugScript, "Opcode %d: Play sound %d at volume %d in direction %d",
2564 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
2565
2566 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2567 int32 heading = _vm->_state->valueOrVarValue(cmd.args[2]);
2568 _vm->_sound->playEffect(cmd.args[0], volume, heading, 85);
2569 }
2570
soundPlayVolumeDirectionAtt(Context & c,const Opcode & cmd)2571 void Script::soundPlayVolumeDirectionAtt(Context &c, const Opcode &cmd) {
2572 debugC(kDebugScript, "Opcode %d: Play sound %d at volume %d in direction %d with attenuation %d",
2573 cmd.op, cmd.args[0], cmd.args[1], cmd.args[2], cmd.args[3]);
2574
2575 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2576 int32 heading = _vm->_state->valueOrVarValue(cmd.args[2]);
2577 int32 att = _vm->_state->valueOrVarValue(cmd.args[3]);
2578 _vm->_sound->playEffect(cmd.args[0], volume, heading, att);
2579 }
2580
soundStopEffect(Context & c,const Opcode & cmd)2581 void Script::soundStopEffect(Context &c, const Opcode &cmd) {
2582 debugC(kDebugScript, "Opcode %d: Stop sound effect %d", cmd.op, cmd.args[0]);
2583
2584 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2585
2586 _vm->_sound->stopEffect(id, 0);
2587 }
2588
soundFadeOutEffect(Context & c,const Opcode & cmd)2589 void Script::soundFadeOutEffect(Context &c, const Opcode &cmd) {
2590 debugC(kDebugScript, "Opcode %d: Stop sound effect %d", cmd.op, cmd.args[0]);
2591
2592 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2593 int32 fadeDuration = _vm->_state->valueOrVarValue(cmd.args[1]);
2594
2595 _vm->_sound->stopEffect(id, fadeDuration);
2596 }
2597
soundPlayLooping(Context & c,const Opcode & cmd)2598 void Script::soundPlayLooping(Context &c, const Opcode &cmd) {
2599 debugC(kDebugScript, "Opcode %d: Play sound effect looping %d", cmd.op, cmd.args[0]);
2600
2601 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2602
2603 _vm->_sound->playEffectLooping(id, 100);
2604 }
2605
soundPlayFadeInOut(Context & c,const Opcode & cmd)2606 void Script::soundPlayFadeInOut(Context &c, const Opcode &cmd) {
2607 debugC(kDebugScript, "Opcode %d: Play sound effect fade in fade out %d", cmd.op, cmd.args[0]);
2608
2609 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2610 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2611 int32 fadeInDuration = _vm->_state->valueOrVarValue(cmd.args[2]);
2612
2613 int32 playDuration;
2614 if (cmd.args[3] == -1) {
2615 playDuration = 108000;
2616 } else {
2617 playDuration = _vm->_state->valueOrVarValue(cmd.args[3]);
2618 }
2619
2620 int32 fadeOutDuration = _vm->_state->valueOrVarValue(cmd.args[4]);
2621
2622 _vm->_sound->playEffectFadeInOut(id, volume, 0, 0, fadeInDuration, playDuration, fadeOutDuration);
2623 }
2624
soundChooseNext(Context & c,const Opcode & cmd)2625 void Script::soundChooseNext(Context &c, const Opcode &cmd) {
2626 debugC(kDebugScript, "Opcode %d: Setup next sound with control var %d", cmd.op, cmd.args[0]);
2627
2628 int16 controlVar = cmd.args[0];
2629 int16 startSoundId = cmd.args[1];
2630 int16 soundCount = cmd.args[2];
2631 int32 soundMinDelay = _vm->_state->valueOrVarValue(cmd.args[3]);
2632 int32 soundMaxDelay = _vm->_state->valueOrVarValue(cmd.args[4]);
2633
2634 _vm->_sound->setupNextSound(kNext, controlVar, startSoundId, soundCount, soundMinDelay, soundMaxDelay);
2635 }
2636
soundRandomizeNext(Context & c,const Opcode & cmd)2637 void Script::soundRandomizeNext(Context &c, const Opcode &cmd) {
2638 debugC(kDebugScript, "Opcode %d: Setup next sound with control var %d", cmd.op, cmd.args[0]);
2639
2640 int16 controlVar = cmd.args[0];
2641 int16 startSoundId = cmd.args[1];
2642 int16 soundCount = cmd.args[2];
2643 int32 soundMinDelay = _vm->_state->valueOrVarValue(cmd.args[3]);
2644 int32 soundMaxDelay = _vm->_state->valueOrVarValue(cmd.args[4]);
2645
2646 _vm->_sound->setupNextSound(kRandom, controlVar, startSoundId, soundCount, soundMinDelay, soundMaxDelay);
2647 }
2648
soundChooseNextAfterOther(Context & c,const Opcode & cmd)2649 void Script::soundChooseNextAfterOther(Context &c, const Opcode &cmd) {
2650 debugC(kDebugScript, "Opcode %d: Setup next sound with control var %d", cmd.op, cmd.args[0]);
2651
2652 int16 controlVar = cmd.args[0];
2653 int16 startSoundId = cmd.args[1];
2654 int16 soundCount = cmd.args[2];
2655 int32 soundMinDelay = _vm->_state->valueOrVarValue(cmd.args[3]);
2656 int32 soundMaxDelay = _vm->_state->valueOrVarValue(cmd.args[4]);
2657
2658 int32 controlSoundId = _vm->_state->valueOrVarValue(cmd.args[5]);
2659 int32 controlSoundMaxPosition = _vm->_state->valueOrVarValue(cmd.args[6]);
2660
2661 _vm->_sound->setupNextSound(kNextIfOtherStarting, controlVar, startSoundId, soundCount, soundMinDelay, soundMaxDelay, controlSoundId, controlSoundMaxPosition);
2662 }
2663
soundRandomizeNextAfterOther(Context & c,const Opcode & cmd)2664 void Script::soundRandomizeNextAfterOther(Context &c, const Opcode &cmd) {
2665 debugC(kDebugScript, "Opcode %d: Setup next sound with control var %d", cmd.op, cmd.args[0]);
2666
2667 int16 controlVar = cmd.args[0];
2668 int16 startSoundId = cmd.args[1];
2669 int16 soundCount = cmd.args[2];
2670 int32 soundMinDelay = _vm->_state->valueOrVarValue(cmd.args[3]);
2671 int32 soundMaxDelay = _vm->_state->valueOrVarValue(cmd.args[4]);
2672
2673 int32 controlSoundId = _vm->_state->valueOrVarValue(cmd.args[5]);
2674 int32 controlSoundMaxPosition = _vm->_state->valueOrVarValue(cmd.args[6]);
2675
2676 _vm->_sound->setupNextSound(kRandomIfOtherStarting, controlVar, startSoundId, soundCount, soundMinDelay, soundMaxDelay, controlSoundId, controlSoundMaxPosition);
2677 }
2678
ambientSetFadeOutDelay(Context & c,const Opcode & cmd)2679 void Script::ambientSetFadeOutDelay(Context &c, const Opcode &cmd) {
2680 debugC(kDebugScript, "Opcode %d: Set fade out delay : %d", cmd.op, cmd.args[0]);
2681
2682 _vm->_state->setAmbiantPreviousFadeOutDelay(cmd.args[0]);
2683 }
2684
ambientAddSound1(Context & c,const Opcode & cmd)2685 void Script::ambientAddSound1(Context &c, const Opcode &cmd) {
2686 debugC(kDebugScript, "Opcode %d: Add ambient sound %d", cmd.op, cmd.args[0]);
2687
2688 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2689 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2690
2691 _vm->_ambient->addSound(id, volume, 0, 0, 0, 0);
2692 }
2693
ambientAddSound2(Context & c,const Opcode & cmd)2694 void Script::ambientAddSound2(Context &c, const Opcode &cmd) {
2695 debugC(kDebugScript, "Opcode %d: Add ambient sound %d", cmd.op, cmd.args[0]);
2696
2697 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2698 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2699 int32 fadeOutDelay = cmd.args[2];
2700
2701 _vm->_ambient->addSound(id, volume, 0, 0, 0, fadeOutDelay);
2702 }
2703
ambientAddSound3(Context & c,const Opcode & cmd)2704 void Script::ambientAddSound3(Context &c, const Opcode &cmd) {
2705 debugC(kDebugScript, "Opcode %d: Add ambient sound %d", cmd.op, cmd.args[0]);
2706
2707 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2708 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2709 int32 heading = cmd.args[2];
2710
2711 _vm->_ambient->addSound(id, volume, heading, 85, 0, 0);
2712 }
2713
ambientAddSound4(Context & c,const Opcode & cmd)2714 void Script::ambientAddSound4(Context &c, const Opcode &cmd) {
2715 debugC(kDebugScript, "Opcode %d: Add ambient sound %d", cmd.op, cmd.args[0]);
2716
2717 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2718 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2719 int32 heading = cmd.args[2];
2720 int32 angle = cmd.args[3];
2721
2722 _vm->_ambient->addSound(id, volume, heading, angle, 0, 0);
2723 }
2724
ambientAddSound5(Context & c,const Opcode & cmd)2725 void Script::ambientAddSound5(Context &c, const Opcode &cmd) {
2726 debugC(kDebugScript, "Opcode %d: Add ambient sound %d", cmd.op, cmd.args[0]);
2727
2728 int32 id = _vm->_state->valueOrVarValue(cmd.args[0]);
2729 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2730 int32 u1 = _vm->_state->valueOrVarValue(cmd.args[2]);
2731
2732 _vm->_ambient->addSound(id, volume, 0, 0, u1, 0);
2733 }
2734
ambientSetCue1(Context & c,const Opcode & cmd)2735 void Script::ambientSetCue1(Context &c, const Opcode &cmd) {
2736 debugC(kDebugScript, "Opcode %d: Set ambient cue %d", cmd.op, cmd.args[0]);
2737
2738 int32 id = cmd.args[0];
2739 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2740
2741 _vm->_ambient->setCueSheet(id, volume, 0, 0);
2742 }
2743
ambientSetCue2(Context & c,const Opcode & cmd)2744 void Script::ambientSetCue2(Context &c, const Opcode &cmd) {
2745 debugC(kDebugScript, "Opcode %d: Set ambient cue %d", cmd.op, cmd.args[0]);
2746
2747 int32 id = cmd.args[0];
2748 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2749 int32 heading = cmd.args[2];
2750
2751 _vm->_ambient->setCueSheet(id, volume, heading, 85);
2752 }
2753
ambientSetCue3(Context & c,const Opcode & cmd)2754 void Script::ambientSetCue3(Context &c, const Opcode &cmd) {
2755 debugC(kDebugScript, "Opcode %d: Set ambient cue %d", cmd.op, cmd.args[0]);
2756
2757 int32 id = cmd.args[0];
2758 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2759 int32 heading = cmd.args[2];
2760 int32 angle = cmd.args[3];
2761
2762 _vm->_ambient->setCueSheet(id, volume, heading, angle);
2763 }
2764
ambientSetCue4(Context & c,const Opcode & cmd)2765 void Script::ambientSetCue4(Context &c, const Opcode &cmd) {
2766 debugC(kDebugScript, "Opcode %d: Set ambient cue %d", cmd.op, cmd.args[0]);
2767
2768 int32 id = cmd.args[0];
2769 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2770
2771 _vm->_ambient->setCueSheet(id, volume, 32766, 85);
2772 }
2773
runAmbientScriptNode(Context & c,const Opcode & cmd)2774 void Script::runAmbientScriptNode(Context &c, const Opcode &cmd) {
2775 debugC(kDebugScript, "Opcode %d: Run ambient script for node %d",
2776 cmd.op, cmd.args[0]);
2777
2778 int32 node = _vm->_state->valueOrVarValue(cmd.args[0]);
2779 _vm->runAmbientScripts(node);
2780 }
2781
runAmbientScriptNodeRoomAge(Context & c,const Opcode & cmd)2782 void Script::runAmbientScriptNodeRoomAge(Context &c, const Opcode &cmd) {
2783 debugC(kDebugScript, "Opcode %d: Run sound script for node %d, room %d, age %d",
2784 cmd.op, cmd.args[2], cmd.args[1], cmd.args[0]);
2785
2786 int32 node = _vm->_state->valueOrVarValue(cmd.args[2]);
2787 _vm->_ambient->_scriptRoom = _vm->_state->valueOrVarValue(cmd.args[1]);
2788 _vm->_ambient->_scriptAge = _vm->_state->valueOrVarValue(cmd.args[0]);
2789
2790 _vm->runAmbientScripts(node);
2791 _vm->_ambient->scaleVolume(_vm->_state->valueOrVarValue(cmd.args[3]));
2792 }
2793
runSoundScriptNode(Context & c,const Opcode & cmd)2794 void Script::runSoundScriptNode(Context &c, const Opcode &cmd) {
2795 debugC(kDebugScript, "Opcode %d: Run sound script for node %d",
2796 cmd.op, cmd.args[0]);
2797
2798 int32 node = _vm->_state->valueOrVarValue(cmd.args[0]);
2799 _vm->runBackgroundSoundScriptsFromNode(node);
2800 }
2801
runSoundScriptNodeRoom(Context & c,const Opcode & cmd)2802 void Script::runSoundScriptNodeRoom(Context &c, const Opcode &cmd) {
2803 debugC(kDebugScript, "Opcode %d: Run sound script for node %d, room %d",
2804 cmd.op, cmd.args[1], cmd.args[0]);
2805
2806 int32 node = _vm->_state->valueOrVarValue(cmd.args[1]);
2807 int32 room = _vm->_state->valueOrVarValue(cmd.args[0]);
2808 _vm->runBackgroundSoundScriptsFromNode(node, room);
2809 }
2810
runSoundScriptNodeRoomAge(Context & c,const Opcode & cmd)2811 void Script::runSoundScriptNodeRoomAge(Context &c, const Opcode &cmd) {
2812 debugC(kDebugScript, "Opcode %d: Run sound script for node %d, room %d, age %d",
2813 cmd.op, cmd.args[2], cmd.args[1], cmd.args[0]);
2814
2815 int32 node = _vm->_state->valueOrVarValue(cmd.args[2]);
2816 int32 room = _vm->_state->valueOrVarValue(cmd.args[1]);
2817 int32 age = _vm->_state->valueOrVarValue(cmd.args[0]);
2818 _vm->runBackgroundSoundScriptsFromNode(node, room, age);
2819 }
2820
soundStopMusic(Context & c,const Opcode & cmd)2821 void Script::soundStopMusic(Context &c, const Opcode &cmd) {
2822 debugC(kDebugScript, "Opcode %d: Stop music", cmd.op);
2823
2824 int32 fadeOutDuration = _vm->_state->valueOrVarValue(cmd.args[0]);
2825
2826 _vm->_sound->stopMusic(fadeOutDuration);
2827 }
2828
movieSetStartupSound(Context & c,const Opcode & cmd)2829 void Script::movieSetStartupSound(Context &c, const Opcode &cmd) {
2830 debugC(kDebugScript, "Opcode %d: Set movie startup sound %d", cmd.op, cmd.args[0]);
2831
2832 int32 soundId = _vm->_state->valueOrVarValue(cmd.args[0]);
2833
2834 _vm->_state->setMovieStartSoundId(soundId);
2835 _vm->_state->setMovieStartSoundVolume(100);
2836 _vm->_state->setMovieStartSoundHeading(0);
2837 _vm->_state->setMovieStartSoundAttenuation(0);
2838 }
2839
movieSetStartupSoundVolume(Context & c,const Opcode & cmd)2840 void Script::movieSetStartupSoundVolume(Context &c, const Opcode &cmd) {
2841 debugC(kDebugScript, "Opcode %d: Set movie startup sound %d", cmd.op, cmd.args[0]);
2842
2843 int32 soundId = _vm->_state->valueOrVarValue(cmd.args[0]);
2844 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2845
2846 _vm->_state->setMovieStartSoundId(soundId);
2847 _vm->_state->setMovieStartSoundVolume(volume);
2848 _vm->_state->setMovieStartSoundHeading(0);
2849 _vm->_state->setMovieStartSoundAttenuation(0);
2850 }
2851
movieSetStartupSoundVolumeH(Context & c,const Opcode & cmd)2852 void Script::movieSetStartupSoundVolumeH(Context &c, const Opcode &cmd) {
2853 debugC(kDebugScript, "Opcode %d: Set movie startup sound %d", cmd.op, cmd.args[0]);
2854
2855 int32 soundId = _vm->_state->valueOrVarValue(cmd.args[0]);
2856 int32 volume = _vm->_state->valueOrVarValue(cmd.args[1]);
2857 int32 heading = _vm->_state->valueOrVarValue(cmd.args[2]);
2858
2859 _vm->_state->setMovieStartSoundId(soundId);
2860 _vm->_state->setMovieStartSoundVolume(volume);
2861 _vm->_state->setMovieStartSoundHeading(heading);
2862 _vm->_state->setMovieStartSoundAttenuation(0);
2863 }
2864
drawOneFrame(Context & c,const Opcode & cmd)2865 void Script::drawOneFrame(Context &c, const Opcode &cmd) {
2866 debugC(kDebugScript, "Opcode %d: Draw one frame", cmd.op);
2867
2868 _vm->processInput(false);
2869 _vm->drawFrame();
2870 }
2871
cursorHide(Context & c,const Opcode & cmd)2872 void Script::cursorHide(Context &c, const Opcode &cmd) {
2873 debugC(kDebugScript, "Opcode %d: Hide cursor", cmd.op);
2874
2875 _vm->_cursor->setVisible(false);
2876 }
2877
cursorShow(Context & c,const Opcode & cmd)2878 void Script::cursorShow(Context &c, const Opcode &cmd) {
2879 debugC(kDebugScript, "Opcode %d: Show cursor", cmd.op);
2880
2881 _vm->_cursor->setVisible(true);
2882 }
2883
cursorSet(Context & c,const Opcode & cmd)2884 void Script::cursorSet(Context &c, const Opcode &cmd) {
2885 debugC(kDebugScript, "Opcode %d: Set cursor %d", cmd.op, cmd.args[0]);
2886
2887 _vm->_cursor->changeCursor(cmd.args[0]);
2888 }
2889
cursorLock(Context & c,const Opcode & cmd)2890 void Script::cursorLock(Context &c, const Opcode &cmd) {
2891 debugC(kDebugScript, "Opcode %d: Lock cursor", cmd.op);
2892
2893 _vm->_state->setCursorLocked(true);
2894 }
2895
cursorUnlock(Context & c,const Opcode & cmd)2896 void Script::cursorUnlock(Context &c, const Opcode &cmd) {
2897 debugC(kDebugScript, "Opcode %d: Unlock cursor", cmd.op);
2898
2899 _vm->_state->setCursorLocked(false);
2900 }
2901
dialogOpen(Context & c,const Opcode & cmd)2902 void Script::dialogOpen(Context &c, const Opcode &cmd) {
2903 debugC(kDebugScript, "Opcode %d: Open dialog %d", cmd.op, cmd.args[0]);
2904
2905 uint16 dialog = _vm->_state->valueOrVarValue(cmd.args[0]);
2906 int16 result = _vm->openDialog(dialog);
2907 _vm->_state->setDialogResult(result);
2908 }
2909
newGame(Context & c,const Opcode & cmd)2910 void Script::newGame(Context &c, const Opcode &cmd) {
2911 debugC(kDebugScript, "Opcode %d: New game", cmd.op);
2912
2913 _vm->_state->newGame();
2914 _vm->_inventory->reset();
2915 }
2916
2917 } // End of namespace Myst3
2918