aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--NEWS19
-rw-r--r--backends/events/default/default-events.cpp48
-rw-r--r--backends/events/default/default-events.h4
-rw-r--r--backends/platform/dc/Makefile2
-rw-r--r--backends/platform/symbian/S60/scummvm-CVS-SymbianS60v1.pkg2
-rw-r--r--backends/platform/symbian/S60/scummvm-CVS-SymbianS60v2.pkg1
-rw-r--r--backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg1
-rw-r--r--backends/platform/symbian/S80/scummvm-CVS-SymbianS80.pkg1
-rw-r--r--backends/platform/symbian/S90/scummvm-CVS-SymbianS90.pkg1
-rw-r--r--backends/platform/symbian/UIQ2/scummvm-CVS-SymbianUIQ2.pkg2
-rw-r--r--backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg1
-rw-r--r--base/main.cpp8
-rw-r--r--common/events.h22
-rw-r--r--common/keyboard.h5
-rw-r--r--common/list.h5
-rw-r--r--common/queue.h71
-rw-r--r--engines/agi/agi.cpp16
-rw-r--r--engines/agi/agi.h3
-rw-r--r--engines/agi/cycle.cpp8
-rw-r--r--engines/agi/detection.cpp33
-rw-r--r--engines/agi/loader_v3.cpp4
-rw-r--r--engines/agi/op_cmd.cpp8
-rw-r--r--engines/agi/op_test.cpp3
-rw-r--r--engines/agi/preagi.cpp3
-rw-r--r--engines/agi/preagi_common.cpp7
-rw-r--r--engines/agi/preagi_mickey.cpp14
-rw-r--r--engines/agi/preagi_troll.cpp11
-rw-r--r--engines/agi/preagi_winnie.cpp11
-rw-r--r--engines/agi/saveload.cpp5
-rw-r--r--engines/agos/agos.cpp21
-rw-r--r--engines/agos/agos.h3
-rw-r--r--engines/agos/animation.cpp4
-rw-r--r--engines/agos/detection.cpp32
-rw-r--r--engines/agos/event.cpp6
-rw-r--r--engines/agos/gfx.cpp2
-rw-r--r--engines/agos/input.cpp8
-rw-r--r--engines/agos/midi.cpp56
-rw-r--r--engines/agos/midi.h7
-rw-r--r--engines/agos/script.cpp8
-rw-r--r--engines/agos/script_e1.cpp5
-rw-r--r--engines/agos/script_s1.cpp5
-rw-r--r--engines/agos/subroutine.cpp2
-rw-r--r--engines/cine/anim.cpp2
-rw-r--r--engines/cine/cine.cpp4
-rw-r--r--engines/cine/detection.cpp36
-rw-r--r--engines/cine/main_loop.cpp12
-rw-r--r--engines/cine/prc.cpp5
-rw-r--r--engines/cine/various.cpp4
-rw-r--r--engines/cine/various.h2
-rw-r--r--engines/dialogs.cpp189
-rw-r--r--engines/dialogs.h73
-rw-r--r--engines/engine.cpp47
-rw-r--r--engines/engine.h27
-rw-r--r--engines/gob/game_v1.cpp4
-rw-r--r--engines/gob/game_v2.cpp10
-rw-r--r--engines/gob/gob.cpp8
-rw-r--r--engines/gob/gob.h3
-rw-r--r--engines/gob/inter.cpp4
-rw-r--r--engines/gob/inter_bargon.cpp6
-rw-r--r--engines/gob/inter_v1.cpp4
-rw-r--r--engines/gob/inter_v2.cpp3
-rw-r--r--engines/gob/mult.cpp2
-rw-r--r--engines/gob/palanim.cpp3
-rw-r--r--engines/gob/sound/sound.cpp2
-rw-r--r--engines/gob/util.cpp6
-rw-r--r--engines/gob/videoplayer.cpp3
-rw-r--r--engines/kyra/gui.cpp3
-rw-r--r--engines/kyra/gui_hof.cpp2
-rw-r--r--engines/kyra/gui_lok.cpp16
-rw-r--r--engines/kyra/gui_mr.cpp2
-rw-r--r--engines/kyra/gui_v2.cpp6
-rw-r--r--engines/kyra/kyra_hof.cpp9
-rw-r--r--engines/kyra/kyra_lok.cpp25
-rw-r--r--engines/kyra/kyra_mr.cpp10
-rw-r--r--engines/kyra/kyra_v1.cpp9
-rw-r--r--engines/kyra/kyra_v1.h5
-rw-r--r--engines/kyra/kyra_v2.cpp8
-rw-r--r--engines/kyra/lol.cpp36
-rw-r--r--engines/kyra/saveload.cpp2
-rw-r--r--engines/kyra/saveload_lok.cpp2
-rw-r--r--engines/kyra/scene_hof.cpp2
-rw-r--r--engines/kyra/scene_mr.cpp2
-rw-r--r--engines/kyra/script_mr.cpp2
-rw-r--r--engines/kyra/sequences_hof.cpp22
-rw-r--r--engines/kyra/sequences_lok.cpp17
-rw-r--r--engines/kyra/sprites.cpp1
-rw-r--r--engines/kyra/text.cpp1
-rw-r--r--engines/kyra/text_hof.cpp12
-rw-r--r--engines/kyra/text_lok.cpp2
-rw-r--r--engines/kyra/text_mr.cpp10
-rw-r--r--engines/kyra/vqa.cpp3
-rw-r--r--engines/lure/animseq.cpp3
-rw-r--r--engines/lure/detection.cpp30
-rw-r--r--engines/lure/events.cpp19
-rw-r--r--engines/lure/events.h2
-rw-r--r--engines/lure/fights.cpp8
-rw-r--r--engines/lure/game.cpp29
-rw-r--r--engines/lure/game.h5
-rw-r--r--engines/lure/intro.cpp7
-rw-r--r--engines/lure/lure.cpp73
-rw-r--r--engines/lure/lure.h6
-rw-r--r--engines/lure/menu.cpp6
-rw-r--r--engines/lure/scripts.cpp6
-rw-r--r--engines/lure/sound.cpp31
-rw-r--r--engines/lure/sound.h4
-rw-r--r--engines/lure/surface.cpp14
-rw-r--r--engines/module.mk4
-rw-r--r--engines/parallaction/detection.cpp29
-rw-r--r--engines/parallaction/dialogue.cpp4
-rw-r--r--engines/parallaction/exec_ns.cpp11
-rw-r--r--engines/parallaction/gui_br.cpp5
-rw-r--r--engines/parallaction/gui_ns.cpp2
-rw-r--r--engines/parallaction/input.cpp4
-rw-r--r--engines/parallaction/parallaction.cpp21
-rw-r--r--engines/parallaction/parallaction.h9
-rw-r--r--engines/parallaction/parallaction_br.cpp6
-rw-r--r--engines/parallaction/parallaction_ns.cpp29
-rw-r--r--engines/parallaction/saveload.cpp8
-rw-r--r--engines/parallaction/sound.cpp3
-rw-r--r--engines/queen/input.cpp5
-rw-r--r--engines/queen/journal.cpp2
-rw-r--r--engines/queen/logic.cpp10
-rw-r--r--engines/queen/midiadlib.cpp2
-rw-r--r--engines/queen/queen.cpp45
-rw-r--r--engines/queen/queen.h5
-rw-r--r--engines/queen/sound.cpp7
-rw-r--r--engines/queen/talk.cpp2
-rw-r--r--engines/saga/detection.cpp31
-rw-r--r--engines/saga/input.cpp3
-rw-r--r--engines/saga/interface.cpp10
-rw-r--r--engines/saga/introproc_ihnm.cpp10
-rw-r--r--engines/saga/music.cpp14
-rw-r--r--engines/saga/music.h3
-rw-r--r--engines/saga/saga.cpp38
-rw-r--r--engines/saga/saga.h6
-rw-r--r--engines/saga/scene.cpp2
-rw-r--r--engines/saga/sfuncs.cpp4
-rw-r--r--engines/saga/sound.cpp47
-rw-r--r--engines/saga/sound.h7
-rw-r--r--engines/scumm/dialogs.cpp12
-rw-r--r--engines/scumm/dialogs.h6
-rw-r--r--engines/scumm/he/cup_player_he.cpp6
-rw-r--r--engines/scumm/he/script_v100he.cpp4
-rw-r--r--engines/scumm/he/script_v70he.cpp4
-rw-r--r--engines/scumm/he/script_v72he.cpp4
-rw-r--r--engines/scumm/input.cpp8
-rw-r--r--engines/scumm/resource.cpp2
-rw-r--r--engines/scumm/saveload.cpp2
-rw-r--r--engines/scumm/script_v5.cpp2
-rw-r--r--engines/scumm/script_v6.cpp2
-rw-r--r--engines/scumm/script_v8.cpp4
-rw-r--r--engines/scumm/scumm.cpp41
-rw-r--r--engines/scumm/scumm.h10
-rw-r--r--engines/scumm/smush/smush_player.cpp2
-rw-r--r--engines/sky/control.cpp11
-rw-r--r--engines/sky/intro.cpp4
-rw-r--r--engines/sky/intro.h1
-rw-r--r--engines/sky/logic.cpp2
-rw-r--r--engines/sky/mouse.cpp1
-rw-r--r--engines/sky/sky.cpp25
-rw-r--r--engines/sky/sky.h1
-rw-r--r--engines/sword1/animation.cpp3
-rw-r--r--engines/sword1/control.cpp9
-rw-r--r--engines/sword1/credits.cpp15
-rw-r--r--engines/sword1/logic.cpp2
-rw-r--r--engines/sword1/sword1.cpp159
-rw-r--r--engines/sword1/sword1.h2
-rw-r--r--engines/sword2/animation.cpp4
-rw-r--r--engines/sword2/controls.cpp8
-rw-r--r--engines/sword2/function.cpp2
-rw-r--r--engines/sword2/palette.cpp2
-rw-r--r--engines/sword2/resman.cpp2
-rw-r--r--engines/sword2/screen.cpp8
-rw-r--r--engines/sword2/sword2.cpp45
-rw-r--r--engines/sword2/sword2.h3
-rw-r--r--engines/touche/detection.cpp53
-rw-r--r--engines/touche/menu.cpp10
-rw-r--r--engines/touche/opcodes.cpp4
-rw-r--r--engines/touche/saveload.cpp7
-rw-r--r--engines/touche/touche.cpp52
-rw-r--r--engines/touche/touche.h5
-rw-r--r--gui/launcher.cpp158
-rw-r--r--gui/launcher.h7
-rw-r--r--gui/newgui.cpp6
-rw-r--r--gui/theme-config.cpp27
-rw-r--r--gui/themes/classic080.ini3
-rw-r--r--gui/themes/modern.ini1
188 files changed, 1815 insertions, 715 deletions
diff --git a/Makefile b/Makefile
index 2395511ee3..506265032a 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ CXXFLAGS:= -Wall $(CXXFLAGS)
CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder
# Enable even more warnings...
CXXFLAGS+= -pedantic -Wpointer-arith -Wcast-qual -Wcast-align
-CXXFLAGS+= -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings
+CXXFLAGS+= -Wshadow -Wimplicit -Wundef -Wnon-virtual-dtor -Wwrite-strings
# Disable RTTI and exceptions, and enabled checking of pointers returned by "new"
CXXFLAGS+= -fno-rtti -fno-exceptions -fcheck-new
diff --git a/NEWS b/NEWS
index eba57b9b43..e008ae24a4 100644
--- a/NEWS
+++ b/NEWS
@@ -7,23 +7,20 @@ For a more comprehensive changelog for the latest experimental SVN code, see:
0.12.0 (????-??-??)
New Games:
- - Added support for The Legend of Kyrandia: Book Two: Hand of Fate.
- - Added support for The Legend of Kyrandia: Book Three: Malcolm's Revenge.
- - Added support for Lost in Time.
- - Added support for The Bizarre Adventures of Woodruff and the Schnibble.
- - Added support for the PC version of Waxworks.
+ - Added support for The Legend of Kyrandia: Book Two: Hand of Fate
+ - Added support for The Legend of Kyrandia: Book Three: Malcolm's Revenge
+ - Added support for Lost in Time
+ - Added support for The Bizarre Adventures of Woodruff and the Schnibble
+ - Added support for the PC version of Waxworks
- Added support for the Macintosh version of I Have no Mouth, and I
- must Scream.
- - Added support for Drascula: The Vampire Strikes Back.
+ must Scream
+ - Added support for Drascula: The Vampire Strikes Back
General:
- Added CAMD MIDI driver for AmigaOS4.
- Revived the PS2 port (was already in 0.11.1 but was forgotten in the
release notes).
- - Plugged numerous memory leaks in all engines (part of GSoC'08 task),
- - Added audio double buffering to the SDL backend, which fixes the
- problems with the MT-32 emulator on Mac OS X (for now only enabled
- on Mac OS X).
+ - Plugged numerous memory leaks in all engines (part of GSoC'08 task)
AGOS:
- Fixed crashes during certain music in Amiga versions of Elvira 1 and
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index 0caba25792..b070fb89ef 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -93,7 +93,8 @@ DefaultEventManager::DefaultEventManager(OSystem *boss) :
_boss(boss),
_buttonState(0),
_modifierState(0),
- _shouldQuit(false) {
+ _shouldQuit(false),
+ _shouldRTL(false) {
assert(_boss);
@@ -200,6 +201,9 @@ DefaultEventManager::~DefaultEventManager() {
_boss->unlockMutex(_timeMutex);
_boss->unlockMutex(_recorderMutex);
+ if (!artificialEventQueue.empty())
+ artificialEventQueue.clear();
+
if (_playbackFile != NULL) {
delete _playbackFile;
}
@@ -349,7 +353,11 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
uint32 time = _boss->getMillis();
bool result;
- result = _boss->pollEvent(event);
+ if (!artificialEventQueue.empty()) {
+ event = artificialEventQueue.pop();
+ result = true;
+ } else
+ result = _boss->pollEvent(event);
if (_recordMode != kPassthrough) {
@@ -375,7 +383,6 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
_modifierState = event.kbd.flags;
-
// init continuous event stream
// not done on PalmOS because keyboard is emulated and keyup is not generated
#if !defined(PALMOS_MODE)
@@ -384,7 +391,15 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_currentKeyDown.flags = event.kbd.flags;
_keyRepeatTime = time + kKeyRepeatInitialDelay;
#endif
+ // Global Main Menu
+ if (event.kbd.keycode == Common::KEYCODE_MAINMENU)
+ if (g_engine && !g_engine->isPaused()) {
+ Common::Event menuEvent;
+ menuEvent.type = Common::EVENT_MAINMENU;
+ pushEvent(menuEvent);
+ }
break;
+
case Common::EVENT_KEYUP:
_modifierState = event.kbd.flags;
if (event.kbd.keycode == _currentKeyDown.keycode) {
@@ -401,6 +416,7 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_mousePos = event.mouse;
_buttonState |= LBUTTON;
break;
+
case Common::EVENT_LBUTTONUP:
_mousePos = event.mouse;
_buttonState &= ~LBUTTON;
@@ -410,11 +426,26 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_mousePos = event.mouse;
_buttonState |= RBUTTON;
break;
+
case Common::EVENT_RBUTTONUP:
_mousePos = event.mouse;
_buttonState &= ~RBUTTON;
break;
+ case Common::EVENT_MAINMENU:
+ if (g_engine && !g_engine->isPaused())
+ g_engine->mainMenuDialog();
+
+ if (_shouldQuit)
+ event.type = Common::EVENT_QUIT;
+ else if (_shouldRTL)
+ event.type = Common::EVENT_RTL;
+ break;
+
+ case Common::EVENT_RTL:
+ _shouldRTL = true;
+ break;
+
case Common::EVENT_QUIT:
if (ConfMan.getBool("confirm_exit")) {
if (g_engine)
@@ -425,6 +456,7 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
g_engine->pauseEngine(false);
} else
_shouldQuit = true;
+
break;
default:
@@ -447,4 +479,14 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
return result;
}
+void DefaultEventManager::pushEvent(Common::Event event) {
+
+ // If already received an EVENT_QUIT, don't add another one
+ if (event.type == Common::EVENT_QUIT) {
+ if (!_shouldQuit)
+ artificialEventQueue.push(event);
+ } else
+ artificialEventQueue.push(event);
+}
+
#endif // !defined(DISABLE_DEFAULT_EVENTMANAGER)
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
index 98dcd4b3de..b2cd1354cc 100644
--- a/backends/events/default/default-events.h
+++ b/backends/events/default/default-events.h
@@ -48,6 +48,7 @@ class DefaultEventManager : public Common::EventManager {
int _buttonState;
int _modifierState;
bool _shouldQuit;
+ bool _shouldRTL;
class RandomSourceRecord {
public:
@@ -107,6 +108,7 @@ public:
~DefaultEventManager();
virtual bool pollEvent(Common::Event &event);
+ virtual void pushEvent(Common::Event event);
virtual void registerRandomSource(Common::RandomSource &rnd, const char *name);
virtual void processMillis(uint32 &millis);
@@ -114,6 +116,8 @@ public:
virtual int getButtonState() const { return _buttonState; }
virtual int getModifierState() const { return _modifierState; }
virtual int shouldQuit() const { return _shouldQuit; }
+ virtual int shouldRTL() const { return _shouldRTL; }
+ virtual void resetRTL() { _shouldRTL = false; }
};
#endif
diff --git a/backends/platform/dc/Makefile b/backends/platform/dc/Makefile
index db5861903b..56848504e1 100644
--- a/backends/platform/dc/Makefile
+++ b/backends/platform/dc/Makefile
@@ -75,7 +75,7 @@ SCUMMVM.BIN : scummvm.bin
plugin_dist :
for p in plugins/*.plg; do \
- sh-elf-strip -g -o "`basename \"$$p\" | LC_CTYPE=C tr '[:lower:]' '[:upper:]'`" "$$p"; \
+ sh-elf-strip -g -o "`basename \"$$p\" | tr '[:lower:]' '[:upper:]'`" "$$p"; \
done
dist : SCUMMVM.BIN plugins plugin_dist
diff --git a/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v1.pkg b/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v1.pkg
index bf3c69ae08..67d9d83160 100644
--- a/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v1.pkg
+++ b/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v1.pkg
@@ -16,7 +16,7 @@
; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
;
; $URL:$
-; $Id:$
+; $Id$
;
;
diff --git a/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v2.pkg b/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v2.pkg
index 3f88ec918c..3afb7a094c 100644
--- a/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v2.pkg
+++ b/backends/platform/symbian/S60/scummvm-CVS-SymbianS60v2.pkg
@@ -52,7 +52,6 @@
"..\..\..\..\dists\engine-data\sky.cpt"-"!:\system\apps\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\igor.tbl"-"!:\system\apps\scummvm\igor.tbl"
"..\..\..\..\dists\engine-data\lure.dat"-"!:\system\apps\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"!:\system\apps\scummvm\drascula.dat"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"!:\system\apps\ScummVM\scummvm.ini",FILENULL
diff --git a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
index 6bd1fbd047..32df2aee8b 100644
--- a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
+++ b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
@@ -63,7 +63,6 @@
"..\..\..\..\dists\engine-data\sky.cpt"-"c:\data\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\igor.tbl"-"c:\data\scummvm\igor.tbl"
"..\..\..\..\dists\engine-data\lure.dat"-"c:\data\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\drascula.dat"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"c:\data\scummvm\scummvm.ini",FILENULL
diff --git a/backends/platform/symbian/S80/scummvm-CVS-SymbianS80.pkg b/backends/platform/symbian/S80/scummvm-CVS-SymbianS80.pkg
index 29e318a479..94d457b93a 100644
--- a/backends/platform/symbian/S80/scummvm-CVS-SymbianS80.pkg
+++ b/backends/platform/symbian/S80/scummvm-CVS-SymbianS80.pkg
@@ -53,7 +53,6 @@
"..\..\..\..\dists\engine-data\sky.cpt"-"!:\system\apps\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\igor.tbl"-"!:\system\apps\scummvm\igor.tbl"
"..\..\..\..\dists\engine-data\lure.dat"-"!:\system\apps\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"!:\system\apps\scummvm\drascula.dat"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"!:\system\apps\ScummVM\scummvm.ini",FILENULL
diff --git a/backends/platform/symbian/S90/scummvm-CVS-SymbianS90.pkg b/backends/platform/symbian/S90/scummvm-CVS-SymbianS90.pkg
index 0173da7699..ca7f08d85f 100644
--- a/backends/platform/symbian/S90/scummvm-CVS-SymbianS90.pkg
+++ b/backends/platform/symbian/S90/scummvm-CVS-SymbianS90.pkg
@@ -53,7 +53,6 @@
"..\..\..\..\dists\engine-data\sky.cpt"-"!:\system\apps\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\igor.tbl"-"!:\system\apps\scummvm\igor.tbl"
"..\..\..\..\dists\engine-data\lure.dat"-"!:\system\apps\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"!:\system\apps\scummvm\drascula.dat"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"!:\system\apps\ScummVM\scummvm.ini",FILENULL
diff --git a/backends/platform/symbian/UIQ2/scummvm-CVS-SymbianUIQ2.pkg b/backends/platform/symbian/UIQ2/scummvm-CVS-SymbianUIQ2.pkg
index aca927eadd..8a121227bc 100644
--- a/backends/platform/symbian/UIQ2/scummvm-CVS-SymbianUIQ2.pkg
+++ b/backends/platform/symbian/UIQ2/scummvm-CVS-SymbianUIQ2.pkg
@@ -16,7 +16,7 @@
; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
;
; $URL:$
-; $Id:$
+; $Id$
;
;
diff --git a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
index 0883c88a21..5aad403074 100644
--- a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
+++ b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
@@ -61,7 +61,6 @@
"..\..\..\..\dists\engine-data\sky.cpt"-"c:\shared\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\igor.tbl"-"c:\shared\scummvm\igor.tbl"
"..\..\..\..\dists\engine-data\lure.dat"-"c:\shared\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"c:\shared\scummvm\drascula.dat"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"c:\shared\scummvm\scummvm.ini",FILENULL
diff --git a/base/main.cpp b/base/main.cpp
index 115a920f36..4283b6cacf 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -38,6 +38,7 @@
#include "base/version.h"
#include "common/config-manager.h"
+#include "common/events.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/system.h"
@@ -200,7 +201,8 @@ static int runGame(const EnginePlugin *plugin, OSystem &system, const Common::St
// Reset the file/directory mappings
Common::File::resetDefaultDirectories();
- return 0;
+ // If result=1 return to the launcher, else quit ScummVM
+ return result;
}
@@ -286,6 +288,10 @@ extern "C" int scummvm_main(int argc, char *argv[]) {
// TODO: We should keep running if starting the selected game failed
// (so instead of just quitting, show a nice error dialog to the
// user and let him pick another game).
+
+ // Reset RTL flag in case we want to load another engine
+ g_system->getEventManager()->resetRTL();
+
if (result == 0)
break;
diff --git a/common/events.h b/common/events.h
index d0cb740692..3e4fdbf5ef 100644
--- a/common/events.h
+++ b/common/events.h
@@ -27,6 +27,7 @@
#define COMMON_EVENTS_H
#include "common/keyboard.h"
+#include "common/queue.h"
#include "common/rect.h"
#include "common/system.h"
#include "common/noncopyable.h"
@@ -58,6 +59,9 @@ enum EventType {
EVENT_MBUTTONDOWN = 13,
EVENT_MBUTTONUP = 14,
+ EVENT_MAINMENU = 15,
+ EVENT_RTL = 16,
+
EVENT_QUIT = 10,
EVENT_SCREEN_CHANGED = 11,
/**
@@ -142,6 +146,11 @@ public:
*/
virtual bool pollEvent(Common::Event &event) = 0;
+ /**
+ * Pushes a "fake" event of the specified type into the event queue
+ */
+ virtual void pushEvent(Common::Event event) = 0;
+
/** Register random source so it can be serialized in game test purposes **/
virtual void registerRandomSource(Common::RandomSource &rnd, const char *name) = 0;
@@ -166,6 +175,16 @@ public:
*/
virtual int shouldQuit() const = 0;
+ /**
+ * Should we return to the launcher?
+ */
+ virtual int shouldRTL() const = 0;
+
+ /**
+ * We have returned to the launcher, and the _shouldRTL should be reset to false
+ */
+ virtual void resetRTL() = 0;
+
// Optional: check whether a given key is currently pressed ????
//virtual bool isKeyPressed(int keycode) = 0;
@@ -173,6 +192,9 @@ public:
// TODO: Consider removing OSystem::getScreenChangeID and
// replacing it by a generic getScreenChangeID method here
+protected:
+
+ Common::Queue<Common::Event> artificialEventQueue;
};
} // End of namespace Common
diff --git a/common/keyboard.h b/common/keyboard.h
index 93579cbed6..fbbc289a3b 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -178,7 +178,10 @@ enum KeyCode {
KEYCODE_MENU = 319,
KEYCODE_POWER = 320, // Power Macintosh power key
KEYCODE_EURO = 321, // Some european keyboards
- KEYCODE_UNDO = 322 // Atari keyboard has Undo
+ KEYCODE_UNDO = 322, // Atari keyboard has Undo
+
+ // Global Main Menu key
+ KEYCODE_MAINMENU = KEYCODE_F6
};
/**
diff --git a/common/list.h b/common/list.h
index c4e7b47644..0372d217b7 100644
--- a/common/list.h
+++ b/common/list.h
@@ -209,6 +209,11 @@ public:
++i;
}
+ void pop_front() {
+ iterator i = begin();
+ i = erase(i);
+ }
+
List<t_T> &operator=(const List<t_T> &list) {
if (this != &list) {
diff --git a/common/queue.h b/common/queue.h
new file mode 100644
index 0000000000..51d56ed54b
--- /dev/null
+++ b/common/queue.h
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * 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 source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2008-rtl/common/stack.h $
+ * $Id$
+ */
+
+#ifndef COMMON_QUEUE_H
+#define COMMON_QUEUE_H
+
+#include "common/scummsys.h"
+#include "common/list.h"
+
+namespace Common {
+
+/**
+ * Variable size Queue class, implemented using our Array class.
+ */
+template<class T>
+class Queue {
+protected:
+ List<T> _queue;
+public:
+ Queue<T>() {}
+ Queue<T>(const List<T> &queueContent) : _queue(queueContent) {}
+
+ bool empty() const {
+ return _queue.empty();
+ }
+ void clear() {
+ _queue.clear();
+ }
+ void push(const T &x) {
+ _queue.push_back(x);
+ }
+ T back() const {
+ return _queue.reverse_begin().operator*();
+ }
+ T front() const {
+ return _queue.begin().operator*();
+ }
+ T pop() {
+ T tmp = front();
+ _queue.pop_front();
+ return tmp;
+ }
+ int size() const {
+ return _queue.size();
+ }
+};
+
+} // End of namespace Common
+
+#endif
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 9d88dd73ef..d67e16d196 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -25,7 +25,6 @@
#include "common/md5.h"
-#include "common/events.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -61,9 +60,6 @@ void AgiEngine::processEvents() {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _game.quitProgNow = true;
- break;
case Common::EVENT_PREDICTIVE_DIALOG:
if (_predictiveDialogRunning)
break;
@@ -809,7 +805,17 @@ int AgiEngine::go() {
runGame();
- return 0;
+ return _eventMan->shouldRTL();
+}
+
+void AgiEngine::syncSoundSettings() {
+ int soundVolumeMusic = ConfMan.getInt("music_volume");
+ int soundVolumeSFX = ConfMan.getInt("music_volume");
+ int soundVolumeSpeech = ConfMan.getInt("music_volume");
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSFX);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, soundVolumeSpeech);
}
} // End of namespace Agi
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 9240d562af..ec290b812d 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -530,7 +530,6 @@ struct AgiGame {
/* internal flags */
int playerControl; /**< player is in control */
- int quitProgNow; /**< quit now */
int statusLine; /**< status line on/off */
int clockEnabled; /**< clock is on/off */
int exitAllLogics; /**< break cycle after new.room */
@@ -754,6 +753,8 @@ public:
return _gameId;
}
+ virtual void syncSoundSettings();
+
private:
int _keyQueue[KEY_QUEUE_SIZE];
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index e0babdf926..3ceaaa8c90 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -24,7 +24,6 @@
*/
-
#include "agi/agi.h"
#include "agi/sprite.h"
#include "agi/graphics.h"
@@ -116,7 +115,7 @@ void AgiEngine::interpretCycle() {
oldSound = getflag(fSoundOn);
_game.exitAllLogics = false;
- while (runLogic(0) == 0 && !_game.quitProgNow) {
+ while (runLogic(0) == 0 && !quit()) {
_game.vars[vWordNotFound] = 0;
_game.vars[vBorderTouchObj] = 0;
_game.vars[vBorderCode] = 0;
@@ -314,7 +313,6 @@ int AgiEngine::playGame() {
setvar(vTimeDelay, 2); /* "normal" speed */
_game.gfxMode = true;
- _game.quitProgNow = false;
_game.clockEnabled = true;
_game.lineUserInput = 22;
@@ -354,10 +352,10 @@ int AgiEngine::playGame() {
_game.vars[vKey] = 0;
}
- if (_game.quitProgNow == 0xff)
+ if (quit() == 0xff)
ec = errRestartGame;
- } while (_game.quitProgNow == 0);
+ } while (quit() == 0);
_sound->stopSound();
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index cd6942f9c0..8ddeae1b17 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -2123,7 +2123,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
-
+ virtual SaveStateList listSaves(const char *target) const;
const Common::ADGameDescription *fallbackDetect(const FSList *fslist) const;
};
@@ -2147,6 +2147,37 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common:
return res;
}
+SaveStateList AgiMetaEngine::listSaves(const char *target) const {
+ const uint32 AGIflag = MKID_BE('AGI:');
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ char saveDesc[31];
+ Common::String pattern = target;
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ uint32 type = in->readUint32BE();
+ if (type == AGIflag)
+ in->read(saveDesc, 31);
+ saveList.push_back(SaveStateDescriptor(slotNum, Common::String(saveDesc), *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
const Common::ADGameDescription *AgiMetaEngine::fallbackDetect(const FSList *fslist) const {
typedef Common::HashMap<Common::String, int32> IntMap;
IntMap allFiles;
diff --git a/engines/agi/loader_v3.cpp b/engines/agi/loader_v3.cpp
index dcf7d83809..9f1255a43a 100644
--- a/engines/agi/loader_v3.cpp
+++ b/engines/agi/loader_v3.cpp
@@ -230,8 +230,8 @@ uint8 *AgiLoader_v3::loadVolRes(AgiDir *agid) {
debugC(3, kDebugLevelResources, "offset = %d", agid->offset);
debugC(3, kDebugLevelResources, "x = %x %x", x[0], x[1]);
error("ACK! BAD RESOURCE");
-
- g_system->quit();
+
+ _vm->quitGame();
}
agid->len = READ_LE_UINT16((uint8 *) x + 3); /* uncompressed size */
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp
index 7ecedfbc8c..758bff0cb6 100644
--- a/engines/agi/op_cmd.cpp
+++ b/engines/agi/op_cmd.cpp
@@ -1213,11 +1213,11 @@ cmd(quit) {
g_sound->stopSound();
if (p0) {
- game.quitProgNow = true;
+ g_agi->quitGame();
} else {
if (g_agi->selectionBox
(" Quit the game, or continue? \n\n\n", buttons) == 0) {
- game.quitProgNow = true;
+ g_agi->quitGame();
}
}
}
@@ -1231,7 +1231,7 @@ cmd(restart_game) {
g_agi->selectionBox(" Restart game, or continue? \n\n\n", buttons);
if (sel == 0) {
- game.quitProgNow = 0xff;
+ g_agi->quitGame();
g_agi->setflag(fRestartGame, true);
g_agi->_menu->enableAll();
}
@@ -1739,7 +1739,7 @@ int AgiEngine::runLogic(int n) {
curLogic->cIP = curLogic->sIP;
timerHack = 0;
- while (ip < _game.logics[n].size && !_game.quitProgNow) {
+ while (ip < _game.logics[n].size && !quit()) {
if (_debug.enabled) {
if (_debug.steps > 0) {
if (_debug.logic0 || n) {
diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp
index 7ba3e625bf..393057ed9c 100644
--- a/engines/agi/op_test.cpp
+++ b/engines/agi/op_test.cpp
@@ -24,7 +24,6 @@
*/
-
#include "agi/agi.h"
#include "agi/keyboard.h"
#include "agi/opcodes.h"
@@ -232,7 +231,7 @@ int AgiEngine::testIfCode(int lognum) {
uint8 p[16] = { 0 };
bool end_test = false;
- while (retval && !game.quitProgNow && !end_test) {
+ while (retval && !quit() && !end_test) {
if (_debug.enabled && (_debug.logic0 || lognum))
debugConsole(lognum, lTEST_MODE, NULL);
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index f2301e012a..f391cd974a 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -23,7 +23,6 @@
*
*/
-#include "common/events.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -228,7 +227,7 @@ FIXME (Fingolfin asks): Why are Mickey, Winnie and Troll standalone classes
error("Unknown preagi engine");
break;
}
- return 0;
+ return _eventMan->shouldRTL();
}
} // End of namespace Agi
diff --git a/engines/agi/preagi_common.cpp b/engines/agi/preagi_common.cpp
index 5d99dfa7f9..3cd04351f7 100644
--- a/engines/agi/preagi_common.cpp
+++ b/engines/agi/preagi_common.cpp
@@ -23,8 +23,6 @@
*
*/
-#include "common/events.h"
-
#include "agi/preagi.h"
#include "agi/font.h"
#include "agi/graphics.h"
@@ -122,11 +120,12 @@ void PreAgiEngine::printStrXOR(char *szMsg) {
int PreAgiEngine::getSelection(SelectionTypes type) {
Common::Event event;
- for (;;) {
+ while (!quit()) {
while (_eventMan->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _system->quit();
+ return 0;
case Common::EVENT_RBUTTONUP:
return 0;
case Common::EVENT_LBUTTONUP:
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index 08f8969ca3..5d89e96d59 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -23,7 +23,6 @@
*
*/
-#include "common/events.h"
#include "common/savefile.h"
#include "common/stream.h"
@@ -343,11 +342,12 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
drawMenu(menu, *sel0, *sel1);
- for (;;) {
+ while (!_vm->quit()) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- exit(0);
+ return 0;
case Common::EVENT_MOUSEMOVE:
if (iRow < 2) {
x = event.mouse.x / 8;
@@ -640,8 +640,8 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
if (iSound == IDI_MSA_SND_THEME) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->_system->quit();
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONUP:
case Common::EVENT_KEYDOWN:
@@ -1214,7 +1214,7 @@ void Mickey::gameOver() {
}
waitAnyKey();
- exit(0);
+ _vm->quitGame();
}
void Mickey::flipSwitch() {
@@ -2053,8 +2053,8 @@ void Mickey::waitAnyKey(bool anim) {
for (;;) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->_system->quit();
case Common::EVENT_KEYDOWN:
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONUP:
@@ -2153,7 +2153,7 @@ void Mickey::run() {
intro();
// Game loop
- for (;;) {
+ while (!_vm->quit()) {
drawRoom();
if (_game.fIntro) {
diff --git a/engines/agi/preagi_troll.cpp b/engines/agi/preagi_troll.cpp
index 7502c63c6c..beff721fda 100644
--- a/engines/agi/preagi_troll.cpp
+++ b/engines/agi/preagi_troll.cpp
@@ -30,8 +30,6 @@
#include "graphics/cursorman.h"
-#include "common/events.h"
-
namespace Agi {
Troll::Troll(PreAgiEngine* vm) : _vm(vm) {
@@ -58,11 +56,12 @@ bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
drawMenu(szMenu, *iSel);
- for (;;) {
+ while (!_vm->quit()) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->_system->quit();
+ return 0;
case Common::EVENT_MOUSEMOVE:
y = event.mouse.y / 8;
@@ -205,8 +204,8 @@ void Troll::waitAnyKeyIntro() {
for (;;) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->_system->quit();
case Common::EVENT_LBUTTONUP:
case Common::EVENT_KEYDOWN:
return;
@@ -269,7 +268,7 @@ void Troll::tutorial() {
int iSel = 0;
//char szTreasure[16] = {0};
- for (;;) {
+ while (!_vm->quit()) {
_vm->clearScreen(0xFF);
_vm->printStr(IDS_TRO_TUTORIAL_0);
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 87d13bff3d..bf023fe5e5 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -29,7 +29,6 @@
#include "graphics/cursorman.h"
-#include "common/events.h"
#include "common/savefile.h"
#include "common/stream.h"
@@ -241,7 +240,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
// extract header from buffer
parseRoomHeader(&hdr, buffer, sizeof(WTP_ROOM_HDR));
- for (;;) {
+ while (!_vm->quit()) {
pc = startpc;
// check if block is to be run
@@ -797,12 +796,12 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
// Show the mouse cursor for the menu
CursorMan.showMouse(true);
- for (;;) {
+ while (!_vm->quit()) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch(event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->_system->quit();
- break;
+ return;
case Common::EVENT_MOUSEMOVE:
x = event.mouse.x / 8;
y = event.mouse.y / 8;
@@ -1014,7 +1013,7 @@ phase2:
if (parser(hdr.ofsDesc[iBlock] - _roomOffset, iBlock, roomdata) == IDI_WTP_PAR_BACK)
goto phase1;
}
- for (;;) {
+ while (!_vm->quit()) {
for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
switch(parser(hdr.ofsBlock[iBlock] - _roomOffset, iBlock, roomdata)) {
case IDI_WTP_PAR_GOTO:
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index db7bba13e4..1589611c01 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -91,7 +91,7 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
out->writeSint16BE((int16)_game.lognum);
out->writeSint16BE((int16)_game.playerControl);
- out->writeSint16BE((int16)_game.quitProgNow);
+ out->writeSint16BE((int16)quit());
out->writeSint16BE((int16)_game.statusLine);
out->writeSint16BE((int16)_game.clockEnabled);
out->writeSint16BE((int16)_game.exitAllLogics);
@@ -281,7 +281,8 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
_game.lognum = in->readSint16BE();
_game.playerControl = in->readSint16BE();
- _game.quitProgNow = in->readSint16BE();
+ if (in->readSint16BE())
+ quitGame();
_game.statusLine = in->readSint16BE();
_game.clockEnabled = in->readSint16BE();
_game.exitAllLogics = in->readSint16BE();
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index a9fd204d73..7d03156bb6 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -97,8 +97,6 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_vc_get_out_of_code = 0;
_gameOffsetsPtr = 0;
- _quit = false;
-
_debugger = 0;
_gameFile = 0;
@@ -550,6 +548,7 @@ int AGOSEngine::init() {
// Setup mixer
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
if ((getGameType() == GType_SIMON2 && getPlatform() == Common::kPlatformWindows) ||
(getGameType() == GType_SIMON1 && getPlatform() == Common::kPlatformWindows) ||
@@ -574,7 +573,7 @@ int AGOSEngine::init() {
if (ret)
warning("MIDI Player init failed: \"%s\"", _midi.getErrorName (ret));
- _midi.setVolume(ConfMan.getInt("music_volume"));
+ _midi.setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume"));
_midiEnabled = true;
@@ -952,7 +951,7 @@ void AGOSEngine::pauseEngineIntern(bool pauseIt) {
void AGOSEngine::pause() {
pauseEngine(true);
- while (_pause && !_quit) {
+ while (_pause && !quit()) {
delay(1);
if (_keyPressed.keycode == Common::KEYCODE_p)
pauseEngine(false);
@@ -989,7 +988,7 @@ int AGOSEngine::go() {
(getFeatures() & GF_DEMO)) {
int i;
- while (!_quit) {
+ while (!quit()) {
for (i = 0; i < 4; i++) {
setWindowImage(3, 9902 + i);
debug(0, "Displaying image %d", 9902 + i);
@@ -1018,13 +1017,13 @@ int AGOSEngine::go() {
runSubroutine101();
permitInput();
- while (!_quit) {
+ while (!quit()) {
waitForInput();
handleVerbClicked(_verbHitArea);
delay(100);
}
- return 0;
+ return _eventMan->shouldRTL();
}
@@ -1084,4 +1083,12 @@ uint32 AGOSEngine::getTime() const {
return (uint32)time(NULL);
}
+
+void AGOSEngine::syncSoundSettings() {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+ _midi.setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume"));
+}
+
} // End of namespace AGOS
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 8ad5487b35..49b4478ec7 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -269,7 +269,6 @@ protected:
uint16 _marks;
- bool _quit;
bool _scriptVar2;
bool _runScriptReturn1;
bool _runScriptCondition[40];
@@ -589,6 +588,8 @@ protected:
void loadSoundFile(const char *filename);
+ virtual void syncSoundSettings();
+
int getUserFlag(Item *item, int a);
int getUserFlag1(Item *item, int a);
int getUserItem(Item *item, int n);
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index c92f834a3b..1b6626fa89 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -26,7 +26,6 @@
#include "common/endian.h"
-#include "common/events.h"
#include "common/system.h"
#include "graphics/cursorman.h"
@@ -279,9 +278,6 @@ void MoviePlayer::handleNextFrame() {
case Common::EVENT_RBUTTONUP:
_rightButtonDown = false;
break;
- case Common::EVENT_QUIT:
- _vm->_quit = true;
- break;
default:
break;
}
diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp
index 26d8916ab7..42dce0f121 100644
--- a/engines/agos/detection.cpp
+++ b/engines/agos/detection.cpp
@@ -27,6 +27,7 @@
#include "common/advancedDetector.h"
#include "common/config-manager.h"
+#include "common/savefile.h"
#include "agos/agos.h"
@@ -100,7 +101,7 @@ static const Common::ADParams detectionParams = {
class AgosMetaEngine : public Common::AdvancedMetaEngine {
public:
AgosMetaEngine() : Common::AdvancedMetaEngine(detectionParams) {}
-
+
virtual const char *getName() const {
return "AGOS";
}
@@ -110,6 +111,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
};
bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
@@ -149,6 +151,34 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common
return res;
}
+SaveStateList AgosMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ Common::String saveDesc;
+ Common::String pattern = target;
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ saveDesc = file->c_str();
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc, *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(AGOS)
REGISTER_PLUGIN_DYNAMIC(AGOS, PLUGIN_TYPE_ENGINE, AgosMetaEngine);
#else
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index 010b331cf8..4db3545594 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -142,7 +142,7 @@ bool AGOSEngine::kickoffTimeEvents() {
cur_time = getTime() - _gameStoppedClock;
- while ((te = _firstTimeStruct) != NULL && te->time <= cur_time && !_quit) {
+ while ((te = _firstTimeStruct) != NULL && te->time <= cur_time && !quit()) {
result = true;
_pendingDeleteTimeEvent = te;
invokeTimeEvent(te);
@@ -520,8 +520,8 @@ void AGOSEngine::delay(uint amount) {
setBitFlag(92, false);
_rightButtonDown++;
break;
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _quit = true;
return;
default:
break;
@@ -544,7 +544,7 @@ void AGOSEngine::delay(uint amount) {
_system->delayMillis(this_delay);
cur = _system->getMillis();
- } while (cur < start + amount && !_quit);
+ } while (cur < start + amount && !quit());
}
void AGOSEngine::timer_callback() {
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 9a3962ea21..25a4b919f4 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -1286,7 +1286,7 @@ void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) {
if (getGameType() == GType_WW && (mode == 6 || mode == 8 || mode == 9)) {
setWindowImage(mode, vga_res);
} else {
- while (_copyScnFlag && !_quit)
+ while (_copyScnFlag && !quit())
delay(1);
setWindowImage(mode, vga_res);
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index d36549f187..3ee81e1375 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -189,12 +189,12 @@ void AGOSEngine::waitForInput() {
resetVerbs();
}
- while (!_quit) {
+ while (!quit()) {
_lastHitArea = NULL;
_lastHitArea3 = NULL;
_dragAccept = 1;
- while (!_quit) {
+ while (!quit()) {
if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
_keyPressed.keycode == Common::KEYCODE_F10)
displayBoxStars();
@@ -563,14 +563,14 @@ bool AGOSEngine::processSpecialKeys() {
case Common::KEYCODE_PLUS:
case Common::KEYCODE_KP_PLUS:
if (_midiEnabled) {
- _midi.setVolume(_midi.getVolume() + 16);
+ _midi.setVolume(_midi.getMusicVolume() + 16, _midi.getSFXVolume() + 16);
}
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) + 16);
break;
case Common::KEYCODE_MINUS:
case Common::KEYCODE_KP_MINUS:
if (_midiEnabled) {
- _midi.setVolume(_midi.getVolume() - 16);
+ _midi.setVolume(_midi.getMusicVolume() - 16, _midi.getSFXVolume() - 16);
}
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) - 16);
break;
diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp
index 3114b24549..6d24c7db2c 100644
--- a/engines/agos/midi.cpp
+++ b/engines/agos/midi.cpp
@@ -49,7 +49,9 @@ MidiPlayer::MidiPlayer() {
_enable_sfx = true;
_current = 0;
- _masterVolume = 255;
+ _musicVolume = 255;
+ _sfxVolume = 255;
+
resetVolumeTable();
_paused = false;
@@ -104,10 +106,13 @@ void MidiPlayer::send(uint32 b) {
byte channel = (byte)(b & 0x0F);
if ((b & 0xFFF0) == 0x07B0) {
- // Adjust volume changes by master volume.
+ // Adjust volume changes by master music and master sfx volume.
byte volume = (byte)((b >> 16) & 0x7F);
_current->volume[channel] = volume;
- volume = volume * _masterVolume / 255;
+ if (_current == &_sfx)
+ volume = volume * _sfxVolume / 255;
+ else if (_current == &_music)
+ volume = volume * _musicVolume / 255;
b = (b & 0xFF00FFFF) | (volume << 16);
} else if ((b & 0xF0) == 0xC0 && _map_mt32_to_gm) {
b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
@@ -133,8 +138,12 @@ void MidiPlayer::send(uint32 b) {
if (!_current->channel[channel])
_current->channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
if (_current->channel[channel]) {
- if (channel == 9)
- _current->channel[9]->volume(_current->volume[9] * _masterVolume / 255);
+ if (channel == 9) {
+ if (_current == &_sfx)
+ _current->channel[9]->volume(_current->volume[9] * _sfxVolume / 255);
+ else if (_current == &_music)
+ _current->channel[9]->volume(_current->volume[9] * _musicVolume / 255);
+ }
_current->channel[channel]->send(b);
if ((b & 0xFFF0) == 0x79B0) {
// We have received a "Reset All Controllers" message
@@ -143,7 +152,10 @@ void MidiPlayer::send(uint32 b) {
// consistent behaviour, explicitly set the volume to
// what we think it should be.
- _current->channel[channel]->volume(_current->volume[channel] * _masterVolume / 255);
+ if (_current == &_sfx)
+ _current->channel[channel]->volume(_current->volume[channel] * _sfxVolume / 255);
+ else if (_current == &_music)
+ _current->channel[channel]->volume(_current->volume[channel] * _musicVolume / 255);
}
}
}
@@ -255,30 +267,36 @@ void MidiPlayer::pause(bool b) {
Common::StackLock lock(_mutex);
for (int i = 0; i < 16; ++i) {
if (_music.channel[i])
- _music.channel[i]->volume(_paused ? 0 : (_music.volume[i] * _masterVolume / 255));
+ _music.channel[i]->volume(_paused ? 0 : (_music.volume[i] * _musicVolume / 255));
if (_sfx.channel[i])
- _sfx.channel[i]->volume(_paused ? 0 : (_sfx.volume[i] * _masterVolume / 255));
+ _sfx.channel[i]->volume(_paused ? 0 : (_sfx.volume[i] * _sfxVolume / 255));
}
}
-void MidiPlayer::setVolume(int volume) {
- if (volume < 0)
- volume = 0;
- else if (volume > 255)
- volume = 255;
-
- if (_masterVolume == volume)
+void MidiPlayer::setVolume(int musicVol, int sfxVol) {
+ if (musicVol < 0)
+ musicVol = 0;
+ else if (musicVol > 255)
+ musicVol = 255;
+ if (sfxVol < 0)
+ sfxVol = 0;
+ else if (sfxVol > 255)
+ sfxVol = 255;
+
+ if (_musicVolume == musicVol && _sfxVolume == sfxVol)
return;
- _masterVolume = volume;
+
+ _musicVolume = musicVol;
+ _sfxVolume = sfxVol;
// Now tell all the channels this.
Common::StackLock lock(_mutex);
if (_driver && !_paused) {
for (int i = 0; i < 16; ++i) {
if (_music.channel[i])
- _music.channel[i]->volume(_music.volume[i] * _masterVolume / 255);
+ _music.channel[i]->volume(_music.volume[i] * _musicVolume / 255);
if (_sfx.channel[i])
- _sfx.channel[i]->volume(_sfx.volume[i] * _masterVolume / 255);
+ _sfx.channel[i]->volume(_sfx.volume[i] * _sfxVolume / 255);
}
}
}
@@ -354,7 +372,7 @@ void MidiPlayer::resetVolumeTable() {
for (i = 0; i < 16; ++i) {
_music.volume[i] = _sfx.volume[i] = 127;
if (_driver)
- _driver->send(((_masterVolume >> 1) << 16) | 0x7B0 | i);
+ _driver->send(((_musicVolume >> 1) << 16) | 0x7B0 | i);
}
}
diff --git a/engines/agos/midi.h b/engines/agos/midi.h
index 2994c49bb6..c004230e5b 100644
--- a/engines/agos/midi.h
+++ b/engines/agos/midi.h
@@ -68,6 +68,8 @@ protected:
// These are maintained for both music and SFX
byte _masterVolume; // 0-255
+ byte _musicVolume;
+ byte _sfxVolume;
bool _paused;
// These are only used for music.
@@ -103,8 +105,9 @@ public:
void stop();
void pause(bool b);
- int getVolume() { return _masterVolume; }
- void setVolume(int volume);
+ int getMusicVolume() { return _musicVolume; }
+ int getSFXVolume() { return _sfxVolume; }
+ void setVolume(int musicVol, int sfxVol);
void setDriver(MidiDriver *md);
public:
diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp
index 6758aec511..a0151d7713 100644
--- a/engines/agos/script.cpp
+++ b/engines/agos/script.cpp
@@ -410,7 +410,7 @@ void AGOSEngine::o_msg() {
void AGOSEngine::o_end() {
// 68: exit interpreter
- _quit = true;
+ quitGame();
}
void AGOSEngine::o_done() {
@@ -965,7 +965,7 @@ void AGOSEngine::writeVariable(uint16 variable, uint16 contents) {
int AGOSEngine::runScript() {
bool flag;
- if (_quit)
+ if (quit())
return 1;
do {
@@ -1010,7 +1010,7 @@ int AGOSEngine::runScript() {
error("Invalid opcode '%d' encountered", _opcode);
executeOpcode(_opcode);
- } while (getScriptCondition() != flag && !getScriptReturn() && !_quit);
+ } while (getScriptCondition() != flag && !getScriptReturn() && !quit());
return getScriptReturn();
}
@@ -1066,7 +1066,7 @@ void AGOSEngine::waitForSync(uint a) {
_exitCutscene = false;
_rightButtonDown = false;
- while (_vgaWaitFor != 0 && !_quit) {
+ while (_vgaWaitFor != 0 && !quit()) {
if (_rightButtonDown) {
if (_vgaWaitFor == 200 && (getGameType() == GType_FF || !getBitFlag(14))) {
skipSpeech();
diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp
index c7e1d6736e..9ac308b114 100644
--- a/engines/agos/script_e1.cpp
+++ b/engines/agos/script_e1.cpp
@@ -24,7 +24,6 @@
*/
-
#include "agos/agos.h"
#include "agos/vga.h"
@@ -565,7 +564,7 @@ void AGOSEngine_Elvira1::oe1_look() {
lobjFunc(l, "You can see "); /* Show objects */
}
if (r && (r->flags & 4) && levelOf(i) < 10000) {
- _quit = true;
+ quitGame();
}
}
@@ -944,7 +943,7 @@ restart:
windowPutChar(window, *message2);
if (confirmYesOrNo(120, 62) == 0x7FFF) {
- _quit = true;
+ quitGame();
} else {
goto restart;
}
diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp
index 51918b9515..8bd9159ad8 100644
--- a/engines/agos/script_s1.cpp
+++ b/engines/agos/script_s1.cpp
@@ -24,7 +24,6 @@
*/
-
#include "common/system.h"
#include "agos/agos.h"
@@ -345,14 +344,14 @@ void AGOSEngine_Simon1::os1_pauseGame() {
if (isSmartphone()) {
if (_keyPressed.keycode) {
if (_keyPressed.keycode == Common::KEYCODE_RETURN)
- _quit = true;
+ quitGame();
else
break;
}
}
#endif
if (_keyPressed.keycode == keyYes)
- _quit = true;
+ quitGame();
else if (_keyPressed.keycode == keyNo)
break;
}
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index cb71ed7efa..488ebf4edf 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -555,7 +555,7 @@ int AGOSEngine::startSubroutine(Subroutine *sub) {
_currentTable = sub;
restart:
- if (_quit)
+ if (quit())
return result;
while ((byte *)sl != (byte *)sub) {
diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp
index 28c2ee3ac8..eb820804a6 100644
--- a/engines/cine/anim.cpp
+++ b/engines/cine/anim.cpp
@@ -745,7 +745,7 @@ int loadResource(const char *resourceName, int16 idx) {
} else if (strstr(resourceName, ".AMI")) {
warning("loadResource: Ignoring file '%s' (Load at %d)", resourceName, idx);
} else if (strstr(resourceName, "ECHEC")) { // Echec (French) means failure
- exitEngine = 1;
+ g_cine->quitGame();
} else {
error("loadResource: Cannot determine type for '%s'", resourceName);
}
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index f6778b6457..50aefe5ff9 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -23,7 +23,6 @@
*
*/
-#include "common/events.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -102,7 +101,8 @@ int CineEngine::go() {
delete renderer;
delete[] page3Raw;
delete g_sound;
- return 0;
+
+ return _eventMan->shouldRTL();
}
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index 8c940bcfd4..899e4c4754 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -499,6 +499,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
};
bool CineMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
@@ -509,6 +510,41 @@ bool CineMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common
return gd != 0;
}
+SaveStateList CineMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ SaveStateList saveList;
+ Common::String filename = target;
+ filename += ".dir";
+ Common::InSaveFile *in = saveFileMan->openForLoading(filename.c_str());
+ if (in) {
+ int8 ch;
+ int slotNum = 0;
+ char saveDesc[20];
+ do {
+ uint pos = 0;
+ do {
+ ch = in->readByte();
+ if (pos < (sizeof(saveDesc) - 1)) {
+ if (ch < 32 || in->eos()) {
+ saveDesc[pos++] = '\0';
+ }
+ else if (ch >= 32) {
+ saveDesc[pos++] = ch;
+ }
+ }
+ } while (ch >= 32 && !in->eos());
+ if (saveDesc[0] != 0) {
+ saveList.push_back(SaveStateDescriptor(slotNum, Common::String(saveDesc), filename));
+ slotNum++;
+ }
+ } while (!in->eos());
+ }
+
+ delete in;
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(CINE)
REGISTER_PLUGIN_DYNAMIC(CINE, PLUGIN_TYPE_ENGINE, CineMetaEngine);
#else
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index e5e670c973..deac4fd57f 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -25,7 +25,6 @@
#include "common/scummsys.h"
-#include "common/events.h"
#include "common/system.h"
#include "cine/main_loop.h"
@@ -61,9 +60,6 @@ static void processEvent(Common::Event &event) {
break;
case Common::EVENT_MOUSEMOVE:
break;
- case Common::EVENT_QUIT:
- exitEngine = 1;
- break;
case Common::EVENT_KEYDOWN:
switch (event.kbd.keycode) {
case Common::KEYCODE_RETURN:
@@ -195,13 +191,9 @@ void purgeSeqList() {
void CineEngine::mainLoop(int bootScriptIdx) {
bool playerAction;
- uint16 quitFlag;
byte di;
uint16 mouseButton;
- quitFlag = 0;
- exitEngine = 0;
-
if (_preLoad == false) {
resetBgIncrustList();
@@ -322,7 +314,7 @@ void CineEngine::mainLoop(int bootScriptIdx) {
if ("quit"[menuCommandLen] == (char)di) {
++menuCommandLen;
if (menuCommandLen == 4) {
- quitFlag = 1;
+ quitGame();
}
} else {
menuCommandLen = 0;
@@ -331,7 +323,7 @@ void CineEngine::mainLoop(int bootScriptIdx) {
manageEvents();
- } while (!exitEngine && !quitFlag && _danKeysPressed != 7);
+ } while (!quit() && _danKeysPressed != 7);
hideMouse();
g_sound->stopMusic();
diff --git a/engines/cine/prc.cpp b/engines/cine/prc.cpp
index 27b1044620..657edf96af 100644
--- a/engines/cine/prc.cpp
+++ b/engines/cine/prc.cpp
@@ -25,6 +25,7 @@
#include "common/endian.h"
+#include "common/events.h"
#include "cine/cine.h"
#include "cine/various.h"
@@ -54,7 +55,9 @@ bool loadPrc(const char *pPrcName) {
// This is copy protection. Used to hang the machine
if (!scumm_stricmp(pPrcName, COPY_PROT_FAIL_PRC_NAME)) {
- exitEngine = 1;
+ Common::Event event;
+ event.type = Common::EVENT_RTL;
+ g_system->getEventManager()->pushEvent(event);
return false;
}
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 58b0c9f269..c490756403 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -25,7 +25,6 @@
#include "common/endian.h"
-#include "common/events.h"
#include "common/savefile.h"
#include "cine/cine.h"
@@ -113,7 +112,6 @@ static const int16 canUseOnItemTable[] = { 1, 0, 0, 1, 1, 0, 0 };
CommandeType objectListCommand[20];
int16 objListTab[20];
-uint16 exitEngine;
uint16 zoneData[NUM_MAX_ZONE];
uint16 zoneQuery[NUM_MAX_ZONE]; //!< Only exists in Operation Stealth
@@ -1179,7 +1177,7 @@ void CineEngine::makeSystemMenu(void) {
{
getMouseData(mouseUpdateStatus, (uint16 *)&mouseButton, (uint16 *)&mouseX, (uint16 *)&mouseY);
if (!makeMenuChoice(confirmMenu, 2, mouseX, mouseY + 8, 100)) {
- exitEngine = 1;
+ quitGame();
}
break;
}
diff --git a/engines/cine/various.h b/engines/cine/various.h
index d87679ca08..5f24d502be 100644
--- a/engines/cine/various.h
+++ b/engines/cine/various.h
@@ -117,8 +117,6 @@ void mainLoopSub6(void);
void checkForPendingDataLoad(void);
-extern uint16 exitEngine;
-
void hideMouse(void);
void removeExtention(char *dest, const char *source);
diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp
new file mode 100644
index 0000000000..adcb7b54ee
--- /dev/null
+++ b/engines/dialogs.cpp
@@ -0,0 +1,189 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * 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 source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "common/config-manager.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/events.h"
+
+#include "graphics/scaler.h"
+
+#include "gui/about.h"
+#include "gui/eval.h"
+#include "gui/newgui.h"
+#include "gui/ListWidget.h"
+
+#include "engines/dialogs.h"
+#include "engines/engine.h"
+
+#ifdef SMALL_SCREEN_DEVICE
+#include "gui/KeysDialog.h"
+#endif
+
+using GUI::CommandSender;
+using GUI::StaticTextWidget;
+using GUI::kButtonWidth;
+using GUI::kButtonHeight;
+using GUI::kBigButtonWidth;
+using GUI::kBigButtonHeight;
+using GUI::kCloseCmd;
+using GUI::kTextAlignCenter;
+using GUI::kTextAlignLeft;
+using GUI::WIDGET_ENABLED;
+
+typedef GUI::OptionsDialog GUI_OptionsDialog;
+typedef GUI::Dialog GUI_Dialog;
+
+GlobalDialog::GlobalDialog(String name)
+ : GUI::Dialog(name) {
+_drawingHints |= GUI::THEME_HINT_SPECIAL_COLOR;}
+
+enum {
+ kSaveCmd = 'SAVE',
+ kLoadCmd = 'LOAD',
+ kPlayCmd = 'PLAY',
+ kOptionsCmd = 'OPTN',
+ kHelpCmd = 'HELP',
+ kAboutCmd = 'ABOU',
+ kQuitCmd = 'QUIT',
+ kRTLCmd = 'RTL',
+ kChooseCmd = 'CHOS'
+};
+
+MainMenuDialog::MainMenuDialog(Engine *engine)
+ : GlobalDialog("globalmain"), _engine(engine) {
+
+ new GUI::ButtonWidget(this, "globalmain_resume", "Resume", kPlayCmd, 'P');
+
+// new GUI::ButtonWidget(this, "scummmain_load", "Load", kLoadCmd, 'L');
+// new GUI::ButtonWidget(this, "scummmain_save", "Save", kSaveCmd, 'S');
+
+ new GUI::ButtonWidget(this, "globalmain_options", "Options", kOptionsCmd, 'O');
+
+ new GUI::ButtonWidget(this, "globalmain_about", "About", kAboutCmd, 'A');
+
+ new GUI::ButtonWidget(this, "globalmain_rtl", "Return to Launcher", kRTLCmd, 'R');
+
+ new GUI::ButtonWidget(this, "globalmain_quit", "Quit", kQuitCmd, 'Q');
+
+ _aboutDialog = new GUI::AboutDialog();
+ _optionsDialog = new ConfigDialog();
+}
+
+MainMenuDialog::~MainMenuDialog() {
+ delete _aboutDialog;
+ delete _optionsDialog;
+}
+
+void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+ switch (cmd) {
+ case kPlayCmd:
+ close();
+ break;
+ case kOptionsCmd:
+ _optionsDialog->runModal();
+ break;
+ case kAboutCmd:
+ _aboutDialog->runModal();
+ break;
+ case kRTLCmd: {
+ Common::Event eventRTL;
+ eventRTL.type = Common::EVENT_RTL;
+ g_system->getEventManager()->pushEvent(eventRTL);
+ close();
+ }
+ break;
+ case kQuitCmd: {
+ Common::Event eventQ;
+ eventQ.type = Common::EVENT_QUIT;
+ g_system->getEventManager()->pushEvent(eventQ);
+ close();
+ }
+ break;
+ default:
+ GlobalDialog::handleCommand(sender, cmd, data);
+ }
+}
+
+enum {
+ kOKCmd = 'ok '
+};
+
+enum {
+ kKeysCmd = 'KEYS'
+};
+
+ConfigDialog::ConfigDialog()
+ : GUI::OptionsDialog("", "scummconfig") {
+
+ //
+ // Sound controllers
+ //
+
+ addVolumeControls(this, "scummconfig_");
+
+ //
+ // Some misc options
+ //
+
+ // SCUMM has a talkspeed range of 0-9
+ addSubtitleControls(this, "scummconfig_", 9);
+
+ //
+ // Add the buttons
+ //
+
+ new GUI::ButtonWidget(this, "scummconfig_ok", "OK", GUI::OptionsDialog::kOKCmd, 'O');
+ new GUI::ButtonWidget(this, "scummconfig_cancel", "Cancel", kCloseCmd, 'C');
+
+#ifdef SMALL_SCREEN_DEVICE
+ new GUI::ButtonWidget(this, "scummconfig_keys", "Keys", kKeysCmd, 'K');
+
+ //
+ // Create the sub dialog(s)
+ //
+
+ _keysDialog = new GUI::KeysDialog();
+#endif
+}
+
+ConfigDialog::~ConfigDialog() {
+#ifdef SMALL_SCREEN_DEVICE
+ delete _keysDialog;
+#endif
+}
+
+void ConfigDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+ switch (cmd) {
+ case kKeysCmd:
+
+#ifdef SMALL_SCREEN_DEVICE
+ _keysDialog->runModal();
+#endif
+ break;
+ default:
+ GUI_OptionsDialog::handleCommand (sender, cmd, data);
+ }
+}
+
diff --git a/engines/dialogs.h b/engines/dialogs.h
new file mode 100644
index 0000000000..dc6bff4dd6
--- /dev/null
+++ b/engines/dialogs.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * 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 source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef GLOBAL_DIALOGS_H
+#define GLOBAL_DIALOGS_H
+
+#include "common/str.h"
+#include "gui/dialog.h"
+#include "gui/options.h"
+#include "gui/widget.h"
+
+#include "engines/engine.h"
+
+
+class GlobalDialog : public GUI::Dialog {
+public:
+ GlobalDialog(Common::String name);
+
+protected:
+ typedef Common::String String;
+};
+
+
+class MainMenuDialog : public GlobalDialog {
+public:
+ MainMenuDialog(Engine *engine);
+ ~MainMenuDialog();
+
+ virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+
+protected:
+ Engine *_engine;
+
+ GUI::Dialog *_aboutDialog;
+ GUI::Dialog *_optionsDialog;
+
+};
+
+class ConfigDialog : public GUI::OptionsDialog {
+protected:
+#ifdef SMALL_SCREEN_DEVICE
+ GUI::Dialog *_keysDialog;
+#endif
+
+public:
+ ConfigDialog();
+ ~ConfigDialog();
+
+ virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+};
+
+#endif
diff --git a/engines/engine.cpp b/engines/engine.cpp
index 757a77f82b..ffc044a508 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -36,7 +36,9 @@
#include "common/savefile.h"
#include "common/system.h"
#include "gui/message.h"
+#include "gui/newgui.h"
#include "sound/mixer.h"
+#include "engines/dialogs.h"
#ifdef _WIN32_WCE
extern bool isSmartphone(void);
@@ -54,7 +56,10 @@ Engine::Engine(OSystem *syst)
_saveFileMan(_system->getSavefileManager()),
_targetName(ConfMan.getActiveDomainName()),
_gameDataPath(ConfMan.get("path")),
- _pauseLevel(0) {
+ _pauseLevel(0),
+ _mainMenuDialog(NULL),
+ _quit(false),
+ _rtl(false) {
g_engine = this;
_autosavePeriod = ConfMan.getInt("autosave_period");
@@ -72,7 +77,8 @@ Engine::Engine(OSystem *syst)
Engine::~Engine() {
_mixer->stopAll();
-
+
+ delete _mainMenuDialog;
g_engine = NULL;
}
@@ -210,3 +216,40 @@ void Engine::pauseEngineIntern(bool pause) {
// By default, just (un)pause all digital sounds
_mixer->pauseAll(pause);
}
+
+void Engine::mainMenuDialog() {
+ if (!_mainMenuDialog)
+ _mainMenuDialog = new MainMenuDialog(this);
+ runDialog(*_mainMenuDialog);
+ syncSoundSettings();
+}
+
+int Engine::runDialog(Dialog &dialog) {
+
+ pauseEngine(true);
+
+ int result = dialog.runModal();
+
+ pauseEngine(false);
+
+ return 0;
+}
+
+void Engine::syncSoundSettings() {
+
+ // Sync the engine with the config manager
+ int soundVolumeMusic = ConfMan.getInt("music_volume");
+ int soundVolumeSFX = ConfMan.getInt("sfx_volume");
+ int soundVolumeSpeech = ConfMan.getInt("speech_volume");
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSFX);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, soundVolumeSpeech);
+}
+
+void Engine::quitGame() {
+ Common::Event event;
+
+ event.type = Common::EVENT_QUIT;
+ _eventMan->pushEvent(event);
+}
diff --git a/engines/engine.h b/engines/engine.h
index 73d529cc62..278c259ea8 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -25,6 +25,7 @@
#ifndef ENGINES_ENGINE_H
#define ENGINES_ENGINE_H
+#include "common/events.h"
#include "common/scummsys.h"
#include "common/str.h"
@@ -39,17 +40,25 @@ namespace Common {
}
namespace GUI {
class Debugger;
+ class Dialog;
}
+using GUI::Dialog;
+
class Engine {
public:
OSystem *_system;
Audio::Mixer *_mixer;
Common::TimerManager * _timer;
+ bool _quit, _rtl;
+
protected:
Common::EventManager *_eventMan;
Common::SaveFileManager *_saveFileMan;
+
+ Dialog *_mainMenuDialog;
+ virtual int runDialog(Dialog &dialog);
const Common::String _targetName; // target name for saves
const Common::String _gameDataPath;
@@ -109,10 +118,28 @@ public:
void pauseEngine(bool pause);
/**
+ * Quit the engine, sends a Quit event to the Event Manager
+ */
+ void quitGame();
+
+ /**
* Return whether the engine is currently paused or not.
*/
bool isPaused() const { return _pauseLevel != 0; }
+ /**
+ * Return whether or not the ENGINE should quit
+ */
+ bool quit() const { return (_eventMan->shouldQuit() || _eventMan->shouldRTL()); }
+
+ /** Run the Global Main Menu Dialog
+ */
+ virtual void mainMenuDialog();
+
+ /** Sync the engine's sound settings with the config manager
+ */
+ virtual void syncSoundSettings();
+
public:
/** Setup the backend's graphics mode. */
diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp
index 66deea8ec4..0ecbc81358 100644
--- a/engines/gob/game_v1.cpp
+++ b/engines/gob/game_v1.cpp
@@ -63,7 +63,7 @@ void Game_v1::playTot(int16 skipPlay) {
strcpy(savedTotName, _curTotFile);
if (skipPlay <= 0) {
- while (!_vm->_quitRequested) {
+ while (!_vm->quit()) {
for (int i = 0; i < 4; i++) {
_vm->_draw->_fontToSprite[i].sprite = -1;
_vm->_draw->_fontToSprite[i].base = -1;
@@ -997,7 +997,7 @@ void Game_v1::collisionsBlock(void) {
WRITE_VAR(16, 0);
_activeCollResId = 0;
}
- while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->_quitRequested);
+ while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->quit());
if (((uint16) _activeCollResId & ~0x8000) == collResId) {
collStackPos = 0;
diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp
index adf75176ab..7d9419b592 100644
--- a/engines/gob/game_v2.cpp
+++ b/engines/gob/game_v2.cpp
@@ -70,7 +70,7 @@ void Game_v2::playTot(int16 skipPlay) {
strcpy(savedTotName, _curTotFile);
if (skipPlay <= 0) {
- while (!_vm->_quitRequested) {
+ while (!_vm->quit()) {
if (_vm->_inter->_variables)
_vm->_draw->animateCursor(4);
@@ -438,7 +438,7 @@ int16 Game_v2::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
timeKey = _vm->_util->getTimeKey();
while (1) {
- if (_vm->_inter->_terminate || _vm->_quitRequested) {
+ if (_vm->_inter->_terminate || _vm->quit()) {
if (handleMouse)
_vm->_draw->blitCursor();
return 0;
@@ -1043,7 +1043,7 @@ void Game_v2::collisionsBlock(void) {
WRITE_VAR(16, 0);
_activeCollResId = 0;
}
- while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->_quitRequested);
+ while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->quit());
if ((_activeCollResId & 0xFFF) == collResId) {
collStackPos = 0;
@@ -1465,7 +1465,7 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
key = checkCollisions(handleMouse, -300, collResId, collIndex);
if ((key != 0) || (*collResId != 0) ||
- _vm->_inter->_terminate || _vm->_quitRequested)
+ _vm->_inter->_terminate || _vm->quit())
break;
if (*pTotTime > 0) {
@@ -1479,7 +1479,7 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
}
if ((key == 0) || (*collResId != 0) ||
- _vm->_inter->_terminate || _vm->_quitRequested)
+ _vm->_inter->_terminate || _vm->quit())
return 0;
switch (key) {
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 34443251d8..d64ce3c9cc 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -24,7 +24,6 @@
*/
#include "common/endian.h"
-#include "common/events.h"
#include "base/plugins.h"
#include "common/config-manager.h"
@@ -82,7 +81,6 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) {
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
_copyProtection = ConfMan.getBool("copy_protection");
- _quitRequested = false;
Common::addSpecialDebugLevel(kDebugFuncOp, "FuncOpcodes", "Script FuncOpcodes debug level");
Common::addSpecialDebugLevel(kDebugDrawOp, "DrawOpcodes", "Script DrawOpcodes debug level");
@@ -112,11 +110,7 @@ GobEngine::~GobEngine() {
int GobEngine::go() {
_init->initGame(0);
- return 0;
-}
-
-void GobEngine::shutdown() {
- _quitRequested = true;
+ return _eventMan->shouldRTL();
}
const char *GobEngine::getLangDesc(int16 language) const {
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 041658baea..485389f990 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -209,7 +209,6 @@ public:
char *_startTot0;
bool _copyProtection;
bool _noMusic;
- bool _quitRequested;
Global *_global;
Util *_util;
@@ -229,8 +228,6 @@ public:
SaveLoad *_saveLoad;
VideoPlayer *_vidPlayer;
- void shutdown();
-
const char *getLangDesc(int16 language) const;
void validateLanguage();
void validateVideoMode(int16 videoMode);
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index 02e7f99cbd..4973bd756d 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -259,7 +259,7 @@ void Inter::funcBlock(int16 retFlag) {
if (executeFuncOpcode(cmd2, cmd, params))
return;
- if (_vm->_quitRequested)
+ if (_vm->quit())
break;
if (_break) {
@@ -279,7 +279,7 @@ void Inter::funcBlock(int16 retFlag) {
void Inter::callSub(int16 retFlag) {
byte block;
- while (!_vm->_quitRequested && _vm->_global->_inter_execPtr &&
+ while (!_vm->quit() && _vm->_global->_inter_execPtr &&
(_vm->_global->_inter_execPtr != _vm->_game->_totFileData)) {
block = *_vm->_global->_inter_execPtr;
diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp
index d493fb00d3..d23841efd6 100644
--- a/engines/gob/inter_bargon.cpp
+++ b/engines/gob/inter_bargon.cpp
@@ -750,7 +750,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams &params) {
for (i = 320; i >= 0; i--) {
_vm->_util->setScrollOffset(i, 0);
if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) ||
- _vm->_quitRequested) {
+ _vm->quit()) {
_vm->_palAnim->fade(0, -2, 0);
_vm->_video->clearSurf(_vm->_draw->_frontSurface);
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
@@ -760,7 +760,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams &params) {
break;
}
}
- if (!_vm->_quitRequested)
+ if (!_vm->quit())
_vm->_util->setScrollOffset(0, 0);
surface = 0;
if (VAR(57) == ((uint32) -1))
@@ -799,7 +799,7 @@ void Inter_Bargon::oBargon_intro3(OpGobParams &params) {
_vm->_util->longDelay(_vm->_util->getRandom(200));
}
if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) ||
- _vm->_quitRequested) {
+ _vm->quit()) {
_vm->_sound->blasterStop(10);
_vm->_palAnim->fade(0, -2, 0);
_vm->_video->clearSurf(_vm->_draw->_frontSurface);
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 865d188a2e..cc114f0afc 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1234,7 +1234,7 @@ bool Inter_v1::o1_repeatUntil(OpFuncParams &params) {
funcBlock(1);
_vm->_global->_inter_execPtr = blockPtr + size + 1;
flag = evalBoolResult();
- } while (!flag && !_break && !_terminate && !_vm->_quitRequested);
+ } while (!flag && !_break && !_terminate && !_vm->quit());
_nestLevel[0]--;
@@ -1269,7 +1269,7 @@ bool Inter_v1::o1_whileDo(OpFuncParams &params) {
} else
_vm->_global->_inter_execPtr += size;
- if (_break || _terminate || _vm->_quitRequested) {
+ if (_break || _terminate || _vm->quit()) {
_vm->_global->_inter_execPtr = blockPtr;
_vm->_global->_inter_execPtr += size;
break;
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 2f1d2ec0be..b245001653 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -24,6 +24,7 @@
*/
#include "common/endian.h"
+
#include "sound/mixer.h"
#include "sound/mods/infogrames.h"
@@ -1489,7 +1490,7 @@ void Inter_v2::o2_scroll() {
curX = startX;
curY = startY;
- while (!_vm->_quitRequested && ((curX != endX) || (curY != endY))) {
+ while (!_vm->quit() && ((curX != endX) || (curY != endY))) {
curX = stepX > 0 ? MIN(curX + stepX, (int) endX) :
MAX(curX + stepX, (int) endX);
curY = stepY > 0 ? MIN(curY + stepY, (int) endY) :
diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp
index b9373d48b3..a502e92188 100644
--- a/engines/gob/mult.cpp
+++ b/engines/gob/mult.cpp
@@ -209,7 +209,7 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_frame++;
_vm->_util->waitEndFrame();
- } while (!stop && !stopNoClear && !_vm->_quitRequested);
+ } while (!stop && !stopNoClear && !_vm->quit());
if (!stopNoClear) {
if (_animDataAllocated) {
diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp
index 71e73adf53..4f2e921dcb 100644
--- a/engines/gob/palanim.cpp
+++ b/engines/gob/palanim.cpp
@@ -23,6 +23,7 @@
*
*/
+
#include "gob/gob.h"
#include "gob/palanim.h"
#include "gob/global.h"
@@ -131,7 +132,7 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) {
bool stop;
int16 i;
- if (_vm->_quitRequested)
+ if (_vm->quit())
return;
_fadeValue = (fadeV < 0) ? -fadeV : 2;
diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp
index 2d2bf8e043..e0c18b155f 100644
--- a/engines/gob/sound/sound.cpp
+++ b/engines/gob/sound/sound.cpp
@@ -369,7 +369,7 @@ void Sound::blasterWaitEndPlay(bool interruptible, bool stopComp) {
if (stopComp)
_blaster->endComposition();
- while (_blaster->isPlaying() && !_vm->_quitRequested) {
+ while (_blaster->isPlaying() && !_vm->_quit) {
if (interruptible && (_vm->_util->checkKey() == 0x11B)) {
WRITE_VAR(57, (uint32) -1);
return;
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 4987426fe0..0a7b889031 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -23,7 +23,6 @@
*
*/
-#include "common/events.h"
#include "gob/gob.h"
#include "gob/util.h"
@@ -72,7 +71,7 @@ void Util::longDelay(uint16 msecs) {
_vm->_video->waitRetrace();
processInput();
delay(15);
- } while (!_vm->_quitRequested &&
+ } while (!_vm->quit() &&
((g_system->getMillis() * _vm->_global->_speedFactor) < time));
}
@@ -118,9 +117,6 @@ void Util::processInput(bool scroll) {
break;
case Common::EVENT_KEYUP:
break;
- case Common::EVENT_QUIT:
- _vm->_quitRequested = true;
- break;
default:
break;
}
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index aa47e6cf84..daf7bdd801 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -23,6 +23,7 @@
*
*/
+
#include "gob/videoplayer.h"
#include "gob/global.h"
#include "gob/util.h"
@@ -568,7 +569,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
_vm->_util->processInput();
- if (_vm->_quitRequested) {
+ if (_vm->quit()) {
_primaryVideo->getVideo()->disableSound();
return true;
}
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 96ea233025..8a5a4dfc91 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -378,9 +378,6 @@ bool MainMenu::getInput() {
while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _vm->quitGame();
- break;
case Common::EVENT_LBUTTONUP:
return true;
default:
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index 7d56743af5..cb3cef2fb3 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -512,7 +512,7 @@ void KyraEngine_HoF::bookLoop() {
showBookPage();
_bookShown = true;
- while (_bookShown && !_quitFlag) {
+ while (_bookShown && !quit()) {
checkInput(buttonList);
removeInputTop();
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 47ce698e50..818d2f9b4e 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -34,7 +34,6 @@
#include "common/config-manager.h"
#include "common/savefile.h"
-#include "common/events.h"
#include "common/system.h"
namespace Kyra {
@@ -460,7 +459,7 @@ int GUI_LoK::buttonMenuCallback(Button *caller) {
updateAllMenuButtons();
}
- while (_displayMenu && !_vm->_quitFlag) {
+ while (_displayMenu && !_vm->quit()) {
Common::Point mouse = _vm->getMousePos();
processHighlights(_menu[_toplevelMenu], mouse.x, mouse.y);
processButtonList(_menuButtonList, 0, 0);
@@ -485,9 +484,6 @@ void GUI_LoK::getInput() {
_mouseWheel = 0;
while (_vm->_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _vm->quitGame();
- break;
case Common::EVENT_LBUTTONDOWN:
_vm->_mousePressFlag = true;
break;
@@ -583,7 +579,7 @@ int GUI_LoK::saveGameMenu(Button *button) {
_displaySubMenu = true;
_cancelSubMenu = false;
- while (_displaySubMenu && !_vm->_quitFlag) {
+ while (_displaySubMenu && !_vm->quit()) {
getInput();
Common::Point mouse = _vm->getMousePos();
processHighlights(_menu[2], mouse.x, mouse.y);
@@ -632,7 +628,7 @@ int GUI_LoK::loadGameMenu(Button *button) {
_vm->_gameToLoad = -1;
- while (_displaySubMenu && !_vm->_quitFlag) {
+ while (_displaySubMenu && !_vm->quit()) {
getInput();
Common::Point mouse = _vm->getMousePos();
processHighlights(_menu[2], mouse.x, mouse.y);
@@ -720,7 +716,7 @@ int GUI_LoK::saveGame(Button *button) {
}
redrawTextfield();
- while (_displaySubMenu && !_vm->_quitFlag) {
+ while (_displaySubMenu && !_vm->quit()) {
getInput();
updateSavegameString();
Common::Point mouse = _vm->getMousePos();
@@ -796,7 +792,7 @@ bool GUI_LoK::quitConfirm(const char *str) {
_displaySubMenu = true;
_cancelSubMenu = true;
- while (_displaySubMenu && !_vm->_quitFlag) {
+ while (_displaySubMenu && !_vm->quit()) {
getInput();
Common::Point mouse = _vm->getMousePos();
processHighlights(_menu[1], mouse.x, mouse.y);
@@ -862,7 +858,7 @@ int GUI_LoK::gameControlsMenu(Button *button) {
_displaySubMenu = true;
_cancelSubMenu = false;
- while (_displaySubMenu && !_vm->_quitFlag) {
+ while (_displaySubMenu && !_vm->quit()) {
getInput();
Common::Point mouse = _vm->getMousePos();
processHighlights(_menu[5], mouse.x, mouse.y);
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index 6822b303c3..40fe78c439 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -868,7 +868,7 @@ void KyraEngine_MR::processAlbum() {
albumNewPage();
_album.running = true;
- while (_album.running && !_quitFlag) {
+ while (_album.running && !quit()) {
updateInput();
checkInput(buttonList);
removeInputTop();
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index e4cec760fa..a7ae2a6c44 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -822,13 +822,9 @@ void GUI_v2::checkTextfieldInput() {
int keys = 0;
while (_vm->_eventMan->pollEvent(event) && running) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _vm->_quitFlag = true;
- break;
-
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL)
- _vm->_quitFlag = true;
+ _vm->quitGame();
else
_keyPressed = event.kbd;
running = false;
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 27d905435f..fd14e8c909 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -317,7 +317,7 @@ int KyraEngine_HoF::go() {
seq_playSequences(kSequenceFunters, kSequenceFrash);
}
- return 0;
+ return _eventMan->shouldRTL();
}
void KyraEngine_HoF::startup() {
@@ -446,9 +446,8 @@ void KyraEngine_HoF::startup() {
void KyraEngine_HoF::runLoop() {
_screen->updateScreen();
- _quitFlag = false;
_runFlag = true;
- while (!_quitFlag && _runFlag) {
+ while (!quit() && _runFlag) {
if (_deathHandler >= 0) {
removeHandItem();
delay(5);
@@ -1609,7 +1608,7 @@ void KyraEngine_HoF::loadInvWsa(const char *filename, int run, int delayTime, in
_invWsa.timer = _system->getMillis();
if (run) {
- while (_invWsa.running && !skipFlag() && !_quitFlag) {
+ while (_invWsa.running && !skipFlag() && !quit()) {
update();
_system->delayMillis(10);
}
@@ -1983,7 +1982,7 @@ void KyraEngine_HoF::playTim(const char *filename) {
return;
_tim->resetFinishedFlag();
- while (!_quitFlag && !_tim->finished()) {
+ while (!quit() && !_tim->finished()) {
_tim->exec(tim, 0);
if (_chatText)
updateWithText();
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index db3a8fb627..f668ae8401 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -26,7 +26,6 @@
#include "kyra/kyra_lok.h"
#include "common/file.h"
-#include "common/events.h"
#include "common/system.h"
#include "common/savefile.h"
@@ -301,8 +300,8 @@ int KyraEngine_LoK::go() {
if (_gameToLoad == -1) {
setGameFlag(0xEF);
seq_intro();
- if (_quitFlag)
- return 0;
+ if (quit())
+ return _eventMan->shouldRTL();
if (_skipIntroFlag && _abortIntroFlag)
resetGameFlag(0xEF);
}
@@ -310,7 +309,7 @@ int KyraEngine_LoK::go() {
resetGameFlag(0xEF);
mainLoop();
}
- return 0;
+ return _eventMan->shouldRTL();
}
@@ -401,7 +400,7 @@ void KyraEngine_LoK::startup() {
void KyraEngine_LoK::mainLoop() {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::mainLoop()");
- while (!_quitFlag) {
+ while (!quit()) {
int32 frameTime = (int32)_system->getMillis();
_skipFlag = false;
@@ -446,7 +445,7 @@ void KyraEngine_LoK::mainLoop() {
}
void KyraEngine_LoK::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) {
- while (_system->getMillis() < timestamp && !_quitFlag) {
+ while (_system->getMillis() < timestamp && !quit()) {
if (updateTimers)
_timer->update();
@@ -478,7 +477,7 @@ void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) {
if (event.kbd.keycode == 'd')
_debugger->attach();
else if (event.kbd.keycode == 'q')
- _quitFlag = true;
+ quitGame();
} else if (event.kbd.keycode == '.') {
_skipFlag = true;
} else if (event.kbd.keycode == Common::KEYCODE_RETURN || event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_ESCAPE) {
@@ -490,9 +489,6 @@ void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) {
case Common::EVENT_MOUSEMOVE:
_animator->_updateScreen = true;
break;
- case Common::EVENT_QUIT:
- quitGame();
- break;
case Common::EVENT_LBUTTONDOWN:
_mousePressFlag = true;
break;
@@ -531,27 +527,24 @@ void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) {
if (_skipFlag && !_abortIntroFlag && !queryGameFlag(0xFE))
_skipFlag = false;
- if (amount > 0 && !_skipFlag && !_quitFlag)
+ if (amount > 0 && !_skipFlag && !quit())
_system->delayMillis(10);
if (_skipFlag)
_sound->voiceStop();
- } while (!_skipFlag && _system->getMillis() < start + amount && !_quitFlag);
+ } while (!_skipFlag && _system->getMillis() < start + amount && !quit());
}
void KyraEngine_LoK::waitForEvent() {
bool finished = false;
Common::Event event;
- while (!finished && !_quitFlag) {
+ while (!finished && !quit()) {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
finished = true;
break;
- case Common::EVENT_QUIT:
- quitGame();
- break;
case Common::EVENT_LBUTTONDOWN:
finished = true;
_skipFlag = true;
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index a4e5b58364..7097543750 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -263,7 +263,7 @@ int KyraEngine_MR::go() {
running = false;
}
- while (running && !_quitFlag) {
+ while (running && !quit()) {
_screen->_curPage = 0;
_screen->clearPage(0);
@@ -272,14 +272,14 @@ int KyraEngine_MR::go() {
// XXX
playMenuAudioFile();
- for (int i = 0; i < 64 && !_quitFlag; ++i) {
+ for (int i = 0; i < 64 && !quit(); ++i) {
uint32 nextRun = _system->getMillis() + 3 * _tickLength;
_menuAnim->displayFrame(i, 0);
_screen->updateScreen();
delayUntil(nextRun);
}
- for (int i = 64; i > 29 && !_quitFlag; --i) {
+ for (int i = 64; i > 29 && !quit(); --i) {
uint32 nextRun = _system->getMillis() + 3 * _tickLength;
_menuAnim->displayFrame(i, 0);
_screen->updateScreen();
@@ -324,7 +324,7 @@ int KyraEngine_MR::go() {
if (_showOutro)
playVQA("CREDITS");
- return 0;
+ return _eventMan->shouldRTL();
}
void KyraEngine_MR::initMainMenu() {
@@ -995,7 +995,7 @@ void KyraEngine_MR::runLoop() {
_eventList.clear();
_runFlag = true;
- while (_runFlag && !_quitFlag) {
+ while (_runFlag && !quit()) {
if (_deathHandler >= 0) {
removeHandItem();
delay(5);
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index bc46d8e1f5..f3014911fc 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -52,8 +52,6 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
_gameSpeed = 60;
_tickLength = (uint8)(1000.0 / _gameSpeed);
- _quitFlag = false;
-
_speechFile = "";
_trackMap = 0;
_trackMapSize = 0;
@@ -202,7 +200,10 @@ KyraEngine_v1::~KyraEngine_v1() {
void KyraEngine_v1::quitGame() {
debugC(9, kDebugLevelMain, "KyraEngine_v1::quitGame()");
- _quitFlag = true;
+ Common::Event event;
+
+ event.type = Common::EVENT_QUIT;
+ _eventMan->pushEvent(event);
// Nothing to do here
}
@@ -240,7 +241,7 @@ int KyraEngine_v1::resetGameFlag(int flag) {
}
void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) {
- while (_system->getMillis() < timestamp && !_quitFlag) {
+ while (_system->getMillis() < timestamp && !quit()) {
if (timestamp - _system->getMillis() >= 10)
delay(10, update, isMainLoop);
}
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 05c746f289..6d61bd997f 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -118,8 +118,6 @@ public:
virtual void pauseEngineIntern(bool pause);
- bool quit() const { return _quitFlag; }
-
uint8 game() const { return _flags.gameID; }
const GameFlags &gameFlags() const { return _flags; }
@@ -178,9 +176,6 @@ protected:
virtual int go() = 0;
virtual int init();
- // quit Handling
- bool _quitFlag;
-
// intern
Resource *_res;
Sound *_sound;
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 2e704f2aa2..08a4e9f4c5 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -159,7 +159,7 @@ void KyraEngine_v2::delay(uint32 amount, bool updateGame, bool isMainLoop) {
if (amount > 0)
_system->delayMillis(amount > 10 ? 10 : amount);
- } while (!skipFlag() && _system->getMillis() < start + amount && !_quitFlag);
+ } while (!skipFlag() && _system->getMillis() < start + amount && !quit());
}
int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) {
@@ -238,15 +238,11 @@ void KyraEngine_v2::updateInput() {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _quitFlag = true;
- break;
-
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE)
_eventList.push_back(Event(event, true));
else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL)
- _quitFlag = true;
+ quitGame();
else
_eventList.push_back(event);
break;
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index ef1121baa0..148b7daf4d 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -180,15 +180,11 @@ void LoLEngine::updateInput() {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _quitFlag = true;
- break;
-
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE)
_eventList.push_back(Event(event, true));
else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL)
- _quitFlag = true;
+ quitGame();
else
_eventList.push_back(event);
break;
@@ -301,7 +297,7 @@ void LoLEngine::showIntro() {
_screen->hideMouse();
uint32 palNextFadeStep = 0;
- while (!_tim->finished() && !_quitFlag && !skipFlag()) {
+ while (!_tim->finished() && !quit() && !skipFlag()) {
updateInput();
_tim->exec(intro, false);
_screen->checkedPageUpdate(8, 4);
@@ -379,14 +375,14 @@ int LoLEngine::chooseCharacter() {
_screen->fadePalette(_screen->getPalette(0), 30, 0);
bool kingIntro = true;
- while (!_quitFlag) {
+ while (!quit()) {
if (kingIntro)
kingSelectionIntro();
if (_charSelection < 0)
processCharacterSelection();
- if (_quitFlag)
+ if (quit())
break;
if (_charSelection == 100) {
@@ -407,11 +403,11 @@ int LoLEngine::chooseCharacter() {
}
}
- if (_quitFlag)
+ if (quit())
return -1;
uint32 waitTime = _system->getMillis() + 420 * _tickLength;
- while (waitTime > _system->getMillis() && !skipFlag() && !_quitFlag) {
+ while (waitTime > _system->getMillis() && !skipFlag() && !quit()) {
updateInput();
_system->delayMillis(10);
}
@@ -443,7 +439,7 @@ void LoLEngine::kingSelectionIntro() {
_chargenWSA->setDrawPage(0);
int index = 4;
- while (_sound->voiceIsPlaying("KING01") && _charSelection == -1 && !_quitFlag && !skipFlag()) {
+ while (_sound->voiceIsPlaying("KING01") && _charSelection == -1 && !quit() && !skipFlag()) {
index = MAX(index, 4);
_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0);
@@ -454,7 +450,7 @@ void LoLEngine::kingSelectionIntro() {
_screen->updateScreen();
uint32 waitEnd = _system->getMillis() + 7 * _tickLength;
- while (waitEnd > _system->getMillis() && _charSelection == -1 && !_quitFlag && !skipFlag()) {
+ while (waitEnd > _system->getMillis() && _charSelection == -1 && !quit() && !skipFlag()) {
_charSelection = getCharSelection();
_system->delayMillis(10);
}
@@ -485,7 +481,7 @@ void LoLEngine::kingSelectionReminder() {
_chargenWSA->setDrawPage(0);
int index = 0;
- while (_sound->voiceIsPlaying("KING02") && _charSelection == -1 && !_quitFlag && index < 15) {
+ while (_sound->voiceIsPlaying("KING02") && _charSelection == -1 && !quit() && index < 15) {
_chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 0, 0);
_screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
_screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
@@ -494,7 +490,7 @@ void LoLEngine::kingSelectionReminder() {
_screen->updateScreen();
uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
- while (waitEnd > _system->getMillis() && !_quitFlag) {
+ while (waitEnd > _system->getMillis() && !quit()) {
_charSelection = getCharSelection();
_system->delayMillis(10);
}
@@ -515,14 +511,14 @@ void LoLEngine::kingSelectionOutro() {
_chargenWSA->setDrawPage(0);
int index = 0;
- while (_sound->voiceIsPlaying("KING03") && !_quitFlag && !skipFlag()) {
+ while (_sound->voiceIsPlaying("KING03") && !quit() && !skipFlag()) {
index = MAX(index, 4);
_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0);
_screen->updateScreen();
uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
- while (waitEnd > _system->getMillis() && !_quitFlag && !skipFlag()) {
+ while (waitEnd > _system->getMillis() && !quit() && !skipFlag()) {
updateInput();
_system->delayMillis(10);
}
@@ -541,10 +537,10 @@ void LoLEngine::processCharacterSelection() {
debugC(9, kDebugLevelMain, "LoLEngine::processCharacterSelection()");
_charSelection = -1;
- while (!_quitFlag && _charSelection == -1) {
+ while (!quit() && _charSelection == -1) {
uint32 nextKingMessage = _system->getMillis() + 900 * _tickLength;
- while (nextKingMessage > _system->getMillis() && _charSelection == -1 && !_quitFlag) {
+ while (nextKingMessage > _system->getMillis() && _charSelection == -1 && !quit()) {
updateSelectionAnims();
_charSelection = getCharSelection();
_system->delayMillis(10);
@@ -663,12 +659,12 @@ void LoLEngine::selectionCharInfoIntro(char *file) {
int index = 0;
file[4] = '0';
- while (_charSelectionInfoResult == -1 && !_quitFlag) {
+ while (_charSelectionInfoResult == -1 && !quit()) {
if (!_sound->voicePlay(file))
break;
int i = 0;
- while (_sound->voiceIsPlaying(file) && _charSelectionInfoResult == -1 && !_quitFlag) {
+ while (_sound->voiceIsPlaying(file) && _charSelectionInfoResult == -1 && !quit()) {
_screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), _charInfoFrameTable[i]), 11, 130, 0, 0);
_screen->updateScreen();
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index 8bed4e57e1..0dc7cf2c02 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -164,7 +164,7 @@ Common::InSaveFile *KyraEngine_v1::openSaveForReading(const char *filename, Save
Common::OutSaveFile *KyraEngine_v1::openSaveForWriting(const char *filename, const char *saveName) const {
debugC(9, kDebugLevelMain, "KyraEngine_v1::openSaveForWriting('%s', '%s')", filename, saveName);
- if (_quitFlag)
+ if (quit())
return 0;
Common::OutSaveFile *out = 0;
diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp
index 8af73acc61..74cf26646c 100644
--- a/engines/kyra/saveload_lok.cpp
+++ b/engines/kyra/saveload_lok.cpp
@@ -221,7 +221,7 @@ void KyraEngine_LoK::loadGame(const char *fileName) {
void KyraEngine_LoK::saveGame(const char *fileName, const char *saveName) {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::saveGame('%s', '%s')", fileName, saveName);
- if (_quitFlag)
+ if (quit())
return;
Common::OutSaveFile *out = openSaveForWriting(fileName, saveName);
diff --git a/engines/kyra/scene_hof.cpp b/engines/kyra/scene_hof.cpp
index 62df683ea2..08df7b064e 100644
--- a/engines/kyra/scene_hof.cpp
+++ b/engines/kyra/scene_hof.cpp
@@ -277,7 +277,7 @@ int KyraEngine_HoF::trySceneChange(int *moveTable, int unk1, int updateChar) {
int changedScene = 0;
const int *moveTableStart = moveTable;
_unk4 = 0;
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (*moveTable >= 0 && *moveTable <= 7) {
_mainCharacter.facing = getOppositeFacingDirection(*moveTable);
unkFlag = true;
diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp
index e4a3a5c54e..716c139129 100644
--- a/engines/kyra/scene_mr.cpp
+++ b/engines/kyra/scene_mr.cpp
@@ -653,7 +653,7 @@ int KyraEngine_MR::trySceneChange(int *moveTable, int unk1, int updateChar) {
const int *moveTableStart = moveTable;
_unk4 = 0;
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (*moveTable >= 0 && *moveTable <= 7) {
_mainCharacter.facing = getOppositeFacingDirection(*moveTable);
unkFlag = true;
diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp
index 9a059ead2a..6dda6c8bd7 100644
--- a/engines/kyra/script_mr.cpp
+++ b/engines/kyra/script_mr.cpp
@@ -786,7 +786,7 @@ int KyraEngine_MR::o3_daggerWarning(EMCState *script) {
_screen->_curPage = curPageBackUp;
_screen->showMouse();
- while (!_quitFlag) {
+ while (!quit()) {
int keys = checkInput(0);
removeInputTop();
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index 635db3629c..b42374f44f 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -75,7 +75,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
_seqEndTime = 0;
_menuChoice = 0;
- for (int seqNum = startSeq; seqNum <= endSeq && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice); seqNum++) {
+ for (int seqNum = startSeq; seqNum <= endSeq && !((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice); seqNum++) {
_screen->clearPage(0);
_screen->clearPage(8);
memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300);
@@ -131,7 +131,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
seq_sequenceCommand(cseq.startupCommand);
- if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ if (!((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_screen->copyPage(2, 0);
_screen->updateScreen();
}
@@ -165,7 +165,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
_seqWsaCurrentFrame = cseq.startFrame;
bool loop = true;
- while (loop && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ while (loop && !((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
if (_seqWsa || !cb)
@@ -189,16 +189,16 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
seq_processWSAs();
seq_processText();
- if ((_seqWsa || !cb) && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ if ((_seqWsa || !cb) && !((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_screen->copyPage(2, 0);
_screen->updateScreen();
}
bool loop2 = true;
- while (loop2 && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ while (loop2 && !((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
if (_seqWsa) {
seq_processText();
- if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ if (!((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_screen->copyPage(2, 0);
_screen->updateScreen();
}
@@ -230,7 +230,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
} else {
_seqFrameDelay = cseq.frameDelay;
_seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
- while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ while (!((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_seqSubFrameStartTime = _system->getMillis();
seq_processWSAs();
if (cb)
@@ -262,7 +262,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
dl = ct;
_seqEndTime = _system->getMillis() + dl;
- while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
+ while (!((skipFlag() && allowSkip) || quit() || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_seqSubFrameStartTime = _system->getMillis();
seq_processWSAs();
@@ -2267,7 +2267,7 @@ void KyraEngine_HoF::seq_loadNestedSequence(int wsaNum, int seqNum) {
void KyraEngine_HoF::seq_nestedSequenceFrame(int command, int wsaNum) {
int xa = 0, ya = 0;
command--;
- if (!_activeWSA[wsaNum].movie || skipFlag() || _quitFlag || _abortIntroFlag)
+ if (!_activeWSA[wsaNum].movie || skipFlag() || quit() || _abortIntroFlag)
return;
switch (command) {
@@ -2467,7 +2467,7 @@ bool KyraEngine_HoF::seq_processNextSubFrame(int wsaNum) {
void KyraEngine_HoF::seq_printCreditsString(uint16 strIndex, int x, int y, const uint8 *colorMap, uint8 textcolor) {
uint8 colormap[16];
- if (skipFlag() || _quitFlag || _abortIntroFlag || _menuChoice)
+ if (skipFlag() || quit() || _abortIntroFlag || _menuChoice)
return;
memset(&_screen->getPalette(0)[0x2fa], 0x3f, 6);
@@ -2954,7 +2954,7 @@ void KyraEngine_HoF::seq_makeBookAppear() {
++_invWsa.curFrame;
- if (_invWsa.curFrame >= _invWsa.lastFrame && !_quitFlag)
+ if (_invWsa.curFrame >= _invWsa.lastFrame && !quit())
break;
switch (_invWsa.curFrame) {
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index 3a497a258f..77cfbed2d0 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -34,7 +34,6 @@
#include "kyra/text.h"
#include "kyra/timer.h"
-#include "common/events.h"
#include "common/system.h"
#include "common/savefile.h"
@@ -164,7 +163,7 @@ void KyraEngine_LoK::seq_introLogos() {
_screen->updateScreen();
_screen->fadeFromBlack();
- if (_seq->playSequence(_seq_WestwoodLogo, _skipFlag) || _quitFlag) {
+ if (_seq->playSequence(_seq_WestwoodLogo, _skipFlag) || quit()) {
_screen->fadeToBlack();
_screen->clearPage(0);
return;
@@ -176,14 +175,14 @@ void KyraEngine_LoK::seq_introLogos() {
_screen->setScreenPalette(_screen->_currentPalette);
}
- if ((_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence()) || _quitFlag) {
+ if ((_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence()) || quit()) {
_screen->fadeToBlack();
_screen->clearPage(0);
return;
}
_screen->fillRect(0, 179, 319, 199, 0);
- if (_quitFlag)
+ if (quit())
return;
if (_flags.platform == Common::kPlatformAmiga) {
@@ -223,10 +222,10 @@ void KyraEngine_LoK::seq_introLogos() {
oldDistance = distance;
delay(10);
- } while (!doneFlag && !_quitFlag && !_abortIntroFlag);
+ } while (!doneFlag && !quit() && !_abortIntroFlag);
}
- if (_quitFlag)
+ if (quit())
return;
_seq->playSequence(_seq_Forest, true);
@@ -1030,7 +1029,7 @@ void KyraEngine_LoK::seq_brandonToStone() {
void KyraEngine_LoK::seq_playEnding() {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playEnding()");
- if (_quitFlag)
+ if (quit())
return;
_screen->hideMouse();
_screen->_curPage = 0;
@@ -1186,8 +1185,8 @@ void KyraEngine_LoK::seq_playCredits() {
case Common::EVENT_KEYDOWN:
finished = true;
break;
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- quitGame();
finished = true;
break;
default:
@@ -1211,7 +1210,7 @@ void KyraEngine_LoK::seq_playCredits() {
bool KyraEngine_LoK::seq_skipSequence() const {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_skipSequence()");
- return _quitFlag || _abortIntroFlag;
+ return quit() || _abortIntroFlag;
}
int KyraEngine_LoK::handleMalcolmFlag() {
diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp
index 34c2986f25..05074d20b1 100644
--- a/engines/kyra/sprites.cpp
+++ b/engines/kyra/sprites.cpp
@@ -28,7 +28,6 @@
#include "common/stream.h"
#include "common/util.h"
#include "common/system.h"
-#include "common/events.h"
#include "kyra/screen.h"
#include "kyra/kyra_lok.h"
#include "kyra/sprites.h"
diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp
index f8eb10a85e..eecb617942 100644
--- a/engines/kyra/text.cpp
+++ b/engines/kyra/text.cpp
@@ -29,7 +29,6 @@
#include "kyra/screen.h"
#include "kyra/text.h"
-#include "common/events.h"
#include "common/system.h"
#include "common/endian.h"
diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp
index dd587c5112..b94b8a6258 100644
--- a/engines/kyra/text_hof.cpp
+++ b/engines/kyra/text_hof.cpp
@@ -335,7 +335,7 @@ void KyraEngine_HoF::objectChatWaitToFinish() {
const uint32 endTime = _chatEndTime;
resetSkipFlag();
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (!_emc->isValid(&_chatScriptState))
_emc->start(&_chatScriptState, 1);
@@ -353,7 +353,7 @@ void KyraEngine_HoF::objectChatWaitToFinish() {
uint32 nextFrame = _system->getMillis() + delayTime * _tickLength;
- while (_system->getMillis() < nextFrame && !_quitFlag) {
+ while (_system->getMillis() < nextFrame && !quit()) {
updateWithText();
const uint32 curTime = _system->getMillis();
@@ -593,7 +593,7 @@ void KyraEngine_HoF::initTalkObject(int index) {
if (_currentTalkSections.STATim) {
_tim->resetFinishedFlag();
- while (!_quitFlag && !_tim->finished()) {
+ while (!quit() && !_tim->finished()) {
_tim->exec(_currentTalkSections.STATim, false);
if (_chatText)
updateWithText();
@@ -609,7 +609,7 @@ void KyraEngine_HoF::deinitTalkObject(int index) {
if (_currentTalkSections.ENDTim) {
_tim->resetFinishedFlag();
- while (!_quitFlag && !_tim->finished()) {
+ while (!quit() && !_tim->finished()) {
_tim->exec(_currentTalkSections.ENDTim, false);
if (_chatText)
updateWithText();
@@ -647,10 +647,10 @@ void KyraEngine_HoF::npcChatSequence(const char *str, int objectId, int vocHigh,
_chatVocHigh = _chatVocLow = -1;
}
- while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || skipFlag())) {
+ while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(quit() || skipFlag())) {
if ((!speechEnabled() && chatAnimEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) {
_tim->resetFinishedFlag();
- while (!_tim->finished() && !skipFlag() && !_quitFlag) {
+ while (!_tim->finished() && !skipFlag() && !quit()) {
if (_currentTalkSections.TLKTim)
_tim->exec(_currentTalkSections.TLKTim, false);
else
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index f6b0407a75..150ec59a23 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -120,8 +120,8 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const
if (event.kbd.keycode == '.')
_skipFlag = true;
break;
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- quitGame();
runLoop = false;
break;
case Common::EVENT_LBUTTONDOWN:
diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp
index 16c56da099..be306ceec1 100644
--- a/engines/kyra/text_mr.cpp
+++ b/engines/kyra/text_mr.cpp
@@ -349,7 +349,7 @@ void KyraEngine_MR::objectChatWaitToFinish() {
const uint32 endTime = _chatEndTime;
resetSkipFlag();
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (!_emc->isValid(&_chatScriptState))
_emc->start(&_chatScriptState, 1);
@@ -367,7 +367,7 @@ void KyraEngine_MR::objectChatWaitToFinish() {
uint32 nextFrame = _system->getMillis() + delayTime * _tickLength;
- while (_system->getMillis() < nextFrame && !_quitFlag) {
+ while (_system->getMillis() < nextFrame && !quit()) {
updateWithText();
const uint32 curTime = _system->getMillis();
@@ -419,7 +419,7 @@ void KyraEngine_MR::badConscienceChatWaitToFinish() {
uint32 nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength;
int frame = _badConscienceFrameTable[_badConscienceAnim+24];
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (nextFrame < _system->getMillis()) {
++frame;
if (_badConscienceFrameTable[_badConscienceAnim+32] < frame)
@@ -477,7 +477,7 @@ void KyraEngine_MR::goodConscienceChatWaitToFinish() {
uint32 nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(3, 6) * _tickLength;
int frame = _goodConscienceFrameTable[_goodConscienceAnim+15];
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (nextFrame < _system->getMillis()) {
++frame;
if (_goodConscienceFrameTable[_goodConscienceAnim+20] < frame)
@@ -597,7 +597,7 @@ void KyraEngine_MR::albumChatWaitToFinish() {
uint32 nextFrame = 0;
int frame = 12;
- while (running && !_quitFlag) {
+ while (running && !quit()) {
if (nextFrame < _system->getMillis()) {
++frame;
if (frame > 22)
diff --git a/engines/kyra/vqa.cpp b/engines/kyra/vqa.cpp
index 3d18f27c7e..c55c573ea3 100644
--- a/engines/kyra/vqa.cpp
+++ b/engines/kyra/vqa.cpp
@@ -32,7 +32,6 @@
// The jung2.vqa movie does work, but only thanks to a grotesque hack.
-#include "common/events.h"
#include "common/system.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
@@ -671,8 +670,8 @@ void VQAMovie::play() {
if (event.kbd.ascii == 27)
return;
break;
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->quitGame();
return;
default:
break;
diff --git a/engines/lure/animseq.cpp b/engines/lure/animseq.cpp
index 2af02b0374..3d5265c90f 100644
--- a/engines/lure/animseq.cpp
+++ b/engines/lure/animseq.cpp
@@ -45,10 +45,11 @@ AnimAbortType AnimationSequence::delay(uint32 milliseconds) {
while (events.pollEvent()) {
if ((events.type() == Common::EVENT_KEYDOWN) && (events.event().kbd.ascii != 0)) {
if (events.event().kbd.keycode == Common::KEYCODE_ESCAPE) return ABORT_END_INTRO;
+ else if (events.event().kbd.keycode == Common::KEYCODE_MAINMENU) return ABORT_NONE;
else return ABORT_NEXT_SCENE;
} else if (events.type() == Common::EVENT_LBUTTONDOWN)
return ABORT_NEXT_SCENE;
- else if (events.type() == Common::EVENT_QUIT)
+ else if ((events.type() == Common::EVENT_QUIT) || (events.type() == Common::EVENT_RTL))
return ABORT_END_INTRO;
}
diff --git a/engines/lure/detection.cpp b/engines/lure/detection.cpp
index 7dd1c77348..8ed2e62760 100644
--- a/engines/lure/detection.cpp
+++ b/engines/lure/detection.cpp
@@ -26,6 +26,7 @@
#include "base/plugins.h"
#include "common/advancedDetector.h"
+#include "common/savefile.h"
#include "lure/lure.h"
@@ -185,6 +186,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
};
bool LureMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
@@ -195,6 +197,34 @@ bool LureMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common
return gd != 0;
}
+SaveStateList LureMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ Common::String saveDesc;
+ Common::String pattern = target;
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ saveDesc = Lure::getSaveName(in);
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc, *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(LURE)
REGISTER_PLUGIN_DYNAMIC(LURE, PLUGIN_TYPE_ENGINE, LureMetaEngine);
#else
diff --git a/engines/lure/events.cpp b/engines/lure/events.cpp
index 30e0e571b7..97da8bdb03 100644
--- a/engines/lure/events.cpp
+++ b/engines/lure/events.cpp
@@ -29,6 +29,7 @@
#include "graphics/cursorman.h"
#include "lure/events.h"
+#include "lure/lure.h"
#include "lure/res.h"
namespace Lure {
@@ -137,11 +138,12 @@ void Mouse::setPosition(int newX, int newY) {
void Mouse::waitForRelease() {
Events &e = Events::getReference();
+ LureEngine &engine = LureEngine::getReference();
do {
- while (e.pollEvent() && !e.quitFlag) ;
+ while (e.pollEvent() && !engine.quit()) ;
g_system->delayMillis(20);
- } while (!e.quitFlag && (lButton() || rButton() || mButton()));
+ } while (!engine.quit() && (lButton() || rButton() || mButton()));
}
/*--------------------------------------------------------------------------*/
@@ -150,7 +152,6 @@ static Events *int_events = NULL;
Events::Events() {
int_events = this;
- quitFlag = false;
}
Events &Events::getReference() {
@@ -163,10 +164,6 @@ bool Events::pollEvent() {
// Handle keypress
switch (_event.type) {
- case Common::EVENT_QUIT:
- quitFlag = true;
- break;
-
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONDOWN:
@@ -190,7 +187,7 @@ void Events::waitForPress() {
bool keyButton = false;
while (!keyButton) {
while (pollEvent()) {
- if (_event.type == Common::EVENT_QUIT) return;
+ if ((_event.type == Common::EVENT_QUIT) || (_event.type == Common::EVENT_RTL)) return;
else if ((_event.type == Common::EVENT_KEYDOWN) && (_event.kbd.ascii != 0))
keyButton = true;
else if ((_event.type == Common::EVENT_LBUTTONDOWN) ||
@@ -210,13 +207,15 @@ void Events::waitForPress() {
bool Events::interruptableDelay(uint32 milliseconds) {
Events &events = Events::getReference();
+ LureEngine &engine = LureEngine::getReference();
uint32 delayCtr = g_system->getMillis() + milliseconds;
while (g_system->getMillis() < delayCtr) {
- if (events.quitFlag) return true;
+ if (engine.quit()) return true;
if (events.pollEvent()) {
- if (((events.type() == Common::EVENT_KEYDOWN) && (events.event().kbd.ascii != 0)) ||
+ if (((events.type() == Common::EVENT_KEYDOWN) && (events.event().kbd.ascii != 0) &&
+ events.event().kbd.keycode != KEYCODE_MAINMENU) ||
(events.type() == Common::EVENT_LBUTTONDOWN))
return true;
}
diff --git a/engines/lure/events.h b/engines/lure/events.h
index d1246f95d8..f04072aa0f 100644
--- a/engines/lure/events.h
+++ b/engines/lure/events.h
@@ -66,8 +66,6 @@ class Events {
private:
Common::Event _event;
public:
- bool quitFlag;
-
Events();
static Events &getReference();
diff --git a/engines/lure/fights.cpp b/engines/lure/fights.cpp
index dcf09ba50d..51fce850e6 100644
--- a/engines/lure/fights.cpp
+++ b/engines/lure/fights.cpp
@@ -22,6 +22,7 @@
#include "lure/fights.h"
#include "lure/luredefs.h"
#include "lure/game.h"
+#include "lure/lure.h"
#include "lure/res.h"
#include "lure/room.h"
#include "lure/sound.h"
@@ -108,15 +109,15 @@ bool FightsManager::isFighting() {
}
void FightsManager::fightLoop() {
+ LureEngine &engine = LureEngine::getReference();
Resources &res = Resources::getReference();
Game &game = Game::getReference();
Room &room = Room::getReference();
- Events &events = Events::getReference();
FighterRecord &playerFight = getDetails(PLAYER_ID);
uint32 timerVal = g_system->getMillis();
// Loop for the duration of the battle
- while (!events.quitFlag && (playerFight.fwhits != GENERAL_MAGIC_ID)) {
+ while (!engine.quit() && (playerFight.fwhits != GENERAL_MAGIC_ID)) {
checkEvents();
if (g_system->getMillis() > timerVal + GAME_FRAME_DELAY) {
@@ -184,6 +185,7 @@ const KeyMapping keyList[] = {
{Common::KEYCODE_INVALID, 0}};
void FightsManager::checkEvents() {
+ LureEngine &engine = LureEngine::getReference();
Game &game = Game::getReference();
Events &events = Events::getReference();
Mouse &mouse = Mouse::getReference();
@@ -196,7 +198,7 @@ void FightsManager::checkEvents() {
if (events.type() == Common::EVENT_KEYDOWN) {
switch (events.event().kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- events.quitFlag = true;
+ engine.quitGame();
return;
case Common::KEYCODE_d:
diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp
index f9b31c21c5..479877f229 100644
--- a/engines/lure/game.cpp
+++ b/engines/lure/game.cpp
@@ -23,10 +23,10 @@
*
*/
-#include "lure/lure.h"
#include "lure/game.h"
#include "lure/animseq.h"
#include "lure/fights.h"
+#include "lure/lure.h"
#include "lure/res_struct.h"
#include "lure/room.h"
#include "lure/scripts.h"
@@ -125,6 +125,7 @@ void Game::nextFrame() {
void Game::execute() {
OSystem &system = *g_system;
+ LureEngine &engine = LureEngine::getReference();
Room &room = Room::getReference();
Resources &res = Resources::getReference();
Events &events = Events::getReference();
@@ -137,12 +138,20 @@ void Game::execute() {
screen.empty();
screen.setPaletteEmpty();
+
+ bool _loadSavegame = false;
+
+ if (engine.gameToLoad() != -1)
+ _loadSavegame = engine.loadGame(engine.gameToLoad());
+
+ if (!_loadSavegame) {
+ // Flag for starting game
+ setState(GS_RESTART);
+ }
- // Flag for starting game
- setState(GS_RESTART);
bool initialRestart = true;
- while (!events.quitFlag) {
+ while (!engine.quit()) {
if ((_state & GS_RESTART) != 0) {
res.reset();
@@ -162,7 +171,7 @@ void Game::execute() {
mouse.cursorOn();
// Main game loop
- while (!events.quitFlag && ((_state & GS_RESTART) == 0)) {
+ while (!engine.quit() && ((_state & GS_RESTART) == 0)) {
// If time for next frame, allow everything to update
if (system.getMillis() > timerVal + GAME_FRAME_DELAY) {
timerVal = system.getMillis();
@@ -291,10 +300,7 @@ void Game::execute() {
if (restartFlag)
setState(GS_RESTART);
-
- } else if ((_state & GS_RESTART) == 0)
- // Exiting game
- events.quitFlag = true;
+ }
}
}
@@ -892,7 +898,7 @@ void Game::doShowCredits() {
void Game::doQuit() {
Sound.pause();
if (getYN())
- Events::getReference().quitFlag = true;
+ LureEngine::getReference().quitGame();
Sound.resume();
}
@@ -977,6 +983,7 @@ bool Game::getYN() {
Events &events = Events::getReference();
Screen &screen = Screen::getReference();
Resources &res = Resources::getReference();
+ LureEngine &engine = LureEngine::getReference();
Common::Language l = LureEngine::getReference().getLanguage();
Common::KeyCode y = Common::KEYCODE_y;
@@ -1018,7 +1025,7 @@ bool Game::getYN() {
}
g_system->delayMillis(10);
- } while (!events.quitFlag && !breakFlag);
+ } while (!engine.quit() && !breakFlag);
screen.update();
if (!vKbdFlag)
diff --git a/engines/lure/game.h b/engines/lure/game.h
index 5054074fb2..06dcee750f 100644
--- a/engines/lure/game.h
+++ b/engines/lure/game.h
@@ -27,6 +27,7 @@
#define LURE_GAME_H
+#include "common/config-manager.h"
#include "engines/engine.h"
#include "lure/luredefs.h"
#include "lure/menu.h"
@@ -85,8 +86,8 @@ public:
bool &debugFlag() { return _debugFlag; }
bool fastTextFlag() { return _fastTextFlag; }
bool soundFlag() { return _soundFlag; }
- uint8 sfxVolume() { return _sfxVolume; }
- uint8 musicVolume() { return _musicVolume; }
+ uint8 sfxVolume() { return ConfMan.getInt("sfx_volume"); }
+ uint8 musicVolume() { return ConfMan.getInt("music_volume"); }
Debugger &debugger() { return *_debugger; }
// Menu item support methods
diff --git a/engines/lure/intro.cpp b/engines/lure/intro.cpp
index 4d3e172dc5..b4cbf4a833 100644
--- a/engines/lure/intro.cpp
+++ b/engines/lure/intro.cpp
@@ -55,17 +55,18 @@ static const AnimRecord anim_screens[] = {
bool Introduction::showScreen(uint16 screenId, uint16 paletteId, uint16 delaySize) {
Screen &screen = Screen::getReference();
- Events &events = Events::getReference();
bool isEGA = LureEngine::getReference().isEGA();
screen.screen().loadScreen(screenId);
screen.update();
Palette p(paletteId);
+ if (LureEngine::getReference().quit()) return true;
+
if (isEGA) screen.setPalette(&p);
else screen.paletteFadeIn(&p);
bool result = interruptableDelay(delaySize);
- if (events.quitFlag) return true;
+ if (LureEngine::getReference().quit()) return true;
if (!isEGA)
screen.paletteFadeOut();
@@ -83,6 +84,8 @@ bool Introduction::interruptableDelay(uint32 milliseconds) {
if (events.interruptableDelay(milliseconds)) {
if (events.type() == Common::EVENT_KEYDOWN)
return events.event().kbd.keycode == 27;
+ else if (LureEngine::getReference().quit())
+ return true;
else if (events.type() == Common::EVENT_LBUTTONDOWN)
return false;
}
diff --git a/engines/lure/lure.cpp b/engines/lure/lure.cpp
index ea760ddb4f..335f3384a1 100644
--- a/engines/lure/lure.cpp
+++ b/engines/lure/lure.cpp
@@ -92,6 +92,7 @@ int LureEngine::init() {
_room = new Room();
_fights = new FightsManager();
+ _gameToLoad = -1;
_initialised = true;
return 0;
}
@@ -121,38 +122,45 @@ LureEngine &LureEngine::getReference() {
}
int LureEngine::go() {
-
- if (ConfMan.getBool("copy_protection")) {
- CopyProtectionDialog *dialog = new CopyProtectionDialog();
- bool result = dialog->show();
- delete dialog;
- if (_events->quitFlag)
- return 0;
-
- if (!result)
- error("Sorry - copy protection failed");
- }
-
Game *gameInstance = new Game();
+
+ // If requested, load a savegame instead of showing the intro
+ if (ConfMan.hasKey("save_slot")) {
+ _gameToLoad = ConfMan.getInt("save_slot");
+ if (_gameToLoad < 0 || _gameToLoad > 999)
+ _gameToLoad = -1;
+ }
+
+ if (_gameToLoad == -1) {
+ if (ConfMan.getBool("copy_protection")) {
+ CopyProtectionDialog *dialog = new CopyProtectionDialog();
+ bool result = dialog->show();
+ delete dialog;
+ if (quit())
+ return _eventMan->shouldRTL();
+
+ if (!result)
+ error("Sorry - copy protection failed");
+ }
- if (ConfMan.getInt("boot_param") == 0) {
- // Show the introduction
- Sound.loadSection(Sound.isRoland() ? ROLAND_INTRO_SOUND_RESOURCE_ID : ADLIB_INTRO_SOUND_RESOURCE_ID);
-
- Introduction *intro = new Introduction();
- intro->show();
- delete intro;
+ if (ConfMan.getInt("boot_param") == 0) {
+ // Show the introduction
+ Sound.loadSection(Sound.isRoland() ? ROLAND_INTRO_SOUND_RESOURCE_ID : ADLIB_INTRO_SOUND_RESOURCE_ID);
+ Introduction *intro = new Introduction();
+ intro->show();
+ delete intro;
+ }
}
// Play the game
- if (!_events->quitFlag) {
+ if (!quit()) {
// Play the game
Sound.loadSection(Sound.isRoland() ? ROLAND_MAIN_SOUND_RESOURCE_ID : ADLIB_MAIN_SOUND_RESOURCE_ID);
gameInstance->execute();
}
delete gameInstance;
- return 0;
+ return _eventMan->shouldRTL();
}
void LureEngine::pauseEngineIntern(bool pause) {
@@ -246,6 +254,10 @@ void LureEngine::GUIError(const char *msg, ...) {
Engine::GUIErrorMessage(buffer);
}
+void LureEngine::syncSoundSettings() {
+ Sound.syncSounds();
+}
+
Common::String *LureEngine::detectSave(int slotNumber) {
Common::ReadStream *f = this->_saveFileMan->openForLoading(
generateSaveName(slotNumber));
@@ -274,4 +286,23 @@ Common::String *LureEngine::detectSave(int slotNumber) {
return result;
}
+Common::String getSaveName(Common::InSaveFile *in) {
+ // Check for header
+ char saveName[MAX_DESC_SIZE];
+ char buffer[5];
+ in->read(&buffer[0], 5);
+ if (memcmp(&buffer[0], "lure", 5) == 0) {
+ // Check language version
+ in->readByte();
+ in->readByte();
+ char *p = saveName;
+ int decCtr = MAX_DESC_SIZE - 1;
+ while ((decCtr > 0) && ((*p++ = in->readByte()) != 0)) --decCtr;
+ *p = '\0';
+
+ }
+
+ return Common::String(saveName);
+}
+
} // End of namespace Lure
diff --git a/engines/lure/lure.h b/engines/lure/lure.h
index 1c5b40e54b..2c1a70329e 100644
--- a/engines/lure/lure.h
+++ b/engines/lure/lure.h
@@ -30,6 +30,7 @@
#include "common/rect.h"
#include "sound/mixer.h"
#include "common/file.h"
+#include "common/savefile.h"
#include "lure/disk.h"
#include "lure/res.h"
@@ -47,6 +48,7 @@ struct LureGameDescription;
class LureEngine : public Engine {
private:
bool _initialised;
+ int _gameToLoad;
uint8 _saveVersion;
Disk *_disk;
Resources *_resources;
@@ -70,9 +72,11 @@ public:
virtual int init();
virtual int go();
virtual void pauseEngineIntern(bool pause);
+ virtual void syncSoundSettings();
Disk &disk() { return *_disk; }
+ int gameToLoad() { return _gameToLoad; }
bool loadGame(uint8 slotNumber);
bool saveGame(uint8 slotNumber, Common::String &caption);
Common::String *detectSave(int slotNumber);
@@ -84,7 +88,7 @@ public:
Common::Platform getPlatform() const;
bool isEGA() const { return (getFeatures() & GF_EGA) != 0; }
};
-
+ Common::String getSaveName(Common::InSaveFile *in);
} // End of namespace Lure
#endif
diff --git a/engines/lure/menu.cpp b/engines/lure/menu.cpp
index 0b4ef06081..562f54da20 100644
--- a/engines/lure/menu.cpp
+++ b/engines/lure/menu.cpp
@@ -116,6 +116,7 @@ Menu &Menu::getReference() {
uint8 Menu::execute() {
OSystem &system = *g_system;
+ LureEngine &engine = LureEngine::getReference();
Mouse &mouse = Mouse::getReference();
Events &events = Events::getReference();
Screen &screen = Screen::getReference();
@@ -130,7 +131,7 @@ uint8 Menu::execute() {
while (mouse.lButton() || mouse.rButton()) {
while (events.pollEvent()) {
- if (events.quitFlag) return MENUITEM_NONE;
+ if (engine.quit()) return MENUITEM_NONE;
if (mouse.y() < MENUBAR_Y_SIZE) {
MenuRecord *p = getMenuAt(mouse.x());
@@ -467,6 +468,7 @@ Action PopupMenu::Show(int numEntries, Action *actions) {
uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
if (numEntries == 0) return 0xffff;
+ LureEngine &engine = LureEngine::getReference();
Events &e = Events::getReference();
Mouse &mouse = Mouse::getReference();
OSystem &system = *g_system;
@@ -545,7 +547,7 @@ uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
}
while (e.pollEvent()) {
- if (e.quitFlag) {
+ if (engine.quit()) {
selectedIndex = 0xffff;
goto bail_out;
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index 7490f05b24..495f8046bb 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -26,6 +26,7 @@
#include "lure/animseq.h"
#include "lure/fights.h"
#include "lure/game.h"
+#include "lure/lure.h"
#include "lure/res.h"
#include "lure/room.h"
#include "lure/screen.h"
@@ -190,6 +191,7 @@ void Script::addSound(uint16 soundIndex, uint16 v2, uint16 v3) {
}
void Script::endgameSequence(uint16 v1, uint16 v2, uint16 v3) {
+ LureEngine &engine = LureEngine::getReference();
Screen &screen = Screen::getReference();
Mouse &mouse = Mouse::getReference();
Events &events = Events::getReference();
@@ -219,7 +221,7 @@ void Script::endgameSequence(uint16 v1, uint16 v2, uint16 v3) {
anim->show();
if (!events.interruptableDelay(30000)) {
// No key yet pressed, so keep waiting
- while (Sound.musicInterface_CheckPlaying(6) && !events.quitFlag) {
+ while (Sound.musicInterface_CheckPlaying(6) && !engine.quit()) {
if (events.interruptableDelay(20))
break;
}
@@ -227,7 +229,7 @@ void Script::endgameSequence(uint16 v1, uint16 v2, uint16 v3) {
delete anim;
screen.paletteFadeOut();
- events.quitFlag = true;
+ engine.quitGame();
}
// Setup the pig fight in the cave
diff --git a/engines/lure/sound.cpp b/engines/lure/sound.cpp
index 285f66e4e2..a0fbcdbac2 100644
--- a/engines/lure/sound.cpp
+++ b/engines/lure/sound.cpp
@@ -220,10 +220,12 @@ void SoundManager::addSound(uint8 soundIndex, bool tidyFlag) {
newEntry->channel = channelCtr;
newEntry->numChannels = numChannels;
newEntry->flags = rec.flags;
+
if (_isRoland)
newEntry->volume = rec.volume;
else /* resource volumes do not seem to work well with our adlib emu */
newEntry->volume = 240; /* 255 causes clipping with adlib */
+
_activeSounds.push_back(SoundList::value_type(newEntry));
musicInterface_Play(rec.soundNumber, channelCtr, numChannels);
@@ -280,6 +282,23 @@ uint8 SoundManager::descIndexOf(uint8 soundNumber) {
return 0xff; // Couldn't find entry
}
+// Used to sync the volume for all channels with the Config Manager
+//
+void SoundManager::syncSounds() {
+ Game &game = Game::getReference();
+ musicInterface_TidySounds();
+
+ g_system->lockMutex(_soundMutex);
+ MusicListIterator i;
+ for (i = _playingSounds.begin(); i != _playingSounds.end(); ++i) {
+ if ((*i)->isMusic())
+ (*i)->setVolume(game.musicVolume());
+ else
+ (*i)->setVolume(game.sfxVolume());
+ }
+ g_system->unlockMutex(_soundMutex);
+}
+
SoundDescResource *SoundManager::findSound(uint8 soundNumber) {
debugC(ERROR_BASIC, kLureDebugSounds, "SoundManager::findSound soundNumber=%d", soundNumber);
SoundListIterator i;
@@ -404,7 +423,7 @@ void SoundManager::musicInterface_Play(uint8 soundNumber, uint8 channelNumber, u
bool isMusic = (soundNumber & 0x80) != 0;
uint8 volume = isMusic ? game.musicVolume() : game.sfxVolume();
- if (!game.soundFlag() || (volume == 0))
+ if (!game.soundFlag())
// Don't play sounds if sound is turned off
return;
@@ -563,12 +582,12 @@ void SoundManager::doTimer() {
/*------------------------------------------------------------------------*/
MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
- uint8 channelNum, uint8 soundNum, bool isMusic, uint8 numChannels, void *soundData, uint32 size) {
+ uint8 channelNum, uint8 soundNum, bool isMus, uint8 numChannels, void *soundData, uint32 size) {
_driver = driver;
_channels = channels;
_soundNumber = soundNum;
_channelNumber = channelNum;
- _isMusic = isMusic;
+ _isMusic = isMus;
_numChannels = numChannels;
_volume = 0;
@@ -576,7 +595,11 @@ MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
/* 90 is power on default for midi compliant devices */
_channels[_channelNumber + i].volume = 90;
}
- setVolume(240); /* 255 causes clipping with mastervol 192 and adlib */
+
+ if (_isMusic)
+ setVolume(ConfMan.getInt("music_volume"));
+ else
+ setVolume(ConfMan.getInt("sfx_volume"));
_passThrough = false;
diff --git a/engines/lure/sound.h b/engines/lure/sound.h
index c5a31a6c28..cf5dca7e96 100644
--- a/engines/lure/sound.h
+++ b/engines/lure/sound.h
@@ -66,7 +66,7 @@ private:
public:
MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
- uint8 channelNum, uint8 soundNum, bool isMusic, uint8 numChannels, void *soundData, uint32 size);
+ uint8 channelNum, uint8 soundNum, bool isMus, uint8 numChannels, void *soundData, uint32 size);
~MidiMusic();
void setVolume(int volume);
int getVolume() { return _volume; }
@@ -98,6 +98,7 @@ public:
uint8 channelNumber() { return _channelNumber; }
uint8 soundNumber() { return _soundNumber; }
bool isPlaying() { return _isPlaying; }
+ bool isMusic() {return _isMusic; }
};
class SoundManager: public Common::Singleton<SoundManager> {
@@ -142,6 +143,7 @@ public:
void stopSound(uint8 soundIndex);
void killSound(uint8 soundNumber);
void setVolume(uint8 soundNumber, uint8 volume);
+ void syncSounds();
void tidySounds();
uint8 descIndexOf(uint8 soundNumber);
SoundDescResource *findSound(uint8 soundNumber);
diff --git a/engines/lure/surface.cpp b/engines/lure/surface.cpp
index 64394545d1..23cc9043cf 100644
--- a/engines/lure/surface.cpp
+++ b/engines/lure/surface.cpp
@@ -506,6 +506,7 @@ Surface *Surface::getScreen(uint16 resourceId) {
bool Surface::getString(Common::String &line, int maxSize, bool isNumeric, bool varLength, int16 x, int16 y) {
OSystem &system = *g_system;
+ LureEngine &engine = LureEngine::getReference();
Mouse &mouse = Mouse::getReference();
Events &events = Events::getReference();
Screen &screen = Screen::getReference();
@@ -533,7 +534,7 @@ bool Surface::getString(Common::String &line, int maxSize, bool isNumeric, bool
// Loop until the input string changes
refreshFlag = false;
while (!refreshFlag && !abortFlag) {
- abortFlag = events.quitFlag;
+ abortFlag = engine.quit();
if (abortFlag) break;
while (events.pollEvent()) {
@@ -975,7 +976,7 @@ bool SaveRestoreDialog::show(bool saveDialog) {
// Provide highlighting of lines to select a save slot
while (!abortFlag && !(mouse.lButton() && (selectedLine != -1))
&& !mouse.rButton() && !mouse.mButton()) {
- abortFlag = events.quitFlag;
+ abortFlag = engine.quit();
if (abortFlag) break;
while (events.pollEvent()) {
@@ -1178,7 +1179,7 @@ bool RestartRestoreDialog::show() {
// Event loop for making selection
bool buttonPressed = false;
- while (!events.quitFlag) {
+ while (!engine.quit()) {
// Handle events
while (events.pollEvent()) {
if ((events.type() == Common::EVENT_LBUTTONDOWN) && (highlightedButton != -1)) {
@@ -1230,7 +1231,7 @@ bool RestartRestoreDialog::show() {
Sound.killSounds();
- if (!restartFlag && !events.quitFlag) {
+ if (!restartFlag && !engine.quit()) {
// Need to show Restore game dialog
if (!SaveRestoreDialog::show(false))
// User cancelled, so fall back on Restart
@@ -1299,6 +1300,7 @@ bool CopyProtectionDialog::show() {
Screen &screen = Screen::getReference();
Events &events = Events::getReference();
Common::RandomSource rnd;
+ LureEngine &engine = LureEngine::getReference();
screen.setPaletteEmpty();
Palette p(COPY_PROTECTION_RESOURCE_ID - 1);
@@ -1349,7 +1351,7 @@ bool CopyProtectionDialog::show() {
// Clear any prior try
_charIndex = 0;
- while (!events.quitFlag) {
+ while (!engine.quit()) {
while (events.pollEvent() && (_charIndex < 4)) {
if (events.type() == Common::EVENT_KEYDOWN) {
if ((events.event().kbd.keycode == Common::KEYCODE_BACKSPACE) && (_charIndex > 0)) {
@@ -1383,7 +1385,7 @@ bool CopyProtectionDialog::show() {
break;
}
- if (events.quitFlag)
+ if (engine.quit())
return false;
// At this point, two page numbers have been entered - validate them
diff --git a/engines/module.mk b/engines/module.mk
index 6cfe9b36fa..f7dd71f403 100644
--- a/engines/module.mk
+++ b/engines/module.mk
@@ -1,7 +1,7 @@
MODULE := engines
MODULE_OBJS := \
- engine.o
-
+ engine.o \
+ dialogs.o
# Include common rules
include $(srcdir)/rules.mk
diff --git a/engines/parallaction/detection.cpp b/engines/parallaction/detection.cpp
index 0476b01454..531bd8ee16 100644
--- a/engines/parallaction/detection.cpp
+++ b/engines/parallaction/detection.cpp
@@ -244,6 +244,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
};
bool ParallactionMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
@@ -265,6 +266,34 @@ bool ParallactionMetaEngine::createInstance(OSystem *syst, Engine **engine, cons
return res;
}
+SaveStateList ParallactionMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ char saveDesc[200];
+ Common::String pattern = target;
+ pattern += ".0??";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 0 && slotNum <= 99) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ in->readLine(saveDesc, 199);
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc, *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(PARALLACTION)
REGISTER_PLUGIN_DYNAMIC(PARALLACTION, PLUGIN_TYPE_ENGINE, ParallactionMetaEngine);
#else
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index 21584a0525..4f2343be64 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -289,6 +289,9 @@ int16 DialogueManager::selectAnswerN() {
_vm->_balloonMan->setBalloonText(_oldSelection, _q->_answers[_visAnswers[_oldSelection]]->_text, 3);
}
+ if (_vm->quit())
+ return -1;
+
if (_selection != -1) {
_vm->_balloonMan->setBalloonText(_selection, _q->_answers[_visAnswers[_selection]]->_text, 0);
_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[_selection]]->_mood & 0xF);
@@ -362,7 +365,6 @@ void DialogueManager::nextQuestion() {
}
}
-
void DialogueManager::run() {
// cache event data
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index 99a492863b..2235c4e98e 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -312,7 +312,8 @@ DECLARE_COMMAND_OPCODE(drop){
DECLARE_COMMAND_OPCODE(quit) {
- _engineFlags |= kEngineQuit;
+ _vm->_quit = true;
+ _vm->quitGame();
}
@@ -442,11 +443,15 @@ void CommandExec::runList(CommandList::iterator first, CommandList::iterator las
_ctxt.suspend = false;
for ( ; first != last; first++) {
- if (_engineFlags & kEngineQuit)
+
+ if (_vm->quit())
break;
CommandPtr cmd = *first;
+ if (_vm->quit())
+ break;
+
if (cmd->_flagsOn & kFlagsGlobal) {
useFlags = _commandFlags | kFlagsGlobal;
useLocalFlags = false;
@@ -628,7 +633,7 @@ uint16 Parallaction::runZone(ZonePtr z) {
break;
case kZoneHear:
- _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60);
+ _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping);
break;
case kZoneSpeak:
diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp
index 3315433762..4343a982bf 100644
--- a/engines/parallaction/gui_br.cpp
+++ b/engines/parallaction/gui_br.cpp
@@ -166,8 +166,9 @@ class MainMenuInputState_BR : public MenuInputState {
void performChoice(int selectedItem) {
switch (selectedItem) {
- case kMenuQuit:
- _engineFlags |= kEngineQuit;
+ case kMenuQuit: {
+ _vm->quitGame();
+ }
break;
case kMenuLoadGame:
diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp
index 815c27bd1c..942f2fd553 100644
--- a/engines/parallaction/gui_ns.cpp
+++ b/engines/parallaction/gui_ns.cpp
@@ -701,7 +701,7 @@ public:
}
if (_isDemo) {
- _engineFlags |= kEngineQuit;
+ _vm->quitGame();
return 0;
}
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
index 287618e803..19747c007e 100644
--- a/engines/parallaction/input.cpp
+++ b/engines/parallaction/input.cpp
@@ -78,9 +78,9 @@ void Input::readInput() {
case Common::EVENT_MOUSEMOVE:
_mousePos = e.mouse;
break;
-
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _engineFlags |= kEngineQuit;
+ _vm->_quit = true;
return;
default:
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index bb306c3299..6a61087804 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -118,12 +118,15 @@ int Parallaction::init() {
_location._hasSound = false;
_baseTime = 0;
_numLocations = 0;
+ _gameToLoad = -1;
_location._startPosition.x = -1000;
_location._startPosition.y = -1000;
_location._startFrame = 0;
_location._comment = NULL;
_location._endComment = NULL;
+ _quit = false;
+
_pathBuffer = 0;
_screenSize = _screenWidth * _screenHeight;
@@ -143,6 +146,7 @@ int Parallaction::init() {
_menuHelper = 0;
setupBalloonManager();
+ syncSoundSettings();
return 0;
}
@@ -309,6 +313,7 @@ void Parallaction::processInput(InputData *data) {
}
switch (data->_event) {
+
case kEvSaveGame:
_input->stopHovering();
saveGame();
@@ -329,18 +334,21 @@ void Parallaction::processInput(InputData *data) {
void Parallaction::runGame() {
InputData *data = _input->updateInput();
- if (_engineFlags & kEngineQuit)
+ if (_vm->quit())
return;
runGuiFrame();
runDialogueFrame();
runCommentFrame();
+ if (_vm->quit())
+ return;
+
if (_input->_inputMode == Input::kInputModeGame) {
processInput(data);
runPendingZones();
- if (_engineFlags & kEngineQuit)
+ if (_vm->quit())
return;
if (_engineFlags & kEngineChangeLocation) {
@@ -443,7 +451,7 @@ ZonePtr Parallaction::findZone(const char *name) {
void Parallaction::freeZones() {
- debugC(2, kDebugExec, "freeZones: kEngineQuit = %i", _engineFlags & kEngineQuit);
+ debugC(2, kDebugExec, "freeZones: _vm->_quit = %i", _vm->_quit);
ZoneList::iterator it = _location._zones.begin();
@@ -452,7 +460,7 @@ void Parallaction::freeZones() {
// NOTE : this condition has been relaxed compared to the original, to allow the engine
// to retain special - needed - zones that were lost across location switches.
ZonePtr z = *it;
- if (((z->_top == -1) || (z->_left == -2)) && ((_engineFlags & kEngineQuit) == 0)) {
+ if (((z->_top == -1) || (z->_left == -2)) && ((_vm->_quit) == 0)) {
debugC(2, kDebugExec, "freeZones preserving zone '%s'", z->_name);
it++;
} else {
@@ -466,6 +474,11 @@ void Parallaction::freeZones() {
return;
}
+void Parallaction::syncSoundSettings() {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume") / 6);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+}
enum {
WALK_LEFT = 0,
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index e5c5221414..2a32904d63 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -99,7 +99,6 @@ enum {
};
enum EngineFlags {
- kEngineQuit = (1 << 0),
kEnginePauseJobs = (1 << 1),
kEngineWalking = (1 << 3),
kEngineChangeLocation = (1 << 4),
@@ -254,6 +253,11 @@ public:
virtual bool loadGame() = 0;
virtual bool saveGame() = 0;
+ bool _quit; /* The only reason this flag exists is for freeZones() to properly
+ * delete all zones when necessary. THIS FLAG IS NOT THE ENGINE QUIT FLAG,
+ * use _eventMan->shouldQuit() for that.
+ */
+
Input *_input;
void processInput(InputData* data);
@@ -261,6 +265,8 @@ public:
void pauseJobs();
void resumeJobs();
+ virtual void syncSoundSettings();
+
ZonePtr findZone(const char *name);
ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
uint16 runZone(ZonePtr z);
@@ -332,6 +338,7 @@ protected: // data
uint32 _baseTime;
char _characterName1[50]; // only used in changeCharacter
+ int _gameToLoad;
Common::String _saveFileName;
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index 761c8d1b74..f4329edf74 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -141,12 +141,12 @@ int Parallaction_br::go() {
startGui();
}
- while ((_engineFlags & kEngineQuit) == 0) {
+ while (quit() == 0) {
// initCharacter();
_input->_inputMode = Input::kInputModeGame;
- while ((_engineFlags & (kEngineReturn | kEngineQuit)) == 0) {
+ while (((_engineFlags & kEngineReturn) == 0) && (!quit())) {
runGame();
}
_engineFlags &= ~kEngineReturn;
@@ -156,7 +156,7 @@ int Parallaction_br::go() {
}
- return 0;
+ return _eventMan->shouldRTL();
}
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index e81492e655..076df92085 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -28,6 +28,7 @@
#include "common/config-manager.h"
#include "parallaction/parallaction.h"
+#include "parallaction/gui.h"
#include "parallaction/input.h"
#include "parallaction/sound.h"
@@ -219,14 +220,32 @@ int Parallaction_ns::go() {
renameOldSavefiles();
_globalTable = _disk->loadTable("global");
-
+/*
+ // If requested, load a savegame instead of showing the intro
+ if (ConfMan.hasKey("save_slot")) {
+ _gameToLoad = ConfMan.getInt("save_slot");
+ if (_gameToLoad < 0 || _gameToLoad > 99)
+ _gameToLoad = -1;
+ }
+ if (_gameToLoad == -1) {
+ startGui();
+ } else {
+ _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
+
+ _menuHelper = new MenuInputHelper;
+ assert(_menuHelper);
+
+ new ChooseLanguageInputState_NS(this, _menuHelper);
+ doLoadGame(_gameToLoad);
+ }
+*/
startGui();
- while ((_engineFlags & kEngineQuit) == 0) {
+ while (!quit()) {
runGame();
}
- return 0;
+ return _eventMan->shouldRTL();
}
void Parallaction_ns::switchBackground(const char* background, const char* mask) {
@@ -444,13 +463,13 @@ void Parallaction_ns::cleanupGame() {
memset(_locationNames, 0, sizeof(_locationNames));
// this flag tells freeZones to unconditionally remove *all* Zones
- _engineFlags |= kEngineQuit;
+ _vm->_quit = true;
freeZones();
freeAnimations();
// this dangerous flag can now be cleared
- _engineFlags &= ~kEngineQuit;
+ _vm->_quit = false;
// main character animation is restored
_location._animations.push_front(_char._ani);
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 002295315d..86700d6bb1 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -132,11 +132,13 @@ void Parallaction_ns::doLoadGame(uint16 slot) {
// TODO (LIST): unify (and parametrize) calls to freeZones.
// We aren't calling freeAnimations because it is not needed, since
// kChangeLocation will trigger a complete deletion. Anyway, we still
- // need to invoke freeZones here with kEngineQuit set, because the
+ // need to invoke freeZones here with _quit set, because the
// call in changeLocation preserve certain zones.
- _engineFlags |= kEngineQuit;
+ _quit = true;
+
freeZones();
- _engineFlags &= ~kEngineQuit;
+
+ _quit = false;
_numLocations = atoi(s);
diff --git a/engines/parallaction/sound.cpp b/engines/parallaction/sound.cpp
index df6867a90c..4ac1399c3a 100644
--- a/engines/parallaction/sound.cpp
+++ b/engines/parallaction/sound.cpp
@@ -387,7 +387,8 @@ void AmigaSoundMan::playSfx(const char *filename, uint channel, bool looping, in
rate = ch->header.samplesPerSec;
}
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize, rate, flags, -1, volume, 0, loopStart, loopEnd);
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize, rate, flags, -1,
+ Audio::Mixer::kMaxChannelVolume, 0, loopStart, loopEnd);
}
void AmigaSoundMan::stopSfx(uint channel) {
diff --git a/engines/queen/input.cpp b/engines/queen/input.cpp
index 9f03c341c9..84e21fbcaa 100644
--- a/engines/queen/input.cpp
+++ b/engines/queen/input.cpp
@@ -118,9 +118,10 @@ void Input::delay(uint amount) {
case Common::EVENT_RBUTTONDOWN:
_mouseButton |= MOUSE_RBUTTON;
break;
-
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->quitGame();
+ if (_cutawayRunning)
+ _cutawayQuit = true;
return;
default:
diff --git a/engines/queen/journal.cpp b/engines/queen/journal.cpp
index 0327fb74b8..ead759cdb6 100644
--- a/engines/queen/journal.cpp
+++ b/engines/queen/journal.cpp
@@ -84,8 +84,8 @@ void Journal::use() {
case Common::EVENT_WHEELDOWN:
handleMouseWheel(1);
break;
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->quitGame();
return;
default:
break;
diff --git a/engines/queen/logic.cpp b/engines/queen/logic.cpp
index 9e4770553c..7fcc761018 100644
--- a/engines/queen/logic.cpp
+++ b/engines/queen/logic.cpp
@@ -2076,6 +2076,8 @@ bool LogicDemo::changeToSpecialRoom() {
displayRoom(currentRoom(), RDM_FADE_NOJOE, 100, 2, true);
playCutaway("CLOGO.CUT");
sceneReset();
+ if (_vm->quit())
+ return true;
currentRoom(ROOM_HOTEL_LOBBY);
entryObj(584);
displayRoom(currentRoom(), RDM_FADE_JOE, 100, 2, true);
@@ -2129,7 +2131,11 @@ bool LogicGame::changeToSpecialRoom() {
} else if (currentRoom() == FOTAQ_LOGO && gameState(VAR_INTRO_PLAYED) == 0) {
displayRoom(currentRoom(), RDM_FADE_NOJOE, 100, 2, true);
playCutaway("COPY.CUT");
+ if (_vm->quit())
+ return true;
playCutaway("CLOGO.CUT");
+ if (_vm->quit())
+ return true;
if (_vm->resource()->getPlatform() != Common::kPlatformAmiga) {
if (ConfMan.getBool("alt_intro") && _vm->resource()->isCD()) {
playCutaway("CINTR.CUT");
@@ -2137,7 +2143,11 @@ bool LogicGame::changeToSpecialRoom() {
playCutaway("CDINT.CUT");
}
}
+ if (_vm->quit())
+ return true;
playCutaway("CRED.CUT");
+ if (_vm->quit())
+ return true;
_vm->display()->palSetPanel();
sceneReset();
currentRoom(ROOM_HOTEL_LOBBY);
diff --git a/engines/queen/midiadlib.cpp b/engines/queen/midiadlib.cpp
index 155bb66716..200c7282f9 100644
--- a/engines/queen/midiadlib.cpp
+++ b/engines/queen/midiadlib.cpp
@@ -132,7 +132,7 @@ int AdlibMidiDriver::open() {
adlibSetNoteVolume(i, 0);
adlibTurnNoteOff(i);
}
- _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
return 0;
}
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index c95e44b477..593597ce12 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -63,6 +63,7 @@ public:
virtual GameList getSupportedGames() const;
virtual GameDescriptor findGame(const char *gameid) const;
virtual GameList detectGames(const FSList &fslist) const;
+ virtual SaveStateList listSaves(const char *target) const;
virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
};
@@ -121,6 +122,36 @@ GameList QueenMetaEngine::detectGames(const FSList &fslist) const {
return detectedGames;
}
+SaveStateList QueenMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ char saveDesc[32];
+ Common::String pattern = target;
+ pattern += ".s??";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 0 && slotNum <= 99) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ for (int i = 0; i < 4; i++)
+ in->readUint32BE();
+ in->read(saveDesc, 32);
+ saveList.push_back(SaveStateDescriptor(slotNum, Common::String(saveDesc), *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
PluginError QueenMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(engine);
*engine = new Queen::QueenEngine(syst);
@@ -180,6 +211,10 @@ void QueenEngine::checkOptionSettings() {
}
}
+void QueenEngine::syncSoundSettings() {
+ readOptionSettings();
+}
+
void QueenEngine::readOptionSettings() {
_sound->setVolume(ConfMan.getInt("music_volume"));
_sound->musicToggle(!ConfMan.getBool("music_mute"));
@@ -381,8 +416,8 @@ int QueenEngine::go() {
loadGameState(ConfMan.getInt("save_slot"));
}
_lastSaveTime = _lastUpdateTime = _system->getMillis();
- _quit = false;
- while (!_quit) {
+
+ while (!quit()) {
if (_logic->newRoom() > 0) {
_logic->update();
_logic->oldRoom(_logic->currentRoom());
@@ -400,7 +435,7 @@ int QueenEngine::go() {
update(true);
}
}
- return 0;
+ return _eventMan->shouldRTL();
}
int QueenEngine::init() {
@@ -428,10 +463,6 @@ int QueenEngine::init() {
_logic = new LogicGame(this);
}
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
- // Set mixer music volume to maximum, since music volume is regulated by MusicPlayer's MIDI messages
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume);
-
_sound = Sound::makeSoundInstance(_mixer, this, _resource->getCompression());
_walk = new Walk(this);
//_talkspeedScale = (MAX_TEXT_SPEED - MIN_TEXT_SPEED) / 255.0;
diff --git a/engines/queen/queen.h b/engines/queen/queen.h
index 1eea43e882..66931e037d 100644
--- a/engines/queen/queen.h
+++ b/engines/queen/queen.h
@@ -97,13 +97,13 @@ public:
void checkOptionSettings();
void readOptionSettings();
void writeOptionSettings();
+ virtual void syncSoundSettings();
int talkSpeed() const { return _talkSpeed; }
void talkSpeed(int speed) { _talkSpeed = speed; }
bool subtitles() const { return _subtitles; }
void subtitles(bool enable) { _subtitles = enable; }
- void quitGame() { _quit = true; }
-
+
void update(bool checkPlayerInput = false);
bool canLoadOrSave() const;
@@ -137,7 +137,6 @@ protected:
int _talkSpeed;
bool _subtitles;
- bool _quit;
uint32 _lastSaveTime;
uint32 _lastUpdateTime;
diff --git a/engines/queen/sound.cpp b/engines/queen/sound.cpp
index 27cf1bf6a2..6513a92018 100644
--- a/engines/queen/sound.cpp
+++ b/engines/queen/sound.cpp
@@ -261,8 +261,6 @@ void PCSound::playSpeech(const char *base) {
void PCSound::setVolume(int vol) {
Sound::setVolume(vol);
- // Set mixer music volume to maximum, since music volume is regulated by MusicPlayer's MIDI messages
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume);
_music->setVolume(vol);
}
@@ -316,7 +314,10 @@ void SBSound::playSoundData(Common::File *f, uint32 size, Audio::SoundHandle *so
if (sound) {
f->read(sound, size);
byte flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, soundHandle, sound, size, 11840, flags);
+ if (soundHandle == &_speechHandle)
+ _mixer->playRaw(Audio::Mixer::kSpeechSoundType, soundHandle, sound, size, 11025, flags);
+ else
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, soundHandle, sound, size, 11025, flags);
}
}
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index ff18ef37d1..fa2ca669cd 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -807,7 +807,7 @@ void Talk::speakSegment(
switch (command) {
case SPEAK_PAUSE:
- for (i = 0; i < 10 && !_vm->input()->talkQuit(); i++) {
+ for (i = 0; i < 10 && !_vm->input()->talkQuit() && !_vm->quit(); i++) {
_vm->update();
}
return;
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 9c897d8ebc..3ed3882b06 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -148,6 +148,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
};
bool SagaMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
@@ -158,6 +159,36 @@ bool SagaMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common
return gd != 0;
}
+SaveStateList SagaMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ char saveDesc[SAVE_TITLE_SIZE];
+ Common::String pattern = target;
+ pattern += ".s??";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 0 && slotNum <= 99) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ for (int i = 0; i < 3; i++)
+ in->readUint32BE();
+ in->read(saveDesc, SAVE_TITLE_SIZE);
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc, *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(SAGA)
REGISTER_PLUGIN_DYNAMIC(SAGA, PLUGIN_TYPE_ENGINE, SagaMetaEngine);
#else
diff --git a/engines/saga/input.cpp b/engines/saga/input.cpp
index ac80d87dd0..61b729b701 100644
--- a/engines/saga/input.cpp
+++ b/engines/saga/input.cpp
@@ -141,9 +141,6 @@ int SagaEngine::processInput() {
break;
case Common::EVENT_MOUSEMOVE:
break;
- case Common::EVENT_QUIT:
- shutDown();
- break;
default:
break;
}
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index 256e231f57..4a4573ccef 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -688,7 +688,7 @@ bool Interface::processAscii(Common::KeyState keystate) {
setMode(kPanelMain);
_vm->_script->setNoPendingVerb();
} else if (ascii == 'q' || ascii == 'Q') {
- _vm->shutDown();
+ _vm->quitGame();
}
break;
case kPanelBoss:
@@ -1084,7 +1084,7 @@ void Interface::setQuit(PanelButton *panelButton) {
if (_vm->getGameId() == GID_IHNM_DEMO)
_vm->_scene->creditsScene(); // display sales info for IHNM demo
else
- _vm->shutDown();
+ _vm->quitGame();
break;
}
}
@@ -1650,8 +1650,8 @@ void Interface::setOption(PanelButton *panelButton) {
break;
case kTextSound:
_vm->_soundVolume = (_vm->_soundVolume + 1) % 11;
- _vm->_sound->setVolume(_vm->_soundVolume == 10 ? 255 : _vm->_soundVolume * 25);
ConfMan.setInt("sfx_volume", _vm->_soundVolume * 25);
+ _vm->_sound->setVolume();
break;
case kTextVoices:
if (_vm->_voiceFilesExist) {
@@ -1669,6 +1669,10 @@ void Interface::setOption(PanelButton *panelButton) {
_vm->_subtitlesEnabled = true; // Set it to "Text"
_vm->_voicesEnabled = false;
}
+
+ _vm->_speechVolume = (_vm->_speechVolume + 1) % 11;
+ ConfMan.setInt("speech_volume", _vm->_speechVolume * 25);
+ _vm->_sound->setVolume();
ConfMan.setBool("subtitles", _vm->_subtitlesEnabled);
ConfMan.setBool("voices", _vm->_voicesEnabled);
diff --git a/engines/saga/introproc_ihnm.cpp b/engines/saga/introproc_ihnm.cpp
index 6614f4098f..aaa428ca53 100644
--- a/engines/saga/introproc_ihnm.cpp
+++ b/engines/saga/introproc_ihnm.cpp
@@ -59,8 +59,12 @@ int Scene::IHNMStartProc() {
// Play Cyberdreams logo for 168 frames
if (!playTitle(0, logoLength, true)) {
+ if (_vm->quit())
+ return !SUCCESS;
// Play Dreamers Guild logo for 10 seconds
if (!playLoopingTitle(1, 10)) {
+ if (_vm->quit())
+ return !SUCCESS;
// Play the title music
_vm->_music->play(1, MUSIC_NORMAL);
// Play title screen
@@ -70,6 +74,8 @@ int Scene::IHNMStartProc() {
} else {
_vm->_music->play(1, MUSIC_NORMAL);
playTitle(0, 10);
+ if (_vm->quit())
+ return !SUCCESS;
playTitle(2, 12);
}
@@ -142,9 +148,9 @@ bool Scene::checkKey() {
while (_vm->_eventMan->pollEvent(event)) {
switch (event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
res = true;
- _vm->shutDown();
break;
case Common::EVENT_KEYDOWN:
// Don't react to modifier keys alone. The original did
@@ -187,7 +193,7 @@ bool Scene::playTitle(int title, int time, int mode) {
_vm->_gfx->getCurrentPal(pal_cut);
- while (!done) {
+ while (!done && !_vm->quit()) {
curTime = _vm->_system->getMillis();
switch (phase) {
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 732bd0b50c..1005b0ab5f 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -346,7 +346,7 @@ void MusicPlayer::stopMusic() {
}
}
-Music::Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enabled) : _vm(vm), _mixer(mixer), _enabled(enabled), _adlib(false) {
+Music::Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver) : _vm(vm), _mixer(mixer), _adlib(false) {
_player = new MusicPlayer(driver);
_currentVolume = 0;
@@ -432,11 +432,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
uint32 loopStart;
debug(2, "Music::play %d, %d", resourceId, flags);
-
- if (!_enabled) {
- return;
- }
-
+
if (isPlaying() && _trackNumber == resourceId) {
return;
}
@@ -444,11 +440,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
_trackNumber = resourceId;
_player->stopMusic();
_mixer->stopHandle(_musicHandle);
-
- if (!_vm->_musicVolume) {
- return;
- }
-
+
int realTrackNumber;
if (_vm->getGameType() == GType_ITE) {
diff --git a/engines/saga/music.h b/engines/saga/music.h
index 1953dc6f91..57ff9e0671 100644
--- a/engines/saga/music.h
+++ b/engines/saga/music.h
@@ -105,7 +105,7 @@ protected:
class Music {
public:
- Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enabled);
+ Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver);
~Music(void);
void setNativeMT32(bool b) { _player->setNativeMT32(b); }
bool hasNativeMT32() { return _player->hasNativeMT32(); }
@@ -133,7 +133,6 @@ private:
Audio::SoundHandle _musicHandle;
uint32 _trackNumber;
- int _enabled;
bool _adlib;
int _targetVolume;
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index fafbd02cec..47228ae68a 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -64,7 +64,6 @@ SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc)
_leftMouseButtonPressed = _rightMouseButtonPressed = false;
_console = NULL;
- _quit = false;
_resource = NULL;
_sndRes = NULL;
@@ -142,8 +141,7 @@ SagaEngine::~SagaEngine() {
}
int SagaEngine::init() {
- _soundVolume = ConfMan.getInt("sfx_volume") / 25;
- _musicVolume = ConfMan.getInt("music_volume") / 25;
+ _musicVolume = ConfMan.getInt("music_volume");
_subtitlesEnabled = ConfMan.getBool("subtitles");
_readingSpeed = getTalkspeed();
_copyProtection = ConfMan.getBool("copy_protection");
@@ -194,29 +192,21 @@ int SagaEngine::init() {
if (native_mt32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _music = new Music(this, _mixer, _driver, _musicVolume);
+ _music = new Music(this, _mixer, _driver);
_music->setNativeMT32(native_mt32);
_music->setAdlib(adlib);
-
- if (!_musicVolume) {
- debug(1, "Music disabled.");
- }
-
_render = new Render(this, _system);
if (!_render->initialized()) {
return FAILURE;
}
// Initialize system specific sound
- _sound = new Sound(this, _mixer, _soundVolume);
- if (!_soundVolume) {
- debug(1, "Sound disabled.");
- }
-
+ _sound = new Sound(this, _mixer);
+
_interface->converseInit();
_script->setVerb(_script->getVerbType(kVerbWalkTo));
- _music->setVolume(-1, 1);
+ _music->setVolume(_musicVolume, 1);
_gfx->initPalette();
@@ -233,6 +223,8 @@ int SagaEngine::init() {
}
}
+ syncSoundSettings();
+
// FIXME: This is the ugly way of reducing redraw overhead. It works
// well for 320x200 but it's unclear how well it will work for
// 640x480.
@@ -270,7 +262,7 @@ int SagaEngine::go() {
uint32 currentTicks;
- while (!_quit) {
+ while (!quit()) {
if (_console->isAttached())
_console->onFrame();
@@ -310,7 +302,7 @@ int SagaEngine::go() {
_system->delayMillis(10);
}
- return 0;
+ return _eventMan->shouldRTL();
}
void SagaEngine::loadStrings(StringsTable &stringsTable, const byte *stringsPointer, size_t stringsLength) {
@@ -520,4 +512,16 @@ int SagaEngine::getTalkspeed() {
return (ConfMan.getInt("talkspeed") * 3 + 255 / 2) / 255;
}
+void SagaEngine::syncSoundSettings() {
+ _subtitlesEnabled = ConfMan.getBool("subtitles");
+ _readingSpeed = getTalkspeed();
+
+ if (_readingSpeed > 3)
+ _readingSpeed = 0;
+
+ _musicVolume = ConfMan.getInt("music_volume");
+ _music->setVolume(_musicVolume, 1);
+ _sound->setVolume();
+}
+
} // End of namespace Saga
diff --git a/engines/saga/saga.h b/engines/saga/saga.h
index eeb8f7a61b..0b6b3b1478 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -492,7 +492,6 @@ protected:
public:
SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc);
virtual ~SagaEngine();
- void shutDown() { _quit = true; }
void save(const char *fileName, const char *saveName);
void load(const char *fileName);
@@ -513,6 +512,8 @@ public:
return isSaveListFull() ? _saveFilesCount : _saveFilesCount + 1;
}
+ virtual void syncSoundSettings();
+
int16 _framesEsc;
uint32 _globalFlags;
@@ -521,6 +522,7 @@ public:
int _soundVolume;
int _musicVolume;
+ int _speechVolume;
bool _subtitlesEnabled;
bool _voicesEnabled;
bool _voiceFilesExist;
@@ -611,8 +613,6 @@ public:
bool _rightMouseButtonPressed;
int _mouseClickCount;
- bool _quit;
-
//current game description
int _gameNumber;
const SAGAGameDescription *_gameDescription;
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index c3c1587822..074b4c933a 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -315,7 +315,7 @@ void Scene::creditsScene() {
break;
}
- _vm->shutDown();
+ _vm->quitGame();
return;
}
diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp
index ea61f5ce04..9a304de8e1 100644
--- a/engines/saga/sfuncs.cpp
+++ b/engines/saga/sfuncs.cpp
@@ -356,7 +356,7 @@ void Script::sfMainMode(SCRIPTFUNC_PARAMS) {
// exit the game. Known non-interactive demos are GID_ITE_MACDEMO1 and
// GID_ITE_WINDEMO1
if (_vm->getFeatures() & GF_NON_INTERACTIVE)
- _vm->shutDown();
+ _vm->quitGame();
}
// Script function #6 (0x06) blocking
@@ -572,7 +572,7 @@ void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) {
}
if (_vm->getGameType() == GType_ITE && sceneNumber < 0) {
- _vm->shutDown();
+ _vm->quitGame();
return;
}
diff --git a/engines/saga/sound.cpp b/engines/saga/sound.cpp
index 1d3263d302..1d41d39cf2 100644
--- a/engines/saga/sound.cpp
+++ b/engines/saga/sound.cpp
@@ -22,8 +22,10 @@
* $Id$
*
*/
-#include "saga/saga.h"
+#include "common/config-manager.h"
+
+#include "saga/saga.h"
#include "saga/sound.h"
#include "sound/audiostream.h"
@@ -32,13 +34,13 @@
namespace Saga {
-Sound::Sound(SagaEngine *vm, Audio::Mixer *mixer, int volume) :
+Sound::Sound(SagaEngine *vm, Audio::Mixer *mixer) :
_vm(vm), _mixer(mixer), _voxStream(0) {
for (int i = 0; i < SOUND_HANDLES; i++)
_handles[i].type = kFreeHandle;
- setVolume(volume == 10 ? 255 : volume * 25);
+ setVolume();
}
Sound::~Sound() {
@@ -61,7 +63,8 @@ SndHandle *Sound::getHandle() {
return NULL;
}
-void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int volume, bool loop) {
+void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int volume,
+ sndHandleType handleType, bool loop) {
byte flags;
flags = Audio::Mixer::FLAG_AUTOFREE;
@@ -81,7 +84,12 @@ void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int
flags |= Audio::Mixer::FLAG_UNSIGNED;
if (!(_vm->getFeatures() & GF_COMPRESSED_SOUNDS)) {
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume);
+ if (handleType == kVoiceHandle)
+ _mixer->playRaw(Audio::Mixer::kSpeechSoundType, handle, buffer.buffer,
+ buffer.size, buffer.frequency, flags, -1, volume);
+ else
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer,
+ buffer.size, buffer.frequency, flags, -1, volume);
} else {
Audio::AudioStream *stream = NULL;
MemoryReadStream *tmp = NULL;
@@ -116,12 +124,23 @@ void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int
#endif
default:
// No compression, play it as raw sound
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume);
+ if (handleType == kVoiceHandle)
+ _mixer->playRaw(Audio::Mixer::kSpeechSoundType, handle, buffer.buffer,
+ buffer.size, buffer.frequency, flags, -1, volume);
+ else
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer,
+ buffer.size, buffer.frequency, flags, -1, volume);
break;
}
- if (stream != NULL)
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, stream, -1, volume, 0, true, false);
+ if (stream != NULL) {
+ if (handleType == kVoiceHandle)
+ _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, handle, stream, -1,
+ volume, 0, true, false);
+ else
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, stream, -1,
+ volume, 0, true, false);
+ }
}
}
@@ -129,7 +148,7 @@ void Sound::playSound(SoundBuffer &buffer, int volume, bool loop) {
SndHandle *handle = getHandle();
handle->type = kEffectHandle;
- playSoundBuffer(&handle->handle, buffer, 2 * volume, loop);
+ playSoundBuffer(&handle->handle, buffer, 2 * volume, handle->type, loop);
}
void Sound::pauseSound() {
@@ -156,7 +175,7 @@ void Sound::playVoice(SoundBuffer &buffer) {
SndHandle *handle = getHandle();
handle->type = kVoiceHandle;
- playSoundBuffer(&handle->handle, buffer, 255, false);
+ playSoundBuffer(&handle->handle, buffer, 255, handle->type, false);
}
void Sound::pauseVoice() {
@@ -184,9 +203,11 @@ void Sound::stopAll() {
stopSound();
}
-void Sound::setVolume(int volume) {
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
+void Sound::setVolume() {
+ _vm->_soundVolume = ConfMan.getInt("sound_volume");
+ _vm->_speechVolume = ConfMan.getInt("speech_volume");
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, _vm->_soundVolume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, _vm->_speechVolume);
}
} // End of namespace Saga
diff --git a/engines/saga/sound.h b/engines/saga/sound.h
index ce479c64d1..6d9e42a49d 100644
--- a/engines/saga/sound.h
+++ b/engines/saga/sound.h
@@ -71,7 +71,7 @@ struct SndHandle {
class Sound {
public:
- Sound(SagaEngine *vm, Audio::Mixer *mixer, int volume);
+ Sound(SagaEngine *vm, Audio::Mixer *mixer);
~Sound();
void playSound(SoundBuffer &buffer, int volume, bool loop);
@@ -86,11 +86,12 @@ public:
void stopAll();
- void setVolume(int volume);
+ void setVolume();
private:
- void playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int volume, bool loop);
+ void playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int volume,
+ sndHandleType handleType, bool loop);
SndHandle *getHandle();
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index e4e2b2b620..cb9113fe65 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -442,7 +442,7 @@ Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
return descriptions;
}
-MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
+ScummMenuDialog::ScummMenuDialog(ScummEngine *scumm)
: ScummDialog("scummmain"), _vm(scumm) {
new GUI::ButtonWidget(this, "scummmain_resume", "Resume", kPlayCmd, 'P');
@@ -470,7 +470,7 @@ MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
_loadDialog = new SaveLoadChooser("Load game:", "Load", false, scumm);
}
-MainMenuDialog::~MainMenuDialog() {
+ScummMenuDialog::~ScummMenuDialog() {
delete _aboutDialog;
delete _optionsDialog;
#ifndef DISABLE_HELP
@@ -480,7 +480,7 @@ MainMenuDialog::~MainMenuDialog() {
delete _loadDialog;
}
-void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+void ScummMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kSaveCmd:
save();
@@ -503,7 +503,7 @@ void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
break;
#endif
case kQuitCmd:
- _vm->_quit = true;
+ _vm->quitGame();
close();
break;
default:
@@ -511,7 +511,7 @@ void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
}
}
-void MainMenuDialog::save() {
+void ScummMenuDialog::save() {
int idx;
_saveDialog->setList(generateSavegameList(_vm, true));
idx = _saveDialog->runModal();
@@ -530,7 +530,7 @@ void MainMenuDialog::save() {
}
}
-void MainMenuDialog::load() {
+void ScummMenuDialog::load() {
int idx;
_loadDialog->setList(generateSavegameList(_vm, false));
idx = _loadDialog->runModal();
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index 0d04d8faea..3837787a3b 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -82,10 +82,10 @@ public:
virtual void reflowLayout();
};
-class MainMenuDialog : public ScummDialog {
+class ScummMenuDialog : public ScummDialog {
public:
- MainMenuDialog(ScummEngine *scumm);
- ~MainMenuDialog();
+ ScummMenuDialog(ScummEngine *scumm);
+ ~ScummMenuDialog();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
protected:
diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp
index e611c85e9d..685bd00065 100644
--- a/engines/scumm/he/cup_player_he.cpp
+++ b/engines/scumm/he/cup_player_he.cpp
@@ -99,7 +99,7 @@ void CUP_Player::play() {
debug(1, "rate %d width %d height %d", _playbackRate, _width, _height);
int ticks = _system->getMillis();
- while (_dataSize != 0 && !_vm->_quit) {
+ while (_dataSize != 0 && !_vm->quit()) {
while (parseNextBlockTag(_fileStream)) {
if (_fileStream.ioFailed()) {
return;
@@ -190,7 +190,7 @@ void CUP_Player::waitForSfxChannel(int channel) {
CUP_SfxChannel *sfxChannel = &_sfxChannels[channel];
debug(1, "waitForSfxChannel %d", channel);
if ((sfxChannel->flags & kSfxFlagLoop) == 0) {
- while (_mixer->isSoundHandleActive(sfxChannel->handle) && !_vm->_quit) {
+ while (_mixer->isSoundHandleActive(sfxChannel->handle) && !_vm->quit()) {
_vm->parseEvents();
_system->delayMillis(10);
}
@@ -496,7 +496,7 @@ void CUP_Player::handleTOIL(Common::SeekableReadStream &dataStream, uint32 dataS
for (int i = 0; i < kSfxChannels; ++i) {
waitForSfxChannel(i);
}
- _vm->_quit = true;
+ _vm->quitGame();
break;
case 7: {
int channelSync = dataStream.readUint32LE();
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index f72701c229..5f907d7f04 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2147,10 +2147,10 @@ void ScummEngine_v100he::o100_systemOps() {
break;
case 71:
// Confirm shutdown
- shutDown();
+ quitGame();
break;
case 72:
- shutDown();
+ quitGame();
break;
case 73:
copyScriptString(string, sizeof(string));
diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp
index 3f22c16648..c7256835eb 100644
--- a/engines/scumm/he/script_v70he.cpp
+++ b/engines/scumm/he/script_v70he.cpp
@@ -634,10 +634,10 @@ void ScummEngine_v70he::o70_systemOps() {
break;
case 160:
// Confirm shutdown
- shutDown();
+ quitGame();
break;
case 244:
- shutDown();
+ quitGame();
break;
case 250:
id = pop();
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 6c3d0023d8..484e11cf50 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -1485,10 +1485,10 @@ void ScummEngine_v72he::o72_systemOps() {
break;
case 160:
// Confirm shutdown
- shutDown();
+ quitGame();
break;
case 244:
- shutDown();
+ quitGame();
break;
case 251:
copyScriptString(string, sizeof(string));
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 35028c7e1c..cc98cc00ae 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -192,10 +192,6 @@ void ScummEngine::parseEvents() {
_keyPressed = Common::KeyState(Common::KEYCODE_6, 54); // '6'
break;
- case Common::EVENT_QUIT:
- _quit = true;
- break;
-
default:
break;
}
@@ -475,7 +471,7 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) {
if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT), 0, 0, 0);
- mainMenuDialog(); // Display NewGui
+ scummMenuDialog(); // Display NewGui
if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT2), 0, 0, 0);
@@ -514,7 +510,7 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) {
vol = Audio::Mixer::kMaxMixerVolume;
ConfMan.setInt("music_volume", vol);
- updateSoundSettings();
+ syncSoundSettings();
} else if (lastKeyHit.ascii == '-' || lastKeyHit.ascii == '+') { // Change text speed
if (lastKeyHit.ascii == '+' && _defaultTalkDelay > 0)
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 6bd62c1761..9823a9483f 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -291,7 +291,7 @@ void ScummEngine::readIndexFile() {
if (checkTryMedia(_fileHandle)) {
displayMessage(NULL, "You're trying to run game encrypted by ActiveMark. This is not supported.");
- _quit = true;
+ quitGame();
return;
}
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 54dfca9eea..426c7ee48b 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -275,7 +275,7 @@ bool ScummEngine::loadState(int slot, bool compat) {
delete in;
// Update volume settings
- updateSoundSettings();
+ syncSoundSettings();
// Init NES costume data
if (_game.platform == Common::kPlatformNES) {
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 431321f459..1d90b5e4af 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1769,7 +1769,7 @@ void ScummEngine_v5::o5_systemOps() {
pauseGame();
break;
case 3: // SO_QUIT
- shutDown();
+ quitGame();
break;
default:
error("o5_systemOps: unknown subopcode %d", subOp);
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index 04ea53137b..f8502cbbe7 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -2310,7 +2310,7 @@ void ScummEngine_v6::o6_systemOps() {
pauseGame();
break;
case 160: // SO_QUIT
- shutDown();
+ quitGame();
break;
default:
error("o6_systemOps invalid case %d", subOp);
diff --git a/engines/scumm/script_v8.cpp b/engines/scumm/script_v8.cpp
index 08629afb07..63e54417a9 100644
--- a/engines/scumm/script_v8.cpp
+++ b/engines/scumm/script_v8.cpp
@@ -1170,7 +1170,7 @@ void ScummEngine_v8::o8_systemOps() {
restart();
break;
case 0x29: // SO_SYSTEM_QUIT Quit game
- shutDown();
+ quitGame();
break;
default:
error("o8_systemOps: invalid case 0x%x", subOp);
@@ -1289,7 +1289,7 @@ void ScummEngine_v8::o8_kernelSetFunctions() {
if (ConfMan.getBool("confirm_exit"))
confirmExitDialog();
else
- _quit = true;
+ quitGame();
break;
case 108: // buildPaletteShadow
setShadowPalette(args[1], args[2], args[3], args[4], args[5], args[6]);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 2f0593dca8..cc7e01fca7 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -109,7 +109,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_language(dr.language),
_debugger(0),
_currentScript(0xFF), // Let debug() work on init stage
- _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0) {
+ _pauseDialog(0), _scummMenuDialog(0), _versionDialog(0) {
if (_game.platform == Common::kPlatformNES) {
_gdi = new GdiNES(this);
@@ -143,9 +143,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_objs = NULL;
_sound = NULL;
memset(&vm, 0, sizeof(vm));
- _quit = false;
_pauseDialog = NULL;
- _mainMenuDialog = NULL;
+ _scummMenuDialog = NULL;
_versionDialog = NULL;
_fastMode = 0;
_actors = NULL;
@@ -561,7 +560,7 @@ ScummEngine::~ScummEngine() {
delete _2byteFontPtr;
delete _charset;
delete _pauseDialog;
- delete _mainMenuDialog;
+ delete _scummMenuDialog;
delete _versionDialog;
delete _fileHandle;
@@ -815,7 +814,6 @@ ScummEngine_vCUPhe::ScummEngine_vCUPhe(OSystem *syst, const DetectorResult &dr)
_syst = syst;
_game = dr.game;
_filenamePattern = dr.fp,
- _quit = false;
_cupPlayer = new CUP_Player(syst, this, _mixer);
}
@@ -846,9 +844,6 @@ void ScummEngine_vCUPhe::parseEvents() {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _quit = true;
- break;
default:
break;
@@ -1108,7 +1103,7 @@ int ScummEngine::init() {
if (_game.version >= 5 && _game.version <= 7)
_sound->setupSound();
- updateSoundSettings();
+ syncSoundSettings();
return 0;
}
@@ -1667,7 +1662,7 @@ void ScummEngine::setupMusic(int midi) {
}
}
-void ScummEngine::updateSoundSettings() {
+void ScummEngine::syncSoundSettings() {
// Sync the engine with the config manager
int soundVolumeMusic = ConfMan.getInt("music_volume");
@@ -1721,7 +1716,7 @@ int ScummEngine::go() {
int diff = 0; // Duration of one loop iteration
- while (!_quit) {
+ while (!quit()) {
if (_debugger->isAttached())
_debugger->onFrame();
@@ -1754,12 +1749,12 @@ int ScummEngine::go() {
diff = _system->getMillis() - diff;
- if (_quit) {
+ if (quit()) {
// TODO: Maybe perform an autosave on exit?
}
}
- return 0;
+ return _eventMan->shouldRTL();
}
void ScummEngine::waitForTimer(int msec_delay) {
@@ -1772,7 +1767,7 @@ void ScummEngine::waitForTimer(int msec_delay) {
start_time = _system->getMillis();
- while (!_quit) {
+ while (!quit()) {
_sound->updateCD(); // Loop CD Audio if needed
parseEvents();
_system->updateScreen();
@@ -1895,7 +1890,7 @@ load_game:
checkExecVerbs();
checkAndRunSentenceScript();
- if (_quit)
+ if (quit())
return;
// HACK: If a load was requested, immediately perform it. This avoids
@@ -2160,10 +2155,6 @@ void ScummEngine::pauseGame() {
pauseDialog();
}
-void ScummEngine::shutDown() {
- _quit = true;
-}
-
void ScummEngine::restart() {
// TODO: Check this function - we should probably be reinitting a lot more stuff, and I suspect
// this leaks memory like a sieve
@@ -2305,18 +2296,18 @@ void ScummEngine::versionDialog() {
runDialog(*_versionDialog);
}
-void ScummEngine::mainMenuDialog() {
- if (!_mainMenuDialog)
- _mainMenuDialog = new MainMenuDialog(this);
- runDialog(*_mainMenuDialog);
- updateSoundSettings();
+void ScummEngine::scummMenuDialog() {
+ if (!_scummMenuDialog)
+ _scummMenuDialog = new ScummMenuDialog(this);
+ runDialog(*_scummMenuDialog);
+ syncSoundSettings();
}
void ScummEngine::confirmExitDialog() {
ConfirmDialog d(this, 6);
if (runDialog(d)) {
- _quit = true;
+ quitGame();
}
}
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 5011781820..b839d37b08 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -462,7 +462,7 @@ protected:
virtual void loadLanguageBundle() {}
void loadCJKFont();
void setupMusic(int midi);
- void updateSoundSettings();
+ virtual void syncSoundSettings();
void setTalkspeed(int talkspeed);
int getTalkspeed();
@@ -496,22 +496,18 @@ protected:
public:
void pauseGame();
void restart();
- void shutDown();
-
- /** We keep running until this is set to true. */
- bool _quit;
protected:
Dialog *_pauseDialog;
Dialog *_versionDialog;
- Dialog *_mainMenuDialog;
+ Dialog *_scummMenuDialog;
virtual int runDialog(Dialog &dialog);
void confirmExitDialog();
void confirmRestartDialog();
void pauseDialog();
void versionDialog();
- void mainMenuDialog();
+ void scummMenuDialog();
char displayMessage(const char *altButton, const char *message, ...);
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 494357a90c..850b547021 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -1333,7 +1333,7 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
}
if (_endOfFile)
break;
- if (_vm->_quit || _vm->_saveLoadFlag || _vm->_smushVideoShouldFinish) {
+ if (_vm->quit() || _vm->_saveLoadFlag || _vm->_smushVideoShouldFinish) {
_smixer->stop();
_vm->_mixer->stopHandle(_compressedFileSoundHandle);
_vm->_mixer->stopHandle(_IACTchannel);
diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index 9d6b58704d..3edc087f57 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -492,7 +492,7 @@ void Control::doControlPanel(void) {
_curButtonText = 0;
uint16 clickRes = 0;
- while (!quitPanel && !SkyEngine::_systemVars.quitGame) {
+ while (!quitPanel && !g_engine->quit()) {
_text->drawToScreen(WITH_MASK);
_system->updateScreen();
_mouseClicked = false;
@@ -524,7 +524,7 @@ void Control::doControlPanel(void) {
}
memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
- if (!SkyEngine::_systemVars.quitGame)
+ if (!g_engine->quit())
_system->updateScreen();
_skyScreen->forceRefresh();
_skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars.currentPalette));
@@ -603,7 +603,7 @@ uint16 Control::handleClick(ConResource *pButton) {
case QUIT_TO_DOS:
animClick(pButton);
if (getYesNo(quitDos))
- SkyEngine::_systemVars.quitGame = true;
+ g_engine->quitGame();
return 0;
default:
error("Control::handleClick: unknown routine: %X",pButton->_onClick);
@@ -875,7 +875,7 @@ uint16 Control::saveRestorePanel(bool allowSave) {
bool refreshNames = true;
bool refreshAll = true;
uint16 clickRes = 0;
- while (!quitPanel && !SkyEngine::_systemVars.quitGame) {
+ while (!quitPanel && !g_engine->quit()) {
clickRes = 0;
if (refreshNames || refreshAll) {
if (refreshAll) {
@@ -1546,9 +1546,6 @@ void Control::delay(unsigned int amount) {
case Common::EVENT_WHEELDOWN:
_mouseWheel = 1;
break;
- case Common::EVENT_QUIT:
- SkyEngine::_systemVars.quitGame = true;
- break;
default:
break;
}
diff --git a/engines/sky/intro.cpp b/engines/sky/intro.cpp
index 024360561c..d7a94f6c2f 100644
--- a/engines/sky/intro.cpp
+++ b/engines/sky/intro.cpp
@@ -636,7 +636,6 @@ Intro::Intro(Disk *disk, Screen *screen, MusicBase *music, Sound *sound, Text *t
_textBuf = (uint8*)malloc(10000);
_saveBuf = (uint8*)malloc(10000);
_bgBuf = NULL;
- _quitProg = false;
_relDelay = 0;
}
@@ -912,8 +911,7 @@ bool Intro::escDelay(uint32 msecs) {
if (event.type == Common::EVENT_KEYDOWN) {
if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
return false;
- } else if (event.type == Common::EVENT_QUIT) {
- _quitProg = true;
+ } else if (event.type == Common::EVENT_QUIT || event.type == Common::EVENT_RTL) {
return false;
}
}
diff --git a/engines/sky/intro.h b/engines/sky/intro.h
index 4a54fb8dd3..796bcf7e36 100644
--- a/engines/sky/intro.h
+++ b/engines/sky/intro.h
@@ -43,7 +43,6 @@ public:
Intro(Disk *disk, Screen *screen, MusicBase *music, Sound *sound, Text *text, Audio::Mixer *mixer, OSystem *system);
~Intro(void);
bool doIntro(bool floppyIntro);
- bool _quitProg;
private:
static uint16 _mainIntroSeq[];
static uint16 _floppyIntroSeq[];
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index c6c6c34c4d..9f13bf9bee 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -2490,7 +2490,7 @@ bool Logic::fnFadeUp(uint32 a, uint32 b, uint32 c) {
}
bool Logic::fnQuitToDos(uint32 a, uint32 b, uint32 c) {
- SkyEngine::_systemVars.quitGame = true;
+ g_engine->quitGame();
return false;
}
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index b3be8b4f36..1fc9e47539 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -180,7 +180,6 @@ void Mouse::waitMouseNotPressed(int minDelay) {
while (mousePressed || _system->getMillis() < now + minDelay) {
if (eventMan->shouldQuit()) {
- SkyEngine::_systemVars.quitGame = true;
minDelay = 0;
mousePressed = false;
}
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index d87ed06fef..44347cf9a7 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -257,7 +257,7 @@ namespace Sky {
void *SkyEngine::_itemList[300];
-SystemVars SkyEngine::_systemVars = {0, 0, 0, 0, 4316, 0, 0, false, false, false };
+SystemVars SkyEngine::_systemVars = {0, 0, 0, 0, 4316, 0, 0, false, false };
SkyEngine::SkyEngine(OSystem *syst)
: Engine(syst), _fastMode(0), _debugger(0) {
@@ -340,25 +340,23 @@ void SkyEngine::handleKey(void) {
int SkyEngine::go() {
- _systemVars.quitGame = false;
-
_keyPressed.reset();
uint16 result = 0;
- if (ConfMan.hasKey("save_slot") && ConfMan.getInt("save_slot") >= 0)
- result = _skyControl->quickXRestore(ConfMan.getInt("save_slot"));
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 999)
+ result = _skyControl->quickXRestore(ConfMan.getInt("save_slot"));
+ }
if (result != GAME_RESTORED) {
bool introSkipped = false;
if (_systemVars.gameVersion > 267) { // don't do intro for floppydemos
_skyIntro = new Intro(_skyDisk, _skyScreen, _skyMusic, _skySound, _skyText, _mixer, _system);
introSkipped = !_skyIntro->doIntro(_floppyIntro);
- _systemVars.quitGame = _skyIntro->_quitProg;
-
- delete _skyIntro;
}
- if (!_systemVars.quitGame) {
+ if (!quit()) {
_skyLogic->initScreen0();
if (introSkipped)
_skyControl->restartGame();
@@ -368,7 +366,7 @@ int SkyEngine::go() {
_lastSaveTime = _system->getMillis();
uint32 delayCount = _system->getMillis();
- while (!_systemVars.quitGame) {
+ while (!quit()) {
if (_debugger->isAttached())
_debugger->onFrame();
@@ -419,7 +417,7 @@ int SkyEngine::go() {
_skyMusic->stopMusic();
ConfMan.flushToDisk();
delay(1500);
- return 0;
+ return _eventMan->shouldRTL();
}
int SkyEngine::init() {
@@ -440,7 +438,7 @@ int SkyEngine::init() {
_floppyIntro = ConfMan.getBool("alt_intro");
_skyDisk = new Disk();
- _skySound = new Sound(_mixer, _skyDisk, ConfMan.getInt("sfx_volume"));
+ _skySound = new Sound(_mixer, _skyDisk, Audio::Mixer::kMaxChannelVolume);
_systemVars.gameVersion = _skyDisk->determineGameVersion();
@@ -615,9 +613,6 @@ void SkyEngine::delay(int32 amount) {
_skyMouse->mouseMoved(event.mouse.x, event.mouse.y);
_skyMouse->buttonPressed(1);
break;
- case Common::EVENT_QUIT:
- _systemVars.quitGame = true;
- break;
default:
break;
}
diff --git a/engines/sky/sky.h b/engines/sky/sky.h
index b5d1701930..47aebaba77 100644
--- a/engines/sky/sky.h
+++ b/engines/sky/sky.h
@@ -41,7 +41,6 @@ struct SystemVars {
uint16 gameSpeed;
uint16 currentMusic;
bool pastIntro;
- bool quitGame;
bool paused;
};
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 2bb027ddb4..caf766ed9f 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -300,9 +300,6 @@ void MoviePlayer::play(void) {
terminated = true;
}
break;
- case Common::EVENT_QUIT:
- _system->quit();
- break;
default:
break;
}
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 980e0b4f9f..3a26f4dd33 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -215,7 +215,7 @@ void Control::askForCd(void) {
notAccepted = false;
}
}
- } while (notAccepted && (!SwordEngine::_systemVars.engineQuit));
+ } while (notAccepted && (!g_engine->quit()));
_resMan->resClose(fontId);
free(_screenBuf);
@@ -317,7 +317,7 @@ uint8 Control::runPanel(void) {
}
delay(1000 / 12);
newMode = getClicks(mode, &retVal);
- } while ((newMode != BUTTON_DONE) && (retVal == 0) && (!SwordEngine::_systemVars.engineQuit));
+ } while ((newMode != BUTTON_DONE) && (retVal == 0) && (!g_engine->quit()));
if (SwordEngine::_systemVars.controlPanelMode == CP_NORMAL) {
uint8 volL, volR;
@@ -425,7 +425,7 @@ uint8 Control::handleButtonClick(uint8 id, uint8 mode, uint8 *retVal) {
_buttons[5]->setSelected(SwordEngine::_systemVars.showText);
} else if (id == BUTTON_QUIT) {
if (getConfirm(_lStrings[STR_QUIT]))
- SwordEngine::_systemVars.engineQuit = true;
+ g_engine->quitGame();
return mode;
}
break;
@@ -1091,9 +1091,6 @@ void Control::delay(uint32 msecs) {
_mouseDown = false;
_mouseState |= BS1_WHEEL_DOWN;
break;
- case Common::EVENT_QUIT:
- SwordEngine::_systemVars.engineQuit = true;
- break;
default:
break;
}
diff --git a/engines/sword1/credits.cpp b/engines/sword1/credits.cpp
index 14dd0ecd2b..55f1f7358b 100644
--- a/engines/sword1/credits.cpp
+++ b/engines/sword1/credits.cpp
@@ -125,7 +125,7 @@ void CreditsPlayer::play(void) {
uint16 renderY = BUFSIZE_Y / 2;
uint16 clearY = 0xFFFF;
bool clearLine = false;
- while (((*textData != FNT_EOB) || (scrollY != renderY)) && !SwordEngine::_systemVars.engineQuit) {
+ while (((*textData != FNT_EOB) || (scrollY != renderY)) && !g_engine->quit()) {
if ((int32)_mixer->getSoundElapsedTime(bgSound) - relDelay < (SCROLL_TIMING * 2)) { // sync to audio
if (scrollY < BUFSIZE_Y - CREDITS_Y)
_system->copyRectToScreen(screenBuf + scrollY * CREDITS_X, CREDITS_X, START_X, START_Y, CREDITS_X, CREDITS_Y);
@@ -175,7 +175,7 @@ void CreditsPlayer::play(void) {
uint8 *revoBuf = credFile.decompressFile(REVO_LOGO);
uint8 *revoPal = credFile.fetchFile(REVO_PAL, &_palLen);
_palLen /= 3;
- while ((_mixer->getSoundElapsedTime(bgSound) < LOGO_FADEUP_TIME) && !SwordEngine::_systemVars.engineQuit) {
+ while ((_mixer->getSoundElapsedTime(bgSound) < LOGO_FADEUP_TIME) && !g_engine->quit()) {
delay(100);
}
memset(_palette, 0, 256 * 4);
@@ -184,13 +184,13 @@ void CreditsPlayer::play(void) {
_system->updateScreen();
fadePalette(revoPal, true, _palLen);
- while ((_mixer->getSoundElapsedTime(bgSound) < LOGO_FADEDOWN_TIME) && !SwordEngine::_systemVars.engineQuit) {
+ while ((_mixer->getSoundElapsedTime(bgSound) < LOGO_FADEDOWN_TIME) && !g_engine->quit()) {
delay(100);
}
fadePalette(revoPal, false, _palLen);
delay(3000);
- if (SwordEngine::_systemVars.engineQuit)
+ if (g_engine->quit())
_mixer->stopAll();
free(revoBuf);
}
@@ -200,7 +200,7 @@ void CreditsPlayer::fadePalette(uint8 *srcPal, bool fadeup, uint16 len) {
int fadeStart = fadeup ? 0 : 12;
int relDelay = _system->getMillis();
- for (int fadeStep = fadeStart; (fadeStep >= 0) && (fadeStep <= 12) && !SwordEngine::_systemVars.engineQuit; fadeStep += fadeDir) {
+ for (int fadeStep = fadeStart; (fadeStep >= 0) && (fadeStep <= 12) && !g_engine->quit(); fadeStep += fadeDir) {
for (uint16 cnt = 0; cnt < len * 3; cnt++)
_palette[(cnt / 3) * 4 + (cnt % 3)] = (srcPal[cnt] * fadeStep) / 12;
_system->setPalette(_palette, 0, 256);
@@ -281,9 +281,6 @@ void CreditsPlayer::delay(int msecs) {
Common::EventManager *eventMan = _system->getEventManager();
while (eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- SwordEngine::_systemVars.engineQuit = true;
- break;
default:
break;
}
@@ -294,7 +291,7 @@ void CreditsPlayer::delay(int msecs) {
if (msecs > 0)
_system->delayMillis(10);
- } while ((_system->getMillis() < start + msecs) && !SwordEngine::_systemVars.engineQuit);
+ } while ((_system->getMillis() < start + msecs) && !g_engine->quit());
}
ArcFile::ArcFile(void) {
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index e7e1fb39a4..2fa108ebdd 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -1636,7 +1636,7 @@ int Logic::fnQuitGame(Object *cpt, int32 id, int32 a, int32 b, int32 c, int32 d,
if (SwordEngine::_systemVars.isDemo) {
GUI::MessageDialog dialog("This is the end of the Broken Sword 1 Demo", "OK", NULL);
dialog.runModal();
- SwordEngine::_systemVars.engineQuit = true;
+ g_engine->quitGame();
} else
error("fnQuitGame() called");
return fnQuit(cpt, id, 0, 0, 0, 0, 0, 0);
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 7372779199..8bfb5d8698 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -32,6 +32,7 @@
#include "common/fs.h"
#include "common/timer.h"
#include "common/events.h"
+#include "common/savefile.h"
#include "common/system.h"
#include "engines/metaengine.h"
@@ -97,6 +98,7 @@ public:
virtual GameList getSupportedGames() const;
virtual GameDescriptor findGame(const char *gameid) const;
virtual GameList detectGames(const FSList &fslist) const;
+ virtual SaveStateList listSaves(const char *target) const;
virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
};
@@ -187,6 +189,39 @@ PluginError SwordMetaEngine::createInstance(OSystem *syst, Engine **engine) cons
return kNoError;
}
+SaveStateList SwordMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ SaveStateList saveList;
+ Common::InSaveFile *in = saveFileMan->openForLoading("SAVEGAME.INF");
+ if (in) {
+ uint8 stop;
+ char saveDesc[32];
+ int slotNum = 0;
+ do {
+ uint pos = 0;
+ do {
+ stop = in->readByte();
+ if (pos < (sizeof(saveDesc) - 1)) {
+ if ((stop == 10) || (stop == 255) || (in->eos())) {
+ saveDesc[pos++] = '\0';
+ }
+ else if (stop >= 32) {
+ saveDesc[pos++] = stop;
+ }
+ }
+ } while ((stop != 10) && (stop != 255) && (!in->eos()));
+ if (saveDesc[0] != 0) {
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc, "SAVEGAME.INF"));
+ slotNum++;
+ }
+ } while ((stop != 255) && (!in->eos()));
+ }
+
+ delete in;
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(SWORD1)
REGISTER_PLUGIN_DYNAMIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine);
#else
@@ -247,8 +282,6 @@ int SwordEngine::init() {
_resMan = new ResMan("swordres.rif", _systemVars.isMac);
debug(5, "Starting object manager");
_objectMan = new ObjectMan(_resMan);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, Audio::Mixer::kMaxMixerVolume);
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume);
_mouse = new Mouse(_system, _resMan, _objectMan);
_screen = new Screen(_system, _resMan, _objectMan);
_music = new Music(_mixer);
@@ -257,60 +290,13 @@ int SwordEngine::init() {
_logic = new Logic(_objectMan, _resMan, _screen, _mouse, _sound, _music, _menu, _system, _mixer);
_mouse->useLogicAndMenu(_logic, _menu);
- uint musicVol = ConfMan.getInt("music_volume");
- uint speechVol = ConfMan.getInt("speech_volume");
- uint sfxVol = ConfMan.getInt("sfx_volume");
- uint musicBal = 50;
- if (ConfMan.hasKey("music_balance")) {
- musicBal = CLIP(ConfMan.getInt("music_balance"), 0, 100);
- }
- uint speechBal = 50;
- if (ConfMan.hasKey("speech_balance")) {
- speechBal = CLIP(ConfMan.getInt("speech_balance"), 0, 100);
- }
- uint sfxBal = 50;
- if (ConfMan.hasKey("sfx_balance")) {
- sfxBal = CLIP(ConfMan.getInt("sfx_balance"), 0, 100);
- }
-
- uint musicVolL = 2 * musicVol * musicBal / 100;
- uint musicVolR = 2 * musicVol - musicVolL;
-
- uint speechVolL = 2 * speechVol * speechBal / 100;
- uint speechVolR = 2 * speechVol - speechVolL;
-
- uint sfxVolL = 2 * sfxVol * sfxBal / 100;
- uint sfxVolR = 2 * sfxVol - sfxVolL;
-
- if (musicVolR > 255) {
- musicVolR = 255;
- }
- if (musicVolL > 255) {
- musicVolL = 255;
- }
- if (speechVolR > 255) {
- speechVolR = 255;
- }
- if (speechVolL > 255) {
- speechVolL = 255;
- }
- if (sfxVolR > 255) {
- sfxVolR = 255;
- }
- if (sfxVolL > 255) {
- sfxVolL = 255;
- }
-
- _music->setVolume(musicVolL, musicVolR);
- _sound->setSpeechVol(speechVolL, speechVolR);
- _sound->setSfxVol(sfxVolL, sfxVolR);
+ syncSoundSettings();
_systemVars.justRestoredGame = 0;
_systemVars.currentCD = 0;
_systemVars.controlPanelMode = CP_NEWGAME;
_systemVars.forceRestart = false;
_systemVars.wantFade = true;
- _systemVars.engineQuit = false;
switch (Common::parseLanguage(ConfMan.get("language"))) {
case Common::DE_DEU:
@@ -358,6 +344,62 @@ void SwordEngine::reinitialize(void) {
_systemVars.wantFade = true;
}
+void SwordEngine::syncSoundSettings() {
+ uint musicVol = ConfMan.getInt("music_volume");
+ uint sfxVol = ConfMan.getInt("sfx_volume");
+ uint speechVol = ConfMan.getInt("speech_volume");
+
+ uint musicBal = 50;
+ if (ConfMan.hasKey("music_balance")) {
+ musicBal = CLIP(ConfMan.getInt("music_balance"), 0, 100);
+ }
+
+ uint speechBal = 50;
+ if (ConfMan.hasKey("speech_balance")) {
+ speechBal = CLIP(ConfMan.getInt("speech_balance"), 0, 100);
+ }
+ uint sfxBal = 50;
+ if (ConfMan.hasKey("sfx_balance")) {
+ sfxBal = CLIP(ConfMan.getInt("sfx_balance"), 0, 100);
+ }
+
+ uint musicVolL = 2 * musicVol * musicBal / 100;
+ uint musicVolR = 2 * musicVol - musicVolL;
+
+ uint speechVolL = 2 * speechVol * speechBal / 100;
+ uint speechVolR = 2 * speechVol - speechVolL;
+
+ uint sfxVolL = 2 * sfxVol * sfxBal / 100;
+ uint sfxVolR = 2 * sfxVol - sfxVolL;
+
+ if (musicVolR > 255) {
+ musicVolR = 255;
+ }
+ if (musicVolL > 255) {
+ musicVolL = 255;
+ }
+
+ if (speechVolR > 255) {
+ speechVolR = 255;
+ }
+ if (speechVolL > 255) {
+ speechVolL = 255;
+ }
+ if (sfxVolR > 255) {
+ sfxVolR = 255;
+ }
+ if (sfxVolL > 255) {
+ sfxVolL = 255;
+ }
+
+ _music->setVolume(musicVolL, musicVolR);
+ _sound->setSpeechVol(speechVolL, speechVolR);
+ _sound->setSfxVol(sfxVolL, sfxVolR);
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+}
+
void SwordEngine::flagsToBool(bool *dest, uint8 flags) {
uint8 bitPos = 0;
while (flags) {
@@ -645,7 +687,7 @@ int SwordEngine::go() {
_systemVars.controlPanelMode = CP_NEWGAME;
if (_control->runPanel() == CONTROL_GAME_RESTORED)
_control->doRestore();
- else if (!_systemVars.engineQuit)
+ else if (!quit())
_logic->startPositions(0);
} else {
// no savegames, start new game.
@@ -654,10 +696,10 @@ int SwordEngine::go() {
}
_systemVars.controlPanelMode = CP_NORMAL;
- while (!_systemVars.engineQuit) {
+ while (!quit()) {
uint8 action = mainLoop();
- if (!_systemVars.engineQuit) {
+ if (!quit()) {
// the mainloop was left, we have to reinitialize.
reinitialize();
if (action == CONTROL_GAME_RESTORED)
@@ -669,7 +711,7 @@ int SwordEngine::go() {
}
}
- return 0;
+ return _eventMan->shouldRTL();
}
void SwordEngine::checkCd(void) {
@@ -698,7 +740,7 @@ uint8 SwordEngine::mainLoop(void) {
uint8 retCode = 0;
_keyPressed.reset();
- while ((retCode == 0) && (!_systemVars.engineQuit)) {
+ while ((retCode == 0) && (!quit())) {
// do we need the section45-hack from sword.c here?
checkCd();
@@ -747,9 +789,9 @@ uint8 SwordEngine::mainLoop(void) {
}
_mouseState = 0;
_keyPressed.reset();
- } while ((Logic::_scriptVars[SCREEN] == Logic::_scriptVars[NEW_SCREEN]) && (retCode == 0) && (!_systemVars.engineQuit));
+ } while ((Logic::_scriptVars[SCREEN] == Logic::_scriptVars[NEW_SCREEN]) && (retCode == 0) && (!quit()));
- if ((retCode == 0) && (Logic::_scriptVars[SCREEN] != 53) && _systemVars.wantFade && (!_systemVars.engineQuit)) {
+ if ((retCode == 0) && (Logic::_scriptVars[SCREEN] != 53) && _systemVars.wantFade && (!quit())) {
_screen->fadeDownPalette();
int32 relDelay = (int32)_system->getMillis();
while (_screen->stillFading()) {
@@ -796,9 +838,6 @@ void SwordEngine::delay(int32 amount) { //copied and mutilated from sky.cpp
_mouseState |= BS1R_BUTTON_UP;
_mouseCoord = event.mouse;
break;
- case Common::EVENT_QUIT:
- _systemVars.engineQuit = true;
- break;
default:
break;
}
diff --git a/engines/sword1/sword1.h b/engines/sword1/sword1.h
index cfb6750a47..5bc80b4f6d 100644
--- a/engines/sword1/sword1.h
+++ b/engines/sword1/sword1.h
@@ -58,7 +58,6 @@ struct SystemVars {
bool runningFromCd;
uint32 currentCD; // starts at zero, then either 1 or 2 depending on section being played
uint32 justRestoredGame; // see main() in sword.c & New_screen() in gtm_core.c
- bool engineQuit;
uint8 controlPanelMode; // 1 death screen version of the control panel, 2 = successful end of game, 3 = force restart
bool forceRestart;
@@ -78,6 +77,7 @@ public:
virtual ~SwordEngine();
static SystemVars _systemVars;
void reinitialize(void);
+ virtual void syncSoundSettings();
uint32 _features;
protected:
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 48196a2f7d..76f14851e7 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -357,8 +357,8 @@ bool MoviePlayer::userInterrupt() {
case Common::EVENT_SCREEN_CHANGED:
handleScreenChanged();
break;
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
- _vm->closeGame();
terminate = true;
break;
case Common::EVENT_KEYDOWN:
@@ -379,7 +379,7 @@ void MoviePlayer::play(SequenceTextInfo *textList, uint32 numLines, int32 leadIn
bool startNextText = false;
// This happens if the user quits during the "eye" cutscene.
- if (_vm->_quit)
+ if (_vm->quit())
return;
_numSpeechLines = numLines;
diff --git a/engines/sword2/controls.cpp b/engines/sword2/controls.cpp
index 6b466d6be0..dcacbc78d4 100644
--- a/engines/sword2/controls.cpp
+++ b/engines/sword2/controls.cpp
@@ -396,7 +396,7 @@ int Dialog::runModal() {
_vm->_system->delayMillis(20);
- if (_vm->_quit)
+ if (_vm->quit())
setResult(0);
}
@@ -842,7 +842,7 @@ int StartDialog::runModal() {
if (startDialog.runModal())
return 1;
- if (_vm->_quit)
+ if (_vm->quit())
return 0;
RestoreDialog restoreDialog(_vm);
@@ -850,7 +850,7 @@ int StartDialog::runModal() {
if (restoreDialog.runModal())
return 0;
- if (_vm->_quit)
+ if (_vm->quit())
return 0;
}
@@ -882,7 +882,7 @@ int QuitDialog::runModal() {
int result = MiniDialog::runModal();
if (result)
- _vm->closeGame();
+ _vm->quitGame();
return result;
}
diff --git a/engines/sword2/function.cpp b/engines/sword2/function.cpp
index 84a5b5af76..31b799386f 100644
--- a/engines/sword2/function.cpp
+++ b/engines/sword2/function.cpp
@@ -2388,7 +2388,7 @@ int32 Logic::fnPlayCredits(int32 *params) {
// params: none
if (readVar(DEMO)) {
- _vm->closeGame();
+ _vm->quitGame();
return IR_STOP;
}
diff --git a/engines/sword2/palette.cpp b/engines/sword2/palette.cpp
index 81f93c77ae..b66a3c9a81 100644
--- a/engines/sword2/palette.cpp
+++ b/engines/sword2/palette.cpp
@@ -212,7 +212,7 @@ uint8 Screen::getFadeStatus() {
}
void Screen::waitForFade() {
- while (getFadeStatus() != RDFADE_NONE && getFadeStatus() != RDFADE_BLACK && !_vm->_quit) {
+ while (getFadeStatus() != RDFADE_NONE && getFadeStatus() != RDFADE_BLACK && !_vm->quit()) {
updateDisplay();
_vm->_system->delayMillis(20);
}
diff --git a/engines/sword2/resman.cpp b/engines/sword2/resman.cpp
index 8cddddff78..880234aab0 100644
--- a/engines/sword2/resman.cpp
+++ b/engines/sword2/resman.cpp
@@ -412,7 +412,7 @@ Common::File *ResourceManager::openCluFile(uint16 fileNum) {
// quit while the game is asking for the user to insert a CD.
// But recovering from this situation gracefully is just too
// much trouble, so quit now.
- if (_vm->_quit)
+ if (_vm->quit())
g_system->quit();
// If the file is supposed to be on hard disk, or we're
diff --git a/engines/sword2/screen.cpp b/engines/sword2/screen.cpp
index fdabb3ee6f..b2fcc45c9c 100644
--- a/engines/sword2/screen.cpp
+++ b/engines/sword2/screen.cpp
@@ -389,7 +389,7 @@ void Screen::displayMsg(byte *text, int time) {
uint32 targetTime = _vm->getMillis() + (time * 1000);
_vm->sleepUntil(targetTime);
} else {
- while (!_vm->_quit) {
+ while (!_vm->quit()) {
MouseEvent *me = _vm->mouseEvent();
if (me && (me->buttons & (RD_LEFTBUTTONDOWN | RD_RIGHTBUTTONDOWN)))
break;
@@ -1035,7 +1035,7 @@ void Screen::rollCredits() {
uint32 musicLength = MAX((int32)(1000 * (_vm->_sound->musicTimeRemaining() - 3)), 25 * (int32)scrollSteps);
- while (scrollPos < scrollSteps && !_vm->_quit) {
+ while (scrollPos < scrollSteps && !_vm->quit()) {
clearScene();
for (i = startLine; i < lineCount; i++) {
@@ -1123,13 +1123,13 @@ void Screen::rollCredits() {
// The music should either have stopped or be about to stop, so
// wait for it to really happen.
- while (_vm->_sound->musicTimeRemaining() && !_vm->_quit) {
+ while (_vm->_sound->musicTimeRemaining() && !_vm->quit()) {
updateDisplay(false);
_vm->_system->delayMillis(100);
}
}
- if (_vm->_quit)
+ if (_vm->quit())
return;
waitForFade();
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index 7331d1f761..3b6f51050b 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -33,6 +33,7 @@
#include "common/file.h"
#include "common/fs.h"
#include "common/events.h"
+#include "common/savefile.h"
#include "common/system.h"
#include "engines/metaengine.h"
@@ -82,6 +83,7 @@ public:
virtual GameList getSupportedGames() const;
virtual GameDescriptor findGame(const char *gameid) const;
virtual GameList detectGames(const FSList &fslist) const;
+ virtual SaveStateList listSaves(const char *target) const;
virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
};
@@ -156,6 +158,35 @@ GameList Sword2MetaEngine::detectGames(const FSList &fslist) const {
return detectedGames;
}
+SaveStateList Sword2MetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ char saveDesc[SAVE_DESCRIPTION_LEN];
+ Common::String pattern = target;
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ in->readUint32LE();
+ in->read(saveDesc, SAVE_DESCRIPTION_LEN);
+ saveList.push_back(SaveStateDescriptor(slotNum, Common::String(saveDesc), *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
PluginError Sword2MetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(syst);
assert(engine);
@@ -229,7 +260,6 @@ Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst) {
_gameCycle = 0;
_gameSpeed = 1;
- _quit = false;
syst->getEventManager()->registerRandomSource(_rnd, "sword2");
}
@@ -371,7 +401,7 @@ int Sword2Engine::init() {
// player will kill the music for us. Otherwise, the restore
// will either have killed the music, or done a crossfade.
- if (_quit)
+ if (quit())
return 0;
if (result)
@@ -443,7 +473,7 @@ int Sword2Engine::go() {
// because we want the break to happen before updating the
// screen again.
- if (_quit)
+ if (quit())
break;
// creates the debug text blocks
@@ -460,11 +490,7 @@ int Sword2Engine::go() {
#endif
}
- return 0;
-}
-
-void Sword2Engine::closeGame() {
- _quit = true;
+ return _eventMan->shouldRTL();
}
void Sword2Engine::restartGame() {
@@ -610,9 +636,6 @@ void Sword2Engine::parseInputEvents() {
_mouseEvent.buttons = RD_WHEELDOWN;
}
break;
- case Common::EVENT_QUIT:
- closeGame();
- break;
default:
break;
}
diff --git a/engines/sword2/sword2.h b/engines/sword2/sword2.h
index 05c5d7fa47..9b589c347e 100644
--- a/engines/sword2/sword2.h
+++ b/engines/sword2/sword2.h
@@ -141,8 +141,6 @@ public:
bool getSubtitles() { return _useSubtitles; }
void setSubtitles(bool b) { _useSubtitles = b; }
- bool _quit;
-
uint32 _features;
MemoryManager *_memory;
@@ -210,7 +208,6 @@ public:
void startGame();
void gameCycle();
- void closeGame();
void restartGame();
void sleepUntil(uint32 time);
diff --git a/engines/touche/detection.cpp b/engines/touche/detection.cpp
index d2798d7060..63d2a3a078 100644
--- a/engines/touche/detection.cpp
+++ b/engines/touche/detection.cpp
@@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/advancedDetector.h"
+#include "common/savefile.h"
#include "base/plugins.h"
@@ -136,6 +137,7 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
};
bool ToucheMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
@@ -146,6 +148,57 @@ bool ToucheMetaEngine::createInstance(OSystem *syst, Engine **engine, const Comm
return gd != 0;
}
+SaveStateList ToucheMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringList filenames;
+ char saveDesc[Touche::kGameStateDescriptionLen];
+ Common::String pattern = target;
+ pattern += ".?";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last digit of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 1);
+
+ if (slotNum >= 0 && slotNum <= 9) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ in->readUint16LE();
+ in->readUint16LE();
+ in->read(saveDesc, Touche::kGameStateDescriptionLen);
+ saveList.push_back(SaveStateDescriptor(slotNum, Common::String(saveDesc), *file));
+ delete in;
+ }
+ }
+ }
+
+ pattern += "?";
+
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 10 && slotNum <= 99) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ in->readUint16LE();
+ in->readUint16LE();
+ in->read(saveDesc, Touche::kGameStateDescriptionLen);
+ saveList.push_back(SaveStateDescriptor(slotNum, Common::String(saveDesc), *file));
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(TOUCHE)
REGISTER_PLUGIN_DYNAMIC(TOUCHE, PLUGIN_TYPE_ENGINE, ToucheMetaEngine);
#else
diff --git a/engines/touche/menu.cpp b/engines/touche/menu.cpp
index 6d2d90a572..82490fca38 100644
--- a/engines/touche/menu.cpp
+++ b/engines/touche/menu.cpp
@@ -297,7 +297,7 @@ void ToucheEngine::handleMenuAction(void *menu, int actionId) {
menuData->quit = true;
break;
case kActionQuitGame:
- _flagsTable[611] = 1;
+ quitGame();
menuData->quit = true;
break;
case kActionTextOnly:
@@ -395,10 +395,10 @@ void ToucheEngine::handleOptions(int forceDisplay) {
while (_eventMan->pollEvent(event)) {
const Button *button = 0;
switch (event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
menuData.quit = true;
menuData.exit = true;
- _flagsTable[611] = 1;
break;
case Common::EVENT_LBUTTONDOWN:
button = menuData.findButtonUnderCursor(event.mouse.x, event.mouse.y);
@@ -433,8 +433,9 @@ void ToucheEngine::handleOptions(int forceDisplay) {
_system->delayMillis(10);
}
_fullRedrawCounter = 2;
- if (!menuData.exit && _flagsTable[611] != 0) {
- _flagsTable[611] = displayQuitDialog();
+ if (!menuData.exit && quit()) {
+ if (displayQuitDialog())
+ quitGame();
}
}
}
@@ -556,6 +557,7 @@ int ToucheEngine::displayQuitDialog() {
Common::Event event;
while (_eventMan->pollEvent(event)) {
switch (event.type) {
+ case Common::EVENT_RTL:
case Common::EVENT_QUIT:
quitLoop = true;
ret = 1;
diff --git a/engines/touche/opcodes.cpp b/engines/touche/opcodes.cpp
index 4405c614ac..b2b16eb29d 100644
--- a/engines/touche/opcodes.cpp
+++ b/engines/touche/opcodes.cpp
@@ -408,6 +408,10 @@ void ToucheEngine::op_setFlag() {
case 104:
_currentKeyCharNum = val;
break;
+ case 611:
+ if (val != 0)
+ quitGame();
+ break;
case 612:
_flagsTable[613] = getRandomNumber(val);
break;
diff --git a/engines/touche/saveload.cpp b/engines/touche/saveload.cpp
index 4fcf6e114d..fedd40eb76 100644
--- a/engines/touche/saveload.cpp
+++ b/engines/touche/saveload.cpp
@@ -31,11 +31,6 @@
namespace Touche {
-enum {
- kCurrentGameStateVersion = 6,
- kGameStateDescriptionLen = 32
-};
-
static void saveOrLoad(Common::WriteStream &stream, uint16 &i) {
stream.writeUint16LE(i);
}
@@ -292,7 +287,7 @@ void ToucheEngine::loadGameStateData(Common::ReadStream *stream) {
if (stream->readUint32LE() != saveLoadEndMarker) {
warning("Corrupted gamestate data");
// if that ever happens, exit the game
- _flagsTable[611] = 1;
+ quitGame();
}
_flagsTable[614] = roomOffsX;
_flagsTable[615] = roomOffsY;
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index ac8e8a786a..a7a362f2b1 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -95,7 +95,7 @@ int ToucheEngine::init() {
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
return 0;
}
@@ -111,7 +111,7 @@ int ToucheEngine::go() {
res_deallocateTables();
res_closeDataFile();
- return 0;
+ return _eventMan->shouldRTL();
}
void ToucheEngine::restart() {
@@ -234,6 +234,13 @@ Common::Point ToucheEngine::getMousePos() const {
return _eventMan->getMousePos();
}
+void ToucheEngine::syncSoundSettings() {
+ readConfigurationSettings();
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+}
+
void ToucheEngine::mainLoop() {
restart();
@@ -245,10 +252,13 @@ void ToucheEngine::mainLoop() {
_inp_rightMouseButtonPressed = false;
if (ConfMan.hasKey("save_slot")) {
- loadGameState(ConfMan.getInt("save_slot"));
- _newEpisodeNum = 0;
- resetSortedKeyCharsTable();
- showCursor(true);
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 99) {
+ loadGameState(saveSlot);
+ _newEpisodeNum = 0;
+ resetSortedKeyCharsTable();
+ showCursor(true);
+ }
} else {
_newEpisodeNum = ConfMan.getInt("boot_param");
if (_newEpisodeNum == 0) {
@@ -258,7 +268,7 @@ void ToucheEngine::mainLoop() {
}
uint32 frameTimeStamp = _system->getMillis();
- for (uint32 cycleCounter = 0; _flagsTable[611] == 0; ++cycleCounter) {
+ for (uint32 cycleCounter = 0; !quit(); ++cycleCounter) {
if ((cycleCounter % 3) == 0) {
runCycle();
}
@@ -287,9 +297,6 @@ void ToucheEngine::processEvents(bool handleKeyEvents) {
Common::Event event;
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_QUIT:
- _flagsTable[611] = 1;
- break;
case Common::EVENT_KEYDOWN:
if (!handleKeyEvents) {
break;
@@ -297,7 +304,8 @@ void ToucheEngine::processEvents(bool handleKeyEvents) {
_flagsTable[600] = event.kbd.keycode;
if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
if (_displayQuitDialog) {
- _flagsTable[611] = displayQuitDialog();
+ if (displayQuitDialog())
+ quitGame();
}
} else if (event.kbd.keycode == Common::KEYCODE_F5) {
if (_flagsTable[618] == 0 && !_hideInventoryTexts) {
@@ -1828,7 +1836,7 @@ int ToucheEngine::handleActionMenuUnderCursor(const int16 *actions, int offs, in
_menuRedrawCounter = 2;
Common::Rect rect(0, y, kScreenWidth, y + h);
i = -1;
- while (_inp_rightMouseButtonPressed && _flagsTable[611] == 0) {
+ while (_inp_rightMouseButtonPressed && !quit()) {
Common::Point mousePos = getMousePos();
if (rect.contains(mousePos)) {
int c = (mousePos.y - y) / kTextHeight;
@@ -2691,10 +2699,10 @@ bool ToucheEngine::sortPointsData(int num1, int num2) {
const int md2 = _programWalkTable[num1].point2;
_programPointsTable[md2].order = 0;
}
- bool quit = false;
+ bool quitLoop = false;
int order = 1;
- while (!quit) {
- quit = true;
+ while (!quitLoop) {
+ quitLoop = true;
for (uint i = 0; i < _programWalkTable.size(); ++i) {
const int md1 = _programWalkTable[i].point1;
const int md2 = _programWalkTable[i].point2;
@@ -2702,11 +2710,11 @@ bool ToucheEngine::sortPointsData(int num1, int num2) {
assert((md2 & 0x4000) == 0);
if (_programPointsTable[md1].order == order - 1 && _programPointsTable[md2].order > order) {
_programPointsTable[md2].order = order;
- quit = false;
+ quitLoop = false;
}
if (_programPointsTable[md2].order == order - 1 && _programPointsTable[md1].order > order) {
_programPointsTable[md1].order = order;
- quit = false;
+ quitLoop = false;
}
}
}
@@ -2938,9 +2946,9 @@ void ToucheEngine::markWalkPoints(int keyChar) {
resetPointsData(0);
if (pointsDataNum != -1) {
_programPointsTable[pointsDataNum].order = 1;
- bool quit = false;
- while (!quit) {
- quit = true;
+ bool quitLoop = false;
+ while (!quitLoop) {
+ quitLoop = true;
for (uint i = 0; i < _programWalkTable.size(); ++i) {
int16 md1 = _programWalkTable[i].point1;
int16 md2 = _programWalkTable[i].point2;
@@ -2948,11 +2956,11 @@ void ToucheEngine::markWalkPoints(int keyChar) {
assert((md2 & 0x4000) == 0);
if (_programPointsTable[md1].order != 0 && _programPointsTable[md2].order == 0) {
_programPointsTable[md2].order = 1;
- quit = false;
+ quitLoop = false;
}
if (_programPointsTable[md2].order != 0 && _programPointsTable[md1].order == 0) {
_programPointsTable[md1].order = 1;
- quit = false;
+ quitLoop = false;
}
}
}
diff --git a/engines/touche/touche.h b/engines/touche/touche.h
index c1bc12655f..90ab9933bd 100644
--- a/engines/touche/touche.h
+++ b/engines/touche/touche.h
@@ -328,7 +328,9 @@ enum {
kCursorHeight = 42,
kTextHeight = 16,
kMaxProgramDataSize = 61440,
- kMaxSaveStates = 100
+ kMaxSaveStates = 100,
+ kGameStateDescriptionLen = 32, // Need these two values defined here
+ kCurrentGameStateVersion = 6 // for --list-saves support
};
class MidiPlayer;
@@ -356,6 +358,7 @@ public:
virtual int init();
virtual int go();
+ virtual void syncSoundSettings();
protected:
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 7cfe3943a7..2953988ed3 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -61,7 +61,9 @@ enum {
kAddGameCmd = 'ADDG',
kEditGameCmd = 'EDTG',
kRemoveGameCmd = 'REMG',
+ kLoadGameCmd = 'LOAD',
kQuitCmd = 'QUIT',
+ kChooseCmd = 'CHOS',
kCmdGlobalGraphicsOverride = 'OGFX',
@@ -468,6 +470,122 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
}
}
+class SaveLoadChooser : public GUI::Dialog {
+ typedef Common::String String;
+ typedef Common::StringList StringList;
+protected:
+ bool _saveMode;
+ GUI::ListWidget *_list;
+ GUI::ButtonWidget *_chooseButton;
+ GUI::GraphicsWidget *_gfxWidget;
+ GUI::ContainerWidget *_container;
+
+ uint8 _fillR, _fillG, _fillB;
+
+ void updateInfos(bool redraw);
+public:
+ SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode);
+ ~SaveLoadChooser();
+
+ virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+ const String &getResultString() const;
+ void setList(const StringList& list);
+ int runModal();
+
+ virtual void reflowLayout();
+};
+
+SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode)
+ : Dialog("scummsaveload"), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0) {
+
+ _drawingHints |= GUI::THEME_HINT_SPECIAL_COLOR;
+
+ new StaticTextWidget(this, "scummsaveload_title", title);
+
+ // Add choice list
+ _list = new GUI::ListWidget(this, "scummsaveload_list");
+ _list->setEditable(saveMode);
+ _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
+
+ _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);
+
+ // Buttons
+ new GUI::ButtonWidget(this, "scummsaveload_cancel", "Cancel", kCloseCmd, 0);
+ _chooseButton = new GUI::ButtonWidget(this, "scummsaveload_choose", buttonLabel, kChooseCmd, 0);
+ _chooseButton->setEnabled(false);
+}
+
+SaveLoadChooser::~SaveLoadChooser() {
+}
+
+const Common::String &SaveLoadChooser::getResultString() const {
+ return _list->getSelectedString();
+}
+
+void SaveLoadChooser::setList(const StringList& list) {
+ _list->setList(list);
+}
+
+int SaveLoadChooser::runModal() {
+ if (_gfxWidget)
+ _gfxWidget->setGfx(0);
+ 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 (_saveMode || !getResultString().empty()) {
+ _list->endEditMode();
+ setResult(selItem);
+ close();
+ }
+ }
+ break;
+ case kChooseCmd:
+ _list->endEditMode();
+ setResult(selItem);
+ close();
+ break;
+ case GUI::kListSelectionChangedCmd: {
+ if (_gfxWidget) {
+ updateInfos(true);
+ }
+
+ if (_saveMode) {
+ _list->startEditMode();
+ }
+ // Disable button if nothing is selected, or (in load mode) if an empty
+ // list item is selected. We allow choosing an empty item in save mode
+ // because we then just assign a default name.
+ _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().empty()));
+ _chooseButton->draw();
+ } break;
+ case kCloseCmd:
+ setResult(-1);
+ default:
+ Dialog::handleCommand(sender, cmd, data);
+ }
+}
+
+void SaveLoadChooser::reflowLayout() {
+ _container->setFlags(GUI::WIDGET_INVISIBLE);
+ _gfxWidget->setFlags(GUI::WIDGET_INVISIBLE);
+ Dialog::reflowLayout();
+}
+
+void SaveLoadChooser::updateInfos(bool redraw) {
+ _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB);
+ if (redraw)
+ _gfxWidget->draw();
+}
#pragma mark -
@@ -501,6 +619,8 @@ LauncherDialog::LauncherDialog()
new ButtonWidget(this, "launcher_options_button", "Options", kOptionsCmd, 'O');
_startButton =
new ButtonWidget(this, "launcher_start_button", "Start", kStartCmd, 'S');
+
+ new ButtonWidget(this, "launcher_loadGame_button", "Load", kLoadGameCmd, 'L');
// Above the lowest button rows: two more buttons (directly below the list box)
_addButton =
@@ -529,6 +649,9 @@ LauncherDialog::LauncherDialog()
// Create file browser dialog
_browser = new BrowserDialog("Select directory with game data", true);
+
+ // Create SaveLoad dialog
+ _loadDialog = new SaveLoadChooser("Load game:", "Load", false);
}
void LauncherDialog::selectGame(const String &name) {
@@ -795,6 +918,38 @@ void LauncherDialog::editGame(int item) {
}
}
+void LauncherDialog::loadGame(int item) {
+ int idx;
+ _loadDialog->setList(generateSavegameList(item));
+ idx = _loadDialog->runModal();
+ if (idx >= 0) {
+ ConfMan.setInt("save_slot", idx);
+ ConfMan.setActiveDomain(_domains[item]);
+ close();
+ }
+}
+
+Common::StringList LauncherDialog::generateSavegameList(int item) {
+ String gameId = ConfMan.get("gameid", _domains[item]);
+ if (gameId.empty())
+ gameId = _domains[item];
+
+ String description = _domains[item];
+ description.toLowercase();
+
+ const EnginePlugin *plugin = 0;
+ GameDescriptor game = EngineMan.findGame(gameId, &plugin);
+
+ SaveStateList saveList = (*plugin)->listSaves(description.c_str());
+ StringList saveNames;
+
+ for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) {
+ saveNames.push_back(x->description().c_str());
+ }
+
+ return saveNames;
+}
+
void LauncherDialog::handleKeyDown(Common::KeyState state) {
Dialog::handleKeyDown(state);
updateButtons();
@@ -818,6 +973,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();
diff --git a/gui/launcher.h b/gui/launcher.h
index a9d09bf109..cff6f2a8ba 100644
--- a/gui/launcher.h
+++ b/gui/launcher.h
@@ -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;
@@ -62,6 +61,7 @@ protected:
#endif
StringList _domains;
BrowserDialog *_browser;
+ SaveLoadChooser *_loadDialog;
virtual void reflowLayout();
@@ -73,6 +73,9 @@ protected:
virtual void addGame();
void removeGame(int item);
void editGame(int item);
+ void loadGame(int item);
+
+ StringList generateSavegameList(int item);
void selectGame(const String &name);
};
diff --git a/gui/newgui.cpp b/gui/newgui.cpp
index 618c7bc873..b892fe076a 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"
@@ -255,7 +256,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);
@@ -313,7 +314,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/theme-config.cpp b/gui/theme-config.cpp
index 47f60d3d7b..25507d2f13 100644
--- a/gui/theme-config.cpp
+++ b/gui/theme-config.cpp
@@ -171,10 +171,11 @@ const char *Theme::_defaultConfigINI =
"launcher_options_button=(prev.x2 + space) prev.y prev.w prev.h\n"
"launcher_start_button=(prev.x2 + space) prev.y prev.w prev.h\n"
"top=(top - buttonHeight * 2)\n"
-"numButtons=3\n"
+"numButtons=4\n"
"space=10\n"
"butWidth=((w - 2 * hBorder - space * (numButtons - 1)) / numButtons)\n"
-"launcher_addGame_button=hBorder top butWidth buttonHeight\n"
+"launcher_loadGame_button=hBorder top butWidth buttonHeight\n"
+"launcher_addGame_button=(prev.x2 + space) prev.y prev.w prev.h\n"
"launcher_editGame_button=(prev.x2 + space) prev.y prev.w prev.h\n"
"launcher_removeGame_button=(prev.x2 + space) prev.y prev.w prev.h\n"
"launcher_list=hBorder (kLineHeight + 16) (w - 2 * hBorder) (top - kLineHeight - 20)\n"
@@ -482,6 +483,28 @@ const char *Theme::_defaultConfigINI =
"smH=(smY + scummmainVSpace)\n"
"scummmain=((w - smW) / 2) ((h - smH) / 2) smW smH\n"
"\n"
+
+"#### Global Main Menu Dialog"
+"[globalmain]\n"
+"# note that globalmain size depends on overall height\n"
+"gmY=(scummmainVSpace + scummmainVAddOff)\n"
+"globalmain_resume=scummmainHOffset gmY scummmainButtonWidth scummmainButtonHeight\n"
+"gmY=(gmY + scummmainButtonHeight + scummmainVAddOff)\n"
+"gmY=(gmY + scummmainVSpace)\n"
+"globalmain_options=prev.x gmY prev.w prev.h\n"
+"gmY=(gmY + scummmainButtonHeight + scummmainVAddOff)\n"
+"globalmain_about=prev.x gmY prev.w prev.h\n"
+"gmY=(gmY + scummmainButtonHeight + scummmainVAddOff)\n"
+"gmY=(gmY + scummmainVSpace)\n"
+"globalmain_rtl=prev.x gmY prev.w prev.h\n"
+"gmY=(gmY + scummmainButtonHeight + scummmainVAddOff)\n"
+"gmW=(scummmainButtonWidth + 2 * scummmainHOffset)\n"
+"globalmain_quit=prev.x gmY prev.w prev.h\n"
+"gmY=(gmY + scummmainButtonHeight + scummmainVAddOff)\n"
+"gmW=(scummmainButtonWidth + 2 * scummmainHOffset)\n"
+"gmH=(gmY + scummmainVSpace)\n"
+"globalmain=((w - gmW) / 2) ((h - gmH) / 2) gmW gmH\n"
+"\n"
"# PSP GUI\n"
"[480x272]\n"
"def_buttonWidth=100\n"
diff --git a/gui/themes/classic080.ini b/gui/themes/classic080.ini
index b5c911bada..83713eafd1 100644
--- a/gui/themes/classic080.ini
+++ b/gui/themes/classic080.ini
@@ -82,13 +82,14 @@ hBorder=10
launcher_version=hBorder 8 (w - 2 * hBorder) kLineHeight
launcher_version.align=kTextAlignCenter
top=(h - 8 - buttonHeight)
-numButtons=4
+numButtons=3
space=8
butWidth=((w - 2 * hBorder - space * (numButtons - 1)) / numButtons)
launcher_quit_button=hBorder top butWidth buttonHeight
launcher_about_button=(prev.x2 + space) prev.y prev.w prev.h
launcher_options_button=(prev.x2 + space) prev.y prev.w prev.h
launcher_start_button=(prev.x2 + space) prev.y prev.w prev.h
+launcher_loadGame_button=(prev.x2 + space) prev.y prev.w prev.h
top=(top - buttonHeight * 2)
numButtons=3
space=10
diff --git a/gui/themes/modern.ini b/gui/themes/modern.ini
index 87ef0bcbb9..77c7237451 100644
--- a/gui/themes/modern.ini
+++ b/gui/themes/modern.ini
@@ -250,6 +250,7 @@ space1=20
space2=5
launcher_list=insetX insetY insetW insetH
launcher_start_button=(prev.x2 + 17) prev.y buttonWidth buttonHeight
+launcher_loadGame_button=prev.x (prev.y2 + space2) prev.w prev.h
launcher_addGame_button=prev.x (prev.y2 + space1) prev.w prev.h
launcher_editGame_button=prev.x (prev.y2 + space2) prev.w prev.h
launcher_removeGame_button=prev.x (prev.y2 + space2) prev.w prev.h