void MainMenuDialog::save() { int slot = _saveDialog->runModalWithCurrentTarget(); #if defined(__PLAYSTATION2__) && defined(DYNAMIC_MODULES) char pokeme[32]; snprintf(pokeme,32,"hack"); #endif if (slot >= 0) { Common::String result(_saveDialog->getResultString()); if (result.empty()) { // If the user was lazy and entered no save name, come up with a default name. result = _saveDialog->createDefaultSaveDescription(slot); } Common::Error status = _engine->saveGameState(slot, result); if (status.getCode() != Common::kNoError) { Common::String failMessage = Common::String::format(_("Gamestate save failed (%s)! " "Please consult the README for basic information, and for " "instructions on how to obtain further assistance."), status.getDesc().c_str()); GUI::MessageDialog dialog(failMessage); dialog.runModal(); } close(); } }
void Engine::openMainMenuDialog() { if (!_mainMenuDialog) _mainMenuDialog = new MainMenuDialog(this); setGameToLoadSlot(-1); runDialog(*_mainMenuDialog); // Load savegame after main menu execution // (not from inside the menu loop to avoid // mouse cursor glitches and simliar bugs, // e.g. #2822778). if (_saveSlotToLoad >= 0) { Common::Error status = loadGameState(_saveSlotToLoad); if (status.getCode() != Common::kNoError) { Common::String failMessage = Common::String::format(_("Gamestate load failed (%s)! " "Please consult the README for basic information, and for " "instructions on how to obtain further assistance."), status.getDesc().c_str()); GUI::MessageDialog dialog(failMessage); dialog.runModal(); } } syncSoundSettings(); }
void MohawkEngine_Riven::loadGameStateAndDisplayError(int slot) { assert(slot >= 0); Common::Error loadError = loadGameState(slot); if (loadError.getCode() != Common::kNoError) { GUI::MessageDialog dialog(loadError.getDesc()); dialog.runModal(); } }
Common::Error Pink::PinkEngine::run() { Common::Error error = init(); if (error.getCode() != Common::kNoError) return error; while (!shouldQuit()) { Common::Event event; while (_eventMan->pollEvent(event)) { if (_director->processEvent(event)) continue; switch (event.type) { case Common::EVENT_QUIT: case Common::EVENT_RTL: return Common::kNoError; case Common::EVENT_MOUSEMOVE: _actor->onMouseMove(event.mouse); break; case Common::EVENT_LBUTTONDOWN: _actor->onLeftButtonClick(event.mouse); break; case Common::EVENT_LBUTTONUP: _actor->onLeftButtonUp(); break; case Common::EVENT_RBUTTONDOWN: if (isPeril()) _actor->onRightButtonClick(event.mouse); break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) { _console->attach(); _console->onFrame(); } else { _actor->onKeyboardButtonClick(event.kbd.keycode); } break; default: break; } } _actor->update(); _director->update(); _system->delayMillis(10); } return Common::kNoError; }
Common::Error Sword25Engine::run() { // Engine initialisation Common::Error error = appStart(); if (error.getCode() != Common::kNoError) { appEnd(); return error; } // Run the game bool runSuccess = appMain(); // Engine de-initialisation bool deinitSuccess = appEnd(); return (runSuccess && deinitSuccess) ? Common::kNoError : Common::kUnknownError; }
TestExitStatus SaveGametests::testErrorMessages() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); saveFileMan->clearError(); // Try opening a non existing file readAndVerifyData("tBedSomeNonExistentSaveFile.0", "File doesn't exists!"); Common::Error err = saveFileMan->getError(); if (err.getCode() == Common::kNoError) { // blunder! how come? Testsuite::logDetailedPrintf("SaveFileMan.getError() failed\n"); return kTestFailed; } // Can't actually predict whether which error, kInvalidPath or kPathDoesNotExist or some other? // So just return kTestPassed if some error Testsuite::logDetailedPrintf("getError returned : %s\n", saveFileMan->getErrorDesc().c_str()); return kTestPassed; }
Common::Error DarkMoonEngine::init() { Common::Error err = EoBCoreEngine::init(); if (err.getCode() != Common::kNoError) return err; initStaticResource(); _monsterProps = new EoBMonsterProperty[10]; if (_configRenderMode == Common::kRenderEGA) { Palette pal(16); _screen->loadPalette(_egaDefaultPalette, pal, 16); _screen->setScreenPalette(pal); } _screen->loadPalette("PALETTE.COL", _screen->getPalette(0)); _screen->setScreenPalette(_screen->getPalette(0)); return Common::kNoError; }
TestExitStatus SaveGametests::testListingSavefile() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); saveFileMan->clearError(); // create some savefiles const char *savefileName[] = {"tBedSavefileToList.0", "tBedSavefileToList.1", "tBedSavefileToList.2"}; writeDataToFile("tBedSavefileToList.0", "Save me!"); writeDataToFile("tBedSavefileToList.1", "Save me!"); writeDataToFile("tBedSavefileToList.2", "Save me!"); Common::Error err = saveFileMan->getError(); if (err.getCode() != Common::kNoError) { // Abort. Some Error in writing files Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", err.getDesc().c_str()); return kTestFailed; } Common::StringArray savefileList = saveFileMan->listSavefiles("tBedSavefileToList.?"); if (savefileList.size() == ARRAYSIZE(savefileName)) { // Match them exactly // As the order of savefileList may be platform specific, match them exhaustively for (uint i = 0; i < ARRAYSIZE(savefileName); i++) { for (uint j = 0; j < savefileList.size(); j++) { if (savefileList[j].equals(savefileName[i])) { break; } if (savefileList.size() == j) { // A match for this name not found Testsuite::logDetailedPrintf("Listed Names don't match\n"); return kTestFailed; } } } return kTestPassed; } Testsuite::logDetailedPrintf("listing Savefiles failed!\n"); return kTestFailed; }
bool EventRecorder::switchMode() { const Common::String gameId = ConfMan.get("gameid"); const EnginePlugin *plugin = 0; EngineMan.findGame(gameId, &plugin); bool metaInfoSupport = (*plugin)->hasFeature(MetaEngine::kSavesSupportMetaInfo); bool featuresSupport = metaInfoSupport && g_engine->canSaveGameStateCurrently() && (*plugin)->hasFeature(MetaEngine::kSupportsListSaves) && (*plugin)->hasFeature(MetaEngine::kSupportsDeleteSave); if (!featuresSupport) { return false; } int emptySlot = 1; SaveStateList saveList = (*plugin)->listSaves(gameId.c_str()); for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { int saveSlot = x->getSaveSlot(); if (saveSlot == 0) { continue; } if (emptySlot != saveSlot) { break; } emptySlot++; } Common::String saveName; if (emptySlot >= 0) { saveName = Common::String::format("Save %d", emptySlot + 1); Common::Error status = g_engine->saveGameState(emptySlot, saveName); if (status.getCode() == Common::kNoError) { Common::Event eventRTL; eventRTL.type = Common::EVENT_RTL; g_system->getEventManager()->pushEvent(eventRTL); } } ConfMan.set("record_mode", "", Common::ConfigManager::kTransientDomain); ConfMan.setInt("save_slot", emptySlot, Common::ConfigManager::kTransientDomain); _needcontinueGame = true; return true; }
Common::Error GagEngine::run() { Init(); Common::Error status; do { // do periodic processing uint32 time_start = _system->getMillis(); status = Update(); uint32 time_end = _system->getMillis(); // wrap around check uint32 time_spent = time_end >= time_start ? time_end - time_start : std::numeric_limits<uint32>::max() - time_start + time_end + 1; // sleep remaining frame time uint time_for_frame = 1000 / _SCREEN_FPS; _system->delayMillis(time_spent < time_for_frame ? time_for_frame - time_spent : 0); } while(status.getCode() == Common::kNoError && !shouldQuit()); return status; }
// TODO: specify the possible return values here static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const Common::String &edebuglevels) { // Determine the game data path, for validation and error messages Common::FSNode dir(ConfMan.get("path")); Common::Error err = Common::kNoError; Engine *engine = 0; // Verify that the game path refers to an actual directory if (!(dir.exists() && dir.isDirectory())) err = Common::kPathNotDirectory; // Create the game engine if (err.getCode() == Common::kNoError) err = (*plugin)->createInstance(&system, &engine); // Check for errors if (!engine || err.getCode() != Common::kNoError) { // Print a warning; note that scummvm_main will also // display an error dialog, so we don't have to do this here. warning("%s failed to instantiate engine: %s (target '%s', path '%s')", plugin->getName(), err.getDesc().c_str(), ConfMan.getActiveDomainName().c_str(), dir.getPath().c_str() ); // Autoadded is set only when no path was provided and // the game is run from command line. // // Thus, we remove this garbage entry // // Fixes bug #1544799 if (ConfMan.hasKey("autoadded")) { ConfMan.removeGameDomain(ConfMan.getActiveDomainName().c_str()); } return err; } // Set the window caption to the game name Common::String caption(ConfMan.get("description")); if (caption.empty()) { caption = EngineMan.findGame(ConfMan.get("gameid")).description(); } if (caption.empty()) caption = ConfMan.getActiveDomainName(); // Use the domain (=target) name if (!caption.empty()) { system.setWindowCaption(caption.c_str()); } // // Setup various paths in the SearchManager // // Add the game path to the directory search list SearchMan.addDirectory(dir.getPath(), dir, 0, 4); // Add extrapath (if any) to the directory search list if (ConfMan.hasKey("extrapath")) { dir = Common::FSNode(ConfMan.get("extrapath")); SearchMan.addDirectory(dir.getPath(), dir); } // If a second extrapath is specified on the app domain level, add that as well. if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) { dir = Common::FSNode(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain)); SearchMan.addDirectory(dir.getPath(), dir); } // On creation the engine should have set up all debug levels so we can use // the command line arugments here Common::StringTokenizer tokenizer(edebuglevels, " ,"); while (!tokenizer.empty()) { Common::String token = tokenizer.nextToken(); if (!DebugMan.enableDebugChannel(token)) warning(_("Engine does not support debug level '%s'"), token.c_str()); } // Inform backend that the engine is about to be run system.engineInit(); // Run the engine Common::Error result = engine->run(); // Inform backend that the engine finished system.engineDone(); // Free up memory delete engine; // We clear all debug levels again even though the engine should do it DebugMan.clearAllDebugChannels(); // Reset the file/directory mappings SearchMan.clear(); // Return result (== 0 means no error) return result; }
extern "C" int scummvm_main(int argc, const char * const argv[]) { Common::String specialDebug; Common::String command; // Verify that the backend has been initialized (i.e. g_system has been set). assert(g_system); OSystem &system = *g_system; // Register config manager defaults Base::registerDefaults(); // Parse the command line Common::StringMap settings; command = Base::parseCommandLine(settings, argc, argv); // Load the config file (possibly overridden via command line): if (settings.contains("config")) { ConfMan.loadConfigFile(settings["config"]); settings.erase("config"); } else { ConfMan.loadDefaultConfigFile(); } // Update the config file ConfMan.set("versioninfo", gScummVMVersion, Common::ConfigManager::kApplicationDomain); // Load and setup the debuglevel and the debug flags. We do this at the // soonest possible moment to ensure debug output starts early on, if // requested. if (settings.contains("debuglevel")) { gDebugLevel = (int)strtol(settings["debuglevel"].c_str(), 0, 10); printf("Debuglevel (from command line): %d\n", gDebugLevel); settings.erase("debuglevel"); // This option should not be passed to ConfMan. } else if (ConfMan.hasKey("debuglevel")) gDebugLevel = ConfMan.getInt("debuglevel"); if (settings.contains("debugflags")) { specialDebug = settings["debugflags"]; settings.erase("debugflags"); } PluginManager::instance().init(); PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager // If we received an invalid music parameter via command line we check this here. // We can't check this before loading the music plugins. // On the other hand we cannot load the plugins before we know the file paths (in case of external plugins). if (settings.contains("music-driver")) { if (MidiDriver::getMusicType(MidiDriver::getDeviceHandle(settings["music-driver"])) == MT_INVALID) { warning("Unrecognized music driver '%s'. Switching to default device", settings["music-driver"].c_str()); settings["music-driver"] = "auto"; } } // Process the remaining command line settings. Must be done after the // config file and the plugins have been loaded. Common::Error res; // TODO: deal with settings that require plugins to be loaded res = Base::processSettings(command, settings); if (res.getCode() != Common::kArgumentNotProcessed) { warning("%s", res.getDesc().c_str()); return res.getCode(); } // Init the backend. Must take place after all config data (including // the command line params) was read. system.initBackend(); // If we received an invalid graphics mode parameter via command line // we check this here. We can't do it until after the backend is inited, // or there won't be a graphics manager to ask for the supported modes. if (settings.contains("gfx-mode")) { const OSystem::GraphicsMode *gm = g_system->getSupportedGraphicsModes(); Common::String option = settings["gfx-mode"]; bool isValid = false; while (gm->name && !isValid) { isValid = !scumm_stricmp(gm->name, option.c_str()); gm++; } if (!isValid) { warning("Unrecognized graphics mode '%s'. Switching to default mode", option.c_str()); settings["gfx-mode"] = "default"; } } setupGraphics(system); // Init the different managers that are used by the engines. // Do it here to prevent fragmentation later system.getAudioCDManager(); MusicManager::instance(); Common::DebugManager::instance(); // Init the event manager. As the virtual keyboard is loaded here, it must // take place after the backend is initiated and the screen has been setup system.getEventManager()->init(); // Directly after initializing the event manager, we will initialize our // event recorder. // // TODO: This is just to match the current behavior, when we further extend // our event recorder, we might do this at another place. Or even change // the whole API for that ;-). g_eventRec.init(); // Now as the event manager is created, setup the keymapper setupKeymapper(system); // Unless a game was specified, show the launcher dialog if (0 == ConfMan.getActiveDomain()) launcherDialog(); // FIXME: We're now looping the launcher. This, of course, doesn't // work as well as it should. In theory everything should be destroyed // cleanly, so this is now enabled to encourage people to fix bits :) while (0 != ConfMan.getActiveDomain()) { // Try to find a plugin which feels responsible for the specified game. const EnginePlugin *plugin = detectPlugin(); if (plugin) { // Unload all plugins not needed for this game, // to save memory PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin); // Try to run the game Common::Error result = runGame(plugin, system, specialDebug); #if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES) // do our best to prevent fragmentation by unloading as soon as we can PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // reallocate the config manager to get rid of any fragmentation ConfMan.defragment(); #endif // Did an error occur ? if (result.getCode() != Common::kNoError) { // Shows an informative error dialog if starting the selected game failed. GUI::displayErrorDialog(result, _("Error running game:")); } // Quit unless an error occurred, or Return to launcher was requested #ifndef FORCE_RTL if (result.getCode() == Common::kNoError && !g_system->getEventManager()->shouldRTL()) break; #endif // Reset RTL flag in case we want to load another engine g_system->getEventManager()->resetRTL(); #ifdef FORCE_RTL g_system->getEventManager()->resetQuit(); #endif // Discard any command line options. It's unlikely that the user // wanted to apply them to *all* games ever launched. ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear(); // Clear the active config domain ConfMan.setActiveDomain(""); PluginManager::instance().loadAllPlugins(); // only for cached manager } else { GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game")); } // reset the graphics to default setupGraphics(system); launcherDialog(); } PluginManager::instance().unloadAllPlugins(); PluginManager::destroy(); GUI::GuiManager::destroy(); Common::ConfigManager::destroy(); Common::SearchManager::destroy(); #ifdef USE_TRANSLATION Common::TranslationManager::destroy(); #endif return 0; }
Common::Error MohawkEngine_Riven::run() { MohawkEngine::run(); // Let's try to open the installer file (it holds extras.mhk) // Though, we set a low priority to prefer the extracted version if (_installerArchive.open("arcriven.z")) SearchMan.add("arcriven.z", &_installerArchive, 0, false); _gfx = new RivenGraphics(this); _video = new RivenVideoManager(this); _sound = new RivenSoundManager(this); _console = new RivenConsole(this); _saveLoad = new RivenSaveLoad(this, _saveFileMan); _optionsDialog = new RivenOptionsDialog(this); _scriptMan = new RivenScriptManager(this); _inventory = new RivenInventory(this); _rnd = new Common::RandomSource("riven"); // Create the cursor manager if (Common::File::exists("rivendmo.exe")) _cursor = new PECursorManager("rivendmo.exe"); else if (Common::File::exists("riven.exe")) _cursor = new PECursorManager("riven.exe"); else // last resort: try the Mac executable _cursor = new MacCursorManager("Riven"); initVars(); // Check the user has copied all the required datafiles if (!checkDatafiles()) { return Common::kNoGameDataFoundError; } // We need to have a cursor source, or the game won't work if (!_cursor->hasSource()) { Common::String message = _("You're missing a Riven executable. The Windows executable is 'riven.exe' or 'rivendmo.exe'. "); message += _("Using the 'arcriven.z' installer file also works. In addition, you can use the Mac 'Riven' executable."); GUIErrorMessage(message); warning("%s", message.c_str()); return Common::kNoGameDataFoundError; } // Open extras.mhk for common images _extrasFile = new MohawkArchive(); // We need extras.mhk for inventory images, marble images, and credits images if (!_extrasFile->openFile("extras.mhk")) { Common::String message = _("You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also works."); GUIErrorMessage(message); warning("%s", message.c_str()); return Common::kNoGameDataFoundError; } // Set the transition speed _gfx->setTransitionMode((RivenTransitionMode) _vars["transitionmode"]); // Start at main cursor _cursor->setCursor(kRivenMainCursor); _cursor->showCursor(); // Let's begin, shall we? if (getFeatures() & GF_DEMO) { // Start the demo off with the videos changeToStack(kStackAspit); changeToCard(6); } else if (ConfMan.hasKey("save_slot")) { // Load game from launcher/command line if requested int gameToLoad = ConfMan.getInt("save_slot"); // Attempt to load the game. Common::Error loadError = _saveLoad->loadGame(gameToLoad); if (loadError.getCode() != Common::kNoError) { return loadError; } } else { // Otherwise, start us off at aspit's card 1 (the main menu) changeToStack(kStackAspit); changeToCard(1); } while (!hasGameEnded()) doFrame(); return Common::kNoError; }
void SaveLoadMenuScreen::checkError(Common::Error error) { if (error.getCode() != Common::kNoError) { GUI::MessageDialog dialog(error.getDesc()); dialog.runModal(); } }
// TODO: specify the possible return values here static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const Common::String &edebuglevels) { // Determine the game data path, for validation and error messages Common::FSNode dir(ConfMan.get("path")); Common::Error err = Common::kNoError; Engine *engine = 0; #if defined(SDL_BACKEND) && defined(USE_OPENGL) && defined(USE_RGB_COLOR) // HACK: We set up the requested graphics mode setting here to allow the // backend to switch from Surface SDL to OpenGL if necessary. This is // needed because otherwise the g_system->getSupportedFormats might return // bad values. g_system->beginGFXTransaction(); g_system->setGraphicsMode(ConfMan.get("gfx_mode").c_str()); if (g_system->endGFXTransaction() != OSystem::kTransactionSuccess) { warning("Switching graphics mode to '%s' failed", ConfMan.get("gfx_mode").c_str()); return Common::kUnknownError; } #endif // Verify that the game path refers to an actual directory if (!dir.exists()) { err = Common::kPathDoesNotExist; } else if (!dir.isDirectory()) { err = Common::kPathNotDirectory; } // Create the game engine if (err.getCode() == Common::kNoError) { // Set default values for all of the custom engine options // Appareantly some engines query them in their constructor, thus we // need to set this up before instance creation. const ExtraGuiOptions engineOptions = (*plugin)->getExtraGuiOptions(Common::String()); for (uint i = 0; i < engineOptions.size(); i++) { ConfMan.registerDefault(engineOptions[i].configOption, engineOptions[i].defaultState); } err = (*plugin)->createInstance(&system, &engine); } // Check for errors if (!engine || err.getCode() != Common::kNoError) { // Print a warning; note that scummvm_main will also // display an error dialog, so we don't have to do this here. warning("%s failed to instantiate engine: %s (target '%s', path '%s')", plugin->getName(), err.getDesc().c_str(), ConfMan.getActiveDomainName().c_str(), dir.getPath().c_str() ); // Autoadded is set only when no path was provided and // the game is run from command line. // // Thus, we remove this garbage entry // // Fixes bug #1544799 if (ConfMan.hasKey("autoadded")) { ConfMan.removeGameDomain(ConfMan.getActiveDomainName().c_str()); } return err; } // Set the window caption to the game name Common::String caption(ConfMan.get("description")); if (caption.empty()) { caption = EngineMan.findGame(ConfMan.get("gameid")).description(); } if (caption.empty()) caption = ConfMan.getActiveDomainName(); // Use the domain (=target) name if (!caption.empty()) { system.setWindowCaption(caption.c_str()); } // // Setup various paths in the SearchManager // // Add the game path to the directory search list engine->initializePath(dir); // Add extrapath (if any) to the directory search list if (ConfMan.hasKey("extrapath")) { dir = Common::FSNode(ConfMan.get("extrapath")); SearchMan.addDirectory(dir.getPath(), dir); } // If a second extrapath is specified on the app domain level, add that as well. // However, since the default hasKey() and get() check the app domain level, // verify that it's not already there before adding it. The search manager will // check for that too, so this check is mostly to avoid a warning message. if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) { Common::String extraPath = ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain); if (!SearchMan.hasArchive(extraPath)) { dir = Common::FSNode(extraPath); SearchMan.addDirectory(dir.getPath(), dir); } } // On creation the engine should have set up all debug levels so we can use // the command line arguments here Common::StringTokenizer tokenizer(edebuglevels, " ,"); while (!tokenizer.empty()) { Common::String token = tokenizer.nextToken(); if (token.equalsIgnoreCase("all")) DebugMan.enableAllDebugChannels(); else if (!DebugMan.enableDebugChannel(token)) warning(_("Engine does not support debug level '%s'"), token.c_str()); } // Initialize any game-specific keymaps engine->initKeymap(); // Inform backend that the engine is about to be run system.engineInit(); // Run the engine Common::Error result = engine->run(); // Inform backend that the engine finished system.engineDone(); // Clean up any game-specific keymaps engine->deinitKeymap(); // Free up memory delete engine; // We clear all debug levels again even though the engine should do it DebugMan.clearAllDebugChannels(); // Reset the file/directory mappings SearchMan.clear(); // Return result (== 0 means no error) return result; }
extern "C" int scummvm_main(int argc, const char * const argv[]) { Common::String specialDebug; Common::String command; // Verify that the backend has been initialized (i.e. g_system has been set). assert(g_system); OSystem &system = *g_system; // Register config manager defaults Base::registerDefaults(); // Parse the command line Common::StringMap settings; command = Base::parseCommandLine(settings, argc, argv); // Load the config file (possibly overridden via command line): if (settings.contains("config")) { ConfMan.loadConfigFile(settings["config"]); settings.erase("config"); } else { ConfMan.loadDefaultConfigFile(); } // Update the config file ConfMan.set("versioninfo", gScummVMVersion, Common::ConfigManager::kApplicationDomain); // Load and setup the debuglevel and the debug flags. We do this at the // soonest possible moment to ensure debug output starts early on, if // requested. if (settings.contains("debuglevel")) { gDebugLevel = (int)strtol(settings["debuglevel"].c_str(), 0, 10); printf("Debuglevel (from command line): %d\n", gDebugLevel); settings.erase("debuglevel"); // This option should not be passed to ConfMan. } else if (ConfMan.hasKey("debuglevel")) gDebugLevel = ConfMan.getInt("debuglevel"); if (settings.contains("debugflags")) { specialDebug = settings["debugflags"]; settings.erase("debugflags"); } else if (ConfMan.hasKey("debugflags")) specialDebug = ConfMan.get("debugflags"); if (settings.contains("debug-channels-only")) gDebugChannelsOnly = true; PluginManager::instance().init(); PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager // If we received an invalid music parameter via command line we check this here. // We can't check this before loading the music plugins. // On the other hand we cannot load the plugins before we know the file paths (in case of external plugins). if (settings.contains("music-driver")) { if (MidiDriver::getMusicType(MidiDriver::getDeviceHandle(settings["music-driver"])) == MT_INVALID) { warning("Unrecognized music driver '%s'. Switching to default device", settings["music-driver"].c_str()); settings["music-driver"] = "auto"; } } // Process the remaining command line settings. Must be done after the // config file and the plugins have been loaded. Common::Error res; // TODO: deal with settings that require plugins to be loaded if (Base::processSettings(command, settings, res)) { if (res.getCode() != Common::kNoError) warning("%s", res.getDesc().c_str()); return res.getCode(); } // Init the backend. Must take place after all config data (including // the command line params) was read. system.initBackend(); // If we received an invalid graphics mode parameter via command line // we check this here. We can't do it until after the backend is inited, // or there won't be a graphics manager to ask for the supported modes. if (settings.contains("gfx-mode")) { const OSystem::GraphicsMode *gm = g_system->getSupportedGraphicsModes(); Common::String option = settings["gfx-mode"]; bool isValid = false; while (gm->name && !isValid) { isValid = !scumm_stricmp(gm->name, option.c_str()); gm++; } if (!isValid) { warning("Unrecognized graphics mode '%s'. Switching to default mode", option.c_str()); settings["gfx-mode"] = "default"; } } if (settings.contains("disable-display")) { ConfMan.setInt("disable-display", 1, Common::ConfigManager::kTransientDomain); } setupGraphics(system); // Init the different managers that are used by the engines. // Do it here to prevent fragmentation later system.getAudioCDManager(); MusicManager::instance(); Common::DebugManager::instance(); // Init the event manager. As the virtual keyboard is loaded here, it must // take place after the backend is initiated and the screen has been setup system.getEventManager()->init(); #ifdef ENABLE_EVENTRECORDER // Directly after initializing the event manager, we will initialize our // event recorder. // // TODO: This is just to match the current behavior, when we further extend // our event recorder, we might do this at another place. Or even change // the whole API for that ;-). g_eventRec.RegisterEventSource(); #endif Common::OSDMessageQueue::instance().registerEventSource(); // Now as the event manager is created, setup the keymapper setupKeymapper(system); #ifdef USE_UPDATES if (!ConfMan.hasKey("updates_check") && g_system->getUpdateManager()) { GUI::UpdatesDialog dlg; dlg.runModal(); } #endif #if defined(USE_CLOUD) && defined(USE_LIBCURL) CloudMan.init(); CloudMan.syncSaves(); #endif // Unless a game was specified, show the launcher dialog if (0 == ConfMan.getActiveDomain()) launcherDialog(); // FIXME: We're now looping the launcher. This, of course, doesn't // work as well as it should. In theory everything should be destroyed // cleanly, so this is now enabled to encourage people to fix bits :) while (0 != ConfMan.getActiveDomain()) { // Try to find a plugin which feels responsible for the specified game. const EnginePlugin *plugin = detectPlugin(); if (plugin) { // Unload all plugins not needed for this game, // to save memory PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin); #ifdef ENABLE_EVENTRECORDER Common::String recordMode = ConfMan.get("record_mode"); Common::String recordFileName = ConfMan.get("record_file_name"); if (recordMode == "record") { g_eventRec.init(g_eventRec.generateRecordFileName(ConfMan.getActiveDomainName()), GUI::EventRecorder::kRecorderRecord); } else if (recordMode == "playback") { g_eventRec.init(recordFileName, GUI::EventRecorder::kRecorderPlayback); } else if ((recordMode == "info") && (!recordFileName.empty())) { Common::PlaybackFile record; record.openRead(recordFileName); debug("info:author=%s name=%s description=%s", record.getHeader().author.c_str(), record.getHeader().name.c_str(), record.getHeader().description.c_str()); break; } #endif // Try to run the game Common::Error result = runGame(plugin, system, specialDebug); #ifdef ENABLE_EVENTRECORDER // Flush Event recorder file. The recorder does not get reinitialized for next game // which is intentional. Only single game per session is allowed. g_eventRec.deinit(); #endif #if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES) // do our best to prevent fragmentation by unloading as soon as we can PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // reallocate the config manager to get rid of any fragmentation ConfMan.defragment(); #endif // Did an error occur ? if (result.getCode() != Common::kNoError && result.getCode() != Common::kUserCanceled) { // Shows an informative error dialog if starting the selected game failed. GUI::displayErrorDialog(result, _("Error running game:")); } // Quit unless an error occurred, or Return to launcher was requested #ifndef FORCE_RTL if (result.getCode() == Common::kNoError && !g_system->getEventManager()->shouldRTL()) break; #endif // Reset RTL flag in case we want to load another engine g_system->getEventManager()->resetRTL(); #ifdef FORCE_RTL g_system->getEventManager()->resetQuit(); #endif #ifdef ENABLE_EVENTRECORDER if (g_eventRec.checkForContinueGame()) { continue; } #endif // At this point, we usually return to the launcher. However, the // game may have requested that one or more other games be "chained" // to the current one, with optional save slots to start the games // at. At the time of writing, this is used for the Maniac Mansion // easter egg in Day of the Tentacle. Common::String chainedGame; int saveSlot = -1; ChainedGamesMan.pop(chainedGame, saveSlot); // Discard any command line options. It's unlikely that the user // wanted to apply them to *all* games ever launched. ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear(); if (!chainedGame.empty()) { if (saveSlot != -1) { ConfMan.setInt("save_slot", saveSlot, Common::ConfigManager::kTransientDomain); } // Start the chained game ConfMan.setActiveDomain(chainedGame); } else { // Clear the active config domain ConfMan.setActiveDomain(""); } PluginManager::instance().loadAllPlugins(); // only for cached manager } else { GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game")); // Clear the active domain ConfMan.setActiveDomain(""); } // reset the graphics to default setupGraphics(system); if (0 == ConfMan.getActiveDomain()) { launcherDialog(); } } #ifdef USE_CLOUD #ifdef USE_SDL_NET Networking::LocalWebserver::destroy(); #endif #ifdef USE_LIBCURL Networking::ConnectionManager::destroy(); //I think it's important to destroy it after ConnectionManager Cloud::CloudManager::destroy(); #endif #endif PluginManager::instance().unloadAllPlugins(); PluginManager::destroy(); GUI::GuiManager::destroy(); Common::ConfigManager::destroy(); Common::DebugManager::destroy(); Common::OSDMessageQueue::destroy(); #ifdef ENABLE_EVENTRECORDER GUI::EventRecorder::destroy(); #endif Common::SearchManager::destroy(); #ifdef USE_TRANSLATION Common::TranslationManager::destroy(); #endif MusicManager::destroy(); Graphics::CursorManager::destroy(); Graphics::FontManager::destroy(); #ifdef USE_FREETYPE2 Graphics::shutdownTTF(); #endif EngineManager::destroy(); Graphics::YUVToRGBManager::destroy(); return 0; }
Common::Error GobEngine::run() { Common::Error err; err = initGameParts(); if (err.getCode() != Common::kNoError) return err; err = initGraphics(); if (err.getCode() != Common::kNoError) return err; // On some systems it's not safe to run CD audio games from the CD. if (isCD()) checkCD(); _system->getAudioCDManager()->open(); _global->_debugFlag = 1; _video->_doRangeClamp = true; // WORKAROUND: Some versions check the video mode to detect the system if (_platform == Common::kPlatformAmiga) _global->_fakeVideoMode = 0x11; else if (_platform == Common::kPlatformAtariST) _global->_fakeVideoMode = 0x10; else _global->_fakeVideoMode = 0x13; _global->_videoMode = 0x13; _global->_useMouse = 1; _global->_soundFlags = MIDI_FLAG | SPEAKER_FLAG | BLASTER_FLAG | ADLIB_FLAG; if (ConfMan.hasKey("language")) _language = Common::parseLanguage(ConfMan.get("language")); switch (_language) { case Common::FR_FRA: case Common::RU_RUS: _global->_language = kLanguageFrench; break; case Common::DE_DEU: _global->_language = kLanguageGerman; break; case Common::EN_ANY: case Common::EN_GRB: case Common::HU_HUN: _global->_language = kLanguageBritish; break; case Common::ES_ESP: _global->_language = kLanguageSpanish; break; case Common::IT_ITA: _global->_language = kLanguageItalian; break; case Common::EN_USA: _global->_language = kLanguageAmerican; break; case Common::NL_NLD: _global->_language = kLanguageDutch; break; case Common::KO_KOR: _global->_language = kLanguageKorean; break; case Common::HE_ISR: _global->_language = kLanguageHebrew; break; case Common::PT_BRA: _global->_language = kLanguagePortuguese; break; case Common::JA_JPN: _global->_language = kLanguageJapanese; break; default: _global->_language = kLanguageBritish; break; } _global->_languageWanted = _global->_language; _init->initGame(); return Common::kNoError; }