remade the in-game GUI/menu

svn-id: r11119
This commit is contained in:
Max Horn 2003-11-03 23:26:13 +00:00
parent 2ad5fcfb7d
commit 3456b6f50b
6 changed files with 164 additions and 160 deletions

14
TODO
View File

@ -16,9 +16,8 @@ General
some kind of main loop, which, besides many other things, also polls and
dispatches events. The idea is to turn this around: the event loop
frequently gives the engine time to do these "other things".
* Remove various parts from GameSettings struct: "id", "version", "detectname".
Those are only needed internally by the plugins, and hence shouldn't be
exported. On the long run, "midi" and "features" might be removed, too.
* Remove "detectname" from GameSettings struct. On the long run, "midi" and/or
"features" might be removed, too.
* Enhance the Makefile-based build system to support VPATH and stuff, so that
one can compile scummvm in a directory tree seperate from the source tree.
That would make it possible to build ScummVM with different build options,
@ -51,19 +50,10 @@ GUI
* LAUNCHER: fix global options dialog to be properly persistent
* LAUNCHER: add more options to global options dialog
* LAUNCHER: add more options to game target options dialog
* Maybe make use of TabWidget in the Scumm help dialog?
* Global & game target options dialogs probably could share some "panes"
-> write code allowing this
-> also, 'in game' option dialogs (for volume/scaler/etc. settings)
could potentially reuse these, too
* Maybe rearrange SCUMM in-game menu: essentially, only keep the headline
("How may I serve you?") and the buttons in it (maybe rename "Play"
to "Resume" or so). I.e. remove the savegame list. Then, turn
"Save" and "Load" into real buttons, which when clicked pop up a
new save or load dialog. That way we avoid all the confusing parts of the
current scheme in an elegant fashion. A similar approach is used by
StarCraft/WarCraft/Diablo/NWN/many others. Drawback: Loading a game
would now require one click more.
* Maybe rearrange Launcher dialog, too, to look a bit like the current
SCUMM in-game menu: instead of two button rows, have a single button
column at the right side, and the target list on the left side.

View File

