diff options
Diffstat (limited to 'engines')
165 files changed, 1450 insertions, 683 deletions
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 ¶ms) {  	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 ¶ms) {  			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 ¶ms) {  			_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 ¶ms) {  		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 ¶ms) {  		} 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:  | 
