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 * Originally written by Syn9 in FreeBASIC with SDL
23 * http://syn9.thehideoutgames.com/index_backup.php
24 *
25 * Ported to plain C for GCW-Zero handheld by Dmitry Smagin
26 * http://github.com/dmitrysmagin/griffon_legend
27 *
28 *
29 * Programming/Graphics: Daniel "Syn9" Kennedy
30 * Music/Sound effects: David Turner
31 *
32 * Beta testing and gameplay design help:
33 * Deleter, Cha0s, Aether Fox, and Kiz
34 *
35 */
36
37 #include "common/system.h"
38 #include "common/config-manager.h"
39
40 #include "griffon/griffon.h"
41
42 #include "common/text-to-speech.h"
43
44 namespace Griffon {
45
46 #define MINCURSEL 7
47 #define MAXCURSEL 16
48 #define SY 25
49 #define PI 3.141593
50
title(int mode)51 void GriffonEngine::title(int mode) {
52 const char *optionTitles[4] = {
53 "new game/save/load",
54 "options",
55 "quit game",
56 "return"
57 };
58
59 Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
60
61 float xofs = 0;
62 _itemyloc = 0;
63 bool exitTitle = false;
64
65 rcSrc.left = 0;
66 rcSrc.top = 0;
67 rcSrc.setWidth(320);
68 rcSrc.setHeight(240);
69
70 _videoBuffer2->fillRect(rcSrc, 0);
71 _videoBuffer3->fillRect(rcSrc, 0);
72
73 _ticks = g_system->getMillis();
74
75 _videoBuffer->blit(*_videoBuffer3);
76 _videoBuffer->blit(*_videoBuffer2);
77
78 int cursel = 0;
79 int ticks1 = _ticks;
80
81 if (config.music) {
82 setChannelVolume(_musicChannel, 0);
83 pauseSoundChannel(_musicChannel);
84
85 _menuChannel = playSound(_musicMenu, true);
86 setChannelVolume(_menuChannel, config.musicVol);
87 _pmenu = true;
88 }
89
90 bool ldstop = false;
91
92 float ld = 0;
93 do {
94 Common::Rect rc;
95
96 ld += 4.0 * _fpsr;
97 if (ld > config.musicVol)
98 ld = config.musicVol;
99 if (!ldstop) {
100 setChannelVolume(_menuChannel, (int)ld);
101 if ((int)ld == config.musicVol)
102 ldstop = true;
103 }
104
105 rc.left = -xofs;
106 rc.top = 0;
107
108 _titleImg->blit(*_videoBuffer, rc.left, rc.top);
109
110 rc.left = -xofs + 320.0;
111 rc.top = 0;
112
113 _titleImg->blit(*_videoBuffer, rc.left, rc.top);
114
115 rc.left = 0;
116 rc.top = 0;
117
118 _titleImg2->blit(*_videoBuffer, rc.left, rc.top);
119
120 int y = 172;
121 int x = 160 - 14 * 4;
122
123 drawString(_videoBuffer, optionTitles[0], x, y, 4);
124 drawString(_videoBuffer, optionTitles[1], x, y + 16, 4);
125 drawString(_videoBuffer, optionTitles[2], x, y + 32, 4);
126
127 if (mode == 1)
128 drawString(_videoBuffer, optionTitles[3], x, y + 48, 4);
129 else
130 drawString(_videoBuffer, "(c) 2005 by Daniel 'Syn9' Kennedy", 28, 224, 4);
131
132 rc.left = (int16)(x - 16 - 4 * cos(2 * PI * _itemyloc / 16));
133 rc.top = (int16)(y - 4 + 16 * cursel);
134
135 _itemImg[15]->blit(*_videoBuffer, rc.left, rc.top);
136
137 float yf = 255.0;
138 if (_ticks < ticks1 + 1000) {
139 yf = 255.0 * ((float)(_ticks - ticks1) / 1000.0);
140 yf = CLIP<float>(yf, 0.0, 255.0);
141 }
142
143 _videoBuffer->setAlpha((int)yf);
144 g_system->copyRectToScreen(_videoBuffer->getPixels(), _videoBuffer->pitch, 0, 0, _videoBuffer->w, _videoBuffer->h);
145 g_system->updateScreen();
146
147 _ticksPassed = _ticks;
148 _ticks = g_system->getMillis();
149
150 _ticksPassed = _ticks - _ticksPassed;
151 _fpsr = (float)_ticksPassed / 24.0;
152
153 _fp++;
154 if (_ticks > _nextTicks) {
155 _nextTicks = _ticks + 1000;
156 _fps = _fp;
157 _fp = 0;
158 }
159
160 float add = 0.5 * _fpsr;
161 if (add > 1)
162 add = 1;
163
164 xofs += add;
165 if (xofs >= 320.0)
166 xofs -= 320.0;
167
168 _itemyloc += 0.75 * _fpsr;
169
170 while (_itemyloc >= 16)
171 _itemyloc = _itemyloc - 16;
172
173 if (g_system->getEventManager()->pollEvent(_event)) {
174 if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER)
175 _shouldQuit = true;
176
177 if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
178
179 switch(_event.customType) {
180 case kGriffonMenu:
181 if (mode == 1)
182 exitTitle = true;
183 break;
184 case kGriffonUp:
185 cursel--;
186 if (cursel < 0)
187 cursel = (mode == 1 ? 3 : 2);
188 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
189 ttsMan->say(optionTitles[cursel]);
190 break;
191 case kGriffonDown:
192 cursel++;
193 if (cursel >= (mode == 1 ? 4 : 3))
194 cursel = 0;
195 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
196 ttsMan->say(optionTitles[cursel]);
197 break;
198 case kGriffonConfirm:
199 if (ttsMan != nullptr)
200 ttsMan->stop();
201 switch(cursel) {
202 case 0:
203 _ticks = g_system->getMillis();
204 ticks1 = _ticks;
205
206 saveLoadNew();
207
208 if (_gameMode == kGameModeNewGame || _gameMode == kGameModeLoadGame) {
209 exitTitle = true;
210 }
211 break;
212 case 1:
213 configMenu();
214 _ticks = g_system->getMillis();
215 ticks1 = _ticks;
216 break;
217 case 2:
218 _shouldQuit = true;
219 break;
220 case 3:
221 exitTitle = true;
222 default:
223 break;
224 }
225 break;
226 default:
227 break;
228 }
229 }
230 }
231
232 g_system->delayMillis(10);
233 } while (!_shouldQuit && !exitTitle && _gameMode != kGameModeNewGame && _gameMode != kGameModeLoadGame);
234
235 _itemTicks = _ticks + 210;
236
237 if (config.music) {
238 haltSoundChannel(_menuChannel);
239 resumeSoundChannel(_musicChannel);
240 setChannelVolume(_musicChannel, config.musicVol);
241 _pmenu = false;
242 }
243 }
244
formatPercent(int val)245 static Common::String formatPercent(int val) {
246 val = val / 2.55;
247 return Common::String::format("%d percent", val - val % 10);
248 }
249
speakMenuItem(int mapTitles,int mapValues,const char * mapTitleText[],const char * mapValueText[])250 static void speakMenuItem(int mapTitles, int mapValues, const char *mapTitleText[], const char *mapValueText[]) {
251 Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
252 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
253 Common::TextToSpeechManager::Action valueAction = Common::TextToSpeechManager::INTERRUPT;
254 if (mapTitles != 0) {
255 ttsMan->say(mapTitleText[mapTitles]);
256 valueAction = Common::TextToSpeechManager::QUEUE;
257 }
258 if (mapValues != 0)
259 ttsMan->say(mapValueText[mapValues], valueAction);
260 }
261 }
262
configMenu()263 void GriffonEngine::configMenu() {
264 static const char *optionTitles[25] = {
265 "", "",
266 "", "", "", "",
267 "", "", "",
268 "Music:", "", "",
269 "Sound Effects:", "", "",
270 "Text to Speech:", "", "",
271 "Music Volume:", "",
272 "Effects Volume:", "", "", "", ""
273 };
274 static const char *optionValues[25] = {
275 "", "",
276 "", "", "", "",
277 "", "", "",
278 "On", "Off", "",
279 "On", "Off", "",
280 "On", "Off", "",
281 "[----------]", "",
282 "[----------]", "",
283 "Exit + Save", "",
284 "Exit"
285 };
286 static const int curselMapTitles[MAXCURSEL+1] = {
287 0, 0, 0, 0, 0,
288 0, 0, 9, 9, 12,
289 12, 15, 15, 18, 20,
290 0, 0
291 };
292 static const int curselMapValues[MAXCURSEL+1] = {
293 0, 0, 0, 0, 0,
294 0, 0, 9, 10, 12,
295 13, 15, 16, 0, 0,
296 22, 24
297 };
298
299 int cursel = MINCURSEL;
300 bool exitMenu = false;
301
302 _ticks = g_system->getMillis();
303
304 Graphics::TransparentSurface *configwindow = loadImage("art/configwindow.bmp", true);
305 configwindow->setAlpha(160, true);
306
307 int ticks1 = _ticks;
308
309 Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
310
311 do {
312 _videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
313 _videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
314
315 rcDest.left = 256 + 256 * cos(PI / 180 * _cloudAngle * 40);
316 rcDest.top = 192 + 192 * sin(PI / 180 * _cloudAngle * 40);
317 rcDest.setWidth(320);
318 rcDest.setHeight(240);
319
320 _cloudImg->blit(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, TS_ARGB(128, 255, 255, 255));
321
322 rcDest.left = 256;
323 rcDest.top = 192;
324 rcDest.setWidth(320);
325 rcDest.setHeight(240);
326
327 _cloudImg->blit(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, TS_ARGB(128, 255, 255, 255));
328
329 configwindow->blit(*_videoBuffer);
330
331 int sy = SY;
332
333 for (int i = 0; i <= 24; i++) {
334 static char line[24];
335
336 int destColumn = 3;
337 if (i == 9 && config.music)
338 destColumn = 0;
339 else if (i == 10 && !config.music)
340 destColumn = 0;
341 else if (i == 12 && config.effects)
342 destColumn = 0;
343 else if (i == 13 && !config.effects)
344 destColumn = 0;
345 else if (i == 15 && ConfMan.getBool("tts_enabled"))
346 destColumn = 0;
347 else if (i == 16 && !ConfMan.getBool("tts_enabled"))
348 destColumn = 0;
349 else if (i == 18|| i == 20) {
350 int vol = (i ==18 ? config.musicVol : config.effectsVol) * 9 / 255;
351 vol = CLIP(vol, 0, 9);
352
353 strcpy(line, "[----------]");
354 line[vol + 1] = 'X';
355 optionValues[i] = line;
356 } else if (i > 21)
357 destColumn = 0;
358
359 drawString(_videoBuffer, optionTitles[i], 156 - 8 * strlen(optionTitles[i]), sy + i * 8, 0);
360 drawString(_videoBuffer, optionValues[i], 164, sy + i * 8, destColumn);
361 }
362
363 int curselt = cursel + 2;
364 if (cursel > 8)
365 curselt += 1;
366 if (cursel > 10)
367 curselt += 1;
368 if (cursel > 12)
369 curselt += 1;
370 if (cursel > 13)
371 curselt += 1;
372 if (cursel > 14)
373 curselt += 1;
374 if (cursel > 15)
375 curselt += 1;
376
377 Common::Rect rc;
378 rc.left = 148 + 3 * cos(2 * PI * _itemyloc / 16.0);
379 rc.top = sy + 8 * curselt - 4;
380
381 _itemImg[15]->blit(*_videoBuffer, rc.left, rc.top);
382
383 if (_ticks < ticks1 + 1000) {
384 float yy = 255.0 * ((float)(_ticks - ticks1) / 1000.0);
385 yy = CLIP<float>(yy, 0.0, 255.0);
386
387 _videoBuffer->setAlpha((uint8)yy);
388 }
389
390 _videoBuffer->blit(*_videoBuffer2);
391 g_system->copyRectToScreen(_videoBuffer2->getPixels(), _videoBuffer2->pitch, 0, 0, _videoBuffer2->w, _videoBuffer2->h);
392
393 _ticksPassed = _ticks;
394 _ticks = g_system->getMillis();
395
396 _ticksPassed = _ticks - _ticksPassed;
397 _fpsr = (float)_ticksPassed / 24;
398
399 _fp++;
400 if (_ticks > _nextTicks) {
401 _nextTicks = _ticks + 1000;
402 _fps = _fp;
403 _fp = 0;
404 }
405
406 _itemyloc += 0.75 * _fpsr;
407 while (_itemyloc >= 16)
408 _itemyloc -= 16;
409
410 while (g_system->getEventManager()->pollEvent(_event)) {
411 switch (_event.type) {
412 case Common::EVENT_QUIT:
413 case Common::EVENT_RETURN_TO_LAUNCHER:
414 _shouldQuit = true;
415 break;
416
417 case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
418 switch (_event.customType) {
419 case kGriffonMenu:
420 exitMenu = true;
421 break;
422
423 case kGriffonLeft:
424 if (cursel == 13) {
425 config.musicVol = CLIP(config.musicVol - 25, 0, 255);
426 setChannelVolume(_musicChannel, config.musicVol);
427 setChannelVolume(_menuChannel, config.musicVol);
428 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
429 ttsMan->say(formatPercent(config.musicVol));
430 } else if (cursel == 14) {
431 config.effectsVol = CLIP(config.effectsVol - 25, 0, 255);
432
433 setChannelVolume(-1, config.effectsVol);
434 setChannelVolume(_musicChannel, config.musicVol);
435 setChannelVolume(_menuChannel, config.musicVol);
436 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
437 ttsMan->say(formatPercent(config.effectsVol));
438
439 if (config.effects) {
440 int snd = playSound(_sfx[kSndDoor]);
441 setChannelVolume(snd, config.effectsVol);
442 }
443 }
444 break;
445
446 case kGriffonRight:
447 if (cursel == 13) {
448 config.musicVol = CLIP(config.musicVol + 25, 0, 255);
449 setChannelVolume(_musicChannel, config.musicVol);
450 setChannelVolume(_menuChannel, config.musicVol);
451 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
452 ttsMan->say(formatPercent(config.musicVol));
453 } else if (cursel == 14) {
454 config.effectsVol = CLIP(config.effectsVol + 25, 0, 255);
455 setChannelVolume(-1, config.effectsVol);
456 setChannelVolume(_musicChannel, config.musicVol);
457 setChannelVolume(_menuChannel, config.musicVol);
458 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
459 ttsMan->say(formatPercent(config.effectsVol));
460
461 if (config.effects) {
462 int snd = playSound(_sfx[kSndDoor]);
463 setChannelVolume(snd, config.effectsVol);
464 }
465 }
466 break;
467
468 case kGriffonUp:
469 cursel--;
470 if (cursel < MINCURSEL)
471 cursel = MAXCURSEL;
472 speakMenuItem(curselMapTitles[cursel], curselMapValues[cursel], optionTitles, optionValues);
473 break;
474
475 case kGriffonDown:
476 ++cursel;
477 if (cursel > MAXCURSEL)
478 cursel = MINCURSEL;
479 speakMenuItem(curselMapTitles[cursel], curselMapValues[cursel], optionTitles, optionValues);
480 break;
481
482 case kGriffonConfirm:
483 switch (cursel) {
484 case 7:
485 if (!config.music) {
486 config.music = true;
487 _menuChannel = playSound(_musicMenu, true);
488 setChannelVolume(_menuChannel, config.musicVol);
489 }
490 break;
491 case 8:
492 if (config.music) {
493 config.music = false;
494 haltSoundChannel(_musicChannel);
495 haltSoundChannel(_menuChannel);
496 }
497 break;
498 case 9:
499 if (!config.effects) {
500 config.effects = true;
501 int snd = playSound(_sfx[kSndDoor]);
502 setChannelVolume(snd, config.effectsVol);
503 }
504 break;
505 case 10:
506 if (config.effects)
507 config.effects = false;
508 break;
509 case 11:
510 if (!ConfMan.getBool("tts_enabled")) {
511 ConfMan.setBool("tts_enabled", true);
512 }
513 break;
514 case 12:
515 if (ConfMan.getBool("tts_enabled")) {
516 ConfMan.setBool("tts_enabled", false);
517 }
518 break;
519 case 15:
520 saveConfig();
521 // fall through
522 case 16:
523 if (ttsMan != nullptr)
524 ttsMan->stop();
525 exitMenu = true;
526 break;
527 default:
528 break;
529 }
530 break;
531
532 default:
533 break;
534 }
535
536 default:
537 break;
538 }
539 }
540
541 _cloudAngle += 0.01 * _fpsr;
542 while (_cloudAngle >= 360)
543 _cloudAngle -= 360;
544
545 g_system->updateScreen();
546 g_system->delayMillis(10);
547 } while (!_shouldQuit && !exitMenu && _gameMode != kGameModeNewGame && _gameMode != kGameModeLoadGame);
548
549
550 configwindow->free();
551 _itemTicks = _ticks + 210;
552 }
553
renderSaveStates()554 void GriffonEngine::renderSaveStates() {
555 _videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
556
557 for (int ff = 0; ff <= 3; ff++) {
558 loadPlayer(ff);
559
560 if (_playera.level > 0) {
561 int sx = 8;
562 int sy = 57 + ff * 48;
563
564 // time
565 int ase = _asecstart;
566 int h = ((ase - (ase % 3600)) / 3600);
567 ase = (ase - h * 3600);
568 int m = ((ase - (ase % 60)) / 60);
569 int s = (ase - m * 60);
570
571 char line[256];
572 sprintf(line, "Game Time: %02i:%02i:%02i", h, m, s);
573 drawString(_videoBuffer2, line, 160 - strlen(line) * 4, sy, 0);
574
575 sx = 12;
576 sy += 11;
577 int cc = 0;
578
579 sprintf(line, "Health: %i/%i", _playera.hp, _playera.maxHp);
580 drawString(_videoBuffer2, line, sx, sy, cc);
581
582 if (_playera.level == 22)
583 strcpy(line, "Level: MAX");
584 else
585 sprintf(line, "Level: %i", _playera.level);
586
587 drawString(_videoBuffer2, line, sx, sy + 11, 0);
588
589 rcSrc.left = sx + 15 * 8 + 24;
590 rcSrc.top = sy + 1;
591
592 int ss = (_playera.sword - 1) * 3;
593 if (_playera.sword == 3)
594 ss = 18;
595 _itemImg[ss]->blit(*_videoBuffer2, rcSrc.left, rcSrc.top);
596
597 rcSrc.left += 16;
598 ss = (_playera.shield - 1) * 3 + 1;
599 if (_playera.shield == 3)
600 ss = 19;
601 _itemImg[ss]->blit(*_videoBuffer2, rcSrc.left, rcSrc.top);
602
603 rcSrc.left += 16;
604 ss = (_playera.armour - 1) * 3 + 2;
605 if (_playera.armour == 3)
606 ss = 20;
607 _itemImg[ss]->blit(*_videoBuffer2, rcSrc.left, rcSrc.top);
608
609 int nx = rcSrc.left + 13 + 3 * 8;
610 rcSrc.left = nx - 17;
611
612 if (_playera.foundSpell[0]) {
613 for (int i = 0; i < 5; i++) {
614 rcSrc.left += 17;
615 if (_playera.foundSpell[i])
616 _itemImg[7 + i]->blit(*_videoBuffer2, rcSrc.left, rcSrc.top);
617 }
618 }
619 } else {
620 int sy = 57 + ff * 48;
621 drawString(_videoBuffer2, "Empty", 160 - 5 * 4, sy, 0);
622 }
623 }
624 }
625
saveLoadNew()626 void GriffonEngine::saveLoadNew() {
627 const char *optionTitles[4] = {
628 "new game", "", "load", "return",
629 };
630
631 float y = 0.0;
632
633 _cloudAngle = 0;
634
635 int curRow = 0;
636 int curCol = 0;
637
638 bool lowerLock = false;
639
640 _ticks = g_system->getMillis();
641 int ticks1 = _ticks;
642 int tickPause = _ticks + 150;
643
644
645 renderSaveStates();
646
647 delete _saveLoadImg;
648
649 _saveLoadImg = loadImage("art/saveloadnew.bmp", true);
650 if (_gameMode == kGameModeIntro) {
651 uint32 color = *(uint32 *)_saveLoadImg->getBasePtr(120, 10);
652 _saveLoadImg->fillRect(Common::Rect(125, 15, 160, 33), color);
653 }
654 _saveLoadImg->setAlpha(192, true);
655
656 Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
657
658 // Main menu loop
659 do {
660 _videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
661
662 y += 1 * _fpsr;
663
664 rcDest.left = 256 + 256 * cos(PI / 180 * _cloudAngle * 40);
665 rcDest.top = 192 + 192 * sin(PI / 180 * _cloudAngle * 40);
666 rcDest.setWidth(320);
667 rcDest.setHeight(240);
668
669 _cloudImg->blit(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, TS_ARGB(128, 255, 255, 255));
670
671 rcDest.left = 256;
672 rcDest.top = 192;
673 rcDest.setWidth(320);
674 rcDest.setHeight(240);
675
676 _cloudImg->blit(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, TS_ARGB(128, 255, 255, 255));
677
678 _saveLoadImg->blit(*_videoBuffer);
679
680 if (g_system->getEventManager()->pollEvent(_event)) {
681 if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER) {
682 _shouldQuit = true;
683 return;
684 }
685
686 if (tickPause < _ticks && _event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
687 _itemTicks = _ticks + 220;
688
689 if (_event.customType == kGriffonConfirm) {
690 if (curRow == 0) {
691 if (curCol == 0) {
692 // NEW GAME
693 if (ttsMan != nullptr)
694 ttsMan->stop();
695 _gameMode = kGameModeNewGame;
696
697 return;
698 } else if (curCol == 1) {
699 // SAVE GAME
700 lowerLock = true;
701 curRow = 1 + _saveSlot;
702 tickPause = _ticks + 125;
703 } else if (curCol == 2) {
704 // LOAD GAME
705 lowerLock = true;
706 curRow = 1;
707 tickPause = _ticks + 125;
708 } else if (curCol == 3) {
709 if (ttsMan != nullptr)
710 ttsMan->stop();
711 // RETURN
712 return;
713 } else if (curCol == 4) {
714 // QUIT - non existent :)
715 _shouldQuit = true;
716 return;
717 }
718 }
719 if (lowerLock && tickPause < _ticks) {
720 if ((curCol == 1) && saveGameState(curRow - 1, "", false).getCode() == Common::kNoError) {
721 _secStart += _secsInGame;
722 _secsInGame = 0;
723 lowerLock = false;
724 _saveSlot = curRow - 1;
725 curRow = 0;
726
727 renderSaveStates();
728 } else if ((curCol == 2) && loadGameState(curRow - 1).getCode() == Common::kNoError) {
729
730 return;
731 }
732 tickPause = _ticks + 125;
733 }
734 }
735
736 switch (_event.customType) {
737 case kGriffonMenu:
738 if (curRow == 0)
739 return;
740 lowerLock = false;
741 curRow = 0;
742 tickPause = _ticks + 125;
743 break;
744 case kGriffonDown:
745 if (lowerLock) {
746 ++curRow;
747 if (curRow == 5)
748 curRow = 1;
749 tickPause = _ticks + 125;
750 }
751 break;
752
753 case kGriffonUp:
754 if (lowerLock) {
755 --curRow;
756 if (curRow == 0)
757 curRow = 4;
758 tickPause = _ticks + 125;
759 }
760 break;
761
762 case kGriffonLeft:
763 if (!lowerLock) {
764 --curCol;
765 if (curCol == -1)
766 curCol = 3;
767
768 if (curCol == 1 && _gameMode == kGameModeIntro)
769 curCol = 0;
770
771 tickPause = _ticks + 125;
772 }
773 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
774 ttsMan -> say(optionTitles[curCol]);
775 break;
776
777 case kGriffonRight:
778 if (!lowerLock) {
779 ++curCol;
780 if (curCol == 4)
781 curCol = 0;
782
783 if (curCol == 1 && _gameMode == kGameModeIntro)
784 curCol = 2;
785
786 tickPause = _ticks + 125;
787 }
788 if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
789 ttsMan -> say(optionTitles[curCol]);
790 break;
791 default:
792 ;
793 }
794 }
795 }
796
797 // Render savestates
798 _videoBuffer2->blit(*_videoBuffer);
799
800 // ------------------------------------------
801
802 if (curRow == 0) {
803 rcDest.top = 18;
804 switch(curCol) {
805 case 0:
806 rcDest.left = 10;
807 break;
808 case 1:
809 rcDest.left = 108;
810 break;
811 case 2:
812 rcDest.left = 170;
813 break;
814 case 3:
815 rcDest.left = 230;
816 default:
817 break;
818 }
819
820 rcDest.left += (int16)(2 + 2 * sin(2 * PI * _itemyloc / 16));
821 }
822
823 if (curRow > 0) {
824 rcDest.left = (int16)(0 + 2 * sin(2 * PI * _itemyloc / 16));
825 rcDest.top = (int16)(53 + (curRow - 1) * 48);
826 }
827
828 _itemImg[15]->blit(*_videoBuffer, rcDest.left, rcDest.top);
829
830 if (curRow != 0) {
831 rcDest.top = 18;
832 if (curCol == 1)
833 rcDest.left = 108;
834 else if (curCol == 2)
835 rcDest.left = 170;
836
837 _itemImg[15]->blit(*_videoBuffer, rcDest.left, rcDest.top);
838 }
839
840 if (_ticks < ticks1 + 1000) {
841 int yy = 255 * (_ticks - ticks1) / 1000;
842 yy = CLIP(yy, 0, 255);
843
844 _videoBuffer->setAlpha((uint8)yy);
845 }
846
847 _videoBuffer3->fillRect(Common::Rect(0, 0, _videoBuffer3->w, _videoBuffer3->h), 0);
848 _videoBuffer->blit(*_videoBuffer3);
849
850 g_system->copyRectToScreen(_videoBuffer3->getPixels(), _videoBuffer3->pitch, 0, 0, _videoBuffer3->w, _videoBuffer3->h);
851 g_system->updateScreen();
852
853 _ticksPassed = _ticks;
854 _ticks = g_system->getMillis();
855
856 _ticksPassed = _ticks - _ticksPassed;
857 _fpsr = (float)_ticksPassed / 24;
858
859 _fp++;
860 if (_ticks > _nextTicks) {
861 _nextTicks = _ticks + 1000;
862 _fps = _fp;
863 _fp = 0;
864 }
865
866 _cloudAngle += 0.01 * _fpsr;
867 while (_cloudAngle >= 360)
868 _cloudAngle -= 360;
869
870 _itemyloc += 0.6 * _fpsr;
871 while (_itemyloc >= 16)
872 _itemyloc -= 16;
873
874 g_system->delayMillis(10);
875 } while (!_shouldQuit);
876
877 }
878
879
880 } // end of namespace Griffon
881