@ -19,6 +19,13 @@
*/
#include "stdafx.h"
#include "common/config-manager.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"
@ -32,10 +39,6 @@
#include "scumm/help.h"
#endif
#include "gui/newgui.h"
#include "gui/ListWidget.h"
#include "common/config-manager.h"
#ifdef _WIN32_WCE
#include "gapi_keys.h"
extern bool _get_key_mapping;
@ -192,28 +195,124 @@ enum {
kQuitCmd = 'QUIT'
};
SaveLoadDialog::SaveLoadDialog(ScummEngine *scumm)
: ScummDialog(scumm, 20, 8, 280, 184) {
const int x = _w - kButtonWidth - 8;
int y = 20;
class SaveLoadChooser : public ChooserDialog {
typedef Common::String String;
typedef Common::StringList StringList;
protected:
bool _saveMode;
// The headline
addResText(0, 7, 260, 16, 1);
public:
SaveLoadChooser(const String &title, const StringList& list, const String &buttonLabel, bool saveMode);
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
const String &getResultString() const;
};
// The five buttons on the side
_saveButton = addPushButton(x, y, queryResString(4), kSaveCmd, 'S'); y += 20;
_loadButton = addPushButton(x, y, queryResString(5), kLoadCmd, 'L'); y += 20;
SaveLoadChooser::SaveLoadChooser(const String &title, const StringList& list, const String &buttonLabel, bool saveMode)
: ChooserDialog(title, list, buttonLabel, 182), _saveMode(saveMode) {
_list->setEditable(saveMode);
_list->setNumberingMode(saveMode ? kListNumberingOne : 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 kListItemActivatedCmd:
case kListItemDoubleClickedCmd:
if (selItem >= 0) {
if (!getResultString().isEmpty()) {
setResult(selItem);
close();
} else if (_saveMode) {
// Start editing the selected item, for saving
_list->startEditMode();
}
}
break;
case kListSelectionChangedCmd:
if (_saveMode) {
_list->startEditMode();
}
_chooseButton->setEnabled(selItem >= 0);
_chooseButton->draw();
break;
default:
ChooserDialog::handleCommand(sender, cmd, data);
}
}
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];
SaveFileManager *mgr = OSystem::instance()->get_savefile_manager();
scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves), mgr);
for (; i < ARRAYSIZE(avail_saves); i++) {
if (avail_saves[i])
scumm->getSavegameName(i, name, mgr);
else
name[0] = 0;
l.push_back(name);
}
delete mgr;
return l;
}
enum {
rowHeight = 18,
kMainMenuWidth = (kButtonWidth + 2*8),
kMainMenuHeight = 7*rowHeight + 3*5 + 7 + 5
};
class SeperatorWidget : public Widget {
protected:
typedef Common::String String;
String _label;
int _align;
public:
SeperatorWidget(GuiObject *boss, int x, int y, int w) : Widget(boss, x, y, w, 2) { }
protected:
void drawWidget(bool hilite) {
g_gui.hLine(_x, _y, _x + _w - 2, g_gui._color);
g_gui.hLine(_x+1, _y+1, _x + _w - 1, g_gui._shadowcolor);
}
};
MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
: ScummDialog(scumm, (320 - kMainMenuWidth)/2, (200 - kMainMenuHeight)/2, kMainMenuWidth, kMainMenuHeight) {
int y = 7;
const int x = (_w - kButtonWidth) / 2;
addButton(x, y, "Resume", kPlayCmd, 'P'); y += rowHeight;
y += 5;
addButton(x, y, "About", kAboutCmd, 'A'); y += 20; // About
addButton(x, y, "Load", kLoadCmd, 'L'); y += rowHeight;
addButton(x, y, "Save", kSaveCmd, 'S'); y += rowHeight;
y += 5;
addButton(x, y, "Options", kOptionsCmd, 'O'); y += rowHeight;
#ifndef DISABLE_HELP
addButton(x, y, "Help", kHelpCmd, 'H'); y += 20; // Help
addButton(x, y, "Help", kHelpCmd, 'H'); y += rowHeight;
#endif
addButton(x, y, "Options", kOptionsCmd, 'O'); y += 20; // Options
addButton(x, y, "About", kAboutCmd, 'A'); y += rowHeight;
y += 5;
addButton(x, y, queryResString(6), kPlayCmd, 'P'); y += 20; // Play
addButton(x, y, queryResString(8), kQuitCmd, 'Q'); y += 20; // Quit
addButton(x, y, "Quit", kQuitCmd, 'Q'); y += rowHeight;
//
// Create the sub dialog(s)
@ -222,21 +321,16 @@ SaveLoadDialog::SaveLoadDialog(ScummEngine *scumm)
#ifndef DISABLE_HELP
_helpDialog = new HelpDialog(scumm);
#endif
// The save game list
_savegameList = new ListWidget(this, 8, 20, x - 14, 156);
}
SaveLoadDialog::~SaveLoadDialog() {
MainMenuDialog::~MainMenuDialog() {
delete _aboutDialog;
#ifndef DISABLE_HELP
delete _helpDialog;
#endif
}
void SaveLoadDialog::open() {
switchToLoadMode();
void MainMenuDialog::open() {
#ifdef _WIN32_WCE
force_keyboard(true);
#endif
@ -244,45 +338,13 @@ void SaveLoadDialog::open() {
ScummDialog::open();
}
void SaveLoadDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kSaveCmd:
if (!_saveMode) {
switchToSaveMode();
}
save();
break;
case kLoadCmd:
if (_saveMode) {
switchToLoadMode();
}
break;
case kListItemDoubleClickedCmd:
if (_savegameList->getSelected() >= 0) {
if (_saveMode) {
if (_savegameList->getSelectedString().isEmpty()) {
// Start editing the selected item, for saving
_savegameList->startEditMode();
} else {
save();
}
} else if (!_savegameList->getSelectedString().isEmpty()) {
load();
}
}
break;
case kListItemActivatedCmd:
if (_savegameList->getSelected() >= 0 && !_savegameList->getSelectedString().isEmpty()) {
if (_saveMode) {
save();
} else {
load();
}
}
break;
case kListSelectionChangedCmd:
if (_saveMode) {
_savegameList->startEditMode();
}
load();
break;
case kPlayCmd:
close();
@ -307,7 +369,7 @@ void SaveLoadDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
}
}
void SaveLoadDialog::close() {
void MainMenuDialog::close() {
ScummDialog::close();
#ifdef _WIN32_WCE
@ -315,62 +377,24 @@ void SaveLoadDialog::close() {
#endif
}
void SaveLoadDialog::fillList() {
// Get savegame names
Common::StringList l;
char name[32];
uint i = _saveMode ? 1 : 0;
bool avail_saves[81];
SaveFileManager *mgr = _scumm->_system->get_savefile_manager();
_scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves), mgr);
for (; i < ARRAYSIZE(avail_saves); i++) {
if (avail_saves[i])
_scumm->getSavegameName(i, name, mgr);
else
name[0] = 0;
l.push_back(name);
void MainMenuDialog::save() {
int idx;
SaveLoadChooser dialog("Save game:", generateSavegameList(_scumm, true), "Save", true);
idx = dialog.runModal();
if (idx >= 0) {
_scumm->requestSave(idx + 1, dialog.getResultString().c_str());
close();
}
delete mgr;
_savegameList->setList(l);
_savegameList->setNumberingMode(_saveMode ? kListNumberingOne : kListNumberingZero);
}
void SaveLoadDialog::save() {
// Save the selected item
_scumm->requestSave(_savegameList->getSelected() + 1, _savegameList->getSelectedString().c_str());
close();
}
void SaveLoadDialog::load() {
// Load the selected item
_scumm->requestLoad(_savegameList->getSelected());
close();
}
void SaveLoadDialog::switchToSaveMode() {
_saveMode = true;
_saveButton->setState(true);
_loadButton->setState(false);
_saveButton->clearFlags(WIDGET_ENABLED);
_loadButton->setFlags(WIDGET_ENABLED);
_savegameList->setEditable(true);
fillList();
draw();
}
void SaveLoadDialog::switchToLoadMode() {
_saveMode = false;
_saveButton->setState(false);
_loadButton->setState(true);
_saveButton->setFlags(WIDGET_ENABLED);
_loadButton->clearFlags(WIDGET_ENABLED);
_savegameList->setEditable(false);
fillList();
draw();
void MainMenuDialog::load() {
int idx;
SaveLoadChooser dialog("Load game:", generateSavegameList(_scumm, false), "Load", false);
idx = dialog.runModal();
if (idx >= 0) {
_scumm->requestLoad(idx);
close();
}
}
#pragma mark -
@ -541,8 +565,8 @@ HelpDialog::HelpDialog(ScummEngine *scumm)
_page = 1;
_numPages = ScummHelp::numPages(scumm->_gameId);
_prevButton = addPushButton(10, 170, "Previous", kPrevCmd, 'P');
_nextButton = addPushButton(90, 170, "Next", kNextCmd, 'N');
_prevButton = addButton(10, 170, "Previous", kPrevCmd, 'P');
_nextButton = addButton(90, 170, "Next", kNextCmd, 'N');
addButton(210, 170, "Close", kCloseCmd, 'C');
_prevButton->clearFlags(WIDGET_ENABLED);

View File

@ -52,32 +52,22 @@ protected:
const String queryResString(int stringno);
};
class SaveLoadDialog : public ScummDialog {
class MainMenuDialog : public ScummDialog {
public:
SaveLoadDialog(ScummEngine *scumm);
~SaveLoadDialog();
MainMenuDialog(ScummEngine *scumm);
~MainMenuDialog();
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
virtual void open();
virtual void close();
protected:
ListWidget *_savegameList;
PushButtonWidget *_saveButton;
PushButtonWidget *_loadButton;
Dialog *_aboutDialog;
#ifndef DISABLE_HELP
Dialog *_helpDialog;
#endif
bool _saveMode;
void fillList();
void save();
void load();
void switchToSaveMode();
void switchToLoadMode();
};
#ifndef DISABLE_HELP
@ -90,8 +80,8 @@ public:
protected:
typedef Common::String String;
PushButtonWidget *_nextButton;
PushButtonWidget *_prevButton;
ButtonWidget *_nextButton;
ButtonWidget *_prevButton;
StaticTextWidget *_title;
StaticTextWidget *_key[HELP_NUM_LINES];

View File

@ -343,16 +343,16 @@ public:
protected:
Dialog *_pauseDialog;
Dialog *_optionsDialog;
Dialog *_saveLoadDialog;
Dialog *_mainMenuDialog;
Dialog *_confirmExitDialog;
protected:
int runDialog(Dialog &dialog);
void confirmexitDialog();
void pauseDialog();
void saveloadDialog();
void mainMenuDialog();
public:
void optionsDialog(); // Used by SaveLoadDialog::handleCommand()
void optionsDialog(); // Used by MainMenuDialog::handleCommand()
protected:
char displayError(bool showCancel, const char *message, ...);
@ -1122,7 +1122,7 @@ public:
byte VAR_TMR_4;
byte VAR_SOUNDCARD;
byte VAR_VIDEOMODE;
byte VAR_SAVELOADDIALOG_KEY;
byte VAR_MAINMENU_KEY;
byte VAR_FIXEDDISK;
byte VAR_CURSORSTATE;
byte VAR_USERPUT;

View File

@ -287,7 +287,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_gameId(gs.id),
_version(gs.version),
_features(gs.features),
gdi(this), _pauseDialog(0), _optionsDialog(0), _saveLoadDialog(0),
gdi(this), _pauseDialog(0), _optionsDialog(0), _mainMenuDialog(0),
_targetName(detector->_targetName) {
OSystem::Property prop;
@ -308,7 +308,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_quit = false;
_pauseDialog = NULL;
_optionsDialog = NULL;
_saveLoadDialog = NULL;
_mainMenuDialog = NULL;
_confirmExitDialog = NULL;
_fastMode = 0;
_actors = NULL;
@ -531,7 +531,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
VAR_TMR_4 = 0xFF;
VAR_SOUNDCARD = 0xFF;
VAR_VIDEOMODE = 0xFF;
VAR_SAVELOADDIALOG_KEY = 0xFF;
VAR_MAINMENU_KEY = 0xFF;
VAR_FIXEDDISK = 0xFF;
VAR_CURSORSTATE = 0xFF;
VAR_USERPUT = 0xFF;
@ -799,7 +799,7 @@ ScummEngine::~ScummEngine() {
delete _charset;
delete _pauseDialog;
delete _optionsDialog;
delete _saveLoadDialog;
delete _mainMenuDialog;
delete _confirmExitDialog;
delete _sound;
@ -1778,7 +1778,7 @@ void ScummEngine::processKbd() {
else if ((_version <= 3) || (_gameId == GID_SAMNMAX) || (_gameId == GID_CMI))
saveloadkey = 319; // F5
else
saveloadkey = VAR(VAR_SAVELOADDIALOG_KEY);
saveloadkey = VAR(VAR_MAINMENU_KEY);
if (_lastKeyHit == VAR(VAR_CUTSCENEEXIT_KEY) ||
(VAR(VAR_CUTSCENEEXIT_KEY) == 4 && _lastKeyHit == 27)) {
@ -1799,7 +1799,7 @@ void ScummEngine::processKbd() {
if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT), 0, 0, 0);
saveloadDialog(); // Display NewGui
mainMenuDialog(); // Display NewGui
if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT2), 0, 0, 0);
@ -2459,10 +2459,10 @@ void ScummEngine::pauseDialog() {
runDialog(*_pauseDialog);
}
void ScummEngine::saveloadDialog() {
if (!_saveLoadDialog)
_saveLoadDialog = new SaveLoadDialog(this);
runDialog(*_saveLoadDialog);
void ScummEngine::mainMenuDialog() {
if (!_mainMenuDialog)
_mainMenuDialog = new MainMenuDialog(this);
runDialog(*_mainMenuDialog);
}
void ScummEngine::optionsDialog() {

View File

@ -77,7 +77,7 @@ void ScummEngine::setupScummVars() {
VAR_TMR_4 = 47;
VAR_SOUNDCARD = 48;
VAR_VIDEOMODE = 49;
VAR_SAVELOADDIALOG_KEY = 50;
VAR_MAINMENU_KEY = 50;
VAR_FIXEDDISK = 51;
VAR_CURSORSTATE = 52;
VAR_USERPUT = 53;
@ -205,7 +205,7 @@ void ScummEngine_v7::setupScummVars() {
VAR_CUTSCENEEXIT_KEY = 62;
VAR_RESTART_KEY = 63; // ???
VAR_PAUSE_KEY = 64;
VAR_SAVELOADDIALOG_KEY = 65; // ???
VAR_MAINMENU_KEY = 65; // ???
VAR_TALKSTOP_KEY = 67;
VAR_KEYPRESS = 118;
@ -294,7 +294,7 @@ void ScummEngine_v8::setupScummVars() {
VAR_CUTSCENEEXIT_KEY = 62; // FIXME - guess based on script-1 (could also be 68)
VAR_PAUSE_KEY = 64;
VAR_SAVELOADDIALOG_KEY = 65;
VAR_MAINMENU_KEY = 65;
VAR_TALKSTOP_KEY = 67;