1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/scummsys.h"
24 #include "access/access.h"
25 #include "access/resources.h"
26 #include "access/amazon/amazon_game.h"
27 #include "access/amazon/amazon_resources.h"
28 #include "access/amazon/amazon_scripts.h"
29 
30 namespace Access {
31 
32 namespace Amazon {
33 
AmazonScripts(AccessEngine * vm)34 AmazonScripts::AmazonScripts(AccessEngine *vm) : Scripts(vm) {
35 	_game = (AmazonEngine *)_vm;
36 
37 	setOpcodes_v2();
38 }
39 
cLoop()40 void AmazonScripts::cLoop() {
41 	searchForSequence();
42 	_vm->_images.clear();
43 	_vm->_buffer2.blitFrom(_vm->_buffer1);
44 	_vm->_oldRects.clear();
45 	_vm->_scripts->executeScript();
46 	_vm->plotList1();
47 	_vm->copyBlocks();
48 }
49 
mWhile1()50 void AmazonScripts::mWhile1() {
51 	_vm->_screen->setDisplayScan();
52 	_vm->_screen->fadeOut();
53 	_vm->_events->hideCursor();
54 
55 	_vm->_files->loadScreen(14, 0);
56 	_vm->_buffer2.blitFrom(*_vm->_screen);
57 	_vm->_buffer1.blitFrom(*_vm->_screen);
58 	_vm->_events->showCursor();
59 
60 	_vm->_screen->setIconPalette();
61 	_vm->_screen->forceFadeIn();
62 
63 	Resource *spriteData = _vm->_files->loadFile(14, 6);
64 	_vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
65 	delete spriteData;
66 
67 	_vm->_images.clear();
68 	_vm->_oldRects.clear();
69 	_sequence = 2100;
70 
71 	do {
72 		cLoop();
73 		_sequence = 2100;
74 	} while (_vm->_flags[52] == 1);
75 
76 	_vm->_buffer1.copyTo(_vm->_screen);
77 	_vm->_buffer2.copyTo(&_vm->_buffer1);
78 
79 	_game->establish(-1, 14);
80 
81 	spriteData = _vm->_files->loadFile(14, 7);
82 	_vm->_objectsTable[1] = new SpriteResource(_vm, spriteData);
83 	delete spriteData;
84 
85 	_vm->_sound->playSound(0);
86 	_vm->_screen->setDisplayScan();
87 	_vm->_events->hideCursor();
88 
89 	_vm->_files->loadScreen(14, 1);
90 	_vm->_screen->setPalette();
91 	_vm->_buffer2.blitFrom(*_vm->_screen);
92 	_vm->_buffer1.blitFrom(*_vm->_screen);
93 	_vm->_events->showCursor();
94 
95 	_vm->_screen->setIconPalette();
96 	_vm->_images.clear();
97 	_vm->_oldRects.clear();
98 	_sequence = 2200;
99 
100 	_vm->_sound->loadSoundTable(0, 14, 15);
101 
102 	do {
103 		cLoop();
104 		_sequence = 2200;
105 	} while (_vm->_flags[52] == 2);
106 
107 	_vm->_screen->setDisplayScan();
108 	_vm->_events->hideCursor();
109 
110 	_vm->_files->loadScreen(14, 2);
111 	_vm->_screen->setPalette();
112 	_vm->_buffer2.blitFrom(*_vm->_screen);
113 	_vm->_buffer1.blitFrom(*_vm->_screen);
114 	_vm->_events->showCursor();
115 
116 	_vm->_screen->setIconPalette();
117 	_vm->freeCells();
118 
119 	spriteData = _vm->_files->loadFile(14, 8);
120 	_vm->_objectsTable[2] = new SpriteResource(_vm, spriteData);
121 	delete spriteData;
122 
123 	_vm->_images.clear();
124 	_vm->_oldRects.clear();
125 	_sequence = 2300;
126 	_vm->_sound->playSound(0);
127 
128 	do {
129 		cLoop();
130 		_sequence = 2300;
131 	} while (_vm->_flags[52] == 3);
132 
133 	_vm->freeCells();
134 	spriteData = _vm->_files->loadFile(14, 9);
135 	_vm->_objectsTable[3] = new SpriteResource(_vm, spriteData);
136 	delete spriteData;
137 
138 	_vm->_screen->setDisplayScan();
139 	_vm->_events->hideCursor();
140 
141 	_vm->_files->loadScreen(14, 3);
142 	_vm->_screen->setPalette();
143 	_vm->_buffer2.blitFrom(*_vm->_screen);
144 	_vm->_buffer1.blitFrom(*_vm->_screen);
145 	_vm->_events->showCursor();
146 
147 	_vm->_screen->setIconPalette();
148 	_vm->_images.clear();
149 	_vm->_oldRects.clear();
150 	_sequence = 2400;
151 
152 	do {
153 		cLoop();
154 		_sequence = 2400;
155 	} while (_vm->_flags[52] == 4);
156 }
157 
mWhile2()158 void AmazonScripts::mWhile2() {
159 	_vm->_screen->setDisplayScan();
160 	_vm->_screen->fadeOut();
161 	_vm->_events->hideCursor();
162 
163 	_vm->_files->loadScreen(14, 0);
164 	_vm->_buffer2.blitFrom(*_vm->_screen);
165 	_vm->_buffer1.blitFrom(*_vm->_screen);
166 	_vm->_events->showCursor();
167 
168 	_vm->_screen->setIconPalette();
169 	_vm->_screen->forceFadeIn();
170 
171 	Resource *spriteData = _vm->_files->loadFile(14, 6);
172 	_vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
173 	delete spriteData;
174 
175 	_vm->_images.clear();
176 	_vm->_oldRects.clear();
177 	_sequence = 2100;
178 
179 	do {
180 		cLoop();
181 		_sequence = 2100;
182 	} while (_vm->_flags[52] == 1);
183 
184 	_vm->_screen->fadeOut();
185 	_vm->freeCells();
186 	spriteData = _vm->_files->loadFile(14, 9);
187 	_vm->_objectsTable[3] = new SpriteResource(_vm, spriteData);
188 	delete spriteData;
189 
190 	_vm->_screen->setDisplayScan();
191 	_vm->_events->hideCursor();
192 
193 	_vm->_files->loadScreen(14, 3);
194 	_vm->_screen->setPalette();
195 	_vm->_buffer2.blitFrom(*_vm->_screen);
196 	_vm->_buffer1.blitFrom(*_vm->_screen);
197 	_vm->_events->showCursor();
198 
199 	_vm->_screen->setIconPalette();
200 	_vm->_images.clear();
201 	_vm->_oldRects.clear();
202 	_sequence = 2400;
203 
204 	do {
205 		cLoop();
206 		_sequence = 2400;
207 	} while (_vm->_flags[52] == 4);
208 }
209 
mWhile(int param1)210 void AmazonScripts::mWhile(int param1) {
211 	switch(param1) {
212 	case 1:
213 		mWhile1();
214 		break;
215 	case 2:
216 		_game->_plane->mWhileFly();
217 		break;
218 	case 3:
219 		_game->_plane->mWhileFall();
220 		break;
221 	case 4:
222 		_game->_jungle->mWhileJWalk();
223 		break;
224 	case 5:
225 		_game->_jungle->mWhileDoOpen();
226 		break;
227 	case 6:
228 		_game->_river->mWhileDownRiver();
229 		break;
230 	case 7:
231 		mWhile2();
232 		break;
233 	case 8:
234 		_game->_jungle->mWhileJWalk2();
235 		break;
236 	default:
237 		break;
238 	}
239 }
240 
loadBackground(int param1,int param2)241 void AmazonScripts::loadBackground(int param1, int param2) {
242 	_vm->_files->_setPaletteFlag = false;
243 	_vm->_files->loadScreen(param1, param2);
244 
245 	_vm->_buffer2.blitFrom(*_vm->_screen);
246 	_vm->_buffer1.blitFrom(*_vm->_screen);
247 
248 	_vm->_screen->forceFadeIn();
249 }
250 
loadNSound(int param1,int param2)251 void AmazonScripts::loadNSound(int param1, int param2) {
252 	Resource *sound = _vm->_files->loadFile(param1, param2);
253 	_vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
254 }
255 
setInactive()256 void AmazonScripts::setInactive() {
257 	_game->_rawInactiveX = _vm->_player->_rawPlayer.x;
258 	_game->_rawInactiveY = _vm->_player->_rawPlayer.y;
259 	_game->_charSegSwitch = false;
260 
261 	mWhile(_game->_rawInactiveY);
262 }
263 
boatWalls(int param1,int param2)264 void AmazonScripts::boatWalls(int param1, int param2) {
265 	if (param1 == 1)
266 		_vm->_room->_plotter._walls[42] = Common::Rect(96, 27, 96 + 87, 27 + 42);
267 	else {
268 		_vm->_room->_plotter._walls[39].bottom = _vm->_room->_plotter._walls[41].bottom = 106;
269 		_vm->_room->_plotter._walls[40].left = 94;
270 	}
271 }
272 
plotInactive()273 void AmazonScripts::plotInactive() {
274 	Player &player = *_vm->_player;
275 	InactivePlayer &inactive = _game->_inactive;
276 
277 	if (_game->_charSegSwitch) {
278 		_game->_currentCharFlag = true;
279 		SWAP(inactive._altSpritesPtr, player._playerSprites);
280 		_game->_charSegSwitch = false;
281 	} else if (_game->_jasMayaFlag != (_game->_currentCharFlag ? 1 : 0)) {
282 		if (player._playerOff) {
283 			_game->_jasMayaFlag = (_game->_currentCharFlag ? 1 : 0);
284 		} else {
285 			_game->_currentCharFlag = (_game->_jasMayaFlag == 1);
286 			int tmpX = _game->_rawInactiveX;
287 			int tmpY = _game->_rawInactiveY;
288 			_game->_rawInactiveX = player._rawPlayer.x;
289 			_game->_rawInactiveY = player._rawPlayer.y;
290 			player._rawPlayer.x = tmpX;
291 			player._rawPlayer.y = tmpY;
292 			_game->_inactiveYOff = player._playerOffset.y;
293 			player.calcManScale();
294 
295 			SWAP(inactive._altSpritesPtr, player._playerSprites);
296 			_vm->_room->setWallCodes();
297 		}
298 	}
299 
300 	_game->_flags[155] = 0;
301 	if (_game->_rawInactiveX >= 152 && _game->_rawInactiveX <= 167 &&
302 			_game->_rawInactiveY >= 158 && _game->_rawInactiveY <= 173) {
303 		_game->_flags[155] = 1;
304 	} else {
305 		_game->_flags[160] = 0;
306 		if (!_game->_jasMayaFlag && _game->_rawInactiveX >= 266 && _game->_rawInactiveX <= 290
307 			&& _game->_rawInactiveY >= 70 && _game->_rawInactiveY <= 87) {
308 			_game->_flags[160] = 1;
309 		}
310 	}
311 
312 	inactive._flags &= ~IMGFLAG_UNSCALED;
313 	inactive._flags &= ~IMGFLAG_BACKWARDS;
314 	inactive._position.x = _game->_rawInactiveX;
315 	inactive._position.y = _game->_rawInactiveY - _game->_inactiveYOff;
316 	inactive._offsetY = _game->_inactiveYOff;
317 	inactive._spritesPtr = inactive._altSpritesPtr;
318 
319 	_vm->_images.addToList(_game->_inactive);
320 }
321 
executeSpecial(int commandIndex,int param1,int param2)322 void AmazonScripts::executeSpecial(int commandIndex, int param1, int param2) {
323 	switch (commandIndex) {
324 	case 0:
325 		warning("TODO: DEMO - RESETAN");
326 		break;
327 	case 1:
328 		_vm->establish(param1, param2);
329 		break;
330 	case 2:
331 		loadBackground(param1, param2);
332 		break;
333 	case 3:
334 		if (_vm->isDemo())
335 			warning("TODO: DEMO - LOADCELLSET");
336 		else
337 			_game->_cast->doCast(param1);
338 		break;
339 	case 4:
340 		if (_vm->isDemo())
341 			loadNSound(param1, param2);
342 		else
343 			setInactive();
344 		break;
345 	case 5:
346 		warning("TODO: DEMO - UNLOADCELLSET");
347 		break;
348 	case 6:
349 		mWhile(param1);
350 		break;
351 	case 7:
352 		warning("TODO: DEMO - ADDMONEY");
353 		break;
354 	case 8:
355 		warning("TODO: DEMO - CHKMONEY");
356 		break;
357 	case 9:
358 		_game->_guard->doGuard();
359 		break;
360 	case 10:
361 		_vm->_midi->newMusic(param1, param2);
362 		break;
363 	case 11:
364 		plotInactive();
365 		break;
366 	case 13:
367 		_game->_river->doRiver();
368 		break;
369 	case 14:
370 		_game->_ant->doAnt();
371 		break;
372 	case 15:
373 		boatWalls(param1, param2);
374 		break;
375 	default:
376 		warning("Unexpected Special code %d - Skipped", commandIndex);
377 	}
378 }
379 
380 typedef void(AmazonScripts::*AmazonScriptMethodPtr)();
381 
executeCommand(int commandIndex)382 void AmazonScripts::executeCommand(int commandIndex) {
383 	static const AmazonScriptMethodPtr AMAZON_COMMAND_LIST[] = {
384 		&AmazonScripts::cmdHelp_v2, &AmazonScripts::cmdCycleBack,
385 		&AmazonScripts::cmdChapter, &AmazonScripts::cmdSetHelp,
386 		&AmazonScripts::cmdCenterPanel, &AmazonScripts::cmdMainPanel,
387 		&AmazonScripts::CMDRETFLASH
388 	};
389 
390 	if (commandIndex >= 73)
391 		(this->*AMAZON_COMMAND_LIST[commandIndex - 73])();
392 	else
393 		Scripts::executeCommand(commandIndex);
394 }
395 
cmdHelp_v2()396 void AmazonScripts::cmdHelp_v2() {
397 	Common::String helpMessage = readString();
398 
399 	if (_game->_helpLevel == 0) {
400 		_game->_timers.saveTimers();
401 		_game->_useItem = 0;
402 
403 		if (_game->_noHints) {
404 			printString(AMRES.NO_HELP_MESSAGE);
405 			return;
406 		} else if (_game->_hintLevel == 0) {
407 			printString(AMRES.NO_HINTS_MESSAGE);
408 			return;
409 		}
410 	}
411 
412 	int level = _game->_hintLevel - 1;
413 	if (level < _game->_helpLevel)
414 		_game->_moreHelp = 0;
415 
416 	_game->drawHelp(helpMessage);
417 
418 	while (!_vm->shouldQuit()) {
419 		while (!_vm->shouldQuit() && !_vm->_events->_leftButton)
420 			_vm->_events->pollEventsAndWait();
421 
422 		_vm->_events->debounceLeft();
423 
424 		static const Common::Rect butn1 = Common::Rect(HELP1COORDS[0][0], HELP1COORDS[0][2], HELP1COORDS[0][1], HELP1COORDS[0][3]);
425 		static const Common::Rect butn2 = Common::Rect(HELP1COORDS[1][0], HELP1COORDS[1][2], HELP1COORDS[1][1], HELP1COORDS[1][3]);
426 		const Common::Point pt = _vm->_events->_mousePos;
427 
428 		int choice = -1;
429 		if (butn1.contains(pt))
430 			choice = 0;
431 		else if (butn2.contains(pt))
432 			choice = 1;
433 
434 		if (choice < 0)
435 			continue;
436 
437 		if (choice == 1) {
438 			// Done button selected
439 			_game->_helpLevel = 0;
440 			_game->_moreHelp = 1;
441 			_game->_useItem = 0;
442 			_vm->_events->hideCursor();
443 			if (_vm->_screen->_vesaMode) {
444 				_vm->_screen->restoreScreen();
445 				_vm->_screen->setPanel(0);
446 			} else {
447 				_vm->_screen->fadeOut();
448 				_vm->_screen->clearBuffer();
449 			}
450 
451 			_vm->_buffer2.copyTo(_vm->_screen);
452 			_vm->_screen->restorePalette();
453 			_vm->_screen->setPalette();
454 			_vm->_events->showCursor();
455 
456 			delete _vm->_objectsTable[45];
457 			_vm->_objectsTable[45] = nullptr;
458 			_vm->_timers.restoreTimers();
459 			break;
460 		} else {
461 			// More button selected
462 			if ((_game->_moreHelp == 0) || (choice != 0))
463 				continue;
464 			++_game->_helpLevel;
465 			_game->_useItem = 1;
466 			break;
467 		}
468 	}
469 	findNull();
470 }
471 
cmdCycleBack()472 void AmazonScripts::cmdCycleBack() {
473 	if (_vm->_startup == -1)
474 		_vm->_screen->cyclePaletteBackwards();
475 }
476 
cmdChapter()477 void AmazonScripts::cmdChapter() {
478 	Resource *activeScript = nullptr;
479 
480 	if (_vm->isDemo()) {
481 		cmdSetHelp();
482 	} else {
483 		int chapter = _data->readByte();
484 
485 		if (!_vm->isCD()) {
486 			// For floppy version, the current script remains active even
487 			// after the end of the chapter start, so we need to save it
488 			activeScript = _resource;
489 			_resource = nullptr;
490 			_data = nullptr;
491 		}
492 
493 		_game->startChapter(chapter);
494 
495 		if (!_vm->isCD()) {
496 			assert(!_resource);
497 			setScript(activeScript, false);
498 		}
499 	}
500 }
501 
cmdSetHelp()502 void AmazonScripts::cmdSetHelp() {
503 	int arrayId = (_data->readUint16LE() & 0xFF) - 1;
504 	int helpId = _data->readUint16LE() & 0xFF;
505 
506 	byte *help = _game->_helpTbl[arrayId];
507 	help[helpId] = 1;
508 
509 	if (_vm->_useItem == 0) {
510 		_sequence = 11000;
511 		searchForSequence();
512 	}
513 }
514 
cmdCenterPanel()515 void AmazonScripts::cmdCenterPanel() {
516 	if (_vm->_screen->_vesaMode) {
517 		_vm->_screen->clearScreen();
518 		_vm->_screen->setPanel(3);
519 	}
520 }
521 
cmdMainPanel()522 void AmazonScripts::cmdMainPanel() {
523 	if (_vm->_screen->_vesaMode) {
524 		_vm->_room->init4Quads();
525 		_vm->_screen->setPanel(0);
526 	}
527 }
528 
CMDRETFLASH()529 void AmazonScripts::CMDRETFLASH() {
530 	error("TODO CMDRETFLASH");
531 }
532 
533 } // End of namespace Amazon
534 
535 } // End of namespace Access
536