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