diff options
Diffstat (limited to 'gui')
-rw-r--r-- | gui/ThemeEngine.cpp | 10 | ||||
-rw-r--r-- | gui/about.cpp | 2 | ||||
-rw-r--r-- | gui/browser.cpp | 13 | ||||
-rw-r--r-- | gui/browser.h | 10 | ||||
-rw-r--r-- | gui/credits.h | 4 | ||||
-rw-r--r-- | gui/launcher.cpp | 354 | ||||
-rw-r--r-- | gui/launcher.h | 10 | ||||
-rw-r--r-- | gui/massadd.cpp | 10 | ||||
-rw-r--r-- | gui/massadd.h | 4 | ||||
-rw-r--r-- | gui/newgui.cpp | 10 | ||||
-rw-r--r-- | gui/options.cpp | 10 | ||||
-rw-r--r-- | gui/theme.cpp | 82 | ||||
-rw-r--r-- | gui/theme.h | 7 | ||||
-rw-r--r-- | gui/themebrowser.cpp | 38 | ||||
-rw-r--r-- | gui/themebrowser.h | 2 | ||||
-rw-r--r-- | gui/themes/default.inc | 14 | ||||
-rw-r--r-- | gui/themes/scummclassic.zip | bin | 40156 -> 42002 bytes | |||
-rw-r--r-- | gui/themes/scummclassic/classic_layout.stx | 7 | ||||
-rw-r--r-- | gui/themes/scummclassic/classic_layout_320.stx | 7 | ||||
-rw-r--r-- | gui/themes/scummodern.zip | bin | 123105 -> 125107 bytes | |||
-rw-r--r-- | gui/themes/scummodern/scummodern_layout.stx | 7 | ||||
-rw-r--r-- | gui/themes/scummodern/scummodern_layout_320.stx | 7 | ||||
-rw-r--r-- | gui/widget.cpp | 3 |
23 files changed, 479 insertions, 132 deletions
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index e75c2e295e..c04ca52834 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -525,7 +525,7 @@ bool ThemeEngine::loadThemeXML(Common::String themeName) { _themeName.clear(); char fileNameBuffer[32]; - char stxHeader[128]; + Common::String stxHeader; int parseCount = 0; #ifdef USE_ZLIB @@ -546,9 +546,9 @@ bool ThemeEngine::loadThemeXML(Common::String themeName) { Common::MemoryReadStream *stream = new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true); if (!strcmp(fileNameBuffer, "THEMERC")) { - stream->readLine(stxHeader, 128); + stxHeader = stream->readLine(); - if (!themeConfigParseHeader(stxHeader, _themeName)) { + if (!themeConfigParseHeader(stxHeader.c_str(), _themeName)) { warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str()); return false; } @@ -591,9 +591,9 @@ bool ThemeEngine::loadThemeXML(Common::String themeName) { } else if (i->getName() == "THEMERC") { Common::File f; f.open(*i); - f.readLine(stxHeader, 128); + stxHeader = f.readLine(); - if (!themeConfigParseHeader(stxHeader, _themeName)) { + if (!themeConfigParseHeader(stxHeader.c_str(), _themeName)) { warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str()); return false; } diff --git a/gui/about.cpp b/gui/about.cpp index eeb2533e0d..1c1e3a3355 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -58,7 +58,7 @@ enum { static const char *copyright_text[] = { "\\C""", -"\\C""Copyright (C) 2002-2007 The ScummVM project", +"\\C""Copyright (C) 2001-2008 The ScummVM project", "\\C""http://www.scummvm.org", "\\C""", "\\C""ScummVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the COPYRIGHT file distributed with this binary.", diff --git a/gui/browser.cpp b/gui/browser.cpp index a5c71e6987..69f5dcd134 100644 --- a/gui/browser.cpp +++ b/gui/browser.cpp @@ -107,7 +107,7 @@ int BrowserDialog::runModal() { err = FSRefMakePath(&ref, (UInt8*)buf, sizeof(buf)-1); assert(err == noErr); - _choice = FilesystemNode(buf); + _choice = Common::FilesystemNode(buf); choiceMade = true; } @@ -160,9 +160,9 @@ BrowserDialog::BrowserDialog(const char *title, bool dirBrowser) void BrowserDialog::open() { if (ConfMan.hasKey("browser_lastpath")) - _node = FilesystemNode(ConfMan.get("browser_lastpath")); + _node = Common::FilesystemNode(ConfMan.get("browser_lastpath")); if (!_node.isDirectory()) - _node = FilesystemNode("."); + _node = Common::FilesystemNode("."); // Alway refresh file list updateListing(); @@ -227,8 +227,9 @@ void BrowserDialog::updateListing() { ConfMan.set("browser_lastpath", _node.getPath()); // Read in the data from the file system - FilesystemNode::ListMode listMode = _isDirBrowser ? FilesystemNode::kListDirectoriesOnly - : FilesystemNode::kListAll; + Common::FilesystemNode::ListMode listMode = + _isDirBrowser ? Common::FilesystemNode::kListDirectoriesOnly + : Common::FilesystemNode::kListAll; if (!_node.getChildren(_nodeContent, listMode)) { _nodeContent.clear(); } else { @@ -237,7 +238,7 @@ void BrowserDialog::updateListing() { // Populate the ListWidget Common::StringList list; - for (FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) { + for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) { if (!_isDirBrowser && i->isDirectory()) list.push_back(i->getDisplayName() + "/"); else diff --git a/gui/browser.h b/gui/browser.h index d330e32269..c8bdec26a2 100644 --- a/gui/browser.h +++ b/gui/browser.h @@ -39,8 +39,6 @@ class ListWidget; class StaticTextWidget; class BrowserDialog : public Dialog { - typedef Common::String String; - typedef Common::StringList StringList; public: BrowserDialog(const char *title, bool dirBrowser); @@ -52,7 +50,7 @@ public: virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); #endif - const FilesystemNode &getResult() { return _choice; } + const Common::FilesystemNode &getResult() { return _choice; } protected: #ifdef MACOSX @@ -60,10 +58,10 @@ protected: #else ListWidget *_fileList; StaticTextWidget *_currentPath; - FilesystemNode _node; - FSList _nodeContent; + Common::FilesystemNode _node; + Common::FSList _nodeContent; #endif - FilesystemNode _choice; + Common::FilesystemNode _choice; bool _isDirBrowser; #ifndef MACOSX diff --git a/gui/credits.h b/gui/credits.h index ca2fda811d..b8d2e345c8 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -175,11 +175,13 @@ static const char *credits[] = { "\\C\\c0""", "\\C\\c1""Miscellaneous", "\\C\\c0""David Corrales-Lopez", -"\\C\\c2""Filesystem access improvements", +"\\C\\c2""Filesystem access improvements (GSoC 2007 task)", "\\C\\c0""Jerome Fisher", "\\C\\c2""MT-32 emulator", "\\C\\c0""Jochen Hoenicke", "\\C\\c2""Speaker & PCjr sound support, Adlib work", +"\\C\\c0""Chris Page", +"\\C\\c2""Return to launcher, savestate improvements, leak fixes, ... (GSoC 2008 task)", "\\C\\c0""Robin Watts", "\\C\\c2""ARM assembly routines for nice speedups on several ports; improvements to the sound mixer", "\\C\\c0""", diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 9ecdbfb6d4..b79891ef76 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -29,6 +29,7 @@ #include "common/events.h" #include "common/fs.h" #include "common/util.h" +#include "common/savefile.h" #include "common/system.h" #include "gui/about.h" @@ -44,6 +45,7 @@ #include "gui/TabWidget.h" #include "gui/PopUpWidget.h" #include "graphics/cursorman.h" +#include "graphics/scaler.h" #include "sound/mididrv.h" @@ -61,7 +63,10 @@ enum { kAddGameCmd = 'ADDG', kEditGameCmd = 'EDTG', kRemoveGameCmd = 'REMG', + kLoadGameCmd = 'LOAD', kQuitCmd = 'QUIT', + kChooseCmd = 'CHOS', + kDelCmd = 'DEL ', kCmdGlobalGraphicsOverride = 'OGFX', @@ -390,7 +395,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat if (browser.runModal() > 0) { // User made this choice... - FilesystemNode file(browser.getResult()); + Common::FilesystemNode file(browser.getResult()); _soundFont->setLabel(file.getPath()); if (!file.getPath().empty() && (file.getPath() != "None")) @@ -408,7 +413,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat BrowserDialog browser("Select directory with game data", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); // TODO: Verify the game can be found in the new directory... Best // done with optional specific gameid to pluginmgr detectgames? @@ -426,7 +431,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat BrowserDialog browser("Select additional game directory", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); _extraPathWidget->setLabel(dir.getPath()); draw(); } @@ -438,7 +443,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat BrowserDialog browser("Select directory for saved games", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); _savePathWidget->setLabel(dir.getPath()); draw(); } @@ -468,6 +473,296 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat } } +class SaveLoadChooser : public GUI::Dialog { + typedef Common::String String; + typedef Common::StringList StringList; +protected: + GUI::ListWidget *_list; + GUI::ButtonWidget *_chooseButton; + GUI::ButtonWidget *_deleteButton; + GUI::GraphicsWidget *_gfxWidget; + GUI::ContainerWidget *_container; + GUI::StaticTextWidget *_date; + GUI::StaticTextWidget *_time; + GUI::StaticTextWidget *_playtime; + + const EnginePlugin *_plugin; + bool _delSupport; + bool _metaInfoSupport; + bool _thumbnailSupport; + bool _saveDateSupport; + bool _playTimeSupport; + String _target; + SaveStateList _saveList; + + uint8 _fillR, _fillG, _fillB; + + void updateSaveList(); + void updateSelection(bool redraw); +public: + SaveLoadChooser(const String &title, const String &buttonLabel); + ~SaveLoadChooser(); + + virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); + void setList(const StringList& list); + int runModal(const EnginePlugin *plugin, const String &target); + + virtual void reflowLayout(); + + virtual void close(); +}; + +SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel) + : Dialog("ScummSaveLoad"), _delSupport(0), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { + _delSupport = _metaInfoSupport = _thumbnailSupport = _saveDateSupport = _playTimeSupport = false; + +// _drawingHints |= GUI::THEME_HINT_SPECIAL_COLOR; + + new StaticTextWidget(this, "ScummSaveLoad.Title", title); + + // Add choice list + _list = new GUI::ListWidget(this, "ScummSaveLoad.List"); + _list->setNumberingMode(GUI::kListNumberingOff); + + _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); +// _container->setHints(GUI::THEME_HINT_USE_SHADOW); + + _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); + + _date = new StaticTextWidget(this, 0, 0, 10, 10, "No date saved", kTextAlignCenter); + _time = new StaticTextWidget(this, 0, 0, 10, 10, "No time saved", kTextAlignCenter); + _playtime = new StaticTextWidget(this, 0, 0, 10, 10, "No playtime saved", kTextAlignCenter); + + // Buttons + new GUI::ButtonWidget(this, "ScummSaveLoad.Cancel", "Cancel", kCloseCmd, 0); + _chooseButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Choose", buttonLabel, kChooseCmd, 0); + _chooseButton->setEnabled(false); + + _deleteButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Delete", "Delete", kDelCmd, 0); + _deleteButton->setEnabled(false); + + _delSupport = _metaInfoSupport = _thumbnailSupport = false; +} + +SaveLoadChooser::~SaveLoadChooser() { +} + +int SaveLoadChooser::runModal(const EnginePlugin *plugin, const String &target) { + if (_gfxWidget) + _gfxWidget->setGfx(0); + + _plugin = plugin; + _target = target; + _delSupport = (*_plugin)->hasFeature(MetaEngine::kSupportsDeleteSave); + _metaInfoSupport = (*_plugin)->hasFeature(MetaEngine::kSupportsMetaInfos); + _thumbnailSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSupportsThumbnails); + _saveDateSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSupportsSaveDate); + _playTimeSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSupportsSavePlayTime); + reflowLayout(); + updateSaveList(); + + int ret = Dialog::runModal(); + return ret; +} + +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 (!_list->getSelectedString().empty()) { + _list->endEditMode(); + setResult(atoi(_saveList[selItem].save_slot().c_str())); + close(); + } + } + break; + case kChooseCmd: + setResult(atoi(_saveList[selItem].save_slot().c_str())); + close(); + break; + case GUI::kListSelectionChangedCmd: { + updateSelection(true); + } break; + case kDelCmd: + if (selItem >= 0 && _delSupport) { + MessageDialog alert("Do you really want to delete this savegame?", + "Delete", "Cancel"); + if (alert.runModal() == GUI::kMessageOK) { + (*_plugin)->removeSaveState(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str())); + + setResult(-1); + _list->setSelected(-1); + + updateSaveList(); + updateSelection(true); + } + } + break; + case kCloseCmd: + setResult(-1); + default: + Dialog::handleCommand(sender, cmd, data); + } +} + +void SaveLoadChooser::reflowLayout() { + if (g_gui.xmlEval()->getVar("Globals.ScummSaveLoad.ExtInfo.Visible") == 1 && _thumbnailSupport) { + int16 x, y; + uint16 w, h; + + if (!g_gui.xmlEval()->getWidgetData("ScummSaveLoad.Thumbnail", x, y, w, h)) + error("Error when loading position data for Save/Load Thumbnails."); + + int thumbW = kThumbnailWidth; + int thumbH = ((g_system->getHeight() % 200 && g_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1); + int thumbX = x + (w >> 1) - (thumbW >> 1); + int thumbY = y + kLineHeight; + + int textLines = 0; + if (_saveDateSupport) + textLines += 2; + if (_playTimeSupport) + textLines += 1; + + if (textLines) + ++textLines; + + _container->resize(x, y, w, h + textLines * kLineHeight); + _gfxWidget->resize(thumbX, thumbY, thumbW, thumbH); + + int height = thumbY + thumbH + kLineHeight; + + if (_saveDateSupport) { + _date->resize(thumbX, height, kThumbnailWidth, kLineHeight); + height += kLineHeight; + _time->resize(thumbX, height, kThumbnailWidth, kLineHeight); + height += kLineHeight; + } + + if (_playTimeSupport) + _playtime->resize(thumbX, height, kThumbnailWidth, kLineHeight); + + _container->clearFlags(GUI::WIDGET_INVISIBLE); + _gfxWidget->clearFlags(GUI::WIDGET_INVISIBLE); + + if (_saveDateSupport) { + _date->clearFlags(GUI::WIDGET_INVISIBLE); + _time->clearFlags(GUI::WIDGET_INVISIBLE); + } else { + _date->setFlags(GUI::WIDGET_INVISIBLE); + _time->setFlags(GUI::WIDGET_INVISIBLE); + } + + if (_playTimeSupport) + _playtime->clearFlags(GUI::WIDGET_INVISIBLE); + else + _playtime->setFlags(GUI::WIDGET_INVISIBLE); + + _fillR = 0; + _fillG = 0; + _fillB = 0; + updateSelection(false); + } else { + _container->setFlags(GUI::WIDGET_INVISIBLE); + _gfxWidget->setFlags(GUI::WIDGET_INVISIBLE); + _date->setFlags(GUI::WIDGET_INVISIBLE); + _time->setFlags(GUI::WIDGET_INVISIBLE); + _playtime->setFlags(GUI::WIDGET_INVISIBLE); + } + + Dialog::reflowLayout(); +} + +void SaveLoadChooser::updateSelection(bool redraw) { + int selItem = _list->getSelected(); + + bool isDeletable = _delSupport; + + if (selItem >= 0 && !_list->getSelectedString().empty() && _metaInfoSupport) { + SaveStateDescriptor desc = (*_plugin)->querySaveMetaInfos(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str())); + + isDeletable = desc.getBool("is_deletable") && _delSupport; + + if (_thumbnailSupport) { + const Graphics::Surface *thumb = desc.getThumbnail(); + if (thumb) { + _gfxWidget->setGfx(thumb); + _gfxWidget->useAlpha(256); + } else { + _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB); + } + } + + if (_saveDateSupport) { + Common::String date = "Date: "; + if (desc.contains("save_date")) + date += desc.getVal("save_date"); + else + date = "No date saved"; + + Common::String time = "Time: "; + if (desc.contains("save_time")) + time += desc.getVal("save_time"); + else + time = "No time saved"; + + _date->setLabel(date); + _time->setLabel(time); + } + + if (_playTimeSupport) { + Common::String time = "Playtime: "; + if (desc.contains("play_time")) + time += desc.getVal("play_time"); + else + time = "No playtime saved"; + + _playtime->setLabel(time); + } + } + + + // Disable these buttons if nothing is selected, or if an empty + // list item is selected. + _chooseButton->setEnabled(selItem >= 0 && (!_list->getSelectedString().empty())); + // Delete will always be disabled if the engine doesn't support it. + _deleteButton->setEnabled(isDeletable && (selItem >= 0) && (!_list->getSelectedString().empty())); + + if (redraw) { + _gfxWidget->draw(); + _date->draw(); + _time->draw(); + _playtime->draw(); + _chooseButton->draw(); + _deleteButton->draw(); + } +} + +void SaveLoadChooser::close() { + _plugin = 0; + _target.clear(); + _saveList.clear(); + _list->setList(StringList()); + + Dialog::close(); +} + +void SaveLoadChooser::updateSaveList() { + _saveList = (*_plugin)->listSaves(_target.c_str()); + + StringList saveNames; + for (SaveStateList::const_iterator x = _saveList.begin(); x != _saveList.end(); ++x) { + Common::String description = x->save_slot(); + description += ". "; + description += x->description(); + + saveNames.push_back(description); + } + _list->setList(saveNames); +} #pragma mark - @@ -502,6 +797,9 @@ LauncherDialog::LauncherDialog() _startButton = new ButtonWidget(this, "Launcher.StartButton", "Start", kStartCmd, 'S'); + _loadButton = + new ButtonWidget(this, "Launcher.LoadGameButton", "Load", kLoadGameCmd, 'L'); + // Above the lowest button rows: two more buttons (directly below the list box) _addButton = new ButtonWidget(this, "Launcher.AddGameButton", "Add Game...", kAddGameCmd, 'A'); @@ -529,6 +827,9 @@ LauncherDialog::LauncherDialog() // Create file browser dialog _browser = new BrowserDialog("Select directory with game data", true); + + // Create Load dialog + _loadDialog = new SaveLoadChooser("Load game:", "Load"); } void LauncherDialog::selectGame(const String &name) { @@ -546,6 +847,7 @@ void LauncherDialog::selectGame(const String &name) { LauncherDialog::~LauncherDialog() { delete _browser; + delete _loadDialog; } void LauncherDialog::open() { @@ -654,9 +956,9 @@ void LauncherDialog::addGame() { if (_browser->runModal() > 0) { // User made his choice... - FilesystemNode dir(_browser->getResult()); - FSList files; - if (!dir.getChildren(files, FilesystemNode::kListAll)) { + Common::FilesystemNode dir(_browser->getResult()); + Common::FSList files; + if (!dir.getChildren(files, Common::FilesystemNode::kListAll)) { error("browser returned a node that is not a directory: '%s'", dir.getPath().c_str()); } @@ -795,6 +1097,37 @@ void LauncherDialog::editGame(int item) { } } +void LauncherDialog::loadGame(int item) { + String gameId = ConfMan.get("gameid", _domains[item]); + if (gameId.empty()) + gameId = _domains[item]; + + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + + String target = _domains[item]; + target.toLowercase(); + + if (plugin) { + if ((*plugin)->hasFeature(MetaEngine::kSupportsListSaves) && + (*plugin)->hasFeature(MetaEngine::kSupportsDirectLoad)) { + int slot = _loadDialog->runModal(plugin, target); + if (slot >= 0) { + ConfMan.setActiveDomain(_domains[item]); + ConfMan.setInt("save_slot", slot, Common::ConfigManager::kTransientDomain); + close(); + } + } else { + MessageDialog dialog + ("This game does not support loading games from the launcher.", "OK"); + dialog.runModal(); + } + } else { + MessageDialog dialog("ScummVM could not find any engine capable of running the selected game!", "OK"); + dialog.runModal(); + } +} + void LauncherDialog::handleKeyDown(Common::KeyState state) { Dialog::handleKeyDown(state); updateButtons(); @@ -818,6 +1151,9 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat case kEditGameCmd: editGame(item); break; + case kLoadGameCmd: + loadGame(item); + break; case kOptionsCmd: { GlobalOptionsDialog options; options.runModal(); @@ -866,6 +1202,10 @@ void LauncherDialog::updateButtons() { _removeButton->setEnabled(enable); _removeButton->draw(); } + if (enable != _loadButton->isEnabled()) { + _loadButton->setEnabled(enable); + _loadButton->draw(); + } // Update the label of the "Add" button depending on whether shift is pressed or not int modifiers = g_system->getEventManager()->getModifierState(); diff --git a/gui/launcher.h b/gui/launcher.h index a9d09bf109..1b2b0a354e 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -26,7 +26,7 @@ #define LAUNCHER_DIALOG_H #include "gui/dialog.h" -#include "base/game.h" +#include "engines/game.h" #include "common/str.h" namespace GUI { @@ -34,11 +34,10 @@ namespace GUI { class BrowserDialog; class ListWidget; class GraphicsWidget; - +class SaveLoadChooser; Common::String addGameToConf(const GameDescriptor &result); - class LauncherDialog : public Dialog { typedef Common::String String; typedef Common::StringList StringList; @@ -55,6 +54,7 @@ protected: ListWidget *_list; ButtonWidget *_addButton; Widget *_startButton; + Widget *_loadButton; Widget *_editButton; Widget *_removeButton; #ifndef DISABLE_FANCY_THEMES @@ -62,6 +62,7 @@ protected: #endif StringList _domains; BrowserDialog *_browser; + SaveLoadChooser *_loadDialog; virtual void reflowLayout(); @@ -73,7 +74,8 @@ protected: virtual void addGame(); void removeGame(int item); void editGame(int item); - + void loadGame(int item); + void selectGame(const String &name); }; diff --git a/gui/massadd.cpp b/gui/massadd.cpp index 6842466ad9..c34c190776 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -58,7 +58,7 @@ enum { -MassAddDialog::MassAddDialog(const FilesystemNode &startDir) +MassAddDialog::MassAddDialog(const Common::FilesystemNode &startDir) : Dialog("massadddialog"), _dirsScanned(0), _okButton(0), @@ -156,10 +156,10 @@ void MassAddDialog::handleTickle() { // Perform a breadth-first scan of the filesystem. while (!_scanStack.empty() && (g_system->getMillis() - t) < kMaxScanTime) { - FilesystemNode dir = _scanStack.pop(); + Common::FilesystemNode dir = _scanStack.pop(); - FSList files; - if (!dir.getChildren(files, FilesystemNode::kListAll)) { + Common::FSList files; + if (!dir.getChildren(files, Common::FilesystemNode::kListAll)) { error("browser returned a node that is not a directory: '%s'", dir.getPath().c_str()); } @@ -206,7 +206,7 @@ void MassAddDialog::handleTickle() { // Recurse into all subdirs - for (FSList::const_iterator file = files.begin(); file != files.end(); ++file) { + for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) { if (file->isDirectory()) { _scanStack.push(*file); } diff --git a/gui/massadd.h b/gui/massadd.h index e0eff75c64..733559cf37 100644 --- a/gui/massadd.h +++ b/gui/massadd.h @@ -38,14 +38,14 @@ class StaticTextWidget; class MassAddDialog : public Dialog { public: - MassAddDialog(const FilesystemNode &startDir); + MassAddDialog(const Common::FilesystemNode &startDir); //void open(); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); void handleTickle(); private: - Common::Stack<FilesystemNode> _scanStack; + Common::Stack<Common::FilesystemNode> _scanStack; GameList _games; /** diff --git a/gui/newgui.cpp b/gui/newgui.cpp index 72b7f2612c..1fa0038ff2 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -25,6 +25,7 @@ #include "common/events.h" #include "common/system.h" #include "common/util.h" +#include "engines/engine.h" #include "graphics/cursorman.h" #include "gui/newgui.h" #include "gui/dialog.h" @@ -67,9 +68,9 @@ void GuiObject::reflowLayout() { error("Widget <%s> has x + w > %d (%d)", _name.c_str(), g_system->getOverlayWidth(), _x + _w); if (_y < 0) error("Widget <%s> has y < 0", _name.c_str()); - if (_y >= g_system->getOverlayWidth()) + if (_y >= g_system->getOverlayHeight()) error("Widget <%s> has y > %d", _name.c_str(), g_system->getOverlayHeight()); - if (_y + _h > g_system->getOverlayWidth()) + if (_y + _h > g_system->getOverlayHeight()) error("Widget <%s> has y + h > %d (%d)", _name.c_str(), g_system->getOverlayHeight(), _y + _h); } } @@ -221,7 +222,7 @@ void NewGui::runLoop() { Common::Event event; while (eventMan->pollEvent(event)) { - if (activeDialog != getTopDialog() && event.type != Common::EVENT_QUIT && event.type != Common::EVENT_SCREEN_CHANGED) + if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED) continue; Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); @@ -286,7 +287,8 @@ void NewGui::runLoop() { activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); break; case Common::EVENT_QUIT: - _system->quit(); + if (!g_engine) + _system->quit(); return; case Common::EVENT_SCREEN_CHANGED: screenChange(); diff --git a/gui/options.cpp b/gui/options.cpp index 110f7c9b69..ea80283f97 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -858,7 +858,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 BrowserDialog browser("Select directory for savegames", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); if (dir.isWritable()) { _savePath->setLabel(dir.getPath()); } else { @@ -874,7 +874,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 BrowserDialog browser("Select directory for GUI themes", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); _themePath->setLabel(dir.getPath()); draw(); } @@ -884,7 +884,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 BrowserDialog browser("Select directory for extra files", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); _extraPath->setLabel(dir.getPath()); draw(); } @@ -895,7 +895,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 BrowserDialog browser("Select directory for plugins", true); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode dir(browser.getResult()); + Common::FilesystemNode dir(browser.getResult()); _pluginsPath->setLabel(dir.getPath()); draw(); } @@ -906,7 +906,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 BrowserDialog browser("Select SoundFont", false); if (browser.runModal() > 0) { // User made his choice... - FilesystemNode file(browser.getResult()); + Common::FilesystemNode file(browser.getResult()); _soundFont->setLabel(file.getPath()); if (!file.getPath().empty() && (file.getPath() != "None")) diff --git a/gui/theme.cpp b/gui/theme.cpp index 3a6280ab95..df9ae34017 100644 --- a/gui/theme.cpp +++ b/gui/theme.cpp @@ -23,7 +23,8 @@ */ #include "gui/theme.h" -#include "common/fs.h" +#include "common/file.h" +#include "common/archive.h" #include "common/unzip.h" namespace GUI { @@ -44,24 +45,11 @@ const Graphics::Font *Theme::loadFont(const char *filename) { return font; #ifdef USE_ZLIB - unzFile zipFile = unzOpen((getThemeFileName()).c_str()); - if (zipFile && unzLocateFile(zipFile, cacheFilename.c_str(), 2) == UNZ_OK) { - unz_file_info fileInfo; - unzOpenCurrentFile(zipFile); - unzGetCurrentFileInfo(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); - uint8 *buffer = new uint8[fileInfo.uncompressed_size+1]; - assert(buffer); - memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8)); - unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size); - unzCloseCurrentFile(zipFile); - Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size+1); - - font = Graphics::NewFont::loadFromCache(stream); - - delete[] buffer; - buffer = 0; + ZipArchive zipArchive(getThemeFileName().c_str()); + if (zipArchive.hasFile(cacheFilename)) { + Common::FilePtr stream(zipArchive.openFile(cacheFilename)); + font = Graphics::NewFont::loadFromCache(*stream.get()); } - unzClose(zipFile); #endif if (font) return font; @@ -74,24 +62,11 @@ const Graphics::Font *Theme::loadFont(const char *filename) { #ifdef USE_ZLIB if (!font) { - unzFile zipFile = unzOpen((getThemeFileName()).c_str()); - if (zipFile && unzLocateFile(zipFile, filename, 2) == UNZ_OK) { - unz_file_info fileInfo; - unzOpenCurrentFile(zipFile); - unzGetCurrentFileInfo(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); - uint8 *buffer = new uint8[fileInfo.uncompressed_size+1]; - assert(buffer); - memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8)); - unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size); - unzCloseCurrentFile(zipFile); - Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size+1); - - font = Graphics::NewFont::loadFont(stream); - - delete[] buffer; - buffer = 0; + ZipArchive zipArchive(getThemeFileName().c_str()); + if (zipArchive.hasFile(filename)) { + Common::FilePtr stream(zipArchive.openFile(filename)); + font = Graphics::NewFont::loadFont(*stream.get()); } - unzClose(zipFile); } #endif @@ -154,8 +129,8 @@ bool Theme::themeConfigParseHeader(Common::String header, Common::String &themeN return tok.empty(); } -bool Theme::themeConfigUseable(const FilesystemNode &node, Common::String &themeName) { - char stxHeader[128]; +bool Theme::themeConfigUseable(const Common::FilesystemNode &node, Common::String &themeName) { + Common::String stxHeader; bool foundHeader = false; if (ConfMan.hasKey("themepath")) @@ -170,40 +145,27 @@ bool Theme::themeConfigUseable(const FilesystemNode &node, Common::String &theme if (node.getName().hasSuffix(".zip")) { #ifdef USE_ZLIB - unzFile zipFile = unzOpen(node.getPath().c_str()); - - if (zipFile && unzLocateFile(zipFile, "THEMERC", 2) == UNZ_OK) { - unz_file_info fileInfo; - unzOpenCurrentFile(zipFile); - unzGetCurrentFileInfo(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); - uint8 *buffer = new uint8[fileInfo.uncompressed_size+1]; - assert(buffer); - memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8)); - unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size); - unzCloseCurrentFile(zipFile); - Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size+1); - stream.readLine(stxHeader, 128); - - if (themeConfigParseHeader(stxHeader, themeName)) + ZipArchive zipArchive(node.getPath().c_str()); + if (zipArchive.hasFile("THEMERC")) { + Common::FilePtr stream(zipArchive.openFile("THEMERC")); + stxHeader = stream->readLine(); + // TODO: Read first line of file. How? + if (themeConfigParseHeader(stxHeader.c_str(), themeName)) foundHeader = true; - - delete[] buffer; - buffer = 0; } - unzClose(zipFile); #else return false; #endif } else if (node.isDirectory()) { - FilesystemNode headerfile = node.getChild("THEMERC"); + Common::FilesystemNode headerfile = node.getChild("THEMERC"); if (!headerfile.exists() || !headerfile.isReadable() || headerfile.isDirectory()) return false; + // TODO: File or FilePtr? Common::File f; f.open(headerfile); - f.readLine(stxHeader, 128); - - if (themeConfigParseHeader(stxHeader, themeName)) + stxHeader = f.readLine(); + if (themeConfigParseHeader(stxHeader.c_str(), themeName)) foundHeader = true; } diff --git a/gui/theme.h b/gui/theme.h index 57744db584..302029247b 100644 --- a/gui/theme.h +++ b/gui/theme.h @@ -28,7 +28,7 @@ #include "common/system.h" #include "common/rect.h" #include "common/str.h" -#include "common/file.h" +#include "common/fs.h" #include "common/config-file.h" #include "graphics/surface.h" @@ -305,7 +305,7 @@ public: bool isThemeLoadingRequired(); virtual ThemeEval *evaluator() = 0; - static bool themeConfigUseable(const FilesystemNode &node, Common::String &themeName); + static bool themeConfigUseable(const Common::FilesystemNode &node, Common::String &themeName); static bool themeConfigParseHeader(Common::String header, Common::String &themeName); virtual const Common::String &getThemeFileName() const = 0; @@ -321,7 +321,8 @@ public: //! Special image ids for images used in the GUI enum kThemeImages { - kImageLogo = 0 //! ScummVM Logo used in the launcher + kImageLogo = 0, //! ScummVM Logo used in the launcher + kImageLogoSmall //! ScummVM logo used in the GMM }; /** diff --git a/gui/themebrowser.cpp b/gui/themebrowser.cpp index f764b05f6a..c935f04143 100644 --- a/gui/themebrowser.cpp +++ b/gui/themebrowser.cpp @@ -140,33 +140,31 @@ void ThemeBrowser::addDir(ThList &list, const Common::String &dir, int level) { if (level < 0) return; - FilesystemNode node(dir); + Common::FilesystemNode node(dir); if (!node.exists() || !node.isReadable()) return; - FSList fslist; - -#ifdef USE_ZLIB - if (node.lookupFile(fslist, "*.zip", false, true, 0)) { - for (FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) { - Entry th; - if (isTheme(*i, th)) { - bool add = true; - - for (ThList::const_iterator p = list.begin(); p != list.end(); ++p) { - if (p->name == th.name || p->file == th.file) { - add = false; - break; - } - } + Common::FSList fslist; + if (!node.getChildren(fslist, Common::FilesystemNode::kListAll)) + return; - if (add) - list.push_back(th); + for (Common::FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) { + Entry th; + if (isTheme(*i, th)) { + bool add = true; + + for (ThList::const_iterator p = list.begin(); p != list.end(); ++p) { + if (p->name == th.name || p->file == th.file) { + add = false; + break; + } } + + if (add) + list.push_back(th); } } -#endif if (node.lookupFile(fslist, "THEMERC", false, true, 1)) { for (FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) { @@ -188,7 +186,7 @@ void ThemeBrowser::addDir(ThList &list, const Common::String &dir, int level) { } } -bool ThemeBrowser::isTheme(const FilesystemNode &node, Entry &out) { +bool ThemeBrowser::isTheme(const Common::FilesystemNode &node, Entry &out) { out.file = node.getPath(); #ifdef USE_ZLIB diff --git a/gui/themebrowser.h b/gui/themebrowser.h index 7a3bc2ca7d..c3a46aa3b0 100644 --- a/gui/themebrowser.h +++ b/gui/themebrowser.h @@ -57,7 +57,7 @@ private: void updateListing(); void addDir(ThList &list, const Common::String &dir, int level = 4); - bool isTheme(const FilesystemNode &node, Entry &out); + bool isTheme(const Common::FilesystemNode &node, Entry &out); }; } // end of namespace GUI diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 71e655f5bc..c0ea4a9228 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -364,6 +364,9 @@ "/> " "<widget name = 'GameList'/> " "<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'> " +"<widget name = 'LoadGameButton' " +"height = '20' " +"/> " "<widget name = 'AddGameButton' " "height = '20' " "/> " @@ -811,6 +814,10 @@ "</layout> " "<layout type = 'horizontal' padding = '0, 0, 0, 0'> " "<space/> " +"<widget name = 'Delete' " +"type = 'Button' " +"/> " +"<space size = '32'/> " "<widget name = 'Cancel' " "type = 'Button' " "/> " @@ -901,6 +908,9 @@ "/> " "<widget name = 'GameList'/> " "<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'> " +"<widget name = 'LoadGameButton' " +"height = '12' " +"/> " "<widget name = 'AddGameButton' " "height = '12' " "/> " @@ -1343,6 +1353,10 @@ "<widget name = 'List' /> " "<layout type = 'horizontal' padding = '0, 0, 16, 0'> " "<space/> " +"<widget name = 'Delete' " +"type = 'Button' " +"/> " +"<space size = '16'/> " "<widget name = 'Cancel' " "type = 'Button' " "/> " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex 22928d2a85..5f04792330 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 005ebb89f3..9416a5a4a0 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -91,6 +91,9 @@ /> <widget name = 'GameList'/> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'> + <widget name = 'LoadGameButton' + height = '20' + /> <widget name = 'AddGameButton' height = '20' /> @@ -556,6 +559,10 @@ </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0'> <space/> + <widget name = 'Delete' + type = 'Button' + /> + <space size = '32'/> <widget name = 'Cancel' type = 'Button' /> diff --git a/gui/themes/scummclassic/classic_layout_320.stx b/gui/themes/scummclassic/classic_layout_320.stx index 1a6f8afa04..89ed033bd5 100644 --- a/gui/themes/scummclassic/classic_layout_320.stx +++ b/gui/themes/scummclassic/classic_layout_320.stx @@ -87,6 +87,9 @@ /> <widget name = 'GameList'/> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'> + <widget name = 'LoadGameButton' + height = '12' + /> <widget name = 'AddGameButton' height = '12' /> @@ -549,6 +552,10 @@ <widget name = 'List' /> <layout type = 'horizontal' padding = '0, 0, 16, 0'> <space/> + <widget name = 'Delete' + type = 'Button' + /> + <space size = '16'/> <widget name = 'Cancel' type = 'Button' /> diff --git a/gui/themes/scummodern.zip b/gui/themes/scummodern.zip Binary files differindex 2a896ca374..93977a3cc7 100644 --- a/gui/themes/scummodern.zip +++ b/gui/themes/scummodern.zip diff --git a/gui/themes/scummodern/scummodern_layout.stx b/gui/themes/scummodern/scummodern_layout.stx index 9d3c009eff..c1029088af 100644 --- a/gui/themes/scummodern/scummodern_layout.stx +++ b/gui/themes/scummodern/scummodern_layout.stx @@ -105,6 +105,9 @@ <widget name = 'StartButton' type = 'Button' /> + <widget name = 'LoadGameButton' + type = 'Button' + /> <space size = '16' /> <widget name = 'AddGameButton' type = 'Button' @@ -568,6 +571,10 @@ </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0'> <space/> + <widget name = 'Delete' + type = 'Button' + /> + <space size = '32'/> <widget name = 'Cancel' type = 'Button' /> diff --git a/gui/themes/scummodern/scummodern_layout_320.stx b/gui/themes/scummodern/scummodern_layout_320.stx index 9d689e5c8d..e154ffdb9a 100644 --- a/gui/themes/scummodern/scummodern_layout_320.stx +++ b/gui/themes/scummodern/scummodern_layout_320.stx @@ -85,6 +85,9 @@ /> <widget name = 'GameList'/> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6'> + <widget name = 'LoadGameButton' + height = 'Globals.Button.Height' + /> <widget name = 'AddGameButton' height = 'Globals.Button.Height' /> @@ -546,6 +549,10 @@ <widget name = 'List' /> <layout type = 'horizontal' padding = '0, 0, 16, 0'> <space/> + <widget name = 'Delete' + type = 'Button' + /> + <space size = '16'/> <widget name = 'Cancel' type = 'Button' /> diff --git a/gui/widget.cpp b/gui/widget.cpp index 685b6dfc65..818676dbf4 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -346,8 +346,7 @@ void GraphicsWidget::setGfx(const Graphics::Surface *gfx) { return; // TODO: add conversion to OverlayColor - _gfx.create(gfx->w, gfx->h, gfx->bytesPerPixel); - memcpy(_gfx.pixels, gfx->pixels, gfx->h * gfx->pitch); + _gfx.copyFrom(*gfx); } void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { |