diff options
Diffstat (limited to 'engines')
162 files changed, 1428 insertions, 659 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/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/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..32c4991a15 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -220,13 +220,31 @@ int Parallaction_ns::go() { _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 +462,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: |