diff --git a/base/engine.h b/base/engine.h index 509d8cd5266..3774c52ac8a 100644 --- a/base/engine.h +++ b/base/engine.h @@ -41,9 +41,20 @@ protected: public: Engine(OSystem *syst); virtual ~Engine(); + + /** + * Init the engine. + * @return 0 for success, else an error code. + */ + virtual int init() = 0; - /** Start the main engine loop. */ - virtual void go() = 0; + /** + * Start the main engine loop. + * The return value is not yet used, but could indicate whether the user + * wants to return to the launch or to fully quit ScummVM. + * @return a result code + */ + virtual int go() = 0; /** Get the path to the save game directory. */ virtual const char *getSavePath() const; diff --git a/base/main.cpp b/base/main.cpp index 15870d7a0bd..695df685460 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -190,11 +190,7 @@ static int launcherDialog(GameDetector &detector, OSystem *system) { // Set the user specified graphics mode (if any). system->setGraphicsMode(ConfMan.get("gfx_mode").c_str()); - // FIXME - we need to call initSize() here so that we can display for example - // the launcher dialog. But the Engine object will also call it again (possibly - // with a different widht/height!9 However, this method is not for all OSystem - // implementations reentrant (it is so now for the SDL backend). Thus we need - // to fix all backends to support it, if they don't already. + // GUI is (currently) always running at 320x200 system->initSize(320, 200); system->endGFXTransaction(); @@ -239,7 +235,7 @@ static int launcherDialog(GameDetector &detector, OSystem *system) { return dlg.runModal(); } -static void runGame(GameDetector &detector, OSystem *system) { +static int runGame(GameDetector &detector, OSystem *system) { // Set the window caption to the game name Common::String caption(ConfMan.get("description", detector._targetName)); @@ -256,6 +252,20 @@ static void runGame(GameDetector &detector, OSystem *system) { !scumm_stricmp(ConfMan.get("gfx_mode", detector._targetName).c_str(), "normal") || !scumm_stricmp(ConfMan.get("gfx_mode", detector._targetName).c_str(), "default"); + // Create the game engine + Engine *engine = detector.createEngine(system); + assert(engine); + + // Add extrapath (if any) to the directory search list + if (ConfMan.hasKey("extrapath")) + File::addDefaultDirectory(ConfMan.get("extrapath")); + + if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) + File::addDefaultDirectory(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain)); + + int result; + + // Start GFX transaction system->beginGFXTransaction(); // See if the game should default to 1x scaler @@ -274,39 +284,23 @@ static void runGame(GameDetector &detector, OSystem *system) { // (De)activate fullscreen mode as determined by the config settings system->setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen")); - // TODO / FIXME: this transaction sould also contain the initial call to initSize - // which all engines perform. However, as long as that is contained within - // the "engine->go()", this is not possible. - // Multiple solutions come to mind, including these: - // * Don't let the engine invoke initSize(); rather, add a method to them which we can - // use to query their desired res, then we set it for them - // * Move the setGraphicsMode/setFeatureState calls here to the Engine class, which the - // engines invoke (in other words: move this transaction into the engines - // * Add an explicit Engine::init() method, which all engines have to implement, - // and into which they should put their call to initSize. Then, make sure this transaction - // surrounds the call to engine->init(); + // Init the engine (this might change the screen parameters + result = engine->init(); system->endGFXTransaction(); - // Create the game engine - Engine *engine = detector.createEngine(system); - assert(engine); - - // Add extrapath (if any) to the directory search list - if (ConfMan.hasKey("extrapath")) - File::addDefaultDirectory(ConfMan.get("extrapath")); - - if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) - File::addDefaultDirectory(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain)); - - // Run the game engine - engine->go(); + // Run the game engine if the initialization was successful. + if (result == 0) { + result = engine->go(); + } // Free up memory delete engine; // Stop all sound processing now (this prevents some race conditions later on) system->clearSoundCallback(); + + return result; } #ifndef _WIN32_WCE @@ -419,7 +413,12 @@ extern "C" int scummvm_main(GameDetector &detector, int argc, char *argv[]) { // to save memory PluginManager::instance().unloadPluginsExcept(detector._plugin); - runGame(detector, system); + int result = runGame(detector, system); + // TODO: for now, return code 0 (which is currently the only return + // code anyway) is interpreted to mean "return to launcher". This is + // *not* fixed, we could (and probably will) change the meaning etc. + if (result != 0) + running = false; // There are some command-line options that it's // unlikely that we want to preserve now that we're diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index 440c1bced1a..485bb4409b8 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -121,6 +121,9 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst) } else { error("unknown game"); } +} + +int KyraEngine::init() { // Initialize backen syst->initSize(320, 200); @@ -169,6 +172,8 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst) assert(_npcScript); assert(_currentScript); + + return 0; } KyraEngine::~KyraEngine() { @@ -185,7 +190,7 @@ void KyraEngine::errorString(const char *buf1, char *buf2) { strcpy(buf2, buf1); } -void KyraEngine::go() { +int KyraEngine::go() { warning("Kyrandia Engine ::go()"); // starts the init script /* if (!_currentScript->startScript(kSetupScene)) { @@ -259,6 +264,8 @@ void KyraEngine::go() { delete movie; delete image; delete [] _buffer; + + return 0; } void KyraEngine::shutdown() { diff --git a/kyra/kyra.h b/kyra/kyra.h index 15564bffee0..e269ad71d23 100644 --- a/kyra/kyra.h +++ b/kyra/kyra.h @@ -67,7 +67,8 @@ public: uint8 game(void) { return _game; } protected: - void go(); + int go(); + int init(); void shutdown(); Resourcemanager* _resMgr; MusicPlayer* _midiDriver; diff --git a/queen/queen.cpp b/queen/queen.cpp index 93f2e70e357..998e0cb501d 100644 --- a/queen/queen.cpp +++ b/queen/queen.cpp @@ -288,12 +288,7 @@ void QueenEngine::errorString(const char *buf1, char *buf2) { strcpy(buf2, buf1); } -void QueenEngine::go() { - initialise(); - - registerDefaultSettings(); - readOptionSettings(); - +int QueenEngine::go() { _logic->oldRoom(0); _logic->newRoom(_logic->currentRoom()); @@ -319,9 +314,11 @@ void QueenEngine::go() { } } } + + return 0; } -void QueenEngine::initialise(void) { +int QueenEngine::init() { _system->initSize(GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT); _bam = new BamScene(this); @@ -361,6 +358,11 @@ void QueenEngine::initialise(void) { _sound = Sound::giveSound(_mixer, this, _resource->compression()); _walk = new Walk(this); + + registerDefaultSettings(); + readOptionSettings(); + + return 0; } } // End of namespace Queen diff --git a/queen/queen.h b/queen/queen.h index 3ca77b9eaa4..ceb895d2cea 100644 --- a/queen/queen.h +++ b/queen/queen.h @@ -123,9 +123,8 @@ protected: void errorString(const char *buf_input, char *buf_output); - void go(); - - void initialise(); + int go(); + int init(); int _talkSpeed; diff --git a/saga/saga.cpp b/saga/saga.cpp index dc3353e6ec6..236ed78ae2b 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -124,9 +124,7 @@ void SagaEngine::errorString(const char *buf1, char *buf2) { strcpy(buf2, buf1); } -void SagaEngine::go() { - int msec = 0; - +int SagaEngine::init() { _soundEnabled = 1; _musicEnabled = 1; @@ -156,7 +154,7 @@ void SagaEngine::go() { // Detect game and open resource files if (GAME_Init() != SUCCESS) { - return; + return -1; } // Initialize engine modules @@ -174,7 +172,8 @@ void SagaEngine::go() { if (!_scene->initialized()) { warning("Couldn't initialize scene module"); - return; + // TODO/FIXME: We are leaking here + return -1; } // System initialization @@ -214,7 +213,8 @@ void SagaEngine::go() { _render = new Render(this, _system); if (!_render->initialized()) { - return; + // TODO/FIXME: We are leaking here + return -1; } // Initialize system specific sound @@ -232,6 +232,12 @@ void SagaEngine::go() { _render->reg(); _anim->reg(); + return 0; +} + +int SagaEngine::go() { + int msec = 0; + _previousTicks = _system->getMillis(); _sprite->loadList(ITE_MAIN_SPRITES, &_mainSprites); @@ -265,6 +271,8 @@ void SagaEngine::go() { _render->drawScene(); _system->delayMillis(10); } + + return 0; } void SagaEngine::shutdown() { diff --git a/saga/saga.h b/saga/saga.h index 8b68088afa7..e1408397403 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -88,7 +88,8 @@ class SagaEngine : public Engine { void errorString(const char *buf_input, char *buf_output); protected: - void go(); + int go(); + int init(); public: SagaEngine(GameDetector * detector, OSystem * syst); diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index f8abc97773e..7df2d8d8ecb 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -972,16 +972,11 @@ ScummEngine_v70he::ScummEngine_v70he(GameDetector *detector, OSystem *syst, cons _heSndSoundFreq = 0; } -void ScummEngine::go() { - mainInit(); - mainRun(); -} - #pragma mark - #pragma mark --- Initialization --- #pragma mark - -void ScummEngine::mainInit() { +int ScummEngine::init() { // Initialize backend _system->initSize(_screenWidth, _screenHeight); @@ -1119,6 +1114,8 @@ void ScummEngine::mainInit() { } else { _saveLoadFlag = 0; } + + return 0; } void ScummEngine::scummInit() { @@ -1397,7 +1394,7 @@ void ScummEngine::setupMusic(int midi) { #pragma mark --- Main loop --- #pragma mark - -void ScummEngine::mainRun() { +int ScummEngine::go() { int delta = 0; int diff = _system->getMillis(); @@ -1418,6 +1415,8 @@ void ScummEngine::mainRun() { // TODO: Maybe perform an autosave on exit? } } + + return 0; } void ScummEngine::waitForTimer(int msec_delay) { diff --git a/scumm/scumm.h b/scumm/scumm.h index 881a7bf6e49..43b77289584 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -385,10 +385,10 @@ public: virtual ~ScummEngine(); /** Startup function: Calls mainInit and then mainRun. */ - void go(); + int go(); // Init functions - void mainInit(); + int init(); virtual void setupScummVars(); void initScummVars(); @@ -399,7 +399,6 @@ public: void setupMusic(int midi); // Scumm main loop - void mainRun(); int scummLoop(int delta); // Event handling diff --git a/simon/simon.cpp b/simon/simon.cpp index b7519e8ca47..44332bc3bac 100644 --- a/simon/simon.cpp +++ b/simon/simon.cpp @@ -659,7 +659,9 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst) _vc_10_base_ptr_old = 0; memcpy (_hebrew_char_widths, "\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32); +} +int SimonEngine::init() { // Setup mixer if (!_mixer->isReady()) warning("Sound initialization failed. " @@ -718,6 +720,8 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst) // FIXME Use auto dirty rects cleanup code to reduce CPU usage g_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true); + + return 0; } SimonEngine::~SimonEngine() { @@ -4668,7 +4672,7 @@ void SimonEngine::fadeUpPalette() { } while (!done); } -void SimonEngine::go() { +int SimonEngine::go() { if (!_dump_file) _dump_file = stdout; @@ -4728,6 +4732,8 @@ void SimonEngine::go() { handle_verb_clicked(_verb_hitarea); delay(100); } + + return 0; } void SimonEngine::shutdown() { diff --git a/simon/simon.h b/simon/simon.h index f2cc99910a6..b0c72491c12 100644 --- a/simon/simon.h +++ b/simon/simon.h @@ -740,7 +740,8 @@ protected: void resfile_read(void *dst, uint32 offs, uint32 size); - void go(); + int init(); + int go(); void openGameFile(); static int CDECL game_thread_proc(void *param); diff --git a/sky/sky.cpp b/sky/sky.cpp index 072c958525d..17a27471919 100644 --- a/sky/sky.cpp +++ b/sky/sky.cpp @@ -183,9 +183,7 @@ void SkyEngine::handleKey(void) { _key_pressed = 0; } -void SkyEngine::go() { - - initialise(); +int SkyEngine::go() { _sdl_mouse_x = GAME_SCREEN_WIDTH / 2; _sdl_mouse_y = GAME_SCREEN_HEIGHT / 2; @@ -243,9 +241,11 @@ void SkyEngine::go() { _skyScreen->flip(); } } + + return 0; } -void SkyEngine::initialise(void) { +int SkyEngine::init() { _system->initSize(320, 200); if (!_mixer->isReady()) @@ -359,6 +359,8 @@ void SkyEngine::initialise(void) { _skyMusic->setVolume(ConfMan.getInt("music_volume") >> 1); _debugger = new Debugger(_skyLogic, _skyMouse, _skyScreen); + + return 0; } void SkyEngine::initItemList() { diff --git a/sky/sky.h b/sky/sky.h index 0eee981dea9..d4e57e9a7ab 100644 --- a/sky/sky.h +++ b/sky/sky.h @@ -93,14 +93,14 @@ protected: void logic_engine(); void delay(uint amount); - void go(); + int go(); void doCheat(uint8 num); void handleKey(void); uint32 _lastSaveTime; Text *getText(); - void initialise(); + int init(); void initItemList(); void initVirgin(); diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 1e56aa0944b..4033ec87042 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -123,7 +123,7 @@ SwordEngine::~SwordEngine() { delete _resMan; } -void SwordEngine::initialize(void) { +int SwordEngine::init() { // Add default file directories File::addDefaultDirectory(_gameDataPath + "CLUSTERS/"); @@ -198,6 +198,8 @@ void SwordEngine::initialize(void) { _objectMan->initialize(); _mouse->initialize(); _control = new Control(_saveFileMan, _resMan, _objectMan, _system, _mouse, _sound, _music, getSavePath()); + + return 0; } void SwordEngine::reinitialize(void) { @@ -1129,9 +1131,8 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or } } -void SwordEngine::go(void) { +int SwordEngine::go() { - initialize(); checkCdFiles(); uint8 startPos = ConfMan.getInt("boot_param"); @@ -1163,6 +1164,8 @@ void SwordEngine::go(void) { _systemVars.controlPanelMode = CP_NORMAL; } } + + return 0; } void SwordEngine::checkCd(void) { diff --git a/sword1/sword1.h b/sword1/sword1.h index dea5ccb24bd..835e4701e37 100644 --- a/sword1/sword1.h +++ b/sword1/sword1.h @@ -75,10 +75,10 @@ public: uint32 _features; protected: - void go(); + int go(); + int init(); private: void delay(uint amount); - void initialize(void); void checkCdFiles(void); void checkCd(void); diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp index 289b6675a4a..05ba3bf340a 100644 --- a/sword2/sword2.cpp +++ b/sword2/sword2.cpp @@ -223,7 +223,7 @@ void Sword2Engine::setupPersistentResources() { _resman->openResource(CUR_PLAYER_ID); } -void Sword2Engine::mainInit() { +int Sword2Engine::init() { // Get some falling RAM and put it in your pocket, never let it slip // away @@ -288,7 +288,7 @@ void Sword2Engine::mainInit() { // will either have killed the music, or done a crossfade. if (_quit) - return; + return 0; if (result) startGame(); @@ -296,9 +296,11 @@ void Sword2Engine::mainInit() { startGame(); _graphics->initialiseRenderCycle(); + + return 0; } -void Sword2Engine::mainRun() { +int Sword2Engine::go() { while (1) { if (_debugger->isAttached()) _debugger->onFrame(); @@ -370,11 +372,8 @@ void Sword2Engine::mainRun() { buildDisplay(); #endif } -} - -void Sword2Engine::go() { - mainInit(); - mainRun(); + + return 0; } void Sword2Engine::closeGame() { diff --git a/sword2/sword2.h b/sword2/sword2.h index 2a8018ef6a5..e775195dd41 100644 --- a/sword2/sword2.h +++ b/sword2/sword2.h @@ -170,9 +170,8 @@ private: public: Sword2Engine(GameDetector *detector, OSystem *syst); ~Sword2Engine(); - void go(); - void mainInit(); - void mainRun(); + int go(); + int init(); void setupPersistentResources();