aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/insane/insane_iact.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/insane/insane_iact.cpp')
-rw-r--r--engines/scumm/insane/insane_iact.cpp558
1 files changed, 558 insertions, 0 deletions
diff --git a/engines/scumm/insane/insane_iact.cpp b/engines/scumm/insane/insane_iact.cpp
new file mode 100644
index 0000000000..c706c7d191
--- /dev/null
+++ b/engines/scumm/insane/insane_iact.cpp
@@ -0,0 +1,558 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "base/engine.h"
+
+#include "scumm/scumm.h"
+
+#include "scumm/smush/smush_player.h"
+#include "scumm/smush/chunk_type.h"
+#include "scumm/smush/chunk.h"
+
+#include "scumm/insane/insane.h"
+
+namespace Scumm {
+
+void Insane::procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ if (_keyboardDisable)
+ return;
+
+ switch (_currSceneId) {
+ case 1:
+ iactScene1(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
+ break;
+ case 3:
+ case 13:
+ iactScene3(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
+ break;
+ case 4:
+ case 5:
+ iactScene4(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
+ break;
+ case 6:
+ iactScene6(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
+ break;
+ case 17:
+ iactScene17(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
+ break;
+ case 21:
+ iactScene21(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
+ break;
+ }
+}
+
+void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ _player->checkBlock(b, TYPE_IACT, 8);
+
+ int16 par1, par2, par3, par4, par5, par6, par7, par9, par11, par13, tmp;
+
+ par1 = b.getWord(); // cx
+ par2 = b.getWord(); // dx
+ par3 = b.getWord(); // si
+ par4 = b.getWord(); // bx
+
+ switch (par1) {
+ case 2: // PATCH
+ if (par3 != 1)
+ break;
+
+ par5 = b.getWord(); // si
+ if (_actor[0].field_8 == 112) {
+ setBit(par5);
+ break;
+ }
+
+ if (_approachAnim == -1) {
+ chooseEnemy(); //PATCH
+ _approachAnim = _enemy[_currEnemy].apprAnim;
+ }
+
+ if (_approachAnim == par4)
+ clearBit(par5);
+ else
+ setBit(par5);
+ break;
+ case 3:
+ if (par3 == 1) {
+ setBit(b.getWord());
+ _approachAnim = -1;
+ }
+ break;
+ case 4:
+ if (par3 == 1 && (_approachAnim < 0 || _approachAnim > 4))
+ setBit(b.getWord());
+ break;
+ case 5:
+ if (par2 != 13)
+ break;
+
+ tmp = b.getWord(); // +8
+ tmp = b.getWord(); // +10
+ par7 = b.getWord(); // +12 dx
+ tmp = b.getWord(); // +14
+ par9 = b.getWord(); // +16 bx
+ tmp = b.getWord(); // +18
+ par11 = b.getWord(); // +20 cx
+ tmp = b.getWord(); // +22
+ par13 = b.getWord(); // +24 ax
+
+ if (par13 > _actor[0].x || par11 < _actor[0].x) {
+ _tiresRustle = true;
+ _actor[0].x1 = -_actor[0].x1;
+ _actor[0].damage++; // PATCH
+ }
+
+ if (par9 < _actor[0].x || par7 > _actor[0].x) {
+ _tiresRustle = true;
+ _actor[0].damage += 4; // PATCH
+ }
+ break;
+ case 6:
+ switch (par2) {
+ case 38:
+ smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
+ _smush_iconsNut, 7, 0, 0);
+ _roadBranch = true;
+ _iactSceneId = par4;
+ break;
+ case 25:
+ _roadBumps = true;
+ _actor[0].y1 = -_actor[0].y1;
+ break;
+ case 11:
+ if (_approachAnim >= 1 && _approachAnim <= 4 && !_needSceneSwitch)
+ queueSceneSwitch(13, _smush_minefiteFlu, "minefite.san", 64, 0,
+ _continueFrame1, 1300);
+ break;
+ case 9:
+ par5 = b.getWord(); // si
+ par6 = b.getWord(); // bx
+ smlayer_setFluPalette(_smush_roadrsh3Rip, 0);
+ if (par5 == par6 - 1)
+ smlayer_setFluPalette(_smush_roadrashRip, 0);
+ }
+ break;
+ case 7:
+ switch (par4) {
+ case 1:
+ _actor[0].x -= (b.getWord() - 160) / 10;
+ break;
+ case 2:
+ par5 = b.getWord();
+
+ if (par5 - 8 > _actor[0].x || par5 + 8 < _actor[0].x) {
+ if (smlayer_isSoundRunning(86))
+ smlayer_stopSound(86);
+ } else {
+ if (!smlayer_isSoundRunning(86))
+ smlayer_startSfx(86);
+ }
+ break;
+ }
+ break;
+ }
+
+ if (_approachAnim < 0 || _approachAnim > 4)
+ if (readArray(8)) {
+ smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-18, 3,
+ _smush_iconsNut, 20, 0, 0);
+ _benHasGoggles = true;
+ }
+}
+
+void Insane::chooseEnemy(void) {
+ if (readArray(58) != 0)
+ _enemy[EN_TORQUE].isEmpty = 1;
+
+ if (_enemy[EN_TORQUE].occurences == 0) {
+ _currEnemy = EN_TORQUE;
+ _metEnemiesListTail++;
+ _metEnemiesList[_metEnemiesListTail] = EN_TORQUE;
+ return;
+ }
+
+ removeEmptyEnemies();
+
+ int32 count, i, j, en, en2;
+ bool notfound;
+
+ en = 0;
+ for (i = 0; i < 9; i++)
+ if (_enemy[i].isEmpty == 0)
+ ++en;
+
+ en -= 4;
+ assert(en >= 0);
+
+ count = 0;
+ while (1) {
+ count++;
+ if (count < 14) {
+ en2 = _vm->_rnd.getRandomNumber(10);
+ if (en2 == 9)
+ en2 = 6;
+ else if (en2 > 9)
+ en2 = 7;
+
+ notfound = true;
+
+ if (_enemy[en2].isEmpty != 0)
+ continue;
+
+ if (0 < _metEnemiesListTail) {
+ i = 0;
+ do {
+ if (en2 == _metEnemiesList[i + 1])
+ notfound = false;
+ i++;
+ } while (i < _metEnemiesListTail && notfound);
+ }
+ if (!notfound) {
+ continue;
+ }
+ } else {
+ j = 0;
+ do {
+ notfound = true;
+ en2 = j;
+ if (0 < _metEnemiesListTail) {
+ i = 0;
+ do {
+ if (en2 == _metEnemiesList[i + 1])
+ notfound = false;
+ i++;
+ } while (i < _metEnemiesListTail && notfound);
+ }
+ j++;
+ } while (j < 9 && !notfound);
+ if (!notfound) {
+ _metEnemiesListTail = 0;
+ count = 0;
+ continue;
+ }
+ }
+
+ ++_metEnemiesListTail;
+ assert(_metEnemiesListTail < ARRAYSIZE(_metEnemiesList));
+ _metEnemiesList[_metEnemiesListTail] = en2;
+
+ if (_metEnemiesListTail >= en) {
+ removeEnemyFromMetList(0);
+ }
+
+ if (notfound)
+ break;
+ }
+
+ _currEnemy = en2;
+}
+
+void Insane::removeEmptyEnemies(void) {
+ if (_metEnemiesListTail > 0) {
+ for (int i = 0; i < _metEnemiesListTail; i++)
+ if (_enemy[i].isEmpty == 1)
+ removeEnemyFromMetList(i);
+ }
+}
+
+void Insane::removeEnemyFromMetList(int32 enemy1) {
+ if (enemy1 >= _metEnemiesListTail)
+ return;
+
+ int en = enemy1;
+ do {
+ ++en;
+ assert(en + 1 < ARRAYSIZE(_metEnemiesList));
+ _metEnemiesList[en] = _metEnemiesList[en + 1];
+ } while (en < _metEnemiesListTail);
+ _metEnemiesListTail--;
+}
+
+void Insane::iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ _player->checkBlock(b, TYPE_IACT, 8);
+
+ int command, par1, par2, par3, tmp;
+ command = b.getWord();
+ par1 = b.getWord();
+ if (command == 6) {
+ if (par1 == 9) {
+ tmp = b.getWord(); // ptr + 4
+ tmp = b.getWord(); // ptr + 6
+ par2 = b.getWord(); // ptr + 8
+ par3 = b.getWord(); // ptr + 10
+
+ if (!par2)
+ smlayer_setFluPalette(_smush_roadrsh3Rip, 0);
+ else {
+ if (par2 == par3 - 1)
+ smlayer_setFluPalette(_smush_roadrashRip, 0);
+ }
+ } else if (par1 == 25) {
+ _roadBumps = true;
+ _actor[0].y1 = -_actor[0].y1;
+ _actor[1].y1 = -_actor[1].y1;
+ }
+ }
+}
+
+void Insane::iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ _player->checkBlock(b, TYPE_IACT, 8);
+
+ if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
+ return;
+
+ int16 par1, par2, par3, par4, par5;
+
+ par1 = b.getWord(); // edx
+ par2 = b.getWord(); // bx
+ par3 = b.getWord();
+ par4 = b.getWord(); // cx
+
+ switch (par1) {
+ case 2:
+ case 4:
+ par5 = b.getWord(); // si
+ switch (par3) {
+ case 1:
+ if (par4 == 1) {
+ if (readArray(6))
+ setBit(par5);
+ else
+ clearBit(par5);
+ } else {
+ if (readArray(6))
+ clearBit(par5);
+ else
+ setBit(par5);
+ }
+ break;
+ case 2:
+ if (readArray(5))
+ clearBit(par5);
+ else
+ setBit(par5);
+ break;
+ }
+ break;
+ case 6:
+ switch (par2) {
+ case 38:
+
+ smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-13, 3,
+ _smush_icons2Nut, 10, 0, 0);
+ _roadBranch = true;
+ _iactSceneId = par4;
+ break;
+ case 7:
+ if (readArray(4) != 0)
+ return;
+
+ smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, // QW
+ _smush_icons2Nut, 8, 0, 0);
+ _roadStop = true;
+ break;
+ case 8:
+ if (readArray(4) == 0 || readArray(6) == 0)
+ return;
+
+ writeArray(1, _posBrokenTruck);
+ writeArray(3, _val57d);
+ smush_setToFinish();
+
+ break;
+ case 25:
+ if (readArray(5) == 0)
+ return;
+
+ _carIsBroken = true;
+ smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, // QW
+ _smush_icons2Nut, 8, 0, 0);
+ break;
+ case 11:
+ smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
+ _smush_icons2Nut, 9, 0, 0);
+ _roadBranch = true;
+ _iactSceneId = par4;
+ break;
+ }
+ break;
+ }
+}
+
+void Insane::iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ _player->checkBlock(b, TYPE_IACT, 8);
+
+ int16 par1, par2, par3, par4, par5;
+
+ par1 = b.getWord();
+ par2 = b.getWord(); // bx
+ par3 = b.getWord();
+ par4 = b.getWord();
+
+ switch (par1) {
+ case 7:
+ par5 = b.getWord();
+ if (par4 != 3)
+ break;
+
+ if (par5 >= _actor[0].x)
+ break;
+
+ _actor[0].x = par5;
+ break;
+ case 2:
+ case 4:
+ par5 = b.getWord();
+ switch (par3) {
+ case 1:
+ if (par4 == 1) {
+ if (readArray(6))
+ setBit(par5);
+ else
+ clearBit(par5);
+ } else {
+ if (readArray(6))
+ clearBit(par5);
+ else
+ setBit(par5);
+ }
+ break;
+ case 2:
+ if (readArray(5))
+ clearBit(par5);
+ else
+ setBit(par5);
+ break;
+ }
+ break;
+ case 6:
+ switch (par2) {
+ case 38:
+ smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-13, 3,
+ _smush_icons2Nut, 10, 0, 0);
+ _roadBranch = true;
+ _iactSceneId = par4;
+ break;
+ case 7:
+ if (readArray(4) != 0)
+ return;
+
+ _roadStop = true;
+ smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, //QW
+ _smush_icons2Nut, 8, 0, 0);
+ break;
+ case 8:
+ if (readArray(4) == 0 || readArray(6) == 0)
+ return;
+
+ writeArray(1, _posBrokenTruck);
+ writeArray(3, _posVista);
+ smush_setToFinish();
+
+ break;
+ case 25:
+ if (readArray(5) == 0)
+ return;
+
+ _carIsBroken = true;
+ smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, //QW
+ _smush_icons2Nut, 8, 0, 0);
+ break;
+ case 11:
+ smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
+ _smush_icons2Nut, 9, 0, 0);
+ _roadBranch = true;
+ _iactSceneId = par4;
+ break;
+ }
+ break;
+ }
+}
+
+void Insane::iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ _player->checkBlock(b, TYPE_IACT, 8);
+ int16 par1, par2, par3, par4;
+
+ par1 = b.getWord(); // dx
+ par2 = b.getWord(); // cx
+ par3 = b.getWord(); // di
+ par4 = b.getWord();
+
+ switch (par1) {
+ case 2:
+ case 3:
+ case 4:
+ if (par3 == 1) {
+ setBit(b.getWord());
+ _approachAnim = -1;
+ }
+ break;
+ case 6:
+ switch (par2) {
+ case 38:
+ smlayer_drawSomething(renderBitmap, codecparam, 28, 48, 1,
+ _smush_iconsNut, 6, 0, 0);
+ _roadBranch = true;
+ _iactSceneId = par4;
+ if (_counter1 <= 4) {
+ if (_counter1 == 4)
+ smlayer_startSfx(94);
+
+ smlayer_showStatusMsg(-1, renderBitmap, codecparam, 24, 167, 1,
+ 2, 0, "%s", handleTrsTag(5000));
+ }
+ _objectDetected = true;
+ break;
+ case 10:
+ smlayer_drawSomething(renderBitmap, codecparam, 28, 48, 1,
+ _smush_iconsNut, 6, 0, 0);
+ if (_counter1 <= 4) {
+ if (_counter1 == 4)
+ smlayer_startSfx(94);
+
+ smlayer_showStatusMsg(-1, renderBitmap, codecparam, 24, 167, 1,
+ 2, 0, "%s", handleTrsTag(5001));
+ }
+ _objectDetected = true;
+ _mineCaveIsNear = true;
+ break;
+ }
+ break;
+ }
+}
+
+void Insane::iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12,
+ int32 setupsan13, Chunk &b, int32 size, int32 flags) {
+ // void implementation
+}
+
+}
+