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 "neverhood/diskplayerscene.h"
24 #include "neverhood/gamemodule.h"
25 #include "neverhood/menumodule.h"
26 #include "neverhood/smackerplayer.h"
27 #include "neverhood/modules/module1000_sprites.h"
28 #include "neverhood/modules/module1200_sprites.h"
29 #include "neverhood/modules/module1300.h"
30 #include "neverhood/modules/module1300_sprites.h"
31 #include "neverhood/modules/module1400_sprites.h"
32 #include "neverhood/modules/module2200_sprites.h"
33
34 namespace Neverhood {
35
36 static const uint32 kModule1300SoundList[] = {
37 0x16805648,
38 0x16805C48,
39 0xB4964448,
40 0x96A05481,
41 0xD0E14441,
42 0x90815450,
43 0
44 };
45
Module1300(NeverhoodEngine * vm,Module * parentModule,int which)46 Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)
47 : Module(vm, parentModule) {
48
49 _vm->_soundMan->addMusic(0x61C090, 0x00203197);
50 _vm->_soundMan->addSoundList(0x61C090, kModule1300SoundList);
51 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 50, 600, 20, 150);
52 _vm->_soundMan->playTwoSounds(0x61C090, 0x48498E46, 0x50399F64, 0);
53 _vm->_soundMan->setSoundVolume(0x48498E46, 70);
54 _vm->_soundMan->setSoundVolume(0x50399F64, 70);
55
56 if (which < 0) {
57 if (_vm->gameState().sceneNum >= 1 && _vm->gameState().sceneNum <= 17)
58 createScene(_vm->gameState().sceneNum, -1);
59 else
60 createScene(11, 0);
61 } else {
62 switch (which) {
63 case 0:
64 createScene(11, 0);
65 break;
66 case 1:
67 createScene(13, 0);
68 break;
69 case 2:
70 createScene(14, 0);
71 break;
72 case 3:
73 createScene(15, 0);
74 break;
75 case 4:
76 createScene(7, 0);
77 break;
78 case 5:
79 createScene(5, 1);
80 break;
81 case 6:
82 createScene(5, 5);
83 break;
84 case 7:
85 createScene(3, 0);
86 break;
87 case 8:
88 createScene(1, 0);
89 break;
90 case 9:
91 createScene(2, 0);
92 break;
93 case 10:
94 createScene(6, 0);
95 break;
96 case 11:
97 createScene(4, 0);
98 break;
99 default:
100 createScene(12, 0);
101 break;
102 }
103 }
104
105 }
106
~Module1300()107 Module1300::~Module1300() {
108 _vm->_soundMan->deleteGroup(0x61C090);
109 }
110
createScene(int sceneNum,int which)111 void Module1300::createScene(int sceneNum, int which) {
112 debug(1, "Module1300::createScene(%d, %d)", sceneNum, which);
113 _sceneNum = sceneNum;
114 switch (_sceneNum) {
115 case 1:
116 _vm->gameState().sceneNum = 1;
117 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
118 _vm->_soundMan->startMusic(0x00203197, 0, 2);
119 _childObject = new Scene1302(_vm, this, which);
120 break;
121 case 2:
122 _vm->gameState().sceneNum = 2;
123 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
124 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
125 _childObject = new Scene1303(_vm, this);
126 break;
127 case 3:
128 _vm->gameState().sceneNum = 3;
129 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
130 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
131 _childObject = new Scene1304(_vm, this, which);
132 break;
133 case 4:
134 _vm->gameState().sceneNum = 4;
135 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
136 _vm->_soundMan->startMusic(0x00203197, 0, 2);
137 _childObject = new Scene1305(_vm, this, which);
138 break;
139 case 5:
140 _vm->gameState().sceneNum = 5;
141 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
142 _vm->_soundMan->startMusic(0x00203197, 0, 2);
143 _childObject = new Scene1306(_vm, this, which);
144 break;
145 case 6:
146 _vm->gameState().sceneNum = 6;
147 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
148 _vm->_soundMan->startMusic(0x00203197, 0, 2);
149 _childObject = new Scene1307(_vm, this);
150 break;
151 case 7:
152 _vm->gameState().sceneNum = 7;
153 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
154 _vm->_soundMan->startMusic(0x00203197, 0, 2);
155 _childObject = new Scene1308(_vm, this, which);
156 break;
157 case 8:
158 _vm->gameState().sceneNum = 8;
159 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
160 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
161 _childObject = new DiskplayerScene(_vm, this, 1);
162 break;
163 case 9:
164 _vm->gameState().sceneNum = 9;
165 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
166 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
167 createSmackerScene(0x20082818, true, true, false);
168 break;
169 case 10:
170 _vm->gameState().sceneNum = 10;
171 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
172 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
173 createSmackerScene(0x20082828, true, true, false);
174 break;
175 case 11:
176 _vm->gameState().sceneNum = 11;
177 _vm->_soundMan->setSoundListParams(kModule1300SoundList, true, 0, 0, 0, 0);
178 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
179 createNavigationScene(0x004B27A8, which);
180 break;
181 case 12:
182 _vm->gameState().sceneNum = 12;
183 _vm->_soundMan->setSoundListParams(kModule1300SoundList, true, 0, 0, 0, 0);
184 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
185 createNavigationScene(0x004B2718, which);
186 break;
187 case 13:
188 _vm->gameState().sceneNum = 13;
189 _vm->_soundMan->setSoundListParams(kModule1300SoundList, true, 0, 0, 0, 0);
190 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
191 createNavigationScene(0x004B27D8, which);
192 break;
193 case 14:
194 _vm->gameState().sceneNum = 14;
195 _vm->_soundMan->setSoundListParams(kModule1300SoundList, true, 0, 0, 0, 0);
196 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
197 createNavigationScene(0x004B2808, which);
198 break;
199 case 15:
200 _vm->gameState().sceneNum = 15;
201 _vm->_soundMan->setSoundListParams(kModule1300SoundList, true, 0, 0, 0, 0);
202 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
203 createNavigationScene(0x004B2838, which);
204 break;
205 case 16:
206 _vm->gameState().sceneNum = 16;
207 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
208 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
209 _childObject = new Scene1317(_vm, this);
210 break;
211 case 17:
212 _vm->gameState().sceneNum = 17;
213 _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 0, 0, 0, 0);
214 _vm->_soundMan->stopMusic(0x00203197, 0, 2);
215 _childObject = new CreditsScene(_vm, this, false);
216 break;
217 default:
218 break;
219 }
220 SetUpdateHandler(&Module1300::updateScene);
221 _childObject->handleUpdate();
222 }
223
updateScene()224 void Module1300::updateScene() {
225 if (!updateChild()) {
226 switch (_sceneNum) {
227 case 1:
228 if (_moduleResult == 1)
229 createScene(4, 0);
230 else
231 createScene(7, 1);
232 break;
233 case 2:
234 createScene(5, 3);
235 break;
236 case 3:
237 createScene(15, 0);
238 break;
239 case 4:
240 createScene(16, -1);
241 break;
242 case 5:
243 if (_moduleResult == 2)
244 createScene(8, 0);
245 else if (_moduleResult == 3)
246 createScene(2, 0);
247 else if (_moduleResult == 0)
248 leaveModule(0);
249 else if (_moduleResult == 1)
250 createScene(10, -1);
251 break;
252 case 6:
253 createScene(7, 2);
254 break;
255 case 7:
256 if (_moduleResult == 0)
257 createScene(13, 0);
258 else if (_moduleResult == 1)
259 createScene(1, 0);
260 else if (_moduleResult == 2)
261 createScene(6, 0);
262 break;
263 case 8:
264 createScene(5, 2);
265 break;
266 case 9:
267 createScene(5, 0);
268 break;
269 case 10:
270 createScene(14, 0);
271 break;
272 case 11:
273 if (_moduleResult == 0)
274 createScene(12, 0);
275 else if (_moduleResult == 1)
276 createScene(11, 1);
277 break;
278 case 12:
279 if (_moduleResult == 0)
280 createScene(14, 1);
281 else if (_moduleResult == 1)
282 createScene(15, 1);
283 else if (_moduleResult == 3)
284 createScene(11, 1);
285 else if (_moduleResult == 5)
286 createScene(13, 1);
287 break;
288 case 13:
289 if (_moduleResult == 0)
290 createScene(12, 2);
291 else if (_moduleResult == 1)
292 createScene(7, 0);
293 break;
294 case 14:
295 if (_moduleResult == 0)
296 createScene(12, 3);
297 else if (_moduleResult == 1)
298 createScene(9, -1);
299 break;
300 case 15:
301 if (_moduleResult == 0)
302 createScene(12, 4);
303 else if (_moduleResult == 1)
304 createScene(3, 0);
305 break;
306 case 16:
307 createScene(17, -1);
308 break;
309 case 17:
310 leaveModule(1);
311 break;
312 default:
313 break;
314 }
315 }
316 }
317
Scene1302(NeverhoodEngine * vm,Module * parentModule,int which)318 Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
319 : Scene(vm, parentModule) {
320
321 SetMessageHandler(&Scene1302::handleMessage);
322
323 setHitRects(0x004B0858);
324 setRectList(0x004B0A38);
325 setBackground(0x420643C4);
326 setPalette(0x420643C4);
327 insertScreenMouse(0x643C0428);
328
329 _class595 = insertStaticSprite(0xB0420130, 1015);
330 _sprite1 = insertStaticSprite(0x942FC224, 300);
331 _sprite2 = insertStaticSprite(0x70430830, 1200);
332 _sprite2->setVisible(false);
333 _sprite3 = insertStaticSprite(0x16E01E20, 1100);
334 _asRing1 = insertSprite<AsScene1002Ring>(this, false, 218, 122, _class595->getDrawRect().y, false);
335 _asRing2 = insertSprite<AsScene1002Ring>(this, true, 218 + 32, 132, _class595->getDrawRect().y, getGlobalVar(V_FLYTRAP_RING_BRIDGE));
336 _asRing3 = insertSprite<AsScene1002Ring>(this, false, 218 + 32 + 32, 122, _class595->getDrawRect().y, false);
337 _asRing4 = insertSprite<AsScene1002Ring>(this, true, 218 + 32 + 32 + 32, 132, _class595->getDrawRect().y, getGlobalVar(V_FLYTRAP_RING_FENCE));
338 _asRing5 = insertSprite<AsScene1002Ring>(this, false, 218 + 32 + 32 + 32 + 32, 115, _class595->getDrawRect().y, false);
339 _asBridge = insertSprite<AsScene1302Bridge>(this);
340 _ssFence = insertSprite<SsScene1302Fence>();
341 _ssFence->setClipRect(0, 0, 640, _sprite1->getDrawRect().y2());
342
343 if (which < 0) {
344 // Restoring game
345 insertKlaymen<KmScene1002>(380, 364);
346 setMessageList(0x004B0868);
347 } else {
348 // Klaymen entering from back
349 insertKlaymen<KmScene1002>(293, 330);
350 setMessageList(0x004B0870);
351 }
352
353 _klaymen->setClipRect(0, 0, _sprite3->getDrawRect().x2(), 480);
354
355 _asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, true);
356 addCollisionSprite(_asVenusFlyTrap);
357
358 sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
359
360 }
361
handleMessage(int messageNum,const MessageParam & param,Entity * sender)362 uint32 Scene1302::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
363 uint32 messageResult = 0;
364 Scene::handleMessage(messageNum, param, sender);
365 switch (messageNum) {
366 case NM_ANIMATION_START:
367 if (param.asInteger() == 0x4A845A00) {
368 sendEntityMessage(_klaymen, 0x1014, _asRing1);
369 } else if (param.asInteger() == 0x43807801) {
370 if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
371 sendEntityMessage(_klaymen, 0x1014, _asRing2);
372 if (_asVenusFlyTrap->getX() - 10 < 218 + 32 && _asVenusFlyTrap->getX() + 10 > 218 + 32)
373 setMessageList(0x004B0940);
374 else
375 setMessageList(0x004B0938);
376 } else
377 setMessageList(0x004B0950);
378 messageResult = 1;
379 } else if (param.asInteger() == 0x46C26A01) {
380 sendEntityMessage(_klaymen, 0x1014, _asRing3);
381 } else if (param.asInteger() == 0x468C7B11) {
382 if (!getGlobalVar(V_FLYTRAP_RING_FENCE)) {
383 sendEntityMessage(_klaymen, 0x1014, _asRing4);
384 if (_asVenusFlyTrap->getX() - 10 < 218 + 32 + 32 + 32 && _asVenusFlyTrap->getX() + 10 > 218 + 32 + 32 + 32)
385 setMessageList(0x004B0940);
386 else
387 setMessageList(0x004B0938);
388 } else
389 setMessageList(0x004B0950);
390 messageResult = 1;
391 } else if (param.asInteger() == 0x42845B19) {
392 sendEntityMessage(_klaymen, 0x1014, _asRing5);
393 } else if (param.asInteger() == 0x430A6060) {
394 if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
395 setMessageList2(0x004B0910);
396 else
397 cancelMessageList();
398 } else if (param.asInteger() == 0x012E2070) {
399 if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
400 setMessageList2(0x004B0968);
401 else
402 cancelMessageList();
403 } else if (param.asInteger() == 0x11C40840) {
404 if (_asVenusFlyTrap->getX() >= 260 && _asVenusFlyTrap->getX() <= 342)
405 setMessageList(0x004B0878);
406 else
407 setMessageList(0x004B0978);
408 }
409 break;
410 case NM_ANIMATION_UPDATE:
411 if (_klaymen->getY() > 360) {
412 sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap);
413 setMessageList2(0x004B08F0);
414 } else
415 setMessageList2(0x004B0920);
416 break;
417 case NM_POSITION_CHANGE:
418 if (_klaymen->getX() > 545)
419 leaveScene(1);
420 break;
421 case 0x2032:
422 _sprite2->setVisible(true);
423 break;
424 case NM_KLAYMEN_USE_OBJECT:
425 sendMessage(_parentModule, 0x1024, 2);
426 if (sender == _asRing1)
427 playSound(0, 0x665198C0);
428 else if (sender == _asRing2) {
429 sendMessage(_asBridge, NM_KLAYMEN_OPEN_DOOR, 0);
430 setGlobalVar(V_FLYTRAP_RING_BRIDGE, 1);
431 } else if (sender == _asRing3) {
432 playSound(0, 0xE2D389C0);
433 } else if (sender == _asRing4) {
434 sendMessage(_ssFence, NM_KLAYMEN_OPEN_DOOR, 0);
435 setGlobalVar(V_FLYTRAP_RING_FENCE, 1);
436 } else if (sender == _asRing5)
437 playSound(0, 0x40428A09);
438 break;
439 case NM_KLAYMEN_RAISE_LEVER:
440 if (sender == _asRing2) {
441 sendMessage(_asBridge, NM_KLAYMEN_CLOSE_DOOR, 0);
442 setGlobalVar(V_FLYTRAP_RING_BRIDGE, 0);
443 _sprite2->setVisible(false);
444 } else if (sender == _asRing4) {
445 sendMessage(_ssFence, NM_KLAYMEN_CLOSE_DOOR, 0);
446 setGlobalVar(V_FLYTRAP_RING_FENCE, 0);
447 } else if (sender == _asVenusFlyTrap) {
448 if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
449 sendMessage(_asRing2, NM_KLAYMEN_RAISE_LEVER, 0);
450 else
451 sendMessage(_asRing4, NM_KLAYMEN_RAISE_LEVER, 0);
452 }
453 break;
454 case NM_KLAYMEN_LOWER_LEVER:
455 if (sender == _asRing2) {
456 playSound(0, 0x60755842);
457 sendMessage(_asBridge, NM_KLAYMEN_OPEN_DOOR, 0);
458 setGlobalVar(V_FLYTRAP_RING_BRIDGE, 1);
459 } else if (sender == _asRing4) {
460 playSound(0, 0x60755842);
461 sendMessage(_ssFence, NM_KLAYMEN_OPEN_DOOR, 0);
462 setGlobalVar(V_FLYTRAP_RING_FENCE, 1);
463 }
464 break;
465 case NM_MOVE_TO_BACK:
466 sendMessage(_asVenusFlyTrap, NM_MOVE_TO_FRONT, 0);
467 break;
468 case NM_MOVE_TO_FRONT:
469 sendMessage(_asVenusFlyTrap, NM_MOVE_TO_BACK, 0);
470 break;
471 case 0x8000:
472 setSpriteSurfacePriority(_class595, 995);
473 break;
474 case 0x8001:
475 setSpriteSurfacePriority(_class595, 1015);
476 break;
477 default:
478 break;
479 }
480 return messageResult;
481 }
482
Scene1303(NeverhoodEngine * vm,Module * parentModule)483 Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
484 : Scene(vm, parentModule), _asBalloon(NULL) {
485
486 SetMessageHandler(&Scene1303::handleMessage);
487
488 setRectList(0x004AF9E8);
489 setBackground(0x01581A9C);
490 setPalette(0x01581A9C);
491 insertScreenMouse(0x81A9801D);
492
493 if (!getGlobalVar(V_BALLOON_POPPED)) {
494 _asBalloon = insertSprite<AsScene1303Balloon>(this);
495 addCollisionSprite(_asBalloon);
496 }
497
498 _sprite1 = insertStaticSprite(0xA014216B, 1100);
499
500 insertKlaymen<KmScene1303>(207, 332);
501 setMessageList(0x004AF9A0);
502
503 _klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
504
505 }
506
handleMessage(int messageNum,const MessageParam & param,Entity * sender)507 uint32 Scene1303::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
508 Scene::handleMessage(messageNum, param, sender);
509 switch (messageNum) {
510 case NM_ANIMATION_UPDATE:
511 setGlobalVar(V_BALLOON_POPPED, 1);
512 sendMessage(_asBalloon, 0x2000, 0);
513 break;
514 case 0x4826:
515 if (sender == _asBalloon && getGlobalVar(V_HAS_NEEDLE))
516 setMessageList(0x004AF9B8);
517 break;
518 default:
519 break;
520 }
521 return 0;
522 }
523
Scene1304(NeverhoodEngine * vm,Module * parentModule,int which)524 Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
525 : Scene(vm, parentModule), _asNeedle(NULL) {
526
527 SetMessageHandler(&Scene1304::handleMessage);
528
529 setRectList(0x004B91A8);
530 setBackground(0x062C0214);
531 setPalette(0x062C0214);
532 insertScreenMouse(0xC021006A);
533
534 if (getGlobalVar(V_BALLOON_POPPED)) {
535 _asKey = insertSprite<AsCommonKey>(this, 0, 1100, 278, 347);
536 addCollisionSprite(_asKey);
537 } else {
538 _asKey = insertSprite<AnimatedSprite>(0x80106018, 100, 279, 48);
539 }
540
541 if (!getGlobalVar(V_HAS_NEEDLE)) {
542 _asNeedle = insertSprite<AsScene1304Needle>(this, 1100, 278, 347);
543 addCollisionSprite(_asNeedle);
544 }
545
546 _sprite1 = insertStaticSprite(0x0562E621, 1100);
547 insertStaticSprite(0x012AE033, 1100);
548 insertStaticSprite(0x090AF033, 1100);
549
550 if (which < 0) {
551 // Restoring game
552 insertKlaymen<KmScene1304>(217, 347);
553 setMessageList(0x004B90E8);
554 } else {
555 // Klaymen entering from the left
556 insertKlaymen<KmScene1304>(100, 347);
557 setMessageList(0x004B90F0);
558 }
559
560 _klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
561
562 }
563
handleMessage(int messageNum,const MessageParam & param,Entity * sender)564 uint32 Scene1304::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
565 Scene::handleMessage(messageNum, param, sender);
566 switch (messageNum) {
567 case NM_ANIMATION_START:
568 if (param.asInteger() == 0x415634A4) {
569 if (getGlobalVar(V_BALLOON_POPPED))
570 cancelMessageList();
571 else
572 setMessageList(0x004B9158);
573 }
574 break;
575 case 0x4826:
576 if (sender == _asNeedle) {
577 sendEntityMessage(_klaymen, 0x1014, _asNeedle);
578 setMessageList(0x004B9130);
579 } else if (sender == _asKey) {
580 sendEntityMessage(_klaymen, 0x1014, _asKey);
581 setMessageList(0x004B9140);
582 }
583 break;
584 default:
585 break;
586 }
587 return 0;
588 }
589
Scene1305(NeverhoodEngine * vm,Module * parentModule,int which)590 Scene1305::Scene1305(NeverhoodEngine *vm, Module *parentModule, int which)
591 : Scene(vm, parentModule) {
592
593 SetMessageHandler(&Scene1305::handleMessage);
594
595 setRectList(0x004B6E98);
596 setBackground(0x28801B64);
597 setPalette(0x28801B64);
598 insertScreenMouse(0x01B60280);
599
600 if (which < 0) {
601 // Restoring game
602 insertKlaymen<KmScene1305>(212, 441);
603 setMessageList(0x004B6E40);
604 } else {
605 // Klaymen enters falling
606 insertKlaymen<KmScene1305>(212, 441);
607 setMessageList(0x004B6E48);
608 }
609
610 }
611
handleMessage(int messageNum,const MessageParam & param,Entity * sender)612 uint32 Scene1305::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
613 return Scene::handleMessage(messageNum, param, sender);
614 }
615
Scene1306(NeverhoodEngine * vm,Module * parentModule,int which)616 Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
617 : Scene(vm, parentModule), _asKey(nullptr) {
618
619 if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
620 setGlobalVar(V_KEY3_LOCATION, 4);
621
622 SetMessageHandler(&Scene1306::handleMessage);
623
624 setBackground(0x05303114);
625 setPalette(0x05303114);
626 insertScreenMouse(0x0311005B);
627
628 if (getGlobalVar(V_KEY3_LOCATION) == 4) {
629 _asKey = insertSprite<AsCommonKey>(this, 2, 1100, 435, 445);
630 addCollisionSprite(_asKey);
631 }
632
633 _ssButton = insertSprite<SsCommonButtonSprite>(this, 0x404A36A0, 100, 0x440C1000);
634 _asTape = insertSprite<AsScene1201Tape>(this, 19, 1100, 359, 445, 0x9148A011);
635 _asElevatorDoor = insertSprite<AnimatedSprite>(0x043B0270, 90, 320, 240);
636 _asElevatorDoor->startAnimation(0x043B0270, 6, -1);
637 _asElevatorDoor->setNewHashListIndex(6);
638 _asElevator = insertSprite<AsScene1306Elevator>(this, _asElevatorDoor);
639 _sprite1 = insertStaticSprite(0x036A1EE0, 80);
640 insertStaticSprite(0x00042313, 1100);
641
642 if (which < 0) {
643 // Restoring game
644 insertKlaymen<KmScene1306>(380, 440);
645 setMessageList(0x004AFAD0);
646 sendMessage(this, 0x2000, 0);
647 addCollisionSprite(_asTape);
648 } else if (which == 1) {
649 // Klaymen teleporting in
650 insertKlaymen<KmScene1306>(136, 440);
651 sendMessage(_klaymen, 0x2000, 1);
652 setMessageList(0x004AFAF0);
653 sendMessage(this, 0x2000, 1);
654 addCollisionSprite(_asTape);
655 } else if (which == 2) {
656 // Klaymen returning from diskplayer
657 if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
658 insertKlaymen<KmScene1306>(515, 440);
659 _klaymen->setDoDeltaX(1);
660 } else {
661 insertKlaymen<KmScene1306>(355, 440);
662 }
663 setMessageList(0x004AFBC8);
664 sendMessage(this, 0x2000, 0);
665 addCollisionSprite(_asTape);
666 } else if (which == 3) {
667 // Klaymen returning from window
668 insertKlaymen<KmScene1306>(534, 440);
669 setMessageList(0x004AFC30);
670 sendMessage(this, 0x2000, 0);
671 addCollisionSprite(_asTape);
672 } else if (which == 4) {
673 // Klaymen teleporting out
674 insertKlaymen<KmScene1306>(136, 440);
675 sendMessage(_klaymen, 0x2000, 1);
676 setMessageList(0x004AFC38);
677 sendMessage(this, 0x2000, 1);
678 addCollisionSprite(_asTape);
679 } else if (which == 5) {
680 // Klaymen returning from teleporter
681 insertKlaymen<KmScene1306>(136, 440);
682 sendMessage(_klaymen, 0x2000, 1);
683 setMessageList(0x004AFB00);
684 sendMessage(this, 0x2000, 1);
685 addCollisionSprite(_asTape);
686 } else {
687 // Klaymen coming up in elevator
688 insertKlaymen<KmScene1306>(286, 408);
689 setSurfacePriority(_asElevator->getSurface(), 1100);
690 setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
691 setSurfacePriority(_sprite1->getSurface(), 1080);
692 sendMessage(this, 0x2000, 0);
693 SetMessageHandler(&Scene1306::handleMessage416EB0);
694 clearRectList();
695 sendMessage(_asElevator, NM_KLAYMEN_OPEN_DOOR, 0);
696 }
697 }
698
~Scene1306()699 Scene1306::~Scene1306() {
700 setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
701 }
702
handleMessage(int messageNum,const MessageParam & param,Entity * sender)703 uint32 Scene1306::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
704 Scene::handleMessage(messageNum, param, sender);
705 switch (messageNum) {
706 case NM_ANIMATION_START:
707 if (param.asInteger() == 0x402064D8)
708 sendEntityMessage(_klaymen, 0x1014, _ssButton);
709 else if (param.asInteger() == 0x01C66840) {
710 if (sendMessage(_asElevator, 0x2001, 0) != 0)
711 setMessageList(0x004AFBD8);
712 else
713 setMessageList(0x004AFAE0);
714 } else if (param.asInteger() == 0x8E646E00) {
715 setMessageList(0x004AFAD8);
716 clearRectList();
717 SetMessageHandler(&Scene1306::handleMessage416EB0);
718 }
719 break;
720 case NM_ANIMATION_UPDATE:
721 if (param.asInteger() != 0) {
722 setRectList(0x004AFD28);
723 _klaymen->setKlaymenIdleTable3();
724 } else {
725 setRectList(0x004AFD18);
726 _klaymen->setKlaymenIdleTable1();
727 }
728 break;
729 case 0x480B:
730 if (sender == _ssButton)
731 sendMessage(_asElevator, NM_KLAYMEN_OPEN_DOOR, 0);
732 break;
733 case 0x4826:
734 if (sender == _asKey) {
735 if (_klaymen->getX() >= 249) {
736 sendEntityMessage(_klaymen, 0x1014, _asKey);
737 setMessageList(0x004AFC58);
738 }
739 } else if (sender == _asTape) {
740 if (_klaymen->getX() >= 249) {
741 sendEntityMessage(_klaymen, 0x1014, _asTape);
742 setMessageList(0x004AFC68);
743 }
744 }
745 break;
746 case NM_MOVE_TO_BACK:
747 setSurfacePriority(_asElevator->getSurface(), 1100);
748 setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
749 setSurfacePriority(_sprite1->getSurface(), 1080);
750 break;
751 case NM_MOVE_TO_FRONT:
752 setSurfacePriority(_asElevator->getSurface(), 100);
753 setSurfacePriority(_asElevatorDoor->getSurface(), 90);
754 setSurfacePriority(_sprite1->getSurface(), 80);
755 sendMessage(this, 0x2000, 0);
756 addCollisionSprite(_asTape);
757 break;
758 default:
759 break;
760 }
761 return 0;
762 }
763
handleMessage416EB0(int messageNum,const MessageParam & param,Entity * sender)764 uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam ¶m, Entity *sender) {
765 Scene::handleMessage(messageNum, param, sender);
766 switch (messageNum) {
767 case NM_KLAYMEN_OPEN_DOOR:
768 setMessageList(0x004AFBD0);
769 SetMessageHandler(&Scene1306::handleMessage);
770 break;
771 case NM_KLAYMEN_CLOSE_DOOR:
772 leaveScene(1);
773 break;
774 case NM_MOVE_TO_BACK:
775 setSurfacePriority(_asElevator->getSurface(), 1100);
776 setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
777 setSurfacePriority(_sprite1->getSurface(), 1080);
778 break;
779 case NM_MOVE_TO_FRONT:
780 setSurfacePriority(_asElevator->getSurface(), 100);
781 setSurfacePriority(_asElevatorDoor->getSurface(), 90);
782 setSurfacePriority(_sprite1->getSurface(), 80);
783 sendMessage(this, 0x2000, 0);
784 addCollisionSprite(_asTape);
785 break;
786 default:
787 break;
788 }
789 return 0;
790 }
791
Scene1307(NeverhoodEngine * vm,Module * parentModule)792 Scene1307::Scene1307(NeverhoodEngine *vm, Module *parentModule)
793 : Scene(vm, parentModule), _countdown(0), _asCurrKey(NULL),
794 _isInsertingKey(false), _doLeaveScene(false), _isPuzzleSolved(false) {
795
796 Sprite *tempSprite;
797
798 _vm->gameModule()->initKeySlotsPuzzle();
799
800 _dataResource.load(0x22102142);
801 _keyHolePoints = _dataResource.getPointArray(0xAC849240);
802
803 for (uint i = 0; i < 16; i++) {
804 NPoint pt = (*_keyHolePoints)[i];
805 _keyHoleRects[i].x1 = pt.x - 15;
806 _keyHoleRects[i].y1 = pt.y - 15;
807 _keyHoleRects[i].x2 = pt.x + 15;
808 _keyHoleRects[i].y2 = pt.y + 15;
809 }
810
811 SetMessageHandler(&Scene1307::handleMessage);
812 SetUpdateHandler(&Scene1307::update);
813
814 setBackground(0xA8006200);
815 setPalette(0xA8006200);
816 addEntity(_palette);
817 insertPuzzleMouse(0x06204A88, 20, 620);
818
819 tempSprite = insertStaticSprite(0x00A3621C, 800);
820 _clipRects[0].set(tempSprite->getDrawRect().x, 0, 640, 480);
821 tempSprite = insertStaticSprite(0x00A3641C, 600);
822 _clipRects[1].set(tempSprite->getDrawRect().x, 0, 640, 480);
823 tempSprite = insertStaticSprite(0x00A3681C, 400);
824 _clipRects[2].set(tempSprite->getDrawRect().x, 0, 640, 480);
825 tempSprite = insertStaticSprite(0x00A3701C, 200);
826 _clipRects[3].set(tempSprite->getDrawRect().x, 0, 640, 480);
827
828 for (uint keyIndex = 0; keyIndex < 3; keyIndex++) {
829 if (getSubVar(VA_IS_KEY_INSERTED, keyIndex)) {
830 _asKeys[keyIndex] = insertSprite<AsScene1307Key>(this, keyIndex, _clipRects);
831 addCollisionSprite(_asKeys[keyIndex]);
832 } else {
833 _asKeys[keyIndex] = NULL;
834 }
835 }
836
837 loadSound(0, 0x68E25540);
838 }
839
update()840 void Scene1307::update() {
841 Scene::update();
842 if (_countdown && (--_countdown == 0))
843 _doLeaveScene = true;
844 else if (_countdown == 20)
845 _palette->startFadeToWhite(40);
846 if (_doLeaveScene && !isSoundPlaying(0)) {
847 leaveScene(1);
848 setGlobalVar(V_KEYDOOR_UNLOCKED, 1);
849 }
850 }
851
handleMessage(int messageNum,const MessageParam & param,Entity * sender)852 uint32 Scene1307::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
853 uint32 messageResult = 0;
854 Scene::handleMessage(messageNum, param, sender);
855 switch (messageNum) {
856 case NM_MOUSE_CLICK:
857 if (!_isPuzzleSolved) {
858 if (param.asPoint().x > 20 && param.asPoint().x < 620) {
859 if (_asCurrKey && !_isInsertingKey) {
860 int16 mouseX = param.asPoint().x;
861 int16 mouseY = param.asPoint().y;
862 uint clickedKeyHoleIndex;
863 for (clickedKeyHoleIndex = 0; clickedKeyHoleIndex < 16; clickedKeyHoleIndex++) {
864 if (mouseX >= _keyHoleRects[clickedKeyHoleIndex].x1 && mouseX <= _keyHoleRects[clickedKeyHoleIndex].x2 &&
865 mouseY >= _keyHoleRects[clickedKeyHoleIndex].y1 && mouseY <= _keyHoleRects[clickedKeyHoleIndex].y2)
866 break;
867 }
868 if (clickedKeyHoleIndex < 16) {
869 // Check if the clicked keyhole is already occupied with a key
870 bool occupied = false;
871 for (uint keyIndex = 0; keyIndex < 3 && !occupied; keyIndex++) {
872 if (getSubVar(VA_IS_KEY_INSERTED, keyIndex) && _asKeys[keyIndex] != _asCurrKey) {
873 if (getSubVar(VA_CURR_KEY_SLOT_NUMBERS, keyIndex) == clickedKeyHoleIndex)
874 occupied = true;
875 }
876 }
877 if (!occupied) {
878 // If the keyhole is free, insert the current key
879 sendMessage(_asCurrKey, 0x2001, clickedKeyHoleIndex);
880 _isInsertingKey = true;
881 _mouseClicked = false;
882 }
883 }
884 }
885 } else if (_countdown == 0 && !_asCurrKey && !_isInsertingKey)
886 leaveScene(0);
887 }
888 break;
889 case NM_POSITION_CHANGE:
890 // Check if all keys are in the correct keyholes
891 if (getSubVar(VA_IS_KEY_INSERTED, 0) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 0) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 0) &&
892 getSubVar(VA_IS_KEY_INSERTED, 1) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 1) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 1) &&
893 getSubVar(VA_IS_KEY_INSERTED, 2) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 2) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 2)) {
894 // Play unlock animations for all keys
895 for (uint keyIndex = 0; keyIndex < 3; keyIndex++) {
896 if (_asKeys[keyIndex])
897 sendMessage(_asKeys[keyIndex], 0x2003, 1);
898 }
899 playSound(0);
900 _isPuzzleSolved = true;
901 _countdown = 47;
902 } else {
903 for (uint keyIndex = 0; keyIndex < 3; keyIndex++)
904 if (getSubVar(VA_IS_KEY_INSERTED, keyIndex) && _asKeys[keyIndex])
905 sendMessage(_asKeys[keyIndex], 0x2000, 1);
906 sendMessage(_asCurrKey, 0x2004, 1);
907 }
908 _asCurrKey = NULL;
909 _isInsertingKey = false;
910 break;
911 case 0x4826:
912 _asCurrKey = (Sprite*)sender;
913 for (uint keyIndex = 0; keyIndex < 3; keyIndex++)
914 if (getSubVar(VA_IS_KEY_INSERTED, keyIndex) && _asKeys[keyIndex])
915 sendMessage(_asKeys[keyIndex], 0x2000, 0);
916 break;
917 default:
918 break;
919 }
920 return messageResult;
921 }
922
923 static const uint32 kScene1308NumberFileHashes[] = {
924 0x08006320, 0x10006320, 0x20006320,
925 0x40006320, 0x80006320, 0x00006321,
926 0x00006322, 0x00006324, 0x00006328,
927 0x08306320, 0x10306320, 0x20306320,
928 0x40306320, 0x80306320, 0x00306321,
929 0x00306322
930 };
931
Scene1308(NeverhoodEngine * vm,Module * parentModule,int which)932 Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
933 : Scene(vm, parentModule), _isProjecting(false), _asProjector(NULL) {
934
935 _vm->gameModule()->initKeySlotsPuzzle();
936
937 SetMessageHandler(&Scene1308::handleMessage);
938
939 setBackground(0x41024202);
940 setPalette(0x41024202);
941 insertScreenMouse(0x24206418);
942
943 _asTape = insertSprite<AsScene1201Tape>(this, 17, 1100, 502, 445, 0x9148A011);
944 addCollisionSprite(_asTape);
945
946 if (getGlobalVar(V_MOUSE_SUCKED_IN)) {
947 insertSprite<AsScene1308Mouse>();
948 insertSprite<AnimatedSprite>(0x461A1490, 200, 235, 429);
949 }
950
951 _sprite1 = insertStaticSprite(0x0A042060, 1100);
952 _asJaggyDoor = insertSprite<AsScene1308JaggyDoor>(this);
953 _asLightWallSymbols = insertSprite<AsScene1308LightWallSymbols>(this);
954 _ssNumber1 = insertSprite<SsScene1308Number>(kScene1308NumberFileHashes[getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 1)], 0);
955 _ssNumber2 = insertSprite<SsScene1308Number>(kScene1308NumberFileHashes[getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 0)], 1);
956 _ssNumber3 = insertSprite<SsScene1308Number>(kScene1308NumberFileHashes[getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 2)], 2);
957 _sprite2 = insertStaticSprite(0x40043120, 995);
958 _sprite3 = insertStaticSprite(0x43003100, 995);
959 _sprite4 = NULL;
960 _sprite5 = nullptr;
961
962 if (which < 0) {
963 // Restoring game
964 insertKlaymen<KmScene1308>(380, 440);
965 setMessageList(0x004B57C0);
966 if (getGlobalVar(V_KEYDOOR_UNLOCKED)) {
967 _sprite4 = insertStaticSprite(0x0101A624, 1100);
968 setRectList(0x004B5990);
969 } else {
970 _sprite5 = insertStaticSprite(0x080811A0, 100);
971 setRectList(0x004B5980);
972 }
973 } else if (which == 1) {
974 // Klaymen entering from the right
975 insertKlaymen<KmScene1308>(640, 440);
976 setMessageList(0x004B57C8);
977 if (getGlobalVar(V_KEYDOOR_UNLOCKED)) {
978 _sprite4 = insertStaticSprite(0x0101A624, 1100);
979 setRectList(0x004B5990);
980 } else {
981 _sprite5 = insertStaticSprite(0x080811A0, 100);
982 setRectList(0x004B5980);
983 }
984 } else if (which == 2) {
985 // Klaymen returning from keyslots panel
986 insertKlaymen<KmScene1308>(475, 440);
987 setMessageList(0x004B58B0);
988 if (getGlobalVar(V_KEYDOOR_UNLOCKED)) {
989 _sprite5 = insertSprite<AsScene1308KeyboardDoor>(this);
990 _sprite4 = insertStaticSprite(0x0101A624, 1100);
991 _sprite4->setVisible(false);
992 } else {
993 _sprite5 = insertStaticSprite(0x080811A0, 100);
994 setRectList(0x004B5980);
995 }
996 } else {
997 // Klaymen entering from the left
998 insertKlaymen<KmScene1308>(41, 440);
999 setMessageList(0x004B57D0);
1000 sendMessage(_asJaggyDoor, NM_KLAYMEN_OPEN_DOOR, 0);
1001 _sprite1->setVisible(false);
1002 if (getGlobalVar(V_KEYDOOR_UNLOCKED)) {
1003 _sprite4 = insertStaticSprite(0x0101A624, 1100);
1004 _klaymen->setVisible(false);
1005 } else {
1006 _sprite5 = insertStaticSprite(0x080811A0, 100);
1007 _klaymen->setVisible(false);
1008 }
1009 }
1010
1011 if (_sprite4)
1012 _klaymen->setClipRect(_sprite1->getDrawRect().x, 0, _sprite4->getDrawRect().x2(), 480);
1013 else
1014 _klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
1015
1016 if (getGlobalVar(V_PROJECTOR_LOCATION) == 4) {
1017 _asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)NULL);
1018 addCollisionSprite(_asProjector);
1019 _asProjector->setClipRect(0, 0, 640, _sprite2->getDrawRect().y2());
1020 _asProjector->setRepl(64, 0);
1021 }
1022
1023 }
1024
handleMessage(int messageNum,const MessageParam & param,Entity * sender)1025 uint32 Scene1308::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
1026 Scene::handleMessage(messageNum, param, sender);
1027 switch (messageNum) {
1028 case NM_ANIMATION_START:
1029 if (param.asInteger() == 0x88C11390) {
1030 setRectList(0x004B59A0);
1031 _isProjecting = true;
1032 } else if (param.asInteger() == 0x08821382) {
1033 sendEntityMessage(_klaymen, 0x1014, _asProjector);
1034 if (getGlobalVar(V_KEYDOOR_UNLOCKED))
1035 setRectList(0x004B5990);
1036 else
1037 setRectList(0x004B5980);
1038 _isProjecting = false;
1039 } else if (param.asInteger() == 0x4AC68808) {
1040 clearRectList();
1041 sendMessage(_asJaggyDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
1042 _sprite1->setVisible(false);
1043 _klaymen->setVisible(false);
1044 }
1045 break;
1046 case NM_PRIORITY_CHANGE:
1047 if (sender == _asProjector) {
1048 if (param.asInteger() >= 1000)
1049 setSurfacePriority(_sprite3->getSurface(), 1100);
1050 else
1051 setSurfacePriority(_sprite3->getSurface(), 995);
1052 }
1053 break;
1054 case NM_ANIMATION_UPDATE:
1055 if (getGlobalVar(V_KEYDOOR_UNLOCKED))
1056 setRectList(0x004B5990);
1057 else
1058 setRectList(0x004B5980);
1059 setMessageList(0x004B57E8, false);
1060 _sprite1->setVisible(true);
1061 _klaymen->setVisible(true);
1062 break;
1063 case 0x2001:
1064 leaveScene(0);
1065 break;
1066 case 0x2003:
1067 _ssNumber1->setVisible(false);
1068 _ssNumber2->setVisible(false);
1069 _ssNumber3->setVisible(false);
1070 break;
1071 case 0x2004:
1072 _sprite4->setVisible(true);
1073 setRectList(0x004B5990);
1074 break;
1075 case NM_KLAYMEN_RAISE_LEVER:
1076 sendMessage(_asLightWallSymbols, 0x2003, 0);
1077 break;
1078 case NM_KLAYMEN_LOWER_LEVER:
1079 sendMessage(_asLightWallSymbols, NM_POSITION_CHANGE, 0);
1080 _ssNumber1->setVisible(true);
1081 _ssNumber2->setVisible(true);
1082 _ssNumber3->setVisible(true);
1083 break;
1084 case 0x4826:
1085 if (sender == _asProjector) {
1086 if (_isProjecting)
1087 setMessageList2(0x004B5868);
1088 else {
1089 if (param.asInteger() == 1) {
1090 sendEntityMessage(_klaymen, 0x1014, _asProjector);
1091 setMessageList2(0x004B5848);
1092 } else if (sendMessage(_asProjector, 0x480C, _klaymen->getX() <= _asProjector->getX() ? 0 : 1) != 0) {
1093 sendEntityMessage(_klaymen, 0x1014, _asProjector);
1094 setMessageList2(0x004B5830);
1095 } else
1096 setMessageList2(0x004B5800);
1097 }
1098 } else if (sender == _asTape) {
1099 if (_isProjecting)
1100 setMessageList2(0x004B5868);
1101 else if (_messageListStatus != 2) {
1102 sendEntityMessage(_klaymen, 0x1014, _asTape);
1103 setMessageList2(0x004B58E0);
1104 }
1105 }
1106 break;
1107 default:
1108 break;
1109 }
1110 return 0;
1111 }
1112
Scene1317(NeverhoodEngine * vm,Module * parentModule)1113 Scene1317::Scene1317(NeverhoodEngine *vm, Module *parentModule)
1114 : Scene(vm, parentModule) {
1115
1116 SetMessageHandler(&Scene1317::handleMessage);
1117 _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x08982841, true, false));
1118 _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
1119 insertScreenMouse(0x08284011);
1120 showMouse(false);
1121 _smackerFileHash = 0;
1122 _keepLastSmackerFrame = false;
1123 }
1124
update()1125 void Scene1317::update() {
1126 if (_smackerFileHash) {
1127 _smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame);
1128 _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
1129 _smackerFileHash = 0;
1130 }
1131 Scene::update();
1132 }
1133
upChooseKing()1134 void Scene1317::upChooseKing() {
1135 if (!_klaymenBlinks && _klaymenBlinkCountdown != 0 && (--_klaymenBlinkCountdown == 0))
1136 _klaymenBlinks = true;
1137
1138 if (!_klaymenBlinks && _smackerPlayer->getFrameNumber() + 1 >= 2) {
1139 _smackerPlayer->rewind();
1140 } else if (_klaymenBlinks && _smackerPlayer->getFrameNumber() + 1 >= 6) {
1141 _smackerPlayer->rewind();
1142 _klaymenBlinks = false;
1143 _klaymenBlinkCountdown = _vm->_rnd->getRandomNumber(30 - 1) + 15;
1144 }
1145
1146 if (!_klaymenBlinks && _decisionCountdown != 0 && (--_decisionCountdown == 0))
1147 stNoDecisionYet();
1148
1149 if (_smackerFileHash) {
1150 _smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame);
1151 _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
1152 _smackerFileHash = 0;
1153 }
1154
1155 Scene::update();
1156
1157 }
1158
handleMessage(int messageNum,const MessageParam & param,Entity * sender)1159 uint32 Scene1317::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
1160 uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
1161 switch (messageNum) {
1162 case NM_ANIMATION_STOP:
1163 stChooseKing();
1164 break;
1165 default:
1166 break;
1167 }
1168 return messageResult;
1169 }
1170
hmChooseKing(int messageNum,const MessageParam & param,Entity * sender)1171 uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam ¶m, Entity *sender) {
1172 uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
1173 switch (messageNum) {
1174 case NM_MOUSE_CLICK:
1175 if (param.asPoint().x >= 21 && param.asPoint().y >= 24 &&
1176 param.asPoint().x <= 261 && param.asPoint().y <= 280) {
1177 stHoborgAsKing();
1178 } else if (param.asPoint().x >= 313 && param.asPoint().y >= 184 &&
1179 param.asPoint().x <= 399 && param.asPoint().y <= 379) {
1180 stKlaymenAsKing();
1181 } else if (param.asPoint().x >= 347 && param.asPoint().y >= 380 &&
1182 param.asPoint().x <= 418 && param.asPoint().y <= 474) {
1183 stKlaymenAsKing();
1184 }
1185 break;
1186 default:
1187 break;
1188 }
1189 return messageResult;
1190 }
1191
hmHoborgAsKing(int messageNum,const MessageParam & param,Entity * sender)1192 uint32 Scene1317::hmHoborgAsKing(int messageNum, const MessageParam ¶m, Entity *sender) {
1193 uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
1194 switch (messageNum) {
1195 case NM_ANIMATION_STOP:
1196 stEndMovie();
1197 break;
1198 default:
1199 break;
1200 }
1201 return messageResult;
1202 }
1203
hmEndMovie(int messageNum,const MessageParam & param,Entity * sender)1204 uint32 Scene1317::hmEndMovie(int messageNum, const MessageParam ¶m, Entity *sender) {
1205 uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
1206 switch (messageNum) {
1207 case NM_ANIMATION_STOP:
1208 leaveScene(0);
1209 break;
1210 default:
1211 break;
1212 }
1213 return messageResult;
1214 }
1215
stChooseKing()1216 void Scene1317::stChooseKing() {
1217 showMouse(true);
1218 _smackerFileHash = 0x10982841;
1219 _keepLastSmackerFrame = true;
1220 _decisionCountdown = 450;
1221 _klaymenBlinks = false;
1222 _klaymenBlinkCountdown = _vm->_rnd->getRandomNumber(30 - 1) + 15;
1223 SetMessageHandler(&Scene1317::hmChooseKing);
1224 SetUpdateHandler(&Scene1317::upChooseKing);
1225 }
1226
stNoDecisionYet()1227 void Scene1317::stNoDecisionYet() {
1228 showMouse(false);
1229 _smackerFileHash = 0x20982841;
1230 _keepLastSmackerFrame = false;
1231 SetMessageHandler(&Scene1317::handleMessage);
1232 SetUpdateHandler(&Scene1317::update);
1233 }
1234
stHoborgAsKing()1235 void Scene1317::stHoborgAsKing() {
1236 showMouse(false);
1237 _smackerFileHash = 0x40982841;
1238 _keepLastSmackerFrame = false;
1239 SetMessageHandler(&Scene1317::hmHoborgAsKing);
1240 SetUpdateHandler(&Scene1317::update);
1241 }
1242
stKlaymenAsKing()1243 void Scene1317::stKlaymenAsKing() {
1244 showMouse(false);
1245 _smackerFileHash = 0x80982841;
1246 _keepLastSmackerFrame = false;
1247 SetMessageHandler(&Scene1317::hmEndMovie);
1248 SetUpdateHandler(&Scene1317::update);
1249 }
1250
stEndMovie()1251 void Scene1317::stEndMovie() {
1252 showMouse(false);
1253 _smackerFileHash = 0x40800711;
1254 _keepLastSmackerFrame = false;
1255 SetMessageHandler(&Scene1317::hmEndMovie);
1256 SetUpdateHandler(&Scene1317::update);
1257 }
1258
1259 } // End of namespace Neverhood
1260