1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
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 "kyra/engine/kyra_mr.h"
24 #include "kyra/text/text_mr.h"
25 #include "kyra/resource/resource.h"
26 
27 #include "common/system.h"
28 
29 namespace Kyra {
30 
o3_getMalcolmShapes(EMCState * script)31 int KyraEngine_MR::o3_getMalcolmShapes(EMCState *script) {
32 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getMaloclmShapes(%p) ()", (const void *)script);
33 	return _characterShapeFile;
34 }
35 
o3_setCharacterPos(EMCState * script)36 int KyraEngine_MR::o3_setCharacterPos(EMCState *script) {
37 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
38 	int x = stackPos(0);
39 	int y = stackPos(1);
40 
41 	if (x != -1 && y != -1) {
42 		x &= ~3;
43 		y &= ~1;
44 	}
45 
46 	_mainCharacter.x1 = _mainCharacter.x2 = x;
47 	_mainCharacter.y1 = _mainCharacter.y2 = y;
48 
49 	return 0;
50 }
51 
o3_defineObject(EMCState * script)52 int KyraEngine_MR::o3_defineObject(EMCState *script) {
53 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineObject(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script,
54 			stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
55 	TalkObject &obj = _talkObjectList[stackPos(0)];
56 	strcpy(obj.filename, stackPosString(1));
57 	obj.sceneAnim = stackPos(2);
58 	obj.sceneScript = stackPos(3);
59 	obj.x = stackPos(4);
60 	obj.y = stackPos(5);
61 	obj.color = stackPos(6);
62 	obj.sceneId = stackPos(7);
63 	return 0;
64 }
65 
o3_refreshCharacter(EMCState * script)66 int KyraEngine_MR::o3_refreshCharacter(EMCState *script) {
67 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_refreshCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
68 	const int frame = stackPos(0);
69 	const int facing = stackPos(1);
70 	const bool updateNeed = stackPos(2) != 0;
71 
72 	if (facing >= 0)
73 		_mainCharacter.facing = facing;
74 
75 	if (frame >= 0 && frame != 87)
76 		_mainCharacter.animFrame = (_mainCharacter.facing == 0xFF) ? 0 : _characterFrameTable[_mainCharacter.facing];
77 	else
78 		_mainCharacter.animFrame = 87;
79 
80 	updateCharacterAnim(0);
81 
82 	if (updateNeed)
83 		refreshAnimObjectsIfNeed();
84 	return 0;
85 }
86 
o3_getMalcolmsMood(EMCState * script)87 int KyraEngine_MR::o3_getMalcolmsMood(EMCState *script) {
88 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getMalcolmsMood(%p) ()", (const void *)script);
89 	return _malcolmsMood;
90 }
91 
o3_getCharacterFrameFromFacing(EMCState * script)92 int KyraEngine_MR::o3_getCharacterFrameFromFacing(EMCState *script) {
93 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getCharacterFrameFromFacing(%p) ()", (const void *)script);
94 	return (_mainCharacter.facing == 0xFF) ? 0 : _characterFrameTable[_mainCharacter.facing];
95 }
96 
o3_setCharacterFacing(EMCState * script)97 int KyraEngine_MR::o3_setCharacterFacing(EMCState *script) {
98 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterFacing(%p) (%d)", (const void *)script, stackPos(0));
99 	_mainCharacter.facing = stackPos(0);
100 	return 0;
101 }
102 
o3_showSceneFileMessage(EMCState * script)103 int KyraEngine_MR::o3_showSceneFileMessage(EMCState *script) {
104 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showSceneFileMessage(%p) (%d)", (const void *)script, stackPos(0));
105 	showMessage((const char *)getTableEntry(_scenesFile, stackPos(0)), 0xFF, 0xF0);
106 	return 0;
107 }
108 
o3_setCharacterAnimFrameFromFacing(EMCState * script)109 int KyraEngine_MR::o3_setCharacterAnimFrameFromFacing(EMCState *script) {
110 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterAnimFrameFromFacing(%p) ()", (const void *)script);
111 	updateCharPal(0);
112 	_mainCharacter.animFrame = (_mainCharacter.facing == 0xFF) ? 0 : _characterFrameTable[_mainCharacter.facing];
113 	updateCharacterAnim(0);
114 	refreshAnimObjectsIfNeed();
115 	return 0;
116 }
117 
o3_showBadConscience(EMCState * script)118 int KyraEngine_MR::o3_showBadConscience(EMCState *script) {
119 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showBadConscience(%p) ()", (const void *)script);
120 	showBadConscience();
121 	return 0;
122 }
123 
o3_hideBadConscience(EMCState * script)124 int KyraEngine_MR::o3_hideBadConscience(EMCState *script) {
125 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_hideBadConscience(%p) ()", (const void *)script);
126 	hideBadConscience();
127 	return 0;
128 }
129 
o3_showAlbum(EMCState * script)130 int KyraEngine_MR::o3_showAlbum(EMCState *script) {
131 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showAlbum(%p) ()", (const void *)script);
132 	showAlbum();
133 	return 0;
134 }
135 
o3_setInventorySlot(EMCState * script)136 int KyraEngine_MR::o3_setInventorySlot(EMCState *script) {
137 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setInventorySlot(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
138 	const int slot = MAX<int16>(0, MIN<int16>(10, stackPos(0)));
139 	return (_mainCharacter.inventory[slot] = stackPos(1));
140 }
141 
o3_getInventorySlot(EMCState * script)142 int KyraEngine_MR::o3_getInventorySlot(EMCState *script) {
143 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getInventorySlot(%p) (%d)", (const void *)script, stackPos(0));
144 	return _mainCharacter.inventory[stackPos(0)];
145 }
146 
o3_addItemToInventory(EMCState * script)147 int KyraEngine_MR::o3_addItemToInventory(EMCState *script) {
148 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_addItemToInventory(%p) (%d)", (const void *)script, stackPos(0));
149 	int slot = findFreeInventorySlot();
150 	if (slot >= 0) {
151 		_mainCharacter.inventory[slot] = stackPos(0);
152 		if (_inventoryState) {
153 			redrawInventory(0);
154 		}
155 	}
156 	return slot;
157 }
158 
o3_addItemToCurScene(EMCState * script)159 int KyraEngine_MR::o3_addItemToCurScene(EMCState *script) {
160 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_addItemToCurScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
161 	const uint16 item = stackPos(0);
162 	int x = stackPos(1);
163 	int y = stackPos(2);
164 	int itemSlot = findFreeItem();
165 
166 	if (x < 20)
167 		x = 20;
168 	else if (x > 299)
169 		x = 299;
170 
171 	if (y < 18)
172 		y = 18;
173 	else if (y >= _interfaceCommandLineY1)
174 		y = _interfaceCommandLineY1 - 1;
175 
176 	if (itemSlot >= 0) {
177 		_itemList[itemSlot].x = x;
178 		_itemList[itemSlot].y = y;
179 		_itemList[itemSlot].id = item;
180 		_itemList[itemSlot].sceneId = _mainCharacter.sceneId;
181 		addItemToAnimList(itemSlot);
182 		refreshAnimObjectsIfNeed();
183 	}
184 
185 	return itemSlot;
186 }
187 
o3_objectChat(EMCState * script)188 int KyraEngine_MR::o3_objectChat(EMCState *script) {
189 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_objectChat(%p) (%d)", (const void *)script, stackPos(0));
190 	int id = stackPos(0);
191 	const char *str = (const char *)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id);
192 	if (str) {
193 		objectChat(str, 0, _vocHigh, id);
194 		playStudioSFX(str);
195 	}
196 	return 0;
197 }
198 
o3_resetInventory(EMCState * script)199 int KyraEngine_MR::o3_resetInventory(EMCState *script) {
200 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_resetInventory(%p) ()", (const void *)script);
201 	memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory));
202 	return 0;
203 }
204 
o3_removeInventoryItemInstances(EMCState * script)205 int KyraEngine_MR::o3_removeInventoryItemInstances(EMCState *script) {
206 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeInventoryItemInstances(%p) (%d)", (const void *)script, stackPos(0));
207 	const int item = stackPos(0);
208 	for (int i = 0; i < 10; ++i) {
209 		if (_mainCharacter.inventory[i] == item)
210 			_mainCharacter.inventory[i] = kItemNone;
211 	}
212 	return 0;
213 }
214 
o3_countInventoryItemInstances(EMCState * script)215 int KyraEngine_MR::o3_countInventoryItemInstances(EMCState *script) {
216 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_countInventoryItemInstances(%p) (%d)", (const void *)script, stackPos(0));
217 	const int item = stackPos(0);
218 	int count = 0;
219 
220 	for (int i = 0; i < 10; ++i) {
221 		if (_mainCharacter.inventory[i] == item)
222 			++count;
223 	}
224 
225 	if (_itemInHand == item)
226 		++count;
227 
228 	return count;
229 }
230 
o3_npcChatSequence(EMCState * script)231 int KyraEngine_MR::o3_npcChatSequence(EMCState *script) {
232 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_npcChatSequence(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
233 	const int id = stackPos(0);
234 	const char *str = (const char *)getTableEntry(_sceneStrings, id);
235 	if (str)
236 		npcChatSequence(str, stackPos(1), _vocHigh, id);
237 	return 0;
238 }
239 
o3_badConscienceChat(EMCState * script)240 int KyraEngine_MR::o3_badConscienceChat(EMCState *script) {
241 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_badConscienceChat(%p) (%d)", (const void *)script, stackPos(0));
242 	int id = stackPos(0);
243 	const char *str = (const char *)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id);
244 	badConscienceChat(str, _vocHigh, id);
245 	return 0;
246 }
247 
o3_wipeDownMouseItem(EMCState * script)248 int KyraEngine_MR::o3_wipeDownMouseItem(EMCState *script) {
249 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_wipeDownMouseItem(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2));
250 	_screen->hideMouse();
251 	const int x = stackPos(1) - 12;
252 	const int y = stackPos(2) - 19;
253 
254 	if (_itemInHand >= 0) {
255 		backUpGfxRect32x32(x, y);
256 		uint8 *shape = getShapePtr(_itemInHand+248);
257 		for (int curY = y, height = 20; height > 0; height -= 2, curY += 2) {
258 			restoreGfxRect32x32(x, y);
259 			_screen->setNewShapeHeight(shape, height);
260 			const uint32 waitTime = _system->getMillis() + _tickLength;
261 			_screen->drawShape(0, shape, x, curY, 0, 0);
262 			_screen->updateScreen();
263 			delayUntil(waitTime);
264 		}
265 		restoreGfxRect32x32(x, y);
266 		_screen->resetShapeHeight(shape);
267 	}
268 
269 	_screen->showMouse();
270 	removeHandItem();
271 
272 	return 0;
273 }
274 
o3_setMalcolmsMood(EMCState * script)275 int KyraEngine_MR::o3_setMalcolmsMood(EMCState *script) {
276 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setMalcolmsMood(%p) (%d)", (const void *)script, stackPos(0));
277 	return (_malcolmsMood = stackPos(0));
278 }
279 
o3_updateScore(EMCState * script)280 int KyraEngine_MR::o3_updateScore(EMCState *script) {
281 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_updateScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
282 	return updateScore(stackPos(0), stackPos(1)) ? 1 : 0;
283 }
284 
o3_makeSecondChanceSave(EMCState * script)285 int KyraEngine_MR::o3_makeSecondChanceSave(EMCState *script) {
286 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_makeSecondChanceSave(%p) ()", (const void *)script);
287 	saveGameStateIntern(999, "Autosave", 0);
288 	return 0;
289 }
290 
o3_setSceneFilename(EMCState * script)291 int KyraEngine_MR::o3_setSceneFilename(EMCState *script) {
292 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSceneFilename(%p) (%d, '%s')", (const void *)script, stackPos(0), stackPosString(1));
293 	strcpy(_sceneList[stackPos(0)].filename1, stackPosString(1));
294 	_sceneList[stackPos(0)].filename1[9] = 0;
295 	return 0;
296 }
297 
o3_removeItemsFromScene(EMCState * script)298 int KyraEngine_MR::o3_removeItemsFromScene(EMCState *script) {
299 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeItemsFromScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
300 	const uint16 itemId = stackPos(0);
301 	const uint16 sceneId = stackPos(1);
302 	const bool allItems = (stackPos(2) != 0);
303 
304 	int retValue = 0;
305 
306 	for (int i = 0; i < 50; ++i) {
307 		if (_itemList[i].sceneId == sceneId && _itemList[i].id == itemId) {
308 			resetItem(i);
309 			retValue = 1;
310 			if (!allItems)
311 				return 1;
312 		}
313 	}
314 
315 	return retValue;
316 }
317 
o3_disguiseMalcolm(EMCState * script)318 int KyraEngine_MR::o3_disguiseMalcolm(EMCState *script) {
319 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_disguiseMalcolm(%p) (%d)", (const void *)script, stackPos(0));
320 	loadCharacterShapes(stackPos(0));
321 	updateDlgIndex();
322 	return 0;
323 }
324 
o3_drawSceneShape(EMCState * script)325 int KyraEngine_MR::o3_drawSceneShape(EMCState *script) {
326 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_drawSceneShape(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
327 
328 	int shape = stackPos(0);
329 	int flag = (stackPos(1) != 0) ? 1 : 0;
330 
331 	restorePage3();
332 
333 	const int x = _sceneShapeDescs[shape].drawX;
334 	const int y = _sceneShapeDescs[shape].drawY;
335 
336 	_screen->drawShape(2, _sceneShapes[shape], x, y, 2, flag);
337 
338 	_screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer);
339 
340 	_screen->drawShape(0, _sceneShapes[shape], x, y, 2, flag);
341 
342 	flagAnimObjsForRefresh();
343 	refreshAnimObjectsIfNeed();
344 	return 0;
345 }
346 
o3_drawSceneShapeOnPage(EMCState * script)347 int KyraEngine_MR::o3_drawSceneShapeOnPage(EMCState *script) {
348 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_drawSceneShapeOnPage(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
349 	const int shape = stackPos(0);
350 
351 	int x = _sceneShapeDescs[shape].drawX;
352 	int y = _sceneShapeDescs[shape].drawY;
353 	_screen->drawShape(stackPos(2), _sceneShapes[shape], x, y, 2, (stackPos(1) != 0) ? 1 : 0);
354 	return 0;
355 }
356 
o3_checkInRect(EMCState * script)357 int KyraEngine_MR::o3_checkInRect(EMCState *script) {
358 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_checkInRect(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script,
359 			stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
360 	const int x1 = stackPos(0);
361 	const int y1 = stackPos(1);
362 	const int x2 = stackPos(2);
363 	const int y2 = stackPos(3);
364 	int x = stackPos(4), y = stackPos(5);
365 	if (_itemInHand >= 0) {
366 		const int8 *desc = &_itemBuffer2[_itemInHand*2];
367 		x -= 12;
368 		x += desc[0];
369 		y -= 19;
370 		y += desc[1];
371 	}
372 
373 	if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
374 		return 1;
375 	else
376 		return 0;
377 }
378 
o3_updateConversations(EMCState * script)379 int KyraEngine_MR::o3_updateConversations(EMCState *script) {
380 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_updateConversations(%p) (%d)", (const void *)script, stackPos(0));
381 	int dlgIndex = stackPos(0);
382 	switch (_currentChapter-2) {
383 	case 0:
384 		dlgIndex -= 34;
385 		break;
386 
387 	case 1:
388 		dlgIndex -= 54;
389 		break;
390 
391 	case 2:
392 		dlgIndex -= 55;
393 		break;
394 
395 	case 3:
396 		dlgIndex -= 70;
397 		break;
398 
399 	default:
400 		break;
401 	}
402 
403 	int convs[4];
404 	Common::fill(convs, convs+4, -1);
405 
406 	if (_currentChapter == 1) {
407 		switch (_mainCharacter.dlgIndex) {
408 		case 0:
409 			convs[0] = 6;
410 			convs[1] = 12;
411 			break;
412 
413 		case 2:
414 			convs[0] = 8;
415 			convs[1] = 14;
416 			break;
417 
418 		case 3:
419 			convs[0] = 9;
420 			convs[1] = 15;
421 			break;
422 
423 		case 4:
424 			convs[0] = 10;
425 			convs[1] = 16;
426 			break;
427 
428 		case 5:
429 			convs[0] = 11;
430 			convs[1] = 17;
431 			break;
432 
433 		case 6:
434 			convs[0] = 0;
435 			convs[1] = 12;
436 			break;
437 
438 		case 8:
439 			convs[0] = 2;
440 			convs[1] = 14;
441 			break;
442 
443 		case 9:
444 			convs[0] = 3;
445 			convs[1] = 15;
446 			break;
447 
448 		case 10:
449 			convs[0] = 4;
450 			convs[1] = 16;
451 			break;
452 
453 		case 11:
454 			convs[0] = 5;
455 			convs[1] = 17;
456 			break;
457 
458 		case 12:
459 			convs[0] = 0;
460 			convs[1] = 6;
461 			break;
462 
463 		case 14:
464 			convs[0] = 2;
465 			convs[1] = 8;
466 			break;
467 
468 		case 15:
469 			convs[0] = 3;
470 			convs[1] = 9;
471 			break;
472 
473 		case 16:
474 			convs[0] = 4;
475 			convs[1] = 10;
476 			break;
477 
478 		case 17:
479 			convs[0] = 5;
480 			convs[1] = 11;
481 			break;
482 
483 		default:
484 			break;
485 		}
486 	} else if (_currentChapter == 2) {
487 		switch (_mainCharacter.dlgIndex) {
488 		case 0:
489 			convs[0] = 4;
490 			convs[1] = 8;
491 			convs[2] = 5;
492 			convs[3] = 9;
493 			break;
494 
495 		case 1:
496 			convs[0] = 4;
497 			convs[1] = 8;
498 			convs[2] = 0;
499 			convs[3] = 5;
500 			break;
501 
502 		case 2:
503 			convs[0] = 6;
504 			convs[2] = 11;
505 			break;
506 
507 		case 3:
508 			convs[0] = 7;
509 			convs[2] = 12;
510 			break;
511 
512 		case 4:
513 			convs[0] = 0;
514 			convs[1] = 8;
515 			convs[2] = 1;
516 			convs[3] = 9;
517 			break;
518 
519 		case 5:
520 			convs[0] = 0;
521 			convs[1] = 8;
522 			convs[2] = 4;
523 			convs[3] = 1;
524 			break;
525 
526 		case 6:
527 			convs[0] = 2;
528 			convs[1] = 10;
529 			break;
530 
531 		case 7:
532 			convs[0] = 3;
533 			convs[1] = 11;
534 			break;
535 
536 		case 8:
537 			convs[0] = 0;
538 			convs[1] = 4;
539 			convs[2] = 1;
540 			break;
541 
542 		case 9:
543 			convs[0] = 0;
544 			convs[1] = 4;
545 			convs[2] = 0;
546 			convs[3] = 1;
547 			break;
548 
549 		case 10:
550 			convs[0] = 2;
551 			convs[1] = 6;
552 			break;
553 
554 		case 11:
555 			convs[0] = 3;
556 			convs[1] = 7;
557 			break;
558 
559 		default:
560 			break;
561 		}
562 	} else if (_currentChapter == 4) {
563 		if (_malcolmsMood == 0) {
564 			convs[0] = _mainCharacter.dlgIndex - 10;
565 			convs[1] = _mainCharacter.dlgIndex - 5;
566 		} else if (_malcolmsMood == 1) {
567 			convs[0] = _mainCharacter.dlgIndex + 5;
568 			convs[1] = _mainCharacter.dlgIndex + 10;
569 		} else if (_malcolmsMood == 2) {
570 			convs[0] = _mainCharacter.dlgIndex - 5;
571 			convs[1] = _mainCharacter.dlgIndex + 5;
572 		}
573 	}
574 
575 	for (int i = 0; i < 4; ++i) {
576 		if (convs[i] != -1)
577 			_conversationState[dlgIndex][convs[i]] = 0;
578 	}
579 
580 	return 1;
581 }
582 
o3_removeItemSlot(EMCState * script)583 int KyraEngine_MR::o3_removeItemSlot(EMCState *script) {
584 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeItemSlot(%p) (%d)", (const void *)script, stackPos(0));
585 	deleteItemAnimEntry(stackPos(0));
586 	_itemList[stackPos(0)].id = kItemNone;
587 	return 1;
588 }
589 
o3_setSceneDim(EMCState * script)590 int KyraEngine_MR::o3_setSceneDim(EMCState *script) {
591 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSceneDim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
592 	_sceneMinX = stackPos(0);
593 	_sceneMaxX = stackPos(1);
594 	return 0;
595 }
596 
o3_setSceneAnimPosAndFrame(EMCState * script)597 int KyraEngine_MR::o3_setSceneAnimPosAndFrame(EMCState *script) {
598 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSceneAnimPosAndFrame(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script,
599 			stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
600 	SceneAnim &anim = _sceneAnims[stackPos(0)];
601 	const int newX2 = stackPos(1);
602 	const int newY2 = stackPos(2);
603 	const int newX = stackPos(3);
604 	const int newY = stackPos(4);
605 
606 	if (newX2 >= 0)
607 		anim.x2 = newX2;
608 	if (newY2 >= 0)
609 		anim.y2 = newY2;
610 
611 	if (newX >= 0)
612 		anim.x = newX;
613 	else
614 		anim.x = anim.x2 + (anim.width >> 1);
615 
616 	if (newY >= 0)
617 		anim.y = newY;
618 	else
619 		anim.y = anim.y2 + anim.height - 1;
620 
621 	updateSceneAnim(stackPos(0), stackPos(5));
622 	_specialSceneScriptRunFlag = false;
623 	return 0;
624 }
625 
o3_removeItemInstances(EMCState * script)626 int KyraEngine_MR::o3_removeItemInstances(EMCState *script) {
627 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeItemInstances(%p) (%d)", (const void *)script, stackPos(0));
628 	const int16 item = stackPos(0);
629 
630 	int deleted = 0;
631 
632 	for (int i = 0; i < 10; ++i) {
633 		if (_mainCharacter.inventory[i] == item) {
634 			_mainCharacter.inventory[i] = kItemNone;
635 			++deleted;
636 		}
637 	}
638 
639 	if (_itemInHand == item) {
640 		removeHandItem();
641 		++deleted;
642 	}
643 
644 	for (int i = 0; i < 50; ++i) {
645 		if (_itemList[i].id == item) {
646 			_itemList[i].id = kItemNone;
647 			++deleted;
648 		}
649 	}
650 
651 	return deleted;
652 }
653 
o3_disableInventory(EMCState * script)654 int KyraEngine_MR::o3_disableInventory(EMCState *script) {
655 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_disableInventory(%p) ()", (const void *)script);
656 	_enableInventory = false;
657 	return 0;
658 }
659 
o3_enableInventory(EMCState * script)660 int KyraEngine_MR::o3_enableInventory(EMCState *script) {
661 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_enableInventory(%p) ()", (const void *)script);
662 	_enableInventory = true;
663 	return 1;
664 }
665 
o3_enterNewScene(EMCState * script)666 int KyraEngine_MR::o3_enterNewScene(EMCState *script) {
667 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0),
668 		stackPos(1), stackPos(2), stackPos(3), stackPos(4));
669 
670 	_screen->hideMouse();
671 	enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
672 
673 	_unk5 = 1;
674 
675 	if (_mainCharX == -1 || _mainCharY == -1) {
676 		_mainCharacter.animFrame = (_mainCharacter.facing == 0xFF) ? 0 : _characterFrameTable[_mainCharacter.facing];
677 		updateCharacterAnim(0);
678 	}
679 	_screen->showMouse();
680 
681 	return 0;
682 }
683 
o3_switchScene(EMCState * script)684 int KyraEngine_MR::o3_switchScene(EMCState *script) {
685 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_switchScene(%p) (%d)", (const void *)script, stackPos(0));
686 	setGameFlag(1);
687 	_mainCharX = _mainCharacter.x1;
688 	_mainCharY = _mainCharacter.y1;
689 	_noScriptEnter = false;
690 	enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0);
691 	_noScriptEnter = true;
692 	return 0;
693 }
694 
o3_setMalcolmPos(EMCState * script)695 int KyraEngine_MR::o3_setMalcolmPos(EMCState *script) {
696 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setMalcolmPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
697 	_mainCharX = stackPos(0);
698 	_mainCharY = stackPos(1);
699 
700 	if (_mainCharX == -1 && _mainCharY == -1)
701 		_mainCharacter.animFrame = 87;
702 	else
703 		_mainCharacter.animFrame = (_mainCharacter.facing == 0xFF) ? 0 : _characterFrameTable[_mainCharacter.facing];
704 
705 	return 0;
706 }
707 
o3_stopMusic(EMCState * script)708 int KyraEngine_MR::o3_stopMusic(EMCState *script) {
709 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_stopMusic(%p) ()", (const void *)script);
710 	stopMusicTrack();
711 	return 0;
712 }
713 
o3_playSoundEffect(EMCState * script)714 int KyraEngine_MR::o3_playSoundEffect(EMCState *script) {
715 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_playSoundEffect(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
716 	snd_playSoundEffect(stackPos(0), stackPos(1));
717 	return 0;
718 }
719 
o3_getScore(EMCState * script)720 int KyraEngine_MR::o3_getScore(EMCState *script) {
721 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getScore(%p) ()", (const void *)script);
722 	return _score;
723 }
724 
o3_daggerWarning(EMCState * script)725 int KyraEngine_MR::o3_daggerWarning(EMCState *script) {
726 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_daggerWarning(%p) ()", (const void *)script);
727 	int selection = 1;
728 
729 	_screen->hideMouse();
730 	_screen->copyRegionToBuffer(1, 0, 0, 320, 200, _screenBuffer);
731 	int curPageBackUp = _screen->_curPage;
732 	_screen->_curPage = 2;
733 
734 
735 	int y1 = 0xAA;
736 	int y2 = 0xBA;
737 	if (_lang == 3) {
738 		y1 -= 2;
739 		y2 += 4;
740 	}
741 
742 	_screen->drawFilledBox(0, 0, 0x13F, 0xC7, 0xB4, 0xB3, 0xB6);
743 	_screen->drawFilledBox(0xF, y1, 0x68, y2, 0xB4, 0xB3, 0xB6);
744 	_screen->drawFilledBox(0x73, y1, 0xCC, y2, 0xB4, 0xB3, 0xB6);
745 	_screen->drawFilledBox(0xD6, y1, 0x12F, y2, 0xB4, 0xB3, 0xB6);
746 
747 	int y = 15;
748 	int last = 107;
749 	int yInc = 10;
750 
751 	if (_lang == 3) {
752 		y = 6;
753 		last = 105;
754 		yInc = 16;
755 	}
756 
757 	for (int i = 100; i <= last; ++i) {
758 		const char *str = (const char *)getTableEntry(_cCodeFile, i);
759 		int x = _text->getCenterStringX(str, 0, 0x13F);
760 		_text->printText(str, x, y, 0xFF, 0xF0, 0x00);
761 		y += yInc;
762 	}
763 
764 	if (_lang == 3) {
765 		y += 6;
766 		last = 112;
767 	} else {
768 		y += 15;
769 		last = 113;
770 	}
771 
772 	for (int i = 110; i <= last; ++i) {
773 		const char *str = (const char *)getTableEntry(_cCodeFile, i);
774 		int x = _text->getCenterStringX(str, 0, 0x13F);
775 		_text->printText(str, x, y, 0xFF, 0xF0, 0x00);
776 		y += yInc;
777 	}
778 
779 	const char *str = 0;
780 	int x = 0;
781 
782 	str = (const char *)getTableEntry(_cCodeFile, 120);
783 	x = _text->getCenterStringX(str, 0xF, 0x68);
784 	_text->printText(str, x, 174, 0xFF, 0xF0, 0x00);
785 
786 	str = (const char *)getTableEntry(_cCodeFile, 121);
787 	x = _text->getCenterStringX(str, 0x73, 0xCC);
788 	_text->printText(str, x, 174, 0xFF, 0xF0, 0x00);
789 
790 	str = (const char *)getTableEntry(_cCodeFile, 122);
791 	x = _text->getCenterStringX(str, 0xD6, 0x12F);
792 	_text->printText(str, x, 174, 0xFF, 0xF0, 0x00);
793 
794 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
795 	_screen->updateScreen();
796 
797 	_screen->_curPage = curPageBackUp;
798 	_screen->showMouse();
799 
800 	while (!shouldQuit()) {
801 		int keys = checkInput(0);
802 		removeInputTop();
803 
804 		if (keys == 198 || keys == 199) {
805 			if (_mouseX >= 15 && _mouseX <= 104 && _mouseY >= 170 && _mouseY <= 186) {
806 				selection = 1;
807 				break;
808 			} else if (_mouseX >= 115 && _mouseX <= 204 && _mouseY >= 170 && _mouseY <= 186) {
809 				selection = 2;
810 				break;
811 			} else if (_mouseX >= 214 && _mouseX <= 303 && _mouseY >= 170 && _mouseY <= 186) {
812 				selection = 3;
813 				break;
814 			}
815 		}
816 
817 		delay(10);
818 	}
819 
820 	restorePage3();
821 	_screen->copyBlockToPage(1, 0, 0, 320, 200, _screenBuffer);
822 	return selection;
823 }
824 
o3_blockOutWalkableRegion(EMCState * script)825 int KyraEngine_MR::o3_blockOutWalkableRegion(EMCState *script) {
826 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
827 	const int x1 = stackPos(0);
828 	int y1 = stackPos(1);
829 	const int x2 = stackPos(2);
830 	int y2 = stackPos(3);
831 
832 	if (y1 < _maskPageMinY)
833 		y1 = _maskPageMinY;
834 	if (y2 > _maskPageMaxY)
835 		y2 = _maskPageMaxY;
836 
837 	_screen->blockOutRegion(x1, y1, x2-x1+1, y2-y1+1);
838 	return 0;
839 }
840 
o3_showSceneStringsMessage(EMCState * script)841 int KyraEngine_MR::o3_showSceneStringsMessage(EMCState *script) {
842 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showSceneStringsMessage(%p) (%d)", (const void *)script, stackPos(0));
843 	showMessage((const char *)getTableEntry(_sceneStrings, stackPos(0)), 0xFF, 0xF0);
844 	return 0;
845 }
846 
o3_showGoodConscience(EMCState * script)847 int KyraEngine_MR::o3_showGoodConscience(EMCState *script) {
848 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showGoodConscience(%p) ()", (const void *)script);
849 	showGoodConscience();
850 	return 0;
851 }
852 
o3_goodConscienceChat(EMCState * script)853 int KyraEngine_MR::o3_goodConscienceChat(EMCState *script) {
854 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_goodConscienceChat(%p) (%d)", (const void *)script, stackPos(0));
855 	int id = stackPos(0);
856 	const char *str = (const char *)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id);
857 	goodConscienceChat(str, _vocHigh, id);
858 	return 0;
859 }
860 
o3_hideGoodConscience(EMCState * script)861 int KyraEngine_MR::o3_hideGoodConscience(EMCState *script) {
862 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_hideGoodConscience(%p) ()", (const void *)script);
863 	hideGoodConscience();
864 	return 0;
865 }
866 
o3_defineSceneAnim(EMCState * script)867 int KyraEngine_MR::o3_defineSceneAnim(EMCState *script) {
868 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')",
869 		(const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7),
870 		stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12));
871 	const int animId = stackPos(0);
872 	SceneAnim &anim = _sceneAnims[animId];
873 
874 	uint16 flags = anim.flags = stackPos(1);
875 	int x = anim.x = stackPos(2);
876 	int y = anim.y = stackPos(3);
877 	int x2 = anim.x2 = stackPos(4);
878 	int y2 = anim.y2 = stackPos(5);
879 	int w = anim.width = stackPos(6);
880 	int h = anim.height = stackPos(7);
881 	anim.specialSize = stackPos(9);
882 	anim.shapeIndex = stackPos(11);
883 	const char *filename = stackPosString(12);
884 
885 	if (filename)
886 		strcpy(anim.filename, filename);
887 
888 	if (flags & 8) {
889 		_sceneAnimMovie[animId]->open(filename, 1, 0);
890 		if (_sceneAnimMovie[animId]->opened()) {
891 			anim.wsaFlag = 1;
892 			if (x2 == -1)
893 				x2 = _sceneAnimMovie[animId]->xAdd();
894 			if (y2 == -1)
895 				y2 = _sceneAnimMovie[animId]->yAdd();
896 			if (w == -1)
897 				w = _sceneAnimMovie[animId]->width();
898 			if (h == -1)
899 				h = _sceneAnimMovie[animId]->height();
900 			if (x == -1)
901 				x = (w >> 1) + x2;
902 			if (y == -1)
903 				y = y2 + h - 1;
904 
905 			anim.x = x;
906 			anim.y = y;
907 			anim.x2 = x2;
908 			anim.y2 = y2;
909 			anim.width = w;
910 			anim.height = h;
911 		}
912 	}
913 
914 	return 9;
915 }
916 
o3_updateSceneAnim(EMCState * script)917 int KyraEngine_MR::o3_updateSceneAnim(EMCState *script) {
918 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
919 	updateSceneAnim(stackPos(0), stackPos(1));
920 	_specialSceneScriptRunFlag = false;
921 	return 0;
922 }
923 
o3_runActorScript(EMCState * script)924 int KyraEngine_MR::o3_runActorScript(EMCState *script) {
925 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_runActorScript(%p) ()", (const void *)script);
926 	EMCData data;
927 	EMCState state;
928 	memset(&data, 0, sizeof(data));
929 	memset(&state, 0, sizeof(state));
930 
931 	_res->exists("_ACTOR.EMC", true);
932 	_emc->load("_ACTOR.EMC", &data, &_opcodes);
933 	_emc->init(&state, &data);
934 	_emc->start(&state, 0);
935 
936 	state.regs[4] = _itemInHand;
937 	state.regs[0] = _mainCharacter.sceneId;
938 
939 	int vocHigh = _vocHigh;
940 	_vocHigh = 200;
941 	_useActorBuffer = true;
942 
943 	while (_emc->isValid(&state))
944 		_emc->run(&state);
945 
946 	_useActorBuffer = false;
947 	_vocHigh = vocHigh;
948 	_emc->unload(&data);
949 
950 	if (queryGameFlag(0x218)) {
951 		resetGameFlag(0x218);
952 		enterNewScene(78, -1, 0, 0, 0);
953 	}
954 
955 	return 0;
956 }
957 
o3_doDialog(EMCState * script)958 int KyraEngine_MR::o3_doDialog(EMCState *script) {
959 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_doDialog(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
960 	doDialog(stackPos(0), stackPos(1));
961 	return 0;
962 }
963 
o3_setConversationState(EMCState * script)964 int KyraEngine_MR::o3_setConversationState(EMCState *script) {
965 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setConversationState(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
966 	int id = stackPos(0);
967 	const int dlgIndex = stackPos(1);
968 	const int value = stackPos(2);
969 
970 	switch (_currentChapter-2) {
971 	case 0:
972 		id -= 34;
973 		break;
974 
975 	case 1:
976 		id -= 54;
977 		break;
978 
979 	case 2:
980 		id -= 55;
981 		break;
982 
983 	case 3:
984 		id -= 70;
985 		break;
986 
987 	default:
988 		break;
989 	}
990 
991 	return (_conversationState[id][dlgIndex] = value);
992 }
993 
o3_getConversationState(EMCState * script)994 int KyraEngine_MR::o3_getConversationState(EMCState *script) {
995 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getConversationState(%p) (%d)", (const void *)script, stackPos(0));
996 	int id = stackPos(0);
997 	const int dlgIndex = _mainCharacter.dlgIndex;
998 
999 	switch (_currentChapter-2) {
1000 	case 0:
1001 		id -= 34;
1002 		break;
1003 
1004 	case 1:
1005 		id -= 54;
1006 		break;
1007 
1008 	case 2:
1009 		id -= 55;
1010 		break;
1011 
1012 	case 3:
1013 		id -= 70;
1014 		break;
1015 
1016 	default:
1017 		break;
1018 	}
1019 
1020 	return _conversationState[id][dlgIndex];
1021 }
1022 
o3_changeChapter(EMCState * script)1023 int KyraEngine_MR::o3_changeChapter(EMCState *script) {
1024 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_changeChapter(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1025 	changeChapter(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1026 	return 0;
1027 }
1028 
o3_countItemInstances(EMCState * script)1029 int KyraEngine_MR::o3_countItemInstances(EMCState *script) {
1030 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_countItemInstances(%p) (%d)", (const void *)script, stackPos(0));
1031 	int count = 0;
1032 	const int16 item = stackPos(0);
1033 
1034 	for (int i = 0; i < 10; ++i) {
1035 		if (_mainCharacter.inventory[i] == item)
1036 			++count;
1037 	}
1038 
1039 	if (_itemInHand == item)
1040 		++count;
1041 
1042 	for (int i = 0; i < 50; ++i) {
1043 		if (_itemList[i].id == item)
1044 			++count;
1045 	}
1046 
1047 	return count;
1048 }
1049 
o3_dialogStartScript(EMCState * script)1050 int KyraEngine_MR::o3_dialogStartScript(EMCState *script) {
1051 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dialogStartScript(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1052 	dialogStartScript(stackPos(0), stackPos(1));
1053 	return 0;
1054 }
1055 
o3_dialogEndScript(EMCState * script)1056 int KyraEngine_MR::o3_dialogEndScript(EMCState *script) {
1057 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dialogEndScript(%p) (%d)", (const void *)script, stackPos(0));
1058 	dialogEndScript(stackPos(0));
1059 	return 0;
1060 }
1061 
o3_customChat(EMCState * script)1062 int KyraEngine_MR::o3_customChat(EMCState *script) {
1063 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_customChat(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1064 	const int id = stackPos(0);
1065 	const int object = stackPos(1);
1066 	const char *str = (const char *)getTableEntry(_sceneStrings, id);
1067 
1068 	if (!str)
1069 		return 0;
1070 
1071 	strcpy(_stringBuffer, str);
1072 	_chatText = _stringBuffer;
1073 	_chatObject = object;
1074 	_chatVocHigh = _chatVocLow = -1;
1075 	objectChatInit(_stringBuffer, object, _vocHigh, id);
1076 	playVoice(_vocHigh, id);
1077 	return 0;
1078 }
1079 
o3_customChatFinish(EMCState * script)1080 int KyraEngine_MR::o3_customChatFinish(EMCState *script) {
1081 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_customChatFinish(%p) ()", (const void *)script);
1082 	_text->restoreScreen();
1083 	_chatText = "";
1084 	_chatObject = -1;
1085 	return 0;
1086 }
1087 
o3_setupSceneAnimObject(EMCState * script)1088 int KyraEngine_MR::o3_setupSceneAnimObject(EMCState *script) {
1089 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setupSceneAnimObject(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %s)", (const void *)script,
1090 			stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9),
1091 			stackPos(10), stackPos(11), stackPosString(12));
1092 	setupSceneAnimObject(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8),
1093 						stackPos(9), stackPos(10), stackPos(11), stackPosString(12));
1094 	return 0;
1095 }
1096 
o3_removeSceneAnimObject(EMCState * script)1097 int KyraEngine_MR::o3_removeSceneAnimObject(EMCState *script) {
1098 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeSceneAnimObject(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1099 	removeSceneAnimObject(stackPos(0), stackPos(1));
1100 	return 0;
1101 }
1102 
o3_dummy(EMCState * script)1103 int KyraEngine_MR::o3_dummy(EMCState *script) {
1104 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dummy(%p) ()", (const void *)script);
1105 	return 0;
1106 }
1107 
1108 #pragma mark -
1109 
o3a_setCharacterFrame(EMCState * script)1110 int KyraEngine_MR::o3a_setCharacterFrame(EMCState *script) {
1111 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3a_setCharacterFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1112 	static const uint8 frameTable[] = {
1113 		0x58, 0xD8, 0xD8, 0x98, 0x78, 0x78, 0xB8, 0xB8
1114 	};
1115 
1116 	_animNewFrame = stackPos(0);
1117 	if (_useFrameTable)
1118 		_animNewFrame += frameTable[_mainCharacter.facing];
1119 
1120 	_animDelayTime = stackPos(1);
1121 	_animNeedUpdate = true;
1122 	return 0;
1123 }
1124 
o3a_playSoundEffect(EMCState * script)1125 int KyraEngine_MR::o3a_playSoundEffect(EMCState *script) {
1126 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3a_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0));
1127 	snd_playSoundEffect(stackPos(0), 200);
1128 	return 0;
1129 }
1130 
1131 #pragma mark -
1132 
o3d_updateAnim(EMCState * script)1133 int KyraEngine_MR::o3d_updateAnim(EMCState *script) {
1134 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3d_updateAnim(%p) (%d)", (const void *)script, stackPos(0));
1135 	if (_dialogSceneAnim >= 0)
1136 		updateSceneAnim(_dialogSceneAnim, stackPos(0));
1137 	return 0;
1138 }
1139 
o3d_delay(EMCState * script)1140 int KyraEngine_MR::o3d_delay(EMCState *script) {
1141 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3d_delay(%p) (%d)", (const void *)script, stackPos(0));
1142 	delayUntil(_system->getMillis() + stackPos(0) * _tickLength, false, true);
1143 	return 0;
1144 }
1145 
1146 #pragma mark -
1147 
1148 typedef Common::Functor1Mem<EMCState *, int, KyraEngine_MR> OpcodeV3;
1149 #define SetOpcodeTable(x) table = &x;
1150 #define Opcode(x) table->push_back(new OpcodeV3(this, &KyraEngine_MR::x))
1151 #define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0))
setupOpcodeTable()1152 void KyraEngine_MR::setupOpcodeTable() {
1153 	Common::Array<const Opcode *> *table = 0;
1154 
1155 	_opcodes.reserve(176);
1156 	SetOpcodeTable(_opcodes);
1157 	// 0x00
1158 	Opcode(o3_getMalcolmShapes);
1159 	Opcode(o3_setCharacterPos);
1160 	Opcode(o3_defineObject);
1161 	Opcode(o3_refreshCharacter);
1162 	// 0x04
1163 	Opcode(o2_getCharacterX);
1164 	Opcode(o2_getCharacterY);
1165 	Opcode(o2_getCharacterFacing);
1166 	Opcode(o2_getCharacterScene);
1167 	// 0x08
1168 	Opcode(o3_getMalcolmsMood);
1169 	Opcode(o3_dummy);
1170 	Opcode(o3_dummy);
1171 	Opcode(o3_getCharacterFrameFromFacing);
1172 	// 0x0C
1173 	Opcode(o2_setCharacterFacingOverwrite);
1174 	Opcode(o2_trySceneChange);
1175 	Opcode(o2_moveCharacter);
1176 	Opcode(o3_setCharacterFacing);
1177 	// 0x10
1178 	OpcodeUnImpl();
1179 	Opcode(o3_showSceneFileMessage);
1180 	Opcode(o3_dummy);
1181 	Opcode(o3_dummy);
1182 	// 0x14
1183 	Opcode(o3_setCharacterAnimFrameFromFacing);
1184 	Opcode(o3_showBadConscience);
1185 	Opcode(o3_dummy);
1186 	Opcode(o3_hideBadConscience);
1187 	// 0x18
1188 	OpcodeUnImpl();
1189 	Opcode(o3_showAlbum);
1190 	Opcode(o3_setInventorySlot);
1191 	Opcode(o3_getInventorySlot);
1192 	// 0x1C
1193 	Opcode(o3_addItemToInventory);
1194 	OpcodeUnImpl();
1195 	Opcode(o3_addItemToCurScene);
1196 	Opcode(o3_objectChat);
1197 	// 0x20
1198 	Opcode(o2_checkForItem);
1199 	Opcode(o3_dummy);
1200 	Opcode(o3_resetInventory);
1201 	Opcode(o2_defineItem);
1202 	// 0x24
1203 	Opcode(o3_removeInventoryItemInstances);
1204 	Opcode(o3_countInventoryItemInstances);
1205 	Opcode(o3_npcChatSequence);
1206 	Opcode(o1_queryGameFlag);
1207 	// 0x28
1208 	Opcode(o1_resetGameFlag);
1209 	Opcode(o1_setGameFlag);
1210 	Opcode(o1_setHandItem);
1211 	Opcode(o1_removeHandItem);
1212 	// 0x2C
1213 	Opcode(o1_getMouseState);
1214 	Opcode(o1_hideMouse);
1215 	Opcode(o2_addSpecialExit);
1216 	Opcode(o1_setMousePos);
1217 	// 0x30
1218 	Opcode(o1_showMouse);
1219 	Opcode(o3_badConscienceChat);
1220 	Opcode(o3_wipeDownMouseItem);
1221 	Opcode(o3_dummy);
1222 	// 0x34
1223 	Opcode(o3_setMalcolmsMood);
1224 	Opcode(o3_playSoundEffect);
1225 	Opcode(o3_dummy);
1226 	Opcode(o2_delay);
1227 	// 0x38
1228 	Opcode(o3_updateScore);
1229 	Opcode(o3_makeSecondChanceSave);
1230 	Opcode(o3_setSceneFilename);
1231 	OpcodeUnImpl();
1232 	// 0x3C
1233 	Opcode(o3_removeItemsFromScene);
1234 	Opcode(o3_disguiseMalcolm);
1235 	Opcode(o3_drawSceneShape);
1236 	Opcode(o3_drawSceneShapeOnPage);
1237 	// 0x40
1238 	Opcode(o3_checkInRect);
1239 	Opcode(o3_updateConversations);
1240 	Opcode(o3_removeItemSlot);
1241 	Opcode(o3_dummy);
1242 	// 0x44
1243 	Opcode(o3_dummy);
1244 	Opcode(o3_setSceneDim);
1245 	OpcodeUnImpl();
1246 	Opcode(o3_dummy);
1247 	// 0x48
1248 	Opcode(o3_dummy);
1249 	Opcode(o3_dummy);
1250 	Opcode(o3_setSceneAnimPosAndFrame);
1251 	Opcode(o2_update);
1252 	// 0x4C
1253 	Opcode(o3_removeItemInstances);
1254 	Opcode(o3_dummy);
1255 	Opcode(o3_disableInventory);
1256 	Opcode(o3_enableInventory);
1257 	// 0x50
1258 	Opcode(o3_enterNewScene);
1259 	Opcode(o3_switchScene);
1260 	Opcode(o2_getShapeFlag1);
1261 	Opcode(o3_dummy);
1262 	// 0x54
1263 	Opcode(o3_dummy);
1264 	Opcode(o3_dummy);
1265 	Opcode(o3_setMalcolmPos);
1266 	Opcode(o3_stopMusic);
1267 	// 0x58
1268 	Opcode(o1_playWanderScoreViaMap);
1269 	Opcode(o3_playSoundEffect);
1270 	Opcode(o3_getScore);
1271 	Opcode(o3_daggerWarning);
1272 	// 0x5C
1273 	Opcode(o3_blockOutWalkableRegion);
1274 	Opcode(o3_dummy);
1275 	Opcode(o3_showSceneStringsMessage);
1276 	OpcodeUnImpl();
1277 	// 0x60
1278 	Opcode(o1_getRand);
1279 	Opcode(o3_dummy);
1280 	Opcode(o1_setDeathHandler);
1281 	Opcode(o3_showGoodConscience);
1282 	// 0x64
1283 	Opcode(o3_goodConscienceChat);
1284 	Opcode(o3_hideGoodConscience);
1285 	Opcode(o3_dummy);
1286 	Opcode(o3_dummy);
1287 	// 0x68
1288 	Opcode(o3_dummy);
1289 	Opcode(o3_dummy);
1290 	Opcode(o3_dummy);
1291 	Opcode(o2_waitForConfirmationClick);
1292 	// 0x6C
1293 	Opcode(o3_dummy);
1294 	Opcode(o2_defineRoomEntrance);
1295 	Opcode(o2_runAnimationScript);
1296 	Opcode(o2_setSpecialSceneScriptRunTime);
1297 	// 0x70
1298 	Opcode(o3_defineSceneAnim);
1299 	Opcode(o3_dummy);
1300 	Opcode(o3_updateSceneAnim);
1301 	Opcode(o3_dummy);
1302 	// 0x74
1303 	Opcode(o3_runActorScript);
1304 	Opcode(o3_doDialog);
1305 	Opcode(o2_randomSceneChat);
1306 	Opcode(o2_setDlgIndex);
1307 	// 0x78
1308 	Opcode(o2_getDlgIndex);
1309 	Opcode(o2_defineScene);
1310 	Opcode(o3_setConversationState);
1311 	OpcodeUnImpl();
1312 	// 0x7C
1313 	OpcodeUnImpl();
1314 	Opcode(o3_getConversationState);
1315 	Opcode(o3_dummy);
1316 	Opcode(o3_dummy);
1317 	// 0x80
1318 	Opcode(o3_dummy);
1319 	Opcode(o3_changeChapter);
1320 	Opcode(o3_dummy);
1321 	Opcode(o3_dummy);
1322 	// 0x84
1323 	Opcode(o3_dummy);
1324 	Opcode(o3_dummy);
1325 	Opcode(o3_dummy);
1326 	Opcode(o3_dummy);
1327 	// 0x88
1328 	Opcode(o3_countItemInstances);
1329 	Opcode(o3_dummy);
1330 	Opcode(o3_dialogStartScript);
1331 	Opcode(o3_dummy);
1332 	// 0x8C
1333 	Opcode(o3_dialogEndScript);
1334 	Opcode(o3_dummy);
1335 	Opcode(o3_dummy);
1336 	Opcode(o2_setSpecialSceneScriptState);
1337 	// 0x90
1338 	Opcode(o2_clearSpecialSceneScriptState);
1339 	Opcode(o2_querySpecialSceneScriptState);
1340 	Opcode(o3_dummy);
1341 	Opcode(o2_setHiddenItemsEntry);
1342 	// 0x94
1343 	Opcode(o2_getHiddenItemsEntry);
1344 	Opcode(o3_dummy);
1345 	Opcode(o3_dummy);
1346 	OpcodeUnImpl();
1347 	// 0x98
1348 	Opcode(o3_customChat);
1349 	Opcode(o3_customChatFinish);
1350 	Opcode(o3_setupSceneAnimObject);
1351 	Opcode(o3_removeSceneAnimObject);
1352 	// 0x9C
1353 	Opcode(o2_disableTimer);
1354 	Opcode(o2_enableTimer);
1355 	Opcode(o2_setTimerCountdown);
1356 	OpcodeUnImpl();
1357 	// 0xA0
1358 	Opcode(o3_dummy);
1359 	Opcode(o3_dummy);
1360 	Opcode(o3_dummy);
1361 	Opcode(o3_dummy);
1362 	// 0xA4
1363 	OpcodeUnImpl();
1364 	OpcodeUnImpl();
1365 	OpcodeUnImpl();
1366 	Opcode(o2_setVocHigh);
1367 	// 0xA8
1368 	Opcode(o2_getVocHigh);
1369 	OpcodeUnImpl();
1370 	OpcodeUnImpl();
1371 	OpcodeUnImpl();
1372 	// 0xAC
1373 	OpcodeUnImpl();
1374 	Opcode(o3_dummy);
1375 	OpcodeUnImpl();
1376 	Opcode(o3_dummy);
1377 
1378 	_opcodesAnimation.reserve(8);
1379 	SetOpcodeTable(_opcodesAnimation);
1380 	// 0x00
1381 	Opcode(o2a_setAnimationShapes);
1382 	Opcode(o3a_setCharacterFrame);
1383 	Opcode(o3a_playSoundEffect);
1384 	Opcode(o3_dummy);
1385 	// 0x04
1386 	Opcode(o2a_setResetFrame);
1387 	Opcode(o1_getRand);
1388 	Opcode(o3_getMalcolmShapes);
1389 	Opcode(o3_dummy);
1390 
1391 	_opcodesDialog.reserve(5);
1392 	SetOpcodeTable(_opcodesDialog);
1393 	// 0x00
1394 	Opcode(o3d_updateAnim);
1395 	Opcode(o3d_delay);
1396 	Opcode(o1_getRand);
1397 	Opcode(o1_queryGameFlag);
1398 	// 0x04
1399 	Opcode(o3_dummy);
1400 }
1401 
1402 } // End of namespace Kyra
1403