1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "scumm/scumm_v7.h"
24 #include "scumm/smush/smush_player.h"
25 #include "scumm/insane/insane.h"
26
27 namespace Scumm {
28
procIACT(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 par1,int16 par2,int16 par3,int16 par4)29 void Insane::procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12,
30 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
31 int16 par1, int16 par2, int16 par3, int16 par4) {
32 if (_keyboardDisable)
33 return;
34
35 switch (_currSceneId) {
36 case 1:
37 iactScene1(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags, par1, par2, par3, par4);
38 break;
39 case 3:
40 case 13:
41 iactScene3(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags, par1, par2, par3, par4);
42 break;
43 case 4:
44 case 5:
45 iactScene4(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags, par1, par2, par3, par4);
46 break;
47 case 6:
48 iactScene6(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags, par1, par2, par3, par4);
49 break;
50 case 17:
51 iactScene17(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags, par1, par2, par3, par4);
52 break;
53 case 21:
54 iactScene21(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags, par1, par2, par3, par4);
55 break;
56 default:
57 break;
58 }
59 }
60
iactScene1(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 par1,int16 par2,int16 par3,int16 par4)61 void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
62 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
63 int16 par1, int16 par2, int16 par3, int16 par4) {
64 int16 par5, par6, par7, par9, par11, par13;
65
66 switch (par1) {
67 case 2: // PATCH
68 if (par3 != 1)
69 break;
70
71 par5 = b.readUint16LE(); // si
72 if (_actor[0].field_8 == 112) {
73 setBit(par5);
74 break;
75 }
76
77 if (_approachAnim == -1) {
78 chooseEnemy(); //PATCH
79 _approachAnim = _enemy[_currEnemy].apprAnim;
80 }
81
82 if (_approachAnim == par4)
83 clearBit(par5);
84 else
85 setBit(par5);
86 break;
87 case 3:
88 if (par3 == 1) {
89 setBit(b.readUint16LE());
90 _approachAnim = -1;
91 }
92 break;
93 case 4:
94 if (par3 == 1 && (_approachAnim < 0 || _approachAnim > 4))
95 setBit(b.readUint16LE());
96 break;
97 case 5:
98 if (par2 != 13)
99 break;
100
101 b.readUint16LE(); // +8
102 b.readUint16LE(); // +10
103 par7 = b.readUint16LE(); // +12 dx
104 b.readUint16LE(); // +14
105 par9 = b.readUint16LE(); // +16 bx
106 b.readUint16LE(); // +18
107 par11 = b.readUint16LE(); // +20 cx
108 b.readUint16LE(); // +22
109 par13 = b.readUint16LE(); // +24 ax
110
111 if (par13 > _actor[0].x || par11 < _actor[0].x) {
112 _tiresRustle = true;
113 _actor[0].x1 = -_actor[0].x1;
114 _actor[0].damage++; // PATCH
115 }
116
117 if (par9 < _actor[0].x || par7 > _actor[0].x) {
118 _tiresRustle = true;
119 _actor[0].damage += 4; // PATCH
120 }
121 break;
122 case 6:
123 switch (par2) {
124 case 38:
125 smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
126 _smush_iconsNut, 7, 0, 0);
127 _roadBranch = true;
128 _iactSceneId = par4;
129 break;
130 case 25:
131 _roadBumps = true;
132 _actor[0].y1 = -_actor[0].y1;
133 break;
134 case 11:
135 if (_approachAnim >= 1 && _approachAnim <= 4 && !_needSceneSwitch)
136 queueSceneSwitch(13, _smush_minefiteFlu, "minefite.san", 64, 0,
137 _continueFrame1, 1300);
138 break;
139 case 9:
140 par5 = b.readUint16LE(); // si
141 par6 = b.readUint16LE(); // bx
142 smlayer_setFluPalette(_smush_roadrsh3Rip, 0);
143 if (par5 == par6 - 1)
144 smlayer_setFluPalette(_smush_roadrashRip, 0);
145 break;
146 default:
147 break;
148 }
149 break;
150 case 7:
151 switch (par4) {
152 case 1:
153 _actor[0].x -= (b.readUint16LE() - 160) / 10;
154 break;
155 case 2:
156 par5 = b.readUint16LE();
157
158 if (par5 - 8 > _actor[0].x || par5 + 8 < _actor[0].x) {
159 if (smlayer_isSoundRunning(86))
160 smlayer_stopSound(86);
161 } else {
162 if (!smlayer_isSoundRunning(86))
163 smlayer_startSfx(86);
164 }
165 break;
166 default:
167 break;
168 }
169 break;
170 default:
171 break;
172 }
173
174 if (_approachAnim < 0 || _approachAnim > 4)
175 if (readArray(8)) {
176 smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-18, 3,
177 _smush_iconsNut, 20, 0, 0);
178 _benHasGoggles = true;
179 }
180 }
181
chooseEnemy()182 void Insane::chooseEnemy() {
183 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) {
184 _currEnemy = EN_ROTT1;
185 return;
186 }
187
188 if (readArray(58) != 0)
189 _enemy[EN_TORQUE].isEmpty = 1;
190
191 if (_enemy[EN_TORQUE].occurences == 0) {
192 _currEnemy = EN_TORQUE;
193 _metEnemiesListTail++;
194 _metEnemiesList[_metEnemiesListTail] = EN_TORQUE;
195 return;
196 }
197
198 removeEmptyEnemies();
199
200 int32 count, i, j, en, en2;
201 bool notfound;
202
203 en = 0;
204 for (i = 0; i < 9; i++)
205 if (_enemy[i].isEmpty == 0)
206 ++en;
207
208 en -= 4;
209 assert(en >= 0);
210
211 count = 0;
212 while (1) {
213 count++;
214 if (count < 14) {
215 en2 = _vm->_rnd.getRandomNumber(10);
216 if (en2 == 9)
217 en2 = 6;
218 else if (en2 > 9)
219 en2 = 7;
220
221 notfound = true;
222
223 if (_enemy[en2].isEmpty != 0)
224 continue;
225
226 if (0 < _metEnemiesListTail) {
227 i = 0;
228 do {
229 if (en2 == _metEnemiesList[i + 1])
230 notfound = false;
231 i++;
232 } while (i < _metEnemiesListTail && notfound);
233 }
234 if (!notfound) {
235 continue;
236 }
237 } else {
238 j = 0;
239 do {
240 notfound = true;
241 en2 = j;
242 if (0 < _metEnemiesListTail) {
243 i = 0;
244 do {
245 if (en2 == _metEnemiesList[i + 1])
246 notfound = false;
247 i++;
248 } while (i < _metEnemiesListTail && notfound);
249 }
250 j++;
251 } while (j < 9 && !notfound);
252 if (!notfound) {
253 _metEnemiesListTail = 0;
254 count = 0;
255 continue;
256 }
257 }
258
259 ++_metEnemiesListTail;
260 assert(_metEnemiesListTail < ARRAYSIZE(_metEnemiesList));
261 _metEnemiesList[_metEnemiesListTail] = en2;
262
263 if (_metEnemiesListTail >= en) {
264 removeEnemyFromMetList(0);
265 }
266
267 if (notfound)
268 break;
269 }
270
271 _currEnemy = en2;
272 }
273
removeEmptyEnemies()274 void Insane::removeEmptyEnemies() {
275 if (_metEnemiesListTail > 0) {
276 for (int i = 0; i < _metEnemiesListTail; i++)
277 if (_enemy[i].isEmpty == 1)
278 removeEnemyFromMetList(i);
279 }
280 }
281
removeEnemyFromMetList(int32 enemy1)282 void Insane::removeEnemyFromMetList(int32 enemy1) {
283 if (enemy1 >= _metEnemiesListTail)
284 return;
285
286 int en = enemy1;
287 do {
288 ++en;
289 assert(en + 1 < ARRAYSIZE(_metEnemiesList));
290 _metEnemiesList[en] = _metEnemiesList[en + 1];
291 } while (en < _metEnemiesListTail);
292 _metEnemiesListTail--;
293 }
294
iactScene3(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 command,int16 par1,int16,int16)295 void Insane::iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
296 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
297 int16 command, int16 par1, int16, int16) {
298 int par2, par3;
299 if (command == 6) {
300 if (par1 == 9) {
301 par2 = b.readUint16LE(); // ptr + 8
302 par3 = b.readUint16LE(); // ptr + 10
303
304 if (!par2)
305 smlayer_setFluPalette(_smush_roadrsh3Rip, 0);
306 else {
307 if (par2 == par3 - 1)
308 smlayer_setFluPalette(_smush_roadrashRip, 0);
309 }
310 } else if (par1 == 25) {
311 _roadBumps = true;
312 _actor[0].y1 = -_actor[0].y1;
313 _actor[1].y1 = -_actor[1].y1;
314 }
315 }
316 }
317
iactScene4(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 par1,int16 par2,int16 par3,int16 par4)318 void Insane::iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
319 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
320 int16 par1, int16 par2, int16 par3, int16 par4) {
321 int16 par5;
322
323 switch (par1) {
324 case 2:
325 case 4:
326 par5 = b.readUint16LE(); // si
327 switch (par3) {
328 case 1:
329 if (par4 == 1) {
330 if (readArray(6))
331 setBit(par5);
332 else
333 clearBit(par5);
334 } else {
335 if (readArray(6))
336 clearBit(par5);
337 else
338 setBit(par5);
339 }
340 break;
341 case 2:
342 if (readArray(5))
343 clearBit(par5);
344 else
345 setBit(par5);
346 break;
347 default:
348 break;
349 }
350 break;
351 case 6:
352 switch (par2) {
353 case 38:
354
355 smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-13, 3,
356 _smush_icons2Nut, 10, 0, 0);
357 _roadBranch = true;
358 _iactSceneId = par4;
359 break;
360 case 7:
361 if (readArray(4) != 0)
362 return;
363
364 smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, // QW
365 _smush_icons2Nut, 8, 0, 0);
366 _roadStop = true;
367 break;
368 case 8:
369 if (readArray(4) == 0 || readArray(6) == 0)
370 return;
371
372 writeArray(1, _posBrokenTruck);
373 writeArray(3, _val57d);
374 smush_setToFinish();
375
376 break;
377 case 25:
378 if (readArray(5) == 0)
379 return;
380
381 _carIsBroken = true;
382 smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, // QW
383 _smush_icons2Nut, 8, 0, 0);
384 break;
385 case 11:
386 smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
387 _smush_icons2Nut, 9, 0, 0);
388 _roadBranch = true;
389 _iactSceneId = par4;
390 break;
391 default:
392 break;
393 }
394 break;
395 default:
396 break;
397 }
398 }
399
iactScene6(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 par1,int16 par2,int16 par3,int16 par4)400 void Insane::iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
401 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
402 int16 par1, int16 par2, int16 par3, int16 par4) {
403 int16 par5;
404
405 switch (par1) {
406 case 7:
407 par5 = b.readUint16LE();
408 if (par4 != 3)
409 break;
410
411 if (par5 >= _actor[0].x)
412 break;
413
414 _actor[0].x = par5;
415 break;
416 case 2:
417 case 4:
418 par5 = b.readUint16LE();
419 switch (par3) {
420 case 1:
421 if (par4 == 1) {
422 if (readArray(6))
423 setBit(par5);
424 else
425 clearBit(par5);
426 } else {
427 if (readArray(6))
428 clearBit(par5);
429 else
430 setBit(par5);
431 }
432 break;
433 case 2:
434 if (readArray(5))
435 clearBit(par5);
436 else
437 setBit(par5);
438 break;
439 default:
440 break;
441 }
442 break;
443 case 6:
444 switch (par2) {
445 case 38:
446 smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-13, 3,
447 _smush_icons2Nut, 10, 0, 0);
448 _roadBranch = true;
449 _iactSceneId = par4;
450 break;
451 case 7:
452 if (readArray(4) != 0)
453 return;
454
455 _roadStop = true;
456 smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, //QW
457 _smush_icons2Nut, 8, 0, 0);
458 break;
459 case 8:
460 if (readArray(4) == 0 || readArray(6) == 0)
461 return;
462
463 writeArray(1, _posBrokenTruck);
464 writeArray(3, _posVista);
465 smush_setToFinish();
466
467 break;
468 case 25:
469 if (readArray(5) == 0)
470 return;
471
472 _carIsBroken = true;
473 smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, //QW
474 _smush_icons2Nut, 8, 0, 0);
475 break;
476 case 11:
477 smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
478 _smush_icons2Nut, 9, 0, 0);
479 _roadBranch = true;
480 _iactSceneId = par4;
481 break;
482 default:
483 break;
484 }
485 break;
486 default:
487 break;
488 }
489 }
490
iactScene17(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 par1,int16 par2,int16 par3,int16 par4)491 void Insane::iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
492 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
493 int16 par1, int16 par2, int16 par3, int16 par4) {
494 switch (par1) {
495 case 2:
496 case 3:
497 case 4:
498 if (par3 == 1) {
499 setBit(b.readUint16LE());
500 _approachAnim = -1;
501 }
502 break;
503 case 6:
504 switch (par2) {
505 case 38:
506 smlayer_drawSomething(renderBitmap, codecparam, 28, 48, 1,
507 _smush_iconsNut, 6, 0, 0);
508 _roadBranch = true;
509 _iactSceneId = par4;
510 if (_counter1 <= 4) {
511 if (_counter1 == 4)
512 smlayer_startSfx(94);
513
514 smlayer_showStatusMsg(-1, renderBitmap, codecparam, 24, 167, 1,
515 2, 0, "%s", handleTrsTag(5000));
516 }
517 _objectDetected = true;
518 break;
519 case 10:
520 smlayer_drawSomething(renderBitmap, codecparam, 28, 48, 1,
521 _smush_iconsNut, 6, 0, 0);
522 if (_counter1 <= 4) {
523 if (_counter1 == 4)
524 smlayer_startSfx(94);
525
526 smlayer_showStatusMsg(-1, renderBitmap, codecparam, 24, 167, 1,
527 2, 0, "%s", handleTrsTag(5001));
528 }
529 _objectDetected = true;
530 _mineCaveIsNear = true;
531 break;
532 default:
533 break;
534 }
535 break;
536 default:
537 break;
538 }
539 }
540
iactScene21(byte * renderBitmap,int32 codecparam,int32 setupsan12,int32 setupsan13,Common::SeekableReadStream & b,int32 size,int32 flags,int16 par1,int16 par2,int16 par3,int16 par4)541 void Insane::iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12,
542 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
543 int16 par1, int16 par2, int16 par3, int16 par4) {
544 // void implementation
545 }
546
547 }
548