int AgiEngine::playGame() { int ec = errOK; debugC(2, kDebugLevelMain, "initializing..."); debugC(2, kDebugLevelMain, "game version = 0x%x", getVersion()); _sound->stopSound(); _gfx->clearScreen(0); _game.horizon = HORIZON; _game.playerControl = false; setflag(fLogicZeroFirsttime, true); // not in 2.917 setflag(fNewRoomExec, true); // needed for MUMG and SQ2! setflag(fSoundOn, true); // enable sound setvar(vTimeDelay, 2); // "normal" speed _game.gfxMode = true; _game.clockEnabled = true; _game.lineUserInput = 22; // We run AGIMOUSE always as a side effect if (getFeatures() & GF_AGIMOUSE || true) debug(1, "Using AGI Mouse 1.0 protocol"); if (getFeatures() & GF_AGIPAL) debug(1, "Running AGIPAL game"); debug(0, "Running AGI script.\n"); setflag(fEnteredCli, false); setflag(fSaidAcceptedInput, false); _game.vars[vWordNotFound] = 0; _game.vars[vKey] = 0; debugC(2, kDebugLevelMain, "Entering main loop"); bool firstLoop = !getflag(fRestartGame); // Do not restore on game restart do { if (!mainCycle()) continue; if (getvar(vTimeDelay) == 0 || (1 + _clockCount) % getvar(vTimeDelay) == 0) { if (!_game.hasPrompt && _game.inputMode == INPUT_NORMAL) { writePrompt(); _game.hasPrompt = 1; } else if (_game.hasPrompt && _game.inputMode == INPUT_NONE) { writePrompt(); _game.hasPrompt = 0; } interpretCycle(); // Check if the user has asked to load a game from the command line // or the launcher if (firstLoop) { checkQuickLoad(); firstLoop = false; } setflag(fEnteredCli, false); setflag(fSaidAcceptedInput, false); _game.vars[vWordNotFound] = 0; _game.vars[vKey] = 0; } if (shouldPerformAutoSave(_lastSaveTime)) { saveGame(getSavegameFilename(0), "Autosave"); } } while (!(shouldQuit() || _restartGame)); _sound->stopSound(); return ec; }
int AgiEngine::playGame() { int ec = errOK; const AgiAppleIIgsDelayOverwriteGameEntry *appleIIgsDelayOverwrite = nullptr; const AgiAppleIIgsDelayOverwriteRoomEntry *appleIIgsDelayRoomOverwrite = nullptr; debugC(2, kDebugLevelMain, "initializing..."); debugC(2, kDebugLevelMain, "game version = 0x%x", getVersion()); _sound->stopSound(); // We need to do this accurately and reset the AGI priorityscreen to 4 // otherwise at least the fan game Nick's Quest will go into an endless // loop, because the game draws views before it draws the first background picture. // For further study see bug #3451122 _gfx->clear(0, 4); _game.horizon = 36; _game.playerControl = false; setFlag(VM_FLAG_LOGIC_ZERO_FIRST_TIME, true); // not in 2.917 setFlag(VM_FLAG_NEW_ROOM_EXEC, true); // needed for MUMG and SQ2! setFlag(VM_FLAG_SOUND_ON, true); // enable sound // do not set VM_VAR_TIME_DELAY, original AGI did not do it (in the data segment it was simply set to 0) _game.gfxMode = true; _text->promptRow_Set(22); // We run AGIMOUSE always as a side effect //if (getFeatures() & GF_AGIMOUSE) debug(1, "Using AGI Mouse 1.0 protocol"); if (getFeatures() & GF_AGIPAL) debug(1, "Running AGIPAL game"); debug(0, "Running AGI script.\n"); setFlag(VM_FLAG_ENTERED_CLI, false); setFlag(VM_FLAG_SAID_ACCEPTED_INPUT, false); setVar(VM_VAR_WORD_NOT_FOUND, 0); setVar(VM_VAR_KEY, 0); debugC(2, kDebugLevelMain, "Entering main loop"); bool firstLoop = !getFlag(VM_FLAG_RESTART_GAME); // Do not restore on game restart if (firstLoop) { if (ConfMan.hasKey("save_slot")) { // quick restore enabled _game.automaticRestoreGame = true; } } artificialDelay_Reset(); if (getPlatform() == Common::kPlatformApple2GS) { // Look up, if there is a time delay overwrite table for the current game appleIIgsDelayOverwrite = appleIIgsDelayOverwriteGameTable; while (appleIIgsDelayOverwrite->gameId != GID_AGIDEMO) { if (appleIIgsDelayOverwrite->gameId == getGameID()) break; // game found appleIIgsDelayOverwrite++; } } do { processAGIEvents(); inGameTimerUpdate(); uint16 timeDelay = getVar(VM_VAR_TIME_DELAY); if (getPlatform() == Common::kPlatformApple2GS) { timeDelay++; // It seems that either Apple IIgs ran very slowly or that the delay in its interpreter was not working as everywhere else // Most games on that platform set the delay to 0, which means no delay in DOS // Gold Rush! even "optimizes" itself when larger sprites are on the screen it sets TIME_DELAY to 0. // Normally that game runs at TIME_DELAY 1. // Maybe a script patch for this game would make sense. // TODO: needs further investigation int16 timeDelayOverwrite = -99; // Now check, if we got a time delay overwrite entry for current room if (appleIIgsDelayOverwrite->roomTable) { byte curRoom = getVar(VM_VAR_CURRENT_ROOM); appleIIgsDelayRoomOverwrite = appleIIgsDelayOverwrite->roomTable; while (appleIIgsDelayRoomOverwrite->fromRoom >= 0) { if ((appleIIgsDelayRoomOverwrite->fromRoom <= curRoom) && (appleIIgsDelayRoomOverwrite->toRoom >= curRoom)) { if (appleIIgsDelayRoomOverwrite->onlyWhenPlayerNotInControl) { if (_game.playerControl) { // Player is actually currently in control? -> then skip this entry appleIIgsDelayRoomOverwrite++; continue; } } timeDelayOverwrite = appleIIgsDelayRoomOverwrite->timeDelayOverwrite; break; } appleIIgsDelayRoomOverwrite++; } if (timeDelayOverwrite == -99) { // use default time delay in case no room specific one was found timeDelayOverwrite = appleIIgsDelayOverwrite->defaultTimeDelayOverwrite; } } else { timeDelayOverwrite = appleIIgsDelayOverwrite->defaultTimeDelayOverwrite; } if (timeDelayOverwrite >= 0) { if (timeDelayOverwrite != timeDelay) { // delayOverwrite is not the same as the delay taken from the scripts? overwrite it warning("AppleIIgs: time delay overwrite from %d to %d", timeDelay, timeDelayOverwrite); setVar(VM_VAR_TIME_DELAY, timeDelayOverwrite - 1); // adjust for Apple IIgs timeDelay = timeDelayOverwrite; } } } if (_passedPlayTimeCycles >= timeDelay) { inGameTimerResetPassedCycles(); interpretCycle(); // Check if the user has asked to load a game from the command line // or the launcher if (_game.automaticRestoreGame) { _game.automaticRestoreGame = false; checkQuickLoad(); } setFlag(VM_FLAG_ENTERED_CLI, false); setFlag(VM_FLAG_SAID_ACCEPTED_INPUT, false); setVar(VM_VAR_WORD_NOT_FOUND, 0); setVar(VM_VAR_KEY, 0); } if (shouldPerformAutoSave(_lastSaveTime)) { saveGame(getSavegameFilename(0), "Autosave"); } } while (!(shouldQuit() || _restartGame)); _sound->stopSound(); return ec; }