/* ScummVM - Scumm Interpreter * Copyright (C) 2002-2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Header$ */ #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 - 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)); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); idx = _saveDialog->runModal(); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); 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) { 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, _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() { g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor); g_gui.box(_x, _y, _w, _h, g_gui._color, g_gui._shadowcolor); const int labelWidth = _w - 8 - _percentBarWidth; // Draw the label g_gui.drawString(_label, _x + 4, _y + 4, labelWidth, g_gui._textcolor); // Draw the percentage bar g_gui.fillRect(_x + 4 + labelWidth, _y + 4, _percentBarWidth * (_value - _min) / (_max - _min), _h - 8, g_gui._textcolorhi); g_gui.frameRect(_x + 4 + labelWidth, _y + 4, _percentBarWidth, _h - 8, g_gui._textcolor); // Flag the draw area as dirty g_gui.addDirtyRect(_x, _y, _w, _h); } 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