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
24
25 #include "engines/engine.h"
26
27 #include "common/system.h"
28
29 #include "scumm/actor.h"
30 #include "scumm/file.h"
31 #include "scumm/resource.h"
32 #include "scumm/scumm_v7.h"
33 #include "scumm/sound.h"
34
35 #include "scumm/imuse/imuse.h"
36 #include "scumm/imuse_digi/dimuse.h"
37
38 #include "scumm/smush/smush_player.h"
39 #include "scumm/smush/smush_font.h"
40
41 #include "scumm/insane/insane.h"
42
43 // TODO (in no particular order):
44 // o Code review/cleanup
45
46 namespace Scumm {
47
48 static const int actorAnimationData[21] = {20, 21, 22, 23, 24, 25, 26, 13, 14, 15, 16, 17,
49 18, 19, 6, 7, 8, 9, 10, 11, 12};
50
51
Insane(ScummEngine_v7 * scumm)52 Insane::Insane(ScummEngine_v7 *scumm) {
53 _vm = scumm;
54
55 initvars();
56
57 if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) {
58 readFileToMem("roadrash.rip", &_smush_roadrashRip);
59 readFileToMem("roadrsh2.rip", &_smush_roadrsh2Rip);
60 readFileToMem("roadrsh3.rip", &_smush_roadrsh3Rip);
61 readFileToMem("goglpalt.rip", &_smush_goglpaltRip);
62 readFileToMem("tovista1.flu", &_smush_tovista1Flu);
63 readFileToMem("tovista2.flu", &_smush_tovista2Flu);
64 readFileToMem("toranch.flu", &_smush_toranchFlu);
65 readFileToMem("minedriv.flu", &_smush_minedrivFlu);
66 readFileToMem("minefite.flu", &_smush_minefiteFlu);
67 _smush_bensgoggNut = new NutRenderer(_vm, "bensgogg.nut");
68 _smush_bencutNut = new NutRenderer(_vm, "bencut.nut");
69 } else {
70 _smush_roadrashRip = NULL;
71 _smush_roadrsh2Rip = NULL;
72 _smush_roadrsh3Rip = NULL;
73 _smush_goglpaltRip = NULL;
74 _smush_tovista1Flu = NULL;
75 _smush_tovista2Flu = NULL;
76 _smush_toranchFlu = NULL;
77 _smush_minedrivFlu = NULL;
78 _smush_minefiteFlu = NULL;
79 _smush_bensgoggNut = NULL;
80 _smush_bencutNut = NULL;
81 }
82
83 _smush_iconsNut = new NutRenderer(_vm, "icons.nut");
84 _smush_icons2Nut = new NutRenderer(_vm, "icons2.nut");
85 }
86
~Insane()87 Insane::~Insane() {
88 free(_smush_roadrashRip);
89 free(_smush_roadrsh2Rip);
90 free(_smush_roadrsh3Rip);
91 free(_smush_goglpaltRip);
92 free(_smush_tovista1Flu);
93 free(_smush_tovista2Flu);
94 free(_smush_toranchFlu);
95 free(_smush_minedrivFlu);
96 free(_smush_minefiteFlu);
97
98 delete _smush_bencutNut;
99 delete _smush_bensgoggNut;
100 delete _smush_iconsNut;
101 delete _smush_icons2Nut;
102 }
103
setSmushParams(int speed)104 void Insane::setSmushParams(int speed) {
105 _speed = speed;
106 }
107
initvars()108 void Insane::initvars() {
109 int i, j;
110
111 _speed = 12;
112 _insaneIsRunning = false;
113
114 _numberArray = 0;
115 _emulateInterrupt = 0;
116 _flag1d = 0;
117 _objArray1Idx = 0;
118 _objArray1Idx2 = 0;
119 _objArray2Idx = 0;
120 _objArray2Idx2 = 0;
121 _currSceneId = 1;
122 _timer6Id = 0;
123 _timerSpriteId = 0;
124 _temp2SceneId = 0;
125 _tempSceneId = 0;
126 _currEnemy = -1;
127 _currScenePropIdx = 0;
128 _currScenePropSubIdx = 0;
129 _currTrsMsg = 0;
130 _sceneData2Loaded = 0;
131 _sceneData1Loaded = 0;
132 _keyboardDisable = 0;
133 _needSceneSwitch = false;
134 _idx2Exceeded = 0;
135 _tiresRustle = false;
136 _keybOldDx = 0;
137 _keybOldDy = 0;
138 _velocityX = 0;
139 _velocityY = 0;
140 _keybX = 0;
141 _keybY = 0;
142 _firstBattle = false;
143 _battleScene = true;
144 _kickBenProgress = false;
145 _weaponBenJustSwitched = false;
146 _kickEnemyProgress = false;
147 _weaponEnemyJustSwitched = false;
148 _beenCheated = 0;
149 _posBrokenTruck = 0;
150 _posBrokenCar = 0;
151 _posFatherTorque = 0;
152 _posCave = 0;
153 _posVista = 0;
154 _roadBranch = false;
155 _roadStop = false;
156 _carIsBroken = false;
157 _benHasGoggles = false;
158 _mineCaveIsNear = false;
159 _objectDetected = false;
160 _approachAnim = -1;
161 _val54d = 0;
162 _val57d = 0;
163 _val115_ = false;
164 _roadBumps = false;
165 _val211d = 0;
166 _val213d = 0;
167 _metEnemiesListTail = 0;
168 _smlayer_room = 0;
169 _smlayer_room2 = 0;
170 _isBenCut = 0;
171 _continueFrame = 0;
172 _continueFrame1 = 0;
173 _counter1 = 0;
174 _iactSceneId = 0;
175 _iactSceneId2 = 0;
176
177 for (i = 0; i < 12; i++)
178 _metEnemiesList[i] = 0;
179
180 for (i = 0; i < 9; i++)
181 for (j = 0; j < 9; j++)
182 _enHdlVar[i][j] = 0;
183
184 for (i = 0; i < 0x80; i++)
185 _iactBits[i] = 0;
186
187
188 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) {
189 init_enemyStruct(EN_ROTT1, EN_ROTT1, 0, 0, 60, 0, INV_MACE, 63, "endcrshr.san",
190 25, 15, 16, 26, 13, 3);
191 } else {
192 init_enemyStruct(EN_ROTT1, EN_ROTT1, 0, 0, 160, 0, INV_MACE, 90, "wr2_rott.san",
193 26, 16, 17, 27, 11, 3);
194 }
195
196 init_enemyStruct(EN_ROTT2, EN_ROTT2, 1, 0, 250, 0, INV_2X4, 90, "wr2_rott.san",
197 28, 16, 17, 42, 11, 3);
198 init_enemyStruct(EN_ROTT3, EN_ROTT3, 2, 0, 120, 0, INV_HAND, 90, "wr2_rott.san",
199 15, 16, 17, 43, 11, 3);
200 init_enemyStruct(EN_VULTF1, EN_VULTF1, 3, 0, 60, 0, INV_HAND, 91, "wr2_vltp.san",
201 29, 33, 32, 37, 12, 4);
202 init_enemyStruct(EN_VULTM1, EN_VULTM1, 4, 0, 100, 0, INV_CHAIN, 91, "wr2_vltc.san",
203 30, 33, 32, 36, 12, 4);
204 init_enemyStruct(EN_VULTF2, EN_VULTF2, 5, 0, 250, 0, INV_CHAINSAW, 91, "wr2_vlts.san",
205 31, 33, 32, 35, 12, 4);
206 init_enemyStruct(EN_VULTM2, EN_VULTM2, 6, 0, 900, 0, INV_BOOT, 91, "wr2_rott.san",
207 34, 33, 32, 45, 16, 4);
208 init_enemyStruct(EN_CAVEFISH, EN_CAVEFISH, 7, 0, 60, 0, INV_DUST, 92, "wr2_cave.san",
209 39, 0, 0, 41, 13, 2);
210 init_enemyStruct(EN_TORQUE, EN_TORQUE, 8, 0, 900, 0, INV_HAND, 93, "wr2_vltp.san",
211 57, 0, 0, 37, 12, 1);
212
213 init_fluConfStruct(1, 1, &_smush_minedrivFlu, "minedriv.san", 235, 1300);
214 init_fluConfStruct(2, 1, &_smush_minedrivFlu, "minedriv.san", 355, 1300);
215 init_fluConfStruct(3, 1, &_smush_minedrivFlu, "minedriv.san", 1255, 1300);
216 init_fluConfStruct(4, 1, &_smush_minedrivFlu, "minedriv.san", 565, 1300);
217 init_fluConfStruct(5, 1, &_smush_minedrivFlu, "minedriv.san", 1040, 1300);
218 init_fluConfStruct(8, 1, &_smush_minedrivFlu, "minedriv.san", 1040, 1300);
219 init_fluConfStruct(9, 1, &_smush_minedrivFlu, "minedriv.san", 655, 1300);
220 init_fluConfStruct(10, 1, &_smush_minedrivFlu, "minedriv.san", 115, 1300);
221 init_fluConfStruct(11, 1, &_smush_minedrivFlu, "minedriv.san", 315, 1300);
222 init_fluConfStruct(12, 1, &_smush_minedrivFlu, "minedriv.san", 235, 1300);
223 init_fluConfStruct(15, 6, &_smush_toranchFlu, "toranch.san", 115, 530);
224 init_fluConfStruct(16, 5, &_smush_tovista2Flu, "tovista2.san", 235, 290);
225 init_fluConfStruct(17, 4, &_smush_tovista1Flu, "tovista1.san", 175, 230);
226 init_fluConfStruct(18, 4, &_smush_tovista1Flu, "tovista1.san", 175, 230);
227 init_fluConfStruct(19, 6, &_smush_toranchFlu, "toranch.san", 115, 530);
228 init_fluConfStruct(20, 6, &_smush_toranchFlu, "toranch.san", 115, 530);
229
230 init_scenePropStruct( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
231 init_scenePropStruct( 1, 0, 1, 128, 2001, 0, 0, 0, 0, 56, 2);
232 init_scenePropStruct( 2, 0, 0, 125, 1002, 0, 0, 0, 0, 35, 3);
233 init_scenePropStruct( 3, 0, 1, 129, 2002, 0, 0, 0, 0, 23, 4);
234 init_scenePropStruct( 4, 0, 1, 130, 2003, 0, 0, 0, 0, 40, 5);
235 init_scenePropStruct( 5, 0, 0, 126, 1005, 0, 0, 0, 0, 46, 6);
236 init_scenePropStruct( 6, 0, 1, 131, 2004, 0, 0, 0, 0, 39, 7);
237 init_scenePropStruct( 7, 0, 1, 132, 2005, 0, 0, 0, 0, 45, 8);
238 init_scenePropStruct( 8, 0, 1, 133, 2006, 0, 0, 0, 0, 14, 9);
239 init_scenePropStruct( 9, 0, 0, 127, 1009, 0, 0, 0, 0, 15, 10);
240 init_scenePropStruct( 10, 0, 1, 134, 501, 0, 0, 0, 0, 25, 11);
241 init_scenePropStruct( 11, 0, 1, 135, 502, 0, 0, 0, 0, 15, 0);
242 init_scenePropStruct( 12, 1, -1, 0, 0, 0xFF, 0xFF, 0xFF, 0, 0, 1);
243 init_scenePropStruct( 13, 1, 0, 291, 135, 0xFF, 0xFF, 0xFF, 0, 25, 0);
244 init_scenePropStruct( 14, 2, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
245 init_scenePropStruct( 15, 2, 1, 277, 17, 0xFC, 0, 0xFC, 0, 56, 2);
246 init_scenePropStruct( 16, 2, 0, 288, 18, 0xFF, 0xFF, 0xFF, 0, 56, 3);
247 init_scenePropStruct( 17, 2, 1, 278, 19, 0xFC, 0, 0xFC, 0, 56, 0);
248 init_scenePropStruct( 18, 3, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
249 init_scenePropStruct( 19, 3, 1, 282, 23, 0xFC, 0, 0xFC, 0, 56, 0);
250 init_scenePropStruct( 20, 4, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
251 init_scenePropStruct( 21, 4, 1, 283, 24, 0xFC, 0, 0xFC, 0, 56, 0);
252 init_scenePropStruct( 22, 5, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
253 init_scenePropStruct( 23, 5, 1, 284, 25, 0xFC, 0, 0xFC, 0, 56, 0);
254 init_scenePropStruct( 24, 6, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
255 init_scenePropStruct( 25, 6, 1, 285, 26, 0xFC, 0, 0xFC, 0, 56, 0);
256 init_scenePropStruct( 26, 7, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
257 init_scenePropStruct( 27, 7, 1, 286, 27, 0xFC, 0, 0xFC, 0, 56, 0);
258 init_scenePropStruct( 28, 8, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
259 init_scenePropStruct( 29, 8, 1, 287, 28, 0xFC, 0, 0xFC, 0, 56, 0);
260 init_scenePropStruct( 30, 9, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
261 init_scenePropStruct( 31, 9, 1, 261, 1, 0xFC, 0, 0, 0, 40, 2);
262 init_scenePropStruct( 32, 9, 1, 262, 2, 0xFC, 0, 0, 0, 40, 3);
263 init_scenePropStruct( 33, 9, 1, 263, 3, 0xFC, 0, 0, 0, 40, 0);
264 init_scenePropStruct( 34, 10, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
265 init_scenePropStruct( 35, 10, 1, 263, 3, 0xFC, 0, 0, 0, 30, 0);
266 init_scenePropStruct( 36, 11, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
267 init_scenePropStruct( 37, 11, 1, 264, 4, 0xFC, 0, 0, 0, 30, 0);
268 init_scenePropStruct( 38, 12, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
269 init_scenePropStruct( 39, 12, 1, 265, 5, 0xFC, 0, 0, 0, 30, 0);
270 init_scenePropStruct( 40, 13, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
271 init_scenePropStruct( 41, 13, 1, 266, 6, 0xFC, 0, 0, 0, 30, 0);
272 init_scenePropStruct( 42, 14, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
273 init_scenePropStruct( 43, 14, 1, 267, 7, 0xFC, 0, 0, 0, 30, 0);
274 init_scenePropStruct( 44, 15, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
275 init_scenePropStruct( 45, 15, 1, 268, 8, 0xFC, 0, 0, 0, 30, 0);
276 init_scenePropStruct( 46, 16, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
277 init_scenePropStruct( 47, 16, 1, 274, 14, 0xFC, 0, 0, 0, 30, 0);
278 init_scenePropStruct( 48, 17, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
279 init_scenePropStruct( 49, 17, 1, 270, 10, 0xFC, 0, 0, 0, 30, 0);
280 init_scenePropStruct( 50, 18, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
281 init_scenePropStruct( 51, 18, 0, 289, 45, 0xFF, 0xFF, 0xFF, 0, 40, 2);
282 init_scenePropStruct( 52, 18, 1, 177, 49, 0xFC, 0xFC, 0x54, 0, 40, 3);
283 init_scenePropStruct( 53, 18, 1, 178, 50, 0xFC, 0xFC, 0x54, 0, 40, 4);
284 init_scenePropStruct( 54, 18, 0, 290, 47, 0xFF, 0xFF, 0xFF, 0, 40, 0);
285 init_scenePropStruct( 55, 19, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
286 init_scenePropStruct( 56, 19, 1, 179, 51, 0xFC, 0xFC, 0x54, 0, 40, 0);
287 init_scenePropStruct( 57, 20, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
288 init_scenePropStruct( 58, 20, 1, 183, 55, 0xFC, 0xFC, 0x54, 0, 40, 0);
289 init_scenePropStruct( 59, 21, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
290 init_scenePropStruct( 60, 21, 1, 184, 56, 0xFC, 0xFC, 0x54, 0, 40, 0);
291 init_scenePropStruct( 61, 22, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
292 init_scenePropStruct( 62, 22, 1, 186, 58, 0xFC, 0xFC, 0x54, 0, 40, 0);
293 init_scenePropStruct( 63, 23, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
294 init_scenePropStruct( 64, 23, 1, 191, 63, 0xFC, 0xFC, 0x54, 0, 40, 0);
295 init_scenePropStruct( 65, 24, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
296 init_scenePropStruct( 66, 24, 1, 192, 64, 0xFC, 0xFC, 0x54, 0, 40, 0);
297 init_scenePropStruct( 67, 25, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
298 init_scenePropStruct( 68, 25, 1, 220, 93, 0xBC, 0x78, 0x48, 0, 40, 2);
299 init_scenePropStruct( 69, 25, 1, 221, 94, 0xBC, 0x78, 0x48, 0, 40, 3);
300 init_scenePropStruct( 70, 25, 1, 222, 95, 0xBC, 0x78, 0x48, 0, 40, 0);
301 init_scenePropStruct( 71, 26, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
302 init_scenePropStruct( 72, 26, 1, 223, 96, 0xBC, 0x78, 0x48, 0, 40, 0);
303 init_scenePropStruct( 73, 27, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
304 init_scenePropStruct( 74, 27, 1, 224, 97, 0xBC, 0x78, 0x48, 0, 40, 0);
305 init_scenePropStruct( 75, 28, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
306 init_scenePropStruct( 76, 28, 1, 225, 98, 0xBC, 0x78, 0x48, 0, 40, 0);
307 init_scenePropStruct( 77, 29, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
308 init_scenePropStruct( 78, 29, 1, 226, 99, 0xBC, 0x78, 0x48, 0, 40, 0);
309 init_scenePropStruct( 79, 30, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
310 init_scenePropStruct( 80, 30, 1, 228, 101, 0xBC, 0x78, 0x48, 0, 40, 0);
311 init_scenePropStruct( 81, 31, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
312 init_scenePropStruct( 82, 31, 1, 229, 102, 0xBC, 0x78, 0x48, 0, 40, 0);
313 init_scenePropStruct( 83, 32, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
314 init_scenePropStruct( 84, 32, 1, 233, 106, 0xA8, 0xA8, 0xA8, 0, 40, 2);
315 init_scenePropStruct( 85, 32, 1, 234, 107, 0xA8, 0xA8, 0xA8, 0, 40, 0);
316 init_scenePropStruct( 86, 33, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
317 init_scenePropStruct( 87, 33, 1, 241, 114, 0xA8, 0xA8, 0xA8, 0, 40, 2);
318 init_scenePropStruct( 88, 33, 1, 242, 115, 0xA8, 0xA8, 0xA8, 0, 40, 0);
319 init_scenePropStruct( 89, 34, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
320 init_scenePropStruct( 90, 34, 1, 237, 110, 0xA8, 0xA8, 0xA8, 0, 40, 2);
321 init_scenePropStruct( 91, 34, 1, 238, 111, 0xA8, 0xA8, 0xA8, 0, 40, 3);
322 init_scenePropStruct( 92, 34, 1, 239, 112, 0xA8, 0xA8, 0xA8, 0, 40, 0);
323 init_scenePropStruct( 93, 35, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
324 init_scenePropStruct( 94, 35, 1, 258, 131, 0xA8, 0xA8, 0xA8, 0, 40, 0);
325 init_scenePropStruct( 95, 36, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
326 init_scenePropStruct( 96, 36, 1, 260, 133, 0xA8, 0xA8, 0xA8, 0, 40, 0);
327 init_scenePropStruct( 97, 37, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
328 init_scenePropStruct( 98, 37, 1, 252, 125, 0xA8, 0xA8, 0xA8, 0, 40, 0);
329 init_scenePropStruct( 99, 38, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
330 init_scenePropStruct(100, 38, 1, 254, 127, 0xA8, 0xA8, 0xA8, 0, 40, 0);
331 init_scenePropStruct(101, 39, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
332 init_scenePropStruct(102, 39, 1, 236, 109, 0xA8, 0xA8, 0xA8, 0, 40, 0);
333 init_scenePropStruct(103, 40, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
334 init_scenePropStruct(104, 40, 1, 174, 42, 4, 0xBC, 0, 0, 40, 0);
335 init_scenePropStruct(105, 41, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
336 init_scenePropStruct(106, 41, 1, 167, 36, 4, 0xBC, 0, 0, 40, 0);
337 init_scenePropStruct(107, 42, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
338 init_scenePropStruct(108, 42, 1, 160, 29, 4, 0xBC, 0, 0, 40, 0);
339 init_scenePropStruct(109, 43, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
340 init_scenePropStruct(110, 43, 1, 161, 30, 4, 0xBC, 0, 0, 40, 0);
341 init_scenePropStruct(111, 44, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
342 init_scenePropStruct(112, 44, 1, 163, 32, 4, 0xBC, 0, 0, 40, 0);
343 init_scenePropStruct(113, 45, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
344 init_scenePropStruct(114, 45, 1, 164, 33, 4, 0xBC, 0, 0, 40, 0);
345 init_scenePropStruct(115, 46, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
346 init_scenePropStruct(116, 46, 1, 170, 39, 4, 0xBC, 0, 0, 40, 0);
347 init_scenePropStruct(117, 47, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
348 init_scenePropStruct(118, 47, 1, 166, 35, 4, 0xBC, 0, 0, 40, 0);
349 init_scenePropStruct(119, 48, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
350 init_scenePropStruct(120, 48, 1, 175, 43, 4, 0xBC, 0, 0, 40, 0);
351 init_scenePropStruct(121, 49, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
352 init_scenePropStruct(122, 49, 1, 203, 75, 0x40, 0x40, 0xFC, 0, 40, 0);
353 init_scenePropStruct(123, 50, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
354 init_scenePropStruct(124, 50, 1, 194, 66, 0x40, 0x40, 0xFC, 0, 40, 0);
355 init_scenePropStruct(125, 51, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
356 init_scenePropStruct(126, 51, 1, 195, 67, 0x40, 0x40, 0xFC, 0, 40, 0);
357 init_scenePropStruct(127, 52, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
358 init_scenePropStruct(128, 52, 1, 199, 71, 0x40, 0x40, 0xFC, 0, 40, 0);
359 init_scenePropStruct(129, 53, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
360 init_scenePropStruct(130, 53, 1, 205, 77, 0x40, 0x40, 0xFC, 0, 40, 0);
361 init_scenePropStruct(131, 54, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
362 init_scenePropStruct(132, 54, 1, 212, 85, 0x40, 0x40, 0xFC, 0, 40, 0);
363 init_scenePropStruct(133, 55, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
364 init_scenePropStruct(134, 55, 1, 201, 73, 0x40, 0x40, 0xFC, 0, 40, 0);
365 init_scenePropStruct(135, 56, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
366 init_scenePropStruct(136, 56, 1, 198, 70, 0x40, 0x40, 0xFC, 0, 40, 0);
367 init_scenePropStruct(137, 57, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
368 init_scenePropStruct(138, 57, 0, 59, 134, 0xFF, 0xFF, 0xFF, 0, 30, 0);
369
370 _actor[0].damage = 0;
371 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))
372 _actor[0].maxdamage = 60;
373 else
374 _actor[0].maxdamage = 80;
375 _actor[0].field_8 = 1;
376 _actor[0].frame = 0;
377 _actor[0].tilt = 0;
378 _actor[0].cursorX = 0;
379 _actor[0].speed = 0;
380 _actor[0].x = 160;
381 _actor[0].y = 0;
382 _actor[0].y1 = -1;
383 _actor[0].x1 = -1;
384 _actor[0].weaponClass = 2;
385 _actor[0].animWeaponClass = 0;
386 _actor[0].newFacingFlag = 2;
387 _actor[0].curFacingFlag = 0;
388 _actor[0].lost = false;
389 _actor[0].kicking = false;
390 _actor[0].field_44 = false;
391 _actor[0].field_48 = false;
392 _actor[0].defunct = 0;
393 _actor[0].scenePropSubIdx = 0;
394 _actor[0].field_54 = 0;
395 _actor[0].runningSound = 0;
396 _actor[0].weapon = INV_HAND;
397 _actor[0].inventory[INV_CHAIN] = 0;
398 _actor[0].inventory[INV_CHAINSAW] = 0;
399 _actor[0].inventory[INV_MACE] = 0;
400 _actor[0].inventory[INV_2X4] = 0;
401 _actor[0].inventory[INV_WRENCH] = 1;
402 _actor[0].inventory[INV_BOOT] = 1;
403 _actor[0].inventory[INV_HAND] = 1;
404 _actor[0].inventory[INV_DUST] = 0;
405 _actor[0].probability = 5;
406 _actor[0].enemyHandler = EN_BEN;
407 init_actStruct(0, 0, 11, 1, 1, 0, 0, 0);
408 init_actStruct(0, 1, 12, 1, 1, 0, 0, 0);
409 init_actStruct(0, 2, 1, 1, 1, 0, 0, 0);
410 init_actStruct(0, 3, 1, 1, 1, 0, 0, 0);
411
412 _actor[1].damage = 0;
413 _actor[1].maxdamage = -1;
414 _actor[1].field_8 = 1;
415 _actor[1].frame = 0;
416 _actor[1].tilt = 0;
417 _actor[1].cursorX = 0;
418 _actor[1].speed = 0;
419 _actor[1].x = 160;
420 _actor[1].y = 0;
421 _actor[1].y1 = -1;
422 _actor[1].x1 = -1;
423 _actor[1].weaponClass = 2;
424 _actor[1].animWeaponClass = 0;
425 _actor[1].newFacingFlag = 0;
426 _actor[1].curFacingFlag = 0;
427 _actor[1].lost = false;
428 _actor[1].kicking = false;
429 _actor[1].field_44 = false;
430 _actor[1].field_48 = false;
431 _actor[1].defunct = 0;
432 _actor[1].scenePropSubIdx = 0;
433 _actor[1].field_54 = 0;
434 _actor[1].runningSound = 0;
435 _actor[1].weapon = INV_HAND;
436 _actor[1].inventory[INV_CHAIN] = 0;
437 _actor[1].inventory[INV_CHAINSAW] = 0;
438 _actor[1].inventory[INV_MACE] = 1;
439 _actor[1].inventory[INV_2X4] = 0;
440 _actor[1].inventory[INV_WRENCH] = 0;
441 _actor[1].inventory[INV_BOOT] = 0;
442 _actor[1].inventory[INV_HAND] = 0;
443 _actor[1].inventory[INV_DUST] = 0;
444 _actor[1].probability = 5;
445 _actor[1].enemyHandler = -1;
446
447 init_actStruct(1, 0, 14, 1, 1, 0, 0, 0);
448 init_actStruct(1, 1, 15, 1, 1, 0, 0, 0);
449 init_actStruct(1, 2, 13, 1, 1, 0, 0, 0);
450 init_actStruct(1, 3, 13, 1, 1, 0, 0, 0);
451
452 for (i = 0; i < 10; i++)
453 for (j = 0; j < 10; j++)
454 _enemyState[i][j] = 0;
455 }
456
init_actStruct(int actornum,int actnum,int32 actorval,byte state,int32 room,int32 animTilt,int32 tilt,int32 frame)457 void Insane::init_actStruct(int actornum, int actnum, int32 actorval, byte state,
458 int32 room, int32 animTilt, int32 tilt, int32 frame) {
459 _actor[actornum].act[actnum].actor = actorval;
460 _actor[actornum].act[actnum].state = state;
461 _actor[actornum].act[actnum].room = room;
462 _actor[actornum].act[actnum].animTilt = animTilt;
463 _actor[actornum].act[actnum].tilt = tilt;
464 _actor[actornum].act[actnum].frame = frame;
465 }
466
init_enemyStruct(int n,int32 handler,int32 initializer,int16 occurences,int32 maxdamage,int32 isEmpty,int32 weapon,int32 sound,const char * filename,int32 costume4,int32 costume6,int32 costume5,int16 costumevar,int32 maxframe,int32 apprAnim)467 void Insane::init_enemyStruct(int n, int32 handler, int32 initializer,
468 int16 occurences, int32 maxdamage, int32 isEmpty,
469 int32 weapon, int32 sound, const char *filename,
470 int32 costume4, int32 costume6, int32 costume5,
471 int16 costumevar, int32 maxframe, int32 apprAnim) {
472 assert(strlen(filename) < 20);
473
474 _enemy[n].handler = handler;
475 _enemy[n].initializer = initializer;
476 _enemy[n].occurences = occurences;
477 _enemy[n].maxdamage = maxdamage;
478 _enemy[n].isEmpty = isEmpty;
479 _enemy[n].weapon = weapon;
480 _enemy[n].sound = sound;
481 Common::strlcpy(_enemy[n].filename, filename, 20);
482 _enemy[n].costume4 = costume4;
483 _enemy[n].costume6 = costume6;
484 _enemy[n].costume5 = costume5;
485 _enemy[n].costumevar = costumevar;
486 _enemy[n].maxframe = maxframe;
487 _enemy[n].apprAnim = apprAnim;
488 }
489
init_fluConfStruct(int n,int sceneId,byte ** fluPtr,const char * filenamePtr,int startFrame,int numFrames)490 void Insane::init_fluConfStruct(int n, int sceneId, byte **fluPtr,
491 const char *filenamePtr, int startFrame, int numFrames) {
492 _fluConf[n].sceneId = sceneId;
493 _fluConf[n].fluPtr = fluPtr;
494 _fluConf[n].filenamePtr = filenamePtr;
495 _fluConf[n].startFrame = startFrame;
496 _fluConf[n].numFrames = numFrames;
497 }
498
init_scenePropStruct(int32 n,int32 n1,int32 actornum,int32 sound,int32 trsId,byte r,byte g,byte b,int32 counter,int32 maxCounter,int32 index)499 void Insane::init_scenePropStruct(int32 n, int32 n1, int32 actornum, int32 sound, int32 trsId,
500 byte r, byte g, byte b, int32 counter, int32 maxCounter,
501 int32 index) {
502 _sceneProp[n].actor = actornum; // main actor number, -1 if not applicable
503 _sceneProp[n].sound = sound;
504 _sceneProp[n].trsId = trsId;
505 _sceneProp[n].r = r;
506 _sceneProp[n].g = g;
507 _sceneProp[n].b = b;
508 _sceneProp[n].counter = counter;
509 _sceneProp[n].maxCounter = maxCounter;
510 _sceneProp[n].index = index;
511 }
512
setBenAnimation(int32 actornum,int anim)513 void Insane::setBenAnimation(int32 actornum, int anim) {
514 if (anim <= 12)
515 smlayer_setActorFacing(actornum, 1,
516 actorAnimationData[_actor[actornum].weaponClass * 7 + anim - 6], 180);
517 }
518
setEnemyAnimation(int32 actornum,int anim)519 void Insane::setEnemyAnimation(int32 actornum, int anim) {
520 int d = 0;
521
522 if (_currEnemy == EN_VULTM1)
523 d = 14;
524
525 if (anim <= 12)
526 smlayer_setActorFacing(actornum, 1,
527 actorAnimationData[_actor[actornum].weaponClass * 7 + anim - 6] + d, 180);
528 }
529
processMouse()530 int32 Insane::processMouse() {
531 int32 buttons = 0;
532
533 _enemyState[EN_BEN][0] = _vm->_mouse.x;
534 _enemyState[EN_BEN][1] = _vm->_mouse.y;
535
536 buttons = _vm->VAR(_vm->VAR_LEFTBTN_HOLD) ? 1 : 0;
537 buttons |= _vm->VAR(_vm->VAR_RIGHTBTN_HOLD) ? 2 : 0;
538
539 return buttons;
540 }
541
processKeyboard()542 int32 Insane::processKeyboard() {
543 int32 retval = 0;
544 int dx = 0, dy = 0;
545 int tmpx, tmpy;
546
547 if (_vm->getKeyState(0x14f) || _vm->getKeyState(0x14b) || _vm->getKeyState(0x147))
548 dx--;
549
550 if (_vm->getKeyState(0x151) || _vm->getKeyState(0x14d) || _vm->getKeyState(0x149))
551 dx++;
552
553 if (_vm->getKeyState(0x147) || _vm->getKeyState(0x148) || _vm->getKeyState(0x149))
554 dy--;
555
556 if (_vm->getKeyState(0x14f) || _vm->getKeyState(0x150) || _vm->getKeyState(0x151))
557 dy++;
558
559 if (dx == _keybOldDx)
560 _velocityX += 4;
561 else
562 _velocityX = 3;
563
564 if (dy == _keybOldDy)
565 _velocityY += 4;
566 else
567 _velocityY = 2;
568
569 _keybOldDx = dx;
570 _keybOldDy = dy;
571
572 if (_velocityX > 48)
573 _velocityX = 48;
574
575 if (_velocityY > 32)
576 _velocityY = 32;
577
578 _keybX += dx * _velocityX;
579 _keybY += dy * _velocityY;
580
581 tmpx = _keybX / 4;
582 tmpy = _keybY / 4;
583
584 _keybX -= tmpx * 4;
585 _keybY -= tmpy * 4;
586
587 if (tmpx || tmpy) {
588 _enemyState[EN_BEN][0] += tmpx;
589 _enemyState[EN_BEN][1] += tmpy;
590 }
591
592 if (_vm->getKeyState(Common::KEYCODE_RETURN))
593 retval |= 1;
594
595 if (_vm->getKeyState(Common::KEYCODE_TAB))
596 retval |= 2;
597
598 return retval;
599 }
600
readFileToMem(const char * name,byte ** buf)601 void Insane::readFileToMem(const char *name, byte **buf) {
602 ScummFile in;
603 uint32 len;
604
605 if (!_vm->openFile(in, name))
606 error("Cannot open file %s", name);
607 len = in.size();
608 *buf = (byte *)malloc(len);
609 in.read(*buf, len);
610 }
611
startVideo(const char * filename,int num,int argC,int frameRate,int doMainLoop,byte * fluPtr,int32 startFrame)612 void Insane::startVideo(const char *filename, int num, int argC, int frameRate,
613 int doMainLoop, byte *fluPtr, int32 startFrame) {
614 int32 offset = 0;
615
616 _smush_curFrame = 0;
617 _smush_isSanFileSetup = 0;
618 _smush_setupsan4 = 0;
619 _smush_smushState = 0;
620 _smush_setupsan1 = 0;
621 _smush_setupsan17 = 0;
622
623 if (fluPtr) {
624 offset = smush_setupSanWithFlu(filename, 0, -1, -1, 0, fluPtr, startFrame);
625 } else {
626 smush_setupSanFromStart(filename, 0, -1, -1, 0);
627 }
628
629 _player->play(filename, _speed, offset, startFrame);
630 }
631
smush_warpMouse(int x,int y,int buttons)632 void Insane::smush_warpMouse(int x, int y, int buttons) {
633 _player->warpMouse(x, y, buttons);
634 }
635
putActors()636 void Insane::putActors() {
637 smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1, _smlayer_room);
638 smlayer_putActor(0, 0, _actor[0].x, _actor[0].y1, _smlayer_room);
639 smlayer_putActor(0, 1, _actor[0].x, _actor[0].y1, _smlayer_room);
640 smlayer_putActor(1, 2, _actor[0].x, _actor[0].y1, _smlayer_room);
641 smlayer_putActor(1, 0, _actor[0].x, _actor[0].y1, _smlayer_room);
642 smlayer_putActor(1, 1, _actor[0].x, _actor[0].y1, _smlayer_room);
643 }
644
readState()645 void Insane::readState() { // PATCH
646
647 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) {
648 _actor[0].inventory[INV_CHAIN] = 0;
649 _actor[0].inventory[INV_CHAINSAW] = 0;
650 _actor[0].inventory[INV_MACE] = 0;
651 _actor[0].inventory[INV_2X4] = 0;
652 _actor[0].inventory[INV_WRENCH] = 1;
653 _actor[0].inventory[INV_DUST] = 0;
654 _actor[0].inventory[INV_HAND] = 1;
655 _actor[0].inventory[INV_BOOT] = 0;
656 _smlayer_room2 = 13;
657 } else {
658 _actor[0].inventory[INV_CHAIN] = readArray(50) != 0;
659 _actor[0].inventory[INV_CHAINSAW] = readArray(51) != 0;
660 _actor[0].inventory[INV_MACE] = readArray(52) != 0;
661 _actor[0].inventory[INV_2X4] = readArray(53) != 0;
662 _actor[0].inventory[INV_WRENCH] = readArray(54) != 0;
663 _actor[0].inventory[INV_DUST] = readArray(55) != 0;
664 _actor[0].inventory[INV_HAND] = 1;
665 _actor[0].inventory[INV_BOOT] = 1;
666 _smlayer_room = readArray(320);
667 _smlayer_room2 = readArray(321);
668 _posBrokenTruck = readArray(322);
669 _posVista = readArray(323);
670 _val57d = readArray(324);
671 _posCave = readArray(325);
672 _posBrokenCar = readArray(326);
673 _val54d = readArray(327);
674 _posFatherTorque = readArray(328);
675 _enemy[EN_TORQUE].occurences = readArray(337);
676 _enemy[EN_ROTT1].occurences = readArray(329);
677 _enemy[EN_ROTT2].occurences = readArray(330);
678 _enemy[EN_ROTT3].occurences = readArray(331);
679 _enemy[EN_VULTF1].occurences = readArray(332);
680 _enemy[EN_VULTM1].occurences = readArray(333);
681 _enemy[EN_VULTF2].occurences = readArray(334);
682 _enemy[EN_VULTM2].occurences = readArray(335);
683 _enemy[EN_CAVEFISH].occurences = readArray(336);
684 _enemy[EN_VULTM2].isEmpty = readArray(340);
685 _enemy[EN_VULTF2].isEmpty = readArray(339);
686 _enemy[EN_CAVEFISH].isEmpty = readArray(56);
687
688 // FIXME
689 // Some sanity checks. There were submitted savefiles where these values were wrong
690 // Still it is unknown what leads to this state. Most probably it is memory
691 // overwrite
692 if (_enemy[EN_VULTM2].isEmpty != readArray(7)) {
693 warning("Wrong INSANE parameters for EN_VULTM2 (%d %d)",
694 _enemy[EN_VULTM2].isEmpty, readArray(7));
695 _enemy[EN_VULTM2].isEmpty = readArray(7);
696 }
697
698 if (_enemy[EN_VULTF2].isEmpty != (_actor[0].inventory[INV_CHAINSAW] != 0)) {
699 warning("Wrong INSANE parameters for EN_VULTF2 (%d %d)",
700 _enemy[EN_VULTF2].isEmpty, _actor[0].inventory[INV_CHAINSAW]);
701 _enemy[EN_VULTF2].isEmpty = (_actor[0].inventory[INV_CHAINSAW] != 0);
702 }
703
704 // FIXME
705 // This used to be here but.
706 // - bootparam 551 gives googles without cavefish met
707 // - when you get the ramp, googles disappear, but you already won the cavefish
708 // Incorrect situation would be
709 // you won cavefish, don't have googles, don't have ramp
710 //
711 // So if you find out what how to check ramp presense, feel free to add check here
712 // (beware of FT ver a and ver b. In version b var311 is inserted and all vars >311
713 // are shifted),
714 //
715 //if (_enemy[EN_CAVEFISH].isEmpty != readArray(8))
716 // error("Wrong INSANE parameters for EN_CAVEFISH (%d %d). Please, report this",
717 // _enemy[EN_CAVEFISH].isEmpty, readArray(8));
718 }
719 }
720
setupValues()721 void Insane::setupValues() {
722 _actor[0].x = 160;
723 _actor[0].y = 200;
724 _actor[0].tilt = 0;
725 _actor[0].field_8 = 1;
726 _actor[0].frame = 0;
727 _actor[0].act[2].state = 1;
728 _actor[0].act[0].state = 1;
729 _actor[0].act[1].state = 0;
730 _actor[0].act[2].room = 1;
731 _actor[0].act[1].room = 0;
732 _actor[0].act[0].room = 0;
733 _actor[0].cursorX = 0;
734 _actor[0].lost = false;
735 _currEnemy = -1;
736 _approachAnim = -1;
737 smush_warpMouse(160, 100, -1);
738 }
739
idx1Compare()740 bool Insane::idx1Compare() {
741 return _objArray1Idx == _objArray1Idx2;
742 }
743
idx2Compare()744 bool Insane::idx2Compare() {
745 return _objArray2Idx == _objArray2Idx2;
746 }
747
idx1Tweak()748 int32 Insane::idx1Tweak() {
749 _objArray1Idx++;
750 if (_objArray1Idx >= 100)
751 _objArray1Idx = 0;
752
753 return _objArray1[_objArray1Idx];
754 }
755
idx2Tweak()756 int32 Insane::idx2Tweak() {
757 if (!_idx2Exceeded)
758 if (_objArray2Idx >= _objArray2Idx2)
759 return false;
760
761 _objArray2Idx++;
762 if (_objArray2Idx >= 100) {
763 _idx2Exceeded = 0;
764 _objArray2Idx = 0;
765 }
766 return _objArray2[_objArray2Idx];
767 }
768
smush_setToFinish()769 void Insane::smush_setToFinish() {
770 debugC(DEBUG_INSANE, "Video is set to finish");
771 _vm->_smushVideoShouldFinish = true;
772 }
773
774 // smlayer_stopSound
smlayer_stopSound(int idx)775 void Insane::smlayer_stopSound(int idx) {
776 _vm->_imuseDigital->stopSound(readArray(idx));
777 }
778
switchSceneIfNeeded()779 void Insane::switchSceneIfNeeded() {
780 if (_needSceneSwitch && !_smush_isSanFileSetup) {
781 putActors();
782 stopSceneSounds(_currSceneId);
783 _tempSceneId = _currSceneId;
784 _currSceneId = _temp2SceneId;
785 _needSceneSwitch = false;
786 loadSceneData(_temp2SceneId, 0, 1);
787
788 if (loadSceneData(_temp2SceneId, 0, 2)) {
789 setSceneCostumes(_temp2SceneId);
790 _sceneData2Loaded = 0;
791 _sceneData1Loaded = 0;
792 return;
793 }
794
795 _sceneData2Loaded = 1;
796 if (_temp2SceneId == 13 || _temp2SceneId == 3)
797 _isBenCut = 1;
798 }
799
800 if (_sceneData2Loaded && !_sceneData1Loaded) {
801 setSceneCostumes(_currSceneId);
802 _sceneData2Loaded = 0;
803 }
804 }
805
prepareScenePropScene(int32 scenePropNum,bool arg_4,bool arg_8)806 void Insane::prepareScenePropScene(int32 scenePropNum, bool arg_4, bool arg_8) {
807 static const int scenePropIdx[58] = {0, 12, 14, 18, 20, 22, 24, 26, 28, 30, 34,
808 36, 38, 40, 42, 44, 46, 48, 50, 55, 57, 59, 61, 63, 65, 67, 71,
809 73, 75, 77, 79, 81, 83, 85, 89, 93, 95, 97, 99, 101, 103, 105, 107,
810 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137};
811
812 int tmp, idx = scenePropIdx[scenePropNum];
813
814 debugC(DEBUG_INSANE, "Insane::prepareScenePropScene(%d, %d, %d)", scenePropNum, arg_4, arg_8);
815
816 if (((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) || !loadScenePropSounds(idx))
817 return;
818
819 _actor[0].defunct = arg_4;
820 _actor[1].defunct = arg_8;
821 _currScenePropIdx = idx;
822 _sceneProp[idx + 1].counter = 0;
823 _currScenePropSubIdx = 1;
824 if (_sceneProp[idx + 1].trsId)
825 _currTrsMsg = handleTrsTag(_sceneProp[idx + 1].trsId);
826 else
827 _currTrsMsg = 0;
828
829 tmp = _sceneProp[idx + 1].actor;
830 if (tmp != -1) {
831 _actor[tmp].field_54 = 1;
832 _actor[tmp].act[3].state = 117;
833 _actor[tmp].scenePropSubIdx = _currScenePropSubIdx;
834 }
835 }
836
smush_changeState(int state)837 int Insane::smush_changeState(int state) {
838 if (state == 2) {
839 if (_smush_smushState == 0)
840 _smush_smushState = 1;
841 else
842 _smush_smushState = 0;
843 } else if (state == 4) {
844 if (_smush_smushState)
845 _smush_smushState = 3;
846 } else if (state != 5) {
847 _smush_smushState = state;
848 }
849 return _smush_smushState;
850 }
851
queueSceneSwitch(int32 sceneId,byte * fluPtr,const char * filename,int32 arg_C,int32 arg_10,int32 startFrame,int32 numFrames)852 void Insane::queueSceneSwitch(int32 sceneId, byte *fluPtr, const char *filename,
853 int32 arg_C, int32 arg_10, int32 startFrame, int32 numFrames) {
854 int32 tmp;
855
856 debugC(DEBUG_INSANE, "queueSceneSwitch(%d, *, %s, %d, %d, %d, %d)", sceneId, filename, arg_C, arg_10,
857 startFrame, numFrames);
858 if (_needSceneSwitch || _sceneData1Loaded)
859 return;
860
861 if (fluPtr) {
862 tmp = ((int)startFrame/30+1)*30;
863 if (tmp >= numFrames)
864 tmp = 0;
865
866 smush_setupSanWithFlu(filename, arg_C|32, -1, -1, 0, fluPtr, tmp);
867 } else {
868 smush_setupSanFromStart(filename, arg_C|32, -1, -1, 0);
869 }
870 _needSceneSwitch = true;
871 _temp2SceneId = sceneId;
872 }
873
smush_rewindCurrentSan(int arg_0,int arg_4,int arg_8)874 void Insane::smush_rewindCurrentSan(int arg_0, int arg_4, int arg_8) {
875 debugC(DEBUG_INSANE, "smush_rewindCurrentSan(%d, %d, %d)", arg_0, arg_4, arg_8);
876 _smush_setupsan2 = arg_0;
877
878 smush_setupSanFile(0, 0, 0);
879 _smush_isSanFileSetup = 1;
880 smush_setFrameSteps(arg_4, arg_8);
881
882 _smush_curFrame = 0; // HACK
883 }
884
weaponMaxRange(int32 actornum)885 int32 Insane::weaponMaxRange(int32 actornum) {
886 static const int map[8] = {135, 125, 130, 125, 120, 104, 104, 104};
887
888 if (_actor[actornum].weapon == -1)
889 return 104;
890
891 return map[_actor[actornum].weapon];
892 }
893
weaponMinRange(int32 actornum)894 int32 Insane::weaponMinRange(int32 actornum) {
895 static const int map[8] = {80, 40, 80, 40, 80, 80, 40, 50};
896
897 if (_actor[actornum].weapon == -1)
898 return 40;
899
900 return map[_actor[actornum].weapon];
901 }
902
weaponDamage(int32 actornum)903 int32 Insane::weaponDamage(int32 actornum) {
904 static const int map[8] = {20, 300, 25, 40, 15, 10, 10, 5};
905
906 if (_actor[actornum].weapon == -1)
907 return 10;
908
909 return map[_actor[actornum].weapon];
910 }
911
reinitActors()912 void Insane::reinitActors() {
913 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) {
914 smlayer_setActorCostume(0, 2, readArray(11));
915 smlayer_setActorCostume(0, 0, readArray(13));
916 smlayer_setActorCostume(0, 1, readArray(12));
917 } else {
918 smlayer_setActorCostume(0, 2, readArray(12));
919 smlayer_setActorCostume(0, 0, readArray(14));
920 smlayer_setActorCostume(0, 1, readArray(13));
921 }
922 smlayer_setActorLayer(0, 1, 1);
923 smlayer_setActorLayer(0, 2, 5);
924 smlayer_setActorLayer(0, 0, 10);
925 _actor[0].weapon = INV_HAND;
926 _actor[0].weaponClass = 2;
927 _actor[0].animWeaponClass = 0;
928 _actor[0].newFacingFlag = 2;
929 _actor[0].curFacingFlag = 0;
930 _actor[0].tilt = 0;
931 _actor[0].field_8 = 1;
932 _actor[0].act[2].state = 1;
933 _actor[0].act[2].animTilt = 1;
934 _actor[0].act[0].state = 0;
935 _actor[0].act[1].state = 1;
936 _actor[0].act[2].room = 1;
937 _actor[0].act[1].room = 1;
938 _actor[0].act[0].room = 1;
939 _actor[0].cursorX = 0;
940 }
941
calcTilt(int speed)942 int Insane::calcTilt(int speed) {
943 static const int tilt[7] = {-5, -4, -2, 0, 2, 4, 5};
944 if (speed + 3 > 6)
945 return 0;
946
947 return tilt[speed + 3];
948 }
949
actor1StateFlags(int state)950 bool Insane::actor1StateFlags(int state) {
951 // This is compressed table. It contains indexes where state
952 // changes. I.e. 0-33: true, 34-38: false 39-72: true, etc.
953 static const int spans[] = {0, 34, 39, 73, 89, 90, 92, 93, 99, 100, 117};
954 bool retvalue = 0;
955 unsigned int i;
956
957 for (i = 0; i < ARRAYSIZE(spans); i++) {
958 retvalue = !retvalue;
959 if (spans[i] <= state)
960 break;
961 }
962 return retvalue;
963 }
964
escapeKeyHandler()965 void Insane::escapeKeyHandler() {
966 struct fluConf *flu;
967
968 // The Macintosh demo has just one scene
969 if (((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformMacintosh)) ||
970 !_insaneIsRunning) {
971 smush_setToFinish();
972 return;
973 }
974
975 if (_needSceneSwitch || _keyboardDisable)
976 return;
977
978 debugC(DEBUG_INSANE, "scene: %d", _currSceneId);
979 switch (_currSceneId) {
980 case 1:
981 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) {
982 queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0);
983 } else {
984 queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300);
985 writeArray(9, 0);
986 }
987 break;
988 case 18:
989 queueSceneSwitch(17, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300);
990 writeArray(9, 1);
991 break;
992 case 2:
993 flu = &_fluConf[14 + _iactSceneId2];
994 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))
995 queueSceneSwitch(4, 0, "tovista.san", 64, 0, 0, 0);
996 else
997 queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
998 flu->startFrame, flu->numFrames);
999 break;
1000 case 3:
1001 queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300);
1002 break;
1003 case 4:
1004 if (_needSceneSwitch)
1005 return;
1006
1007 if (readArray(6)) {
1008 if (readArray(4)) {
1009 queueSceneSwitch(14, 0, "hitdust2.san", 64, 0, 0, 0);
1010 } else {
1011 queueSceneSwitch(14, 0, "hitdust4.san", 64, 0, 0, 0);
1012 }
1013 } else {
1014 if (readArray(4)) {
1015 queueSceneSwitch(14, 0, "hitdust1.san", 64, 0, 0, 0);
1016 } else {
1017 queueSceneSwitch(14, 0, "hitdust3.san", 64, 0, 0, 0);
1018 }
1019 }
1020 break;
1021 case 5:
1022 if (readArray(4)) {
1023 if (_needSceneSwitch)
1024 return;
1025 queueSceneSwitch(15, 0, "vistthru.san", 64, 0, 0, 0);
1026 } else {
1027 writeArray(1, _posVista);
1028 smush_setToFinish();
1029 }
1030 break;
1031 case 6:
1032 if (readArray(4)) {
1033 if (_needSceneSwitch)
1034 return;
1035 queueSceneSwitch(15, 0, "chasthru.san", 64, 0, 0, 0);
1036 } else {
1037 if (readArray(5)) {
1038 writeArray(1, _val57d);
1039 smush_setToFinish();
1040 } else {
1041 writeArray(4, 1);
1042 queueSceneSwitch(15, 0, "chasout.san", 64, 0, 0, 0);
1043 }
1044 }
1045 break;
1046 case 8:
1047 flu = &_fluConf[7 + _iactSceneId2];
1048 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))
1049 queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0);
1050 else
1051 queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
1052 flu->startFrame, flu->numFrames);
1053 break;
1054 case 7:
1055 flu = &_fluConf[0 + _iactSceneId2];
1056 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))
1057 queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0);
1058 else
1059 queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
1060 flu->startFrame, flu->numFrames);
1061 break;
1062 case 23:
1063 _actor[0].damage = 0;
1064 queueSceneSwitch(21, 0, "rottfite.san", 64, 0, 0, 0);
1065 break;
1066 case 9:
1067 _actor[0].damage = 0;
1068 queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300);
1069 break;
1070 case 10:
1071 _actor[0].damage = 0;
1072 queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300);
1073 break;
1074 case 13:
1075 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))
1076 queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0);
1077 else
1078 queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300);
1079 break;
1080 case 24:
1081 queueSceneSwitch(21, 0, "rottfite.san", 64, 0, 0, 0);
1082 break;
1083 case 16:
1084 writeArray(4, 0);
1085 writeArray(5, 1);
1086 writeArray(1, _posBrokenCar);
1087 writeArray(3, _posBrokenTruck);
1088 smush_setToFinish();
1089 break;
1090 case 15:
1091 switch (_tempSceneId) {
1092 case 5:
1093 queueSceneSwitch(6, 0, "toranch.san", 64, 0, 0, 530);
1094 break;
1095 case 6:
1096 queueSceneSwitch(4, 0, "tovista1.san", 64, 0, 0, 230);
1097 break;
1098 default:
1099 break;
1100 }
1101 break;
1102 default:
1103 break;
1104 }
1105 }
1106
actor0StateFlags1(int state)1107 bool Insane::actor0StateFlags1(int state) {
1108 static const int spans[] = {0, 2, 34, 35, 39, 69, 98, 100, 117};
1109 bool retvalue = 1;
1110 unsigned int i;
1111
1112 for (i = 0; i < ARRAYSIZE(spans); i++) {
1113 retvalue = !retvalue;
1114 if (spans[i] >= state)
1115 break;
1116 }
1117 return retvalue;
1118 }
1119
actor0StateFlags2(int state)1120 bool Insane::actor0StateFlags2(int state) {
1121 static const int spans[] = {0, 10, 14, 34, 39, 73, 75, 79, 81, 90, 93, 94,
1122 98, 100, 117, 133, 136, 153, 158, 200, 202, 209, 212, 213, 217,
1123 219, 236, 256, 259, 272, 277, 311, 312, 315, 317, 328, 331, 332,
1124 336, 338, 355, 379, 382, 391, 396, 440, 441, 447, 450, 451, 455,
1125 457, 474, 502, 505, 510, 515, 549, 553, 566, 569, 570, 574, 576,
1126 593, 601, 604, 629, 634, 680, 682, 685, 688, 689, 693, 695, 712,
1127 716, 718, 748, 753, 787, 788, 804, 807, 808, 812, 814, 831, 863,
1128 866, 867, 872, 920, 922, 923, 926, 927, 931, 933, 950};
1129 bool retvalue = 1;
1130 unsigned int i;
1131
1132 for (i = 0; i < ARRAYSIZE(spans); i++) {
1133 retvalue = !retvalue;
1134 if (spans[i] >= state)
1135 break;
1136 }
1137 return retvalue;
1138 }
1139
1140 // smlayer_loadSound1 && smlayer_loadSound2
smlayer_loadSound(int id,int flag,int phase)1141 int Insane::smlayer_loadSound(int id, int flag, int phase) {
1142 int resid;
1143
1144 if (phase == 1) {
1145 if (_idx2Exceeded != 0)
1146 if (_objArray2Idx >= _objArray2Idx2)
1147 return 0;
1148 }
1149 resid = readArray(id);
1150
1151 if (!resid && phase == 2)
1152 return 0;
1153
1154 if (phase == 2)
1155 _vm->ensureResourceLoaded(rtSound, resid);
1156
1157 _vm->_res->setResourceCounter(rtSound, resid, 1);
1158
1159 if (phase == 1) {
1160 _objArray2Idx2++;
1161 _objArray2[_objArray2Idx2] = id;
1162 if (_objArray2Idx2 >= 100) {
1163 _idx2Exceeded = 1;
1164 _objArray2Idx2 = 0;
1165 }
1166 }
1167 return resid;
1168 }
1169
1170 // smlayer_loadCostume1 && smlayer_loadCostume2
smlayer_loadCostume(int id,int phase)1171 int Insane::smlayer_loadCostume(int id, int phase) {
1172 int resid;
1173 resid = readArray(id);
1174
1175 if (!resid)
1176 return 0;
1177
1178 _vm->ensureResourceLoaded(rtCostume, resid);
1179 _vm->_res->setResourceCounter(rtCostume, resid, 1);
1180
1181 if (phase == 1) {
1182 _objArray1Idx2++;
1183 _objArray1[_objArray1Idx2] = id;
1184 if (_objArray1Idx2 == 100)
1185 _objArray1Idx2 = 0;
1186 }
1187
1188 return resid;
1189 }
1190
smlayer_setActorCostume(int actornum,int actnum,int costume)1191 void Insane::smlayer_setActorCostume(int actornum, int actnum, int costume) {
1192 Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_setActorCostume");
1193 a->setActorCostume(costume);
1194 a->setDirection(180);
1195 a->startAnimActor(1);
1196 _actor[actornum].act[actnum].frame = 0;
1197 }
1198
smlayer_putActor(int actornum,int actnum,int x,int y,byte room)1199 void Insane::smlayer_putActor(int actornum, int actnum, int x, int y, byte room) {
1200 Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_putActor");
1201 a->putActor(x, y, room);
1202 }
1203
smlayer_setActorLayer(int actornum,int actnum,int layer)1204 void Insane::smlayer_setActorLayer(int actornum, int actnum, int layer) {
1205 Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_setActorLayer");
1206 a->_layer = layer;
1207 }
1208
smlayer_setFluPalette(byte * pal,int shut_flag)1209 void Insane::smlayer_setFluPalette(byte *pal, int shut_flag) {
1210 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))
1211 return;
1212
1213 // if (shut_flag)
1214 // // FIXME: shut colors and make picture appear smoothly
1215 // SmushPlayer::setPalette(pal);
1216 // else
1217 _player->setPalette(pal);
1218 }
1219
smlayer_isSoundRunning(int32 sound)1220 bool Insane::smlayer_isSoundRunning(int32 sound) {
1221 return _vm->_imuseDigital->getSoundStatus(readArray(sound)) != 0;
1222 }
1223
smlayer_startSfx(int32 sound)1224 bool Insane::smlayer_startSfx(int32 sound) {
1225 if (smlayer_loadSound(sound, 0, 2)) {
1226 _vm->_imuseDigital->startSfx(readArray(sound), 40);
1227 return true;
1228 } else
1229 return false;
1230 }
1231
smlayer_startVoice(int32 sound)1232 bool Insane::smlayer_startVoice(int32 sound) {
1233 if (smlayer_loadSound(sound, 0, 2)) {
1234 _vm->_imuseDigital->startSfx(readArray(sound), 126);
1235 return true;
1236 } else
1237 return false;
1238 }
1239
smlayer_soundSetPan(int32 soundId,int32 pan)1240 void Insane::smlayer_soundSetPan(int32 soundId, int32 pan) {
1241 _vm->_imuseDigital->setPan(soundId, pan);
1242 }
1243
smlayer_soundSetPriority(int32 soundId,int32 priority)1244 void Insane::smlayer_soundSetPriority(int32 soundId, int32 priority) {
1245 _vm->_imuseDigital->setPriority(soundId, priority);
1246 }
1247
smlayer_drawSomething(byte * renderBitmap,int32 codecparam,int32 x,int32 y,int32 arg_10,NutRenderer * nutfile,int32 c,int32 arg_1C,int32 arg_20)1248 void Insane::smlayer_drawSomething(byte *renderBitmap, int32 codecparam,
1249 int32 x, int32 y, int32 arg_10, NutRenderer *nutfile,
1250 int32 c, int32 arg_1C, int32 arg_20) {
1251 nutfile->drawFrame(renderBitmap, c, x, y);
1252 }
1253
smlayer_overrideDrawActorAt(byte * arg_0,byte arg_4,byte arg_8)1254 void Insane::smlayer_overrideDrawActorAt(byte *arg_0, byte arg_4, byte arg_8) {
1255 // FIXME: doublecheck
1256
1257 // noop in current implementation
1258 }
1259
smlayer_showStatusMsg(int32 arg_0,byte * renderBitmap,int32 codecparam,int32 pos_x,int32 pos_y,int32 arg_14,int32 arg_18,int32 flags,const char * formatString,const char * strng)1260 void Insane::smlayer_showStatusMsg(int32 arg_0, byte *renderBitmap, int32 codecparam,
1261 int32 pos_x, int32 pos_y, int32 arg_14, int32 arg_18,
1262 int32 flags, const char *formatString, const char *strng) {
1263 SmushFont *sf = _player->getFont(0);
1264 int color = 1;
1265 int32 top = 0;
1266 char *str = NULL, *string;
1267 int len = strlen(formatString) + strlen(strng) + 16;
1268
1269 string = (char *)malloc(len);
1270 str = string;
1271
1272 while (*strng == '/') {
1273 strng++; // For text resources
1274 }
1275
1276 snprintf(str, len, formatString, strng);
1277
1278 while (str[0] == '^') {
1279 switch (str[1]) {
1280 case 'f':
1281 {
1282 int id = str[3] - '0';
1283 str += 4;
1284 sf = _player->getFont(id);
1285 }
1286 break;
1287 case 'c':
1288 {
1289 color = str[4] - '0' + 10 *(str[3] - '0');
1290 str += 5;
1291 }
1292 break;
1293 default:
1294 error("invalid escape code in text string");
1295 }
1296 }
1297
1298 assert(sf != NULL);
1299 sf->setColor(color);
1300
1301 // flags:
1302 // bit 0 - center 1
1303 // bit 1 - not used 2
1304 // bit 2 - ??? 4
1305 // bit 3 - wrap around 8
1306 switch (flags) {
1307 case 0:
1308 sf->drawString(str, renderBitmap, _player->_width, _player->_height, pos_x, pos_y, false);
1309 break;
1310 case 1:
1311 sf->drawString(str, renderBitmap, _player->_width, _player->_height, pos_x, MAX(pos_y, top), true);
1312 break;
1313 case 5:
1314 sf->drawStringWrap(str, renderBitmap, _player->_width, _player->_height, pos_x, pos_y, 10, 300, true);
1315 break;
1316 default:
1317 error("Insane::smlayer_showStatusMsg. Not handled flags: %d", flags);
1318 }
1319 free (string);
1320 }
1321
procSKIP(int32 subSize,Common::SeekableReadStream & b)1322 void Insane::procSKIP(int32 subSize, Common::SeekableReadStream &b) {
1323 int16 par1, par2;
1324 _player->_skipNext = false;
1325
1326 if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) {
1327 assert(subSize >= 2);
1328 par1 = b.readUint16LE();
1329 par2 = 0;
1330 } else {
1331 assert(subSize >= 4);
1332 par1 = b.readUint16LE();
1333 par2 = b.readUint16LE();
1334 }
1335
1336 if (!par2) {
1337 if (isBitSet(par1))
1338 _player->_skipNext = true;
1339 } else if (isBitSet(par1) != isBitSet(par2)) {
1340 _player->_skipNext = true;
1341 }
1342 }
1343
isBitSet(int n)1344 bool Insane::isBitSet(int n) {
1345 assert (n < 0x80);
1346
1347 return (_iactBits[n] != 0);
1348 }
1349
setBit(int n)1350 void Insane::setBit(int n) {
1351 assert (n < 0x80);
1352
1353 _iactBits[n] = 1;
1354 }
1355
clearBit(int n)1356 void Insane::clearBit(int n) {
1357 assert (n < 0x80);
1358
1359 _iactBits[n] = 0;
1360 }
1361
smlayer_setActorFacing(int actornum,int actnum,int frame,int direction)1362 void Insane::smlayer_setActorFacing(int actornum, int actnum, int frame, int direction) {
1363 if (_actor[actornum].act[actnum].room) {
1364 Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_setActorFacing");
1365 a->setDirection(direction);
1366 a->startAnimActor(frame);
1367 _actor[actornum].act[actnum].frame = 0;
1368 }
1369 }
1370
handleTrsTag(int32 trsId)1371 const char *Insane::handleTrsTag(int32 trsId) {
1372 debugC(DEBUG_INSANE, "Insane::handleTrsTag(%d)", trsId);
1373 return _player->getString(trsId);
1374 }
1375
smush_eitherNotStartNewFrame()1376 bool Insane::smush_eitherNotStartNewFrame() {
1377 if (_smush_setupsan17)
1378 return false;
1379
1380 if (_smush_isSanFileSetup) {
1381 if (_smush_frameStep < 0)
1382 return false;
1383
1384 if (_smush_curFrame > _smush_frameStep + _smush_frameNum2)
1385 return true;
1386 else
1387 return false;
1388 } else {
1389 if (_smush_frameNum1 < 0)
1390 return false;
1391
1392 if (_smush_curFrame >= _smush_frameNum1) {
1393 _smush_frameNum1 = -1;
1394 return false;
1395 } else
1396 return true;
1397 }
1398 }
1399
smlayer_actorNeedRedraw(int actornum,int actnum)1400 bool Insane::smlayer_actorNeedRedraw(int actornum, int actnum) {
1401 Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_actorNeedRedraw");
1402
1403 return a->_needRedraw;
1404 }
1405
readArray(int item)1406 int32 Insane::readArray (int item) {
1407 return _vm->readArray(_numberArray, 0, item);
1408 }
1409
writeArray(int item,int value)1410 void Insane::writeArray(int item, int value) {
1411 _vm->writeArray(_numberArray, 0, item, value);
1412 }
1413
smush_setupSanWithFlu(const char * filename,int32 setupsan2,int32 step1,int32 step2,int32 setupsan1,byte * fluPtr,int32 numFrames)1414 int32 Insane::smush_setupSanWithFlu(const char *filename, int32 setupsan2, int32 step1,
1415 int32 step2, int32 setupsan1, byte *fluPtr,
1416 int32 numFrames) {
1417 byte *tmp = fluPtr;
1418 int32 offset;
1419
1420 debugC(DEBUG_INSANE, "smush_setupSanWithFlu(%s, %d, %d, %d, %d, %p, %d)", filename, setupsan2,
1421 step1, step2, setupsan1, (void *)fluPtr, numFrames);
1422
1423 _smush_setupsan1 = setupsan1;
1424
1425 /* skip FLUP marker */
1426 if (READ_BE_UINT32(fluPtr) == MKTAG('F','L','U','P'))
1427 tmp += 8;
1428
1429 _smush_setupsan2 = setupsan2;
1430
1431 if (tmp[2] <= 1) {
1432 /* 0x300 -- palette, 0x8 -- header */
1433 offset = READ_LE_UINT32(tmp + 0x308 + numFrames*4);
1434 smush_setupSanFile(filename, offset, numFrames);
1435 memcpy(_smush_earlyFluContents, tmp+2, 0x306);
1436 _smush_earlyFluContents[0x30e] = 0;
1437 _smush_earlyFluContents[0x30f] = 0;
1438 _smush_earlyFluContents[0x310] = 0;
1439 _smush_earlyFluContents[0x311] = 0;
1440 _smush_earlyFluContents[0x306] = 0;
1441 _smush_earlyFluContents[0x307] = 0;
1442 } else {
1443 offset = READ_LE_UINT32(tmp + 0x31c + numFrames*4);
1444 smush_setupSanFile(filename, offset, numFrames);
1445 memcpy(_smush_earlyFluContents, tmp+2, 0x31a);
1446 }
1447 _smush_isSanFileSetup = 1;
1448 _smush_setupsan4 = 1;
1449 _smush_curFrame = numFrames;
1450 smush_setFrameSteps(step1, step2);
1451 smush_warpMouse(160, 100, -1);
1452
1453 return offset;
1454 }
1455
smush_setupSanFromStart(const char * filename,int32 setupsan2,int32 step1,int32 step2,int32 setupsan1)1456 void Insane::smush_setupSanFromStart(const char *filename, int32 setupsan2, int32 step1,
1457 int32 step2, int32 setupsan1) {
1458 debugC(DEBUG_INSANE, "Insane::smush_setupFromStart(%s)", filename);
1459 _smush_setupsan1 = setupsan1;
1460 _smush_setupsan2 = setupsan2;
1461 smush_setupSanFile(filename, 0, 0);
1462 _smush_isSanFileSetup = 1;
1463 smush_setFrameSteps(step1, step2);
1464 smush_warpMouse(160, 100, -1);
1465 }
1466
smush_setFrameSteps(int32 step1,int32 step2)1467 void Insane::smush_setFrameSteps(int32 step1, int32 step2) {
1468 _smush_frameNum2 = _smush_curFrame;
1469 _smush_frameNum1 = step2;
1470 _smush_frameStep = step1;
1471 }
1472
smush_setupSanFile(const char * filename,int32 offset,int32 contFrame)1473 void Insane::smush_setupSanFile(const char *filename, int32 offset, int32 contFrame) {
1474 debugC(DEBUG_INSANE, "Insane::smush_setupSanFile(%s, %x, %d)", filename, offset, contFrame);
1475
1476 _player->seekSan(filename, offset, contFrame);
1477 }
1478
1479 }
1480