diff options
Diffstat (limited to 'engines/agi/cycle.cpp')
| -rw-r--r-- | engines/agi/cycle.cpp | 544 | 
1 files changed, 307 insertions, 237 deletions
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index 6b34605364..19aca6f2c4 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -20,11 +20,17 @@   *   */ +#include "common/config-manager.h" +  #include "agi/agi.h"  #include "agi/sprite.h"  #include "agi/graphics.h" +#include "agi/inv.h" +#include "agi/text.h"  #include "agi/keyboard.h"  #include "agi/menu.h" +#include "agi/systemui.h" +#include "agi/appleIIgs_timedelay_overwrite.h"  namespace Agi { @@ -33,295 +39,286 @@ namespace Agi {   * This function is called when ego enters a new room.   * @param n room number   */ -void AgiEngine::newRoom(int n) { -	VtEntry *v; +void AgiEngine::newRoom(int16 newRoomNr) { +	ScreenObjEntry *screenObj; +	ScreenObjEntry *screenObjEgo = &_game.screenObjTable[SCREENOBJECTS_EGO_ENTRY];  	int i; -	// Simulate slowww computer. -	// Many effects rely on it. -	pause(kPauseRoom); +	// Loading trigger +	artificialDelayTrigger_NewRoom(newRoomNr); -	debugC(4, kDebugLevelMain, "*** room %d ***", n); +	debugC(4, kDebugLevelMain, "*** room %d ***", newRoomNr);  	_sound->stopSound();  	i = 0; -	for (v = _game.viewTable; v < &_game.viewTable[MAX_VIEWTABLE]; v++) { -		v->entry = i++; -		v->flags &= ~(fAnimated | fDrawn); -		v->flags |= fUpdate; -		v->stepTime = 1; -		v->stepTimeCount = 1; -		v->cycleTime = 1; -		v->cycleTimeCount = 1; -		v->stepSize = 1; +	for (screenObj = _game.screenObjTable; screenObj < &_game.screenObjTable[SCREENOBJECTS_MAX]; screenObj++) { +		screenObj->objectNr = i++; +		screenObj->flags &= ~(fAnimated | fDrawn); +		screenObj->flags |= fUpdate; +		screenObj->stepTime = 1; +		screenObj->stepTimeCount = 1; +		screenObj->cycleTime = 1; +		screenObj->cycleTimeCount = 1; +		screenObj->stepSize = 1;  	}  	agiUnloadResources();  	_game.playerControl = true;  	_game.block.active = false;  	_game.horizon = 36; -	_game.vars[vPrevRoom] = _game.vars[vCurRoom]; -	_game.vars[vCurRoom] = n; -	_game.vars[vBorderTouchObj] = 0; -	_game.vars[vBorderCode] = 0; -	_game.vars[vEgoViewResource] = _game.viewTable[0].currentView; +	setVar(VM_VAR_PREVIOUS_ROOM, getVar(VM_VAR_CURRENT_ROOM)); +	setVar(VM_VAR_CURRENT_ROOM, newRoomNr); +	setVar(VM_VAR_BORDER_TOUCH_OBJECT, 0); +	setVar(VM_VAR_BORDER_CODE, 0); +	setVar(VM_VAR_EGO_VIEW_RESOURCE, screenObjEgo->currentViewNr); -	agiLoadResource(rLOGIC, n); +	agiLoadResource(RESOURCETYPE_LOGIC, newRoomNr);  	// Reposition ego in the new room -	switch (_game.vars[vBorderTouchEgo]) { +	switch (getVar(VM_VAR_BORDER_TOUCH_EGO)) {  	case 1: -		_game.viewTable[0].yPos = _HEIGHT - 1; +		screenObjEgo->yPos = SCRIPT_HEIGHT - 1;  		break;  	case 2: -		_game.viewTable[0].xPos = 0; +		screenObjEgo->xPos = 0;  		break;  	case 3: -		_game.viewTable[0].yPos = HORIZON + 1; +		screenObjEgo->yPos = _game.horizon + 1;  		break;  	case 4: -		_game.viewTable[0].xPos = _WIDTH - _game.viewTable[0].xSize; +		screenObjEgo->xPos = SCRIPT_WIDTH - screenObjEgo->xSize;  		break;  	} -	_game.vars[vBorderTouchEgo] = 0; -	setflag(fNewRoomExec, true); +	uint16 agiVersion = getVersion(); + +	if (agiVersion < 0x2000) { +		warning("STUB: NewRoom(%d)", newRoomNr); + +		screenObjEgo->flags &= ~fDidntMove; +		// animateObject(0); +		agiLoadResource(RESOURCETYPE_VIEW, screenObjEgo->currentViewNr); +		setView(screenObjEgo, screenObjEgo->currentViewNr); -	_game.exitAllLogics = true; +	} else { +		if (agiVersion >= 0x3000) { +			// this was only done in AGI3 +			if (screenObjEgo->motionType == kMotionEgo) { +				screenObjEgo->motionType = kMotionNormal; +				setVar(VM_VAR_EGO_DIRECTION, 0); +			} +		} -	writeStatus(); -	writePrompt(); +		setVar(VM_VAR_BORDER_TOUCH_EGO, 0); +		setFlag(VM_FLAG_NEW_ROOM_EXEC, true); + +		_game.exitAllLogics = true; + +		_game._vm->_text->statusDraw(); +		_game._vm->_text->promptRedraw(); +	}  }  void AgiEngine::resetControllers() {  	int i; -	for (i = 0; i < MAX_DIRS; i++) { +	for (i = 0; i < MAX_CONTROLLERS; i++) {  		_game.controllerOccured[i] = false;  	}  }  void AgiEngine::interpretCycle() { -	int oldSound, oldScore; +	ScreenObjEntry *screenObjEgo = &_game.screenObjTable[SCREENOBJECTS_EGO_ENTRY]; +	bool oldSound; +	byte oldScore; -	if (_game.playerControl) -		_game.vars[vEgoDir] = _game.viewTable[0].direction; +	if (!_game.playerControl) +		setVar(VM_VAR_EGO_DIRECTION, screenObjEgo->direction);  	else -		_game.viewTable[0].direction = _game.vars[vEgoDir]; +		screenObjEgo->direction = getVar(VM_VAR_EGO_DIRECTION);  	checkAllMotions(); -	oldScore = _game.vars[vScore]; -	oldSound = getflag(fSoundOn); +	oldScore = getVar(VM_VAR_SCORE); +	oldSound = getFlag(VM_FLAG_SOUND_ON); + +	// Reset script heuristic here +	resetGetVarSecondsHeuristic();  	_game.exitAllLogics = false;  	while (runLogic(0) == 0 && !(shouldQuit() || _restartGame)) { -		_game.vars[vWordNotFound] = 0; -		_game.vars[vBorderTouchObj] = 0; -		_game.vars[vBorderCode] = 0; -		oldScore = _game.vars[vScore]; -		setflag(fEnteredCli, false); +		setVar(VM_VAR_WORD_NOT_FOUND, 0); +		setVar(VM_VAR_BORDER_TOUCH_OBJECT, 0); +		setVar(VM_VAR_BORDER_CODE, 0); +		oldScore = getVar(VM_VAR_SCORE); +		setFlag(VM_FLAG_ENTERED_CLI, false);  		_game.exitAllLogics = false; +		_veryFirstInitialCycle = false; +		artificialDelay_CycleDone();  		resetControllers();  	} +	_veryFirstInitialCycle = false; +	artificialDelay_CycleDone();  	resetControllers(); -	_game.viewTable[0].direction = _game.vars[vEgoDir]; +	screenObjEgo->direction = getVar(VM_VAR_EGO_DIRECTION); -	if (_game.vars[vScore] != oldScore || getflag(fSoundOn) != oldSound) -		writeStatus(); +	if (getVar(VM_VAR_SCORE) != oldScore || getFlag(VM_FLAG_SOUND_ON) != oldSound) +		_game._vm->_text->statusDraw(); -	_game.vars[vBorderTouchObj] = 0; -	_game.vars[vBorderCode] = 0; -	setflag(fNewRoomExec, false); -	setflag(fRestartGame, false); -	setflag(fRestoreJustRan, false); +	setVar(VM_VAR_BORDER_TOUCH_OBJECT, 0); +	setVar(VM_VAR_BORDER_CODE, 0); +	setFlag(VM_FLAG_NEW_ROOM_EXEC, false); +	setFlag(VM_FLAG_RESTART_GAME, false); +	setFlag(VM_FLAG_RESTORE_JUST_RAN, false);  	if (_game.gfxMode) { -		updateViewtable(); -		_gfx->doUpdate(); +		updateScreenObjTable();  	} +	_gfx->updateScreen(); +	//_gfx->doUpdate();  } -/** - * Update AGI interpreter timer. - */ -void AgiEngine::updateTimer() { -	_clockCount++; -	if (_clockCount <= TICK_SECONDS) -		return; - -	_clockCount -= TICK_SECONDS; - -	if (!_game.clockEnabled) -		return; - -	setvar(vSeconds, getvar(vSeconds) + 1); -	if (getvar(vSeconds) < 60) -		return; - -	setvar(vSeconds, 0); -	setvar(vMinutes, getvar(vMinutes) + 1); -	if (getvar(vMinutes) < 60) -		return; - -	setvar(vMinutes, 0); -	setvar(vHours, getvar(vHours) + 1); -	if (getvar(vHours) < 24) -		return; - -	setvar(vHours, 0); -	setvar(vDays, getvar(vDays) + 1); -} - -void AgiEngine::newInputMode(InputMode mode) { -	if (mode == INPUT_MENU && !getflag(fMenusWork) && !(getFeatures() & GF_MENUS)) -		return; - -	_oldMode = _game.inputMode; -	_game.inputMode = mode; -} - -void AgiEngine::oldInputMode() { -	_game.inputMode = _oldMode; -} - -// If main_cycle returns false, don't process more events! -int AgiEngine::mainCycle(bool onlyCheckForEvents) { -	unsigned int key, kascii; -	VtEntry *v = &_game.viewTable[0]; - -	if (!onlyCheckForEvents) { -		pollTimer(); -		updateTimer(); -	} +// We return the current key, or 0 if no key was pressed +uint16 AgiEngine::processAGIEvents() { +	uint16 key; +	ScreenObjEntry *screenObjEgo = &_game.screenObjTable[SCREENOBJECTS_EGO_ENTRY]; +	wait(10);  	key = doPollKeyboard();  	// In AGI Mouse emulation mode we must update the mouse-related  	// vars in every interpreter cycle.  	//  	// We run AGIMOUSE always as a side effect -	//if (getFeatures() & GF_AGIMOUSE) { -		_game.vars[28] = _mouse.x / 2; -		_game.vars[29] = _mouse.y; -	//} - -	if (key == KEY_STATUSLN) {	// F11 -		_debug.statusline = !_debug.statusline; -		writeStatus(); -		key = 0; +	setVar(VM_VAR_MOUSE_X, _mouse.pos.x / 2); +	setVar(VM_VAR_MOUSE_Y, _mouse.pos.y); + +	if (!cycleInnerLoopIsActive()) { +		// Click-to-walk mouse interface +		if (_game.playerControl && (screenObjEgo->flags & fAdjEgoXY)) { +			int toX = screenObjEgo->move_x; +			int toY = screenObjEgo->move_y; + +			// AGI Mouse games use ego's sprite's bottom left corner for mouse walking target. +			// Amiga games use ego's sprite's bottom center for mouse walking target. +			// Atari ST and Apple II GS seem to use the bottom left +			if (getPlatform() == Common::kPlatformAmiga) +				toX -= (screenObjEgo->xSize / 2); // Center ego's sprite horizontally + +			// Adjust ego's sprite's mouse walking target position (These parameters are +			// controlled with the adj.ego.move.to.x.y-command). Note that these values rely +			// on the horizontal centering of the ego's sprite at least on the Amiga platform. +			toX += _game.adjMouseX; +			toY += _game.adjMouseY; + +			screenObjEgo->direction = getDirection(screenObjEgo->xPos, screenObjEgo->yPos, toX, toY, screenObjEgo->stepSize); + +			if (screenObjEgo->direction == 0) +				inDestination(screenObjEgo); +		}  	} -	if (key == KEY_PRIORITY) {	// F12 -		_sprites->eraseBoth(); -		_debug.priority = !_debug.priority; -		_picture->showPic(); -		_sprites->blitBoth(); -		_sprites->commitBoth(); -		key = 0; -	} +	handleMouseClicks(key); -	// Click-to-walk mouse interface -	if (_game.playerControl && (v->flags & fAdjEgoXY)) { -		int toX = v->parm1; -		int toY = v->parm2; +	if (!cycleInnerLoopIsActive()) { +		// no inner loop active at the moment, regular processing -		// AGI Mouse games use ego's sprite's bottom left corner for mouse walking target. -		// Amiga games use ego's sprite's bottom center for mouse walking target. -		// TODO: Check what Atari ST AGI and Apple IIGS AGI use for mouse walking target. -		if (getPlatform() == Common::kPlatformAmiga) -			toX -= (v->xSize / 2); // Center ego's sprite horizontally +		if (key) { +			if (!handleController(key)) { +				if (key) { +					// Only set VAR_KEY, when no controller/direction was detected +					setVar(VM_VAR_KEY, key & 0xFF); +					if (_text->promptIsEnabled()) { +						_text->promptKeyPress(key); +					} +				} +			} +		} -		// Adjust ego's sprite's mouse walking target position (These parameters are -		// controlled with the adj.ego.move.to.x.y-command). Note that these values rely -		// on the horizontal centering of the ego's sprite at least on the Amiga platform. -		toX += _game.adjMouseX; -		toY += _game.adjMouseY; +		if (_menu->delayedExecuteActive()) { +			_menu->execute(); +		} -		v->direction = getDirection(v->xPos, v->yPos, toX, toY, v->stepSize); +	} else { +		// inner loop active +		// call specific workers +		switch (_game.cycleInnerLoopType) { +		case CYCLE_INNERLOOP_GETSTRING: // loop called from TextMgr::stringEdit() +		case CYCLE_INNERLOOP_GETNUMBER: +			if (key) { +				_text->stringKeyPress(key); +			} +			break; -		if (v->direction == 0) -			inDestination(v); -	} +		case CYCLE_INNERLOOP_INVENTORY: // loop called from InventoryMgr::show() +			if (key) { +				_inventory->keyPress(key); +			} +			break; -	kascii = KEY_ASCII(key); +		case CYCLE_INNERLOOP_MENU_VIA_KEYBOARD: +			if (key) { +				_menu->keyPress(key); +			} +			break; -	if (kascii) -		setvar(vKey, kascii); +		case CYCLE_INNERLOOP_MENU_VIA_MOUSE: +			_menu->mouseEvent(key); +			break; -	bool restartProcessKey; -	do { -		restartProcessKey = false; +		case CYCLE_INNERLOOP_SYSTEMUI_SELECTSAVEDGAMESLOT: +			if (key) { +				_systemUI->savedGameSlot_KeyPress(key); +			} +			break; -		switch (_game.inputMode) { -		case INPUT_NORMAL: -			if (!handleController(key)) { -				if (key == 0 || !_game.inputEnabled) -					break; -				handleKeys(key); - -				// if ESC pressed, activate menu before -				// accept.input from the interpreter cycle -				// sets the input mode to normal again -				// (closes: #540856) -				if (key == KEY_ESCAPE) { -					key = 0; -					restartProcessKey = true; -				} +		case CYCLE_INNERLOOP_SYSTEMUI_VERIFICATION: +			_systemUI->askForVerificationKeyPress(key); +			break; -				// commented out to close Sarien bug #438872 -				//if (key) -				//	_game.keypress = key; +		case CYCLE_INNERLOOP_MESSAGEBOX: +			if (key) { +				_text->messageBox_KeyPress(key);  			}  			break; -		case INPUT_GETSTRING: -			handleController(key); -			handleGetstring(key); -			setvar(vKey, 0);	// clear ENTER key -			break; -		case INPUT_MENU: -			_menu->keyhandler(key); -			_gfx->doUpdate(); -			return false; -		case INPUT_NONE: -			handleController(key); -			if (key) -				_game.keypress = key; + +		default:  			break;  		} -	} while (restartProcessKey); - -	if (!onlyCheckForEvents) { -		_gfx->doUpdate(); - -		if (_game.msgBoxTicks > 0) -			_game.msgBoxTicks--;  	} -	return true; +	_gfx->updateScreen(); + +	return key;  }  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(); -	_gfx->clearScreen(0); -	_game.horizon = HORIZON; +	// 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(fLogicZeroFirsttime, true);	// not in 2.917 -	setflag(fNewRoomExec, true);	// needed for MUMG and SQ2! -	setflag(fSoundOn, true);	// enable sound -	setvar(vTimeDelay, 2);	// "normal" speed +	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; -	_game.clockEnabled = true; -	_game.lineUserInput = 22; +	_text->promptRow_Set(22);  	// We run AGIMOUSE always as a side effect  	//if (getFeatures() & GF_AGIMOUSE) @@ -332,41 +329,106 @@ int AgiEngine::playGame() {  	debug(0, "Running AGI script.\n"); -	setflag(fEnteredCli, false); -	setflag(fSaidAcceptedInput, false); -	_game.vars[vWordNotFound] = 0; -	_game.vars[vKey] = 0; +	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(fRestartGame); // Do not restore on game restart +	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 (!mainCycle()) -			continue; +			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); -		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; +					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 (firstLoop) { +			if (_game.automaticRestoreGame) { +				_game.automaticRestoreGame = false;  				checkQuickLoad(); -				firstLoop = false;  			} -			setflag(fEnteredCli, false); -			setflag(fSaidAcceptedInput, false); -			_game.vars[vWordNotFound] = 0; -			_game.vars[vKey] = 0; +			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)) { @@ -392,66 +454,74 @@ int AgiEngine::runGame() {  			break;  		if (_restartGame) { -			setflag(fRestartGame, true); -			setvar(vTimeDelay, 2);	// "normal" speed +			setFlag(VM_FLAG_RESTART_GAME, true); +			// do not set VM_VAR_TIME_DELAY, original AGI did not do it + +			// Reset in-game timer +			inGameTimerReset(); +  			_restartGame = false;  		}  		// Set computer type (v20 i.e. vComputer) and sound type  		switch (getPlatform()) {  		case Common::kPlatformAtariST: -			setvar(vComputer, kAgiComputerAtariST); -			setvar(vSoundgen, kAgiSoundPC); +			setVar(VM_VAR_COMPUTER, kAgiComputerAtariST); +			setVar(VM_VAR_SOUNDGENERATOR, kAgiSoundPC);  			break;  		case Common::kPlatformAmiga:  			if (getFeatures() & GF_OLDAMIGAV20) -				setvar(vComputer, kAgiComputerAmigaOld); +				setVar(VM_VAR_COMPUTER, kAgiComputerAmigaOld);  			else -				setvar(vComputer, kAgiComputerAmiga); -			setvar(vSoundgen, kAgiSoundTandy); +				setVar(VM_VAR_COMPUTER, kAgiComputerAmiga); +			setVar(VM_VAR_SOUNDGENERATOR, kAgiSoundTandy);  			break;  		case Common::kPlatformApple2GS: -			setvar(vComputer, kAgiComputerApple2GS); +			setVar(VM_VAR_COMPUTER, kAgiComputerApple2GS);  			if (getFeatures() & GF_2GSOLDSOUND) -				setvar(vSoundgen, kAgiSound2GSOld); +				setVar(VM_VAR_SOUNDGENERATOR, kAgiSound2GSOld);  			else -				setvar(vSoundgen, kAgiSoundTandy); +				setVar(VM_VAR_SOUNDGENERATOR, kAgiSoundTandy);  			break;  		case Common::kPlatformDOS:  		default: -			setvar(vComputer, kAgiComputerPC); -			setvar(vSoundgen, kAgiSoundPC); +			setVar(VM_VAR_COMPUTER, kAgiComputerPC); +			setVar(VM_VAR_SOUNDGENERATOR, kAgiSoundPC);  			break;  		}  		// Set monitor type (v26 i.e. vMonitor)  		switch (_renderMode) {  		case Common::kRenderCGA: -			setvar(vMonitor, kAgiMonitorCga); +			setVar(VM_VAR_MONITOR, kAgiMonitorCga);  			break; -		case Common::kRenderHercG:  		case Common::kRenderHercA: -			setvar(vMonitor, kAgiMonitorHercules); +		case Common::kRenderHercG: +			// Set EGA for now. Some games place text differently, when this is set to kAgiMonitorHercules. +			// Text placement was different for Hercules rendering (16x12 instead of 16x16). There also was +			// not enough space left for the prompt at the bottom. This was caused by the Hercules resolution. +			// We don't have this restriction and we also support the regular prompt for Hercules mode. +			// In theory Sierra could have had special Hercules code inside their games. +			// TODO: check this. +			setVar(VM_VAR_MONITOR, kAgiMonitorEga);  			break;  		// Don't know if Amiga AGI games use a different value than kAgiMonitorEga  		// for vMonitor so I just use kAgiMonitorEga for them (As was done before too).  		case Common::kRenderAmiga: -		case Common::kRenderDefault: +		case Common::kRenderApple2GS: +		case Common::kRenderAtariST:  		case Common::kRenderEGA: +		case Common::kRenderVGA:  		default: -			setvar(vMonitor, kAgiMonitorEga); +			setVar(VM_VAR_MONITOR, kAgiMonitorEga);  			break;  		} -		setvar(vFreePages, 180); // Set amount of free memory to realistic value -		setvar(vMaxInputChars, 38); -		_game.inputMode = INPUT_NONE; -		_game.inputEnabled = false; -		_game.hasPrompt = 0; +		setVar(VM_VAR_FREE_PAGES, 180); // Set amount of free memory to realistic value +		setVar(VM_VAR_MAX_INPUT_CHARACTERS, 38); +		_text->promptDisable(); -		_game.state = STATE_RUNNING;  		ec = playGame(); -		_game.state = STATE_LOADED;  		agiDeinit();  	} while (_restartGame);  | 
