mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-22 01:39:57 +00:00
7af17382b5
svn-id: r25530
1652 lines
41 KiB
C++
1652 lines
41 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2005-2006 The ScummVM project
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "kyra/kyra.h"
|
|
#include "kyra/screen.h"
|
|
#include "kyra/script.h"
|
|
#include "kyra/text.h"
|
|
#include "kyra/animator.h"
|
|
#include "kyra/sound.h"
|
|
|
|
#include "common/config-manager.h"
|
|
#include "common/savefile.h"
|
|
#include "common/system.h"
|
|
|
|
namespace Kyra {
|
|
|
|
void KyraEngine::registerDefaultSettings() {
|
|
// Most settings already have sensible defaults. This one, however, is
|
|
// specific to the Kyra engine.
|
|
ConfMan.registerDefault("walkspeed", 2);
|
|
}
|
|
|
|
void KyraEngine::readSettings() {
|
|
int talkspeed = ConfMan.getInt("talkspeed");
|
|
|
|
// The default talk speed is 60. This should be mapped to "Normal".
|
|
|
|
if (talkspeed == 0)
|
|
_configTextspeed = 3; // Clickable
|
|
if (talkspeed <= 50)
|
|
_configTextspeed = 0; // Slow
|
|
else if (talkspeed <= 150)
|
|
_configTextspeed = 1; // Normal
|
|
else
|
|
_configTextspeed = 2; // Fast
|
|
|
|
_configWalkspeed = ConfMan.getInt("walkspeed");
|
|
_configMusic = ConfMan.getBool("music_mute") ? 0 : 1;
|
|
_configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1;
|
|
|
|
_sound->enableMusic(_configMusic);
|
|
_sound->enableSFX(_configSounds);
|
|
|
|
bool speechMute = ConfMan.getBool("speech_mute");
|
|
bool subtitles = ConfMan.getBool("subtitles");
|
|
|
|
if (!speechMute && subtitles)
|
|
_configVoice = 2; // Voice & Text
|
|
else if (!speechMute && !subtitles)
|
|
_configVoice = 1; // Voice only
|
|
else
|
|
_configVoice = 0; // Text only
|
|
|
|
setWalkspeed(_configWalkspeed);
|
|
}
|
|
|
|
void KyraEngine::writeSettings() {
|
|
bool speechMute, subtitles;
|
|
int talkspeed;
|
|
|
|
switch (_configTextspeed) {
|
|
case 0: // Slow
|
|
talkspeed = 1;
|
|
break;
|
|
case 1: // Normal
|
|
talkspeed = 60;
|
|
break;
|
|
case 2: // Fast
|
|
talkspeed = 255;
|
|
break;
|
|
default: // Clickable
|
|
talkspeed = 0;
|
|
break;
|
|
}
|
|
|
|
ConfMan.setInt("talkspeed", talkspeed);
|
|
ConfMan.setInt("walkspeed", _configWalkspeed);
|
|
ConfMan.setBool("music_mute", _configMusic == 0);
|
|
ConfMan.setBool("sfx_mute", _configSounds == 0);
|
|
|
|
switch (_configVoice) {
|
|
case 0: // Text only
|
|
speechMute = true;
|
|
subtitles = true;
|
|
break;
|
|
case 1: // Voice only
|
|
speechMute = false;
|
|
subtitles = false;
|
|
break;
|
|
default: // Voice & Text
|
|
speechMute = false;
|
|
subtitles = true;
|
|
break;
|
|
}
|
|
|
|
if (!_configMusic)
|
|
_sound->beginFadeOut();
|
|
|
|
_sound->enableMusic(_configMusic);
|
|
_sound->enableSFX(_configSounds);
|
|
|
|
ConfMan.setBool("speech_mute", speechMute);
|
|
ConfMan.setBool("subtitles", subtitles);
|
|
|
|
ConfMan.flushToDisk();
|
|
}
|
|
|
|
void KyraEngine::initMainButtonList() {
|
|
_haveScrollButtons = false;
|
|
_buttonList = &_buttonData[0];
|
|
for (int i = 0; _buttonDataListPtr[i]; ++i) {
|
|
_buttonList = initButton(_buttonList, _buttonDataListPtr[i]);
|
|
}
|
|
}
|
|
|
|
Button *KyraEngine::initButton(Button *list, Button *newButton) {
|
|
if (!newButton)
|
|
return list;
|
|
if (!list)
|
|
return newButton;
|
|
Button *cur = list;
|
|
while (true) {
|
|
if (!cur->nextButton) {
|
|
break;
|
|
}
|
|
cur = cur->nextButton;
|
|
}
|
|
cur->nextButton = newButton;
|
|
return list;
|
|
}
|
|
|
|
int KyraEngine::buttonInventoryCallback(Button *caller) {
|
|
int itemOffset = caller->specialValue - 2;
|
|
uint8 inventoryItem = _currentCharacter->inventoryItems[itemOffset];
|
|
if (_itemInHand == -1) {
|
|
if (inventoryItem == 0xFF) {
|
|
snd_playSoundEffect(0x36);
|
|
return 0;
|
|
} else {
|
|
_screen->hideMouse();
|
|
_screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
|
|
snd_playSoundEffect(0x35);
|
|
setMouseItem(inventoryItem);
|
|
updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179);
|
|
_itemInHand = inventoryItem;
|
|
_screen->showMouse();
|
|
_currentCharacter->inventoryItems[itemOffset] = 0xFF;
|
|
}
|
|
} else {
|
|
if (inventoryItem != 0xFF) {
|
|
snd_playSoundEffect(0x35);
|
|
_screen->hideMouse();
|
|
_screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
|
|
_screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
|
|
setMouseItem(inventoryItem);
|
|
updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179);
|
|
_screen->showMouse();
|
|
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
|
|
_itemInHand = inventoryItem;
|
|
} else {
|
|
snd_playSoundEffect(0x32);
|
|
_screen->hideMouse();
|
|
_screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
|
|
_screen->setMouseCursor(1, 1, _shapes[4]);
|
|
updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179);
|
|
_screen->showMouse();
|
|
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
|
|
_itemInHand = -1;
|
|
}
|
|
}
|
|
_screen->updateScreen();
|
|
// XXX clearKyrandiaButtonIO
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::buttonAmuletCallback(Button *caller) {
|
|
if (!(_deathHandler & 8))
|
|
return 1;
|
|
int jewel = caller->specialValue - 0x14;
|
|
if (_currentCharacter->sceneId == 210) {
|
|
if (_beadStateVar == 4 || _beadStateVar == 6)
|
|
return 1;
|
|
}
|
|
if (!queryGameFlag(0x2D))
|
|
return 1;
|
|
if (_itemInHand != -1) {
|
|
assert(_putDownFirst);
|
|
characterSays(2000, _putDownFirst[0], 0, -2);
|
|
return 1;
|
|
}
|
|
if (queryGameFlag(0xF1)) {
|
|
assert(_waitForAmulet);
|
|
characterSays(2001, _waitForAmulet[0], 0, -2);
|
|
return 1;
|
|
}
|
|
if (!queryGameFlag(0x55+jewel)) {
|
|
assert(_blackJewel);
|
|
_animator->makeBrandonFaceMouse();
|
|
drawJewelPress(jewel, 1);
|
|
characterSays(2002, _blackJewel[0], 0, -2);
|
|
return 1;
|
|
}
|
|
drawJewelPress(jewel, 0);
|
|
drawJewelsFadeOutStart();
|
|
drawJewelsFadeOutEnd(jewel);
|
|
|
|
_scriptInterpreter->initScript(_scriptClick, _scriptClickData);
|
|
_scriptClick->variables[3] = 0;
|
|
_scriptClick->variables[6] = jewel;
|
|
_scriptInterpreter->startScript(_scriptClick, 4);
|
|
|
|
while (_scriptInterpreter->validScript(_scriptClick)) {
|
|
_scriptInterpreter->runScript(_scriptClick);
|
|
}
|
|
|
|
if (_scriptClick->variables[3])
|
|
return 1;
|
|
|
|
_unkAmuletVar = 1;
|
|
switch (jewel-1) {
|
|
case 0:
|
|
if (_brandonStatusBit & 1) {
|
|
seq_brandonHealing2();
|
|
} else if (_brandonStatusBit == 0) {
|
|
seq_brandonHealing();
|
|
assert(_healingTip);
|
|
characterSays(2003, _healingTip[0], 0, -2);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
seq_makeBrandonInv();
|
|
break;
|
|
|
|
case 2:
|
|
if (_brandonStatusBit & 1) {
|
|
assert(_wispJewelStrings);
|
|
characterSays(2004, _wispJewelStrings[0], 0, -2);
|
|
} else {
|
|
if (_brandonStatusBit & 2) {
|
|
// XXX
|
|
seq_makeBrandonNormal2();
|
|
// XXX
|
|
} else {
|
|
// do not check for item in hand again as in the original since some strings are missing
|
|
// in the cd version
|
|
if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
|
|
snd_playWanderScoreViaMap(1, 0);
|
|
seq_makeBrandonWisp();
|
|
snd_playWanderScoreViaMap(17, 0);
|
|
} else {
|
|
seq_makeBrandonWisp();
|
|
}
|
|
setGameFlag(0x9E);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
seq_dispelMagicAnimation();
|
|
assert(_magicJewelString);
|
|
characterSays(2007, _magicJewelString[0], 0, -2);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
_unkAmuletVar = 0;
|
|
// XXX clearKyrandiaButtonIO (!used before every return in this function!)
|
|
return 1;
|
|
}
|
|
|
|
void KyraEngine::processButtonList(Button *list) {
|
|
if (_haveScrollButtons) {
|
|
if (_mouseWheel < 0)
|
|
gui_scrollUp(&_scrollUpButton);
|
|
else if (_mouseWheel > 0)
|
|
gui_scrollDown(&_scrollDownButton);
|
|
}
|
|
while (list) {
|
|
if (list->flags & 8) {
|
|
list = list->nextButton;
|
|
continue;
|
|
}
|
|
|
|
int x = list->x;
|
|
int y = list->y;
|
|
assert(list->dimTableIndex < _screen->_screenDimTableCount);
|
|
if (x < 0) {
|
|
x += _screen->_screenDimTable[list->dimTableIndex].w << 3;
|
|
}
|
|
x += _screen->_screenDimTable[list->dimTableIndex].sx << 3;
|
|
|
|
if (y < 0) {
|
|
y += _screen->_screenDimTable[list->dimTableIndex].h;
|
|
}
|
|
y += _screen->_screenDimTable[list->dimTableIndex].sy;
|
|
|
|
if (_mouseX >= x && _mouseY >= y && x + list->width >= _mouseX && y + list->height >= _mouseY) {
|
|
int processMouseClick = 0;
|
|
if (list->flags & 0x400) {
|
|
if (_mousePressFlag) {
|
|
if (!(list->flags2 & 1)) {
|
|
list->flags2 |= 1;
|
|
list->flags2 |= 4;
|
|
processButton(list);
|
|
_screen->updateScreen();
|
|
}
|
|
} else {
|
|
if (list->flags2 & 1) {
|
|
list->flags2 &= 0xFFFE;
|
|
processButton(list);
|
|
processMouseClick = 1;
|
|
}
|
|
}
|
|
} else if (_mousePressFlag) {
|
|
processMouseClick = 1;
|
|
}
|
|
|
|
if (processMouseClick) {
|
|
if (list->buttonCallback) {
|
|
if ((this->*(list->buttonCallback))(list)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (list->flags2 & 1) {
|
|
list->flags2 &= 0xFFFE;
|
|
processButton(list);
|
|
}
|
|
if (list->flags2 & 4) {
|
|
list->flags2 &= 0xFFFB;
|
|
processButton(list);
|
|
_screen->updateScreen();
|
|
}
|
|
list = list->nextButton;
|
|
continue;
|
|
}
|
|
|
|
list = list->nextButton;
|
|
}
|
|
}
|
|
|
|
void KyraEngine::processButton(Button *button) {
|
|
if (!button)
|
|
return;
|
|
|
|
int processType = 0;
|
|
uint8 *shape = 0;
|
|
Button::ButtonCallback callback = 0;
|
|
|
|
int flags = (button->flags2 & 5);
|
|
if (flags == 1) {
|
|
processType = button->process2;
|
|
if (processType == 1) {
|
|
shape = button->process2PtrShape;
|
|
} else if (processType == 4) {
|
|
callback = button->process2PtrCallback;
|
|
}
|
|
} else if (flags == 4 || flags == 5) {
|
|
processType = button->process1;
|
|
if (processType == 1) {
|
|
shape = button->process1PtrShape;
|
|
} else if (processType == 4) {
|
|
callback = button->process1PtrCallback;
|
|
}
|
|
} else {
|
|
processType = button->process0;
|
|
if (processType == 1) {
|
|
shape = button->process0PtrShape;
|
|
} else if (processType == 4) {
|
|
callback = button->process0PtrCallback;
|
|
}
|
|
}
|
|
|
|
int x = button->x;
|
|
int y = button->y;
|
|
assert(button->dimTableIndex < _screen->_screenDimTableCount);
|
|
if (x < 0) {
|
|
x += _screen->_screenDimTable[button->dimTableIndex].w << 3;
|
|
}
|
|
|
|
if (y < 0) {
|
|
y += _screen->_screenDimTable[button->dimTableIndex].h;
|
|
}
|
|
|
|
if (processType == 1 && shape) {
|
|
_screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10);
|
|
} else if (processType == 4 && callback) {
|
|
(this->*callback)(button);
|
|
}
|
|
}
|
|
|
|
void KyraEngine::processAllMenuButtons() {
|
|
if (!_menuButtonList)
|
|
return;
|
|
|
|
Button *cur = _menuButtonList;
|
|
while (true) {
|
|
if (!cur->nextButton) {
|
|
break;
|
|
}
|
|
processMenuButton(cur);
|
|
cur = cur->nextButton;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void KyraEngine::processMenuButton(Button *button) {
|
|
if (!_displayMenu)
|
|
return;
|
|
|
|
if ( !button || (button->flags & 8))
|
|
return;
|
|
|
|
if (button->flags2 & 1)
|
|
button->flags2 &= 0xf7;
|
|
else
|
|
button->flags2 |= 8;
|
|
|
|
button->flags2 &= 0xfc;
|
|
|
|
if (button->flags2 & 4)
|
|
button->flags2 |= 0x10;
|
|
else
|
|
button->flags2 &= 0xef;
|
|
|
|
button->flags2 &= 0xfb;
|
|
|
|
processButton(button);
|
|
}
|
|
|
|
int KyraEngine::drawBoxCallback(Button *button) {
|
|
if (!_displayMenu)
|
|
return 0;
|
|
|
|
_screen->hideMouse();
|
|
_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xf8);
|
|
_screen->showMouse();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::drawShadedBoxCallback(Button *button) {
|
|
|
|
if (!_displayMenu)
|
|
return 0;
|
|
|
|
_screen->hideMouse();
|
|
_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xf9, 0xfa);
|
|
_screen->showMouse();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine::setGUILabels() {
|
|
int offset = 0;
|
|
int offsetOptions = 0;
|
|
int offsetMainMenu = 0;
|
|
int offsetOn = 0;
|
|
|
|
int walkspeedGarbageOffset = 36;
|
|
int menuLabelGarbageOffset = 0;
|
|
|
|
if (_flags.isTalkie) {
|
|
if (_flags.lang == Common::EN_ANY) {
|
|
offset = 52;
|
|
} else if (_flags.lang == Common::DE_DEU) {
|
|
offset = 30;
|
|
} else if (_flags.lang == Common::FR_FRA) {
|
|
offset = 6;
|
|
}
|
|
offsetOn = offsetMainMenu = offsetOptions = offset;
|
|
walkspeedGarbageOffset = 48;
|
|
} else if (_flags.lang == Common::ES_ESP) {
|
|
offsetOn = offsetMainMenu = offsetOptions = offset = -4;
|
|
menuLabelGarbageOffset = 72;
|
|
} else if (_flags.platform == Common::kPlatformFMTowns) {
|
|
offset = 1;
|
|
offsetOptions = 10;
|
|
offsetOn = 0;
|
|
walkspeedGarbageOffset = 0;
|
|
}
|
|
|
|
assert(offset + 27 < _guiStringsSize);
|
|
|
|
// The Legend of Kyrandia
|
|
_menu[0].menuName = _guiStrings[0];
|
|
// Load a Game
|
|
_menu[0].item[0].itemString = _guiStrings[1];
|
|
// Save a Game
|
|
_menu[0].item[1].itemString = _guiStrings[2];
|
|
// Game controls
|
|
_menu[0].item[2].itemString = _guiStrings[3];
|
|
// Quit playing
|
|
_menu[0].item[3].itemString = _guiStrings[4];
|
|
// Resume game
|
|
_menu[0].item[4].itemString = _guiStrings[5];
|
|
|
|
// Cancel
|
|
_menu[2].item[5].itemString = _guiStrings[10];
|
|
|
|
// Enter a description of your saved game:
|
|
_menu[3].menuName = _guiStrings[11];
|
|
// Save
|
|
_menu[3].item[0].itemString = _guiStrings[12];
|
|
// Cancel
|
|
_menu[3].item[1].itemString = _guiStrings[10];
|
|
|
|
// Rest in peace, Brandon
|
|
_menu[4].menuName = _guiStrings[13];
|
|
// Load a game
|
|
_menu[4].item[0].itemString = _guiStrings[1];
|
|
// Quit playing
|
|
_menu[4].item[1].itemString = _guiStrings[4];
|
|
|
|
// Game Controls
|
|
_menu[5].menuName = _guiStrings[6];
|
|
// Yes
|
|
_menu[1].item[0].itemString = _guiStrings[22 + offset];
|
|
// No
|
|
_menu[1].item[1].itemString = _guiStrings[23 + offset];
|
|
|
|
// Music is
|
|
_menu[5].item[0].labelString = _guiStrings[26 + offsetOptions];
|
|
// Sounds are
|
|
_menu[5].item[1].labelString = _guiStrings[27 + offsetOptions];
|
|
// Walk speed
|
|
_menu[5].item[2].labelString = &_guiStrings[24 + offsetOptions][walkspeedGarbageOffset];
|
|
// Text speed
|
|
_menu[5].item[4].labelString = _guiStrings[25 + offsetOptions];
|
|
// Main Menu
|
|
_menu[5].item[5].itemString = &_guiStrings[19 + offsetMainMenu][menuLabelGarbageOffset];
|
|
|
|
if (_flags.isTalkie) {
|
|
// Text & Voice
|
|
_voiceTextString = _guiStrings[28 + offset];
|
|
}
|
|
_textSpeedString = _guiStrings[25 + offsetOptions];
|
|
_onString = _guiStrings[20 + offsetOn];
|
|
_offString = _guiStrings[21 + offset];
|
|
}
|
|
|
|
int KyraEngine::buttonMenuCallback(Button *caller) {
|
|
_displayMenu = true;
|
|
|
|
assert(_guiStrings);
|
|
assert(_configStrings);
|
|
|
|
/*
|
|
for (int i = 0; i < _guiStringsSize; i++)
|
|
debug("GUI string %i: %s", i, _guiStrings[i]);
|
|
|
|
for (int i = 0; i < _configStringsSize; i++)
|
|
debug("Config string %i: %s", i, _configStrings[i]);
|
|
*/
|
|
|
|
setGUILabels();
|
|
if (_currentCharacter->sceneId == 210 && _deathHandler == 0xFF) {
|
|
snd_playSoundEffect(0x36);
|
|
return 0;
|
|
}
|
|
// XXX
|
|
_screen->setPaletteIndex(0xFE, 60, 60, 0);
|
|
for (int i = 0; i < 6; i++) {
|
|
_menuButtonData[i].process0 = _menuButtonData[i].process1 = _menuButtonData[i].process2 = 4;
|
|
_menuButtonData[i].process0PtrCallback = &KyraEngine::drawShadedBoxCallback;
|
|
_menuButtonData[i].process1PtrCallback = &KyraEngine::drawBoxCallback;
|
|
_menuButtonData[i].process2PtrCallback = &KyraEngine::drawShadedBoxCallback;
|
|
}
|
|
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
gui_fadePalette();
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
calcCoords(_menu[i]);
|
|
|
|
_menuRestoreScreen = true;
|
|
_keyboardEvent.pending = 0;
|
|
_keyboardEvent.repeat = 0;
|
|
_mousePressFlag = false;
|
|
|
|
_toplevelMenu = 0;
|
|
if (_menuDirectlyToLoad)
|
|
gui_loadGameMenu(0);
|
|
else {
|
|
if (!caller)
|
|
_toplevelMenu = 4;
|
|
|
|
initMenu(_menu[_toplevelMenu]);
|
|
processAllMenuButtons();
|
|
}
|
|
|
|
while (_displayMenu && !_quitFlag) {
|
|
gui_processHighlights(_menu[_toplevelMenu]);
|
|
processButtonList(_menuButtonList);
|
|
gui_getInput();
|
|
}
|
|
|
|
if (_menuRestoreScreen) {
|
|
gui_restorePalette();
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_animator->_updateScreen = true;
|
|
}
|
|
else
|
|
_screen->deletePageFromDisk(0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine::initMenu(Menu &menu) {
|
|
_menuButtonList = 0;
|
|
|
|
_screen->hideMouse();
|
|
|
|
int textX;
|
|
int textY;
|
|
|
|
int menu_x2 = menu.width + menu.x - 1;
|
|
int menu_y2 = menu.height + menu.y - 1;
|
|
|
|
_screen->fillRect(menu.x + 2, menu.y + 2, menu_x2 - 2, menu_y2 - 2, menu.bgcolor);
|
|
_screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2);
|
|
|
|
if (menu.field_10 != -1)
|
|
textX = menu.x;
|
|
else
|
|
textX = _text->getCenterStringX(menu.menuName, menu.x, menu_x2);
|
|
|
|
textY = menu.y + menu.field_12;
|
|
|
|
_text->printText(menu.menuName, textX - 1, textY + 1, 12, 248, 0);
|
|
_text->printText(menu.menuName, textX, textY, menu.textColor, 0, 0);
|
|
|
|
int x1, y1, x2, y2;
|
|
for (int i = 0; i < menu.nrOfItems; i++) {
|
|
if (!menu.item[i].enabled)
|
|
continue;
|
|
|
|
|
|
x1 = menu.x + menu.item[i].x;
|
|
y1 = menu.y + menu.item[i].y;
|
|
|
|
x2 = x1 + menu.item[i].width - 1;
|
|
y2 = y1 + menu.item[i].height - 1;
|
|
|
|
if (i < 6) {
|
|
_menuButtonData[i].nextButton = 0;
|
|
_menuButtonData[i].x = x1;
|
|
_menuButtonData[i].y = y1;
|
|
_menuButtonData[i].width = menu.item[i].width - 1;
|
|
_menuButtonData[i].height = menu.item[i].height - 1;
|
|
_menuButtonData[i].buttonCallback = menu.item[i].callback;
|
|
_menuButtonData[i].specialValue = menu.item[i].field_1b;
|
|
//_menuButtonData[i].field_6 = menu.item[i].field_25;
|
|
//_menuButtonData[i].field_8 = 0;
|
|
|
|
if (!_menuButtonList)
|
|
_menuButtonList = &_menuButtonData[i];
|
|
else
|
|
_menuButtonList = initButton(_menuButtonList, &_menuButtonData[i]);
|
|
}
|
|
_screen->fillRect(x1, y1, x2, y2, menu.item[i].bgcolor);
|
|
_screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2);
|
|
|
|
if (menu.item[i].itemString) {
|
|
if (menu.item[i].field_12 != -1 && _flags.lang == Common::EN_ANY)
|
|
textX = x1 + menu.item[i].field_12 + 3;
|
|
else
|
|
textX = _text->getCenterStringX(menu.item[i].itemString, x1, x2);
|
|
|
|
textY = y1 + 2;
|
|
_text->printText(menu.item[i].itemString, textX - 1, textY + 1, 12, 0, 0);
|
|
|
|
if (i == menu.highlightedItem)
|
|
_text->printText(menu.item[i].itemString, textX, textY, menu.item[i].highlightColor, 0, 0);
|
|
else
|
|
_text->printText(menu.item[i].itemString, textX, textY, menu.item[i].textColor, 0, 0);
|
|
|
|
if (menu.item[i].labelString) {
|
|
_text->printText(menu.item[i].labelString, menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, 12, 0, 0);
|
|
_text->printText(menu.item[i].labelString, menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, 253, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (menu.scrollUpBtnX != -1) {
|
|
_haveScrollButtons = true;
|
|
|
|
_scrollUpButton.x = menu.scrollUpBtnX + menu.x;
|
|
_scrollUpButton.y = menu.scrollUpBtnY + menu.y;
|
|
_scrollUpButton.buttonCallback = &KyraEngine::gui_scrollUp;
|
|
_scrollUpButton.nextButton = 0;
|
|
_menuButtonList = initButton(_menuButtonList, &_scrollUpButton);
|
|
processMenuButton(&_scrollUpButton);
|
|
|
|
_scrollDownButton.x = menu.scrollDownBtnX + menu.x;
|
|
_scrollDownButton.y = menu.scrollDownBtnY + menu.y;
|
|
_scrollDownButton.buttonCallback = &KyraEngine::gui_scrollDown;
|
|
_scrollDownButton.nextButton = 0;
|
|
_menuButtonList = initButton(_menuButtonList, &_scrollDownButton);
|
|
processMenuButton(&_scrollDownButton);
|
|
} else
|
|
_haveScrollButtons = false;
|
|
|
|
_screen->showMouse();
|
|
_screen->updateScreen();
|
|
}
|
|
|
|
void KyraEngine::calcCoords(Menu &menu) {
|
|
assert(menu.nrOfItems < 7);
|
|
|
|
int widthBackup = _screen->_charWidth;
|
|
_screen->_charWidth = -2;
|
|
|
|
menu.x = (320 - menu.width)/2;
|
|
|
|
int menu_x2 = menu.width + menu.x - 1;
|
|
int maxOffset = 0;
|
|
int x1, x2, y1, y2;
|
|
|
|
for (int i = 0; i < menu.nrOfItems; i++) {
|
|
if (menu.item[i].x == -1)
|
|
menu.item[i].x = (menu.width - menu.item[i].width)/2;
|
|
|
|
if (menu.item[i].labelString) {
|
|
x1 = menu.x + menu.item[i].x + 25;
|
|
y1 = (200 - menu.height)/2 + menu.item[i].y;
|
|
|
|
x2 = x1 + menu.item[i].width;
|
|
y2 = y1 + menu.item[i].height;
|
|
|
|
int textWidth = _screen->getTextWidth(menu.item[i].labelString) + 25;
|
|
int textX = menu.item[i].labelX + menu.x;
|
|
|
|
if (textWidth + textX > x1) {
|
|
int offset = ((textWidth + textX) - x1);
|
|
if (maxOffset < offset)
|
|
maxOffset = offset;
|
|
}
|
|
}
|
|
|
|
if (menu.item[i].itemString) {
|
|
int textWidth = _screen->getTextWidth(menu.item[i].itemString) + 15;
|
|
|
|
if (menu.item[i].width < textWidth) {
|
|
menu.item[i].width = textWidth;
|
|
|
|
if ( menu.x + menu.item[i].x + menu.item[i].width > menu_x2)
|
|
menu.item[i].x -= (menu.x + menu.item[i].x + menu.item[i].width) - menu_x2 + 10;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (maxOffset > 0) {
|
|
maxOffset = maxOffset/2;
|
|
for (int i = 0; i < menu.nrOfItems; i++) {
|
|
menu.item[i].x += maxOffset + 10;
|
|
menu.item[i].labelX -= maxOffset;
|
|
}
|
|
menu.width += maxOffset;
|
|
}
|
|
|
|
if (menu.menuName != 0) {
|
|
int menuNameLength = _screen->getTextWidth(menu.menuName);
|
|
if (menuNameLength > menu.width)
|
|
menu.width = menuNameLength;
|
|
}
|
|
|
|
if (menu.width > 310)
|
|
menu.width = 310;
|
|
|
|
menu.x = (320 - menu.width)/2;
|
|
|
|
if (menu.y == -1)
|
|
menu.y = (200 - menu.height)/2;
|
|
|
|
_screen->_charWidth = widthBackup;
|
|
}
|
|
|
|
void KyraEngine::gui_getInput() {
|
|
OSystem::Event event;
|
|
static uint32 lastScreenUpdate = 0;
|
|
uint32 now = _system->getMillis();
|
|
|
|
_mouseWheel = 0;
|
|
while (_system->pollEvent(event)) {
|
|
switch (event.type) {
|
|
case OSystem::EVENT_QUIT:
|
|
quitGame();
|
|
break;
|
|
case OSystem::EVENT_LBUTTONDOWN:
|
|
_mousePressFlag = true;
|
|
break;
|
|
case OSystem::EVENT_LBUTTONUP:
|
|
_mousePressFlag = false;
|
|
break;
|
|
case OSystem::EVENT_MOUSEMOVE:
|
|
_mouseX = event.mouse.x;
|
|
_mouseY = event.mouse.y;
|
|
if (_flags.useHiResOverlay) {
|
|
_mouseX >>= 1;
|
|
_mouseY >>= 1;
|
|
}
|
|
_system->updateScreen();
|
|
lastScreenUpdate = now;
|
|
break;
|
|
case OSystem::EVENT_WHEELUP:
|
|
_mouseWheel = -1;
|
|
break;
|
|
case OSystem::EVENT_WHEELDOWN:
|
|
_mouseWheel = 1;
|
|
break;
|
|
case OSystem::EVENT_KEYDOWN:
|
|
_keyboardEvent.pending = true;
|
|
_keyboardEvent.repeat = now + 400;
|
|
_keyboardEvent.ascii = event.kbd.ascii;
|
|
break;
|
|
case OSystem::EVENT_KEYUP:
|
|
_keyboardEvent.repeat = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (now - lastScreenUpdate > 50) {
|
|
_system->updateScreen();
|
|
lastScreenUpdate = now;
|
|
}
|
|
|
|
if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {
|
|
_keyboardEvent.pending = true;
|
|
_keyboardEvent.repeat = now + 100;
|
|
}
|
|
_system->delayMillis(3);
|
|
}
|
|
|
|
int KyraEngine::gui_resumeGame(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_resumeGame()");
|
|
processMenuButton(button);
|
|
_displayMenu = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char *KyraEngine::getSavegameFilename(int num) {
|
|
static char saveLoadSlot[12];
|
|
|
|
sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num);
|
|
return saveLoadSlot;
|
|
}
|
|
|
|
int KyraEngine::getNextSavegameSlot() {
|
|
Common::InSaveFile *in;
|
|
|
|
for (int i = 1; i < 1000; i++) {
|
|
if ((in = _saveFileMan->openForLoading(getSavegameFilename(i)))) {
|
|
delete in;
|
|
} else {
|
|
return i;
|
|
}
|
|
}
|
|
warning("Didn't save: Ran out of savegame filenames");
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine::setupSavegames(Menu &menu, int num) {
|
|
Common::InSaveFile *in;
|
|
static char savenames[5][31];
|
|
uint8 startSlot;
|
|
assert(num <= 5);
|
|
|
|
if (_savegameOffset == 0) {
|
|
menu.item[0].itemString = _specialSavegameString;
|
|
menu.item[0].enabled = 1;
|
|
menu.item[0].field_1b = 0;
|
|
startSlot = 1;
|
|
} else
|
|
startSlot = 0;
|
|
|
|
for (int i = startSlot; i < num; i++) {
|
|
if ((in = _saveFileMan->openForLoading(getSavegameFilename(i + _savegameOffset)))) {
|
|
in->skip(8);
|
|
in->read(savenames[i], 31);
|
|
menu.item[i].itemString = savenames[i];
|
|
menu.item[i].enabled = 1;
|
|
menu.item[i].field_1b = i + _savegameOffset;
|
|
delete in;
|
|
} else {
|
|
menu.item[i].enabled = 0;
|
|
//menu.item[i].itemString = "";
|
|
//menu.item[i].field_1b = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
int KyraEngine::gui_saveGameMenu(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_saveGameMenu()");
|
|
processMenuButton(button);
|
|
_menu[2].item[5].enabled = true;
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
_menu[2].menuName = _guiStrings[8]; // Select a position to save to:
|
|
_specialSavegameString = _guiStrings[9]; // [ EMPTY SLOT ]
|
|
for (int i = 0; i < 5; i++)
|
|
_menu[2].item[i].callback = &KyraEngine::gui_saveGame;
|
|
|
|
_savegameOffset = 0;
|
|
setupSavegames(_menu[2], 5);
|
|
|
|
initMenu(_menu[2]);
|
|
processAllMenuButtons();
|
|
|
|
_displaySubMenu = true;
|
|
_cancelSubMenu = false;
|
|
|
|
while (_displaySubMenu && !_quitFlag) {
|
|
gui_getInput();
|
|
gui_processHighlights(_menu[2]);
|
|
processButtonList(_menuButtonList);
|
|
}
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
if (_cancelSubMenu) {
|
|
initMenu(_menu[0]);
|
|
processAllMenuButtons();
|
|
} else {
|
|
_displayMenu = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_loadGameMenu(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_loadGameMenu()");
|
|
if (_menuDirectlyToLoad)
|
|
_menu[2].item[5].enabled = false;
|
|
else {
|
|
processMenuButton(button);
|
|
_menu[2].item[5].enabled = true;
|
|
}
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
_specialSavegameString = _newGameString[0]; //[ START A NEW GAME ]
|
|
_menu[2].menuName = _guiStrings[7]; // Which game would you like to reload?
|
|
for (int i = 0; i < 5; i++)
|
|
_menu[2].item[i].callback = &KyraEngine::gui_loadGame;
|
|
|
|
_savegameOffset = 0;
|
|
setupSavegames(_menu[2], 5);
|
|
|
|
initMenu(_menu[2]);
|
|
processAllMenuButtons();
|
|
|
|
_displaySubMenu = true;
|
|
_cancelSubMenu = false;
|
|
|
|
while (_displaySubMenu && !_quitFlag) {
|
|
gui_getInput();
|
|
gui_processHighlights(_menu[2]);
|
|
processButtonList(_menuButtonList);
|
|
}
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
if (_cancelSubMenu) {
|
|
initMenu(_menu[_toplevelMenu]);
|
|
processAllMenuButtons();
|
|
} else {
|
|
gui_restorePalette();
|
|
loadGame(getSavegameFilename(_gameToLoad));
|
|
_displayMenu = false;
|
|
_menuRestoreScreen = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine::gui_redrawTextfield() {
|
|
_screen->fillRect(38, 91, 287, 102, 250);
|
|
_text->printText(_savegameName, 38, 92, 253, 0, 0);
|
|
|
|
_screen->_charWidth = -2;
|
|
int width = _screen->getTextWidth(_savegameName);
|
|
_screen->fillRect(39 + width, 93, 45 + width, 100, 254);
|
|
_screen->_charWidth = 0;
|
|
|
|
_screen->updateScreen();
|
|
}
|
|
|
|
void KyraEngine::gui_updateSavegameString() {
|
|
int length;
|
|
|
|
if (_keyboardEvent.pending && _keyboardEvent.ascii) {
|
|
length = strlen(_savegameName);
|
|
|
|
if (_keyboardEvent.ascii > 31 && _keyboardEvent.ascii < 127) {
|
|
if (length < 31) {
|
|
_savegameName[length] = _keyboardEvent.ascii;
|
|
_savegameName[length+1] = 0;
|
|
gui_redrawTextfield();
|
|
}
|
|
} else if (_keyboardEvent.ascii == 8 ||_keyboardEvent.ascii == 127) {
|
|
if (length > 0) {
|
|
_savegameName[length-1] = 0;
|
|
gui_redrawTextfield();
|
|
}
|
|
} else if (_keyboardEvent.ascii == 13) {
|
|
_displaySubMenu = false;
|
|
}
|
|
}
|
|
|
|
_keyboardEvent.pending = false;
|
|
}
|
|
|
|
int KyraEngine::gui_saveGame(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_saveGame()");
|
|
processMenuButton(button);
|
|
_gameToLoad = button->specialValue;
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
initMenu(_menu[3]);
|
|
processAllMenuButtons();
|
|
|
|
_displaySubMenu = true;
|
|
_cancelSubMenu = false;
|
|
|
|
if (_savegameOffset == 0 && _gameToLoad == 0) {
|
|
_savegameName[0] = 0;
|
|
} else {
|
|
for (int i = 0; i < 5; i++) {
|
|
if (_menu[2].item[i].field_1b == _gameToLoad) {
|
|
strncpy(_savegameName, _menu[2].item[i].itemString, 31);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
gui_redrawTextfield();
|
|
|
|
while (_displaySubMenu && !_quitFlag) {
|
|
gui_getInput();
|
|
gui_updateSavegameString();
|
|
gui_processHighlights(_menu[3]);
|
|
processButtonList(_menuButtonList);
|
|
}
|
|
|
|
if (_cancelSubMenu) {
|
|
_displaySubMenu = true;
|
|
_cancelSubMenu = false;
|
|
initMenu(_menu[2]);
|
|
processAllMenuButtons();
|
|
} else {
|
|
if (_savegameOffset == 0 && _gameToLoad == 0)
|
|
_gameToLoad = getNextSavegameSlot();
|
|
if (_gameToLoad > 0)
|
|
saveGame(getSavegameFilename(_gameToLoad), _savegameName);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_savegameConfirm(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_savegameConfirm()");
|
|
processMenuButton(button);
|
|
_displaySubMenu = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_loadGame(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_loadGame()");
|
|
processMenuButton(button);
|
|
_displaySubMenu = false;
|
|
_gameToLoad = button->specialValue;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_cancelSubMenu(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_cancelLoadGameMenu()");
|
|
processMenuButton(button);
|
|
_displaySubMenu = false;
|
|
_cancelSubMenu = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_quitPlaying(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_quitPlaying()");
|
|
processMenuButton(button);
|
|
|
|
if (gui_quitConfirm(_guiStrings[14])) // Are you sure you want to quit playing?
|
|
quitGame();
|
|
else {
|
|
initMenu(_menu[_toplevelMenu]);
|
|
processAllMenuButtons();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool KyraEngine::gui_quitConfirm(const char *str) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_quitConfirm()");
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
_menu[1].menuName = str;
|
|
calcCoords(_menu[1]);
|
|
initMenu(_menu[1]);
|
|
|
|
_displaySubMenu = true;
|
|
_cancelSubMenu = true;
|
|
|
|
while (_displaySubMenu && !_quitFlag) {
|
|
gui_getInput();
|
|
gui_processHighlights(_menu[1]);
|
|
processButtonList(_menuButtonList);
|
|
}
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
return !_cancelSubMenu;
|
|
}
|
|
|
|
int KyraEngine::gui_quitConfirmYes(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_quitConfirmYes()");
|
|
processMenuButton(button);
|
|
_displaySubMenu = false;
|
|
_cancelSubMenu = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_quitConfirmNo(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_quitConfirmNo()");
|
|
processMenuButton(button);
|
|
_displaySubMenu = false;
|
|
_cancelSubMenu = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_gameControlsMenu(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_gameControlsMenu()");
|
|
|
|
readSettings();
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
if (_flags.isTalkie) {
|
|
//_menu[5].width = 230;
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
//_menu[5].item[i].labelX = 24;
|
|
//_menu[5].item[i].x = 115;
|
|
//_menu[5].item[i].width = 94;
|
|
}
|
|
|
|
_menu[5].item[3].labelString = _voiceTextString; //"Voice / Text "
|
|
_menu[5].item[3].callback = &KyraEngine::gui_controlsChangeVoice;
|
|
|
|
} else {
|
|
//_menu[5].height = 136;
|
|
//_menu[5].item[5].y = 110;
|
|
_menu[5].item[4].enabled = 0;
|
|
_menu[5].item[3].labelString = _textSpeedString; // "Text speed "
|
|
_menu[5].item[3].callback = &KyraEngine::gui_controlsChangeText;
|
|
}
|
|
|
|
gui_setupControls(_menu[5]);
|
|
|
|
processAllMenuButtons();
|
|
|
|
_displaySubMenu = true;
|
|
_cancelSubMenu = false;
|
|
|
|
while (_displaySubMenu && !_quitFlag) {
|
|
gui_getInput();
|
|
gui_processHighlights(_menu[5]);
|
|
processButtonList(_menuButtonList);
|
|
}
|
|
|
|
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
|
|
_screen->savePageToDisk("SEENPAGE.TMP", 0);
|
|
|
|
if (_cancelSubMenu) {
|
|
initMenu(_menu[_toplevelMenu]);
|
|
processAllMenuButtons();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine::gui_setupControls(Menu &menu) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_setupControls()");
|
|
|
|
if (_configMusic)
|
|
menu.item[0].itemString = _onString; //"On"
|
|
else
|
|
menu.item[0].itemString = _offString; //"Off"
|
|
|
|
if (_configSounds)
|
|
menu.item[1].itemString = _onString; //"On"
|
|
else
|
|
menu.item[1].itemString = _offString; //"Off"
|
|
|
|
|
|
switch (_configWalkspeed) {
|
|
case 0:
|
|
menu.item[2].itemString = _configStrings[0]; //"Slowest"
|
|
break;
|
|
case 1:
|
|
menu.item[2].itemString = _configStrings[1]; //"Slow"
|
|
break;
|
|
case 2:
|
|
menu.item[2].itemString = _configStrings[2]; //"Normal"
|
|
break;
|
|
case 3:
|
|
menu.item[2].itemString = _configStrings[3]; //"Fast"
|
|
break;
|
|
case 4:
|
|
menu.item[2].itemString = _configStrings[4]; //"Fastest"
|
|
break;
|
|
default:
|
|
menu.item[2].itemString = "ERROR";
|
|
break;
|
|
}
|
|
|
|
int textControl = 3;
|
|
int clickableOffset = 8;
|
|
if (_flags.isTalkie) {
|
|
textControl = 4;
|
|
clickableOffset = 11;
|
|
|
|
if (_configVoice == 0)
|
|
_menu[5].item[4].enabled = 1;
|
|
else
|
|
_menu[5].item[4].enabled = 0;
|
|
|
|
switch (_configVoice) {
|
|
case 0:
|
|
menu.item[3].itemString = _configStrings[5]; //"Text only"
|
|
break;
|
|
case 1:
|
|
menu.item[3].itemString = _configStrings[6]; //"Voice only"
|
|
break;
|
|
case 2:
|
|
menu.item[3].itemString = _configStrings[7]; //"Voice & Text"
|
|
break;
|
|
default:
|
|
menu.item[3].itemString = "ERROR";
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (_configTextspeed) {
|
|
case 0:
|
|
menu.item[textControl].itemString = _configStrings[1]; //"Slow"
|
|
break;
|
|
case 1:
|
|
menu.item[textControl].itemString = _configStrings[2]; //"Normal"
|
|
break;
|
|
case 2:
|
|
menu.item[textControl].itemString = _configStrings[3]; //"Fast"
|
|
break;
|
|
case 3:
|
|
menu.item[textControl].itemString = _configStrings[clickableOffset]; //"Clickable"
|
|
break;
|
|
default:
|
|
menu.item[textControl].itemString = "ERROR";
|
|
break;
|
|
}
|
|
|
|
calcCoords(menu);
|
|
initMenu(menu);
|
|
}
|
|
|
|
int KyraEngine::gui_controlsChangeMusic(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsChangeMusic()");
|
|
processMenuButton(button);
|
|
|
|
_configMusic = !_configMusic;
|
|
gui_setupControls(_menu[5]);
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_controlsChangeSounds(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsChangeSounds()");
|
|
processMenuButton(button);
|
|
|
|
_configSounds = !_configSounds;
|
|
gui_setupControls(_menu[5]);
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_controlsChangeWalk(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsChangeWalk()");
|
|
processMenuButton(button);
|
|
|
|
_configWalkspeed = ++_configWalkspeed % 5;
|
|
setWalkspeed(_configWalkspeed);
|
|
gui_setupControls(_menu[5]);
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_controlsChangeText(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsChangeText()");
|
|
processMenuButton(button);
|
|
|
|
_configTextspeed = ++_configTextspeed % 4;
|
|
gui_setupControls(_menu[5]);
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_controlsChangeVoice(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsChangeVoice()");
|
|
processMenuButton(button);
|
|
|
|
_configVoice = ++_configVoice % 3;
|
|
gui_setupControls(_menu[5]);
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_controlsApply(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsApply()");
|
|
writeSettings();
|
|
return gui_cancelSubMenu(button);
|
|
}
|
|
|
|
int KyraEngine::gui_scrollUp(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_scrollUp()");
|
|
processMenuButton(button);
|
|
|
|
if (_savegameOffset > 0) {
|
|
_savegameOffset--;
|
|
setupSavegames(_menu[2], 5);
|
|
initMenu(_menu[2]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KyraEngine::gui_scrollDown(Button *button) {
|
|
debugC(9, kDebugLevelGUI, "KyraEngine::gui_scrollDown()");
|
|
processMenuButton(button);
|
|
|
|
_savegameOffset++;
|
|
setupSavegames(_menu[2], 5);
|
|
initMenu(_menu[2]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine::gui_processHighlights(Menu &menu) {
|
|
int x1, y1, x2, y2;
|
|
|
|
for (int i = 0; i < menu.nrOfItems; i++) {
|
|
if (!menu.item[i].enabled)
|
|
continue;
|
|
|
|
x1 = menu.x + menu.item[i].x;
|
|
y1 = menu.y + menu.item[i].y;
|
|
|
|
x2 = x1 + menu.item[i].width;
|
|
y2 = y1 + menu.item[i].height;
|
|
|
|
if (_mouseX > x1 && _mouseX < x2 &&
|
|
_mouseY > y1 && _mouseY < y2) {
|
|
|
|
if (menu.highlightedItem != i) {
|
|
if (menu.item[menu.highlightedItem].enabled )
|
|
gui_redrawText(menu);
|
|
|
|
menu.highlightedItem = i;
|
|
gui_redrawHighlight(menu);
|
|
_screen->updateScreen();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KyraEngine::gui_redrawText(Menu menu) {
|
|
int textX;
|
|
int i = menu.highlightedItem;
|
|
|
|
int x1 = menu.x + menu.item[i].x;
|
|
int y1 = menu.y + menu.item[i].y;
|
|
|
|
int x2 = x1 + menu.item[i].width - 1;
|
|
|
|
if (menu.item[i].field_12 != -1 &&_flags.lang == Common::EN_ANY)
|
|
textX = x1 + menu.item[i].field_12 + 3;
|
|
else
|
|
textX = _text->getCenterStringX(menu.item[i].itemString, x1, x2);
|
|
|
|
int textY = y1 + 2;
|
|
_text->printText(menu.item[i].itemString, textX - 1, textY + 1, 12, 0, 0);
|
|
_text->printText(menu.item[i].itemString, textX, textY, menu.item[i].textColor, 0, 0);
|
|
}
|
|
|
|
void KyraEngine::gui_redrawHighlight(Menu menu) {
|
|
int textX;
|
|
int i = menu.highlightedItem;
|
|
|
|
int x1 = menu.x + menu.item[i].x;
|
|
int y1 = menu.y + menu.item[i].y;
|
|
|
|
int x2 = x1 + menu.item[i].width - 1;
|
|
|
|
if (menu.item[i].field_12 != -1 &&_flags.lang == Common::EN_ANY)
|
|
textX = x1 + menu.item[i].field_12 + 3;
|
|
else
|
|
textX = _text->getCenterStringX(menu.item[i].itemString, x1, x2);
|
|
|
|
int textY = y1 + 2;
|
|
_text->printText(menu.item[i].itemString, textX - 1, textY + 1, 12, 0, 0);
|
|
_text->printText(menu.item[i].itemString, textX, textY, menu.item[i].highlightColor, 0, 0);
|
|
}
|
|
|
|
void KyraEngine::gui_fadePalette() {
|
|
static int16 menuPalIndexes[] = {248, 249, 250, 251, 252, 253, 254, -1};
|
|
int index = 0;
|
|
|
|
memcpy(_screen->getPalette(2), _screen->_currentPalette, 768);
|
|
|
|
for (int i = 0; i < 768; i++) {
|
|
_screen->_currentPalette[i] /= 2;
|
|
}
|
|
|
|
while (menuPalIndexes[index] != -1) {
|
|
memcpy(&_screen->_currentPalette[menuPalIndexes[index]*3], &_screen->getPalette(2)[menuPalIndexes[index]*3], 3);
|
|
index++;
|
|
}
|
|
|
|
_screen->fadePalette(_screen->_currentPalette, 2);
|
|
}
|
|
|
|
void KyraEngine::gui_restorePalette() {
|
|
memcpy(_screen->_currentPalette, _screen->getPalette(2), 768);
|
|
_screen->fadePalette(_screen->_currentPalette, 2);
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
// Kyra 2 and 3 main menu
|
|
|
|
void KyraEngine::gui_updateMainMenuAnimation() {
|
|
_screen->updateScreen();
|
|
}
|
|
|
|
bool KyraEngine::gui_mainMenuGetInput() {
|
|
OSystem::Event event;
|
|
|
|
while (_system->pollEvent(event)) {
|
|
switch (event.type) {
|
|
case OSystem::EVENT_QUIT:
|
|
quitGame();
|
|
break;
|
|
case OSystem::EVENT_MOUSEMOVE:
|
|
_mouseX = event.mouse.x;
|
|
_mouseY = event.mouse.y;
|
|
if (_flags.useHiResOverlay) {
|
|
_mouseX >>= 1;
|
|
_mouseY >>= 1;
|
|
}
|
|
break;
|
|
case OSystem::EVENT_LBUTTONUP:
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int KyraEngine::gui_handleMainMenu() {
|
|
debugC(9, kDebugLevelMain, "KyraEngine::gui_handleMainMenu()");
|
|
int command = -1;
|
|
|
|
uint8 colorMap[16];
|
|
memset(colorMap, 0, sizeof(colorMap));
|
|
_screen->setTextColorMap(colorMap);
|
|
|
|
const char * const *strings = &_mainMenuStrings[_lang << 2];
|
|
Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT);
|
|
int charWidthBackUp = _screen->_charWidth;
|
|
|
|
_screen->_charWidth = -2;
|
|
_screen->setScreenDim(3);
|
|
int backUpX = _screen->_curDim->sx;
|
|
int backUpY = _screen->_curDim->sy;
|
|
int backUpWidth = _screen->_curDim->w;
|
|
int backUpHeight = _screen->_curDim->h;
|
|
_screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3);
|
|
|
|
int x = _screen->_curDim->sx << 3;
|
|
int y = _screen->_curDim->sy;
|
|
int width = _screen->_curDim->w << 3;
|
|
int height = _screen->_curDim->h;
|
|
|
|
gui_drawMainBox(x, y, width, height, 1);
|
|
gui_drawMainBox(x + 1, y + 1, width - 2, height - 2, 0);
|
|
|
|
int selected = 0;
|
|
|
|
gui_drawMainMenu(strings, selected);
|
|
|
|
_screen->showMouse();
|
|
|
|
int fh = _screen->getFontHeight();
|
|
int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
|
|
|
|
Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4);
|
|
|
|
while (!_quitFlag) {
|
|
gui_updateMainMenuAnimation();
|
|
bool mousePressed = gui_mainMenuGetInput();
|
|
|
|
if (menuRect.contains(mouseX(), mouseY())) {
|
|
int item = (mouseY() - menuRect.top) / fh;
|
|
|
|
if (item != selected) {
|
|
gui_printString(strings[selected], textPos, menuRect.top + selected * fh, 0x80, 0, 5);
|
|
gui_printString(strings[item], textPos, menuRect.top + item * fh, 0xFF, 0, 5);
|
|
|
|
selected = item;
|
|
}
|
|
|
|
if (mousePressed) {
|
|
// TODO: Flash the text
|
|
command = item;
|
|
break;
|
|
}
|
|
}
|
|
_system->delayMillis(10);
|
|
}
|
|
|
|
if (_quitFlag)
|
|
command = -1;
|
|
|
|
_screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0);
|
|
_screen->_charWidth = charWidthBackUp;
|
|
_screen->setFont(oldFont);
|
|
|
|
return command;
|
|
}
|
|
|
|
void KyraEngine::gui_drawMainMenu(const char * const *strings, int select) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine::gui_drawMainMenu(%p)", (const void*)strings);
|
|
static const uint16 menuTable[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 };
|
|
|
|
int top = _screen->_curDim->sy;
|
|
top += menuTable[1];
|
|
|
|
for (int i = 0; i < menuTable[3]; ++i) {
|
|
int curY = top + i * _screen->getFontHeight();
|
|
int color = (i == select) ? menuTable[6] : menuTable[5];
|
|
gui_printString(strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5);
|
|
}
|
|
}
|
|
|
|
void KyraEngine::gui_drawMainBox(int x, int y, int w, int h, int fill) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine::gui_drawMainBox(%d, %d, %d, %d, %d)", x, y, w, h, fill);
|
|
static const uint8 kyra3ColorTable[] = { 0x16, 0x19, 0x1A, 0x16 };
|
|
static const uint8 kyra2ColorTable[] = { 0x0, 0x19, 0x28, 0xc8 };
|
|
|
|
const uint8 *colorTable;
|
|
if (_flags.gameID == GI_KYRA3)
|
|
colorTable = kyra3ColorTable;
|
|
else
|
|
colorTable = kyra2ColorTable;
|
|
|
|
--w; --h;
|
|
|
|
if (fill) {
|
|
_screen->fillRect(x, y, x+w, y+h, colorTable[0]);
|
|
}
|
|
|
|
_screen->drawClippedLine(x, y+h, x+w, y+h, colorTable[1]);
|
|
_screen->drawClippedLine(x+w, y, x+w, y+h, colorTable[1]);
|
|
_screen->drawClippedLine(x, y, x+w, y, colorTable[2]);
|
|
_screen->drawClippedLine(x, y, x, y+h, colorTable[2]);
|
|
|
|
_screen->setPagePixel(_screen->_curPage, x, y+h, colorTable[3]);
|
|
_screen->setPagePixel(_screen->_curPage, x+w, y, colorTable[3]);
|
|
}
|
|
|
|
void KyraEngine::gui_printString(const char *format, int x, int y, int col1, int col2, int flags, ...) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine::gui_printString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags);
|
|
if (!format)
|
|
return;
|
|
|
|
char string[512];
|
|
va_list vaList;
|
|
va_start(vaList, flags);
|
|
vsprintf(string, format, vaList);
|
|
va_end(vaList);
|
|
|
|
if (flags & 1) {
|
|
x -= _screen->getTextWidth(string) >> 1;
|
|
}
|
|
|
|
if (flags & 2) {
|
|
x -= _screen->getTextWidth(string);
|
|
}
|
|
|
|
if (flags & 4) {
|
|
_screen->printText(string, x - 1, y, 240, col2);
|
|
_screen->printText(string, x, y + 1, 240, col2);
|
|
}
|
|
|
|
if (flags & 8) {
|
|
_screen->printText(string, x - 1, y, 227, col2);
|
|
_screen->printText(string, x, y + 1, 227, col2);
|
|
}
|
|
|
|
_screen->printText(string, x, y, col1, col2);
|
|
}
|
|
|
|
} // end of namespace Kyra
|
|
|