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 #ifdef ENABLE_LOL
24 
25 #include "kyra/engine/lol.h"
26 #include "kyra/graphics/screen_lol.h"
27 #include "kyra/engine/timer.h"
28 #include "kyra/resource/resource.h"
29 #include "kyra/sound/sound.h"
30 
31 #include "common/system.h"
32 
33 namespace Kyra {
34 
runInitScript(const char * filename,int optionalFunc)35 void LoLEngine::runInitScript(const char *filename, int optionalFunc) {
36 	_suspendScript = true;
37 	EMCData scriptData;
38 	EMCState scriptState;
39 	memset(&scriptData, 0, sizeof(EMCData));
40 	_emc->unload(&_scriptData);
41 	_emc->load(filename, &scriptData, &_opcodes);
42 
43 	_emc->init(&scriptState, &scriptData);
44 	_emc->start(&scriptState, 0);
45 	while (_emc->isValid(&scriptState))
46 		_emc->run(&scriptState);
47 
48 	if (optionalFunc) {
49 		_emc->init(&scriptState, &scriptData);
50 		_emc->start(&scriptState, optionalFunc);
51 		while (_emc->isValid(&scriptState))
52 			_emc->run(&scriptState);
53 	}
54 
55 	_emc->unload(&scriptData);
56 	_suspendScript = false;
57 }
58 
runInfScript(const char * filename)59 void LoLEngine::runInfScript(const char *filename) {
60 	_emc->unload(&_scriptData);
61 	_emc->load(filename, &_scriptData, &_opcodes);
62 	runLevelScript(0x400, -1);
63 }
64 
runLevelScript(int block,int flags)65 void LoLEngine::runLevelScript(int block, int flags) {
66 	runLevelScriptCustom(block, flags, -1, 0, 0, 0);
67 }
68 
runLevelScriptCustom(int block,int flags,int charNum,int item,int reg3,int reg4)69 void LoLEngine::runLevelScriptCustom(int block, int flags, int charNum, int item, int reg3, int reg4) {
70 	EMCState scriptState;
71 	memset(&scriptState, 0, sizeof(EMCState));
72 
73 	if (!_suspendScript) {
74 		_emc->init(&scriptState, &_scriptData);
75 		_emc->start(&scriptState, block);
76 
77 		scriptState.regs[0] = flags;
78 		scriptState.regs[1] = charNum;
79 		scriptState.regs[2] = item;
80 		scriptState.regs[3] = reg3;
81 		scriptState.regs[4] = reg4;
82 		scriptState.regs[5] = block;
83 		scriptState.regs[6] = _scriptDirection;
84 
85 		if (_emc->isValid(&scriptState)) {
86 			if (*(scriptState.ip - 1) & flags) {
87 				while (_emc->isValid(&scriptState))
88 					_emc->run(&scriptState);
89 			}
90 		}
91 	}
92 
93 	checkSceneUpdateNeed(block);
94 }
95 
olol_setWallType(EMCState * script)96 int LoLEngine::olol_setWallType(EMCState *script) {
97 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setWallType(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
98 	if (stackPos(2) != -1) {
99 		if (_wllWallFlags[stackPos(2)] & 4)
100 			deleteMonstersFromBlock(stackPos(0));
101 	}
102 	setWallType(stackPos(0), stackPos(1), stackPos(2));
103 	return 1;
104 }
105 
olol_getWallType(EMCState * script)106 int LoLEngine::olol_getWallType(EMCState *script) {
107 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getWallType(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
108 	return (int8)_levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3];
109 }
110 
olol_drawScene(EMCState * script)111 int LoLEngine::olol_drawScene(EMCState *script) {
112 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_drawScene(%p) (%d)", (const void *)script, stackPos(0));
113 	drawScene(stackPos(0));
114 	return 1;
115 }
116 
olol_rollDice(EMCState * script)117 int LoLEngine::olol_rollDice(EMCState *script) {
118 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_rollDice(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
119 	return rollDice(stackPos(0), stackPos(1));
120 }
121 
olol_moveParty(EMCState * script)122 int LoLEngine::olol_moveParty(EMCState *script) {
123 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveParty(%p) (%d)", (const void *)script, stackPos(0));
124 	int mode = stackPos(0);
125 	if (mode > 5 && mode < 10)
126 		mode = (mode - 6 - _currentDirection) & 3;
127 
128 	Button b;
129 	b.data0Val2 = b.data1Val2 = b.data2Val2 = 0xFE;
130 	b.data0Val3 = b.data1Val3 = b.data2Val3 = 0x01;
131 
132 	switch (mode) {
133 	case 0:
134 		clickedUpArrow(&b);
135 		break;
136 
137 	case 1:
138 		clickedRightArrow(&b);
139 		break;
140 
141 	case 2:
142 		clickedDownArrow(&b);
143 		break;
144 
145 	case 3:
146 		clickedLeftArrow(&b);
147 		break;
148 
149 	case 4:
150 		clickedTurnLeftArrow(&b);
151 		break;
152 
153 	case 5:
154 		clickedTurnRightArrow(&b);
155 		break;
156 
157 	case 10:
158 	case 11:
159 	case 12:
160 	case 13:
161 		mode = ABS(mode - 10 - _currentDirection);
162 		if (mode > 2)
163 			mode = (mode ^ 2) * -1;
164 
165 		while (mode) {
166 			if (mode > 0) {
167 				clickedTurnRightArrow(&b);
168 				mode--;
169 			} else {
170 				clickedTurnLeftArrow(&b);
171 				mode++;
172 			}
173 		}
174 		break;
175 
176 	default:
177 		break;
178 	}
179 
180 	return 1;
181 }
182 
183 
olol_delay(EMCState * script)184 int LoLEngine::olol_delay(EMCState *script) {
185 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_delay(%p) (%d)", (const void *)script, stackPos(0));
186 	delay(stackPos(0) * _tickLength, true);
187 	return 1;
188 }
189 
olol_setGameFlag(EMCState * script)190 int LoLEngine::olol_setGameFlag(EMCState *script) {
191 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGameFlag(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
192 
193 	if (stackPos(1))
194 		setGameFlag(stackPos(0));
195 	else
196 		resetGameFlag(stackPos(0));
197 
198 	return 1;
199 }
200 
olol_testGameFlag(EMCState * script)201 int LoLEngine::olol_testGameFlag(EMCState *script) {
202 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_testGameFlag(%p) (%d)", (const void *)script, stackPos(0));
203 	if (stackPos(0) < 0)
204 		return 0;
205 
206 	return queryGameFlag(stackPos(0));
207 }
208 
olol_loadLevelGraphics(EMCState * script)209 int LoLEngine::olol_loadLevelGraphics(EMCState *script) {
210 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLevelGraphics(%p) (%s, %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
211 	loadLevelGraphics(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) == -1 ? -1 : (uint16)stackPos(3), stackPos(4) == -1 ? -1 : (uint16)stackPos(4), (stackPos(5) == -1) ? 0 : stackPosString(5));
212 	return 1;
213 }
214 
olol_loadBlockProperties(EMCState * script)215 int LoLEngine::olol_loadBlockProperties(EMCState *script) {
216 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadBlockProperties(%p) (%s)", (const void *)script, stackPosString(0));
217 	loadBlockProperties(stackPosString(0));
218 	return 1;
219 }
220 
olol_loadMonsterShapes(EMCState * script)221 int LoLEngine::olol_loadMonsterShapes(EMCState *script) {
222 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterShapes(%p) (%s, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2));
223 	loadMonsterShapes(stackPosString(0), stackPos(1), stackPos(2));
224 	return 1;
225 }
226 
olol_deleteHandItem(EMCState * script)227 int LoLEngine::olol_deleteHandItem(EMCState *script) {
228 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_deleteHandItem(%p) ()", (const void *)script);
229 	int r = _itemInHand;
230 	deleteItem(_itemInHand);
231 	setHandItem(0);
232 	return r;
233 }
234 
olol_allocItemPropertiesBuffer(EMCState * script)235 int LoLEngine::olol_allocItemPropertiesBuffer(EMCState *script) {
236 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_allocItemPropertiesBuffer(%p) (%d)", (const void *)script, stackPos(0));
237 	delete[] _itemProperties;
238 	_itemProperties = new ItemProperty[stackPos(0)];
239 	return 1;
240 }
241 
olol_setItemProperty(EMCState * script)242 int LoLEngine::olol_setItemProperty(EMCState *script) {
243 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
244 	ItemProperty *tmp = &_itemProperties[stackPos(0)];
245 
246 	tmp->nameStringId = stackPos(1);
247 	tmp->shpIndex = stackPos(2);
248 	tmp->type = stackPos(3);
249 
250 	// WORKAROUND for unpatched early floppy versions.
251 	// The Vaelan's cube should not be able to be equipped in a weapon slot.
252 	if (stackPos(0) == 264 && tmp->type == 5)
253 		tmp->type = 0;
254 
255 	tmp->itemScriptFunc = stackPos(4);
256 	tmp->might = stackPos(5);
257 	tmp->skill = stackPos(6);
258 	tmp->protection = stackPos(7);
259 	tmp->flags = stackPos(8);
260 	tmp->unkB = stackPos(9);
261 	return 1;
262 }
263 
olol_makeItem(EMCState * script)264 int LoLEngine::olol_makeItem(EMCState *script) {
265 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_makeItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
266 	return makeItem(stackPos(0), stackPos(1), stackPos(2));
267 }
268 
olol_placeMoveLevelItem(EMCState * script)269 int LoLEngine::olol_placeMoveLevelItem(EMCState *script) {
270 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeMoveLevelItem(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
271 	placeMoveLevelItem(stackPos(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, stackPos(4) & 0xFF, stackPos(5));
272 	return 1;
273 }
274 
olol_createLevelItem(EMCState * script)275 int LoLEngine::olol_createLevelItem(EMCState *script) {
276 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_createLevelItem(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
277 	int item = makeItem(stackPos(0), stackPos(1), stackPos(2));
278 	if (item == -1)
279 		return item;
280 	placeMoveLevelItem(item, stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
281 	return item;
282 }
283 
olol_getItemPara(EMCState * script)284 int LoLEngine::olol_getItemPara(EMCState *script) {
285 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getItemPara(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
286 	if (!stackPos(0))
287 		return 0;
288 
289 	LoLItem *i = &_itemsInPlay[stackPos(0)];
290 	ItemProperty *p = &_itemProperties[i->itemPropertyIndex];
291 
292 	switch (stackPos(1)) {
293 	case 0:
294 		return i->block;
295 	case 1:
296 		return i->x;
297 	case 2:
298 		return i->y;
299 	case 3:
300 		return i->level;
301 	case 4:
302 		return i->itemPropertyIndex;
303 	case 5:
304 		return i->shpCurFrame_flg;
305 	case 6:
306 		return p->nameStringId;
307 	case 7:
308 		break;
309 	case 8:
310 		return p->shpIndex;
311 	case 9:
312 		return p->type;
313 	case 10:
314 		return p->itemScriptFunc;
315 	case 11:
316 		return p->might;
317 	case 12:
318 		return p->skill;
319 	case 13:
320 		return p->protection;
321 	case 14:
322 		return p->unkB;
323 	case 15:
324 		return i->shpCurFrame_flg & 0x1FFF;
325 	case 16:
326 		return p->flags;
327 	case 17:
328 		return (p->skill << 8) | ((uint8)p->might);
329 	default:
330 		break;
331 	}
332 
333 	return -1;
334 }
335 
olol_getCharacterStat(EMCState * script)336 int LoLEngine::olol_getCharacterStat(EMCState *script) {
337 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getCharacterStat(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
338 	LoLCharacter *c = &_characters[stackPos(0)];
339 	int d = stackPos(2);
340 
341 	switch (stackPos(1)) {
342 	case 0:
343 		return c->flags;
344 
345 	case 1:
346 		return c->raceClassSex;
347 
348 	case 5:
349 		return c->hitPointsCur;
350 
351 	case 6:
352 		return c->hitPointsMax;
353 
354 	case 7:
355 		return c->magicPointsCur;
356 
357 	case 8:
358 		return c->magicPointsMax;
359 
360 	case 9:
361 		return c->itemProtection;
362 
363 	case 10:
364 		return c->items[d];
365 
366 	case 11:
367 		return c->skillLevels[d] + c->skillModifiers[d];
368 
369 	case 12:
370 		return c->protectionAgainstItems[d];
371 
372 	case 13:
373 		return (d & 0x80) ? c->itemsMight[7] : c->itemsMight[d];
374 
375 	case 14:
376 		return c->skillModifiers[d];
377 
378 	case 15:
379 		return c->id;
380 
381 	default:
382 		break;
383 	}
384 
385 	return 0;
386 }
387 
olol_setCharacterStat(EMCState * script)388 int LoLEngine::olol_setCharacterStat(EMCState *script) {
389 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setCharacterStat(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
390 	LoLCharacter *c = &_characters[stackPos(0)];
391 	int d = stackPos(2);
392 	int e = stackPos(3);
393 
394 	switch (stackPos(1)) {
395 	case 0:
396 		c->flags = e;
397 		break;
398 
399 	case 1:
400 		c->raceClassSex = e & 0x0F;
401 		break;
402 
403 	case 5:
404 		setCharacterMagicOrHitPoints(stackPos(0), 0, e, 0);
405 		break;
406 
407 	case 6:
408 		c->hitPointsMax = e;
409 		break;
410 
411 	case 7:
412 		setCharacterMagicOrHitPoints(stackPos(0), 1, e, 0);
413 		break;
414 
415 	case 8:
416 		c->magicPointsMax = e;
417 		break;
418 
419 	case 9:
420 		c->itemProtection = e;
421 		break;
422 
423 	case 10:
424 		c->items[d] = 0;
425 		break;
426 
427 	case 11:
428 		c->skillLevels[d] = e;
429 		break;
430 
431 	case 12:
432 		c->protectionAgainstItems[d] = e;
433 		break;
434 
435 	case 13:
436 		if (d & 0x80)
437 			c->itemsMight[7] = e;
438 		else
439 			c->itemsMight[d] = e;
440 		break;
441 
442 	case 14:
443 		c->skillModifiers[d] = e;
444 		break;
445 
446 	default:
447 		break;
448 	}
449 
450 	return 0;
451 }
452 
olol_loadLevelShapes(EMCState * script)453 int LoLEngine::olol_loadLevelShapes(EMCState *script) {
454 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLevelShapes(%p) (%s, %s)", (const void *)script, stackPosString(0), stackPosString(1));
455 	loadLevelShpDat(stackPosString(0), stackPosString(1), true);
456 	return 1;
457 }
458 
olol_closeLevelShapeFile(EMCState * script)459 int LoLEngine::olol_closeLevelShapeFile(EMCState *script) {
460 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_closeLevelShapeFile(%p) ()", (const void *)script);
461 	delete _lvlShpFileHandle;
462 	_lvlShpFileHandle = 0;
463 	return 1;
464 }
465 
olol_loadDoorShapes(EMCState * script)466 int LoLEngine::olol_loadDoorShapes(EMCState *script) {
467 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadDoorShapes(%p) (%s, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2));
468 	_screen->loadBitmap(stackPosString(0), 3, 3, 0);
469 	const uint8 *p = _screen->getCPagePtr(2);
470 	if (_doorShapes[0])
471 		delete[] _doorShapes[0];
472 	_doorShapes[0] = _screen->makeShapeCopy(p, stackPos(1));
473 	if (_doorShapes[1])
474 		delete[] _doorShapes[1];
475 	_doorShapes[1] = _screen->makeShapeCopy(p, stackPos(2));
476 
477 	for (int i = 0; i < 20; i++) {
478 		_wllWallFlags[i + 3] |= 7;
479 		int t = i % 5;
480 		if (t == 4)
481 			_wllWallFlags[i + 3] &= 0xF8;
482 		if (t == 3)
483 			_wllWallFlags[i + 3] &= 0xFD;
484 	}
485 
486 	if (stackPos(3)) {
487 		for (int i = 3; i < 13; i++)
488 			_wllWallFlags[i] &= 0xFD;
489 	}
490 
491 	if (stackPos(4)) {
492 		for (int i = 13; i < 23; i++)
493 			_wllWallFlags[i] &= 0xFD;
494 	}
495 
496 	return 1;
497 }
498 
olol_initAnimStruct(EMCState * script)499 int LoLEngine::olol_initAnimStruct(EMCState *script) {
500 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_initAnimStruct(%p) (%s, %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
501 	if (_tim->initAnimStruct(stackPos(1), stackPosString(0), stackPos(2), stackPos(3), stackPos(4), 0, stackPos(5)))
502 		return 1;
503 	return 0;
504 }
505 
olol_playAnimationPart(EMCState * script)506 int LoLEngine::olol_playAnimationPart(EMCState *script) {
507 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playAnimationPart(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
508 	_tim->animator()->playPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
509 	return 1;
510 }
511 
olol_freeAnimStruct(EMCState * script)512 int LoLEngine::olol_freeAnimStruct(EMCState *script) {
513 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_freeAnimStruct(%p) (%d)", (const void *)script, stackPos(0));
514 	if (_tim->freeAnimStruct(stackPos(0)))
515 		return 1;
516 	return 0;
517 }
518 
olol_getDirection(EMCState * script)519 int LoLEngine::olol_getDirection(EMCState *script) {
520 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getDirection(%p)", (const void *)script);
521 	return _currentDirection;
522 }
523 
olol_characterSurpriseFeedback(EMCState * script)524 int LoLEngine::olol_characterSurpriseFeedback(EMCState *script) {
525 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterSurpriseFeedback(%p)", (const void *)script);
526 	for (int i = 0; i < 4; i++) {
527 		if (!(_characters[i].flags & 1) || _characters[i].id >= 0)
528 			continue;
529 		int s = -_characters[i].id;
530 		int sfx = (s == 1) ? 136 : ((s == 5) ? 50 : ((s == 8) ? 49 : ((s == 9) ? 48 : 0)));
531 		if (sfx)
532 			snd_playSoundEffect(sfx, -1);
533 		return 1;
534 	}
535 	return 1;
536 }
537 
olol_setMusicTrack(EMCState * script)538 int LoLEngine::olol_setMusicTrack(EMCState *script) {
539 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setMusicTrack(%p) (%d)", (const void *)script, stackPos(0));
540 	_curMusicTheme = stackPos(0);
541 	return 1;
542 }
543 
olol_setSequenceButtons(EMCState * script)544 int LoLEngine::olol_setSequenceButtons(EMCState *script) {
545 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setSequenceButtons(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
546 	setSequenceButtons(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
547 	return 1;
548 }
549 
olol_setDefaultButtonState(EMCState * script)550 int LoLEngine::olol_setDefaultButtonState(EMCState *script) {
551 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setDefaultButtonState(%p)", (const void *)script);
552 	setDefaultButtonState();
553 	return 1;
554 }
555 
olol_checkRectForMousePointer(EMCState * script)556 int LoLEngine::olol_checkRectForMousePointer(EMCState *script) {
557 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkRectForMousePointer(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
558 	return posWithinRect(_mouseX, _mouseY, stackPos(0), stackPos(1), stackPos(2), stackPos(3)) ? 1 : 0;
559 }
560 
olol_clearDialogueField(EMCState * script)561 int LoLEngine::olol_clearDialogueField(EMCState *script) {
562 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_clearDialogueField(%p) (%d)", (const void *)script, stackPos(0));
563 	if (_currentControlMode && (!textEnabled()))
564 		return 1;
565 
566 	_screen->setScreenDim(5);
567 	const ScreenDim *d = _screen->getScreenDim(5);
568 	_screen->fillRect(d->sx, d->sy, d->sx + d->w - (_flags.use16ColorMode ? 3 : 2), d->sy + d->h - 2, d->unkA);
569 	_txt->clearDim(4);
570 	_txt->resetDimTextPositions(4);
571 
572 	return 1;
573 }
574 
olol_setupBackgroundAnimationPart(EMCState * script)575 int LoLEngine::olol_setupBackgroundAnimationPart(EMCState *script) {
576 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupBackgroundAnimationPart(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
577 	_tim->animator()->setupPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
578 	return 0;
579 }
580 
olol_startBackgroundAnimation(EMCState * script)581 int LoLEngine::olol_startBackgroundAnimation(EMCState *script) {
582 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_startBackgroundAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
583 	_tim->animator()->start(stackPos(0), stackPos(1));
584 	return 1;
585 }
586 
olol_fadeToBlack(EMCState * script)587 int LoLEngine::olol_fadeToBlack(EMCState *script) {
588 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeToBlack(%p) (%d)", (const void *)script, stackPos(0));
589 	_screen->fadeToBlack(10);
590 	return 1;
591 }
592 
olol_fadePalette(EMCState * script)593 int LoLEngine::olol_fadePalette(EMCState *script) {
594 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadePalette(%p)", (const void *)script);
595 	if (_flags.use16ColorMode)
596 		setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
597 	else
598 		_screen->fadePalette(_screen->getPalette(3), 10);
599 	_screen->_fadeFlag = 0;
600 	return 1;
601 }
602 
olol_loadBitmap(EMCState * script)603 int LoLEngine::olol_loadBitmap(EMCState *script) {
604 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadBitmap(%p) (%s, %d)", (const void *)script, stackPosString(0), stackPos(1));
605 	_screen->loadBitmap(stackPosString(0), 3, 3, &_screen->getPalette(3));
606 	if (stackPos(1) != 2)
607 		_screen->copyPage(3, stackPos(1));
608 	return 1;
609 }
610 
olol_stopBackgroundAnimation(EMCState * script)611 int LoLEngine::olol_stopBackgroundAnimation(EMCState *script) {
612 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopBackgroundAnimation(%p) (%d)", (const void *)script, stackPos(0));
613 	_tim->animator()->stop(stackPos(0));
614 	return 1;
615 }
616 
olol_getGlobalScriptVar(EMCState * script)617 int LoLEngine::olol_getGlobalScriptVar(EMCState *script) {
618 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getGlobalScriptVar(%p) (%d)", (const void *)script, stackPos(0));
619 	assert(stackPos(0) < 24);
620 	return _globalScriptVars[stackPos(0)];
621 }
622 
olol_setGlobalScriptVar(EMCState * script)623 int LoLEngine::olol_setGlobalScriptVar(EMCState *script) {
624 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGlobalScriptVar(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
625 	assert(stackPos(0) < 24);
626 	_globalScriptVars[stackPos(0)] = stackPos(1);
627 	return 1;
628 }
629 
olol_getGlobalVar(EMCState * script)630 int LoLEngine::olol_getGlobalVar(EMCState *script) {
631 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getGlobalVar(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
632 
633 	switch (stackPos(0)) {
634 	case 0:
635 		return _currentBlock;
636 	case 1:
637 		return _currentDirection;
638 	case 2:
639 		return _currentLevel;
640 	case 3:
641 		return _itemInHand;
642 	case 4:
643 		return _brightness;
644 	case 5:
645 		return _credits;
646 	case 6:
647 		return _globalScriptVars2[stackPos(1)];
648 	case 8:
649 		return _updateFlags;
650 	case 9:
651 		return _lampOilStatus;
652 	case 10:
653 		return _sceneDefaultUpdate;
654 	case 11:
655 		return _compassBroken;
656 	case 12:
657 		return _drainMagic;
658 	case 13:
659 		return getVolume(kVolumeSpeech) - 2;
660 	case 14:
661 		return _tim->_abortFlag;
662 	default:
663 		break;
664 	}
665 
666 	return 0;
667 }
668 
olol_setGlobalVar(EMCState * script)669 int LoLEngine::olol_setGlobalVar(EMCState *script) {
670 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGlobalVar(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
671 	uint16 a = stackPos(1);
672 	uint16 b = stackPos(2);
673 
674 	switch (stackPos(0)) {
675 	case 0:
676 		_currentBlock = b;
677 		calcCoordinates(_partyPosX, _partyPosY, _currentBlock, 0x80, 0x80);
678 		updateAutoMap(_currentBlock);
679 		break;
680 
681 	case 1:
682 		_currentDirection = b;
683 		break;
684 
685 	case 2:
686 		_currentLevel = b & 0xFF;
687 		break;
688 
689 	case 3:
690 		setHandItem(b);
691 		break;
692 
693 	case 4:
694 		_brightness = b & 0xFF;
695 		break;
696 
697 	case 5:
698 		_credits = b;
699 		break;
700 
701 	case 6:
702 		_globalScriptVars2[a] = b;
703 		break;
704 
705 	case 7:
706 		break;
707 
708 	case 8:
709 		_updateFlags = b;
710 		if (b == 1) {
711 			if (!textEnabled() || (!(_currentControlMode & 2)))
712 				timerUpdatePortraitAnimations(1);
713 			disableSysTimer(2);
714 		} else {
715 			enableSysTimer(2);
716 		}
717 		break;
718 
719 	case 9:
720 		_lampOilStatus = b & 0xFF;
721 		break;
722 
723 	case 10:
724 		_sceneDefaultUpdate = b & 0xFF;
725 		gui_toggleButtonDisplayMode(0, 0);
726 		break;
727 
728 	case 11:
729 		_compassBroken = a & 0xFF;
730 		break;
731 
732 	case 12:
733 		_drainMagic = a & 0xFF;
734 		break;
735 
736 	default:
737 		break;
738 	}
739 
740 	return 1;
741 }
742 
olol_triggerDoorSwitch(EMCState * script)743 int LoLEngine::olol_triggerDoorSwitch(EMCState *script) {
744 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_triggerDoorSwitch(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
745 	processDoorSwitch(stackPos(0)/*, (_wllWallFlags[_levelBlockProperties[stackPos(0)].walls[0]] & 8) ? 0 : 1*/, stackPos(1));
746 	return 1;
747 }
748 
olol_checkEquippedItemScriptFlags(EMCState * script)749 int LoLEngine::olol_checkEquippedItemScriptFlags(EMCState *script) {
750 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkEquippedItemScriptFlags(%p)", (const void *)script);
751 	for (int i = 0; i < 4; i++) {
752 		if (!(_characters[i].flags & 1))
753 			continue;
754 		for (int ii = 0; ii < 4; ii++) {
755 			uint8 f = _itemProperties[_itemsInPlay[_characters[i].items[ii]].itemPropertyIndex].itemScriptFunc;
756 			if (f == 0 || f == 2)
757 				return 1;
758 		}
759 	}
760 	return 0;
761 }
762 
olol_setDoorState(EMCState * script)763 int LoLEngine::olol_setDoorState(EMCState *script) {
764 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setDoorState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
765 	if (stackPos(1))
766 		_levelBlockProperties[stackPos(0)].flags = (_levelBlockProperties[stackPos(0)].flags & 0xEF) | 0x20;
767 	else
768 		_levelBlockProperties[stackPos(0)].flags &= 0xDF;
769 	return 1;
770 }
771 
olol_updateBlockAnimations(EMCState * script)772 int LoLEngine::olol_updateBlockAnimations(EMCState *script) {
773 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_updateBlockAnimations(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
774 	int block = stackPos(0);
775 	int wall = stackPos(1);
776 	setWallType(block, wall, _levelBlockProperties[block].walls[(wall == -1) ? 0 : wall] == stackPos(2) ? stackPos(3) : stackPos(2));
777 	return 0;
778 }
779 
olol_assignLevelDecorationShape(EMCState * script)780 int LoLEngine::olol_assignLevelDecorationShape(EMCState *script) {
781 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignLevelDecorationShape(%p) (%d)", (const void *)script, stackPos(0));
782 	return assignLevelDecorationShapes(stackPos(0));
783 }
784 
olol_resetBlockShapeAssignment(EMCState * script)785 int LoLEngine::olol_resetBlockShapeAssignment(EMCState *script) {
786 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_resetBlockShapeAssignment(%p) (%d)", (const void *)script, stackPos(0));
787 	uint8 v = stackPos(0) & 0xFF;
788 	memset(_wllShapeMap + 3, v, 5);
789 	memset(_wllShapeMap + 13, v, 5);
790 	return 1;
791 }
792 
olol_copyRegion(EMCState * script)793 int LoLEngine::olol_copyRegion(EMCState *script) {
794 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_copyRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)",
795 	       (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
796 	_screen->copyRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), Screen::CR_NO_P_CHECK);
797 	if (!stackPos(7))
798 		_screen->updateScreen();
799 	return 1;
800 }
801 
olol_initMonster(EMCState * script)802 int LoLEngine::olol_initMonster(EMCState *script) {
803 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_initMonster(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script,
804 	       stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10));
805 	uint16 x = 0;
806 	uint16 y = 0;
807 	calcCoordinates(x, y, stackPos(0), stackPos(1), stackPos(2));
808 	uint16 w = _monsterProperties[stackPos(4)].maxWidth;
809 
810 	if (checkBlockBeforeObjectPlacement(x, y, w, 7, 7))
811 		return -1;
812 
813 	for (uint8 i = 0; i < 30; i++) {
814 		LoLMonster *l = &_monsters[i];
815 		if (l->hitPoints || l->mode == 13)
816 			continue;
817 
818 		memset(l, 0, sizeof(LoLMonster));
819 		l->id = i;
820 		l->x = x;
821 		l->y = y;
822 		l->facing = stackPos(3);
823 		l->type = stackPos(4);
824 		l->properties = &_monsterProperties[l->type];
825 		l->direction = l->facing << 1;
826 		l->hitPoints = (l->properties->hitPoints * _monsterModifiers1[_monsterDifficulty]) >> 8;
827 
828 		if (_currentLevel != 12 || l->type != 2)
829 			l->hitPoints = (l->hitPoints * (rollDice(1, 128) + 192)) >> 8;
830 
831 		l->numDistAttacks = l->properties->numDistAttacks;
832 		l->distAttackTick = rollDice(1, calcMonsterSkillLevel(l->id | 0x8000, 8)) - 1;
833 		l->flyingHeight = 2;
834 		l->flags = stackPos(5);
835 		l->assignedItems = 0;
836 
837 		setMonsterMode(l, stackPos(6));
838 		placeMonster(l, l->x, l->y);
839 
840 		l->destX = l->x;
841 		l->destY = l->y;
842 		l->destDirection = l->direction;
843 
844 		for (int ii = 0; ii < 4; ii++)
845 			l->equipmentShapes[ii] = stackPos(7 + ii) & 0xFF;
846 
847 		checkSceneUpdateNeed(l->block);
848 		return i;
849 	}
850 
851 	return -1;
852 }
853 
olol_fadeClearSceneWindow(EMCState * script)854 int LoLEngine::olol_fadeClearSceneWindow(EMCState *script) {
855 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeClearSceneWindow(%p)", (const void *)script);
856 	_screen->fadeClearSceneWindow(10);
857 	return 1;
858 }
859 
olol_fadeSequencePalette(EMCState * script)860 int LoLEngine::olol_fadeSequencePalette(EMCState *script) {
861 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeSequencePalette(%p)", (const void *)script);
862 	if (_flags.use16ColorMode) {
863 		setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
864 	} else {
865 		_screen->getPalette(3).copy(_screen->getPalette(0), 128);
866 		_screen->loadSpecialColors(_screen->getPalette(3));
867 		_screen->fadePalette(_screen->getPalette(3), 10);
868 	}
869 	_screen->_fadeFlag = 0;
870 	return 1;
871 }
872 
olol_redrawPlayfield(EMCState * script)873 int LoLEngine::olol_redrawPlayfield(EMCState *script) {
874 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_redrawPlayfield(%p)", (const void *)script);
875 	if (_screen->_fadeFlag != 2)
876 		_screen->fadeClearSceneWindow(10);
877 	gui_drawPlayField();
878 	setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
879 	_screen->_fadeFlag = 0;
880 	return 1;
881 }
882 
olol_loadNewLevel(EMCState * script)883 int LoLEngine::olol_loadNewLevel(EMCState *script) {
884 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadNewLevel(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
885 	_screen->fadeClearSceneWindow(10);
886 	_screen->fillRect(112, 0, 288, 120, 0);
887 	disableSysTimer(2);
888 
889 	for (int i = 0; i < 8; i++) {
890 		if (!_flyingObjects[i].enable || _flyingObjects[i].objectType)
891 			continue;
892 		endObjectFlight(&_flyingObjects[i], _flyingObjects[i].x, _flyingObjects[i].y, 1);
893 	}
894 
895 	completeDoorOperations();
896 
897 	generateTempData();
898 
899 	_currentBlock = stackPos(1);
900 	_currentDirection = stackPos(2);
901 	calcCoordinates(_partyPosX, _partyPosY, _currentBlock, 0x80, 0x80);
902 
903 	loadLevel(stackPos(0));
904 
905 	enableSysTimer(2);
906 
907 	script->ip = 0;
908 	return 1;
909 }
910 
olol_getNearestMonsterFromCharacter(EMCState * script)911 int LoLEngine::olol_getNearestMonsterFromCharacter(EMCState *script) {
912 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getNearestMonsterFromCharacter(%p) (%d)", (const void *)script, stackPos(0));
913 	return getNearestMonsterFromCharacter(stackPos(0));
914 }
915 
olol_dummy0(EMCState * script)916 int LoLEngine::olol_dummy0(EMCState *script) {
917 	return 0;
918 }
919 
olol_loadMonsterProperties(EMCState * script)920 int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
921 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterProperties(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
922 	       (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5),
923 	       stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPos(12), stackPos(13),
924 	       stackPos(14), stackPos(15), stackPos(16), stackPos(17), stackPos(18), stackPos(19), stackPos(20),
925 	       stackPos(21), stackPos(22), stackPos(23), stackPos(24), stackPos(25), stackPos(26), stackPos(27),
926 	       stackPos(28), stackPos(29), stackPos(30), stackPos(31), stackPos(32), stackPos(33), stackPos(34),
927 	       stackPos(35), stackPos(36), stackPos(37), stackPos(38), stackPos(39), stackPos(40), stackPos(41));
928 
929 	LoLMonsterProperty *l = &_monsterProperties[stackPos(0)];
930 	l->shapeIndex = stackPos(1) & 0xFF;
931 
932 	int shpWidthMax = 0;
933 
934 	for (int i = 0; i < 16; i++) {
935 		uint8 m = _monsterShapes[(l->shapeIndex << 4) + i][3];
936 		if (m > shpWidthMax)
937 			shpWidthMax = m;
938 	}
939 
940 	l->maxWidth = shpWidthMax;
941 
942 	l->fightingStats[0] = (stackPos(2) << 8) / 100;     // hit chance
943 	l->fightingStats[1] = 256;                          //
944 	l->fightingStats[2] = (stackPos(3) << 8) / 100;     // protection
945 	l->fightingStats[3] = stackPos(4);                  // evade chance
946 	l->fightingStats[4] = (stackPos(5) << 8) / 100;     // speed
947 	l->fightingStats[5] = (stackPos(6) << 8) / 100;     //
948 	l->fightingStats[6] = (stackPos(7) << 8) / 100;     //
949 	l->fightingStats[7] = (stackPos(8) << 8) / 100;     //
950 	l->fightingStats[8] = 0;
951 
952 	for (int i = 0; i < 8; i++) {
953 		l->itemsMight[i] = stackPos(9 + i);
954 		l->protectionAgainstItems[i] = (stackPos(17 + i) << 8) / 100;
955 	}
956 
957 	l->itemProtection = stackPos(25);
958 	l->hitPoints = stackPos(26);
959 	l->speedTotalWaitTicks = 1;
960 	l->flags = stackPos(27);
961 	// This is what the original does here (setting the value first to stackPos(28) and then to stackPos(29):
962 	//l->unk5 = stackPos(28);
963 	l->unk5 = stackPos(29);
964 
965 	l->numDistAttacks = stackPos(30);
966 	l->numDistWeapons = stackPos(31);
967 	for (int i = 0; i < 3; i++)
968 		l->distWeapons[i] = stackPos(32 + i);
969 
970 	l->attackSkillChance = stackPos(35);
971 	l->attackSkillType = stackPos(36);
972 	l->defenseSkillChance = stackPos(37);
973 	l->defenseSkillType = stackPos(38);
974 
975 	for (int i = 0; i < 3; i++)
976 		l->sounds[i] = stackPos(39 + i);
977 
978 	return 1;
979 }
980 
olol_battleHitSkillTest(EMCState * script)981 int LoLEngine::olol_battleHitSkillTest(EMCState *script) {
982 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_battleHitSkillTest(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
983 	return battleHitSkillTest(stackPos(0), stackPos(1), stackPos(2));
984 }
985 
olol_inflictDamage(EMCState * script)986 int LoLEngine::olol_inflictDamage(EMCState *script) {
987 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_inflictDamage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
988 	if (stackPos(0) == -1) {
989 		for (int i = 0; i < 4; i++)
990 			inflictDamage(i, stackPos(1), stackPos(2), stackPos(3), stackPos(4));
991 	} else {
992 		inflictDamage(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
993 	}
994 
995 	return 1;
996 }
997 
olol_moveMonster(EMCState * script)998 int LoLEngine::olol_moveMonster(EMCState *script) {
999 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveMonster(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1000 	LoLMonster *m = &_monsters[stackPos(0)];
1001 
1002 	if (m->mode == 1 || m->mode == 2) {
1003 		calcCoordinates(m->destX, m->destY, stackPos(1), stackPos(2), stackPos(3));
1004 		m->destDirection = stackPos(4) << 1;
1005 		if (m->x != m->destX || m->y != m->destY)
1006 			setMonsterDirection(m, calcMonsterDirection(m->x, m->y, m->destX, m->destY));
1007 	}
1008 
1009 	return 1;
1010 }
1011 
olol_setupDialogueButtons(EMCState * script)1012 int LoLEngine::olol_setupDialogueButtons(EMCState *script) {
1013 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupDialogueButtons(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1014 	setupDialogueButtons(stackPos(0), getLangString(stackPos(1)), getLangString(stackPos(2)), getLangString(stackPos(3)));
1015 	return 1;
1016 }
1017 
olol_giveTakeMoney(EMCState * script)1018 int LoLEngine::olol_giveTakeMoney(EMCState *script) {
1019 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_giveTakeMoney(%p) (%d)", (const void *)script, stackPos(0));
1020 	int c = stackPos(0);
1021 	if (c >= 0)
1022 		giveCredits(c, 1);
1023 	else
1024 		takeCredits(-c, 1);
1025 
1026 	return 1;
1027 }
1028 
olol_checkMoney(EMCState * script)1029 int LoLEngine::olol_checkMoney(EMCState *script) {
1030 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkMoney(%p) (%d)", (const void *)script, stackPos(0));
1031 	return (stackPos(0) > _credits) ? 0 : 1;
1032 }
1033 
olol_setScriptTimer(EMCState * script)1034 int LoLEngine::olol_setScriptTimer(EMCState *script) {
1035 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setScriptTimer(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1036 	uint8 id = 0x50 + stackPos(0);
1037 
1038 	if (stackPos(1)) {
1039 		_timer->enable(id);
1040 		_timer->setCountdown(id, stackPos(1));
1041 
1042 	} else {
1043 		_timer->disable(id);
1044 	}
1045 
1046 	return 1;
1047 }
1048 
olol_createHandItem(EMCState * script)1049 int LoLEngine::olol_createHandItem(EMCState *script) {
1050 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_createHandItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1051 	if (_itemInHand)
1052 		return 0;
1053 
1054 	setHandItem(makeItem(stackPos(0), stackPos(1), stackPos(2)));
1055 	return 1;
1056 }
1057 
olol_playAttackSound(EMCState * script)1058 int LoLEngine::olol_playAttackSound(EMCState *script) {
1059 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playAttackSound(%p) (%d)", (const void *)script, stackPos(0));
1060 
1061 	static const uint8 sounds[] = { 12, 62, 63 };
1062 	int d = stackPos(0);
1063 
1064 	if ((d < 70 || d > 74) && (d < 81 || d > 89) && (d < 93 || d > 97) && (d < 102 || d > 106))
1065 		snd_playSoundEffect(sounds[_itemProperties[d].skill & 3], -1);
1066 	else
1067 		snd_playSoundEffect(12, -1);
1068 
1069 	return 1;
1070 }
1071 
olol_addRemoveCharacter(EMCState * script)1072 int LoLEngine::olol_addRemoveCharacter(EMCState *script) {
1073 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_addRemoveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1074 
1075 	int16 id = stackPos(0);
1076 	if (id < 0) {
1077 		id = -id;
1078 		for (int i = 0; i < 4; i++) {
1079 			if (!(_characters[i].flags & 1) || _characters[i].id != id)
1080 				continue;
1081 
1082 			_characters[i].flags &= 0xFFFE;
1083 			calcCharPortraitXpos();
1084 
1085 			if (_selectedCharacter == i)
1086 				_selectedCharacter = 0;
1087 			break;
1088 		}
1089 	} else {
1090 		addCharacter(id);
1091 	}
1092 
1093 	if (!_updateFlags) {
1094 		gui_enableDefaultPlayfieldButtons();
1095 		gui_drawPlayField();
1096 	}
1097 
1098 	return 1;
1099 }
olol_giveItem(EMCState * script)1100 int LoLEngine::olol_giveItem(EMCState *script) {
1101 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_giveItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1102 	int item = makeItem(stackPos(0), stackPos(1), stackPos(2));
1103 	if (addItemToInventory(item))
1104 		return 1;
1105 
1106 	deleteItem(item);
1107 	return 0;
1108 }
1109 
olol_loadTimScript(EMCState * script)1110 int LoLEngine::olol_loadTimScript(EMCState *script) {
1111 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadTimScript(%p) (%d, %s)", (const void *)script, stackPos(0), stackPosString(1));
1112 	if (_activeTim[stackPos(0)])
1113 		return 1;
1114 	Common::String file = Common::String::format("%s.TIM", stackPosString(1));
1115 	_activeTim[stackPos(0)] = _tim->load(file.c_str(), &_timIngameOpcodes);
1116 	return 1;
1117 }
1118 
olol_runTimScript(EMCState * script)1119 int LoLEngine::olol_runTimScript(EMCState *script) {
1120 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_runTimScript(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1121 	return _tim->exec(_activeTim[stackPos(0)], stackPos(1));
1122 }
1123 
olol_releaseTimScript(EMCState * script)1124 int LoLEngine::olol_releaseTimScript(EMCState *script) {
1125 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_releaseTimScript(%p) (%d)", (const void *)script, stackPos(0));
1126 	_tim->unload(_activeTim[stackPos(0)]);
1127 	return 1;
1128 }
1129 
olol_initSceneWindowDialogue(EMCState * script)1130 int LoLEngine::olol_initSceneWindowDialogue(EMCState *script) {
1131 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_initSceneWindowDialogue(%p) (%d)", (const void *)script, stackPos(0));
1132 	initSceneWindowDialogue(stackPos(0));
1133 	return 1;
1134 }
1135 
olol_restoreAfterSceneWindowDialogue(EMCState * script)1136 int LoLEngine::olol_restoreAfterSceneWindowDialogue(EMCState *script) {
1137 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreAfterSceneWindowDialogue(%p) (%d)", (const void *)script, stackPos(0));
1138 	restoreAfterSceneWindowDialogue(stackPos(0));
1139 	return 1;
1140 }
1141 
olol_getItemInHand(EMCState * script)1142 int LoLEngine::olol_getItemInHand(EMCState *script) {
1143 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getItemInHand(%p))", (const void *)script);
1144 	return _itemInHand;
1145 }
1146 
olol_checkMagic(EMCState * script)1147 int LoLEngine::olol_checkMagic(EMCState *script) {
1148 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkMagic(%p )(%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1149 	return checkMagic(stackPos(0), stackPos(1), stackPos(2));
1150 }
1151 
olol_giveItemToMonster(EMCState * script)1152 int LoLEngine::olol_giveItemToMonster(EMCState *script) {
1153 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_giveItemToMonster(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1154 	if (stackPos(0) == -1)
1155 		return 0;
1156 	giveItemToMonster(&_monsters[stackPos(0)], stackPos(1));
1157 	return 1;
1158 }
1159 
olol_loadLangFile(EMCState * script)1160 int LoLEngine::olol_loadLangFile(EMCState *script) {
1161 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLangFile(%p) (%s)", (const void *)script, stackPosString(0));
1162 	Common::String filename = Common::String::format("%s.%s", stackPosString(0), _languageExt[_lang]);
1163 	delete[] _levelLangFile;
1164 	_levelLangFile = _res->fileData(filename.c_str(), 0);
1165 	return 1;
1166 }
1167 
olol_playSoundEffect(EMCState * script)1168 int LoLEngine::olol_playSoundEffect(EMCState *script) {
1169 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0));
1170 	snd_playSoundEffect(stackPos(0), -1);
1171 	return 1;
1172 }
1173 
olol_processDialogue(EMCState * script)1174 int LoLEngine::olol_processDialogue(EMCState *script) {
1175 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_processDialogue(%p)", (const void *)script);
1176 	return processDialogue();
1177 }
1178 
olol_stopTimScript(EMCState * script)1179 int LoLEngine::olol_stopTimScript(EMCState *script) {
1180 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopTimScript(%p) (%d)", (const void *)script, stackPos(0));
1181 	_tim->stopAllFuncs(_activeTim[stackPos(0)]);
1182 	return 1;
1183 }
1184 
olol_getWallFlags(EMCState * script)1185 int LoLEngine::olol_getWallFlags(EMCState *script) {
1186 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getWallFlags(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1187 	return _wllWallFlags[_levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3]];
1188 }
1189 
olol_changeMonsterStat(EMCState * script)1190 int LoLEngine::olol_changeMonsterStat(EMCState *script) {
1191 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_changeMonsterStat(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1192 	if (stackPos(0) == -1)
1193 		return 1;
1194 
1195 	LoLMonster *m = &_monsters[stackPos(0) & 0x7FFF];
1196 
1197 	int16 d = stackPos(2);
1198 	uint16 x = 0;
1199 	uint16 y = 0;
1200 
1201 	switch (stackPos(1)) {
1202 	case 0:
1203 		setMonsterMode(m, d);
1204 		break;
1205 
1206 	case 1:
1207 		m->hitPoints = d;
1208 		break;
1209 
1210 	case 2:
1211 		calcCoordinates(x, y, d, m->x & 0xFF, m->y & 0xFF);
1212 		if (!walkMonsterCheckDest(x, y, m, 7))
1213 			placeMonster(m, x, y);
1214 		break;
1215 
1216 	case 3:
1217 		setMonsterDirection(m, d << 1);
1218 		break;
1219 
1220 	case 6:
1221 		m->flags |= d;
1222 		break;
1223 
1224 	default:
1225 		break;
1226 	}
1227 
1228 	return 1;
1229 }
1230 
olol_getMonsterStat(EMCState * script)1231 int LoLEngine::olol_getMonsterStat(EMCState *script) {
1232 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getMonsterStat(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1233 	if (stackPos(0) == -1)
1234 		return 0;
1235 
1236 	LoLMonster *m = &_monsters[stackPos(0) & 0x7FFF];
1237 	int d = stackPos(1);
1238 
1239 	switch (d) {
1240 	case 0:
1241 		return m->mode;
1242 	case 1:
1243 		return m->hitPoints;
1244 	case 2:
1245 		return m->block;
1246 	case 3:
1247 		return m->facing;
1248 	case 4:
1249 		return m->type;
1250 	case 5:
1251 		return m->properties->hitPoints;
1252 	case 6:
1253 		return m->flags;
1254 	case 7:
1255 		return m->properties->flags;
1256 	case 8:
1257 		return _monsterAnimType[m->properties->shapeIndex];
1258 	default:
1259 		break;
1260 	}
1261 
1262 	return 0;
1263 }
1264 
olol_releaseMonsterShapes(EMCState * script)1265 int LoLEngine::olol_releaseMonsterShapes(EMCState *script) {
1266 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_releaseMonsterShapes(%p)", (const void *)script);
1267 	for (int i = 0; i < 3; i++)
1268 		releaseMonsterShapes(i);
1269 	return 0;
1270 }
1271 
olol_playCharacterScriptChat(EMCState * script)1272 int LoLEngine::olol_playCharacterScriptChat(EMCState *script) {
1273 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playCharacterScriptChat(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1274 	if (_flags.isTalkie) {
1275 		snd_stopSpeech(1);
1276 		stopPortraitSpeechAnim();
1277 	}
1278 	return playCharacterScriptChat(stackPos(0), stackPos(1), 1, getLangString(stackPos(2)), script, 0, 3);
1279 }
1280 
olol_playEnvironmentalSfx(EMCState * script)1281 int LoLEngine::olol_playEnvironmentalSfx(EMCState *script) {
1282 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playEnvironmentalSfx(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1283 	uint16 block = (stackPos(1) == -1) ? _currentBlock : stackPos(1);
1284 	snd_processEnvironmentalSoundEffect(stackPos(0), block);
1285 	return 1;
1286 }
1287 
olol_update(EMCState * script)1288 int LoLEngine::olol_update(EMCState *script) {
1289 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_update(%p)", (const void *)script);
1290 	update();
1291 	return 1;
1292 }
1293 
olol_healCharacter(EMCState * script)1294 int LoLEngine::olol_healCharacter(EMCState *script) {
1295 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_healCharacter(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1296 	if (stackPos(3)) {
1297 		processMagicHeal(stackPos(0), stackPos(1));
1298 	} else {
1299 		increaseCharacterHitpoints(stackPos(0), stackPos(1), true);
1300 		if (stackPos(2))
1301 			gui_drawCharPortraitWithStats(stackPos(0));
1302 	}
1303 	return 1;
1304 }
1305 
olol_drawExitButton(EMCState * script)1306 int LoLEngine::olol_drawExitButton(EMCState *script) {
1307 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_drawExitButton(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1308 
1309 	static const uint8 printPara[] = { 0x90, 0x78, 0x0C, 0x9F, 0x80, 0x1E };
1310 
1311 	int cp = _screen->setCurPage(0);
1312 	Screen::FontId cf = _screen->setFont(Screen::FID_6_FNT);
1313 	int x = printPara[3 * stackPos(0)] << 1;
1314 	int y = printPara[3 * stackPos(0) + 1];
1315 	int offs = printPara[3 * stackPos(0) + 2];
1316 
1317 	char *str = getLangString(0x4033);
1318 	int w = _screen->getTextWidth(str);
1319 
1320 	if (_flags.use16ColorMode) {
1321 		gui_drawBox(x - offs - w, y - 9, w + offs, 9, 0xEE, 0xCC, 0x11);
1322 		_screen->printText(str, x - (offs >> 1) - w, y - 7, 0xBB, 0);
1323 	} else {
1324 		gui_drawBox(x - offs - w, y - 9, w + offs, 9, 136, 251, 252);
1325 		_screen->printText(str, x - (offs >> 1) - w, y - 7, 144, 0);
1326 	}
1327 
1328 	if (stackPos(1))
1329 		_screen->drawGridBox(x - offs - w + 1, y - 8, w + offs - 2, 7, 1);
1330 
1331 	_screen->setFont(cf);
1332 	_screen->setCurPage(cp);
1333 	return 1;
1334 }
1335 
olol_loadSoundFile(EMCState * script)1336 int LoLEngine::olol_loadSoundFile(EMCState *script) {
1337 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0));
1338 	snd_loadSoundFile(stackPos(0));
1339 	return 1;
1340 }
1341 
olol_playMusicTrack(EMCState * script)1342 int LoLEngine::olol_playMusicTrack(EMCState *script) {
1343 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playMusicTrack(%p) (%d)", (const void *)script, stackPos(0));
1344 	return snd_playTrack(stackPos(0));
1345 }
1346 
olol_deleteMonstersFromBlock(EMCState * script)1347 int LoLEngine::olol_deleteMonstersFromBlock(EMCState *script) {
1348 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_deleteMonstersFromBlock(%p) (%d)", (const void *)script, stackPos(0));
1349 	deleteMonstersFromBlock(stackPos(0));
1350 	return 1;
1351 }
1352 
olol_countBlockItems(EMCState * script)1353 int LoLEngine::olol_countBlockItems(EMCState *script) {
1354 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countBlockItems(%p) (%d)", (const void *)script, stackPos(0));
1355 	uint16 o = _levelBlockProperties[stackPos(0)].assignedObjects;
1356 	int res = 0;
1357 
1358 	while (o) {
1359 		if (!(o & 0x8000))
1360 			res++;
1361 		o = findObject(o)->nextAssignedObject;
1362 	}
1363 
1364 	return res;
1365 }
1366 
olol_characterSkillTest(EMCState * script)1367 int LoLEngine::olol_characterSkillTest(EMCState *script) {
1368 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterSkillTest(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1369 	int skill = stackPos(0);
1370 	int n = countActiveCharacters();
1371 	int m = 0;
1372 	int c = 0;
1373 
1374 	for (int i = 0; i < n; i++) {
1375 		int v = _characters[i].skillModifiers[skill] + _characters[i].skillLevels[skill] + 25;
1376 		if (v > m) {
1377 			m = v;
1378 			c = i;
1379 		}
1380 	}
1381 
1382 	return (rollDice(1, 100) > m) ? -1 : c;
1383 }
1384 
olol_countAllMonsters(EMCState * script)1385 int LoLEngine::olol_countAllMonsters(EMCState *script) {
1386 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countAllMonsters(%p)", (const void *)script);
1387 	int res = 0;
1388 
1389 	for (int i = 0; i < 30; i++) {
1390 		if (_monsters[i].hitPoints > 0 && _monsters[i].mode != 13)
1391 			res++;
1392 	}
1393 
1394 	return res;
1395 }
1396 
olol_playEndSequence(EMCState * script)1397 int LoLEngine::olol_playEndSequence(EMCState *script) {
1398 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playEndSequence(%p)", (const void *)script);
1399 
1400 	int c = 0;
1401 	if (_characters[0].id == -9)
1402 		c = 1;
1403 	else if (_characters[0].id == -5)
1404 		c = 3;
1405 	else if (_characters[0].id == -1)
1406 		c = 2;
1407 
1408 	while (snd_updateCharacterSpeech())
1409 		delay(_tickLength);
1410 
1411 	_eventList.clear();
1412 	_screen->hideMouse();
1413 	_screen->getPalette(1).clear();
1414 
1415 	showOutro(c, (_monsterDifficulty == 2));
1416 	// Don't call quitGame() on a RTL request (because this would
1417 	// make the next game launched from the launcher quit instantly.
1418 	if (!shouldQuit())
1419 		quitGame();
1420 
1421 	return 0;
1422 }
1423 
olol_stopPortraitSpeechAnim(EMCState * script)1424 int LoLEngine::olol_stopPortraitSpeechAnim(EMCState *script) {
1425 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopPortraitSpeechAnim(%p)", (const void *)script);
1426 	if (_flags.isTalkie)
1427 		snd_stopSpeech(1);
1428 	stopPortraitSpeechAnim();
1429 	return 1;
1430 }
1431 
olol_setPaletteBrightness(EMCState * script)1432 int LoLEngine::olol_setPaletteBrightness(EMCState *script) {
1433 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setPaletteBrightness(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1434 	uint16 old = _brightness;
1435 	_brightness = stackPos(0);
1436 	if (stackPos(1) == 1)
1437 		setPaletteBrightness(_screen->getPalette(0), stackPos(0), _lampEffect);
1438 	return old;
1439 }
1440 
olol_calcInflictableDamage(EMCState * script)1441 int LoLEngine::olol_calcInflictableDamage(EMCState *script) {
1442 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_calcInflictableDamage(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1443 	return calcInflictableDamage(stackPos(0), stackPos(1), stackPos(2));
1444 }
1445 
olol_getInflictedDamage(EMCState * script)1446 int LoLEngine::olol_getInflictedDamage(EMCState *script) {
1447 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getInflictedDamage(%p) (%d)", (const void *)script, stackPos(0));
1448 	int mx = stackPos(0);
1449 	return rollDice(2, mx);
1450 }
1451 
olol_checkForCertainPartyMember(EMCState * script)1452 int LoLEngine::olol_checkForCertainPartyMember(EMCState *script) {
1453 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkForCertainPartyMember(%p) (%d)", (const void *)script, stackPos(0));
1454 	for (int i = 0; i < 4; i++) {
1455 		if (_characters[i].flags & 9 && _characters[i].id == stackPos(0))
1456 			return 1;
1457 	}
1458 	return 0;
1459 }
1460 
olol_printMessage(EMCState * script)1461 int LoLEngine::olol_printMessage(EMCState *script) {
1462 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_printMessage(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
1463 	int snd = stackPos(2);
1464 	_txt->printMessage(stackPos(0), getLangString(stackPos(1)), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
1465 
1466 	if (snd >= 0)
1467 		snd_playSoundEffect(snd, -1);
1468 
1469 	return 1;
1470 }
1471 
olol_deleteLevelItem(EMCState * script)1472 int LoLEngine::olol_deleteLevelItem(EMCState *script) {
1473 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_deleteLevelItem(%p) (%d)", (const void *)script, stackPos(0));
1474 	if (_itemsInPlay[stackPos(0)].block)
1475 		removeLevelItem(stackPos(0), _itemsInPlay[stackPos(0)].block);
1476 
1477 	deleteItem(stackPos(0));
1478 
1479 	return 1;
1480 }
1481 
olol_calcInflictableDamagePerItem(EMCState * script)1482 int LoLEngine::olol_calcInflictableDamagePerItem(EMCState *script) {
1483 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_calcInflictableDamagePerItem(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1484 	return calcInflictableDamagePerItem(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1485 }
1486 
olol_distanceAttack(EMCState * script)1487 int LoLEngine::olol_distanceAttack(EMCState *script) {
1488 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_distanceAttack(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8));
1489 
1490 	uint16 fX = stackPos(3);
1491 	uint16 fY = stackPos(4);
1492 
1493 	if (!(stackPos(8) & 0x8000))
1494 		fX = fY = 0x80;
1495 
1496 	uint16 x = 0;
1497 	uint16 y = 0;
1498 	calcCoordinates(x, y, stackPos(2), fX, fY);
1499 
1500 	if (launchObject(stackPos(0), stackPos(1), x, y, stackPos(5), stackPos(6) << 1, stackPos(7), stackPos(8), 0x3F))
1501 		return 1;
1502 
1503 	deleteItem(stackPos(1));
1504 	return 0;
1505 }
1506 
olol_removeCharacterEffects(EMCState * script)1507 int LoLEngine::olol_removeCharacterEffects(EMCState *script) {
1508 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_removeCharacterEffects(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1509 	removeCharacterEffects(&_characters[stackPos(0)], stackPos(1), stackPos(2));
1510 	return 1;
1511 }
1512 
olol_checkInventoryFull(EMCState * script)1513 int LoLEngine::olol_checkInventoryFull(EMCState *script) {
1514 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkInventoryFull(%p)", (const void *)script);
1515 	for (int i = 0; i < 48; i++) {
1516 		if (_inventory[i])
1517 			return 0;
1518 	}
1519 	return 1;
1520 }
1521 
olol_moveBlockObjects(EMCState * script)1522 int LoLEngine::olol_moveBlockObjects(EMCState *script) {
1523 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveBlockObjects(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
1524 	int o = _levelBlockProperties[stackPos(0)].assignedObjects;
1525 	int res = 0;
1526 	int level = stackPos(2);
1527 	int destBlock = stackPos(1);
1528 	int runScript = stackPos(4);
1529 	int includeMonsters = stackPos(3);
1530 	int includeItems = stackPos(5);
1531 
1532 	// WORKAROUND for script bug
1533 	// Items would vanish when thrown towards the stairs
1534 	// in white tower level 3.
1535 	if (_currentLevel == 21 && level == 21 && destBlock == 0x3E0) {
1536 		level = 20;
1537 		destBlock = 0x0247;
1538 	}
1539 
1540 	while (o) {
1541 		int l = o;
1542 		o = findObject(o)->nextAssignedObject;
1543 		if (l & 0x8000) {
1544 			if (!includeMonsters)
1545 				continue;
1546 
1547 			l &= 0x7FFF;
1548 
1549 			LoLMonster *m = &_monsters[l];
1550 
1551 			setMonsterMode(m, 14);
1552 			checkSceneUpdateNeed(m->block);
1553 			placeMonster(m, 0, 0);
1554 
1555 			res = 1;
1556 
1557 		} else {
1558 			if (!(_itemsInPlay[l].shpCurFrame_flg & 0x4000) || !includeItems)
1559 				continue;
1560 
1561 			placeMoveLevelItem(l, level, destBlock, _itemsInPlay[l].x & 0xFF, _itemsInPlay[l].y & 0xFF, _itemsInPlay[l].flyingHeight);
1562 			res = 1;
1563 
1564 			if (!runScript || level != _currentLevel)
1565 				continue;
1566 
1567 			runLevelScriptCustom(destBlock, 0x80, -1, l, 0, 0);
1568 		}
1569 	}
1570 
1571 	return res;
1572 }
1573 
olol_addSpellToScroll(EMCState * script)1574 int LoLEngine::olol_addSpellToScroll(EMCState *script) {
1575 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_addSpellToScroll(%p) (%d)", (const void *)script, stackPos(0));
1576 	addSpellToScroll(stackPos(0), stackPos(1));
1577 	return 1;
1578 }
1579 
olol_playDialogueText(EMCState * script)1580 int LoLEngine::olol_playDialogueText(EMCState *script) {
1581 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playDialogueText(%p) (%d)", (const void *)script, stackPos(0));
1582 	_txt->printDialogueText(3, getLangString(stackPos(0)), script, 0, 1);
1583 	return 1;
1584 }
1585 
olol_playDialogueTalkText(EMCState * script)1586 int LoLEngine::olol_playDialogueTalkText(EMCState *script) {
1587 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playDialogueTalkText(%p) (%d)", (const void *)script, stackPos(0));
1588 	int track = stackPos(0);
1589 
1590 	if (!snd_playCharacterSpeech(track, 0, 0) || textEnabled()) {
1591 		char *s = getLangString(track);
1592 		_txt->printDialogueText(4, s, script, 0, 1);
1593 	}
1594 
1595 	return 1;
1596 }
1597 
olol_checkMonsterTypeHostility(EMCState * script)1598 int LoLEngine::olol_checkMonsterTypeHostility(EMCState *script) {
1599 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkMonsterTypeHostility(%p) (%d)", (const void *)script, stackPos(0));
1600 	for (int i = 0; i < 30; i++) {
1601 		if (stackPos(0) != _monsters[i].type && stackPos(0) != -1)
1602 			continue;
1603 		return (_monsters[i].mode == 1) ? 0 : 1;
1604 	}
1605 	return 1;
1606 }
1607 
olol_setNextFunc(EMCState * script)1608 int LoLEngine::olol_setNextFunc(EMCState *script) {
1609 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setNextFunc(%p) (%d)", (const void *)script, stackPos(0));
1610 	_nextScriptFunc = stackPos(0);
1611 	return 1;
1612 }
1613 
olol_dummy1(EMCState * script)1614 int LoLEngine::olol_dummy1(EMCState *script) {
1615 	return 1;
1616 }
1617 
olol_suspendMonster(EMCState * script)1618 int LoLEngine::olol_suspendMonster(EMCState *script) {
1619 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_suspendMonster(%p) (%d)", (const void *)script, stackPos(0));
1620 	LoLMonster *m = &_monsters[stackPos(0) & 0x7FFF];
1621 	setMonsterMode(m, 14);
1622 	checkSceneUpdateNeed(m->block);
1623 	placeMonster(m, 0, 0);
1624 	return 1;
1625 }
1626 
olol_setScriptTextParameter(EMCState * script)1627 int LoLEngine::olol_setScriptTextParameter(EMCState *script) {
1628 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setScriptTextParameter(%p) (%d)", (const void *)script, stackPos(0));
1629 	_txt->_scriptTextParameter = stackPos(0);
1630 	return 1;
1631 }
1632 
olol_triggerEventOnMouseButtonClick(EMCState * script)1633 int LoLEngine::olol_triggerEventOnMouseButtonClick(EMCState *script) {
1634 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_triggerEventOnMouseButtonClick(%p) (%d)", (const void *)script, stackPos(0));
1635 	gui_notifyButtonListChanged();
1636 	snd_updateCharacterSpeech();
1637 
1638 	int f = checkInput(0);
1639 	removeInputTop();
1640 	if (f == 0 || (f & 0x800))
1641 		return 0;
1642 
1643 	int evt = stackPos(0);
1644 	if (evt) {
1645 		gui_triggerEvent(evt);
1646 		_seqTrigger = 1;
1647 	} else {
1648 		removeInputTop();
1649 	}
1650 
1651 	return 1;
1652 }
1653 
olol_printWindowText(EMCState * script)1654 int LoLEngine::olol_printWindowText(EMCState *script) {
1655 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_printWindowText(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1656 	int dim = stackPos(0);
1657 	int flg = stackPos(1);
1658 	_screen->setScreenDim(dim);
1659 	if (flg & 1)
1660 		_txt->clearCurDim();
1661 	if (flg & 3)
1662 		_txt->resetDimTextPositions(dim);
1663 	_txt->printDialogueText(dim, getLangString(stackPos(2)), script, 0, 3);
1664 	return 1;
1665 }
1666 
olol_countSpecificMonsters(EMCState * script)1667 int LoLEngine::olol_countSpecificMonsters(EMCState *script) {
1668 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countSpecificMonsters(%p) (%d, ...)", (const void *)script, stackPos(0));
1669 	uint16 types = 0;
1670 	int res = 0;
1671 	int cnt = 0;
1672 
1673 	while (stackPos(cnt) != -1)
1674 		types |= (1 << stackPos(cnt++));
1675 
1676 	for (int i = 0; i < 30; i++) {
1677 		if (((1 << _monsters[i].type) & types) && _monsters[i].mode < 14)
1678 			res++;
1679 	}
1680 
1681 	return res;
1682 }
1683 
olol_updateBlockAnimations2(EMCState * script)1684 int LoLEngine::olol_updateBlockAnimations2(EMCState *script) {
1685 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_updateBlockAnimations2(%p) (%d, %d, %d, %d, ...)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1686 	int numFrames = stackPos(3);
1687 	assert(numFrames <= 97);
1688 	int curFrame = stackPos(2) % numFrames;
1689 	setWallType(stackPos(0), stackPos(1), stackPos(4 + curFrame));
1690 	return 0;
1691 }
1692 
olol_checkPartyForItemType(EMCState * script)1693 int LoLEngine::olol_checkPartyForItemType(EMCState *script) {
1694 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkPartyForItemType(%p) (%d, %d, %d))", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1695 	int p = stackPos(1);
1696 
1697 	if (!stackPos(2)) {
1698 		for (int i = 0; i < 48; i++) {
1699 			if (!_inventory[i] || _itemsInPlay[_inventory[i]].itemPropertyIndex != p)
1700 				continue;
1701 			return 1;
1702 		}
1703 
1704 		if (_itemsInPlay[_itemInHand].itemPropertyIndex == p)
1705 			return 1;
1706 	}
1707 
1708 	int last = (stackPos(0) == -1) ? 3 : stackPos(0);
1709 	int first = (stackPos(0) == -1) ? 0 : stackPos(0);
1710 
1711 	for (int i = first; i <= last; i++) {
1712 		if (itemEquipped(i, p))
1713 			return 1;
1714 	}
1715 
1716 	return 0;
1717 }
1718 
olol_blockDoor(EMCState * script)1719 int LoLEngine::olol_blockDoor(EMCState *script) {
1720 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_blockDoor(%p) (%d)", (const void *)script, stackPos(0));
1721 	_blockDoor = stackPos(0);
1722 	return _blockDoor;
1723 }
1724 
olol_resetTimDialogueState(EMCState * script)1725 int LoLEngine::olol_resetTimDialogueState(EMCState *script) {
1726 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_resetTimDialogueState(%p) (%d)", (const void *)script, stackPos(0));
1727 	_tim->resetDialogueState(_activeTim[stackPos(0)]);
1728 	return 1;
1729 }
1730 
olol_getItemOnPos(EMCState * script)1731 int LoLEngine::olol_getItemOnPos(EMCState *script) {
1732 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getItemOnPos(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1733 	int pX = stackPos(1);
1734 	if (pX != -1)
1735 		pX &= 0xFF;
1736 
1737 	int pY = stackPos(2);
1738 	if (pY != -1)
1739 		pY &= 0xFF;
1740 
1741 	int o = (stackPos(3) || _emcLastItem == -1) ? stackPos(0) : _emcLastItem;
1742 
1743 	_emcLastItem = _levelBlockProperties[o].assignedObjects;
1744 
1745 	while (_emcLastItem) {
1746 		if (_emcLastItem & 0x8000) {
1747 			o = _emcLastItem & 0x7FFF;
1748 			_emcLastItem = _levelBlockProperties[o].assignedObjects;
1749 			continue;
1750 		}
1751 
1752 		if (pX != -1 && (_itemsInPlay[_emcLastItem].x & 0xFF) != pX) {
1753 			o = _emcLastItem & 0x7FFF;
1754 			_emcLastItem = _levelBlockProperties[o].assignedObjects;
1755 			continue;
1756 		}
1757 
1758 		if (pY != -1 && (_itemsInPlay[_emcLastItem].y & 0xFF) != pY) {
1759 			o = _emcLastItem & 0x7FFF;
1760 			_emcLastItem = _levelBlockProperties[o].assignedObjects;
1761 			continue;
1762 		}
1763 
1764 		return _emcLastItem;
1765 	}
1766 
1767 	return 0;
1768 }
1769 
olol_removeLevelItem(EMCState * script)1770 int LoLEngine::olol_removeLevelItem(EMCState *script) {
1771 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_removeLevelItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1772 	removeLevelItem(stackPos(0), stackPos(1));
1773 	return 1;
1774 }
1775 
olol_savePage5(EMCState * script)1776 int LoLEngine::olol_savePage5(EMCState *script) {
1777 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_savePage5(%p)", (const void *)script);
1778 	// Not implemented: The original code uses this to back up and restore page 5 which is used
1779 	// to load WSA files. Since our WSA player provides its own memory buffers we don't
1780 	// need to use page 5.
1781 	return 1;
1782 }
1783 
olol_restorePage5(EMCState * script)1784 int LoLEngine::olol_restorePage5(EMCState *script) {
1785 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restorePage5(%p)", (const void *)script);
1786 	// Not implemented: The original code uses this to back up and restore page 5 which is used
1787 	// to load WSA files. Since our WSA player provides its own memory buffers we don't
1788 	// need to use page 5.
1789 	for (int i = 0; i < 6; i++)
1790 		_tim->freeAnimStruct(i);
1791 	return 1;
1792 }
1793 
olol_initDialogueSequence(EMCState * script)1794 int LoLEngine::olol_initDialogueSequence(EMCState *script) {
1795 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_initDialogueSequence(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1796 	initDialogueSequence(stackPos(0), stackPos(1));
1797 	return 1;
1798 }
1799 
olol_restoreAfterDialogueSequence(EMCState * script)1800 int LoLEngine::olol_restoreAfterDialogueSequence(EMCState *script) {
1801 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreAfterDialogueSequence(%p) (%d)", (const void *)script, stackPos(0));
1802 	restoreAfterDialogueSequence(stackPos(0));
1803 	return 1;
1804 }
1805 
olol_setSpecialSceneButtons(EMCState * script)1806 int LoLEngine::olol_setSpecialSceneButtons(EMCState *script) {
1807 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setSpecialSceneButtons(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1808 	setSpecialSceneButtons(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1809 	return 1;
1810 }
1811 
olol_restoreButtonsAfterSpecialScene(EMCState * script)1812 int LoLEngine::olol_restoreButtonsAfterSpecialScene(EMCState *script) {
1813 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreButtonsAfterSpecialScene(%p)", (const void *)script);
1814 	gui_specialSceneRestoreButtons();
1815 	return 1;
1816 }
1817 
olol_prepareSpecialScene(EMCState * script)1818 int LoLEngine::olol_prepareSpecialScene(EMCState *script) {
1819 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_prepareSpecialScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
1820 	prepareSpecialScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
1821 	return 1;
1822 }
1823 
olol_restoreAfterSpecialScene(EMCState * script)1824 int LoLEngine::olol_restoreAfterSpecialScene(EMCState *script) {
1825 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreAfterSpecialScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1826 	return restoreAfterSpecialScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1827 }
1828 
olol_assignCustomSfx(EMCState * script)1829 int LoLEngine::olol_assignCustomSfx(EMCState *script) {
1830 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignCustomSfx(%p) (%s, %d)", (const void *)script, stackPosString(0), stackPos(1));
1831 	const char *c = stackPosString(0);
1832 	int i = stackPos(1);
1833 
1834 	if (!c || i > 250)
1835 		return 0;
1836 
1837 	uint16 t = READ_LE_UINT16(&_ingameSoundIndex[i << 1]);
1838 	if (t == 0xFFFF)
1839 		return 0;
1840 
1841 	strcpy(_ingameSoundList[t], c);
1842 
1843 	return 0;
1844 }
1845 
olol_findAssignedMonster(EMCState * script)1846 int LoLEngine::olol_findAssignedMonster(EMCState *script) {
1847 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_findAssignedMonster(%p)  (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1848 	uint16 o = stackPos(1) == -1 ? _levelBlockProperties[stackPos(0)].assignedObjects : findObject(stackPos(1))->nextAssignedObject;
1849 	while (o) {
1850 		if (o & 0x8000)
1851 			return o & 0x7FFF;
1852 		o = findObject(o)->nextAssignedObject;
1853 	}
1854 	return -1;
1855 }
1856 
olol_checkBlockForMonster(EMCState * script)1857 int LoLEngine::olol_checkBlockForMonster(EMCState *script) {
1858 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkBlockForMonster(%p)  (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
1859 	uint16 block = stackPos(0);
1860 	uint16 id = stackPos(1) | 0x8000;
1861 
1862 	uint16 o = _levelBlockProperties[block].assignedObjects;
1863 	while (o & 0x8000) {
1864 		if (id == 0xFFFF || id == o)
1865 			return o & 0x7FFF;
1866 		o = findObject(o)->nextAssignedObject;
1867 	}
1868 	return -1;
1869 }
1870 
olol_crossFadeRegion(EMCState * script)1871 int LoLEngine::olol_crossFadeRegion(EMCState *script) {
1872 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_crossFadeRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
1873 	_screen->crossFadeRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
1874 	return 1;
1875 }
1876 
olol_calcCoordinatesAddDirectionOffset(EMCState * script)1877 int LoLEngine::olol_calcCoordinatesAddDirectionOffset(EMCState *script) {
1878 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_calcCoordinatesAddDirectionOffset(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
1879 	uint16 x = stackPos(0);
1880 	uint16 y = stackPos(1);
1881 	calcCoordinatesAddDirectionOffset(x, y, stackPos(2));
1882 	return stackPos(3) ? x : y;
1883 }
1884 
olol_resetPortraitsAndDisableSysTimer(EMCState * script)1885 int LoLEngine::olol_resetPortraitsAndDisableSysTimer(EMCState *script) {
1886 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_resetPortraitsAndDisableSysTimer(%p)", (const void *)script);
1887 	resetPortraitsAndDisableSysTimer();
1888 	return 1;
1889 }
1890 
olol_enableSysTimer(EMCState * script)1891 int LoLEngine::olol_enableSysTimer(EMCState *script) {
1892 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_enableSysTimer(%p)", (const void *)script);
1893 	_needSceneRestore = 0;
1894 	enableSysTimer(2);
1895 	return 1;
1896 }
1897 
olol_checkNeedSceneRestore(EMCState * script)1898 int LoLEngine::olol_checkNeedSceneRestore(EMCState *script) {
1899 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkNeedSceneRestore(%p)", (const void *)script);
1900 	return _needSceneRestore;
1901 }
1902 
olol_getNextActiveCharacter(EMCState * script)1903 int LoLEngine::olol_getNextActiveCharacter(EMCState *script) {
1904 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getNextActiveCharacter(%p)  (%d)", (const void *)script, stackPos(0));
1905 	if (stackPos(0))
1906 		_scriptCharacterCycle = 0;
1907 	else
1908 		_scriptCharacterCycle++;
1909 
1910 	while (_scriptCharacterCycle < 4) {
1911 		if (_characters[_scriptCharacterCycle].flags & 1)
1912 			return _scriptCharacterCycle;
1913 		_scriptCharacterCycle++;
1914 	}
1915 	return -1;
1916 }
1917 
olol_paralyzePoisonCharacter(EMCState * script)1918 int LoLEngine::olol_paralyzePoisonCharacter(EMCState *script) {
1919 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_paralyzePoisonCharacter(%p)  (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1920 	return paralyzePoisonCharacter(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1921 }
1922 
olol_drawCharPortrait(EMCState * script)1923 int LoLEngine::olol_drawCharPortrait(EMCState *script) {
1924 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_drawCharPortrait(%p) (%d)", (const void *)script, stackPos(0));
1925 	int charNum = stackPos(0);
1926 	if (charNum == -1)
1927 		gui_drawAllCharPortraitsWithStats();
1928 	else
1929 		gui_drawCharPortraitWithStats(charNum);
1930 	return 1;
1931 }
1932 
olol_removeInventoryItem(EMCState * script)1933 int LoLEngine::olol_removeInventoryItem(EMCState *script) {
1934 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_removeInventoryItem(%p) (%d)", (const void *)script, stackPos(0));
1935 	int itemType = stackPos(0);
1936 	for (int i = 0; i < 48; i++) {
1937 		if (!_inventory[i] || _itemsInPlay[_inventory[i]].itemPropertyIndex != itemType)
1938 			continue;
1939 		_inventory[i] = 0;
1940 		gui_drawInventory();
1941 		return 1;
1942 	}
1943 
1944 	for (int i = 0; i < 4; i++) {
1945 		if (!(_characters[i].flags & 1))
1946 			continue;
1947 
1948 		for (int ii = 0; ii < 11; ii++) {
1949 			if (!_characters[i].items[ii] || _itemsInPlay[_characters[i].items[ii]].itemPropertyIndex != itemType)
1950 				continue;
1951 			_characters[i].items[ii] = 0;
1952 			return 1;
1953 		}
1954 	}
1955 	return 0;
1956 }
1957 
olol_getAnimationLastPart(EMCState * script)1958 int LoLEngine::olol_getAnimationLastPart(EMCState *script) {
1959 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getAnimationLastPart(%p) (%d)", (const void *)script, stackPos(0));
1960 	return _tim->animator()->resetLastPart(stackPos(0));
1961 }
1962 
olol_assignSpecialGuiShape(EMCState * script)1963 int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) {
1964 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignSpecialGuiShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
1965 	if (stackPos(0)) {
1966 		_specialGuiShape = _levelDecorationShapes[_levelDecorationProperties[_wllShapeMap[stackPos(0)]].shapeIndex[stackPos(1)]];
1967 		_specialGuiShapeX = stackPos(2);
1968 		_specialGuiShapeY = stackPos(3);
1969 		_specialGuiShapeMirrorFlag = stackPos(4);
1970 
1971 	} else {
1972 		_specialGuiShape = 0;
1973 		_specialGuiShapeX = _specialGuiShapeY = _specialGuiShapeMirrorFlag = 0;
1974 	}
1975 	return 1;
1976 }
1977 
olol_findInventoryItem(EMCState * script)1978 int LoLEngine::olol_findInventoryItem(EMCState *script) {
1979 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_findInventoryItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
1980 	if (stackPos(0) == 0) {
1981 		for (int i = 0; i < 48; i++) {
1982 			if (!_inventory[i])
1983 				continue;
1984 			if (_itemsInPlay[_inventory[i]].itemPropertyIndex == stackPos(2))
1985 				return 0;
1986 		}
1987 	}
1988 	int cur = stackPos(1);
1989 	int last = cur;
1990 	if (stackPos(1) == -1) {
1991 		cur = 0;
1992 		last = 4;
1993 	}
1994 	for (; cur < last; cur++) {
1995 		if (!(_characters[cur].flags & 1))
1996 			continue;
1997 		for (int i = 0; i < 11; i++) {
1998 			if (!_characters[cur].items[i])
1999 				continue;
2000 			if (_itemsInPlay[_characters[cur].items[i]].itemPropertyIndex == stackPos(2))
2001 				return cur;
2002 		}
2003 	}
2004 	return -1;
2005 }
2006 
olol_restoreFadePalette(EMCState * script)2007 int LoLEngine::olol_restoreFadePalette(EMCState *script) {
2008 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreFadePalette(%p)", (const void *)script);
2009 	_screen->getPalette(0).copy(_screen->getPalette(1), 0, _flags.use16ColorMode ? 16 : 128);
2010 	_screen->fadePalette(_screen->getPalette(0), 10);
2011 	_screen->_fadeFlag = 0;
2012 	return 1;
2013 }
2014 
olol_getSelectedCharacter(EMCState * script)2015 int LoLEngine::olol_getSelectedCharacter(EMCState *script) {
2016 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getSelectedCharacter(%p)", (const void *)script);
2017 	return _selectedCharacter;
2018 }
2019 
olol_setHandItem(EMCState * script)2020 int LoLEngine::olol_setHandItem(EMCState *script) {
2021 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setHandItem(%p) (%d)", (const void *)script, stackPos(0));
2022 	setHandItem(stackPos(0));
2023 	return 1;
2024 }
2025 
olol_drinkBezelCup(EMCState * script)2026 int LoLEngine::olol_drinkBezelCup(EMCState *script) {
2027 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_drinkBezelCup(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
2028 	drinkBezelCup(3 - stackPos(0), stackPos(1));
2029 	return 1;
2030 }
2031 
olol_changeItemTypeOrFlag(EMCState * script)2032 int LoLEngine::olol_changeItemTypeOrFlag(EMCState *script) {
2033 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_changeItemTypeOrFlag(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
2034 	if (stackPos(0) < 1)
2035 		return 0;
2036 
2037 	LoLItem *i = &_itemsInPlay[stackPos(0)];
2038 	int16 val = stackPos(2);
2039 
2040 	if (stackPos(1) == 4)
2041 		i->itemPropertyIndex = val;
2042 	else if (stackPos(1) == 15)
2043 		i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xE000) | (val & 0x1FFF);
2044 	else
2045 		val = -1;
2046 
2047 	return val;
2048 }
2049 
olol_placeInventoryItemInHand(EMCState * script)2050 int LoLEngine::olol_placeInventoryItemInHand(EMCState *script) {
2051 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeInventoryItemInHand(%p)  (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
2052 	int itemType = stackPos(0);
2053 	int i = 0;
2054 	for (; i < 48; i++) {
2055 		if (!_inventory[i])
2056 			continue;
2057 		if (_itemsInPlay[_inventory[i]].itemPropertyIndex == itemType)
2058 			break;
2059 	}
2060 
2061 	if (i == 48)
2062 		return -1;
2063 
2064 	_inventoryCurItem = i;
2065 	int r = _itemInHand;
2066 	setHandItem(_inventory[i]);
2067 	_inventory[i] = r;
2068 
2069 	if (stackPos(1))
2070 		gui_drawInventory();
2071 
2072 	return r;
2073 }
2074 
olol_castSpell(EMCState * script)2075 int LoLEngine::olol_castSpell(EMCState *script) {
2076 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_castSpell(%p)  (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
2077 	return castSpell(stackPos(0), stackPos(1), stackPos(2));
2078 }
2079 
olol_pitDrop(EMCState * script)2080 int LoLEngine::olol_pitDrop(EMCState *script) {
2081 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_pitDrop(%p)  (%d)", (const void *)script, stackPos(0));
2082 	int m = stackPos(0);
2083 	_screen->updateScreen();
2084 	if (m) {
2085 		gui_drawScene(2);
2086 		pitDropScroll(9);
2087 		snd_playSoundEffect(-1, -1);
2088 		shakeScene(30, 4, 0, 1);
2089 
2090 	} else {
2091 		int t = -1;
2092 		for (int i = 0; i < 4; i++) {
2093 			if (!(_characters[i].flags & 1) || (_characters[i].id >= 0))
2094 				continue;
2095 			if (_characters[i].id == -1)
2096 				t = 54;
2097 			else if (_characters[i].id == -5)
2098 				t = 53;
2099 			else if (_characters[i].id == -8)
2100 				t = 52;
2101 			else if (_characters[i].id == -9)
2102 				t = 51;
2103 		}
2104 
2105 		_screen->fillRect(112, 0, 288, 120, 0, 2);
2106 		snd_playSoundEffect(t, -1);
2107 		pitDropScroll(12);
2108 	}
2109 
2110 	return 1;
2111 }
2112 
olol_increaseSkill(EMCState * script)2113 int LoLEngine::olol_increaseSkill(EMCState *script) {
2114 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_increaseSkill(%p)  (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
2115 	LoLCharacter *c = &_characters[stackPos(0)];
2116 	int s = stackPos(1);
2117 	int l = c->skillLevels[s];
2118 	increaseExperience(stackPos(0), s, _expRequirements[l] - c->experiencePts[s]);
2119 	return c->skillLevels[s] - l;
2120 }
2121 
olol_paletteFlash(EMCState * script)2122 int LoLEngine::olol_paletteFlash(EMCState *script) {
2123 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_paletteFlash(%p) (%d)", (const void *)script, stackPos(0));
2124 	Palette &p1 = _screen->getPalette(1);
2125 
2126 	if (_flags.use16ColorMode) {
2127 		Palette p2(16);
2128 		p2.copy(p1);
2129 		uint8 *d = p2.getData();
2130 
2131 		for (int i = 0; i < 16; i++)
2132 			d[i * 3] = 0x3F;
2133 
2134 		_screen->setScreenPalette(p2);
2135 		_screen->updateScreen();
2136 
2137 		delay(4 * _tickLength);
2138 
2139 		_screen->setScreenPalette(p1);
2140 		if (_smoothScrollModeNormal)
2141 			_screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
2142 
2143 		_screen->updateScreen();
2144 
2145 	} else {
2146 		Palette &p2 = _screen->getPalette(3);
2147 
2148 		uint8 ovl[256];
2149 		generateFlashPalette(p1, p2, stackPos(0));
2150 		_screen->loadSpecialColors(p1);
2151 		_screen->loadSpecialColors(p2);
2152 
2153 		if (_smoothScrollModeNormal) {
2154 			for (int i = 0; i < 256; i++)
2155 				ovl[i] = i;
2156 			ovl[1] = 6;
2157 
2158 			_screen->copyRegion(112, 0, 112, 0, 176, 120, 0, 2);
2159 			_screen->applyOverlay(112, 0, 176, 120, 0, ovl);
2160 		}
2161 
2162 		_screen->setScreenPalette(p2);
2163 		_screen->updateScreen();
2164 
2165 		delay(2 * _tickLength);
2166 
2167 		_screen->setScreenPalette(p1);
2168 		if (_smoothScrollModeNormal)
2169 			_screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
2170 
2171 		_screen->updateScreen();
2172 	}
2173 
2174 	return 0;
2175 }
2176 
olol_restoreMagicShroud(EMCState * script)2177 int LoLEngine::olol_restoreMagicShroud(EMCState *script) {
2178 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreMagicShroud(%p)", (const void *)script);
2179 
2180 	WSAMovie_v2 *mov = new WSAMovie_v2(this);
2181 	mov->open("DARKLITE.WSA", 2, 0);
2182 	if (!mov->opened()) {
2183 		delete mov;
2184 		warning("LoLEngine::olol_restoreMagicShroud: Could not open file: \"DARKLITE.WSA\"");
2185 		return 1;
2186 	}
2187 
2188 	_screen->hideMouse();
2189 
2190 	Palette *fadeTab[28];
2191 	for (int i = 0; i < 28; i++)
2192 		fadeTab[i] = new Palette(_flags.use16ColorMode ? 16 : 256);
2193 
2194 	Palette **tpal1 = &fadeTab[0];
2195 	Palette **tpal2 = &fadeTab[1];
2196 	Palette **tpal3 = &fadeTab[2];
2197 	Palette **tpal4 = 0;
2198 
2199 	int len = _flags.use16ColorMode ? 48 : 768;
2200 	_res->loadFileToBuf("LITEPAL1.COL", (*tpal1)->getData(), len);
2201 	tpal2 = _screen->generateFadeTable(tpal3, 0, *tpal1, 21);
2202 
2203 	_res->loadFileToBuf("LITEPAL2.COL", (*tpal2)->getData(), len);
2204 	tpal4 = tpal2++;
2205 
2206 	_res->loadFileToBuf("LITEPAL3.COL", (*tpal1)->getData(), len);
2207 	_screen->generateFadeTable(tpal2, *tpal4, *tpal1, 4);
2208 
2209 	for (int i = 0; i < 21; i++) {
2210 		uint32 etime = _system->getMillis() + 20 * _tickLength;
2211 		mov->displayFrame(i, 0, 0, 0, 0, 0, 0);
2212 		_screen->setScreenPalette(**tpal3++);
2213 		_screen->updateScreen();
2214 
2215 		if (i == 2 || i == 5 || i == 8 || i == 11 || i == 13 || i == 15 || i == 17 || i == 19)
2216 			snd_playSoundEffect(95, -1);
2217 
2218 		delayUntil(etime);
2219 	}
2220 
2221 	snd_playSoundEffect(91, -1);
2222 	_screen->fadePalette(**tpal3++, 300);
2223 
2224 	for (int i = 22; i < 38; i++) {
2225 		uint32 etime = _system->getMillis() + 12 * _tickLength;
2226 		mov->displayFrame(i, 0, 0, 0, 0, 0, 0);
2227 		if (i == 22 || i == 24 || i == 28 || i == 32) {
2228 			snd_playSoundEffect(131, -1);
2229 			_screen->setScreenPalette(**tpal3++);
2230 		}
2231 		_screen->updateScreen();
2232 		delayUntil(etime);
2233 	}
2234 
2235 	mov->close();
2236 	delete mov;
2237 
2238 	for (int i = 0; i < 28; i++)
2239 		delete fadeTab[i];
2240 
2241 	_screen->showMouse();
2242 
2243 	return 1;
2244 }
2245 
olol_disableControls(EMCState * script)2246 int LoLEngine::olol_disableControls(EMCState *script) {
2247 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_disableControls(%p) (%d)", (const void *)script, stackPos(0));
2248 	return gui_disableControls(stackPos(0));
2249 }
2250 
olol_enableControls(EMCState * script)2251 int LoLEngine::olol_enableControls(EMCState *script) {
2252 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_enableControls(%p)", (const void *)script);
2253 	return gui_enableControls();
2254 }
2255 
olol_shakeScene(EMCState * script)2256 int LoLEngine::olol_shakeScene(EMCState *script) {
2257 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_shakeScene(%p)  (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
2258 	shakeScene(stackPos(0), stackPos(1), stackPos(2), 1);
2259 	return 1;
2260 }
2261 
olol_gasExplosion(EMCState * script)2262 int LoLEngine::olol_gasExplosion(EMCState *script) {
2263 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_gasExplosion(%p) (%d)", (const void *)script, stackPos(0));
2264 	processGasExplosion(stackPos(0));
2265 	return 1;
2266 }
2267 
olol_calcNewBlockPosition(EMCState * script)2268 int LoLEngine::olol_calcNewBlockPosition(EMCState *script) {
2269 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_calcNewBlockPosition(%p)  (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
2270 	return calcNewBlockPosition(stackPos(0), stackPos(1));
2271 }
2272 
olol_crossFadeScene(EMCState * script)2273 int LoLEngine::olol_crossFadeScene(EMCState *script) {
2274 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_crossFadeScene(%p)", (const void *)script);
2275 	gui_drawScene(2);
2276 	_screen->crossFadeRegion(112, 0, 112, 0, 176, 120, 2, 0);
2277 	updateDrawPage2();
2278 	return 1;
2279 }
2280 
olol_updateDrawPage2(EMCState * script)2281 int LoLEngine::olol_updateDrawPage2(EMCState *script) {
2282 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_updateDrawPage2(%p)", (const void *)script);
2283 	updateDrawPage2();
2284 	return 1;
2285 }
2286 
olol_setMouseCursor(EMCState * script)2287 int LoLEngine::olol_setMouseCursor(EMCState *script) {
2288 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setMouseCursor(%p) (%d)", (const void *)script, stackPos(0));
2289 	if (stackPos(0) == 1)
2290 		setMouseCursorToIcon(133);
2291 	else
2292 		setMouseCursorToItemInHand();
2293 	return 1;
2294 }
2295 
olol_characterSays(EMCState * script)2296 int LoLEngine::olol_characterSays(EMCState *script) {
2297 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterSays(%p)  (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
2298 
2299 	if (!_flags.isTalkie)
2300 		return 0;
2301 
2302 	if (stackPos(0) == -1) {
2303 		snd_stopSpeech(true);
2304 		return 1;
2305 	}
2306 
2307 	if (stackPos(0) != -2)
2308 		return characterSays(stackPos(0), stackPos(1), stackPos(2));
2309 	else
2310 		return snd_updateCharacterSpeech();
2311 }
2312 
olol_queueSpeech(EMCState * script)2313 int LoLEngine::olol_queueSpeech(EMCState *script) {
2314 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_queueSpeech(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
2315 	if (stackPos(0) && stackPos(1)) {
2316 		_nextSpeechId = stackPos(0) + 1000;
2317 		_nextSpeaker = stackPos(1);
2318 	}
2319 	return 1;
2320 }
2321 
olol_getItemPrice(EMCState * script)2322 int LoLEngine::olol_getItemPrice(EMCState *script) {
2323 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getItemPrice(%p) (%d)", (const void *)script, stackPos(0));
2324 	int c = stackPos(0);
2325 	if (c < 0) {
2326 		c = -c;
2327 		if (c < 50)
2328 			return 50;
2329 		c = (c + 99) / 100;
2330 		return c * 100;
2331 
2332 	} else {
2333 		for (int i = 0; i < 46; i++) {
2334 			if (_itemCost[i] >= c)
2335 				return _itemCost[i];
2336 		}
2337 	}
2338 
2339 	return 0;
2340 }
2341 
olol_getLanguage(EMCState * script)2342 int LoLEngine::olol_getLanguage(EMCState *script) {
2343 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getLanguage(%p)", (const void *)script);
2344 	return _lang;
2345 }
2346 
2347 #pragma mark -
2348 
tlol_setupPaletteFade(const TIM * tim,const uint16 * param)2349 int LoLEngine::tlol_setupPaletteFade(const TIM *tim, const uint16 *param) {
2350 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_setupPaletteFade(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2351 	_screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
2352 	_tim->_palDelayAcc = 0;
2353 	return 1;
2354 }
2355 
tlol_loadPalette(const TIM * tim,const uint16 * param)2356 int LoLEngine::tlol_loadPalette(const TIM *tim, const uint16 *param) {
2357 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_loadPalette(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2358 	const char *palFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)));
2359 	_screen->loadPalette(palFile, _screen->getPalette(0));
2360 	return 1;
2361 }
2362 
tlol_setupPaletteFadeEx(const TIM * tim,const uint16 * param)2363 int LoLEngine::tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param) {
2364 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_setupPaletteFadeEx(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2365 	_screen->copyPalette(0, 1);
2366 
2367 	_screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
2368 	_tim->_palDelayAcc = 0;
2369 	return 1;
2370 }
2371 
tlol_processWsaFrame(const TIM * tim,const uint16 * param)2372 int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
2373 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_processWsaFrame(%p, %p) (%d, %d, %d, %d, %d)",
2374 	       (const void *)tim, (const void *)param, param[0], param[1], param[2], param[3], param[4]);
2375 
2376 	const int animIndex = tim->wsa[param[0]].anim - 1;
2377 	const int frame = param[1];
2378 	const int x2 = param[2];
2379 	const int y2 = param[3];
2380 	const int factor = MAX<int>(0, (int16)param[4]);
2381 
2382 	const int x1 = _tim->animator()->getAnimX(animIndex);
2383 	const int y1 = _tim->animator()->getAnimY(animIndex);
2384 	const Movie *wsa = _tim->animator()->getWsaCPtr(animIndex);
2385 
2386 	int w1 = wsa->width();
2387 	int h1 = wsa->height();
2388 	int w2 = (w1 * factor) / 100;
2389 	int h2 = (h1 * factor) / 100;
2390 
2391 	_tim->animator()->displayFrame(animIndex, 2, frame);
2392 	_screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, _flags.isDemo && _flags.platform != Common::kPlatformPC98 ? 0 : 8, 0);
2393 	if (!_flags.isDemo && _flags.platform != Common::kPlatformPC98)
2394 		_screen->checkedPageUpdate(8, 4);
2395 	_screen->updateScreen();
2396 
2397 	return 1;
2398 }
2399 
tlol_displayText(const TIM * tim,const uint16 * param)2400 int LoLEngine::tlol_displayText(const TIM *tim, const uint16 *param) {
2401 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayText(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], (int16)param[1]);
2402 	if (tim->isLoLOutro)
2403 		_tim->displayText(param[0], param[1], param[2]);
2404 	else
2405 		_tim->displayText(param[0], param[1]);
2406 	return 1;
2407 }
2408 
tlol_initSceneWindowDialogue(const TIM * tim,const uint16 * param)2409 int LoLEngine::tlol_initSceneWindowDialogue(const TIM *tim, const uint16 *param) {
2410 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_initSceneWindowDialogue(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2411 	initSceneWindowDialogue(param[0]);
2412 	return 1;
2413 }
2414 
tlol_restoreAfterSceneWindowDialogue(const TIM * tim,const uint16 * param)2415 int LoLEngine::tlol_restoreAfterSceneWindowDialogue(const TIM *tim, const uint16 *param) {
2416 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_restoreAfterSceneWindowDialogue(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2417 	restoreAfterSceneWindowDialogue(param[0]);
2418 	return 1;
2419 }
2420 
tlol_giveItem(const TIM * tim,const uint16 * param)2421 int LoLEngine::tlol_giveItem(const TIM *tim, const uint16 *param) {
2422 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_giveItem(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2423 	int item = makeItem(param[0], param[1], param[2]);
2424 	if (addItemToInventory(item))
2425 		return 1;
2426 
2427 	deleteItem(item);
2428 	return 0;
2429 }
2430 
tlol_setPartyPosition(const TIM * tim,const uint16 * param)2431 int LoLEngine::tlol_setPartyPosition(const TIM *tim, const uint16 *param) {
2432 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_setPartyPosition(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
2433 	if (param[0] == 1) {
2434 		_currentDirection = param[1];
2435 	} else if (param[0] == 0) {
2436 		_currentBlock = param[1];
2437 		calcCoordinates(_partyPosX, _partyPosY, _currentBlock, 0x80, 0x80);
2438 	}
2439 
2440 	return 1;
2441 }
2442 
tlol_fadeClearWindow(const TIM * tim,const uint16 * param)2443 int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) {
2444 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeClearWindow(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2445 
2446 	switch (param[0]) {
2447 	case 0:
2448 		_screen->fadeClearSceneWindow(10);
2449 		break;
2450 
2451 	case 1:
2452 		if (_flags.use16ColorMode) {
2453 			_screen->fadePalette(_screen->getPalette(1), 10);
2454 		} else {
2455 			_screen->getPalette(3).copy(_screen->getPalette(0), 128);
2456 			_screen->loadSpecialColors(_screen->getPalette(3));
2457 			_screen->fadePalette(_screen->getPalette(3), 10);
2458 		}
2459 		_screen->_fadeFlag = 0;
2460 		break;
2461 
2462 	case 2:
2463 		_screen->fadeToBlack(10);
2464 		break;
2465 
2466 	case 3:
2467 		_screen->loadSpecialColors(_screen->getPalette(3));
2468 		_screen->fadePalette(_screen->getPalette(_flags.use16ColorMode ? 1 : 3), 10);
2469 		_screen->_fadeFlag = 0;
2470 		break;
2471 
2472 	case 4:
2473 		if (_screen->_fadeFlag != 2)
2474 			_screen->fadeClearSceneWindow(10);
2475 		gui_drawPlayField();
2476 		setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
2477 		_screen->_fadeFlag = 0;
2478 		break;
2479 
2480 	case 5:
2481 		_screen->loadSpecialColors(_screen->getPalette(3));
2482 		_screen->fadePalette(_screen->getPalette(1), 10);
2483 		_screen->_fadeFlag = 0;
2484 		break;
2485 
2486 	default:
2487 		break;
2488 	}
2489 
2490 	return 1;
2491 }
2492 
tlol_copyRegion(const TIM * tim,const uint16 * param)2493 int LoLEngine::tlol_copyRegion(const TIM *tim, const uint16 *param) {
2494 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_copyRegion(%p, %p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)tim, (const void *)param, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7]);
2495 	_screen->copyRegion(param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], Screen::CR_NO_P_CHECK);
2496 	if (!param[7])
2497 		_screen->updateScreen();
2498 	return 1;
2499 }
2500 
tlol_characterChat(const TIM * tim,const uint16 * param)2501 int LoLEngine::tlol_characterChat(const TIM *tim, const uint16 *param) {
2502 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_characterChat(%p, %p) (%d, %d, %d)", (const void *)tim, (const void *)param, param[0], param[1], param[2]);
2503 	playCharacterScriptChat(param[0], param[1], 1, getLangString(param[2]), 0, param, 3);
2504 	return 1;
2505 }
2506 
tlol_drawScene(const TIM * tim,const uint16 * param)2507 int LoLEngine::tlol_drawScene(const TIM *tim, const uint16 *param) {
2508 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_drawScene(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2509 	gui_drawScene(param[0]);
2510 	//if (_sceneDrawPage2 != 2 && param[0] == 2)
2511 	//	_screen->copyRegion(112 << 3, 0, 112 << 3, 0, 176 << 3, 120, _sceneDrawPage2, 2, Screen::CR_NO_P_CHECK);
2512 	return 1;
2513 }
2514 
tlol_update(const TIM * tim,const uint16 * param)2515 int LoLEngine::tlol_update(const TIM *tim, const uint16 *param) {
2516 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_update(%p, %p)", (const void *)tim, (const void *)param);
2517 	update();
2518 	return 1;
2519 }
2520 
tlol_clearTextField(const TIM * tim,const uint16 * param)2521 int LoLEngine::tlol_clearTextField(const TIM *tim, const uint16 *param) {
2522 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_clearTextField(%p, %p)", (const void *)tim, (const void *)param);
2523 	if (_currentControlMode && !textEnabled())
2524 		return 1;
2525 	_screen->setScreenDim(5);
2526 	const ScreenDim *d = _screen->_curDim;
2527 	_screen->fillRect(d->sx, d->sy, d->sx + d->w - (_flags.use16ColorMode ? 3 : 2), d->sy + d->h - 2, d->unkA);
2528 	_txt->clearDim(4);
2529 	_txt->resetDimTextPositions(4);
2530 	return 1;
2531 }
2532 
tlol_loadSoundFile(const TIM * tim,const uint16 * param)2533 int LoLEngine::tlol_loadSoundFile(const TIM *tim, const uint16 *param) {
2534 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_loadSoundFile(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2535 	snd_loadSoundFile(param[0]);
2536 	return 1;
2537 }
2538 
tlol_playMusicTrack(const TIM * tim,const uint16 * param)2539 int LoLEngine::tlol_playMusicTrack(const TIM *tim, const uint16 *param) {
2540 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_playMusicTrack(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2541 	snd_playTrack(param[0]);
2542 	return 1;
2543 }
2544 
tlol_playDialogueTalkText(const TIM * tim,const uint16 * param)2545 int LoLEngine::tlol_playDialogueTalkText(const TIM *tim, const uint16 *param) {
2546 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_playDialogueTalkText(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2547 	if (!snd_playCharacterSpeech(param[0], 0, 0) || textEnabled())
2548 		_txt->printDialogueText(4, getLangString(param[0]), 0, param, 1);
2549 	return 1;
2550 }
2551 
tlol_playSoundEffect(const TIM * tim,const uint16 * param)2552 int LoLEngine::tlol_playSoundEffect(const TIM *tim, const uint16 *param) {
2553 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_playSoundEffect(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2554 	snd_playSoundEffect(param[0], -1);
2555 	return 1;
2556 }
2557 
tlol_startBackgroundAnimation(const TIM * tim,const uint16 * param)2558 int LoLEngine::tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param) {
2559 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_startBackgroundAnimation(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
2560 	_tim->animator()->start(param[0], param[1]);
2561 	return 1;
2562 }
2563 
tlol_stopBackgroundAnimation(const TIM * tim,const uint16 * param)2564 int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param) {
2565 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_stopBackgroundAnimation(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2566 	_tim->animator()->stop(param[0]);
2567 	return 1;
2568 }
2569 
tlol_fadeInScene(const TIM * tim,const uint16 * param)2570 int LoLEngine::tlol_fadeInScene(const TIM *tim, const uint16 *param) {
2571 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInScene(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
2572 	const char *sceneFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)));
2573 	const char *overlayFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[1] << 1)));
2574 
2575 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
2576 
2577 	char filename[32];
2578 	strcpy(filename, sceneFile);
2579 	strcat(filename, ".CPS");
2580 
2581 	_screen->loadBitmap(filename, 7, 5, &_screen->getPalette(0));
2582 
2583 	uint8 *overlay = 0;
2584 	if (!_flags.use16ColorMode) {
2585 		filename[0] = 0;
2586 
2587 		if (_flags.isTalkie) {
2588 			strcpy(filename, _languageExt[_lang]);
2589 			strcat(filename, "/");
2590 		}
2591 
2592 		strcat(filename, overlayFile);
2593 		overlay = _res->fileData(filename, 0);
2594 
2595 		for (int i = 0; i < 3; ++i) {
2596 			uint32 endTime = _system->getMillis() + 10 * _tickLength;
2597 			_screen->copyBlockAndApplyOverlayOutro(4, 2, overlay);
2598 			_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
2599 			_screen->updateScreen();
2600 			delayUntil(endTime);
2601 		}
2602 	}
2603 
2604 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0, Screen::CR_NO_P_CHECK);
2605 
2606 	if (_flags.use16ColorMode) {
2607 		_screen->fadePalette(_screen->getPalette(0), 5);
2608 	} else {
2609 		_screen->updateScreen();
2610 		delete[] overlay;
2611 	}
2612 
2613 	return 1;
2614 }
2615 
tlol_unusedResourceFunc(const TIM * tim,const uint16 * param)2616 int LoLEngine::tlol_unusedResourceFunc(const TIM *tim, const uint16 *param) {
2617 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_unusedResourceFunc(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2618 	// The original used 0x6 / 0x7 for some resource caching, we don't need this.
2619 	return 1;
2620 }
2621 
tlol_fadeInPalette(const TIM * tim,const uint16 * param)2622 int LoLEngine::tlol_fadeInPalette(const TIM *tim, const uint16 *param) {
2623 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInPalette(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
2624 	const char *bitmap = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)));
2625 
2626 	Palette pal(_screen->getPalette(0).getNumColors());
2627 	_screen->loadBitmap(bitmap, 3, 3, &pal);
2628 
2629 	if (_flags.use16ColorMode) {
2630 		_screen->getPalette(0).clear();
2631 		_screen->setScreenPalette(_screen->getPalette(0));
2632 		_screen->copyPage(2, 0);
2633 	}
2634 
2635 	_screen->fadePalette(pal, param[1]);
2636 
2637 	return 1;
2638 }
2639 
tlol_fadeOutSound(const TIM * tim,const uint16 * param)2640 int LoLEngine::tlol_fadeOutSound(const TIM *tim, const uint16 *param) {
2641 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeOutSound(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2642 	_sound->beginFadeOut();
2643 	return 1;
2644 }
2645 
tlol_displayAnimFrame(const TIM * tim,const uint16 * param)2646 int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) {
2647 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayAnimFrame(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
2648 
2649 	const int animIndex = tim->wsa[param[0]].anim - 1;
2650 	const Movie *wsa = _tim->animator()->getWsaCPtr(animIndex);
2651 
2652 	if (param[1] == 0xFFFF) {
2653 		_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
2654 	} else {
2655 		_tim->animator()->displayFrame(animIndex, 2, param[1], 0);
2656 		_screen->copyRegion(wsa->xAdd(), wsa->yAdd(), wsa->xAdd(), wsa->yAdd(), wsa->width(), wsa->height(), 2, 0);
2657 	}
2658 
2659 	return 1;
2660 }
2661 
tlol_delayForChat(const TIM * tim,const uint16 * param)2662 int LoLEngine::tlol_delayForChat(const TIM *tim, const uint16 *param) {
2663 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_delayForChat(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
2664 	if (!speechEnabled())
2665 		delay(param[0]);
2666 	return 1;
2667 }
2668 
2669 #pragma mark -
2670 
2671 typedef Common::Functor1Mem<EMCState *, int, LoLEngine> OpcodeV2;
2672 #define SetOpcodeTable(x) table = &x;
2673 #define Opcode(x) table->push_back(new OpcodeV2(this, &LoLEngine::x))
2674 #define OpcodeUnImpl() table->push_back(new OpcodeV2(this, 0))
2675 
2676 typedef Common::Functor2Mem<const TIM *, const uint16 *, int, LoLEngine> TIMOpcodeLoL;
2677 #define SetTimOpcodeTable(x) timTable = &x;
2678 #define OpcodeTim(x) timTable->push_back(new TIMOpcodeLoL(this, &LoLEngine::x))
2679 #define OpcodeTimUnImpl() timTable->push_back(new TIMOpcodeLoL(this, 0))
2680 
setupOpcodeTable()2681 void LoLEngine::setupOpcodeTable() {
2682 	Common::Array<const Opcode *> *table = 0;
2683 
2684 	_opcodes.reserve(192);
2685 	SetOpcodeTable(_opcodes);
2686 	// 0x00
2687 	Opcode(olol_setWallType);
2688 	Opcode(olol_getWallType);
2689 	Opcode(olol_drawScene);
2690 	Opcode(olol_rollDice);
2691 
2692 	// 0x04
2693 	Opcode(olol_moveParty);
2694 	OpcodeUnImpl();
2695 	Opcode(olol_delay);
2696 	Opcode(olol_setGameFlag);
2697 
2698 	// 0x08
2699 	Opcode(olol_testGameFlag);
2700 	Opcode(olol_loadLevelGraphics);
2701 	Opcode(olol_loadBlockProperties);
2702 	Opcode(olol_loadMonsterShapes);
2703 
2704 	// 0x0C
2705 	Opcode(olol_deleteHandItem);
2706 	Opcode(olol_allocItemPropertiesBuffer);
2707 	Opcode(olol_setItemProperty);
2708 	Opcode(olol_makeItem);
2709 
2710 	// 0x10
2711 	Opcode(olol_placeMoveLevelItem);
2712 	Opcode(olol_createLevelItem);
2713 	Opcode(olol_getItemPara);
2714 	Opcode(olol_getCharacterStat);
2715 
2716 	// 0x14
2717 	Opcode(olol_setCharacterStat);
2718 	Opcode(olol_loadLevelShapes);
2719 	Opcode(olol_closeLevelShapeFile);
2720 	OpcodeUnImpl();
2721 
2722 	// 0x18
2723 	Opcode(olol_loadDoorShapes);
2724 	Opcode(olol_initAnimStruct);
2725 	Opcode(olol_playAnimationPart);
2726 	Opcode(olol_freeAnimStruct);
2727 
2728 	// 0x1C
2729 	Opcode(olol_getDirection);
2730 	Opcode(olol_characterSurpriseFeedback);
2731 	Opcode(olol_setMusicTrack);
2732 	Opcode(olol_setSequenceButtons);
2733 
2734 	// 0x20
2735 	Opcode(olol_setDefaultButtonState);
2736 	Opcode(olol_checkRectForMousePointer);
2737 	Opcode(olol_clearDialogueField);
2738 	Opcode(olol_setupBackgroundAnimationPart);
2739 
2740 	// 0x24
2741 	Opcode(olol_startBackgroundAnimation);
2742 	Opcode(o1_hideMouse);
2743 	Opcode(o1_showMouse);
2744 	Opcode(olol_fadeToBlack);
2745 
2746 	// 0x28
2747 	Opcode(olol_fadePalette);
2748 	Opcode(olol_loadBitmap);
2749 	Opcode(olol_stopBackgroundAnimation);
2750 	OpcodeUnImpl();
2751 
2752 	// 0x2C
2753 	OpcodeUnImpl();
2754 	Opcode(olol_getGlobalScriptVar);
2755 	Opcode(olol_setGlobalScriptVar);
2756 	Opcode(olol_getGlobalVar);
2757 
2758 	// 0x30
2759 	Opcode(olol_setGlobalVar);
2760 	Opcode(olol_triggerDoorSwitch);
2761 	Opcode(olol_checkEquippedItemScriptFlags);
2762 	Opcode(olol_setDoorState);
2763 
2764 	// 0x34
2765 	Opcode(olol_updateBlockAnimations);
2766 	Opcode(olol_assignLevelDecorationShape);
2767 	Opcode(olol_resetBlockShapeAssignment);
2768 	Opcode(olol_copyRegion);
2769 
2770 	// 0x38
2771 	Opcode(olol_initMonster);
2772 	Opcode(olol_fadeClearSceneWindow);
2773 	Opcode(olol_fadeSequencePalette);
2774 	Opcode(olol_redrawPlayfield);
2775 
2776 	// 0x3C
2777 	Opcode(olol_loadNewLevel);
2778 	Opcode(olol_getNearestMonsterFromCharacter);
2779 	Opcode(olol_dummy0);
2780 	Opcode(olol_loadMonsterProperties);
2781 
2782 	// 0x40
2783 	Opcode(olol_battleHitSkillTest);
2784 	Opcode(olol_inflictDamage);
2785 	OpcodeUnImpl();
2786 	OpcodeUnImpl();
2787 
2788 	// 0x44
2789 	Opcode(olol_moveMonster);
2790 	Opcode(olol_setupDialogueButtons);
2791 	Opcode(olol_giveTakeMoney);
2792 	Opcode(olol_checkMoney);
2793 
2794 	// 0x48
2795 	Opcode(olol_setScriptTimer);
2796 	Opcode(olol_createHandItem);
2797 	Opcode(olol_playAttackSound);
2798 	Opcode(olol_addRemoveCharacter);
2799 
2800 	// 0x4C
2801 	Opcode(olol_giveItem);
2802 	OpcodeUnImpl();
2803 	Opcode(olol_loadTimScript);
2804 	Opcode(olol_runTimScript);
2805 
2806 	// 0x50
2807 	Opcode(olol_releaseTimScript);
2808 	Opcode(olol_initSceneWindowDialogue);
2809 	Opcode(olol_restoreAfterSceneWindowDialogue);
2810 	Opcode(olol_getItemInHand);
2811 
2812 	// 0x54
2813 	Opcode(olol_checkMagic);
2814 	Opcode(olol_giveItemToMonster);
2815 	Opcode(olol_loadLangFile);
2816 	Opcode(olol_playSoundEffect);
2817 
2818 	// 0x58
2819 	Opcode(olol_processDialogue);
2820 	Opcode(olol_stopTimScript);
2821 	Opcode(olol_getWallFlags);
2822 	Opcode(olol_changeMonsterStat);
2823 
2824 	// 0x5C
2825 	Opcode(olol_getMonsterStat);
2826 	Opcode(olol_releaseMonsterShapes);
2827 	Opcode(olol_playCharacterScriptChat);
2828 	Opcode(olol_update);
2829 
2830 	// 0x60
2831 	Opcode(olol_playEnvironmentalSfx);
2832 	Opcode(olol_healCharacter);
2833 	Opcode(olol_drawExitButton);
2834 	Opcode(olol_loadSoundFile);
2835 
2836 	// 0x64
2837 	Opcode(olol_playMusicTrack);
2838 	Opcode(olol_deleteMonstersFromBlock);
2839 	Opcode(olol_countBlockItems);
2840 	Opcode(olol_characterSkillTest);
2841 
2842 	// 0x68
2843 	Opcode(olol_countAllMonsters);
2844 	Opcode(olol_playEndSequence);
2845 	Opcode(olol_stopPortraitSpeechAnim);
2846 	Opcode(olol_setPaletteBrightness);
2847 
2848 	// 0x6C
2849 	Opcode(olol_calcInflictableDamage);
2850 	Opcode(olol_getInflictedDamage);
2851 	Opcode(olol_checkForCertainPartyMember);
2852 	Opcode(olol_printMessage);
2853 
2854 	// 0x70
2855 	Opcode(olol_deleteLevelItem);
2856 	Opcode(olol_calcInflictableDamagePerItem);
2857 	Opcode(olol_distanceAttack);
2858 	Opcode(olol_removeCharacterEffects);
2859 
2860 	// 0x74
2861 	Opcode(olol_checkInventoryFull);
2862 	Opcode(olol_moveBlockObjects);
2863 	OpcodeUnImpl();
2864 	OpcodeUnImpl();
2865 
2866 	// 0x78
2867 	Opcode(olol_addSpellToScroll);
2868 	Opcode(olol_playDialogueText);
2869 	Opcode(olol_playDialogueTalkText);
2870 	Opcode(olol_checkMonsterTypeHostility);
2871 
2872 	// 0x7C
2873 	Opcode(olol_setNextFunc);
2874 	Opcode(olol_dummy1);
2875 	OpcodeUnImpl();
2876 	Opcode(olol_suspendMonster);
2877 
2878 	// 0x80
2879 	Opcode(olol_setScriptTextParameter);
2880 	Opcode(olol_triggerEventOnMouseButtonClick);
2881 	Opcode(olol_printWindowText);
2882 	Opcode(olol_countSpecificMonsters);
2883 
2884 	// 0x84
2885 	Opcode(olol_updateBlockAnimations2);
2886 	Opcode(olol_checkPartyForItemType);
2887 	Opcode(olol_blockDoor);
2888 	Opcode(olol_resetTimDialogueState);
2889 
2890 	// 0x88
2891 	Opcode(olol_getItemOnPos);
2892 	Opcode(olol_removeLevelItem);
2893 	Opcode(olol_savePage5);
2894 	Opcode(olol_restorePage5);
2895 
2896 	// 0x8C
2897 	Opcode(olol_initDialogueSequence);
2898 	Opcode(olol_restoreAfterDialogueSequence);
2899 	Opcode(olol_setSpecialSceneButtons);
2900 	Opcode(olol_restoreButtonsAfterSpecialScene);
2901 
2902 	// 0x90
2903 	OpcodeUnImpl();
2904 	OpcodeUnImpl();
2905 	Opcode(olol_prepareSpecialScene);
2906 	Opcode(olol_restoreAfterSpecialScene);
2907 
2908 	// 0x94
2909 	Opcode(olol_assignCustomSfx);
2910 	OpcodeUnImpl();
2911 	Opcode(olol_findAssignedMonster);
2912 	Opcode(olol_checkBlockForMonster);
2913 
2914 	// 0x98
2915 	Opcode(olol_crossFadeRegion);
2916 	Opcode(olol_calcCoordinatesAddDirectionOffset);
2917 	Opcode(olol_resetPortraitsAndDisableSysTimer);
2918 	Opcode(olol_enableSysTimer);
2919 
2920 	// 0x9C
2921 	Opcode(olol_checkNeedSceneRestore);
2922 	Opcode(olol_getNextActiveCharacter);
2923 	Opcode(olol_paralyzePoisonCharacter);
2924 	Opcode(olol_drawCharPortrait);
2925 
2926 	// 0xA0
2927 	Opcode(olol_removeInventoryItem);
2928 	OpcodeUnImpl();
2929 	OpcodeUnImpl();
2930 	Opcode(olol_getAnimationLastPart);
2931 
2932 	// 0xA4
2933 	Opcode(olol_assignSpecialGuiShape);
2934 	Opcode(olol_findInventoryItem);
2935 	Opcode(olol_restoreFadePalette);
2936 	Opcode(olol_calcNewBlockPosition);
2937 
2938 	// 0xA8
2939 	Opcode(olol_getSelectedCharacter);
2940 	Opcode(olol_setHandItem);
2941 	Opcode(olol_drinkBezelCup);
2942 	Opcode(olol_changeItemTypeOrFlag);
2943 
2944 	// 0xAC
2945 	Opcode(olol_placeInventoryItemInHand);
2946 	Opcode(olol_castSpell);
2947 	Opcode(olol_pitDrop);
2948 	Opcode(olol_increaseSkill);
2949 
2950 	// 0xB0
2951 	Opcode(olol_paletteFlash);
2952 	Opcode(olol_restoreMagicShroud);
2953 	Opcode(olol_dummy1); // anim buffer select?
2954 	Opcode(olol_disableControls);
2955 
2956 	// 0xB4
2957 	Opcode(olol_enableControls);
2958 	Opcode(olol_shakeScene);
2959 	Opcode(olol_gasExplosion);
2960 	Opcode(olol_calcNewBlockPosition);
2961 
2962 	// 0xB8
2963 	Opcode(olol_crossFadeScene);
2964 	Opcode(olol_updateDrawPage2);
2965 	Opcode(olol_setMouseCursor);
2966 	Opcode(olol_characterSays);
2967 
2968 	// 0xBC
2969 	Opcode(olol_queueSpeech);
2970 	Opcode(olol_getItemPrice);
2971 	Opcode(olol_getLanguage);
2972 	Opcode(olol_dummy0);
2973 
2974 	Common::Array<const TIMOpcode *> *timTable = 0;
2975 
2976 	_timIntroOpcodes.reserve(8);
2977 	SetTimOpcodeTable(_timIntroOpcodes);
2978 
2979 	// 0x00
2980 	OpcodeTim(tlol_setupPaletteFade);
2981 	OpcodeTimUnImpl();
2982 	OpcodeTim(tlol_loadPalette);
2983 	OpcodeTim(tlol_setupPaletteFadeEx);
2984 
2985 	// 0x04
2986 	OpcodeTim(tlol_processWsaFrame);
2987 	OpcodeTim(tlol_displayText);
2988 	OpcodeTimUnImpl();
2989 	OpcodeTimUnImpl();
2990 
2991 	_timOutroOpcodes.reserve(16);
2992 	SetTimOpcodeTable(_timOutroOpcodes);
2993 
2994 	// 0x00
2995 	OpcodeTim(tlol_setupPaletteFade);
2996 	OpcodeTimUnImpl();
2997 	OpcodeTim(tlol_loadPalette);
2998 	OpcodeTim(tlol_setupPaletteFadeEx);
2999 
3000 	// 0x04
3001 	OpcodeTimUnImpl();
3002 	OpcodeTim(tlol_fadeInScene);
3003 	OpcodeTim(tlol_unusedResourceFunc);
3004 	OpcodeTim(tlol_unusedResourceFunc);
3005 
3006 	// 0x08
3007 	OpcodeTim(tlol_fadeInPalette);
3008 	OpcodeTimUnImpl();
3009 	OpcodeTimUnImpl();
3010 	OpcodeTim(tlol_fadeOutSound);
3011 
3012 	// 0x0C
3013 	OpcodeTim(tlol_displayAnimFrame);
3014 	OpcodeTim(tlol_delayForChat);
3015 	OpcodeTim(tlol_displayText);
3016 	OpcodeTimUnImpl();
3017 
3018 	_timIngameOpcodes.reserve(17);
3019 	SetTimOpcodeTable(_timIngameOpcodes);
3020 
3021 	// 0x00
3022 	OpcodeTim(tlol_initSceneWindowDialogue);
3023 	OpcodeTim(tlol_restoreAfterSceneWindowDialogue);
3024 	OpcodeTimUnImpl();
3025 	OpcodeTim(tlol_giveItem);
3026 
3027 	// 0x04
3028 	OpcodeTim(tlol_setPartyPosition);
3029 	OpcodeTim(tlol_fadeClearWindow);
3030 	OpcodeTim(tlol_copyRegion);
3031 	OpcodeTim(tlol_characterChat);
3032 
3033 	// 0x08
3034 	OpcodeTim(tlol_drawScene);
3035 	OpcodeTim(tlol_update);
3036 	OpcodeTim(tlol_clearTextField);
3037 	OpcodeTim(tlol_loadSoundFile);
3038 
3039 	// 0x0C
3040 	OpcodeTim(tlol_playMusicTrack);
3041 	OpcodeTim(tlol_playDialogueTalkText);
3042 	OpcodeTim(tlol_playSoundEffect);
3043 	OpcodeTim(tlol_startBackgroundAnimation);
3044 
3045 	// 0x10
3046 	OpcodeTim(tlol_stopBackgroundAnimation);
3047 }
3048 
3049 } // End of namespace Kyra
3050 
3051 #endif // ENABLE_LOL
3052