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 "fullpipe/fullpipe.h"
24
25 #include "fullpipe/constants.h"
26 #include "fullpipe/gameloader.h"
27 #include "fullpipe/messages.h"
28 #include "fullpipe/modal.h"
29 #include "fullpipe/motion.h"
30 #include "fullpipe/objectnames.h"
31 #include "fullpipe/scenes.h"
32 #include "fullpipe/statics.h"
33
34 #include "engines/savestate.h"
35
36 #include "graphics/palette.h"
37 #include "graphics/surface.h"
38
39 namespace Fullpipe {
40
ModalIntro()41 ModalIntro::ModalIntro() {
42 _field_8 = 0;
43 _countDown = 0;
44 _stillRunning = 0;
45
46 if (g_vars->sceneIntro_skipIntro) {
47 _introFlags = 4;
48 } else {
49 _introFlags = 33;
50 _countDown = 150;
51
52 PictureObject *pict = g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0);
53 pict->setFlags(pict->_flags & 0xFFFB);
54 }
55
56 g_vars->sceneIntro_skipIntro = false;
57 _sfxVolume = g_fp->_sfxVolume;
58 }
59
~ModalIntro()60 ModalIntro::~ModalIntro() {
61 g_fp->stopAllSounds();
62 g_fp->_sfxVolume = _sfxVolume;
63 }
64
handleMessage(ExCommand * message)65 bool ModalIntro::handleMessage(ExCommand *message) {
66 if (message->_messageKind != 17)
67 return false;
68
69 if (message->_messageNum != 36)
70 return false;
71
72 if (message->_param != 13 && message->_param != 27 && message->_param != 32)
73 return false;
74
75 if (_stillRunning) {
76 if (!(_introFlags & 0x10)) {
77 _countDown = 0;
78 g_vars->sceneIntro_needBlackout = true;
79 return true;
80 }
81 g_vars->sceneIntro_playing = false;
82 g_vars->sceneIntro_needBlackout = true;
83 }
84
85 return true;
86 }
87
init(int counterdiff)88 bool ModalIntro::init(int counterdiff) {
89 if (!g_vars->sceneIntro_playing) {
90 if (!_stillRunning) {
91 finish();
92 return false;
93 }
94
95 if (_introFlags & 0x10)
96 g_fp->_gameLoader->updateSystems(42);
97
98 _introFlags |= 2;
99
100 return true;
101 }
102
103 if (_introFlags & 4) {
104 ModalVideoPlayer *player = new ModalVideoPlayer();
105
106 g_fp->_modalObject = player;
107 player->_parentObj = this;
108 player->play("intro.avi");
109
110 _countDown--;
111
112 if (_countDown > 0 )
113 return true;
114
115 if (_stillRunning <= 0) {
116 _countDown = 0;
117 _stillRunning = 0;
118 _introFlags = (_introFlags & 0xfb) | 0x40;
119
120 return true;
121 }
122
123 _introFlags |= 2;
124 return true;
125 }
126
127 if (_introFlags & 0x40) {
128 ModalVideoPlayer *player = new ModalVideoPlayer();
129
130 g_fp->_modalObject = player;
131 player->_parentObj = this;
132 player->play("intro2.avi");
133
134 _countDown--;
135 if (_countDown > 0)
136 return true;
137
138 if (_stillRunning <= 0) {
139 _countDown = 50;
140 _stillRunning = 0;
141 _introFlags = (_introFlags & 0xbf) | 9;
142
143 return true;
144 }
145
146 _introFlags |= 2;
147 return true;
148 }
149
150 if (_introFlags & 8) {
151 _countDown--;
152
153 if (_countDown > 0 )
154 return true;
155
156 if (_stillRunning > 0) {
157 _introFlags |= 2;
158 return true;
159 }
160
161 _countDown = 150;
162 _introFlags = (_introFlags & 0xf7) | 0x21;
163 g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0)->_flags &= 0xfffb;
164 }
165
166 if (!(_introFlags & 0x20)) {
167 if (_introFlags & 0x10) {
168 if (!_stillRunning) {
169 _introFlags |= 1;
170
171 g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0)->_flags &= 0xfffb;
172 g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_GAMETITLE, 0)->_flags &= 0xfffb;
173
174 chainQueue(QU_INTR_STARTINTRO, 1);
175 }
176 g_fp->_gameLoader->updateSystems(42);
177 }
178 return true;
179 }
180
181 _countDown--;
182
183 if (_countDown <= 0) {
184 if (_stillRunning > 0) {
185 _introFlags |= 2;
186
187 return true;
188 }
189
190 _introFlags = (_introFlags & 0xdf) | 0x10;
191
192 g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_GAMETITLE, 0)->_flags &= 0xfffb;
193
194 _stillRunning = 0;
195 }
196
197 return true;
198 }
199
update()200 void ModalIntro::update() {
201 if (g_fp->_currentScene) {
202 if (_introFlags & 1) {
203 g_fp->sceneFade(g_fp->_currentScene, true);
204 _stillRunning = 255;
205 _introFlags &= 0xfe;
206
207 if (_introFlags & 0x20)
208 g_fp->playSound(SND_INTR_019, 0);
209 } else if (_introFlags & 2) {
210 if (g_vars->sceneIntro_needBlackout) {
211 g_fp->drawAlphaRectangle(0, 0, 800, 600, 0);
212 g_vars->sceneIntro_needBlackout = 0;
213 _stillRunning = 0;
214 _introFlags &= 0xfd;
215 } else {
216 g_fp->sceneFade(g_fp->_currentScene, false);
217 _stillRunning = 0;
218 _introFlags &= 0xfd;
219 }
220 } else if (_stillRunning) {
221 g_fp->_currentScene->draw();
222 }
223 }
224 }
225
finish()226 void ModalIntro::finish() {
227 g_fp->_gameLoader->unloadScene(SC_INTRO2);
228
229 g_fp->_currentScene = g_fp->accessScene(SC_INTRO1);
230 g_fp->_gameLoader->preloadScene(SC_INTRO1, TrubaDown);
231
232 if (g_fp->_currentScene)
233 g_fp->_gameLoader->updateSystems(42);
234 }
235
ModalIntroDemo()236 ModalIntroDemo::ModalIntroDemo() {
237 _field_8 = 0;
238 _countDown = 50;
239 _stillRunning = 0;
240 _introFlags = 9;
241 g_vars->sceneIntro_skipIntro = false;
242 _sfxVolume = g_fp->_sfxVolume;
243 }
244
~ModalIntroDemo()245 ModalIntroDemo::~ModalIntroDemo() {
246 g_fp->stopAllSounds();
247 g_fp->_sfxVolume = _sfxVolume;
248 }
249
handleMessage(ExCommand * message)250 bool ModalIntroDemo::handleMessage(ExCommand *message) {
251 if (message->_messageKind != 17)
252 return false;
253
254 if (message->_messageNum != 36)
255 return false;
256
257 if (message->_param != 13 && message->_param != 27 && message->_param != 32)
258 return false;
259
260 if (_introFlags & 0x8) {
261 _countDown = 0;
262 g_vars->sceneIntro_needBlackout = true;
263 return true;
264 } else if (_stillRunning) {
265 g_vars->sceneIntro_playing = false;
266 g_vars->sceneIntro_needBlackout = true;
267 }
268
269 return true;
270 }
271
init(int counterdiff)272 bool ModalIntroDemo::init(int counterdiff) {
273 if (!g_vars->sceneIntro_playing) {
274 if (!_stillRunning) {
275 finish();
276 return false;
277 }
278
279 if (_introFlags & 0x10)
280 g_fp->_gameLoader->updateSystems(42);
281
282 _introFlags |= 2;
283
284 return true;
285 }
286
287 if (_introFlags & 8) {
288 _countDown--;
289
290 if (_countDown > 0)
291 return true;
292
293 if (_stillRunning > 0) {
294 _introFlags |= 2;
295 return true;
296 }
297
298 _countDown = 150;
299 _introFlags = (_introFlags & 0xf7) | 0x21;
300 g_fp->accessScene(SC_INTRO1)->getPictureObjectById(522, 0)->_flags &= 0xfffb;
301 } else {
302 if (!(_introFlags & 0x20))
303 return true;
304
305 _countDown--;
306
307 if (_countDown > 0)
308 return true;
309
310 if (_stillRunning > 0) {
311 _introFlags |= 2;
312 return true;
313 }
314
315 _introFlags &= 0xDF;
316
317 g_vars->sceneIntro_playing = false;
318 _stillRunning = 0;
319 }
320
321 return true;
322 }
323
update()324 void ModalIntroDemo::update() {
325 if (g_fp->_currentScene) {
326 if (_introFlags & 1) {
327 if (g_vars->sceneIntro_needBlackout) {
328 g_fp->drawAlphaRectangle(0, 0, 800, 600, 0);
329 g_vars->sceneIntro_needBlackout = 0;
330 } else {
331 g_fp->sceneFade(g_fp->_currentScene, true);
332 }
333 _stillRunning = 255;
334 _introFlags &= 0xfe;
335
336 if (_introFlags & 0x20)
337 g_fp->playSound(SND_INTR_019, 0);
338 } else if (_introFlags & 2) {
339 if (g_vars->sceneIntro_needBlackout) {
340 g_fp->drawAlphaRectangle(0, 0, 800, 600, 0);
341 g_vars->sceneIntro_needBlackout = 0;
342 _stillRunning = 0;
343 _introFlags &= 0xfd;
344 } else {
345 g_fp->sceneFade(g_fp->_currentScene, false);
346 _stillRunning = 0;
347 _introFlags &= 0xfd;
348 }
349 } else if (_stillRunning) {
350 g_fp->_currentScene->draw();
351 }
352 }
353 }
354
finish()355 void ModalIntroDemo::finish() {
356 g_fp->_currentScene = g_fp->accessScene(SC_INTRO1);
357 g_fp->_gameLoader->preloadScene(SC_INTRO1, TrubaDown);
358
359 if (g_fp->_currentScene)
360 g_fp->_gameLoader->updateSystems(42);
361 }
362
checkSkipVideo(const Common::Event & event)363 static bool checkSkipVideo(const Common::Event &event) {
364 switch (event.type) {
365 case Common::EVENT_KEYDOWN:
366 switch (event.kbd.keycode) {
367 case Common::KEYCODE_ESCAPE:
368 case Common::KEYCODE_RETURN:
369 case Common::KEYCODE_SPACE:
370 return true;
371 default:
372 return false;
373 }
374 case Common::EVENT_QUIT:
375 case Common::EVENT_RTL:
376 return true;
377 default:
378 return false;
379 }
380 }
381
play(const char * filename)382 void ModalVideoPlayer::play(const char *filename) {
383 if (!_decoder.loadFile(filename))
384 return;
385
386 uint16 x = (g_system->getWidth() - _decoder.getWidth()) / 2;
387 uint16 y = (g_system->getHeight() - _decoder.getHeight()) / 2;
388
389 _decoder.start();
390
391 while (!g_fp->shouldQuit() && !_decoder.endOfVideo()) {
392 if (_decoder.needsUpdate()) {
393 const Graphics::Surface *frame = _decoder.decodeNextFrame();
394 if (frame) {
395 Common::ScopedPtr<Graphics::Surface, Graphics::SurfaceDeleter> tmpFrame;
396 if (frame->format != g_system->getScreenFormat()) {
397 tmpFrame.reset(frame->convertTo(g_system->getScreenFormat()));
398 frame = tmpFrame.get();
399 }
400 g_fp->_system->copyRectToScreen(frame->getPixels(), frame->pitch,
401 x, y, frame->w, frame->h);
402
403 if (_decoder.hasDirtyPalette())
404 g_fp->_system->getPaletteManager()->setPalette(_decoder.getPalette(), 0, 256);
405
406 g_fp->_system->updateScreen();
407 }
408 }
409
410 Common::Event event;
411 while (g_fp->_system->getEventManager()->pollEvent(event)) {
412 if (checkSkipVideo(event)) {
413 goto finish;
414 }
415 }
416
417 g_fp->_system->delayMillis(_decoder.getTimeToNextFrame());
418 }
419
420 finish:
421 _decoder.close();
422 }
423
ModalMap()424 ModalMap::ModalMap() {
425 _mapScene = 0;
426 _pic = NULL;
427 _picI03 = NULL;
428 _highlightedPic = NULL;
429 _isRunning = false;
430 _rect1 = g_fp->_sceneRect;
431 _x = g_fp->_currentScene->_x;
432 _y = g_fp->_currentScene->_y;
433 _flag = 0;
434 _mouseX = 0;
435 _mouseY = 0;
436 _dragX = 0;
437 _dragY = 0;
438 _hotSpotDelay = 12;
439 _rect2.top = 0;
440 _rect2.left = 0;
441 _rect2.bottom = 600;
442 _rect2.right = 800;
443 }
444
~ModalMap()445 ModalMap::~ModalMap() {
446 g_fp->_gameLoader->unloadScene(SC_MAP);
447
448 g_fp->_sceneRect = _rect1;
449
450 g_fp->_currentScene->_x = _x;
451 g_fp->_currentScene->_y = _y;
452 }
453
init(int counterdiff)454 bool ModalMap::init(int counterdiff) {
455 if (_picI03)
456 return init2(counterdiff);
457
458 g_fp->setCursor(PIC_CSR_ITN);
459
460 if (_flag) {
461 _rect2.left = _mouseX + _dragX - g_fp->_mouseScreenPos.x;
462 _rect2.top = _mouseY + _dragY - g_fp->_mouseScreenPos.y;
463 _rect2.right = _rect2.left + 800;
464 _rect2.bottom = _rect2.top + 600;
465
466 g_fp->_sceneRect = _rect2;
467
468 _mapScene->updateScrolling2();
469
470 _rect2 = g_fp->_sceneRect;
471 }
472
473 _hotSpotDelay--;
474
475 if (_hotSpotDelay <= 0) {
476 _hotSpotDelay = 12;
477
478 if (_pic)
479 _pic->_flags ^= 4;
480 }
481
482 return _isRunning;
483 }
484
init2(int counterdiff)485 bool ModalMap::init2(int counterdiff) {
486 g_fp->setCursor(PIC_CSR_DEFAULT);
487
488 _dragX = (int)((double)_dragX * 0.6666666666666666);
489 _dragY = (int)((double)_dragY * 0.6666666666666666);
490
491 if (800 - g_fp->_mouseScreenPos.x < 67) {
492 g_fp->setCursor(PIC_CSR_GOR);
493
494 _dragX = g_fp->_mouseScreenPos.x - 733;
495 _dragY = (int)((double)_dragY * 0.6666666666666666);
496 }
497
498 if (g_fp->_mouseScreenPos.x < 67) {
499 g_fp->setCursor(PIC_CSR_GOL);
500
501 this->_dragX = g_fp->_mouseScreenPos.x - 67;
502 this->_dragY = (int)((double)_dragY * 0.6666666666666666);
503 }
504
505 if (g_fp->_mouseScreenPos.y < 67) {
506 g_fp->setCursor(PIC_CSR_GOU);
507
508 _dragX = (int)((double)_dragX * 0.6666666666666666);
509 _dragY = g_fp->_mouseScreenPos.y - 67;
510 }
511
512 if (600 - g_fp->_mouseScreenPos.y < 87) {
513 g_fp->setCursor(PIC_CSR_GOD);
514
515 _dragX = (int)((double)_dragX * 0.6666666666666666);
516 _dragY = g_fp->_mouseScreenPos.y - 513;
517 }
518
519 g_fp->_sceneRect.translate(_dragX, _dragY);
520 _mapScene->updateScrolling2();
521 _rect2 = g_fp->_sceneRect;
522
523 PictureObject *hpic = getSceneHPicture(_mapScene->getPictureObjectAtPos(g_fp->_mouseVirtX, g_fp->_mouseVirtY));
524
525 if (hpic != _highlightedPic) {
526 if (_highlightedPic) {
527 _highlightedPic->_flags &= 0xFFFB;
528 _picI03->_flags &= 0xFFFB;
529 }
530
531 _highlightedPic = hpic;
532
533 if (hpic) {
534 PreloadItem pitem;
535
536 pitem.preloadId1 = g_fp->_currentScene->_sceneId;
537 pitem.sceneId = findMapSceneId(hpic->_id);
538
539 if (pitem.preloadId1 == pitem.sceneId || checkScenePass(&pitem)) {
540 _highlightedPic->_flags |= 4;
541
542 g_fp->playSound(SND_CMN_070, 0);
543 } else {
544 const Dims d1 = _picI03->getDimensions();
545 const Dims d2 = _highlightedPic->getDimensions();
546
547 _picI03->setOXY(_highlightedPic->_ox + d2.x / 2 - d1.x / 2, _highlightedPic->_oy + d2.y / 2 - d1.y / 2);
548 _picI03->_flags |= 4;
549 }
550 }
551 }
552
553 if (this->_highlightedPic) {
554 g_fp->setCursor(PIC_CSR_ITN);
555
556 _hotSpotDelay--;
557
558 if (_hotSpotDelay <= 0) {
559 _hotSpotDelay = 12;
560
561 if (_pic)
562 _pic->_flags ^= 4;
563 }
564 }
565
566 return _isRunning;
567 }
568
findMapSceneId(int picId)569 int ModalMap::findMapSceneId(int picId) {
570 for (uint i = 0; i < g_fp->_gameLoader->_preloadItems.size(); i++) {
571 PreloadItem &pitem = g_fp->_gameLoader->_preloadItems[i];
572
573 if (pitem.preloadId1 == SC_MAP && pitem.preloadId2 == picId) {
574 return pitem.sceneId;
575 }
576 }
577
578 return 0;
579 }
580
581
update()582 void ModalMap::update() {
583 g_fp->_sceneRect = _rect2;
584
585 _mapScene->draw();
586
587 g_fp->drawArcadeOverlay(1);
588 }
589
handleMessage(ExCommand * cmd)590 bool ModalMap::handleMessage(ExCommand *cmd) {
591 if (cmd->_messageKind != 17)
592 return false;
593
594 switch (cmd->_messageNum) {
595 case 29:
596 if (_picI03) {
597 if (_highlightedPic)
598 clickButton(_highlightedPic);
599
600 return false;
601 }
602
603 _flag = 1;
604 _mouseX = g_fp->_mouseScreenPos.x;
605 _mouseY = g_fp->_mouseScreenPos.y;
606
607 _dragX = _rect2.left;
608 _dragY = _rect2.top;
609
610 return false;
611
612 case 30:
613 if (_picI03)
614 return false;
615
616 _flag = 0;
617 return false;
618
619 case 36:
620 if (cmd->_param != 9 && cmd->_param != 27)
621 return false;
622
623 break;
624
625 case 107:
626 break;
627
628 default:
629 return false;
630 }
631
632 _isRunning = 0;
633
634 return true;
635 }
636
initMap()637 void ModalMap::initMap() {
638 _isRunning = 1;
639
640 _mapScene = g_fp->accessScene(SC_MAP);
641
642 if (!_mapScene)
643 error("ModalMap::initMap(): error accessing scene SC_MAP");
644
645 PictureObject *pic;
646
647 for (int i = 0; i < 200; i++) {
648 if (!(g_fp->_mapTable[i] >> 16))
649 break;
650
651 pic = _mapScene->getPictureObjectById(g_fp->_mapTable[i] >> 16, 0);
652
653 if ((g_fp->_mapTable[i] & 0xffff) == 1)
654 pic->_flags |= 4;
655 else
656 pic->_flags &= 0xfffb;
657 }
658
659 pic = getScenePicture(g_fp->_currentScene->_sceneId);
660
661 if (pic) {
662 const Dims dims = pic->getDimensions();
663 Dims dims2;
664
665 _rect2.left = dims.x / 2 + pic->_ox - 400;
666 _rect2.top = dims.y / 2 + pic->_oy - 300;
667 _rect2.right = _rect2.left + 800;
668 _rect2.bottom = _rect2.top + 600;
669
670 g_fp->_sceneRect = _rect2;
671
672 _mapScene->updateScrolling2();
673
674 _pic = _mapScene->getPictureObjectById(PIC_MAP_I02, 0);
675 dims2 = _pic->getDimensions();
676
677 _pic->setOXY(pic->_ox + dims.x / 2 - dims2.x / 2, dims.y - dims2.y / 2 + pic->_oy - 24);
678 _pic->_flags |= 4;
679
680 _pic = _mapScene->getPictureObjectById(PIC_MAP_I01, 0);
681 dims2 = _pic->getDimensions();
682
683 _pic->setOXY(pic->_ox + dims.x / 2 - dims2.x / 2, dims.y - dims2.y / 2 + pic->_oy - 25);
684 _pic->_flags |= 4;
685 }
686
687 _picI03 = _mapScene->getPictureObjectById(PIC_MAP_I03, 0);
688
689 if (_picI03) {
690 _picI03->_flags &= 0xFFFB;
691 }
692
693 g_system->warpMouse(400, 300);
694 g_fp->_mouseScreenPos.x = 400;
695 g_fp->_mouseScreenPos.y = 300;
696
697 g_fp->setArcadeOverlay(PIC_CSR_MAP);
698 }
699
clickButton(PictureObject * pic)700 void ModalMap::clickButton(PictureObject *pic) {
701 if (g_fp->_currentScene == g_fp->_loaderScene) {
702 _isRunning = 0;
703 return;
704 }
705
706 PreloadItem *pitem = nullptr;
707
708 for (uint i = 0; i < g_fp->_gameLoader->_preloadItems.size(); i++)
709 if (g_fp->_gameLoader->_preloadItems[i].preloadId2 == SC_MAP) {
710 pitem = &g_fp->_gameLoader->_preloadItems[i];
711 break;
712 }
713
714 if (!pitem) {
715 PreloadItem preload;
716
717 preload.preloadId2 = SC_MAP;
718 g_fp->_gameLoader->addPreloadItem(preload);
719 pitem = &g_fp->_gameLoader->_preloadItems[g_fp->_gameLoader->_preloadItems.size() - 1];
720 }
721
722 PreloadItem *pitem2 = nullptr;
723
724 for (uint i = 0; i < g_fp->_gameLoader->_preloadItems.size(); i++)
725 if (g_fp->_gameLoader->_preloadItems[i].preloadId1 == SC_MAP &&
726 g_fp->_gameLoader->_preloadItems[i].preloadId2 == pic->_id) {
727 pitem2 = &g_fp->_gameLoader->_preloadItems[i];
728 break;
729 }
730
731 if (pitem && pitem2) {
732 pitem->preloadId1 = g_fp->_currentScene->_sceneId;
733 pitem->sceneId = pitem2->sceneId;
734 pitem->param = pitem2->param;
735
736 if (pitem->preloadId1 == pitem2->sceneId) {
737 _isRunning = 0;
738 } else if (checkScenePass(pitem)) {
739 _isRunning = 0;
740
741 if (!g_fp->isSaveAllowed()) {
742 //g_fp->_gameLoader->loadAndDecryptSave("savetmp.sav");
743 }
744 g_fp->_gameLoader->preloadScene(pitem->preloadId1, SC_MAP);
745 } else {
746 g_fp->playSound(SND_CMN_056, 0);
747 }
748 }
749 }
750
getScenePicture(int sceneId)751 PictureObject *ModalMap::getScenePicture(int sceneId) {
752 int picId = 0;
753
754 switch (sceneId) {
755 case SC_1:
756 picId = PIC_MAP_S01;
757 break;
758 case SC_2:
759 picId = PIC_MAP_S02;
760 break;
761 case SC_3:
762 picId = PIC_MAP_S03;
763 break;
764 case SC_4:
765 picId = PIC_MAP_S04;
766 break;
767 case SC_5:
768 picId = PIC_MAP_S05;
769 break;
770 case SC_6:
771 picId = PIC_MAP_S06;
772 break;
773 case SC_7:
774 picId = PIC_MAP_S07;
775 break;
776 case SC_8:
777 picId = PIC_MAP_S08;
778 break;
779 case SC_9:
780 picId = PIC_MAP_S09;
781 break;
782 case SC_10:
783 picId = PIC_MAP_S10;
784 break;
785 case SC_11:
786 picId = PIC_MAP_S11;
787 break;
788 case SC_12:
789 picId = PIC_MAP_S12;
790 break;
791 case SC_13:
792 picId = PIC_MAP_S13;
793 break;
794 case SC_14:
795 picId = PIC_MAP_S14;
796 break;
797 case SC_15:
798 picId = PIC_MAP_S15;
799 break;
800 case SC_16:
801 picId = PIC_MAP_S16;
802 break;
803 case SC_17:
804 picId = PIC_MAP_S17;
805 break;
806 case SC_18:
807 case SC_19:
808 picId = PIC_MAP_S1819;
809 break;
810 case SC_20:
811 picId = PIC_MAP_S20;
812 break;
813 case SC_21:
814 picId = PIC_MAP_S21;
815 break;
816 case SC_22:
817 picId = PIC_MAP_S22;
818 break;
819 case SC_23:
820 picId = PIC_MAP_S23_1;
821 break;
822 case SC_24:
823 picId = PIC_MAP_S24;
824 break;
825 case SC_25:
826 picId = PIC_MAP_S25;
827 break;
828 case SC_26:
829 picId = PIC_MAP_S26;
830 break;
831 case SC_27:
832 picId = PIC_MAP_S27;
833 break;
834 case SC_28:
835 picId = PIC_MAP_S28;
836 break;
837 case SC_29:
838 picId = PIC_MAP_S29;
839 break;
840 case SC_30:
841 picId = PIC_MAP_S30;
842 break;
843 case SC_31:
844 picId = PIC_MAP_S31_1;
845 break;
846 case SC_32:
847 picId = PIC_MAP_S32_1;
848 break;
849 case SC_33:
850 picId = PIC_MAP_S33;
851 break;
852 case SC_34:
853 picId = PIC_MAP_S34;
854 break;
855 case SC_35:
856 picId = PIC_MAP_S35;
857 break;
858 case SC_36:
859 picId = PIC_MAP_S36;
860 break;
861 case SC_37:
862 picId = PIC_MAP_S37;
863 break;
864 case SC_38:
865 picId = PIC_MAP_S38;
866 break;
867 case SC_FINAL1:
868 picId = PIC_MAP_S38;
869 break;
870 }
871
872 if (picId)
873 return _mapScene->getPictureObjectById(picId, 0);
874
875 error("ModalMap::getScenePicture(): Unknown scene id: %d", g_fp->_currentScene->_sceneId);
876 }
877
getSceneHPicture(PictureObject * obj)878 PictureObject *ModalMap::getSceneHPicture(PictureObject *obj) {
879 if (!obj)
880 return NULL;
881
882 switch (obj->_id) {
883 case PIC_MAP_S01:
884 return _mapScene->getPictureObjectById(PIC_MAP_H01, 0);
885 case PIC_MAP_S02:
886 return _mapScene->getPictureObjectById(PIC_MAP_H02, 0);
887 case PIC_MAP_S03:
888 return _mapScene->getPictureObjectById(PIC_MAP_H03, 0);
889 case PIC_MAP_S04:
890 return _mapScene->getPictureObjectById(PIC_MAP_H04, 0);
891 case PIC_MAP_S05:
892 return _mapScene->getPictureObjectById(PIC_MAP_H05, 0);
893 case PIC_MAP_S06:
894 return _mapScene->getPictureObjectById(PIC_MAP_H06, 0);
895 case PIC_MAP_S07:
896 return _mapScene->getPictureObjectById(PIC_MAP_H07, 0);
897 case PIC_MAP_S09:
898 return _mapScene->getPictureObjectById(PIC_MAP_H09, 0);
899 case PIC_MAP_S08:
900 return _mapScene->getPictureObjectById(PIC_MAP_H08, 0);
901 case PIC_MAP_S10:
902 return _mapScene->getPictureObjectById(PIC_MAP_H10, 0);
903 case PIC_MAP_S11:
904 return _mapScene->getPictureObjectById(PIC_MAP_H11, 0);
905 case PIC_MAP_S12:
906 return _mapScene->getPictureObjectById(PIC_MAP_H12, 0);
907 case PIC_MAP_S13:
908 return _mapScene->getPictureObjectById(PIC_MAP_H13, 0);
909 case PIC_MAP_S14:
910 return _mapScene->getPictureObjectById(PIC_MAP_H14, 0);
911 case PIC_MAP_S15:
912 return _mapScene->getPictureObjectById(PIC_MAP_H15, 0);
913 case PIC_MAP_S16:
914 return _mapScene->getPictureObjectById(PIC_MAP_H16, 0);
915 case PIC_MAP_S17:
916 return _mapScene->getPictureObjectById(PIC_MAP_H17, 0);
917 case PIC_MAP_S1819:
918 return _mapScene->getPictureObjectById(PIC_MAP_H18, 0);
919 case PIC_MAP_S20:
920 return _mapScene->getPictureObjectById(PIC_MAP_H20, 0);
921 case PIC_MAP_S21:
922 return _mapScene->getPictureObjectById(PIC_MAP_H21, 0);
923 case PIC_MAP_S22:
924 return _mapScene->getPictureObjectById(PIC_MAP_H22, 0);
925 case PIC_MAP_S23_1:
926 case PIC_MAP_S23_2:
927 return _mapScene->getPictureObjectById(PIC_MAP_H23, 0);
928 case PIC_MAP_S24:
929 return _mapScene->getPictureObjectById(PIC_MAP_H24, 0);
930 case PIC_MAP_S25:
931 return _mapScene->getPictureObjectById(PIC_MAP_H25, 0);
932 case PIC_MAP_S26:
933 return _mapScene->getPictureObjectById(PIC_MAP_H26, 0);
934 case PIC_MAP_S27:
935 return _mapScene->getPictureObjectById(PIC_MAP_H27, 0);
936 case PIC_MAP_S28:
937 return _mapScene->getPictureObjectById(PIC_MAP_H28, 0);
938 case PIC_MAP_S29:
939 return _mapScene->getPictureObjectById(PIC_MAP_H29, 0);
940 case PIC_MAP_S30:
941 return _mapScene->getPictureObjectById(PIC_MAP_H30, 0);
942 case PIC_MAP_S31_1:
943 case PIC_MAP_S31_2:
944 return _mapScene->getPictureObjectById(PIC_MAP_H31, 0);
945 case PIC_MAP_S32_1:
946 case PIC_MAP_S32_2:
947 return _mapScene->getPictureObjectById(PIC_MAP_H32, 0);
948 case PIC_MAP_S33:
949 return _mapScene->getPictureObjectById(PIC_MAP_H33, 0);
950 case PIC_MAP_S34:
951 return _mapScene->getPictureObjectById(PIC_MAP_H34, 0);
952 case PIC_MAP_S35:
953 return _mapScene->getPictureObjectById(PIC_MAP_H35, 0);
954 case PIC_MAP_S36:
955 return _mapScene->getPictureObjectById(PIC_MAP_H36, 0);
956 case PIC_MAP_S37:
957 return _mapScene->getPictureObjectById(PIC_MAP_H37, 0);
958 case PIC_MAP_S38:
959 return _mapScene->getPictureObjectById(PIC_MAP_H38, 0);
960 default:
961 return NULL;
962 }
963 }
964
isSceneEnabled(int sceneId)965 bool ModalMap::isSceneEnabled(int sceneId) {
966 int id = getScenePicture(sceneId)->_id;
967
968 for (int i = 0; i < 200; i++) {
969 int mapPic = g_fp->_mapTable[i] >> 16;
970 if (!mapPic)
971 return false;
972
973 if (mapPic == id)
974 return (g_fp->_mapTable[i] & 0xffff) == 1;
975 }
976
977 return false;
978 }
979
checkScenePass(PreloadItem * item)980 bool ModalMap::checkScenePass(PreloadItem *item) {
981 bool res = true;
982
983 switch (item->preloadId1) {
984 case SC_13:
985 if (!isSceneEnabled(SC_14))
986 res = false;
987 break;
988
989 case SC_27:
990 if (item->sceneId == SC_25) {
991 item->param = TrubaRight;
992 } else {
993 res = false;
994 }
995 break;
996
997 case SC_25:
998 if (g_fp->getObjectState(sO_Board_25) != g_fp->getObjectEnumState(sO_Board_25, sO_NearDudesStairs)) {
999 res = false;
1000 }
1001 }
1002
1003 switch (item->sceneId) {
1004 case SC_13:
1005 if (isSceneEnabled(SC_14)) {
1006 item->param = TrubaLeft;
1007 break;
1008 }
1009 item->param = TrubaUp;
1010 break;
1011
1012 case SC_27:
1013 res = false;
1014 break;
1015
1016 case SC_25:
1017 if (g_fp->getObjectState(sO_Pool) != g_fp->getObjectEnumState(sO_Pool, sO_Empty)) {
1018 if (g_fp->getObjectState(sO_Pool) != g_fp->getObjectEnumState(sO_Pool, sO_HalfFull))
1019 res = false;
1020 }
1021 break;
1022
1023 case SC_29:
1024 if (isSceneEnabled(SC_30)) {
1025 item->param = TrubaLeft;
1026 break;
1027 }
1028 item->param = TrubaUp;
1029 break;
1030 }
1031
1032 if ((item->sceneId != SC_37 && item->preloadId1 != SC_37)
1033 || (g_fp->getObjectState(sO_Jawcrucnher) != g_fp->getObjectEnumState(sO_Jawcrucnher, sO_WithoutCarpet))) {
1034 return res;
1035 } else {
1036 res = false;
1037 }
1038 return res;
1039 }
1040
openMap()1041 void FullpipeEngine::openMap() {
1042 if (!_modalObject) {
1043 ModalMap *map = new ModalMap;
1044
1045 _modalObject = map;
1046
1047 map->initMap();
1048 }
1049 }
1050
ModalFinal()1051 ModalFinal::ModalFinal() {
1052 _flags = 0;
1053 _counter = 255;
1054 _sfxVolume = g_fp->_sfxVolume;
1055 }
1056
~ModalFinal()1057 ModalFinal::~ModalFinal() {
1058 if (g_vars->sceneFinal_var01) {
1059 g_fp->_gameLoader->unloadScene(SC_FINAL2);
1060 g_fp->_gameLoader->unloadScene(SC_FINAL3);
1061 g_fp->_gameLoader->unloadScene(SC_FINAL4);
1062
1063 g_fp->_currentScene = g_fp->accessScene(SC_FINAL1);
1064
1065 g_fp->stopAllSounds();
1066
1067 g_vars->sceneFinal_var01 = 0;
1068 }
1069
1070 g_fp->_sfxVolume = _sfxVolume;
1071 }
1072
init(int counterdiff)1073 bool ModalFinal::init(int counterdiff) {
1074 if (g_vars->sceneFinal_var01) {
1075 g_fp->_gameLoader->updateSystems(42);
1076
1077 return true;
1078 }
1079
1080 if (_counter > 0) {
1081 _flags |= 2u;
1082
1083 g_fp->_gameLoader->updateSystems(42);
1084
1085 return true;
1086 }
1087
1088 unloadScenes();
1089
1090 g_fp->_modalObject = new ModalCredits();
1091
1092 return true;
1093 }
1094
unloadScenes()1095 void ModalFinal::unloadScenes() {
1096 g_fp->_gameLoader->unloadScene(SC_FINAL2);
1097 g_fp->_gameLoader->unloadScene(SC_FINAL3);
1098 g_fp->_gameLoader->unloadScene(SC_FINAL4);
1099
1100 g_fp->_currentScene = g_fp->accessScene(SC_FINAL1);
1101
1102 g_fp->stopAllSounds();
1103 }
1104
handleMessage(ExCommand * cmd)1105 bool ModalFinal::handleMessage(ExCommand *cmd) {
1106 if (cmd->_messageKind == 17 && cmd->_messageNum == 36 && cmd->_param == 27) {
1107 g_fp->_modalObject = new ModalMainMenu();
1108 g_fp->_modalObject->_parentObj = this;
1109
1110 return true;
1111 }
1112
1113 return false;
1114 }
1115
update()1116 void ModalFinal::update() {
1117 if (g_fp->_currentScene) {
1118 g_fp->_currentScene->draw();
1119
1120 if (_flags & 1) {
1121 g_fp->drawAlphaRectangle(0, 0, 800, 600, 0xff - _counter);
1122
1123 _counter += 10;
1124
1125 if (_counter >= 255) {
1126 _counter = 255;
1127 _flags &= 0xfe;
1128 }
1129 } else {
1130 if (!(_flags & 2))
1131 return;
1132
1133 g_fp->drawAlphaRectangle(0, 0, 800, 600, 0xff - _counter);
1134 _counter -= 10;
1135
1136 if (_counter <= 0) {
1137 _counter = 0;
1138 _flags &= 0xFD;
1139 }
1140 }
1141
1142 g_fp->_sfxVolume = _counter * (_sfxVolume + 3000) / 255 - 3000;
1143
1144 g_fp->updateSoundVolume();
1145 }
1146 }
1147
ModalCredits()1148 ModalCredits::ModalCredits() {
1149 _sceneTitles = g_fp->accessScene(SC_TITLES);
1150
1151 _creditsPic = _sceneTitles->getPictureObjectById(PIC_TTL_CREDITS, 0);
1152 _creditsPic->_flags |= 4;
1153
1154 _fadeIn = true;
1155 _fadeOut = false;
1156
1157 const Dims dims = _creditsPic->getDimensions();
1158
1159 _countdown = dims.y / 2 + 470;
1160 _sfxVolume = g_fp->_sfxVolume;
1161
1162 _currY = 630;
1163 _maxY = -1000 - dims.y;
1164
1165 _currX = 400 - dims.x / 2;
1166
1167 _creditsPic->setOXY(_currX, _currY);
1168 }
1169
~ModalCredits()1170 ModalCredits::~ModalCredits() {
1171 g_fp->_gameLoader->unloadScene(SC_TITLES);
1172
1173 g_fp->_sfxVolume = _sfxVolume;
1174 }
1175
handleMessage(ExCommand * cmd)1176 bool ModalCredits::handleMessage(ExCommand *cmd) {
1177 if (cmd->_messageKind == 17 && cmd->_messageNum == 36 && cmd->_param == 27) {
1178 _fadeIn = false;
1179
1180 return true;
1181 }
1182
1183 return false;
1184 }
1185
init(int counterdiff)1186 bool ModalCredits::init(int counterdiff) {
1187 if (_fadeIn || _fadeOut) {
1188 _countdown--;
1189
1190 if (_countdown < 0)
1191 _fadeIn = false;
1192
1193 _creditsPic->setOXY(_currX, _currY);
1194
1195 if (_currY > _maxY)
1196 _currY -= 2;
1197 } else {
1198 if (_parentObj)
1199 return 0;
1200
1201 ModalMainMenu *menu = new ModalMainMenu;
1202
1203 g_fp->_modalObject = menu;
1204
1205 menu->_mfield_34 = 1;
1206 }
1207
1208 return true;
1209 }
1210
update()1211 void ModalCredits::update() {
1212 if (_fadeOut) {
1213 if (_fadeIn) {
1214 _sceneTitles->draw();
1215
1216 return;
1217 }
1218 } else if (_fadeIn) {
1219 g_fp->sceneFade(_sceneTitles, true);
1220 _fadeOut = 1;
1221
1222 return;
1223 }
1224
1225 if (_fadeOut) {
1226 g_fp->sceneFade(_sceneTitles, false);
1227 _fadeOut = 0;
1228 return;
1229 }
1230
1231 _sceneTitles->draw();
1232 }
1233
ModalMainMenu()1234 ModalMainMenu::ModalMainMenu() {
1235 _lastArea = 0;
1236 _hoverAreaId = 0;
1237 _mfield_34 = 0;
1238 _scene = g_fp->accessScene(SC_MAINMENU);
1239 _debugKeyCount = 0;
1240 _sliderOffset = 0;
1241 _screct.left = g_fp->_sceneRect.left;
1242 _screct.top = g_fp->_sceneRect.top;
1243 _screct.right = g_fp->_sceneRect.right;
1244 _screct.bottom = g_fp->_sceneRect.bottom;
1245
1246 if (g_fp->_currentScene) {
1247 _bgX = g_fp->_currentScene->_x;
1248 _bgY = g_fp->_currentScene->_y;
1249 } else {
1250 _bgX = 0;
1251 _bgY = 0;
1252 }
1253
1254 g_fp->_sceneRect.top = 0;
1255 g_fp->_sceneRect.left = 0;
1256 g_fp->_sceneRect.right = 800;
1257 g_fp->_sceneRect.bottom = 600;
1258
1259 MenuArea *area;
1260
1261 _areas.push_back(MenuArea());
1262 area = &_areas.back();
1263 area->picIdL = PIC_MNU_EXIT_L;
1264 area->picObjD = 0;
1265 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1266 area->picObjL->_flags &= 0xFFFB;
1267
1268 _areas.push_back(MenuArea());
1269 area = &_areas.back();
1270 area->picIdL = PIC_MNU_CONTINUE_L;
1271 area->picObjD = 0;
1272 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1273 area->picObjL->_flags &= 0xFFFB;
1274
1275 if (isSaveAllowed()) {
1276 _areas.push_back(MenuArea());
1277 area = &_areas.back();
1278 area->picIdL = PIC_MNU_SAVE_L;
1279 area->picObjD = 0;
1280 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1281 area->picObjL->_flags &= 0xFFFB;
1282 }
1283
1284 _areas.push_back(MenuArea());
1285 area = &_areas.back();
1286 area->picIdL = PIC_MNU_LOAD_L;
1287 area->picObjD = 0;
1288 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1289 area->picObjL->_flags &= 0xFFFB;
1290
1291 _areas.push_back(MenuArea());
1292 area = &_areas.back();
1293 area->picIdL = PIC_MNU_RESTART_L;
1294 area->picObjD = 0;
1295 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1296 area->picObjL->_flags &= 0xFFFB;
1297
1298 _areas.push_back(MenuArea());
1299 area = &_areas.back();
1300 area->picIdL = PIC_MNU_AUTHORS_L;
1301 area->picObjD = 0;
1302 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1303 area->picObjL->_flags &= 0xFFFB;
1304
1305 _areas.push_back(MenuArea());
1306 area = &_areas.back();
1307 area->picIdL = PIC_MNU_SLIDER_L;
1308 area->picObjD = _scene->getPictureObjectById(PIC_MNU_SLIDER_D, 0);
1309 area->picObjD->_flags |= 4;
1310 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1311 area->picObjL->_flags &= 0xFFFB;
1312
1313 _menuSliderIdx = _areas.size() - 1;
1314
1315 _areas.push_back(MenuArea());
1316 area = &_areas.back();
1317 area->picIdL = PIC_MNU_MUSICSLIDER_L;
1318 area->picObjD = _scene->getPictureObjectById(PIC_MNU_MUSICSLIDER_D, 0);
1319 area->picObjD->_flags |= 4;
1320 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1321 area->picObjL->_flags &= 0xFFFB;
1322
1323 _musicSliderIdx = _areas.size() - 1;
1324
1325 if (g_fp->_mainMenu_debugEnabled)
1326 enableDebugMenuButton();
1327
1328 setSliderPos();
1329 }
1330
update()1331 void ModalMainMenu::update() {
1332 _scene->draw();
1333 }
1334
handleMessage(ExCommand * message)1335 bool ModalMainMenu::handleMessage(ExCommand *message) {
1336 if (message->_messageKind != 17)
1337 return false;
1338
1339 if (!_scene)
1340 return false;
1341
1342 Common::Point point;
1343
1344 if (message->_messageNum == 29) {
1345 point.x = message->_x;
1346 point.y = message->_y;
1347
1348 int numarea = checkHover(point);
1349
1350 if (numarea >= 0) {
1351 if (numarea == _menuSliderIdx) {
1352 _lastArea = &_areas[_menuSliderIdx];
1353 _sliderOffset = _lastArea->picObjL->_ox - point.x;
1354
1355 return false;
1356 }
1357
1358 if (numarea == _musicSliderIdx) {
1359 _lastArea = &_areas[_musicSliderIdx];
1360 _sliderOffset = _lastArea->picObjL->_ox - point.x;
1361
1362 return false;
1363 }
1364
1365 _hoverAreaId = _areas[numarea].picIdL;
1366 }
1367
1368 return false;
1369 }
1370
1371 if (message->_messageNum == 30) {
1372 if (_lastArea)
1373 _lastArea = 0;
1374
1375 return false;
1376 }
1377
1378 if (message->_messageNum != 36)
1379 return false;
1380
1381 if (message->_param == 27)
1382 _hoverAreaId = PIC_MNU_CONTINUE_L;
1383 else
1384 enableDebugMenu(message->_param);
1385
1386 return false;
1387 }
1388
init(int counterdiff)1389 bool ModalMainMenu::init(int counterdiff) {
1390 switch (_hoverAreaId) {
1391 case PIC_MNU_RESTART_L:
1392 g_fp->restartGame();
1393
1394 if (this == g_fp->_modalObject)
1395 return false;
1396
1397 delete this;
1398 break;
1399
1400 case PIC_MNU_EXIT_L:
1401 {
1402 ModalQuery *mq = new ModalQuery();
1403
1404 g_fp->_modalObject = mq;
1405
1406 mq->_parentObj = this;
1407 mq->create(_scene, _scene, PIC_MEX_BGR);
1408
1409 _hoverAreaId = 0;
1410
1411 return true;
1412 }
1413
1414 case PIC_MNU_DEBUG_L:
1415 g_fp->_gameLoader->unloadScene(SC_MAINMENU);
1416 _scene = nullptr;
1417 g_fp->_sceneRect = _screct;
1418
1419 if (!g_fp->_currentScene)
1420 error("ModalMainMenu::init: Bad state");
1421
1422 g_fp->_currentScene->_x = _bgX;
1423 g_fp->_currentScene->_y = _bgY;
1424
1425 g_fp->_gameLoader->preloadScene(g_fp->_currentScene->_sceneId, SC_DBGMENU);
1426
1427 return false;
1428
1429 case PIC_MNU_CONTINUE_L:
1430 if (!_mfield_34) {
1431 g_fp->_gameLoader->unloadScene(SC_MAINMENU);
1432 _areas.clear();
1433 _scene = nullptr;
1434 g_fp->_sceneRect = _screct;
1435
1436 if (g_fp->_currentScene) {
1437 g_fp->_currentScene->_x = _bgX;
1438 g_fp->_currentScene->_y = _bgY;
1439 }
1440
1441 return false;
1442 }
1443
1444 g_fp->restartGame();
1445
1446 if (this == g_fp->_modalObject)
1447 return false;
1448
1449 delete this;
1450 break;
1451
1452 case PIC_MNU_AUTHORS_L:
1453 g_fp->_modalObject = new ModalCredits();
1454 g_fp->_modalObject->_parentObj = this;
1455
1456 _hoverAreaId = 0;
1457
1458 return true;
1459
1460 case PIC_MNU_SAVE_L:
1461 case PIC_MNU_LOAD_L:
1462 {
1463 ModalSaveGame *sg = new ModalSaveGame();
1464
1465 g_fp->_modalObject = sg;
1466 g_fp->_modalObject->_parentObj = _parentObj;
1467
1468 int mode = 0;
1469 if (_hoverAreaId == PIC_MNU_SAVE_L)
1470 mode = 1;
1471
1472 sg->setup(g_fp->accessScene(SC_MAINMENU), mode);
1473 sg->setScene(g_fp->accessScene(SC_MAINMENU));
1474
1475 sg->_rect = _screct;
1476 sg->_oldBgX = _bgX;
1477 sg->_oldBgY = _bgY;
1478
1479 delete this;
1480 }
1481
1482 break;
1483
1484 default:
1485 if (_lastArea) {
1486 updateSliderPos();
1487 } else {
1488 g_fp->_cursorId = PIC_CSR_DEFAULT;
1489
1490 int idx = checkHover(g_fp->_mouseScreenPos);
1491
1492 if (idx < 0)
1493 goto LABEL_40;
1494
1495 g_fp->_cursorId = PIC_CSR_DEFAULT;
1496
1497 if (idx != this->_menuSliderIdx && idx != this->_musicSliderIdx )
1498 goto LABEL_40;
1499 }
1500
1501 g_fp->_cursorId = PIC_CSR_LIFT;
1502
1503 LABEL_40:
1504 g_fp->setCursor(g_fp->_cursorId);
1505
1506 updateVolume();
1507
1508 return true;
1509 }
1510
1511 return true;
1512 }
1513
updateVolume()1514 void ModalMainMenu::updateVolume() {
1515 if (g_fp->_soundEnabled) {
1516 for (int s = 0; s < g_fp->_currSoundListCount; s++)
1517 for (int i = 0; i < g_fp->_currSoundList1[s]->getCount(); i++) {
1518 updateSoundVolume(g_fp->_currSoundList1[s]->getSoundByIndex(i));
1519 }
1520 }
1521 }
1522
updateSoundVolume(Sound & snd)1523 void ModalMainMenu::updateSoundVolume(Sound &snd) {
1524 if (!snd._objectId)
1525 return;
1526
1527 StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(snd._objectId, -1);
1528 if (!ani)
1529 return;
1530
1531 int a, b;
1532
1533 if (ani->_ox >= _screct.left) {
1534 int par, pan;
1535
1536 if (ani->_ox <= _screct.right) {
1537 int dx;
1538
1539 if (ani->_oy <= _screct.bottom) {
1540 if (ani->_oy >= _screct.top) {
1541 snd.setPanAndVolume(g_fp->_sfxVolume, 0);
1542
1543 return;
1544 }
1545 dx = _screct.top - ani->_oy;
1546 } else {
1547 dx = ani->_oy - _screct.bottom;
1548 }
1549
1550 par = 0;
1551
1552 if (dx > 800) {
1553 snd.setPanAndVolume(-3500, 0);
1554 return;
1555 }
1556
1557 pan = -3500;
1558 a = g_fp->_sfxVolume - (-3500);
1559 b = 800 - dx;
1560 } else {
1561 int dx = ani->_ox - _screct.right;
1562
1563 if (dx > 800) {
1564 snd.setPanAndVolume(-3500, 0);
1565 return;
1566 }
1567
1568 pan = -3500;
1569 par = dx * (-3500) / -800;
1570 a = g_fp->_sfxVolume - (-3500);
1571 b = 800 - dx;
1572 }
1573
1574 int32 pp = b * a;
1575
1576 snd.setPanAndVolume(pan + pp / 800, par);
1577
1578 return;
1579 }
1580
1581 int dx = _screct.left - ani->_ox;
1582 if (dx <= 800) {
1583 int32 s = (800 - dx) * (g_fp->_sfxVolume - (-3500));
1584 int32 p = -3500 + s / 800;
1585
1586 if (p > g_fp->_sfxVolume)
1587 p = g_fp->_sfxVolume;
1588
1589 snd.setPanAndVolume(p, dx * (-3500) / 800);
1590 } else {
1591 snd.setPanAndVolume(-3500, 0);
1592 }
1593 }
1594
updateSliderPos()1595 void ModalMainMenu::updateSliderPos() {
1596 if (_lastArea->picIdL == PIC_MNU_SLIDER_L) {
1597 int x = g_fp->_mouseScreenPos.x + _sliderOffset;
1598
1599 if (x >= 65) {
1600 if (x > 238)
1601 x = 238;
1602 } else {
1603 x = 65;
1604 }
1605
1606 _lastArea->picObjD->setOXY(x, _lastArea->picObjD->_oy);
1607 _lastArea->picObjL->setOXY(x, _lastArea->picObjD->_oy);
1608
1609 int vol = 1000 * (3 * x - 195);
1610 g_fp->_sfxVolume = vol / 173 - 3000;
1611
1612 if (!(vol / 173))
1613 g_fp->_sfxVolume = -10000;
1614
1615 g_fp->updateSoundVolume();
1616 } else if (_lastArea->picIdL == PIC_MNU_MUSICSLIDER_L) {
1617 int x = g_fp->_mouseScreenPos.x + _sliderOffset;
1618
1619 if (x >= 65) {
1620 if (x > 238)
1621 x = 238;
1622 } else {
1623 x = 65;
1624 }
1625
1626 _lastArea->picObjD->setOXY(x, _lastArea->picObjD->_oy);
1627 _lastArea->picObjL->setOXY(x, _lastArea->picObjD->_oy);
1628
1629 g_fp->setMusicVolume(255 * (x - 65) / 173);
1630 }
1631 }
1632
checkHover(Common::Point & point)1633 int ModalMainMenu::checkHover(Common::Point &point) {
1634 for (uint i = 0; i < _areas.size(); i++) {
1635 if (_areas[i].picObjL->isPixelHitAtPos(point.x, point.y)) {
1636 _areas[i].picObjL->_flags |= 4;
1637
1638 return i;
1639 } else {
1640 _areas[i].picObjL->_flags &= 0xFFFB;
1641 }
1642 }
1643
1644 if (isOverArea(_areas[_menuSliderIdx].picObjL, &point)) {
1645 _areas[_menuSliderIdx].picObjL->_flags |= 4;
1646
1647 return _menuSliderIdx;
1648 }
1649
1650 if (isOverArea(_areas[_musicSliderIdx].picObjL, &point)) {
1651 _areas[_musicSliderIdx].picObjL->_flags |= 4;
1652
1653 return _musicSliderIdx;
1654 }
1655
1656 return -1;
1657 }
1658
isOverArea(PictureObject * obj,Common::Point * point)1659 bool ModalMainMenu::isOverArea(PictureObject *obj, Common::Point *point) {
1660 const Dims dims = obj->getDimensions();
1661
1662 int left = point->x - 8;
1663 int right = point->x + 12;
1664 int down = point->y - 11;
1665 int up = point->y + 9;
1666
1667 if (left >= obj->_ox && right < obj->_ox + dims.x && down >= obj->_oy && up < obj->_oy + dims.y)
1668 return true;
1669
1670 return false;
1671 }
1672
isSaveAllowed()1673 bool ModalMainMenu::isSaveAllowed() {
1674 if (!g_fp->_isSaveAllowed)
1675 return false;
1676
1677 if (g_fp->_aniMan->_flags & 0x100)
1678 return false;
1679
1680 for (Common::Array<MessageQueue *>::iterator s = g_fp->_globalMessageQueueList->begin(); s != g_fp->_globalMessageQueueList->end(); ++s) {
1681 if (!(*s)->_isFinished && ((*s)->getFlags() & 1))
1682 return false;
1683 }
1684
1685 return true;
1686 }
1687
enableDebugMenu(char c)1688 void ModalMainMenu::enableDebugMenu(char c) {
1689 const char deb[] = "debuger";
1690
1691 if (c == deb[_debugKeyCount]) {
1692 _debugKeyCount++;
1693
1694 if (deb[_debugKeyCount] )
1695 return;
1696
1697 enableDebugMenuButton();
1698 }
1699
1700 _debugKeyCount = 0;
1701 }
1702
enableDebugMenuButton()1703 void ModalMainMenu::enableDebugMenuButton() {
1704 for (uint i = 0; i < _areas.size(); i++)
1705 if (_areas[i].picIdL == PIC_MNU_DEBUG_L)
1706 return;
1707
1708 _areas.push_back(MenuArea());
1709 MenuArea *area = &_areas.back();
1710 area->picIdL = PIC_MNU_DEBUG_L;
1711 area->picObjD = 0;
1712 area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
1713 area->picObjL->_flags &= 0xFFFB;
1714
1715 g_fp->_mainMenu_debugEnabled = true;
1716 }
1717
setSliderPos()1718 void ModalMainMenu::setSliderPos() {
1719 int x = 173 * (g_fp->_sfxVolume + 3000) / 3000 + 65;
1720 PictureObject *obj = _areas[_menuSliderIdx].picObjD;
1721
1722 if (x >= 65) {
1723 if (x > 238)
1724 x = 238;
1725 } else {
1726 x = 65;
1727 }
1728
1729 obj->setOXY(x, obj->_oy);
1730 _areas[_menuSliderIdx].picObjL->setOXY(x, obj->_oy);
1731
1732 x = 173 * g_fp->_musicVolume / 255 + 65;
1733 obj = _areas[_musicSliderIdx].picObjD;
1734
1735 if (x >= 65) {
1736 if (x > 238)
1737 x = 238;
1738 } else {
1739 x = 65;
1740 }
1741
1742 obj->setOXY(x, obj->_oy);
1743 _areas[_musicSliderIdx].picObjL->setOXY(x, obj->_oy);
1744 }
1745
ModalHelp()1746 ModalHelp::ModalHelp() {
1747 _mainMenuScene = 0;
1748 _bg = 0;
1749 _isRunning = false;
1750 _rect = g_fp->_sceneRect;
1751 _hx = g_fp->_currentScene->_x;
1752 _hy = g_fp->_currentScene->_y;
1753
1754 g_fp->_sceneRect.left = 0;
1755 g_fp->_sceneRect.bottom = 600;
1756 g_fp->_sceneRect.top = 0;
1757 g_fp->_sceneRect.right = 800;
1758 }
1759
~ModalHelp()1760 ModalHelp::~ModalHelp() {
1761 g_fp->_gameLoader->unloadScene(SC_MAINMENU);
1762
1763 g_fp->_sceneRect = _rect;
1764
1765 g_fp->_currentScene->_x = _hx;
1766 g_fp->_currentScene->_y = _hy;
1767 }
1768
handleMessage(ExCommand * cmd)1769 bool ModalHelp::handleMessage(ExCommand *cmd) {
1770 if (cmd->_messageKind == 17) {
1771 int msg = cmd->_messageNum;
1772
1773 if (msg == 29 || msg == 36 || msg == 107) {
1774 _isRunning = 0;
1775
1776 return true;
1777 }
1778 }
1779
1780 return false;
1781 }
1782
init(int counterdiff)1783 bool ModalHelp::init(int counterdiff) {
1784 g_fp->setCursor(PIC_CSR_DEFAULT);
1785
1786 return _isRunning;
1787 }
1788
update()1789 void ModalHelp::update() {
1790 g_fp->_sceneRect.left = 0;
1791 g_fp->_sceneRect.top = 0;
1792 g_fp->_sceneRect.right = 800;
1793 g_fp->_sceneRect.bottom = 600;
1794
1795 _bg->draw(0, 0, 0, 0);
1796 }
1797
launch()1798 void ModalHelp::launch() {
1799 _mainMenuScene = g_fp->accessScene(SC_MAINMENU);
1800
1801 if (_mainMenuScene) {
1802 if (g_fp->isDemo() && g_fp->getLanguage() == Common::RU_RUS)
1803 _bg = _mainMenuScene->getPictureObjectById(364, 0)->_picture.get();
1804 else
1805 _bg = _mainMenuScene->getPictureObjectById(PIC_HLP_BGR, 0)->_picture.get();
1806 _isRunning = 1;
1807 }
1808 }
1809
ModalQuery()1810 ModalQuery::ModalQuery() {
1811 _bgScene = 0;
1812 _bg = 0;
1813 _okBtn = 0;
1814 _cancelBtn = 0;
1815 _queryResult = -1;
1816 }
1817
~ModalQuery()1818 ModalQuery::~ModalQuery() {
1819 _bg->_flags &= 0xFFFB;
1820 _cancelBtn->_flags &= 0xFFFB;
1821 _okBtn->_flags &= 0xFFFB;
1822 }
1823
create(Scene * sc,Scene * bgScene,int id)1824 bool ModalQuery::create(Scene *sc, Scene *bgScene, int id) {
1825 if (g_fp->isDemo() && g_fp->getLanguage() == Common::RU_RUS) {
1826 _bg = sc->getPictureObjectById(386, 0);
1827
1828 if (!_bg)
1829 return false;
1830
1831 _okBtn = sc->getPictureObjectById(392, 0);
1832
1833 if (!_okBtn)
1834 return false;
1835
1836 _cancelBtn = sc->getPictureObjectById(396, 0);
1837
1838 if (!_cancelBtn)
1839 return 0;
1840
1841 _queryResult = -1;
1842 _bgScene = bgScene;
1843
1844 return true;
1845 }
1846
1847 if (id == PIC_MEX_BGR) {
1848 _bg = sc->getPictureObjectById(PIC_MEX_BGR, 0);
1849
1850 if (!_bg)
1851 return false;
1852
1853 _okBtn = sc->getPictureObjectById(PIC_MEX_OK, 0);
1854
1855 if (!_okBtn)
1856 return false;
1857
1858 _cancelBtn = sc->getPictureObjectById(PIC_MEX_CANCEL, 0);
1859
1860 if (!_cancelBtn)
1861 return false;
1862 } else {
1863 if (id != PIC_MOV_BGR)
1864 return false;
1865
1866 _bg = sc->getPictureObjectById(PIC_MOV_BGR, 0);
1867
1868 if (!_bg)
1869 return false;
1870
1871 _okBtn = sc->getPictureObjectById(PIC_MOV_OK, 0);
1872
1873 if (!_okBtn)
1874 return false;
1875
1876 _cancelBtn = sc->getPictureObjectById(PIC_MOV_CANCEL, 0);
1877
1878 if (!_cancelBtn)
1879 return false;
1880 }
1881
1882 _queryResult = -1;
1883 _bgScene = bgScene;
1884
1885 return true;
1886 }
1887
update()1888 void ModalQuery::update() {
1889 if (_bgScene)
1890 _bgScene->draw();
1891
1892 _bg->draw();
1893
1894 if (_okBtn->_flags & 4)
1895 _okBtn->draw();
1896
1897 if (_cancelBtn->_flags & 4)
1898 _cancelBtn->draw();
1899 }
1900
handleMessage(ExCommand * cmd)1901 bool ModalQuery::handleMessage(ExCommand *cmd) {
1902 if (cmd->_messageKind == 17) {
1903 if (cmd->_messageNum == 29) {
1904 if (_okBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) {
1905 _queryResult = 1;
1906
1907 return false;
1908 }
1909
1910 if (_cancelBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
1911 _queryResult = 0;
1912 } else if (cmd->_messageNum == 36 && cmd->_param == 27) {
1913 _queryResult = 0;
1914
1915 return false;
1916 }
1917 }
1918
1919 return false;
1920 }
1921
init(int counterdiff)1922 bool ModalQuery::init(int counterdiff) {
1923 if (_okBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
1924 _okBtn->_flags |= 4;
1925 else
1926 _okBtn->_flags &= 0xFFFB;
1927
1928 if (_cancelBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
1929 _cancelBtn->_flags |= 4;
1930 else
1931 _cancelBtn->_flags &= 0xFFFB;
1932
1933 if (_queryResult == -1) {
1934 return true;
1935 } else {
1936 if (g_fp->isDemo() && g_fp->getLanguage() == Common::RU_RUS) {
1937 if (!_queryResult)
1938 return false;
1939
1940 ModalDemo *demo = new ModalDemo;
1941 demo->launch();
1942
1943 g_fp->_modalObject = demo;
1944
1945 return true;
1946 }
1947
1948 if (_bg->_id == PIC_MEX_BGR) {
1949 _cancelBtn->_flags &= 0xFFFB;
1950 _okBtn->_flags &= 0xFFFB;
1951
1952 if (_queryResult == 1) {
1953 if (_bgScene)
1954 g_fp->sceneFade(_bgScene, false);
1955
1956 g_fp->_gameContinue = false;
1957
1958 return false;
1959 }
1960 }
1961 }
1962
1963 return false;
1964 }
1965
ModalSaveGame()1966 ModalSaveGame::ModalSaveGame() {
1967 _oldBgX = 0;
1968 _oldBgY = 0;
1969
1970 _bgr = 0;
1971 _okD = 0;
1972 _okL = 0;
1973 _cancelD = 0;
1974 _cancelL = 0;
1975 _emptyD = 0;
1976 _emptyL = 0;
1977 _fullD = 0;
1978 _fullL = 0;
1979 _menuScene = 0;
1980 _queryRes = -1;
1981 _rect = g_fp->_sceneRect;
1982 _queryDlg = 0;
1983 _mode = 1;
1984
1985 _objtype = kObjTypeModalSaveGame;
1986 }
1987
~ModalSaveGame()1988 ModalSaveGame::~ModalSaveGame() {
1989 g_fp->_sceneRect = _rect;
1990 }
1991
setScene(Scene * sc)1992 void ModalSaveGame::setScene(Scene *sc) {
1993 _queryRes = -1;
1994 _menuScene = sc;
1995 }
1996
processKey(int key)1997 void ModalSaveGame::processKey(int key) {
1998 if (key == 27)
1999 _queryRes = 0;
2000 }
2001
init(int counterdiff)2002 bool ModalSaveGame::init(int counterdiff) {
2003 if (_queryDlg) {
2004 if (!_queryDlg->init(counterdiff)) {
2005 if (!_queryDlg->getQueryResult())
2006 _queryRes = -1;
2007
2008 delete _queryDlg;
2009 _queryDlg = 0;
2010 }
2011
2012 return true;
2013 }
2014
2015 if (_queryRes == -1)
2016 return true;
2017
2018 g_fp->_sceneRect = _rect;
2019
2020 if (g_fp->_currentScene) {
2021 g_fp->_currentScene->_x = _oldBgX;
2022 g_fp->_currentScene->_y = _oldBgY;
2023 }
2024
2025 if (!_queryRes) {
2026 ModalMainMenu *m = new ModalMainMenu;
2027
2028 g_fp->_modalObject = m;
2029
2030 m->_parentObj = _parentObj;
2031 m->_screct = _rect;
2032 m->_bgX = _oldBgX;
2033 m->_bgY = _oldBgY;
2034
2035 delete this;
2036
2037 return true;
2038 }
2039
2040 return false;
2041 }
2042
setup(Scene * sc,int mode)2043 void ModalSaveGame::setup(Scene *sc, int mode) {
2044 _files.clear();
2045 _arrayL.clear();
2046 _arrayD.clear();
2047 _mode = mode;
2048
2049 if (mode) {
2050 _bgr = sc->getPictureObjectById(PIC_MSV_BGR, 0);
2051 _cancelD = sc->getPictureObjectById(PIC_MSV_CANCEL_D, 0);
2052 _cancelL = sc->getPictureObjectById(PIC_MSV_CANCEL_L, 0);
2053 _okD = sc->getPictureObjectById(PIC_MSV_OK_D, 0);
2054 _okL = sc->getPictureObjectById(PIC_MSV_OK_L, 0);
2055 _emptyD = sc->getPictureObjectById(PIC_MSV_EMPTY_D, 0);
2056 _emptyL = sc->getPictureObjectById(PIC_MSV_EMPTY_L, 0);
2057 } else {
2058 _bgr = sc->getPictureObjectById(PIC_MLD_BGR, 0);
2059 _cancelD = sc->getPictureObjectById(PIC_MLD_CANCEL_D, 0);
2060 _cancelL = sc->getPictureObjectById(PIC_MLD_CANCEL_L, 0);
2061 _okD = sc->getPictureObjectById(PIC_MLD_OK_D, 0);
2062 _okL = sc->getPictureObjectById(PIC_MLD_OK_L, 0);
2063 _emptyD = sc->getPictureObjectById(PIC_MSV_EMPTY_D, 0);
2064 _emptyL = sc->getPictureObjectById(PIC_MSV_EMPTY_D, 0);
2065 }
2066
2067 _fullD = sc->getPictureObjectById(PIC_MSV_FULL_D, 0);
2068 _fullL = sc->getPictureObjectById(PIC_MSV_FULL_L, 0);
2069 _queryRes = -1;
2070
2071 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_0_D, 0));
2072 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_0_L, 0));
2073 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_1_D, 0));
2074 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_1_L, 0));
2075 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_2_D, 0));
2076 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_2_L, 0));
2077 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_3_D, 0));
2078 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_3_L, 0));
2079 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_4_D, 0));
2080 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_4_L, 0));
2081 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_5_D, 0));
2082 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_5_L, 0));
2083 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_6_D, 0));
2084 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_6_L, 0));
2085 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_7_D, 0));
2086 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_7_L, 0));
2087 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_8_D, 0));
2088 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_8_L, 0));
2089 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_9_D, 0));
2090 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_9_L, 0));
2091 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_DOTS_D, 0));
2092 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_DOTS_L, 0));
2093 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_DOT_D, 0));
2094 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_DOT_L, 0));
2095 _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_SPACE_D, 0));
2096 _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_SPACE_L, 0));
2097
2098 int x = _bgr->_ox + _bgr->getDimensions().x / 2;
2099 int y = _bgr->_oy + 90;
2100 int w;
2101
2102 _files.clear();
2103 _files.resize(7);
2104 for (int i = 0; i < 7; i++) {
2105 FileInfo &fileinfo = _files[i];
2106
2107 Common::strlcpy(fileinfo.filename, getSavegameFile(i), sizeof(fileinfo.filename));
2108
2109 if (!getFileInfo(i, &fileinfo)) {
2110 fileinfo.empty = true;
2111 w = _emptyD->getDimensions().x;
2112 } else {
2113 w = 0;
2114
2115 for (uint j = 0; j < _arrayL.size(); j++) {
2116 w += _arrayL[j]->getDimensions().x + 2;
2117 }
2118 }
2119
2120 fileinfo.fx1 = x - w / 2;
2121 fileinfo.fx2 = x + w / 2;
2122 fileinfo.fy1 = y;
2123 fileinfo.fy2 = y + _emptyD->getDimensions().y;
2124 y = fileinfo.fy2 + 3;
2125 }
2126 }
2127
getSaveName()2128 char *ModalSaveGame::getSaveName() {
2129 if (_queryRes < 0)
2130 return 0;
2131
2132 return _files[_queryRes - 1].filename;
2133 }
2134
getFileInfo(int slot,FileInfo * fileinfo)2135 bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
2136 Common::ScopedPtr<Common::InSaveFile> f(g_system->getSavefileManager()->openForLoading(
2137 Fullpipe::getSavegameFile(slot)));
2138
2139 if (!f)
2140 return false;
2141
2142 Fullpipe::FullpipeSavegameHeader header;
2143 if (!Fullpipe::readSavegameHeader(f.get(), header))
2144 return false;
2145
2146 // Create the return descriptor
2147 SaveStateDescriptor desc(slot, header.saveName);
2148 char res[17];
2149
2150 Fullpipe::parseSavegameHeader(header, desc);
2151
2152 snprintf(res, sizeof(res), "%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str());
2153
2154 for (int i = 0; i < 16; i++) {
2155 switch (res[i]) {
2156 case '-':
2157 case '.':
2158 fileinfo->date[i] = 11;
2159 break;
2160 case ' ':
2161 fileinfo->date[i] = 12;
2162 break;
2163 case ':':
2164 fileinfo->date[i] = 10;
2165 break;
2166 case '0':
2167 case '1':
2168 case '2':
2169 case '3':
2170 case '4':
2171 case '5':
2172 case '6':
2173 case '7':
2174 case '8':
2175 case '9':
2176 fileinfo->date[i] = res[i] - '0';
2177 break;
2178 default:
2179 error("Incorrect date format: %s", res);
2180 }
2181 }
2182
2183 return true;
2184 }
2185
update()2186 void ModalSaveGame::update() {
2187 if (_menuScene)
2188 _menuScene->draw();
2189
2190 _bgr->draw();
2191
2192 if (_queryDlg) {
2193 _queryDlg->update();
2194
2195 return;
2196 }
2197
2198 g_fp->_cursorId = PIC_CSR_DEFAULT;
2199
2200 g_fp->setCursor(g_fp->_cursorId);
2201
2202 for (uint i = 0; i < _files.size(); i++) {
2203 if (g_fp->_mouseScreenPos.x < _files[i].fx1 || g_fp->_mouseScreenPos.x > _files[i].fx2 ||
2204 g_fp->_mouseScreenPos.y < _files[i].fy1 || g_fp->_mouseScreenPos.y > _files[i].fy2 ) {
2205 if (_files[i].empty) {
2206 _emptyD->setOXY(_files[i].fx1, _files[i].fy1);
2207 _emptyD->draw();
2208 } else {
2209 int x = _files[i].fx1;
2210
2211 for (int j = 0; j < 16; j++) {
2212 _arrayL[_files[i].date[j]]->setOXY(x + 1, _files[i].fy1);
2213 _arrayL[_files[i].date[j]]->draw();
2214
2215 x += _arrayL[_files[i].date[j]]->getDimensions().x + 2;
2216 }
2217 }
2218 } else {
2219 if (_files[i].empty) {
2220 _emptyL->setOXY(_files[i].fx1, _files[i].fy1);
2221 _emptyL->draw();
2222 } else {
2223 int x = _files[i].fx1;
2224
2225 for (int j = 0; j < 16; j++) {
2226 _arrayD[_files[i].date[j]]->setOXY(x + 1, _files[i].fy1);
2227 _arrayD[_files[i].date[j]]->draw();
2228
2229 x += _arrayD[_files[i].date[j]]->getDimensions().x + 2;
2230 }
2231 }
2232 }
2233 }
2234 if (_cancelL->isPixelHitAtPos(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
2235 _cancelL->draw();
2236 else if (_okL->isPixelHitAtPos(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
2237 _okL->draw();
2238 }
2239
handleMessage(ExCommand * cmd)2240 bool ModalSaveGame::handleMessage(ExCommand *cmd) {
2241 if (_queryDlg)
2242 return _queryDlg->handleMessage(cmd);
2243
2244 if (cmd->_messageNum == 29)
2245 processMouse(cmd->_x, cmd->_y);
2246 else if (cmd->_messageNum == 36)
2247 processKey(cmd->_param);
2248
2249 return false;
2250 }
2251
processMouse(int x,int y)2252 void ModalSaveGame::processMouse(int x, int y) {
2253 for (uint i = 0; i < _files.size(); i++) {
2254 if (x >= _files[i].fx1 && x <= _files[i].fx2 && y >= _files[i].fy1 && y <= _files[i].fy2) {
2255 _queryRes = i + 1;
2256
2257 if (_mode) {
2258 if (!_files[i].empty) {
2259 _queryDlg = new ModalQuery;
2260
2261 _queryDlg->create(_menuScene, 0, PIC_MOV_BGR);
2262 }
2263 }
2264
2265 return;
2266 }
2267 }
2268
2269 if (_cancelL->isPixelHitAtPos(x, y))
2270 _queryRes = 0;
2271 }
2272
saveload()2273 void ModalSaveGame::saveload() {
2274 if (_objtype != kObjTypeModalSaveGame)
2275 return;
2276
2277 if (_mode) {
2278 if (getSaveName()) {
2279 bool allowed = true;
2280
2281 for (Common::Array<MessageQueue *>::iterator s = g_fp->_globalMessageQueueList->begin(); s != g_fp->_globalMessageQueueList->end(); ++s) {
2282 if (!(*s)->_isFinished && ((*s)->getFlags() & 1))
2283 allowed = false;
2284 }
2285
2286 if (g_fp->_isSaveAllowed && allowed)
2287 g_fp->_gameLoader->writeSavegame(g_fp->_currentScene, getSaveName(), "");
2288 }
2289 } else {
2290 if (getSaveName()) {
2291 if (_parentObj) {
2292 delete _parentObj;
2293
2294 _parentObj = 0;
2295 }
2296
2297 g_fp->stopAllSoundStreams();
2298 g_fp->stopSoundStream2();
2299
2300 g_fp->_gameLoader->readSavegame(getSaveName());
2301 }
2302 }
2303 }
2304
ModalDemo()2305 ModalDemo::ModalDemo() {
2306 _bg = 0;
2307 _button = 0;
2308 _text = 0;
2309
2310 if (g_fp->getLanguage() == Common::RU_RUS) {
2311 _clickedQuit = 0;
2312 _countdown = -10;
2313 } else {
2314 _clickedQuit = -1;
2315 _countdown = 1000;
2316 }
2317 _scene = 0;
2318 }
2319
~ModalDemo()2320 ModalDemo::~ModalDemo() {
2321 if (_bg)
2322 _bg->_flags &= 0xFFFB;
2323
2324 _button->_flags &= 0xFFFB;
2325 _text->_flags &= 0xFFFB;
2326 }
2327
launch()2328 bool ModalDemo::launch() {
2329 Scene *sc = g_fp->accessScene(SC_MAINMENU);
2330
2331 if (g_fp->getLanguage() == Common::RU_RUS) {
2332 _scene = sc;
2333
2334 for (uint i = 1; i < sc->_picObjList.size(); i++) {
2335 if (sc->_picObjList[i]->_id == 399)
2336 sc->_picObjList[i]->_flags |= 4;
2337 else
2338 sc->_picObjList[i]->_flags &= 0xFFFB;
2339 }
2340
2341 _button = sc->getPictureObjectById(443, 0);
2342 _text = sc->getPictureObjectById(402, 0);
2343
2344 _countdown = -10;
2345
2346 return true;
2347 }
2348
2349 _bg = sc->getPictureObjectById(PIC_POST_BGR, 0);
2350
2351 if (!_bg)
2352 return false;
2353
2354 _button = sc->getPictureObjectById(PIC_POST_BUTTON, 0);
2355 _text = sc->getPictureObjectById(PIC_POST_TEXT, 0);
2356
2357 _clickedQuit = -1;
2358
2359 // fadeout
2360 warning("STUB: ModelDemo: fadeout");
2361 update();
2362
2363 g_fp->stopAllSoundStreams();
2364 g_fp->stopAllSounds();
2365 g_fp->playSound(SND_CMN_056, 0);
2366 g_fp->playSound(SND_CMN_069, 1);
2367
2368 return true;
2369 }
2370
init(int counterDiff)2371 bool ModalDemo::init(int counterDiff) {
2372 if (g_fp->getLanguage() == Common::RU_RUS)
2373 return init2(counterDiff);
2374
2375 g_fp->_cursorId = PIC_CSR_DEFAULT;
2376
2377 if (_button->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) {
2378 if (!(_button->_flags & 4))
2379 g_fp->playSound(SND_CMN_070, 0);
2380
2381 _button->_flags |= 4;
2382
2383 g_fp->_cursorId = PIC_CSR_ITN;
2384 } else {
2385 _button->_flags &= 0xFFFB;
2386 }
2387
2388 g_fp->setCursor(g_fp->_cursorId);
2389
2390 _countdown -= counterDiff;
2391
2392 if (_countdown <= 0)
2393 _countdown = 1000;
2394
2395 if (_clickedQuit == -1)
2396 return true;
2397
2398 g_system->openUrl("http://www.amazon.de/EuroVideo-Bildprogramm-GmbH-Full-Pipe/dp/B003TO51YE/ref=sr_1_1");
2399
2400 g_fp->_gameContinue = false;
2401
2402 return false;
2403 }
2404
init2(int counterDiff)2405 bool ModalDemo::init2(int counterDiff) {
2406 if (_clickedQuit) {
2407 g_system->openUrl("http://pipestudio.ru/fullpipe/");
2408
2409 g_fp->_gameContinue = false;
2410
2411 return false;
2412 }
2413
2414 if (_countdown > 0) {
2415 _countdown--;
2416 } else {
2417 _text->_flags ^= 4;
2418 _countdown = 24;
2419 }
2420
2421 if (_button->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) {
2422 _button->_flags |= 4;
2423
2424 g_fp->_cursorId = PIC_CSR_ITN;
2425 } else {
2426 _button->_flags &= 0xFFFB;
2427
2428 g_fp->_cursorId = PIC_CSR_DEFAULT;
2429 }
2430
2431 return true;
2432 }
2433
update()2434 void ModalDemo::update() {
2435 if (g_fp->getLanguage() == Common::RU_RUS) {
2436 if (_countdown == -10)
2437 g_fp->sceneFade(_scene, true);
2438
2439 _scene->draw();
2440
2441 return;
2442 }
2443
2444 _bg->draw();
2445
2446 if (_button->_flags & 4)
2447 _button->draw();
2448
2449 if (_text->_flags & 4)
2450 _text->draw();
2451 }
2452
handleMessage(ExCommand * cmd)2453 bool ModalDemo::handleMessage(ExCommand *cmd) {
2454 if (cmd->_messageKind != 17)
2455 return false;
2456
2457 if (cmd->_messageNum == 29) {
2458 if (_button->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
2459 _clickedQuit = 1;
2460 } else if (cmd->_messageNum == 36 && (cmd->_param == 27 || g_fp->getLanguage() == Common::RU_RUS)) {
2461 _clickedQuit = 1;
2462 }
2463
2464 return false;
2465 }
2466
openHelp()2467 void FullpipeEngine::openHelp() {
2468 if (!_modalObject) {
2469 ModalHelp *help = new ModalHelp;
2470
2471 _modalObject = help;
2472
2473 help->launch();
2474 }
2475 }
2476
openMainMenu()2477 void FullpipeEngine::openMainMenu() {
2478 if (isDemo() && getLanguage() == Common::RU_RUS) {
2479 ModalQuery *q = new ModalQuery;
2480
2481 Scene *sc = accessScene(SC_MAINMENU);
2482
2483 q->create(sc, 0, 0);
2484
2485 g_fp->_modalObject = q;
2486
2487 return;
2488 }
2489 ModalMainMenu *menu = new ModalMainMenu;
2490
2491 menu->_parentObj = g_fp->_modalObject;
2492
2493 g_fp->_modalObject = menu;
2494 }
2495
2496 } // End of namespace Fullpipe
2497