aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/ThemeEngine.cpp10
-rw-r--r--gui/about.cpp2
-rw-r--r--gui/browser.cpp13
-rw-r--r--gui/browser.h10
-rw-r--r--gui/credits.h4
-rw-r--r--gui/launcher.cpp354
-rw-r--r--gui/launcher.h10
-rw-r--r--gui/massadd.cpp10
-rw-r--r--gui/massadd.h4
-rw-r--r--gui/newgui.cpp10
-rw-r--r--gui/options.cpp10
-rw-r--r--gui/theme.cpp82
-rw-r--r--gui/theme.h7
-rw-r--r--gui/themebrowser.cpp38
-rw-r--r--gui/themebrowser.h2
-rw-r--r--gui/themes/default.inc14
-rw-r--r--gui/themes/scummclassic.zipbin40156 -> 42002 bytes
-rw-r--r--gui/themes/scummclassic/classic_layout.stx7
-rw-r--r--gui/themes/scummclassic/classic_layout_320.stx7
-rw-r--r--gui/themes/scummodern.zipbin123105 -> 125107 bytes
-rw-r--r--gui/themes/scummodern/scummodern_layout.stx7
-rw-r--r--gui/themes/scummodern/scummodern_layout_320.stx7
-rw-r--r--gui/widget.cpp3
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
index 22928d2a85..5f04792330 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
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
index 2a896ca374..93977a3cc7 100644
--- a/gui/themes/scummodern.zip
+++ b/gui/themes/scummodern.zip
Binary files differ
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) {