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 "illusions/menusystem.h"
24 #include "illusions/illusions.h"
25 #include "illusions/dictionary.h"
26 #include "illusions/input.h"
27 #include "illusions/screen.h"
28 #include "illusions/screentext.h"
29 #include "illusions/thread.h"
30 #include "illusions/time.h"
31 #include "common/config-manager.h"
32 #include "common/translation.h"
33 #include "gui/saveload.h"
34
35 namespace Illusions {
36
37 // MenuItem
38
MenuItem(const Common::String text,BaseMenuAction * action)39 MenuItem::MenuItem(const Common::String text, BaseMenuAction *action)
40 : _text(text), _action(action) {
41 }
42
~MenuItem()43 MenuItem::~MenuItem() {
44 delete _action;
45 }
46
executeAction(const Common::Point & point)47 void MenuItem::executeAction(const Common::Point &point) {
48 _mouseClickPoint = point;
49 _action->execute();
50 }
51
52 // BaseMenu
53
BaseMenu(BaseMenuSystem * menuSystem,uint32 fontId,byte backgroundColor,byte borderColor,byte textColor,byte fieldE,uint defaultMenuItemIndex)54 BaseMenu::BaseMenu(BaseMenuSystem *menuSystem, uint32 fontId, byte backgroundColor, byte borderColor, byte textColor, byte fieldE,
55 uint defaultMenuItemIndex)
56 : _menuSystem(menuSystem), _fontId(fontId), _backgroundColor(backgroundColor), _borderColor(borderColor), _textColor(textColor), _fieldE(fieldE),
57 _defaultMenuItemIndex(defaultMenuItemIndex)
58 {
59 }
60
~BaseMenu()61 BaseMenu::~BaseMenu() {
62 for (MenuItems::iterator it = _menuItems.begin(); it != _menuItems.end(); ++it) {
63 delete *it;
64 }
65 }
66
addText(const Common::String text)67 void BaseMenu::addText(const Common::String text) {
68 _text.push_back(text);
69 }
70
addMenuItem(MenuItem * menuItem)71 void BaseMenu::addMenuItem(MenuItem *menuItem) {
72 _menuItems.push_back(menuItem);
73 }
74
getHeaderLinesCount()75 uint BaseMenu::getHeaderLinesCount() {
76 return _text.size();
77 }
78
getHeaderLine(uint index)79 const Common::String& BaseMenu::getHeaderLine(uint index) {
80 return _text[index];
81 }
82
getMenuItemsCount()83 uint BaseMenu::getMenuItemsCount() {
84 return _menuItems.size();
85 }
86
getMenuItem(uint index)87 MenuItem *BaseMenu::getMenuItem(uint index) {
88 return _menuItems[index];
89 }
90
enterMenu()91 void BaseMenu::enterMenu() {
92 // Empty, implemented if neccessary by the inherited class when the menu is entered
93 }
94
95 // BaseMenuSystem
96
BaseMenuSystem(IllusionsEngine * vm)97 BaseMenuSystem::BaseMenuSystem(IllusionsEngine *vm)
98 : _vm(vm), _isTimeOutEnabled(false), _menuChoiceOffset(0) {
99 }
100
~BaseMenuSystem()101 BaseMenuSystem::~BaseMenuSystem() {
102 }
103
playSoundEffect13()104 void BaseMenuSystem::playSoundEffect13() {
105 playSoundEffect(13);
106 }
107
playSoundEffect14()108 void BaseMenuSystem::playSoundEffect14() {
109 playSoundEffect(14);
110 }
111
selectMenuChoiceIndex(uint choiceIndex)112 void BaseMenuSystem::selectMenuChoiceIndex(uint choiceIndex) {
113 debug(0, "choiceIndex: %d", choiceIndex);
114 debug(0, "_menuChoiceOffset: %p", (void*)_menuChoiceOffset);
115 if (choiceIndex > 0 && _menuChoiceOffset) {
116 *_menuChoiceOffset = _menuChoiceOffsets[choiceIndex - 1];
117 debug(0, "*_menuChoiceOffset: %04X", *_menuChoiceOffset);
118 }
119 _vm->_threads->notifyId(_menuCallerThreadId);
120 _menuCallerThreadId = 0;
121 closeMenu();
122 }
123
leaveMenu()124 void BaseMenuSystem::leaveMenu() {
125 playSoundEffect13();
126 if (!_menuStack.empty())
127 leaveSubMenu();
128 else
129 closeMenu();
130 }
131
enterSubMenu(BaseMenu * menu)132 void BaseMenuSystem::enterSubMenu(BaseMenu *menu) {
133 _menuStack.push(_activeMenu);
134 activateMenu(menu);
135 _hoveredMenuItemIndex = _hoveredMenuItemIndex3;
136 _hoveredMenuItemIndex2 = _hoveredMenuItemIndex3;
137 setMouseCursorToMenuItem(_hoveredMenuItemIndex);
138 placeActorHoverBackground();
139 placeActorTextColorRect();
140 }
141
leaveSubMenu()142 void BaseMenuSystem::leaveSubMenu() {
143 _activeMenu = _menuStack.pop();
144 _field54 = _activeMenu->_field2C18;
145 _menuLinesCount = _activeMenu->getHeaderLinesCount();
146 _hoveredMenuItemIndex = 1;
147 _vm->_screenText->removeText();
148 _vm->_screenText->removeText();
149 activateMenu(_activeMenu);
150 _hoveredMenuItemIndex = _hoveredMenuItemIndex3;
151 _hoveredMenuItemIndex2 = _hoveredMenuItemIndex3;
152 setMouseCursorToMenuItem(_hoveredMenuItemIndex);
153 initActorHoverBackground();
154 placeActorTextColorRect();
155 }
156
enterSubMenuById(int menuId)157 void BaseMenuSystem::enterSubMenuById(int menuId) {
158 BaseMenu *menu = getMenuById(menuId);
159 enterSubMenu(menu);
160 }
161
getQueryConfirmationChoiceIndex() const162 uint BaseMenuSystem::getQueryConfirmationChoiceIndex() const {
163 return _queryConfirmationChoiceIndex;
164 }
165
setQueryConfirmationChoiceIndex(uint queryConfirmationChoiceIndex)166 void BaseMenuSystem::setQueryConfirmationChoiceIndex(uint queryConfirmationChoiceIndex) {
167 _queryConfirmationChoiceIndex = queryConfirmationChoiceIndex;
168 }
169
setMouseCursorToMenuItem(int menuItemIndex)170 void BaseMenuSystem::setMouseCursorToMenuItem(int menuItemIndex) {
171 Common::Point mousePos;
172 if (calcMenuItemMousePos(menuItemIndex, mousePos))
173 setMousePos(mousePos);
174 }
175
calcMenuItemRect(uint menuItemIndex,WRect & rect)176 void BaseMenuSystem::calcMenuItemRect(uint menuItemIndex, WRect &rect) {
177 FontResource *font = _vm->_dict->findFont(_activeMenu->_fontId);
178 int charHeight = font->getCharHeight() + font->getLineIncr();
179
180 _vm->_screenText->getTextInfoPosition(rect._topLeft);
181 if (_activeMenu->_backgroundColor) {
182 rect._topLeft.y += 4;
183 rect._topLeft.x += 4;
184 }
185 rect._topLeft.y += charHeight * (menuItemIndex + _menuLinesCount - 1);
186
187 WidthHeight textInfoDimensions;
188 _vm->_screenText->getTextInfoDimensions(textInfoDimensions);
189 rect._bottomRight.x = rect._topLeft.x + textInfoDimensions._width;
190 rect._bottomRight.y = rect._topLeft.y + charHeight;
191 }
192
calcMenuItemMousePos(uint menuItemIndex,Common::Point & pt)193 bool BaseMenuSystem::calcMenuItemMousePos(uint menuItemIndex, Common::Point &pt) {
194 if (menuItemIndex < _hoveredMenuItemIndex3 || menuItemIndex >= _hoveredMenuItemIndex3 + _menuItemCount)
195 return false;
196
197 WRect rect;
198 calcMenuItemRect(menuItemIndex - _hoveredMenuItemIndex3 + 1, rect);
199 pt.x = rect._topLeft.x;
200 pt.y = rect._topLeft.y + (rect._bottomRight.y - rect._topLeft.y) / 2;
201 return true;
202 }
203
calcMenuItemIndexAtPoint(Common::Point pt,uint & menuItemIndex)204 bool BaseMenuSystem::calcMenuItemIndexAtPoint(Common::Point pt, uint &menuItemIndex) {
205 WRect rect;
206 calcMenuItemRect(1, rect);
207
208 uint index = _hoveredMenuItemIndex3 + (pt.y - rect._topLeft.y) / (rect._bottomRight.y - rect._topLeft.y);
209
210 if (pt.y < rect._topLeft.y || pt.x < rect._topLeft.x || pt.x > rect._bottomRight.x ||
211 index > _field54 || index > _hoveredMenuItemIndex3 + _menuItemCount - 1)
212 return false;
213
214 menuItemIndex = index;
215 return true;
216 }
217
setMousePos(Common::Point & mousePos)218 void BaseMenuSystem::setMousePos(Common::Point &mousePos) {
219 _vm->_input->setCursorPosition(mousePos);
220 Control *mouseCursor = _vm->getObjectControl(Illusions::CURSOR_OBJECT_ID);
221 mouseCursor->_actor->_position = mousePos;
222 }
223
activateMenu(BaseMenu * menu)224 void BaseMenuSystem::activateMenu(BaseMenu *menu) {
225 _activeMenu = menu;
226 // TODO Run menu enter callback if neccessary
227 _menuLinesCount = menu->getHeaderLinesCount();
228 menu->_field2C18 = menu->getMenuItemsCount();
229 _hoveredMenuItemIndex3 = 1;
230 _field54 = menu->_field2C18;
231
232 uint v2 = drawMenuText(menu);
233 if (menu->_field2C18 <= v2)
234 _menuItemCount = menu->_field2C18;
235 else
236 _menuItemCount = v2;
237
238 }
239
initActorHoverBackground()240 void BaseMenuSystem::initActorHoverBackground() {
241 Control *v0 = _vm->getObjectControl(0x4013E);
242 if (!v0) {
243 WidthHeight dimensions;
244 dimensions._width = 300;
245 dimensions._height = 15;
246 if (_vm->getGameId() == kGameIdBBDOU) {
247 _vm->_controls->placeSequenceLessActor(0x4013E, Common::Point(0, 0), dimensions, 91);
248 } else {
249 _vm->_controls->placeSequenceLessActor(0x4013E, Common::Point(0, 0), dimensions, 18);
250 }
251 v0 = _vm->getObjectControl(0x4013E);
252 v0->_flags |= 8;
253 }
254 placeActorHoverBackground();
255 v0->appearActor();
256 }
257
placeActorHoverBackground()258 void BaseMenuSystem::placeActorHoverBackground() {
259 Control *v0 = _vm->getObjectControl(0x4013E);
260 v0->fillActor(0);
261
262 WidthHeight textInfoDimensions;
263 _vm->_screenText->getTextInfoDimensions(textInfoDimensions);
264
265 if (_activeMenu->_backgroundColor && _activeMenu->_borderColor != _activeMenu->_backgroundColor)
266 textInfoDimensions._width -= 6;
267
268 WidthHeight frameDimensions;
269 v0->getActorFrameDimensions(frameDimensions);
270
271 FontResource *font = _vm->_dict->findFont(_activeMenu->_fontId);
272 int charHeight = font->getCharHeight() + font->getLineIncr();
273 if (frameDimensions._height < charHeight)
274 charHeight = frameDimensions._height;
275
276 v0->drawActorRect(Common::Rect(textInfoDimensions._width - 1, charHeight), _activeMenu->_fieldE);
277
278 updateActorHoverBackground();
279 }
280
updateActorHoverBackground()281 void BaseMenuSystem::updateActorHoverBackground() {
282 Control *v0 = _vm->getObjectControl(0x4013E);
283 WRect rect;
284 calcMenuItemRect(_hoveredMenuItemIndex2 - _hoveredMenuItemIndex3 + 1, rect);
285 v0->setActorPosition(rect._topLeft);
286 }
287
hideActorHoverBackground()288 void BaseMenuSystem::hideActorHoverBackground() {
289 Control *v0 = _vm->getObjectControl(0x4013E);
290 if (v0)
291 v0->disappearActor();
292 }
293
initActorTextColorRect()294 void BaseMenuSystem::initActorTextColorRect() {
295 Control *v0 = _vm->getObjectControl(0x40143);
296 if (!v0) {
297 WidthHeight dimensions;
298 if (_vm->getGameId() == kGameIdBBDOU) {
299 dimensions._width = 420;
300 dimensions._height = 180;
301 _vm->_controls->placeSequenceLessActor(0x40143, Common::Point(0, 0), dimensions, 90);
302 } else {
303 dimensions._width = 300;
304 dimensions._height = 180;
305 _vm->_controls->placeSequenceLessActor(0x40143, Common::Point(0, 0), dimensions, 17);
306 }
307 v0 = _vm->getObjectControl(0x40143);
308 v0->_flags |= 8;
309 }
310 placeActorTextColorRect();
311 v0->appearActor();
312 }
313
placeActorTextColorRect()314 void BaseMenuSystem::placeActorTextColorRect() {
315 Control *v0 = _vm->getObjectControl(0x40143);
316 v0->fillActor(0);
317
318 Common::Point textInfoPosition;
319 WidthHeight textInfoDimensions;
320 _vm->_screenText->getTextInfoPosition(textInfoPosition);
321 _vm->_screenText->getTextInfoDimensions(textInfoDimensions);
322
323 if (_activeMenu->_backgroundColor && _activeMenu->_borderColor != _activeMenu->_backgroundColor) {
324 textInfoDimensions._width -= 2;
325 textInfoDimensions._height -= 6;
326 }
327
328 v0->setActorPosition(textInfoPosition);
329 v0->drawActorRect(Common::Rect(textInfoDimensions._width - 1, textInfoDimensions._height - 1), _activeMenu->_textColor);
330 }
331
hideActorTextColorRect()332 void BaseMenuSystem::hideActorTextColorRect() {
333 Control *v0 = _vm->getObjectControl(0x40143);
334 if (v0)
335 v0->disappearActor();
336 }
337
openMenu(BaseMenu * menu)338 void BaseMenuSystem::openMenu(BaseMenu *menu) {
339
340 _isActive = true;
341 _menuStack.clear();
342
343 _cursorInitialVisibleFlag = initMenuCursor();
344 _savedCursorPos = _vm->_input->getCursorPosition();
345 _savedGameState = getGameState();
346 Control *cursorControl = _vm->getObjectControl(Illusions::CURSOR_OBJECT_ID);
347 _savedCursorActorIndex = cursorControl->_actor->_actorIndex;
348 _savedCursorSequenceId = cursorControl->_actor->_sequenceId;
349
350 setMenuCursorNum(1);
351
352 if (_vm->getGameId() == kGameIdDuckman) {
353 setGameState(4);
354 } else if (_vm->getGameId() == kGameIdBBDOU) {
355 setGameState(3);
356 }
357
358 activateMenu(menu);
359
360 _hoveredMenuItemIndex = _hoveredMenuItemIndex3;
361 _hoveredMenuItemIndex2 = _hoveredMenuItemIndex3;
362 setMouseCursorToMenuItem(_hoveredMenuItemIndex);
363 initActorHoverBackground();
364 initActorTextColorRect();
365 _vm->_input->discardAllEvents();
366 }
367
closeMenu()368 void BaseMenuSystem::closeMenu() {
369 while (!_menuStack.empty()) {
370 _vm->_screenText->removeText();
371 _menuStack.pop();
372 }
373 _vm->_screenText->removeText();
374 hideActorHoverBackground();
375 hideActorTextColorRect();
376 Control *mouseCursor = _vm->getObjectControl(Illusions::CURSOR_OBJECT_ID);
377 setGameState(_savedGameState);
378 mouseCursor->_actor->_actorIndex = _savedCursorActorIndex;
379 mouseCursor->_actor->_position = _savedCursorPos;
380 setMousePos(_savedCursorPos);
381 mouseCursor->startSequenceActor(_savedCursorSequenceId, 2, 0);
382 if (_cursorInitialVisibleFlag)
383 mouseCursor->disappearActor();
384 _vm->_input->discardAllEvents();
385 _isActive = false;
386 }
387
handleClick(uint menuItemIndex,const Common::Point & mousePos)388 void BaseMenuSystem::handleClick(uint menuItemIndex, const Common::Point &mousePos) {
389 debug(0, "BaseMenuSystem::handleClick() menuItemIndex: %d click point: (%d, %d)", menuItemIndex, mousePos.x, mousePos.y);
390
391 if (menuItemIndex == 0) {
392 playSoundEffect14();
393 return;
394 }
395
396 MenuItem *menuItem = _activeMenu->getMenuItem(menuItemIndex - 1);
397 menuItem->executeAction(mousePos);
398
399 }
400
drawMenuText(BaseMenu * menu)401 uint BaseMenuSystem::drawMenuText(BaseMenu *menu) {
402 MenuTextBuilder *menuTextBuilder = new MenuTextBuilder();
403 uint lineCount = 0;
404
405 for (uint i = 0; i < menu->getHeaderLinesCount(); ++i) {
406 menuTextBuilder->appendString(menu->getHeaderLine(i));
407 menuTextBuilder->appendNewLine();
408 }
409
410 for (uint i = _hoveredMenuItemIndex3; i <= _field54; ++i) {
411 menuTextBuilder->appendString(menu->getMenuItem(i - 1)->getText());
412 if (i + 1 <= menu->getMenuItemsCount())
413 menuTextBuilder->appendNewLine();
414 ++lineCount;
415 }
416
417 menuTextBuilder->finalize();
418
419 uint16 *text = menuTextBuilder->getText();
420
421 Common::Point textPt;
422 int16 v9 = 0;
423 if (menu->_backgroundColor)
424 v9 = 4;
425 textPt.x = v9;
426 textPt.y = v9;
427
428 uint flags = TEXT_FLAG_LEFT_ALIGN;
429 if (menu->_backgroundColor != menu->_borderColor)
430 flags |= TEXT_FLAG_BORDER_DECORATION;
431
432 WidthHeight dimensions;
433
434 if (_vm->getGameId() == kGameIdDuckman) {
435 dimensions._width = 300;
436 dimensions._height = 180;
437 } else if (_vm->getGameId() == kGameIdBBDOU) {
438 dimensions._width = 580;
439 dimensions._height = 420;
440 }
441
442 uint16 *outTextPtr;
443 if (!_vm->_screenText->insertText(text, menu->_fontId, dimensions, textPt, flags, menu->_backgroundColor, menu->_borderColor, 0xFF, 0xFF, 0xFF, outTextPtr)) {
444 --lineCount;
445 for ( ; *outTextPtr; ++outTextPtr) {
446 if (*outTextPtr == 13)
447 --lineCount;
448 }
449 }
450
451 delete menuTextBuilder;
452
453 return lineCount;
454 }
455
update(Control * cursorControl)456 void BaseMenuSystem::update(Control *cursorControl) {
457 Common::Point mousePos = _vm->_input->getCursorPosition();
458 setMousePos(mousePos);
459
460 uint newHoveredMenuItemIndex;
461 bool resetTimeOut = false;
462
463 if (calcMenuItemIndexAtPoint(mousePos, newHoveredMenuItemIndex)) {
464 if (newHoveredMenuItemIndex != _hoveredMenuItemIndex) {
465 if (_hoveredMenuItemIndex == 0)
466 initActorHoverBackground();
467 _hoveredMenuItemIndex = newHoveredMenuItemIndex;
468 _hoveredMenuItemIndex2 = newHoveredMenuItemIndex;
469 setMenuCursorNum(2);
470 updateActorHoverBackground();
471 resetTimeOut = true;
472 }
473 } else if (_hoveredMenuItemIndex != 0) {
474 setMenuCursorNum(1);
475 hideActorHoverBackground();
476 _hoveredMenuItemIndex = 0;
477 resetTimeOut = true;
478 }
479
480 if (_vm->_input->hasNewEvents())
481 resetTimeOut = true;
482
483 if (_vm->_input->pollEvent(kEventLeftClick)) {
484 handleClick(_hoveredMenuItemIndex, mousePos);
485 } else if (_vm->_input->pollEvent(kEventAbort) && _activeMenu->_defaultMenuItemIndex) {
486 handleClick(_activeMenu->_defaultMenuItemIndex, mousePos);
487 } else if (_vm->_input->pollEvent(kEventUp)) {
488 // TODO handleUpKey();
489 if (_hoveredMenuItemIndex == 1) {
490 _hoveredMenuItemIndex = _activeMenu->getMenuItemsCount();
491 } else {
492 _hoveredMenuItemIndex--;
493 }
494 setMouseCursorToMenuItem(_hoveredMenuItemIndex);
495 _hoveredMenuItemIndex2 = _hoveredMenuItemIndex;
496 updateActorHoverBackground();
497 playSoundEffect(0xC);
498 } else if (_vm->_input->pollEvent(kEventDown)) {
499 // TODO handleDownKey();
500 if (_hoveredMenuItemIndex == _activeMenu->getMenuItemsCount()) {
501 _hoveredMenuItemIndex = 1;
502 } else {
503 _hoveredMenuItemIndex++;
504 }
505 setMouseCursorToMenuItem(_hoveredMenuItemIndex);
506 _hoveredMenuItemIndex2 = _hoveredMenuItemIndex;
507 updateActorHoverBackground();
508 playSoundEffect(0xC);
509 }
510
511 updateTimeOut(resetTimeOut);
512 }
513
setTimeOutDuration(uint32 duration,uint timeOutMenuChoiceIndex)514 void BaseMenuSystem::setTimeOutDuration(uint32 duration, uint timeOutMenuChoiceIndex) {
515 if (duration > 0) {
516 _isTimeOutEnabled = true;
517 _isTimeOutReached = false;
518 _timeOutDuration = duration;
519 _timeOutMenuChoiceIndex = timeOutMenuChoiceIndex;
520 _timeOutStartTime = getCurrentTime();
521 _timeOutEndTime = duration + _timeOutStartTime;
522 } else {
523 _isTimeOutEnabled = false;
524 }
525 }
526
setMenuCallerThreadId(uint32 menuCallerThreadId)527 void BaseMenuSystem::setMenuCallerThreadId(uint32 menuCallerThreadId) {
528 _menuCallerThreadId = menuCallerThreadId;
529 }
530
setMenuChoiceOffsets(MenuChoiceOffsets menuChoiceOffsets,int16 * menuChoiceOffset)531 void BaseMenuSystem::setMenuChoiceOffsets(MenuChoiceOffsets menuChoiceOffsets, int16 *menuChoiceOffset) {
532 _menuChoiceOffsets = menuChoiceOffsets;
533 _menuChoiceOffset = menuChoiceOffset;
534 }
535
setSavegameSlotNum(int slotNum)536 void BaseMenuSystem::setSavegameSlotNum(int slotNum) {
537 _vm->_savegameSlotNum = slotNum;
538 }
539
setSavegameDescription(Common::String desc)540 void BaseMenuSystem::setSavegameDescription(Common::String desc) {
541 _vm->_savegameDescription = desc;
542 }
543
updateTimeOut(bool resetTimeOut)544 void BaseMenuSystem::updateTimeOut(bool resetTimeOut) {
545
546 if (!_isTimeOutEnabled)
547 return;
548
549 if (_menuStack.empty()) {
550 if (_isTimeOutReached) {
551 resetTimeOut = true;
552 _isTimeOutReached = false;
553 }
554 } else if (!_isTimeOutReached) {
555 _isTimeOutReached = true;
556 }
557
558 if (!_isTimeOutReached) {
559 if (resetTimeOut) {
560 _timeOutStartTime = getCurrentTime();
561 _timeOutEndTime = _timeOutDuration + _timeOutStartTime;
562 } else if (isTimerExpired(_timeOutStartTime, _timeOutEndTime)) {
563 _isTimeOutEnabled = false;
564 selectMenuChoiceIndex(_timeOutMenuChoiceIndex);
565 }
566 }
567
568 }
569
redrawMenuText(BaseMenu * menu)570 void BaseMenuSystem::redrawMenuText(BaseMenu *menu) {
571 _vm->_screenText->removeText();
572 drawMenuText(menu);
573 }
574
calcMenuItemTextPositionAtPoint(Common::Point pt,int & offset)575 bool BaseMenuSystem::calcMenuItemTextPositionAtPoint(Common::Point pt, int &offset) {
576 uint menuItemIndex;
577 if (!calcMenuItemIndexAtPoint(pt, menuItemIndex)) {
578 return false;
579 }
580
581 WRect rect;
582
583 MenuItem *menuItem = _activeMenu->getMenuItem(menuItemIndex - 1);
584 calcMenuItemRect(menuItemIndex, rect);
585 int x = pt.x - rect._topLeft.x;
586 Common::String text = menuItem->getText();
587 FontResource *font = _vm->_dict->findFont(_activeMenu->_fontId);
588
589 int curX = 0;
590 for (uint i = 0; i < text.size(); i++) {
591 int16 w = font->getCharInfo(text[i])->_width;
592 if (x >= curX && x <= curX + w) {
593 offset = i;
594 return true;
595 }
596 curX = curX + w;
597 }
598
599 return false;
600 }
601
602 // MenuTextBuilder
603
MenuTextBuilder()604 MenuTextBuilder::MenuTextBuilder() : _pos(0) {
605 }
606
appendString(const Common::String & value)607 void MenuTextBuilder::appendString(const Common::String &value) {
608 for (uint i = 0; i < value.size(); ++i) {
609 _text[_pos++] = value[i];
610 }
611 }
612
appendNewLine()613 void MenuTextBuilder::appendNewLine() {
614 _text[_pos++] = '\r';
615 }
616
finalize()617 void MenuTextBuilder::finalize() {
618 _text[_pos] = '\0';
619 }
620
621 // BaseMenuAction
622
BaseMenuAction(BaseMenuSystem * menuSystem)623 BaseMenuAction::BaseMenuAction(BaseMenuSystem *menuSystem)
624 : _menuSystem(menuSystem) {
625 }
626
627 // MenuActionEnterMenu
628
MenuActionEnterMenu(BaseMenuSystem * menuSystem,int menuId)629 MenuActionEnterMenu::MenuActionEnterMenu(BaseMenuSystem *menuSystem, int menuId)
630 : BaseMenuAction(menuSystem), _menuId(menuId) {
631 }
632
execute()633 void MenuActionEnterMenu::execute() {
634 _menuSystem->enterSubMenuById(_menuId);
635 }
636
637 // MenuActionLeaveMenu
638
MenuActionLeaveMenu(BaseMenuSystem * menuSystem)639 MenuActionLeaveMenu::MenuActionLeaveMenu(BaseMenuSystem *menuSystem)
640 : BaseMenuAction(menuSystem) {
641 }
642
execute()643 void MenuActionLeaveMenu::execute() {
644 _menuSystem->leaveMenu();
645 }
646
647 // MenuActionReturnChoice
648
MenuActionReturnChoice(BaseMenuSystem * menuSystem,uint choiceIndex)649 MenuActionReturnChoice::MenuActionReturnChoice(BaseMenuSystem *menuSystem, uint choiceIndex)
650 : BaseMenuAction(menuSystem), _choiceIndex(choiceIndex) {
651 }
652
execute()653 void MenuActionReturnChoice::execute() {
654 _menuSystem->playSoundEffect13();
655 _menuSystem->selectMenuChoiceIndex(_choiceIndex);
656 }
657
658 // MenuActionEnterQueryMenu
659
MenuActionEnterQueryMenu(BaseMenuSystem * menuSystem,int menuId,uint confirmationChoiceIndex)660 MenuActionEnterQueryMenu::MenuActionEnterQueryMenu(BaseMenuSystem *menuSystem, int menuId, uint confirmationChoiceIndex)
661 : BaseMenuAction(menuSystem), _menuId(menuId), _confirmationChoiceIndex(confirmationChoiceIndex) {
662 }
663
execute()664 void MenuActionEnterQueryMenu::execute() {
665 _menuSystem->setQueryConfirmationChoiceIndex(_confirmationChoiceIndex);
666 _menuSystem->enterSubMenuById(_menuId);
667 }
668
669 // MenuActionLoadGame
670
MenuActionLoadGame(BaseMenuSystem * menuSystem,uint choiceIndex)671 MenuActionLoadGame::MenuActionLoadGame(BaseMenuSystem *menuSystem, uint choiceIndex)
672 : BaseMenuAction(menuSystem), _choiceIndex(choiceIndex) {
673 }
674
execute()675 void MenuActionLoadGame::execute() {
676 const Plugin *plugin = NULL;
677 EngineMan.findGame(ConfMan.get("gameid"), &plugin);
678 GUI::SaveLoadChooser *dialog;
679 Common::String desc;
680 int slot;
681
682 dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
683 slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
684
685 delete dialog;
686
687 if (slot >= 0) {
688 _menuSystem->setSavegameSlotNum(slot);
689 _menuSystem->selectMenuChoiceIndex(_choiceIndex);
690 }
691
692 }
693
694 // MenuActionSaveGame
695
MenuActionSaveGame(BaseMenuSystem * menuSystem,uint choiceIndex)696 MenuActionSaveGame::MenuActionSaveGame(BaseMenuSystem *menuSystem, uint choiceIndex)
697 : BaseMenuAction(menuSystem), _choiceIndex(choiceIndex) {
698 }
699
execute()700 void MenuActionSaveGame::execute() {
701 const Plugin *plugin = NULL;
702 EngineMan.findGame(ConfMan.get("gameid"), &plugin);
703 GUI::SaveLoadChooser *dialog;
704 Common::String desc;
705 int slot;
706
707 dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
708 slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
709 desc = dialog->getResultString().c_str();
710
711 delete dialog;
712
713 if (slot >= 0) {
714 _menuSystem->setSavegameSlotNum(slot);
715 _menuSystem->setSavegameDescription(desc);
716 _menuSystem->selectMenuChoiceIndex(_choiceIndex);
717 }
718 }
719
720 } // End of namespace Illusions
721