diff options
Diffstat (limited to 'engines/scumm/dialogs.cpp')
-rw-r--r-- | engines/scumm/dialogs.cpp | 986 |
1 files changed, 986 insertions, 0 deletions
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp new file mode 100644 index 0000000000..eafd956251 --- /dev/null +++ b/engines/scumm/dialogs.cpp @@ -0,0 +1,986 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-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 "common/stdafx.h" + +#include "common/config-manager.h" +#include "common/savefile.h" +#include "common/system.h" +#include "common/scaler.h" + +#include "gui/about.h" +#include "gui/chooser.h" +#include "gui/newgui.h" +#include "gui/ListWidget.h" + +#include "scumm/dialogs.h" +#include "scumm/sound.h" +#include "scumm/scumm.h" +#include "scumm/imuse.h" +#include "scumm/imuse_digi/dimuse.h" +#include "scumm/player_v2.h" +#include "scumm/verbs.h" +#include "sound/mididrv.h" +#include "sound/mixer.h" + +#ifndef DISABLE_HELP +#include "scumm/help.h" +#endif + +#ifdef SMALL_SCREEN_DEVICE +#include "KeysDialog.h" +#endif + +using GUI::CommandSender; +using GUI::StaticTextWidget; +using GUI::kButtonWidth; +using GUI::kButtonHeight; +using GUI::kBigButtonWidth; +using GUI::kBigButtonHeight; +using GUI::kCloseCmd; +using GUI::kTextAlignCenter; +using GUI::kTextAlignLeft; +using GUI::WIDGET_ENABLED; + +typedef GUI::OptionsDialog GUI_OptionsDialog; +typedef GUI::ChooserDialog GUI_ChooserDialog; +typedef GUI::Dialog GUI_Dialog; + +namespace Scumm { + +struct ResString { + int num; + char string[80]; +}; + +#ifdef PALMOS_68K +static ResString *string_map_table_v7; +static ResString *string_map_table_v6; +static ResString *string_map_table_v5; +#else +static ResString string_map_table_v7[] = { + {96, "game name and version"}, //that's how it's supposed to be + {77, "Select a game to LOAD"}, + {76, "Name your SAVE game"}, + {70, "save"}, //boot8 + {71, "load"}, //boot9 + {72, "play"}, //boot10 + {73, "cancel"}, //boot11 + {74, "quit"}, //boot12 + {75, "ok"}, //boot13 + {85, "game paused"}, // boot3 + {96, "the dig v1.0"}, + + /* this is the almost complete string map for v7 + {63, "how may I serve you?"}, + {64, "the dig v1.0"}, //(game name/version) + {67, "text display only"}, + {68, "c:\\dig"}, //boot007 (save path ?) + {69, "the dig"}, //boot21 (game name) + {70, "save"}, //boot8 + {71, "load"}, //boot9 + {72, "play"}, //boot10 + {73, "cancel"}, //boot11 + {74, "quit"}, //boot12 + {75, "ok"}, //boot13 + {76, "name your save game"}, //boot19 + {77, "select a game to load"}, //boot20 + {78, "you must enter a name"},//boot14 + {79, "saving '%s'"}, //boot17 + {80, "loading '%s'"}, //boot18 + {81, "the game was NOT saved"}, //boot15 + {82, "the game was NOT loaded"}, //boot16 + {83, "how may I serve you?"}, + {84, "how may I serve you?"}, + {85, "game paused"}, // boot3 + {86, "Are you sure you want to restart"}, + {87, "Are you sure you want to quit?"}, //boot05 + {89, "how may I serve you?"}, + {90, "music"}, //boot22 + {91, "voice"}, //boot23 + {92, "sfx"}, //boot24 + {93, "disabled"}, //boot25 + {94, "text speed"}, //boot26 + {95, "text display"}, //boot27 + {96, "the dig v1.0"},*/ + +}; + +static ResString string_map_table_v6[] = { + {117, "How may I serve you?"}, + {109, "Select a game to LOAD"}, + {108, "Name your SAVE game"}, + {96, "Save"}, + {97, "Load"}, + {98, "Play"}, + {99, "Cancel"}, + {100, "Quit"}, + {101, "OK"}, + {93, "Game paused"}, + {210, "Game version"} +}; + +static ResString string_map_table_v5[] = { + {28, "How may I serve you?"}, + {20, "Select a game to LOAD"}, + {19, "Name your SAVE game"}, + {7, "Save"}, + {8, "Load"}, + {9, "Play"}, + {10, "Cancel"}, + {11, "Quit"}, + {12, "OK"}, + {4, "Game paused"} +}; +#endif + +#pragma mark - + +ScummDialog::ScummDialog(ScummEngine *scumm, int x, int y, int w, int h) + : GUI::Dialog(x, y, w, h), _vm(scumm) { +_drawingHints |= GUI::THEME_HINT_SPECIAL_COLOR; +} + +const Common::String ScummDialog::queryResString(int stringno) { + byte buf[256]; + byte *result; + + if (stringno == 0) + return String(); + + if (_vm->_version >= 7) + result = _vm->getStringAddressVar(string_map_table_v7[stringno - 1].num); + else if (_vm->_version == 6) + result = _vm->getStringAddressVar(string_map_table_v6[stringno - 1].num); + else if (_vm->_version == 5) + result = _vm->getStringAddress(string_map_table_v5[stringno - 1].num); + else + // TODO: For V8 games, maybe grab the strings from the language file? + return string_map_table_v5[stringno - 1].string; + + if (result && *result == '/') { + _vm->translateText(result, buf); + result = buf; + } + + if (!result || *result == '\0') { // Gracelessly degrade to english :) + return string_map_table_v5[stringno - 1].string; + } + + // Convert to a proper string (take care of FF codes) + byte chr; + String tmp; + while ((chr = *result++)) { + if (chr == 0xFF) { + result += 3; + } else if (chr != '@') { + tmp += chr; + } + } + return tmp; +} + +#pragma mark - + +Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode); + +enum { + kSaveCmd = 'SAVE', + kLoadCmd = 'LOAD', + kPlayCmd = 'PLAY', + kOptionsCmd = 'OPTN', + kHelpCmd = 'HELP', + kAboutCmd = 'ABOU', + kQuitCmd = 'QUIT' +}; + +class SaveLoadChooser : public GUI::ChooserDialog, public BaseSaveLoadChooser { + typedef Common::String String; + typedef Common::StringList StringList; +protected: + bool _saveMode; + +public: + SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode); + + virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + const String &getResultString() const; + void setList(const StringList& list) { GUI_ChooserDialog::setList(list); } + int runModal() { return GUI_ChooserDialog::runModal(); } +}; + +SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode) + : GUI::ChooserDialog(title, buttonLabel, 182), _saveMode(saveMode) { + + _list->setEditable(saveMode); + _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero); +} + +const Common::String &SaveLoadChooser::getResultString() const { + return _list->getSelectedString(); +} + +void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + int selItem = _list->getSelected(); + switch (cmd) { + case GUI::kListItemActivatedCmd: + case GUI::kListItemDoubleClickedCmd: + if (selItem >= 0) { + if (_saveMode || !getResultString().isEmpty()) { + setResult(selItem); + close(); + } + } + break; + case GUI::kListSelectionChangedCmd: + if (_saveMode) { + _list->startEditMode(); + } + // Disable button if nothing is selected, or (in load mode) if an empty + // list item is selected. We allow choosing an empty item in save mode + // because we then just assign a default name. + _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty())); + _chooseButton->draw(); + break; + default: + GUI_ChooserDialog::handleCommand(sender, cmd, data); + } +} + +#pragma mark - + +enum { + kChooseCmd = 'Chos' +}; + +// only for use with >= 640x400 resolutions +class SaveLoadChooserEx : public GUI::Dialog, public BaseSaveLoadChooser { + typedef Common::String String; + typedef Common::StringList StringList; +protected: + bool _saveMode; + GUI::ListWidget *_list; + GUI::ButtonWidget *_chooseButton; + GUI::GraphicsWidget *_gfxWidget; + GUI::StaticTextWidget *_date; + GUI::StaticTextWidget *_time; + GUI::StaticTextWidget *_playtime; + ScummEngine *_scumm; + +public: + SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine); + + virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + const String &getResultString() const; + void setList(const StringList& list); + int runModal(); +}; + +SaveLoadChooserEx::SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine) + : Dialog(8, 8, engine->_system->getOverlayWidth() - 2 * 8, engine->_system->getOverlayHeight() - 16), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0), _scumm(engine) { + + new StaticTextWidget(this, 10, 6, _w - 2 * 10, kLineHeight, title, kTextAlignCenter); + + // Add choice list + _list = new GUI::ListWidget(this, 10, 18, _w - 2 * 10 - 180, _h - 14 - kBigButtonHeight - 18, GUI::kBigWidgetSize); + _list->setEditable(saveMode); + _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero); + + // Add the thumbnail display + _gfxWidget = new GUI::GraphicsWidget(this, + _w - (kThumbnailWidth + 22), + 18, + kThumbnailWidth + 8, + ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8); + _gfxWidget->setFlags(GUI::WIDGET_BORDER); + + int height = 18 + ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8; + + _date = new StaticTextWidget(this, + _w - (kThumbnailWidth + 22), + height, + kThumbnailWidth + 8, + kLineHeight, + "No date saved", + kTextAlignCenter); + _date->setFlags(GUI::WIDGET_CLEARBG); + + height += kLineHeight; + + _time = new StaticTextWidget(this, + _w - (kThumbnailWidth + 22), + height, + kThumbnailWidth + 8, + kLineHeight, + "No time saved", + kTextAlignCenter); + _time->setFlags(GUI::WIDGET_CLEARBG); + + height += kLineHeight; + + _playtime = new StaticTextWidget(this, + _w - (kThumbnailWidth + 22), + height, + kThumbnailWidth + 8, + kLineHeight, + "No playtime saved", + kTextAlignCenter); + _playtime->setFlags(GUI::WIDGET_CLEARBG); + + // Buttons + addButton(this, _w - 2 * (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, "Cancel", kCloseCmd, 0, GUI::kBigWidgetSize); + _chooseButton = addButton(this, _w - (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, buttonLabel, kChooseCmd, 0, GUI::kBigWidgetSize); + _chooseButton->setEnabled(false); +} + +const Common::String &SaveLoadChooserEx::getResultString() const { + return _list->getSelectedString(); +} + +void SaveLoadChooserEx::setList(const StringList& list) { + _list->setList(list); +} + +int SaveLoadChooserEx::runModal() { + _gfxWidget->setGfx(0); + int ret = Dialog::runModal(); + return ret; +} + +void SaveLoadChooserEx::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + int selItem = _list->getSelected(); + switch (cmd) { + case GUI::kListItemActivatedCmd: + case GUI::kListItemDoubleClickedCmd: + if (selItem >= 0) { + if (_saveMode || !getResultString().isEmpty()) { + _list->endEditMode(); + setResult(selItem); + close(); + } + } + break; + case kChooseCmd: + _list->endEditMode(); + setResult(selItem); + close(); + break; + case GUI::kListSelectionChangedCmd: { + Graphics::Surface *thumb; + thumb = _scumm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem); + _gfxWidget->setGfx(thumb); + if (thumb) + thumb->free(); + delete thumb; + _gfxWidget->draw(); + + InfoStuff infos; + memset(&infos, 0, sizeof(InfoStuff)); + char buffer[32]; + if (_scumm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) { + snprintf(buffer, 32, "Date: %.2d.%.2d.%.4d", + (infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF, + infos.date & 0xFFFF); + _date->setLabel(buffer); + _date->draw(); + + snprintf(buffer, 32, "Time: %.2d:%.2d", + (infos.time >> 8) & 0xFF, infos.time & 0xFF); + _time->setLabel(buffer); + _time->draw(); + + int minutes = infos.playtime / 60; + int hours = minutes / 60; + minutes %= 60; + + snprintf(buffer, 32, "Playtime: %.2d:%.2d", + hours & 0xFF, minutes & 0xFF); + _playtime->setLabel(buffer); + _playtime->draw(); + } else { + snprintf(buffer, 32, "No date saved"); + _date->setLabel(buffer); + _date->draw(); + + snprintf(buffer, 32, "No time saved"); + _time->setLabel(buffer); + _time->draw(); + + snprintf(buffer, 32, "No playtime saved"); + _playtime->setLabel(buffer); + _playtime->draw(); + } + + if (_saveMode) { + _list->startEditMode(); + } + // Disable button if nothing is selected, or (in load mode) if an empty + // list item is selected. We allow choosing an empty item in save mode + // because we then just assign a default name. + _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty())); + _chooseButton->draw(); + } break; + case kCloseCmd: + setResult(-1); + default: + Dialog::handleCommand(sender, cmd, data); + } +} + +#pragma mark - + +Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) { + // Get savegame names + Common::StringList l; + char name[32]; + uint i = saveMode ? 1 : 0; + bool avail_saves[81]; + + scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves)); + for (; i < ARRAYSIZE(avail_saves); i++) { + if (avail_saves[i]) + scumm->getSavegameName(i, name); + else + name[0] = 0; + l.push_back(name); + } + + return l; +} + +#define addBigButton(label, cmd, hotkey) \ + new GUI::ButtonWidget(this, hOffset, y, buttonWidth, buttonHeight, label, cmd, hotkey, ws); \ + y += (buttonHeight + vAddOff) + +MainMenuDialog::MainMenuDialog(ScummEngine *scumm) + : ScummDialog(scumm, 0, 0, 0, 0) { + + const int screenW = g_system->getOverlayWidth(); + const int screenH = g_system->getOverlayHeight(); + + int hOffset; + int vSpace; + int vAddOff; + + GUI::WidgetSize ws; + int buttonWidth; + int buttonHeight; + + if (screenW >= 400 && screenH >= 300) { + buttonWidth = 160; + buttonHeight = 28; + ws = GUI::kBigWidgetSize; + hOffset = 12; + vSpace = 7; + vAddOff = 3; + } else { + buttonWidth = 90; + buttonHeight = 16; + ws = GUI::kNormalWidgetSize; + hOffset = 8; + vSpace = 5; + vAddOff = 2; + } + + int y = vSpace + vAddOff; + + + addBigButton("Resume", kPlayCmd, 'P'); + y += vSpace; + + addBigButton("Load", kLoadCmd, 'L'); + addBigButton("Save", kSaveCmd, 'S'); + y += vSpace; + + addBigButton("Options", kOptionsCmd, 'O'); +#ifndef DISABLE_HELP + addBigButton("Help", kHelpCmd, 'H'); +#endif + addBigButton("About", kAboutCmd, 'A'); + y += vSpace; + + addBigButton("Quit", kQuitCmd, 'Q'); + + + _w = buttonWidth + 2 * hOffset; + _h = y + vSpace; + + _x = (screenW - _w) / 2; + _y = (screenH - _h) / 2; + + + // + // Create the sub dialog(s) + // + _aboutDialog = new GUI::AboutDialog(); + _optionsDialog = new ConfigDialog(scumm); +#ifndef DISABLE_HELP + _helpDialog = new HelpDialog(scumm); +#endif + if (scumm->_system->getOverlayWidth() <= 320) { + _saveDialog = new SaveLoadChooser("Save game:", "Save", true); + _loadDialog = new SaveLoadChooser("Load game:", "Load", false); + } else { + _saveDialog = new SaveLoadChooserEx("Save game:", "Save", true, scumm); + _loadDialog = new SaveLoadChooserEx("Load game:", "Load", false, scumm); + } +} + +MainMenuDialog::~MainMenuDialog() { + delete _aboutDialog; + delete _optionsDialog; +#ifndef DISABLE_HELP + delete _helpDialog; +#endif + delete _saveDialog; + delete _loadDialog; +} + +void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + switch (cmd) { + case kSaveCmd: + save(); + break; + case kLoadCmd: + load(); + break; + case kPlayCmd: + close(); + break; + case kOptionsCmd: + _optionsDialog->runModal(); + break; + case kAboutCmd: + _aboutDialog->runModal(); + break; +#ifndef DISABLE_HELP + case kHelpCmd: + _helpDialog->runModal(); + break; +#endif + case kQuitCmd: + _vm->_quit = true; + close(); + break; + default: + ScummDialog::handleCommand(sender, cmd, data); + } +} + +void MainMenuDialog::save() { + int idx; + _saveDialog->setList(generateSavegameList(_vm, true)); + idx = _saveDialog->runModal(); + if (idx >= 0) { + const String &result = _saveDialog->getResultString(); + char buffer[20]; + const char *str; + if (result.isEmpty()) { + // If the user was lazy and entered no save name, come up with a default name. + sprintf(buffer, "Save %d", idx + 1); + str = buffer; + } else + str = result.c_str(); + _vm->requestSave(idx + 1, str); + close(); + } +} + +void MainMenuDialog::load() { + int idx; + _loadDialog->setList(generateSavegameList(_vm, false)); + idx = _loadDialog->runModal(); + if (idx >= 0) { + _vm->requestLoad(idx); + close(); + } +} + +#pragma mark - + +enum { + kOKCmd = 'ok ' +}; + +enum { + kKeysCmd = 'KEYS' +}; + +ConfigDialog::ConfigDialog(ScummEngine *scumm) + : GUI::OptionsDialog("", 40, 30, 240, 124), _vm(scumm) { + + const int screenW = g_system->getOverlayWidth(); + const int screenH = g_system->getOverlayHeight(); + + _w = screenW - 2 * 40; + + GUI::WidgetSize ws; + int buttonWidth; + int buttonHeight; + + if (screenW >= 400 && screenH >= 300) { + ws = GUI::kBigWidgetSize; + buttonWidth = kBigButtonWidth; + buttonHeight = kBigButtonHeight; + } else { + ws = GUI::kNormalWidgetSize; + buttonWidth = kButtonWidth; + buttonHeight = kButtonHeight; + } + + int yoffset = 8; + + // + // Sound controllers + // + + yoffset = addVolumeControls(this, yoffset, ws) + 4; + + // + // Some misc options + // + + _subtitlesCheckbox = addCheckbox(this, 15, yoffset, "Show subtitles", 0, 'S', ws); + yoffset += _subtitlesCheckbox->getHeight(); + + _speechCheckbox = addCheckbox(this, 15, yoffset, "Enable speech", 0, 'E', ws); + yoffset += _speechCheckbox->getHeight() + 4; + + // + // Add the buttons + // + + _w = 8 + 3 * (buttonWidth + 4); // FIXME/TODO + + addButton(this, _w - (buttonWidth + 4) - 4, yoffset, "OK", GUI::OptionsDialog::kOKCmd, 'O', ws); + addButton(this, _w - 2 * (buttonWidth + 4) - 4, yoffset, "Cancel", kCloseCmd, 'C', ws); +#ifdef SMALL_SCREEN_DEVICE + addButton(this, _w - 3 * (buttonWidth + 4) - 4, yoffset, "Keys", kKeysCmd, 'K', ws); +#endif + + yoffset += buttonHeight; + + _h = yoffset + 8; + + _x = (screenW - _w) / 2; + _y = (screenH - _h) / 2; + +#ifdef SMALL_SCREEN_DEVICE + // + // Create the sub dialog(s) + // + + _keysDialog = new GUI::KeysDialog(); +#endif +} + +ConfigDialog::~ConfigDialog() { +#ifdef SMALL_SCREEN_DEVICE + delete _keysDialog; +#endif +} + +void ConfigDialog::open() { + GUI_OptionsDialog::open(); + + // update checkboxes, too + _subtitlesCheckbox->setState(ConfMan.getBool("subtitles")); + _speechCheckbox->setState(!ConfMan.getBool("speech_mute")); +} + +void ConfigDialog::close() { + if (getResult()) { + // Subtitles + ConfMan.set("subtitles", _subtitlesCheckbox->getState(), _domain); + ConfMan.set("speech_mute", !_speechCheckbox->getState(), _domain); + // Sync with current setting + if (ConfMan.getBool("speech_mute")) + _vm->_voiceMode = 2; + else + _vm->_voiceMode = ConfMan.getBool("subtitles"); + + if (_vm->_version >= 7) + _vm->VAR(_vm->VAR_VOICE_MODE) = _vm->_voiceMode; + } + + GUI_OptionsDialog::close(); + + _vm->setupVolumes(); +} + +void ConfigDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + switch (cmd) { + case kKeysCmd: +#ifdef SMALL_SCREEN_DEVICE + _keysDialog->runModal(); +#endif + break; + default: + GUI_OptionsDialog::handleCommand (sender, cmd, data); + } +} + +#ifndef DISABLE_HELP + +#pragma mark - + +enum { + kNextCmd = 'NEXT', + kPrevCmd = 'PREV' +}; + +HelpDialog::HelpDialog(ScummEngine *scumm) + : ScummDialog(scumm, 5, 5, 310, 190) { + _drawingHints &= ~GUI::THEME_HINT_SPECIAL_COLOR; + + const int screenW = g_system->getOverlayWidth(); + const int screenH = g_system->getOverlayHeight(); + + GUI::WidgetSize ws; + int buttonHeight; + int buttonWidth; + + if (screenW >= 400 && screenH >= 300) { + ws = GUI::kBigWidgetSize; + buttonHeight = kBigButtonHeight; + buttonWidth = kBigButtonWidth; + _w = 370; + _x = (screenW - _w) / 2; + } else { + ws = GUI::kNormalWidgetSize; + buttonHeight = kButtonHeight; + buttonWidth = kButtonWidth; + _x = 5; + _w = screenW - 2 * 5; + } + + int lineHeight = g_gui.getFontHeight(); + + _h = 5 + (2 + HELP_NUM_LINES) * lineHeight + buttonHeight + 7; + _y = (screenH - _h) / 2; + + _title = new StaticTextWidget(this, 10, 5, _w, lineHeight, "", kTextAlignCenter, ws); + + for (int i = 0; i < HELP_NUM_LINES; i++) { + _key[i] = new StaticTextWidget(this, 10, 5 + lineHeight * (i + 2), 80, lineHeight, "", kTextAlignLeft, ws); + _dsc[i] = new StaticTextWidget(this, 90, 5 + lineHeight * (i + 2), _w - 10 - 90, lineHeight, "", kTextAlignLeft, ws); + } + + _page = 1; + _numPages = ScummHelp::numPages(scumm->_gameId); + + int y = 5 + lineHeight * (HELP_NUM_LINES + 2) + 2; + + _prevButton = addButton(this, 10, y, "Previous", kPrevCmd, 'P', ws); + _nextButton = addButton(this, 10 + buttonWidth + 8, y, "Next", kNextCmd, 'N', ws); + addButton(this, _w - 8 - buttonWidth, y, "Close", kCloseCmd, 'C', ws); + _prevButton->clearFlags(WIDGET_ENABLED); + + displayKeyBindings(); +} + +void HelpDialog::displayKeyBindings() { + + String titleStr, *keyStr, *dscStr; + + ScummHelp::updateStrings(_vm->_gameId, _vm->_version, _vm->_platform, _page, titleStr, keyStr, dscStr); + + _title->setLabel(titleStr); + for (int i = 0; i < HELP_NUM_LINES; i++) { + _key[i]->setLabel(keyStr[i]); + _dsc[i]->setLabel(dscStr[i]); + } + + delete [] keyStr; + delete [] dscStr; +} + +void HelpDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + + switch (cmd) { + case kNextCmd: + _page++; + if (_page >= _numPages) { + _nextButton->clearFlags(WIDGET_ENABLED); + } + if (_page >= 2) { + _prevButton->setFlags(WIDGET_ENABLED); + } + displayKeyBindings(); + draw(); + break; + case kPrevCmd: + _page--; + if (_page <= _numPages) { + _nextButton->setFlags(WIDGET_ENABLED); + } + if (_page <= 1) { + _prevButton->clearFlags(WIDGET_ENABLED); + } + displayKeyBindings(); + draw(); + break; + default: + ScummDialog::handleCommand(sender, cmd, data); + } +} + +#endif + +#pragma mark - + +InfoDialog::InfoDialog(ScummEngine *scumm, int res) +: ScummDialog(scumm, 0, 80, 0, 16) { // dummy x and w + setInfoText(queryResString (res)); +} + +InfoDialog::InfoDialog(ScummEngine *scumm, const String& message) +: ScummDialog(scumm, 0, 80, 0, 16) { // dummy x and w + setInfoText(message); +} + +void InfoDialog::setInfoText(const String& message) { + const int screenW = g_system->getOverlayWidth(); + const int screenH = g_system->getOverlayHeight(); + GUI::WidgetSize ws; + + if (screenW >= 400 && screenH >= 300) { + ws = GUI::kBigWidgetSize; + } else { + ws = GUI::kNormalWidgetSize; + } + + int width = g_gui.getStringWidth(message) + 16; + int height = g_gui.getFontHeight() + 8; + + _w = width; + _h = height; + _x = (screenW - width) / 2; + _y = (screenH - height) / 2; + + new StaticTextWidget(this, 4, 4, _w - 8, _h, message, kTextAlignCenter, ws); +} + +#pragma mark - + +PauseDialog::PauseDialog(ScummEngine *scumm, int res) + : InfoDialog(scumm, res) { +} + +void PauseDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { + if (ascii == ' ') // Close pause dialog if space key is pressed + close(); + else + ScummDialog::handleKeyDown(ascii, keycode, modifiers); +} + +ConfirmDialog::ConfirmDialog(ScummEngine *scumm, const String& message) + : InfoDialog(scumm, message) { +} + +void ConfirmDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { + if (tolower(ascii) == 'n') { + setResult(0); + close(); + } else if (tolower(ascii) == 'y') { + setResult(1); + close(); + } else + ScummDialog::handleKeyDown(ascii, keycode, modifiers); +} + +#pragma mark - + +ValueDisplayDialog::ValueDisplayDialog(const Common::String& label, int minVal, int maxVal, int val, uint16 incKey, uint16 decKey) + : GUI::Dialog(0, 80, 0, 16), _label(label), _min(minVal), _max(maxVal), _value(val), _incKey(incKey), _decKey(decKey) { + assert(_min <= _value && _value <= _max); + + const int screenW = g_system->getOverlayWidth(); + const int screenH = g_system->getOverlayHeight(); + + if (screenW >= 400 && screenH >= 300) { + _percentBarWidth = kBigPercentBarWidth; + } else { + _percentBarWidth = kPercentBarWidth; + } + + int width = g_gui.getStringWidth(label) + 16 + _percentBarWidth; + int height = g_gui.getFontHeight() + 4 * 2; + + _x = (screenW - width) / 2; + _y = (screenH - height) / 2; + _w = width; + _h = height; +} + +void ValueDisplayDialog::drawDialog() { + const int labelWidth = _w - 8 - _percentBarWidth; + g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), GUI::THEME_HINT_SAVE_BACKGROUND | GUI::THEME_HINT_FIRST_DRAW); + g_gui.theme()->drawText(Common::Rect(_x+4, _y+4, _x+labelWidth+4, _y+g_gui.theme()->getFontHeight()+4), _label); + g_gui.theme()->drawSlider(Common::Rect(_x+4+labelWidth, _y+4, _x+_w-4, _y+_h-4), _percentBarWidth * (_value - _min) / (_max - _min)); +} + +void ValueDisplayDialog::handleTickle() { + if (getMillis() > _timer) + close(); +} + +void ValueDisplayDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { + if (ascii == _incKey || ascii == _decKey) { + if (ascii == _incKey && _value < _max) + _value++; + else if (ascii == _decKey && _value > _min) + _value--; + + setResult(_value); + _timer = getMillis() + kDisplayDelay; + draw(); + } else { + close(); + } +} + +void ValueDisplayDialog::open() { + GUI_Dialog::open(); + setResult(_value); + _timer = getMillis() + kDisplayDelay; +} + + + +} // End of namespace Scumm + +#ifdef PALMOS_68K +#include "scumm_globals.h" + +_GINIT(Dialogs) +_GSETPTR(Scumm::string_map_table_v7, GBVARS_STRINGMAPTABLEV7_INDEX, Scumm::ResString, GBVARS_SCUMM) +_GSETPTR(Scumm::string_map_table_v6, GBVARS_STRINGMAPTABLEV6_INDEX, Scumm::ResString, GBVARS_SCUMM) +_GSETPTR(Scumm::string_map_table_v5, GBVARS_STRINGMAPTABLEV5_INDEX, Scumm::ResString, GBVARS_SCUMM) +_GEND + +_GRELEASE(Dialogs) +_GRELEASEPTR(GBVARS_STRINGMAPTABLEV7_INDEX, GBVARS_SCUMM) +_GRELEASEPTR(GBVARS_STRINGMAPTABLEV6_INDEX, GBVARS_SCUMM) +_GRELEASEPTR(GBVARS_STRINGMAPTABLEV5_INDEX, GBVARS_SCUMM) +_GEND + +#endif |