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