[Scummvm-cvs-logs] scummvm master -> 62aabc57e446efcf15353a49209ce1d99c567fa4

clone2727 clone2727 at gmail.com
Mon Aug 15 18:00:32 CEST 2011


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
fcd0cda9a9 AGI: Make Winnie inherit from PreAgiEngine
cb43e9694b AGI: Make Mickey inherit from PreAgiEngine
6a9d4b3e5b AGI: Make Troll inherit from PreAgiEngine
62aabc57e4 AGI: Reorganize the PreAGI code a bit


Commit: fcd0cda9a98de7470f40f1db064ed2cce9f3a86c
    https://github.com/scummvm/scummvm/commit/fcd0cda9a98de7470f40f1db064ed2cce9f3a86c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2011-08-15T08:55:01-07:00

Commit Message:
AGI: Make Winnie inherit from PreAgiEngine

Changed paths:
    engines/agi/console.cpp
    engines/agi/console.h
    engines/agi/detection.cpp
    engines/agi/preagi.cpp
    engines/agi/preagi.h
    engines/agi/preagi_winnie.cpp
    engines/agi/preagi_winnie.h



diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp
index 58c61c0..52d7a0b 100644
--- a/engines/agi/console.cpp
+++ b/engines/agi/console.cpp
@@ -317,7 +317,7 @@ bool Mickey_Console::Cmd_DrawObj(int argc, const char **argv) {
 	return true;
 }
 
-Winnie_Console::Winnie_Console(PreAgiEngine *vm, Winnie *winnie) : PreAGI_Console(vm) {
+Winnie_Console::Winnie_Console(WinnieEngine *winnie) : PreAGI_Console(winnie) {
 	_winnie = winnie;
 
 	DCmd_Register("curRoom", WRAP_METHOD(Winnie_Console, Cmd_CurRoom));
diff --git a/engines/agi/console.h b/engines/agi/console.h
index 308b0f1..fc3a507 100644
--- a/engines/agi/console.h
+++ b/engines/agi/console.h
@@ -27,7 +27,7 @@ namespace Agi {
 
 class AgiEngine;
 class PreAgiEngine;
-class Winnie;
+class WinnieEngine;
 class Mickey;
 
 struct AgiDebug {
@@ -93,11 +93,11 @@ private:
 
 class Winnie_Console : public PreAGI_Console {
 public:
-	Winnie_Console(PreAgiEngine *vm, Winnie *winnie);
+	Winnie_Console(WinnieEngine *winnie);
 	virtual ~Winnie_Console() {}
 
 private:
-	Winnie *_winnie;
+	WinnieEngine *_winnie;
 
 	bool Cmd_CurRoom(int argc, const char **argv);
 };
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index e418845..0968e6e 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -36,6 +36,7 @@
 
 #include "agi/agi.h"
 #include "agi/preagi.h"
+#include "agi/preagi_winnie.h"
 #include "agi/wagparser.h"
 
 
@@ -191,7 +192,10 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
 
 	switch (gd->gameType) {
 	case Agi::GType_PreAGI:
-		*engine = new Agi::PreAgiEngine(syst, gd);
+		if (gd->gameID == GID_WINNIE)
+			*engine = new Agi::WinnieEngine(syst, gd);
+		else
+			*engine = new Agi::PreAgiEngine(syst, gd);
 		break;
 	case Agi::GType_V1:
 	case Agi::GType_V2:
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index 6ed3ff8..da163cb 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -142,7 +142,7 @@ Common::Error PreAgiEngine::go() {
 	setflag(fSoundOn, true);	// enable sound
 
 //
-// FIXME (Fingolfin asks): Why are Mickey, Winnie and Troll standalone classes
+// FIXME (Fingolfin asks): Why are Mickey and Troll standalone classes
 // instead of being subclasses of PreAgiEngine ?
 //
 
@@ -156,14 +156,6 @@ Common::Error PreAgiEngine::go() {
 			delete mickey;
 		}
 		break;
-	case GID_WINNIE:
-		{
-			Winnie *winnie = new Winnie(this);
-			winnie->init();
-			winnie->run();
-			delete winnie;
-		}
-		break;
 	case GID_TROLL:
 		{
 			Troll *troll = new Troll(this);
diff --git a/engines/agi/preagi.h b/engines/agi/preagi.h
index bb77786..1e752fb 100644
--- a/engines/agi/preagi.h
+++ b/engines/agi/preagi.h
@@ -34,7 +34,7 @@ class PreAgiEngine : public AgiBase {
 	int _gameId;
 
 protected:
-	Common::Error go();
+	virtual Common::Error go();
 	void initialize();
 
 public:
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 8af2bdb..7b86ca4 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -33,7 +33,7 @@
 
 namespace Agi {
 
-void Winnie::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
+void WinnieEngine::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
 	int i;
 
 	Common::MemoryReadStreamEndian readS(buffer, len, _isBigEndian);
@@ -68,7 +68,7 @@ void Winnie::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
 			roomHdr->opt[i].ofsOpt[j] = readS.readUint16();
 }
 
-void Winnie::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
+void WinnieEngine::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
 	int i;
 
 	Common::MemoryReadStreamEndian readS(buffer, len, _isBigEndian);
@@ -85,16 +85,16 @@ void Winnie::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
 	objHdr->ofsPic = readS.readUint16();
 }
 
-uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
+uint32 WinnieEngine::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
 	Common::String fileName;
 
-	if (_vm->getPlatform() == Common::kPlatformPC)
+	if (getPlatform() == Common::kPlatformPC)
 		fileName = Common::String::format(IDS_WTP_ROOM_DOS, iRoom);
-	else if (_vm->getPlatform() == Common::kPlatformAmiga)
+	else if (getPlatform() == Common::kPlatformAmiga)
 		fileName = Common::String::format(IDS_WTP_ROOM_AMIGA, iRoom);
-	else if (_vm->getPlatform() == Common::kPlatformC64)
+	else if (getPlatform() == Common::kPlatformC64)
 		fileName = Common::String::format(IDS_WTP_ROOM_C64, iRoom);
-	else if (_vm->getPlatform() == Common::kPlatformApple2GS)
+	else if (getPlatform() == Common::kPlatformApple2GS)
 		fileName = Common::String::format(IDS_WTP_ROOM_APPLE, iRoom);
 
 	Common::File file;
@@ -104,7 +104,7 @@ uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
 	}
 
 	uint32 filelen = file.size();
-	if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
+	if (getPlatform() == Common::kPlatformC64) { // Skip the loading address
 		filelen -= 2;
 		file.seek(2, SEEK_CUR);
 	}
@@ -118,16 +118,16 @@ uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
 	return filelen;
 }
 
-uint32 Winnie::readObj(int iObj, uint8 *buffer) {
+uint32 WinnieEngine::readObj(int iObj, uint8 *buffer) {
 	Common::String fileName;
 
-	if (_vm->getPlatform() == Common::kPlatformPC)
+	if (getPlatform() == Common::kPlatformPC)
 		fileName = Common::String::format(IDS_WTP_OBJ_DOS, iObj);
-	else if (_vm->getPlatform() == Common::kPlatformAmiga)
+	else if (getPlatform() == Common::kPlatformAmiga)
 		fileName = Common::String::format(IDS_WTP_OBJ_AMIGA, iObj);
-	else if (_vm->getPlatform() == Common::kPlatformC64)
+	else if (getPlatform() == Common::kPlatformC64)
 		fileName = Common::String::format(IDS_WTP_OBJ_C64, iObj);
-	else if (_vm->getPlatform() == Common::kPlatformApple2GS)
+	else if (getPlatform() == Common::kPlatformApple2GS)
 		fileName = Common::String::format(IDS_WTP_OBJ_APPLE, iObj);
 
 	Common::File file;
@@ -137,7 +137,7 @@ uint32 Winnie::readObj(int iObj, uint8 *buffer) {
 	}
 
 	uint32 filelen = file.size();
-	if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
+	if (getPlatform() == Common::kPlatformC64) { // Skip the loading address
 		filelen -= 2;
 		file.seek(2, SEEK_CUR);
 	}
@@ -148,7 +148,7 @@ uint32 Winnie::readObj(int iObj, uint8 *buffer) {
 	return filelen;
 }
 
-void Winnie::randomize() {
+void WinnieEngine::randomize() {
 	int iObj = 0;
 	int iRoom = 0;
 	bool done;
@@ -157,52 +157,52 @@ void Winnie::randomize() {
 		done = false;
 
 		while (!done) {
-			iObj = _vm->rnd(IDI_WTP_MAX_OBJ - 1);
+			iObj = rnd(IDI_WTP_MAX_OBJ - 1);
 			done = true;
 
 			for (int j = 0; j < IDI_WTP_MAX_OBJ_MISSING; j++) {
-				if (_game.iUsedObj[j] == iObj) {
+				if (_gameStateWinnie.iUsedObj[j] == iObj) {
 					done = false;
 					break;
 				}
 			}
 		}
 
-		_game.iUsedObj[i] = iObj;
+		_gameStateWinnie.iUsedObj[i] = iObj;
 
 		done = false;
 		while (!done) {
-			iRoom = _vm->rnd(IDI_WTP_MAX_ROOM_NORMAL);
+			iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
 			done = true;
 
 			for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
-				if (_game.iObjRoom[j] == iRoom) {
+				if (_gameStateWinnie.iObjRoom[j] == iRoom) {
 					done = false;
 					break;
 				}
 			}
 		}
 
-		_game.iObjRoom[iObj] = iRoom;
+		_gameStateWinnie.iObjRoom[iObj] = iRoom;
 	}
 }
 
-void Winnie::intro() {
+void WinnieEngine::intro() {
 	drawPic(IDS_WTP_FILE_LOGO);
-	_vm->printStr(IDS_WTP_INTRO_0);
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
-	_vm->_system->delayMillis(0x640);
+	printStr(IDS_WTP_INTRO_0);
+	_gfx->doUpdate();
+	_system->updateScreen();
+	_system->delayMillis(0x640);
 
-	if (_vm->getPlatform() == Common::kPlatformAmiga)
-		_vm->_gfx->clearScreen(0);
+	if (getPlatform() == Common::kPlatformAmiga)
+		_gfx->clearScreen(0);
 
 	drawPic(IDS_WTP_FILE_TITLE);
 
-	_vm->printStr(IDS_WTP_INTRO_1);
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
-	_vm->_system->delayMillis(0x640);
+	printStr(IDS_WTP_INTRO_1);
+	_gfx->doUpdate();
+	_system->updateScreen();
+	_system->delayMillis(0x640);
 
 	if (!playSound(IDI_WTP_SND_POOH_0))
 		return;
@@ -214,27 +214,27 @@ void Winnie::intro() {
 		return;
 }
 
-int Winnie::getObjInRoom(int iRoom) {
+int WinnieEngine::getObjInRoom(int iRoom) {
 	for (int iObj = 1; iObj < IDI_WTP_MAX_ROOM_OBJ; iObj++)
-		if (_game.iObjRoom[iObj] == iRoom)
+		if (_gameStateWinnie.iObjRoom[iObj] == iRoom)
 			return iObj;
 	return 0;
 }
 
-void Winnie::setTakeDrop(int fCanSel[]) {
+void WinnieEngine::setTakeDrop(int fCanSel[]) {
 	fCanSel[IDI_WTP_SEL_TAKE] = getObjInRoom(_room);
-	fCanSel[IDI_WTP_SEL_DROP] = _game.iObjHave;
+	fCanSel[IDI_WTP_SEL_DROP] = _gameStateWinnie.iObjHave;
 }
 
-void Winnie::setFlag(int iFlag) {
-	_game.fGame[iFlag] = 1;
+void WinnieEngine::setFlag(int iFlag) {
+	_gameStateWinnie.fGame[iFlag] = 1;
 }
 
-void Winnie::clearFlag(int iFlag) {
-	_game.fGame[iFlag] = 0;
+void WinnieEngine::clearFlag(int iFlag) {
+	_gameStateWinnie.fGame[iFlag] = 0;
 }
 
-int Winnie::parser(int pc, int index, uint8 *buffer) {
+int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 	WTP_ROOM_HDR hdr;
 	int startpc = pc;
 	int8 opcode;
@@ -249,7 +249,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 	// extract header from buffer
 	parseRoomHeader(&hdr, buffer, sizeof(WTP_ROOM_HDR));
 
-	while (!_vm->shouldQuit()) {
+	while (!shouldQuit()) {
 		pc = startpc;
 
 		// check if block is to be run
@@ -259,7 +259,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 			return IDI_WTP_PAR_OK;
 
 		fBlock = *(buffer + pc++);
-		if (_game.fGame[iBlock] != fBlock)
+		if (_gameStateWinnie.fGame[iBlock] != fBlock)
 			return IDI_WTP_PAR_OK;
 
 		// extract text from block
@@ -292,12 +292,12 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 
 			// extract menu string
 			strcpy(szMenu, (char *)(buffer + pc));
-			_vm->XOR80(szMenu);
+			XOR80(szMenu);
 			break;
 		default:
 			// print description
 			printStrWinnie((char *)(buffer + pc));
-			if (_vm->getSelection(kSelBackspace) == 1)
+			if (getSelection(kSelBackspace) == 1)
 				return IDI_WTP_PAR_OK;
 			else
 				return IDI_WTP_PAR_BACK;
@@ -314,7 +314,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 			// get menu selection
 			getMenuSel(szMenu, &iSel, fCanSel);
 
-			if (++_game.nMoves == IDI_WTP_MAX_MOVES_UNTIL_WIND)
+			if (++_gameStateWinnie.nMoves == IDI_WTP_MAX_MOVES_UNTIL_WIND)
 				_doWind = true;
 
 			if (_winnieEvent && (_room <= IDI_WTP_MAX_ROOM_TELEPORT)) {
@@ -356,8 +356,8 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 				iDir = iSel - IDI_WTP_SEL_NORTH;
 
 				if (hdr.roomNew[iDir] == IDI_WTP_ROOM_NONE) {
-					_vm->printStr(IDS_WTP_CANT_GO);
-					_vm->getSelection(kSelAnyKey);
+					printStr(IDS_WTP_CANT_GO);
+					getSelection(kSelAnyKey);
 				} else {
 					_room = hdr.roomNew[iDir];
 					return IDI_WTP_PAR_GOTO;
@@ -391,7 +391,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 			case IDO_WTP_PRINT_MSG:
 				opcode = *(buffer + pc++);
 				printRoomStr(_room, opcode);
-				_vm->getSelection(kSelAnyKey);
+				getSelection(kSelAnyKey);
 				break;
 			case IDO_WTP_PRINT_STR:
 				opcode = *(buffer + pc++);
@@ -416,7 +416,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 			case IDO_WTP_WALK_MIST:
 				_mist--;
 				if (!_mist) {
-					_room = _vm->rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+					_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
 					return IDI_WTP_PAR_GOTO;
 				}
 				break;
@@ -437,13 +437,13 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 				showOwlHelp();
 				break;
 			case IDO_WTP_GOTO_RND:
-				_room = _vm->rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+				_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
 				return IDI_WTP_PAR_GOTO;
 			default:
 				opcode = 0;
 				break;
 			}
-		} while (opcode && !_vm->shouldQuit());
+		} while (opcode && !shouldQuit());
 
 		if (iNewRoom) {
 			_room = iNewRoom;
@@ -452,38 +452,38 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
 
 		if (iBlock == 1)
 			return IDI_WTP_PAR_OK;
-		_vm->_gfx->doUpdate();
-		_vm->_system->updateScreen();
+		_gfx->doUpdate();
+		_system->updateScreen();
 	}
 
 	return IDI_WTP_PAR_OK;
 }
 
-void Winnie::keyHelp() {
+void WinnieEngine::keyHelp() {
 	playSound(IDI_WTP_SND_KEYHELP);
-	_vm->printStr(IDS_WTP_HELP_0);
-	_vm->getSelection(kSelAnyKey);
-	_vm->printStr(IDS_WTP_HELP_1);
-	_vm->getSelection(kSelAnyKey);
+	printStr(IDS_WTP_HELP_0);
+	getSelection(kSelAnyKey);
+	printStr(IDS_WTP_HELP_1);
+	getSelection(kSelAnyKey);
 }
 
-void Winnie::inventory() {
-	if (_game.iObjHave)
-		printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE);
+void WinnieEngine::inventory() {
+	if (_gameStateWinnie.iObjHave)
+		printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_TAKE);
 	else {
-		_vm->clearTextArea();
-		_vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0);
+		clearTextArea();
+		drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0);
 	}
 
-	Common::String missing = Common::String::format(IDS_WTP_INVENTORY_1, _game.nObjMiss);
+	Common::String missing = Common::String::format(IDS_WTP_INVENTORY_1, _gameStateWinnie.nObjMiss);
 
-	_vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, missing.c_str());
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen(); //TODO: Move to game's main loop
-	_vm->getSelection(kSelAnyKey);
+	drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, missing.c_str());
+	_gfx->doUpdate();
+	_system->updateScreen(); //TODO: Move to game's main loop
+	getSelection(kSelAnyKey);
 }
 
-void Winnie::printObjStr(int iObj, int iStr) {
+void WinnieEngine::printObjStr(int iObj, int iStr) {
 	WTP_OBJ_HDR hdr;
 	uint8 *buffer = (uint8 *)malloc(2048);
 
@@ -494,7 +494,7 @@ void Winnie::printObjStr(int iObj, int iStr) {
 	free(buffer);
 }
 
-bool Winnie::isRightObj(int iRoom, int iObj, int *iCode) {
+bool WinnieEngine::isRightObj(int iRoom, int iObj, int *iCode) {
 	WTP_ROOM_HDR roomhdr;
 	WTP_OBJ_HDR	objhdr;
 	uint8 *roomdata = (uint8 *)malloc(4096);
@@ -517,212 +517,212 @@ bool Winnie::isRightObj(int iRoom, int iObj, int *iCode) {
 		return false;
 }
 
-void Winnie::takeObj(int iRoom) {
-	if (_game.iObjHave) {
+void WinnieEngine::takeObj(int iRoom) {
+	if (_gameStateWinnie.iObjHave) {
 		// player is already carrying an object, can't take
-		_vm->printStr(IDS_WTP_CANT_TAKE);
-		_vm->getSelection(kSelAnyKey);
+		printStr(IDS_WTP_CANT_TAKE);
+		getSelection(kSelAnyKey);
 	} else {
 		// take object
 		int iObj = getObjInRoom(iRoom);
 
-		_game.iObjHave = iObj;
-		_game.iObjRoom[iObj] = 0;
+		_gameStateWinnie.iObjHave = iObj;
+		_gameStateWinnie.iObjRoom[iObj] = 0;
 
-		_vm->printStr(IDS_WTP_OK);
+		printStr(IDS_WTP_OK);
 		playSound(IDI_WTP_SND_TAKE);
 
 		drawRoomPic();
 
 		// print object "take" string
-		printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE);
-		_vm->getSelection(kSelAnyKey);
+		printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_TAKE);
+		getSelection(kSelAnyKey);
 
 		// HACK WARNING
 		if (iObj == 18) {
-			_game.fGame[0x0d] = 1;
+			_gameStateWinnie.fGame[0x0d] = 1;
 		}
 	}
 }
 
-void Winnie::dropObj(int iRoom) {
+void WinnieEngine::dropObj(int iRoom) {
 	int iCode;
 
 	if (getObjInRoom(iRoom)) {
 		// there already is an object in the room, can't drop
-		_vm->printStr(IDS_WTP_CANT_DROP);
-		_vm->getSelection(kSelAnyKey);
+		printStr(IDS_WTP_CANT_DROP);
+		getSelection(kSelAnyKey);
 	} else {
 		// HACK WARNING
-		if (_game.iObjHave == 18) {
-			_game.fGame[0x0d] = 0;
+		if (_gameStateWinnie.iObjHave == 18) {
+			_gameStateWinnie.fGame[0x0d] = 0;
 		}
 
-		if (isRightObj(iRoom, _game.iObjHave, &iCode)) {
+		if (isRightObj(iRoom, _gameStateWinnie.iObjHave, &iCode)) {
 			// object has been dropped in the right place
-			_vm->printStr(IDS_WTP_OK);
-			_vm->getSelection(kSelAnyKey);
+			printStr(IDS_WTP_OK);
+			getSelection(kSelAnyKey);
 			playSound(IDI_WTP_SND_DROP_OK);
-			printObjStr(_game.iObjHave, IDI_WTP_OBJ_DROP);
-			_vm->getSelection(kSelAnyKey);
+			printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_DROP);
+			getSelection(kSelAnyKey);
 
 			// increase amount of objects returned, decrease amount of objects missing
-			_game.nObjMiss--;
-			_game.nObjRet++;
+			_gameStateWinnie.nObjMiss--;
+			_gameStateWinnie.nObjRet++;
 
 			// xor the dropped object with 0x80 to signify it has been dropped in the right place
 			for (int i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++) {
-				if (_game.iUsedObj[i] == _game.iObjHave) {
-					_game.iUsedObj[i] ^= 0x80;
+				if (_gameStateWinnie.iUsedObj[i] == _gameStateWinnie.iObjHave) {
+					_gameStateWinnie.iUsedObj[i] ^= 0x80;
 					break;
 				}
 			}
 
 			// set flag according to dropped object's id
-			_game.fGame[iCode] = 1;
+			_gameStateWinnie.fGame[iCode] = 1;
 
 			// player is carrying nothing
-			_game.iObjHave = 0;
+			_gameStateWinnie.iObjHave = 0;
 
-			if (!_game.nObjMiss) {
+			if (!_gameStateWinnie.nObjMiss) {
 				// all objects returned, tell player to find party
 				playSound(IDI_WTP_SND_FANFARE);
-				_vm->printStr(IDS_WTP_GAME_OVER_0);
-				_vm->getSelection(kSelAnyKey);
-				_vm->printStr(IDS_WTP_GAME_OVER_1);
-				_vm->getSelection(kSelAnyKey);
+				printStr(IDS_WTP_GAME_OVER_0);
+				getSelection(kSelAnyKey);
+				printStr(IDS_WTP_GAME_OVER_1);
+				getSelection(kSelAnyKey);
 			}
 		} else {
 			// drop object in the given room
-			_game.iObjRoom[_game.iObjHave] = iRoom;
+			_gameStateWinnie.iObjRoom[_gameStateWinnie.iObjHave] = iRoom;
 
 			// object has been dropped in the wrong place
-			_vm->printStr(IDS_WTP_WRONG_PLACE);
-			_vm->getSelection(kSelAnyKey);
+			printStr(IDS_WTP_WRONG_PLACE);
+			getSelection(kSelAnyKey);
 
 			playSound(IDI_WTP_SND_DROP);
 			drawRoomPic();
 
-			_vm->printStr(IDS_WTP_WRONG_PLACE);
-			_vm->getSelection(kSelAnyKey);
+			printStr(IDS_WTP_WRONG_PLACE);
+			getSelection(kSelAnyKey);
 
 			// print object description
-			printObjStr(_game.iObjHave, IDI_WTP_OBJ_DESC);
-			_vm->getSelection(kSelAnyKey);
+			printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_DESC);
+			getSelection(kSelAnyKey);
 
-			_game.iObjHave = 0;
+			_gameStateWinnie.iObjHave = 0;
 		}
 	}
 }
 
-void Winnie::dropObjRnd() {
-	if (!_game.iObjHave)
+void WinnieEngine::dropObjRnd() {
+	if (!_gameStateWinnie.iObjHave)
 		return;
 
 	int iRoom = 0;
 	bool done = false;
 
 	while (!done) {
-		iRoom = _vm->rnd(IDI_WTP_MAX_ROOM_NORMAL);
+		iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
 		done = true;
 		if (iRoom == _room)
 			done = false;
 		for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
-			if (_game.iObjRoom[j] == iRoom) {
+			if (_gameStateWinnie.iObjRoom[j] == iRoom) {
 				done = false;
 			}
 		}
 	}
 
-	_game.iObjRoom[_game.iObjHave] = iRoom;
-	_game.iObjHave = 0;
+	_gameStateWinnie.iObjRoom[_gameStateWinnie.iObjHave] = iRoom;
+	_gameStateWinnie.iObjHave = 0;
 }
 
-void Winnie::wind() {
+void WinnieEngine::wind() {
 	int iRoom = 0;
 	bool done;
 
 	_doWind = 0;
-	_game.nMoves = 0;
-	if (!_game.nObjMiss)
+	_gameStateWinnie.nMoves = 0;
+	if (!_gameStateWinnie.nObjMiss)
 		return;
 
-	_vm->printStr(IDS_WTP_WIND_0);
+	printStr(IDS_WTP_WIND_0);
 	playSound(IDI_WTP_SND_WIND_0);
-	_vm->getSelection(kSelAnyKey);
+	getSelection(kSelAnyKey);
 
-	_vm->printStr(IDS_WTP_WIND_1);
+	printStr(IDS_WTP_WIND_1);
 	playSound(IDI_WTP_SND_WIND_0);
-	_vm->getSelection(kSelAnyKey);
+	getSelection(kSelAnyKey);
 
 	dropObjRnd();
 
 	// randomize positions of objects at large
 	for (int i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++) {
-		if (!(_game.iUsedObj[i] & IDI_XOR_KEY)) {
+		if (!(_gameStateWinnie.iUsedObj[i] & IDI_XOR_KEY)) {
 			done = false;
 			while (!done) {
-				iRoom = _vm->rnd(IDI_WTP_MAX_ROOM_NORMAL);
+				iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
 				done = true;
 
 				for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
-					if (_game.iObjRoom[j] == iRoom) {
+					if (_gameStateWinnie.iObjRoom[j] == iRoom) {
 						done = false;
 					}
 				}
 			}
-			_game.iObjRoom[_game.iUsedObj[i]] = iRoom;
+			_gameStateWinnie.iObjRoom[_gameStateWinnie.iUsedObj[i]] = iRoom;
 		}
 	}
 }
 
-void Winnie::mist() {
+void WinnieEngine::mist() {
 	// mist length in turns is (2-5)
-	_mist = _vm->rnd(4) + 2;
+	_mist = rnd(4) + 2;
 
 	_room = IDI_WTP_ROOM_MIST;
 	drawRoomPic();
 
-	_vm->printStr(IDS_WTP_MIST);
+	printStr(IDS_WTP_MIST);
 }
 
-void Winnie::tigger() {
+void WinnieEngine::tigger() {
 	_room = IDI_WTP_ROOM_TIGGER;
 
 	drawRoomPic();
-	_vm->printStr(IDS_WTP_TIGGER);
+	printStr(IDS_WTP_TIGGER);
 
 	dropObjRnd();
 }
 
-void Winnie::showOwlHelp() {
-	if (_game.iObjHave) {
-		_vm->printStr(IDS_WTP_OWL_0);
-		_vm->getSelection(kSelAnyKey);
-		printObjStr(_game.iObjHave, IDI_WTP_OBJ_HELP);
-		_vm->getSelection(kSelAnyKey);
+void WinnieEngine::showOwlHelp() {
+	if (_gameStateWinnie.iObjHave) {
+		printStr(IDS_WTP_OWL_0);
+		getSelection(kSelAnyKey);
+		printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_HELP);
+		getSelection(kSelAnyKey);
 	}
 	if (getObjInRoom(_room)) {
-		_vm->printStr(IDS_WTP_OWL_0);
-		_vm->getSelection(kSelAnyKey);
+		printStr(IDS_WTP_OWL_0);
+		getSelection(kSelAnyKey);
 		printObjStr(getObjInRoom(_room), IDI_WTP_OBJ_HELP);
-		_vm->getSelection(kSelAnyKey);
+		getSelection(kSelAnyKey);
 	}
 }
 
 
-void Winnie::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
+void WinnieEngine::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
 	int iRow = 0, iCol = 0;
 
-	_vm->clearTextArea();
-	_vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, szMenu);
+	clearTextArea();
+	drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, szMenu);
 
 	if (fCanSel[IDI_WTP_SEL_NORTH])
-		_vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_NSEW, IDA_DEFAULT, IDS_WTP_NSEW);
+		drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_NSEW, IDA_DEFAULT, IDS_WTP_NSEW);
 	if (fCanSel[IDI_WTP_SEL_TAKE])
-		_vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_TAKE, IDA_DEFAULT, IDS_WTP_TAKE);
+		drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_TAKE, IDA_DEFAULT, IDS_WTP_TAKE);
 	if (fCanSel[IDI_WTP_SEL_DROP])
-		_vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_DROP, IDA_DEFAULT, IDS_WTP_DROP);
+		drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_DROP, IDA_DEFAULT, IDS_WTP_DROP);
 
 	switch (iSel) {
 	case IDI_WTP_SEL_OPT_1:
@@ -756,26 +756,26 @@ void Winnie::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
 		iCol = IDI_WTP_COL_DROP;
 		break;
 	}
-	_vm->drawStr(iRow, iCol - 1, IDA_DEFAULT, ">");
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen(); //TODO: Move to game's main loop
+	drawStr(iRow, iCol - 1, IDA_DEFAULT, ">");
+	_gfx->doUpdate();
+	_system->updateScreen(); //TODO: Move to game's main loop
 }
 
-void Winnie::incMenuSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::incMenuSel(int *iSel, int fCanSel[]) {
 	do {
 		*iSel += 1;
 		if (*iSel > IDI_WTP_SEL_DROP) *iSel = IDI_WTP_SEL_OPT_1;
 	} while (!fCanSel[*iSel]);
 }
 
-void Winnie::decMenuSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::decMenuSel(int *iSel, int fCanSel[]) {
 	do {
 		*iSel -= 1;
 		if (*iSel < IDI_WTP_SEL_OPT_1) *iSel = IDI_WTP_SEL_DROP;
 	} while (!fCanSel[*iSel]);
 }
 
-void Winnie::getMenuMouseSel(int *iSel, int fCanSel[], int x, int y) {
+void WinnieEngine::getMenuMouseSel(int *iSel, int fCanSel[], int x, int y) {
 	switch (y) {
 	case IDI_WTP_ROW_OPTION_1:
 	case IDI_WTP_ROW_OPTION_2:
@@ -793,7 +793,7 @@ void Winnie::getMenuMouseSel(int *iSel, int fCanSel[], int x, int y) {
 	}
 }
 
-void Winnie::makeSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::makeSel(int *iSel, int fCanSel[]) {
 	if (fCanSel[*iSel])
 		return;
 
@@ -801,7 +801,7 @@ void Winnie::makeSel(int *iSel, int fCanSel[]) {
 	clrMenuSel(iSel, fCanSel);
 }
 
-void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
+void WinnieEngine::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 	Common::Event event;
 	int x, y;
 
@@ -811,8 +811,8 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 	// Show the mouse cursor for the menu
 	CursorMan.showMouse(true);
 
-	while (!_vm->shouldQuit()) {
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
+	while (!shouldQuit()) {
+		while (_system->getEventManager()->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_RTL:
 			case Common::EVENT_QUIT:
@@ -824,15 +824,15 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 
 				// Change cursor
 				if (fCanSel[IDI_WTP_SEL_NORTH] && hotspotNorth.contains(event.mouse.x, event.mouse.y)) {
-					_vm->_gfx->setCursorPalette(true);
+					_gfx->setCursorPalette(true);
 				} else if (fCanSel[IDI_WTP_SEL_SOUTH] && hotspotSouth.contains(event.mouse.x, event.mouse.y)) {
-					_vm->_gfx->setCursorPalette(true);
+					_gfx->setCursorPalette(true);
 				} else if (fCanSel[IDI_WTP_SEL_WEST] && hotspotWest.contains(event.mouse.x, event.mouse.y)) {
-					_vm->_gfx->setCursorPalette(true);
+					_gfx->setCursorPalette(true);
 				} else if (fCanSel[IDI_WTP_SEL_EAST] && hotspotEast.contains(event.mouse.x, event.mouse.y)) {
-					_vm->_gfx->setCursorPalette(true);
+					_gfx->setCursorPalette(true);
 				} else {
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 				}
 
 				break;
@@ -841,25 +841,25 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 				if (fCanSel[IDI_WTP_SEL_NORTH] && hotspotNorth.contains(event.mouse.x, event.mouse.y)) {
 					*iSel = IDI_WTP_SEL_NORTH;
 					makeSel(iSel, fCanSel);
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					return;
 				} else if (fCanSel[IDI_WTP_SEL_SOUTH] && hotspotSouth.contains(event.mouse.x, event.mouse.y)) {
 					*iSel = IDI_WTP_SEL_SOUTH;
 					makeSel(iSel, fCanSel);
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					return;
 				} else if (fCanSel[IDI_WTP_SEL_WEST] && hotspotWest.contains(event.mouse.x, event.mouse.y)) {
 					*iSel = IDI_WTP_SEL_WEST;
 					makeSel(iSel, fCanSel);
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					return;
 				} else if (fCanSel[IDI_WTP_SEL_EAST] && hotspotEast.contains(event.mouse.x, event.mouse.y)) {
 					*iSel = IDI_WTP_SEL_EAST;
 					makeSel(iSel, fCanSel);
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					return;
 				} else {
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 				}
 
 				switch (*iSel) {
@@ -896,9 +896,9 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 				incMenuSel(iSel, fCanSel);
 				break;
 			case Common::EVENT_KEYDOWN:
-				if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _vm->_console) {
-					_vm->_console->attach();
-					_vm->_console->onFrame();
+				if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
+					_console->attach();
+					_console->onFrame();
 					continue;
 				}
 
@@ -944,7 +944,7 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 					break;
 				case Common::KEYCODE_s:
 					if (event.kbd.flags & Common::KBD_CTRL) {
-						_vm->flipflag(fSoundOn);
+						flipflag(fSoundOn);
 					} else {
 						*iSel = IDI_WTP_SEL_SOUTH;
 						makeSel(iSel, fCanSel);
@@ -1005,24 +1005,24 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 	}
 }
 
-void Winnie::gameLoop() {
+void WinnieEngine::gameLoop() {
 	WTP_ROOM_HDR hdr;
 	uint8 *roomdata = (uint8 *)malloc(4096);
 	int iBlock;
 
 phase0:
-	if (!_game.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
+	if (!_gameStateWinnie.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
 		_room = IDI_WTP_ROOM_PARTY;
 
 	readRoom(_room, roomdata, hdr);
 	drawRoomPic();
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
+	_gfx->doUpdate();
+	_system->updateScreen();
 
 phase1:
 	if (getObjInRoom(_room)) {
 		printObjStr(getObjInRoom(_room), IDI_WTP_OBJ_DESC);
-		_vm->getSelection(kSelAnyKey);
+		getSelection(kSelAnyKey);
 	}
 
 phase2:
@@ -1031,7 +1031,7 @@ phase2:
 			goto phase1;
 	}
 
-	while (!_vm->shouldQuit()) {
+	while (!shouldQuit()) {
 		for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
 			switch (parser(hdr.ofsBlock[iBlock] - _roomOffset, iBlock, roomdata)) {
 			case IDI_WTP_PAR_GOTO:
@@ -1047,10 +1047,10 @@ phase2:
 	free(roomdata);
 }
 
-void Winnie::drawPic(const char *szName) {
+void WinnieEngine::drawPic(const char *szName) {
 	Common::String fileName = szName;
 
-	if (_vm->getPlatform() != Common::kPlatformAmiga)
+	if (getPlatform() != Common::kPlatformAmiga)
 		fileName += ".pic";
 
 	Common::File file;
@@ -1065,13 +1065,13 @@ void Winnie::drawPic(const char *szName) {
 	file.read(buffer, size);
 	file.close();
 
-	_vm->_picture->decodePicture(buffer, size, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
-	_vm->_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+	_picture->decodePicture(buffer, size, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+	_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
 
 	free(buffer);
 }
 
-void Winnie::drawObjPic(int iObj, int x0, int y0) {
+void WinnieEngine::drawObjPic(int iObj, int x0, int y0) {
 	if (!iObj)
 		return;
 
@@ -1080,28 +1080,28 @@ void Winnie::drawObjPic(int iObj, int x0, int y0) {
 	uint32 objSize = readObj(iObj, buffer);
 	parseObjHeader(&objhdr, buffer, sizeof(WTP_OBJ_HDR));
 
-	_vm->_picture->setOffset(x0, y0);
-	_vm->_picture->decodePicture(buffer + objhdr.ofsPic - _objOffset, objSize, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
-	_vm->_picture->setOffset(0, 0);
-	_vm->_picture->showPic(10, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+	_picture->setOffset(x0, y0);
+	_picture->decodePicture(buffer + objhdr.ofsPic - _objOffset, objSize, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+	_picture->setOffset(0, 0);
+	_picture->showPic(10, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
 
 	free(buffer);
 }
 
-void Winnie::drawRoomPic() {
+void WinnieEngine::drawRoomPic() {
 	WTP_ROOM_HDR roomhdr;
 	uint8 *buffer = (uint8 *)malloc(4096);
 	int iObj = getObjInRoom(_room);
 
 	// clear gfx screen
-	_vm->_gfx->clearScreen(0);
+	_gfx->clearScreen(0);
 
 	// read room picture
 	readRoom(_room, buffer, roomhdr);
 
 	// draw room picture
-	_vm->_picture->decodePicture(buffer + roomhdr.ofsPic - _roomOffset, 4096, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
-	_vm->_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+	_picture->decodePicture(buffer + roomhdr.ofsPic - _roomOffset, 4096, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+	_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
 
 	// draw object picture
 	drawObjPic(iObj, IDI_WTP_PIC_X0 + roomhdr.objX, IDI_WTP_PIC_Y0 + roomhdr.objY);
@@ -1109,9 +1109,9 @@ void Winnie::drawRoomPic() {
 	free(buffer);
 }
 
-bool Winnie::playSound(ENUM_WTP_SOUND iSound) {
+bool WinnieEngine::playSound(ENUM_WTP_SOUND iSound) {
 	// TODO: Only DOS sound is supported, currently
-	if (_vm->getPlatform() != Common::kPlatformPC) {
+	if (getPlatform() != Common::kPlatformPC) {
 		warning("STUB: playSound(%d)", iSound);
 		return false;
 	}
@@ -1127,20 +1127,20 @@ bool Winnie::playSound(ENUM_WTP_SOUND iSound) {
 	file.read(data, size);
 	file.close();
 
-	_vm->_game.sounds[0] = AgiSound::createFromRawResource(data, size, 0, *_vm->_sound, _vm->_soundemu);
-	_vm->_sound->startSound(0, 0);
+	_game.sounds[0] = AgiSound::createFromRawResource(data, size, 0, *_sound, _soundemu);
+	_sound->startSound(0, 0);
 
 	bool cursorShowing = CursorMan.showMouse(false);
-	_vm->_system->updateScreen();
+	_system->updateScreen();
 
 	// Loop until the sound is done
 	bool skippedSound = false;
-	while (!_vm->shouldQuit() && _vm->_game.sounds[0]->isPlaying()) {
+	while (!shouldQuit() && _game.sounds[0]->isPlaying()) {
 		Common::Event event;
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
+		while (_system->getEventManager()->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_KEYDOWN:
-				_vm->_sound->stopSound();
+				_sound->stopSound();
 				skippedSound = true;
 				break;
 			default:
@@ -1148,29 +1148,29 @@ bool Winnie::playSound(ENUM_WTP_SOUND iSound) {
 			}
 		}
 
-		_vm->_system->delayMillis(10);
+		_system->delayMillis(10);
 	}
 
 	if (cursorShowing) {
 		CursorMan.showMouse(true);
-		_vm->_system->updateScreen();
+		_system->updateScreen();
 	}
 
-	delete _vm->_game.sounds[0];
-	_vm->_game.sounds[0] = 0;
+	delete _game.sounds[0];
+	_game.sounds[0] = 0;
 
-	return !_vm->shouldQuit() && !skippedSound;
+	return !shouldQuit() && !skippedSound;
 }
 
-void Winnie::clrMenuSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::clrMenuSel(int *iSel, int fCanSel[]) {
 	*iSel = IDI_WTP_SEL_OPT_1;
 	while (!fCanSel[*iSel]) {
 		*iSel += 1;
 	}
-	_vm->_gfx->setCursorPalette(false);
+	_gfx->setCursorPalette(false);
 }
 
-void Winnie::printRoomStr(int iRoom, int iStr) {
+void WinnieEngine::printRoomStr(int iRoom, int iStr) {
 	WTP_ROOM_HDR hdr;
 	uint8 *buffer = (uint8 *)malloc(4096);
 
@@ -1180,23 +1180,23 @@ void Winnie::printRoomStr(int iRoom, int iStr) {
 	free(buffer);
 }
 
-void Winnie::gameOver() {
+void WinnieEngine::gameOver() {
 	// sing the Pooh song forever
-	while (!_vm->shouldQuit()) {
-		_vm->printStr(IDS_WTP_SONG_0);
+	while (!shouldQuit()) {
+		printStr(IDS_WTP_SONG_0);
 		playSound(IDI_WTP_SND_POOH_0);
-		_vm->printStr(IDS_WTP_SONG_1);
+		printStr(IDS_WTP_SONG_1);
 		playSound(IDI_WTP_SND_POOH_1);
-		_vm->printStr(IDS_WTP_SONG_2);
+		printStr(IDS_WTP_SONG_2);
 		playSound(IDI_WTP_SND_POOH_2);
-		_vm->getSelection(kSelAnyKey);
+		getSelection(kSelAnyKey);
 	}
 }
 
-void Winnie::saveGame() {
+void WinnieEngine::saveGame() {
 	int i = 0;
 
-	Common::OutSaveFile *outfile = _vm->getSaveFileMan()->openForSaving(IDS_WTP_FILE_SAVEGAME);
+	Common::OutSaveFile *outfile = getSaveFileMan()->openForSaving(IDS_WTP_FILE_SAVEGAME);
 
 	if (!outfile)
 		return;
@@ -1204,20 +1204,20 @@ void Winnie::saveGame() {
 	outfile->writeUint32BE(MKTAG('W','I','N','N'));	// header
 	outfile->writeByte(WTP_SAVEGAME_VERSION);
 
-	outfile->writeByte(_game.fSound);
-	outfile->writeByte(_game.nMoves);
-	outfile->writeByte(_game.nObjMiss);
-	outfile->writeByte(_game.nObjRet);
-	outfile->writeByte(_game.iObjHave);
+	outfile->writeByte(_gameStateWinnie.fSound);
+	outfile->writeByte(_gameStateWinnie.nMoves);
+	outfile->writeByte(_gameStateWinnie.nObjMiss);
+	outfile->writeByte(_gameStateWinnie.nObjRet);
+	outfile->writeByte(_gameStateWinnie.iObjHave);
 
 	for (i = 0; i < IDI_WTP_MAX_FLAG; i++)
-		outfile->writeByte(_game.fGame[i]);
+		outfile->writeByte(_gameStateWinnie.fGame[i]);
 
 	for (i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++)
-		outfile->writeByte(_game.iUsedObj[i]);
+		outfile->writeByte(_gameStateWinnie.iUsedObj[i]);
 
 	for (i = 0; i < IDI_WTP_MAX_ROOM_OBJ; i++)
-		outfile->writeByte(_game.iObjRoom[i]);
+		outfile->writeByte(_gameStateWinnie.iObjRoom[i]);
 
 	outfile->finalize();
 
@@ -1227,11 +1227,11 @@ void Winnie::saveGame() {
 	delete outfile;
 }
 
-void Winnie::loadGame() {
+void WinnieEngine::loadGame() {
 	int saveVersion = 0;
 	int i = 0;
 
-	Common::InSaveFile *infile = _vm->getSaveFileMan()->openForLoading(IDS_WTP_FILE_SAVEGAME);
+	Common::InSaveFile *infile = getSaveFileMan()->openForLoading(IDS_WTP_FILE_SAVEGAME);
 
 	if (!infile)
 		return;
@@ -1241,11 +1241,11 @@ void Winnie::loadGame() {
 		if (saveVersion != WTP_SAVEGAME_VERSION)
 			warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, WTP_SAVEGAME_VERSION);
 
-		_game.fSound = infile->readByte();
-		_game.nMoves = infile->readByte();
-		_game.nObjMiss = infile->readByte();
-		_game.nObjRet = infile->readByte();
-		_game.iObjHave = infile->readByte();
+		_gameStateWinnie.fSound = infile->readByte();
+		_gameStateWinnie.nMoves = infile->readByte();
+		_gameStateWinnie.nObjMiss = infile->readByte();
+		_gameStateWinnie.nObjRet = infile->readByte();
+		_gameStateWinnie.iObjHave = infile->readByte();
 	} else {
 		// This is probably a save from the original interpreter, throw a warning and attempt
 		// to read it as LE
@@ -1258,31 +1258,31 @@ void Winnie::loadGame() {
 
 		infile->readUint16LE();				// skip unused field
 		infile->readByte();					// first 8 bits of fSound
-		_game.fSound = infile->readByte();
+		_gameStateWinnie.fSound = infile->readByte();
 		infile->readByte();					// first 8 bits of nMoves
-		_game.nMoves = infile->readByte();
+		_gameStateWinnie.nMoves = infile->readByte();
 		infile->readByte();					// first 8 bits of nObjMiss
-		_game.nObjMiss = infile->readByte();
+		_gameStateWinnie.nObjMiss = infile->readByte();
 		infile->readByte();					// first 8 bits of nObjRet
-		_game.nObjRet = infile->readByte();
+		_gameStateWinnie.nObjRet = infile->readByte();
 		infile->readUint16LE();				// skip unused field
 		infile->readUint16LE();				// skip unused field
 		infile->readUint16LE();				// skip unused field
 		infile->readByte();					// first 8 bits of iObjHave
-		_game.iObjHave = infile->readByte();
+		_gameStateWinnie.iObjHave = infile->readByte();
 		infile->readUint16LE();				// skip unused field
 		infile->readUint16LE();				// skip unused field
 		infile->readUint16LE();				// skip unused field
 	}
 
 	for (i = 0; i < IDI_WTP_MAX_FLAG; i++)
-		_game.fGame[i] = infile->readByte();
+		_gameStateWinnie.fGame[i] = infile->readByte();
 
 	for (i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++)
-		_game.iUsedObj[i] = infile->readByte();
+		_gameStateWinnie.iUsedObj[i] = infile->readByte();
 
 	for (i = 0; i < IDI_WTP_MAX_ROOM_OBJ; i++)
-		_game.iObjRoom[i] = infile->readByte();
+		_gameStateWinnie.iObjRoom[i] = infile->readByte();
 
 	// Note that saved games from the original interpreter have 2 more 16-bit fields here
 	// which are ignored
@@ -1290,37 +1290,41 @@ void Winnie::loadGame() {
 	delete infile;
 }
 
-void Winnie::printStrWinnie(char *szMsg) {
-	if (_vm->getPlatform() != Common::kPlatformAmiga)
-		_vm->printStrXOR(szMsg);
+void WinnieEngine::printStrWinnie(char *szMsg) {
+	if (getPlatform() != Common::kPlatformAmiga)
+		printStrXOR(szMsg);
 	else
-		_vm->printStr(szMsg);
+		printStr(szMsg);
 }
 
 // Console-related functions
 
-void Winnie::debugCurRoom() {
-	_vm->_console->DebugPrintf("Current Room = %d\n", _room);
+void WinnieEngine::debugCurRoom() {
+	_console->DebugPrintf("Current Room = %d\n", _room);
 }
 
-Winnie::Winnie(PreAgiEngine* vm) : _vm(vm) {
-	_vm->_console = new Winnie_Console(_vm, this);
+WinnieEngine::WinnieEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
+	_console = new Winnie_Console(this);
 }
 
-void Winnie::init() {
-	memset(&_game, 0, sizeof(_game));
-	_game.fSound = 1;
-	_game.nObjMiss = IDI_WTP_MAX_OBJ_MISSING;
-	_game.nObjRet = 0;
-	_game.fGame[0] = 1;
-	_game.fGame[1] = 1;
+WinnieEngine::~WinnieEngine() {
+	delete _console;
+}
+
+void WinnieEngine::init() {
+	memset(&_gameStateWinnie, 0, sizeof(_gameStateWinnie));
+	_gameStateWinnie.fSound = 1;
+	_gameStateWinnie.nObjMiss = IDI_WTP_MAX_OBJ_MISSING;
+	_gameStateWinnie.nObjRet = 0;
+	_gameStateWinnie.fGame[0] = 1;
+	_gameStateWinnie.fGame[1] = 1;
 	_room = IDI_WTP_ROOM_HOME;
 
 	_mist = -1;
 	_doWind = false;
 	_winnieEvent = false;
 
-	if (_vm->getPlatform() != Common::kPlatformAmiga) {
+	if (getPlatform() != Common::kPlatformAmiga) {
 		_isBigEndian = false;
 		_roomOffset = IDI_WTP_OFS_ROOM;
 		_objOffset = IDI_WTP_OFS_OBJ;
@@ -1330,8 +1334,8 @@ void Winnie::init() {
 		_objOffset = 0;
 	}
 
-	if (_vm->getPlatform() == Common::kPlatformC64 || _vm->getPlatform() == Common::kPlatformApple2GS)
-		_vm->_picture->setPictureVersion(AGIPIC_C64);
+	if (getPlatform() == Common::kPlatformC64 || getPlatform() == Common::kPlatformApple2GS)
+		_picture->setPictureVersion(AGIPIC_C64);
 
 	hotspotNorth = Common::Rect(20, 0, (IDI_WTP_PIC_WIDTH + 10) * 2, 10);
 	hotspotSouth = Common::Rect(20, IDI_WTP_PIC_HEIGHT - 10, (IDI_WTP_PIC_WIDTH + 10) * 2, IDI_WTP_PIC_HEIGHT);
@@ -1339,11 +1343,17 @@ void Winnie::init() {
 	hotspotWest  = Common::Rect(20, 0, 30, IDI_WTP_PIC_HEIGHT);
 }
 
-void Winnie::run() {
+Common::Error WinnieEngine::go() {
+	init();
 	randomize();
-	if (_vm->getPlatform() != Common::kPlatformC64 && _vm->getPlatform() != Common::kPlatformApple2GS)
+
+	// The intro is not supported on these platforms yet
+	if (getPlatform() != Common::kPlatformC64 && getPlatform() != Common::kPlatformApple2GS)
 		intro();
+
 	gameLoop();
-}
 
+	return Common::kNoError;
 }
+
+} // End of namespace AGI
diff --git a/engines/agi/preagi_winnie.h b/engines/agi/preagi_winnie.h
index 07a1a13..34efcfa 100644
--- a/engines/agi/preagi_winnie.h
+++ b/engines/agi/preagi_winnie.h
@@ -281,19 +281,18 @@ struct WTP_SAVE_GAME {
 
 class PreAgiEngine;
 
-class Winnie {
+class WinnieEngine : public PreAgiEngine {
 public:
-	Winnie(PreAgiEngine *vm);
+	WinnieEngine(OSystem *syst, const AGIGameDescription *gameDesc);
+	~WinnieEngine();
 
 	void init();
-	void run();
+	Common::Error go();
 
 	void debugCurRoom();
 
 private:
-	PreAgiEngine *_vm;
-
-	WTP_SAVE_GAME _game;
+	WTP_SAVE_GAME _gameStateWinnie;
 	int _room;
 	int	_mist;
 	bool _doWind;


Commit: cb43e9694bc2ed8ea19f3d91dd1324670e49314c
    https://github.com/scummvm/scummvm/commit/cb43e9694bc2ed8ea19f3d91dd1324670e49314c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2011-08-15T08:55:03-07:00

Commit Message:
AGI: Make Mickey inherit from PreAgiEngine

Changed paths:
    engines/agi/console.cpp
    engines/agi/console.h
    engines/agi/detection.cpp
    engines/agi/preagi.cpp
    engines/agi/preagi_mickey.cpp
    engines/agi/preagi_mickey.h



diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp
index 52d7a0b..a2daf14 100644
--- a/engines/agi/console.cpp
+++ b/engines/agi/console.cpp
@@ -279,7 +279,7 @@ PreAGI_Console::PreAGI_Console(PreAgiEngine *vm) {
 	_vm = vm;
 }
 
-Mickey_Console::Mickey_Console(PreAgiEngine *vm, Mickey *mickey) : PreAGI_Console(vm) {
+Mickey_Console::Mickey_Console(MickeyEngine *mickey) : PreAGI_Console(mickey) {
 	_mickey = mickey;
 
 	DCmd_Register("curRoom",     WRAP_METHOD(Mickey_Console, Cmd_CurRoom));
diff --git a/engines/agi/console.h b/engines/agi/console.h
index fc3a507..78f0e79 100644
--- a/engines/agi/console.h
+++ b/engines/agi/console.h
@@ -27,8 +27,8 @@ namespace Agi {
 
 class AgiEngine;
 class PreAgiEngine;
+class MickeyEngine;
 class WinnieEngine;
-class Mickey;
 
 struct AgiDebug {
 	int enabled;
@@ -79,11 +79,11 @@ private:
 
 class Mickey_Console : public PreAGI_Console {
 public:
-	Mickey_Console(PreAgiEngine *vm, Mickey *mickey);
+	Mickey_Console(MickeyEngine *mickey);
 	virtual ~Mickey_Console() {}
 
 private:
-	Mickey *_mickey;
+	MickeyEngine *_mickey;
 
 	bool Cmd_CurRoom(int argc, const char **argv);
 	bool Cmd_GotoRoom(int argc, const char **argv);
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 0968e6e..72fd1bc 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -36,6 +36,7 @@
 
 #include "agi/agi.h"
 #include "agi/preagi.h"
+#include "agi/preagi_mickey.h"
 #include "agi/preagi_winnie.h"
 #include "agi/wagparser.h"
 
@@ -192,10 +193,17 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
 
 	switch (gd->gameType) {
 	case Agi::GType_PreAGI:
-		if (gd->gameID == GID_WINNIE)
+		switch (gd->gameID) {
+		case GID_MICKEY:
+			*engine = new Agi::MickeyEngine(syst, gd);
+			break;
+		case GID_WINNIE:
 			*engine = new Agi::WinnieEngine(syst, gd);
-		else
+			break;
+		default:
 			*engine = new Agi::PreAgiEngine(syst, gd);
+			break;
+		}
 		break;
 	case Agi::GType_V1:
 	case Agi::GType_V2:
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index da163cb..b1c9b53 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -148,14 +148,6 @@ Common::Error PreAgiEngine::go() {
 
 	// run preagi engine main loop
 	switch (getGameID()) {
-	case GID_MICKEY:
-		{
-			Mickey *mickey = new Mickey(this);
-			mickey->init();
-			mickey->run();
-			delete mickey;
-		}
-		break;
 	case GID_TROLL:
 		{
 			Troll *troll = new Troll(this);
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index 21eb780..3164011 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -32,7 +32,7 @@
 
 namespace Agi {
 
-int Mickey::getDat(int iRoom) {
+int MickeyEngine::getDat(int iRoom) {
 	if (((iRoom > 0) && (iRoom < 24)) || iRoom == 154 || iRoom == 155) return IDI_MSA_PLANET_EARTH;
 	if ((iRoom >= 30) && (iRoom <= 39)) return IDI_MSA_PLANET_VENUS;
 	if ((iRoom >= 40) && (iRoom <= 69)) return IDI_MSA_PLANET_NEPTUNE;
@@ -45,7 +45,7 @@ int Mickey::getDat(int iRoom) {
 	return IDI_MSA_PLANET_SPACESHIP;
 }
 
-void Mickey::readExe(int ofs, uint8 *buffer, long buflen) {
+void MickeyEngine::readExe(int ofs, uint8 *buffer, long buflen) {
 	Common::File infile;
 	if (!infile.open("mickey.exe"))
 		return;
@@ -54,11 +54,11 @@ void Mickey::readExe(int ofs, uint8 *buffer, long buflen) {
 	infile.close();
 }
 
-void Mickey::getDatFileName(int iRoom, char *szFile) {
+void MickeyEngine::getDatFileName(int iRoom, char *szFile) {
 	sprintf(szFile, IDS_MSA_PATH_DAT, IDS_MSA_NAME_DAT[getDat(iRoom)]);
 }
 
-void Mickey::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
+void MickeyEngine::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
 	Common::File infile;
 
 	if (!infile.open(szFile))
@@ -83,7 +83,7 @@ void Mickey::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
 	infile.close();
 }
 
-void Mickey::readOfsData(int offset, int iItem, uint8 *buffer, long buflen) {
+void MickeyEngine::readOfsData(int offset, int iItem, uint8 *buffer, long buflen) {
 	uint16 ofs[256];
 
 	readExe(offset, buffer, buflen);
@@ -97,11 +97,11 @@ void Mickey::readOfsData(int offset, int iItem, uint8 *buffer, long buflen) {
 
 // User Interface
 
-bool Mickey::chooseY_N(int ofsPrompt, bool fErrorMsg) {
+bool MickeyEngine::chooseY_N(int ofsPrompt, bool fErrorMsg) {
 	printExeStr(ofsPrompt);
 
-	while (!_vm->shouldQuit()) {
-		switch (_vm->getSelection(kSelYesNo)) {
+	while (!shouldQuit()) {
+		switch (getSelection(kSelYesNo)) {
 		case 0: return false;
 		case 1: return true;
 		default:
@@ -117,15 +117,15 @@ bool Mickey::chooseY_N(int ofsPrompt, bool fErrorMsg) {
 	return false;
 }
 
-int Mickey::choose1to9(int ofsPrompt) {
+int MickeyEngine::choose1to9(int ofsPrompt) {
 	int answer = 0;
 	printExeStr(ofsPrompt);
 
-	while (!_vm->shouldQuit()) {
-		answer = _vm->getSelection(kSelNumber);
+	while (!shouldQuit()) {
+		answer = getSelection(kSelNumber);
 		if (answer == 10) {
 			printExeStr(IDO_MSA_PRESS_1_TO_9);
-			if (_vm->getSelection(kSelAnyKey) == 0)
+			if (getSelection(kSelAnyKey) == 0)
 				return 0;
 			printExeStr(ofsPrompt);
 		} else return answer;
@@ -134,38 +134,38 @@ int Mickey::choose1to9(int ofsPrompt) {
 	return 0;
 }
 
-void Mickey::printStr(char *buffer) {
+void MickeyEngine::printStr(char *buffer) {
 	int pc = 1;
 	int nRows, iCol, iRow;
 
 	nRows = *buffer + IDI_MSA_ROW_MENU_0;
 
-	_vm->clearTextArea();
+	clearTextArea();
 
 	for (iRow = IDI_MSA_ROW_MENU_0; iRow < nRows; iRow++) {
 		iCol = *(buffer + pc++);
-		_vm->drawStr(iRow, iCol, IDA_DEFAULT, buffer + pc);
+		drawStr(iRow, iCol, IDA_DEFAULT, buffer + pc);
 		pc += strlen(buffer + pc) + 1;
 	}
 
 	// Show the string on screen
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
+	_gfx->doUpdate();
+	_system->updateScreen();
 }
 
-void Mickey::printLine(const char *buffer) {
-	_vm->clearTextArea();
+void MickeyEngine::printLine(const char *buffer) {
+	clearTextArea();
 
-	_vm->drawStr(22, 18 - strlen(buffer) / 2, IDA_DEFAULT, buffer);
+	drawStr(22, 18 - strlen(buffer) / 2, IDA_DEFAULT, buffer);
 
 	// Show the string on screen
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
+	_gfx->doUpdate();
+	_system->updateScreen();
 
 	waitAnyKey(true);
 }
 
-void Mickey::printExeStr(int ofs) {
+void MickeyEngine::printExeStr(int ofs) {
 	uint8 buffer[256] = {0};
 
 	if (!ofs)
@@ -175,7 +175,7 @@ void Mickey::printExeStr(int ofs) {
 	printStr((char *)buffer);
 }
 
-void Mickey::printExeMsg(int ofs) {
+void MickeyEngine::printExeMsg(int ofs) {
 	if (!ofs)
 		return;
 
@@ -183,9 +183,9 @@ void Mickey::printExeMsg(int ofs) {
 	waitAnyKey(true);
 }
 
-void Mickey::printDatString(int iStr) {
+void MickeyEngine::printDatString(int iStr) {
 	char buffer[256];
-	int iDat = getDat(_game.iRoom);
+	int iDat = getDat(_gameStateMickey.iRoom);
 
 	MSA_DAT_HEADER hdr;
 	char szFile[256] = {0};
@@ -205,7 +205,7 @@ void Mickey::printDatString(int iStr) {
 	printStr(buffer);
 }
 
-void Mickey::printDesc(int iRoom) {
+void MickeyEngine::printDesc(int iRoom) {
 	MSA_DAT_HEADER hdr;
 	char szFile[256] = {0};
 
@@ -228,20 +228,20 @@ void Mickey::printDesc(int iRoom) {
 	free(buffer);
 }
 
-bool Mickey::checkMenu() {
+bool MickeyEngine::checkMenu() {
 	MSA_MENU menu;
 	int iSel0, iSel1;
 	MSA_DAT_HEADER hdr;
 	char szFile[256] = {0};
 	Common::File infile;
 
-	getDatFileName(_game.iRoom, szFile);
+	getDatFileName(_gameStateMickey.iRoom, szFile);
 	readDatHdr(szFile, &hdr);
 	if (!infile.open(szFile))
 		return false;
 
 	char *buffer = new char[sizeof(MSA_MENU)];
-	infile.seek(hdr.ofsRoom[_game.iRoom - 1] + IDI_MSA_OFS_DAT, SEEK_SET);
+	infile.seek(hdr.ofsRoom[_gameStateMickey.iRoom - 1] + IDI_MSA_OFS_DAT, SEEK_SET);
 	infile.read((uint8 *)buffer, sizeof(MSA_MENU));
 	infile.close();
 
@@ -255,7 +255,7 @@ bool Mickey::checkMenu() {
 	return parse(menu.cmd[iSel0].data[iSel1], menu.arg[iSel0].data[iSel1]);
 }
 
-void Mickey::drawMenu(MSA_MENU menu, int sel0, int sel1) {
+void MickeyEngine::drawMenu(MSA_MENU menu, int sel0, int sel1) {
 	int iWord;
 	int iRow;
 	int sel;
@@ -263,7 +263,7 @@ void Mickey::drawMenu(MSA_MENU menu, int sel0, int sel1) {
 
 	// draw menu
 
-	_vm->clearTextArea();
+	clearTextArea();
 
 	for (iRow = 0; iRow < 2; iRow++) {
 		for (iWord = 0; iWord < menu.row[iRow].count; iWord++) {
@@ -277,17 +277,17 @@ void Mickey::drawMenu(MSA_MENU menu, int sel0, int sel1) {
 			else
 				attr = IDA_DEFAULT;
 
-			_vm->drawStr(IDI_MSA_ROW_MENU_0 + iRow, menu.row[iRow].entry[iWord].x0,
+			drawStr(IDI_MSA_ROW_MENU_0 + iRow, menu.row[iRow].entry[iWord].x0,
 							 attr, (char *)menu.row[iRow].entry[iWord].szText);
 		}
 	}
 
 	// Menu created, show it on screen
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
+	_gfx->doUpdate();
+	_system->updateScreen();
 }
 
-void Mickey::getMouseMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow, int x, int y) {
+void MickeyEngine::getMouseMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow, int x, int y) {
 	int iWord;
 	int *sel = 0;
 
@@ -314,7 +314,7 @@ void Mickey::getMouseMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow, i
 	}
 }
 
-bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
+bool MickeyEngine::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 	Common::Event event;
 	int *sel = 0;
 	int nWords;
@@ -357,8 +357,8 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 
 	drawMenu(menu, *sel0, *sel1);
 
-	while (!_vm->shouldQuit()) {
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
+	while (!shouldQuit()) {
+		while (_system->getEventManager()->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_RTL:
 			case Common::EVENT_QUIT:
@@ -376,18 +376,18 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 					// Change cursor
 					if (northIndex >= 0 && (event.mouse.x >= 20 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2) &&
 							(event.mouse.y >= 0 && event.mouse.y <= 10)) {
-						_vm->_gfx->setCursorPalette(true);
+						_gfx->setCursorPalette(true);
 					} else if (southIndex >= 0 && (event.mouse.x >= 20 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2) &&
 								(event.mouse.y >= IDI_MSA_PIC_HEIGHT - 10 && event.mouse.y <= IDI_MSA_PIC_HEIGHT)) {
-						_vm->_gfx->setCursorPalette(true);
+						_gfx->setCursorPalette(true);
 					} else if (westIndex >= 0 && (event.mouse.y >= 0  && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
 								(event.mouse.x >= 20 && event.mouse.x <= 30)) {
-						_vm->_gfx->setCursorPalette(true);
+						_gfx->setCursorPalette(true);
 					} else if (eastIndex >= 0 && (event.mouse.y >= 0  && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
 								(event.mouse.x >= IDI_MSA_PIC_WIDTH * 2 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2)) {
-						_vm->_gfx->setCursorPalette(true);
+						_gfx->setCursorPalette(true);
 					} else {
-						_vm->_gfx->setCursorPalette(false);
+						_gfx->setCursorPalette(false);
 					}
 				}
 				break;
@@ -400,7 +400,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 
 					drawMenu(menu, *sel0, *sel1);
 
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					_clickToMove = true;
 				} else if (southIndex >= 0 && (event.mouse.x >= 20 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2) &&
 							(event.mouse.y >= IDI_MSA_PIC_HEIGHT - 10 && event.mouse.y <= IDI_MSA_PIC_HEIGHT)) {
@@ -409,7 +409,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 
 					drawMenu(menu, *sel0, *sel1);
 
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					_clickToMove = true;
 				} else if (westIndex >= 0 && (event.mouse.y >= 0  && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
 							(event.mouse.x >= 20 && event.mouse.x <= 30)) {
@@ -418,7 +418,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 
 					drawMenu(menu, *sel0, *sel1);
 
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					_clickToMove = true;
 				} else if (eastIndex >= 0 && (event.mouse.y >= 0  && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
 							(event.mouse.x >= IDI_MSA_PIC_WIDTH * 2 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2)) {
@@ -427,10 +427,10 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 
 					drawMenu(menu, *sel0, *sel1);
 
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 					_clickToMove = true;
 				} else {
-					_vm->_gfx->setCursorPalette(false);
+					_gfx->setCursorPalette(false);
 				}
 				return true;
 			case Common::EVENT_RBUTTONUP:
@@ -458,20 +458,20 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 				}
 				break;
 			case Common::EVENT_KEYDOWN:
-				if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _vm->_console) {
-					_vm->_console->attach();
-					_vm->_console->onFrame();
+				if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
+					_console->attach();
+					_console->onFrame();
 					continue;
 				}
 
 				switch (event.kbd.keycode) {
 				case Common::KEYCODE_2:
 					// Hidden message
-					if (_game.iRoom == IDI_MSA_PIC_MERCURY_CAVE_0) {
+					if (_gameStateMickey.iRoom == IDI_MSA_PIC_MERCURY_CAVE_0) {
 						for (int i = 0; i < 5; i++) {
 							printExeMsg(IDO_MSA_HIDDEN_MSG[i]);
 						}
-						_vm->clearTextArea();
+						clearTextArea();
 						waitAnyKey();
 					}
 					break;
@@ -489,7 +489,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 
 					return false;
 				case Common::KEYCODE_s:
-					_vm->flipflag(fSoundOn);
+					flipflag(fSoundOn);
 					break;
 				case Common::KEYCODE_c:
 					inventory();
@@ -552,7 +552,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
 	return false;
 }
 
-void Mickey::getMenuSel(char *buffer, int *sel0, int *sel1) {
+void MickeyEngine::getMenuSel(char *buffer, int *sel0, int *sel1) {
 	MSA_MENU menu;
 
 	memcpy(&menu, buffer, sizeof(MSA_MENU));
@@ -563,8 +563,8 @@ void Mickey::getMenuSel(char *buffer, int *sel0, int *sel1) {
 	// Show the mouse cursor for the menu
 	CursorMan.showMouse(true);
 
-	while (!_vm->shouldQuit()) {
-		while (!_vm->shouldQuit()) {
+	while (!shouldQuit()) {
+		while (!shouldQuit()) {
 			if (getMenuSelRow(menu, sel0, sel1, 0)) {
 				if (_clickToMove)
 					break;
@@ -586,7 +586,7 @@ void Mickey::getMenuSel(char *buffer, int *sel0, int *sel1) {
 	CursorMan.showMouse(false);
 }
 
-void Mickey::centerMenu(MSA_MENU *menu) {
+void MickeyEngine::centerMenu(MSA_MENU *menu) {
 	int iWord;
 	int iRow;
 	int w, x;
@@ -606,19 +606,19 @@ void Mickey::centerMenu(MSA_MENU *menu) {
 	}
 }
 
-void Mickey::patchMenu(MSA_MENU *menu) {
+void MickeyEngine::patchMenu(MSA_MENU *menu) {
 	uint8 buffer[512];
 	uint8 menubuf[sizeof(MSA_MENU)];
 	int nPatches;
 	int pBuf = 0;
 
 	// change planet name in ship airlock menu
-	if (_game.iRoom == IDI_MSA_PIC_SHIP_AIRLOCK) {
-		strcpy((char *)menu->row[1].entry[2].szText, IDS_MSA_NAME_PLANET[_game.iPlanet]);
+	if (_gameStateMickey.iRoom == IDI_MSA_PIC_SHIP_AIRLOCK) {
+		strcpy((char *)menu->row[1].entry[2].szText, IDS_MSA_NAME_PLANET[_gameStateMickey.iPlanet]);
 	}
 
 	// exit if fix unnecessary
-	if (!_game.iRmMenu[_game.iRoom]) {
+	if (!_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
 		centerMenu(menu);
 		return;
 	}
@@ -629,7 +629,7 @@ void Mickey::patchMenu(MSA_MENU *menu) {
 	// read patches
 	readOfsData(
 		IDOFS_MSA_MENU_PATCHES,
-		_game.nRmMenu[_game.iRoom] + _game.iRmMenu[_game.iRoom] - 1,
+		_gameStateMickey.nRmMenu[_gameStateMickey.iRoom] + _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] - 1,
 		buffer, sizeof(buffer)
 	);
 
@@ -652,24 +652,24 @@ void Mickey::patchMenu(MSA_MENU *menu) {
 	centerMenu(menu);
 }
 
-void Mickey::printDatMessage(int iStr) {
+void MickeyEngine::printDatMessage(int iStr) {
 	printDatString(iStr);
 	waitAnyKey(true);
 }
 
 // Sound
 
-void Mickey::playNote(MSA_SND_NOTE note) {
+void MickeyEngine::playNote(MSA_SND_NOTE note) {
 	if (!note.counter) {
 		// Pause
-		_vm->_system->delayMillis((uint) (note.length / IDI_SND_TIMER_RESOLUTION));
+		_system->delayMillis((uint) (note.length / IDI_SND_TIMER_RESOLUTION));
 	} else {
-		_vm->playNote(IDI_SND_OSCILLATOR_FREQUENCY / note.counter, (int32) (note.length / IDI_SND_TIMER_RESOLUTION));
+		PreAgiEngine::playNote(IDI_SND_OSCILLATOR_FREQUENCY / note.counter, (int32) (note.length / IDI_SND_TIMER_RESOLUTION));
 	}
 }
 
-void Mickey::playSound(ENUM_MSA_SOUND iSound) {
-	if (!_vm->getflag(fSoundOn))
+void MickeyEngine::playSound(ENUM_MSA_SOUND iSound) {
+	if (!getflag(fSoundOn))
 		return;
 
 	Common::Event event;
@@ -680,7 +680,7 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
 	switch (iSound) {
 	case IDI_MSA_SND_XL30:
 		for (int iNote = 0; iNote < 6; iNote++) {
-			note.counter = _vm->rnd(59600) + 59;
+			note.counter = rnd(59600) + 59;
 			note.length = 4;
 			playNote(note);
 		}
@@ -698,7 +698,7 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
 			pBuf += 3;
 
 			if (iSound == IDI_MSA_SND_THEME) {
-				while (_vm->_system->getEventManager()->pollEvent(event)) {
+				while (_system->getEventManager()->pollEvent(event)) {
 					switch (event.type) {
 					case Common::EVENT_RTL:
 					case Common::EVENT_QUIT:
@@ -722,7 +722,7 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
 
 // Graphics
 
-void Mickey::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
+void MickeyEngine::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
 	char szFile[255] = {0};
 	sprintf(szFile, IDS_MSA_PATH_OBJ, IDS_MSA_NAME_OBJ[iObj]);
 
@@ -736,15 +736,15 @@ void Mickey::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
 	file.close();
 
 	if (iObj == IDI_MSA_OBJECT_CRYSTAL)
-		_vm->_picture->setPictureFlags(kPicFStep);
+		_picture->setPictureFlags(kPicFStep);
 
-	_vm->_picture->setOffset(x0, y0);
-	_vm->_picture->decodePicture(buffer, size, false, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
-	_vm->_picture->setOffset(0, 0);
-	_vm->_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+	_picture->setOffset(x0, y0);
+	_picture->decodePicture(buffer, size, false, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+	_picture->setOffset(0, 0);
+	_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
 }
 
-void Mickey::drawPic(int iPic) {
+void MickeyEngine::drawPic(int iPic) {
 	char szFile[255] = {0};
 	sprintf(szFile, IDS_MSA_PATH_PIC, iPic);
 
@@ -758,16 +758,16 @@ void Mickey::drawPic(int iPic) {
 	file.close();
 
 	// Note that decodePicture clears the screen
-	_vm->_picture->decodePicture(buffer, size, true, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
-	_vm->_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+	_picture->decodePicture(buffer, size, true, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+	_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
 }
 
-void Mickey::drawRoomAnimation() {
+void MickeyEngine::drawRoomAnimation() {
 	uint8 objLight[] = {
 		0xF0, 1, 0xF9, 2, 43, 45, 0xFF
 	};
 
-	switch (_game.iRoom) {
+	switch (_gameStateMickey.iRoom) {
 	case IDI_MSA_PIC_EARTH_SHIP:
 	case IDI_MSA_PIC_VENUS_SHIP:
 	case IDI_MSA_PIC_NEPTUNE_SHIP:
@@ -790,26 +790,26 @@ void Mickey::drawRoomAnimation() {
 
 			uint8 iColor = 0;
 
-			_vm->_picture->setPattern(2, 0);
+			_picture->setPattern(2, 0);
 
 			for (int i = 0; i < 12; i++) {
-				iColor = _game.nFrame + i;
+				iColor = _gameStateMickey.nFrame + i;
 				if (iColor > 15)
 					iColor -= 15;
 
 				objLight[1] = iColor;
 				objLight[4] += 7;
 
-				_vm->_picture->setPictureData(objLight);
-				_vm->_picture->setPictureFlags(kPicFCircle);
-				_vm->_picture->drawPicture();
+				_picture->setPictureData(objLight);
+				_picture->setPictureFlags(kPicFCircle);
+				_picture->drawPicture();
 			}
-			_vm->_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+			_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
 
 
-			_game.nFrame--;
-			if (_game.nFrame < 0)
-				_game.nFrame = 15;
+			_gameStateMickey.nFrame--;
+			if (_gameStateMickey.nFrame < 0)
+				_gameStateMickey.nFrame = 15;
 
 			playSound(IDI_MSA_SND_PRESS_BLUE);
 		}
@@ -818,12 +818,12 @@ void Mickey::drawRoomAnimation() {
 	case IDI_MSA_PIC_SHIP_CONTROLS:
 
 		// draw XL30 screen
-		if (_game.fAnimXL30) {
-			if (_game.nFrame > 5)
-				_game.nFrame = 0;
+		if (_gameStateMickey.fAnimXL30) {
+			if (_gameStateMickey.nFrame > 5)
+				_gameStateMickey.nFrame = 0;
 
-			drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_XL31 + _game.nFrame), 0, 4);
-			_game.nFrame++;
+			drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_XL31 + _gameStateMickey.nFrame), 0, 4);
+			_gameStateMickey.nFrame++;
 		};
 
 		break;
@@ -831,17 +831,17 @@ void Mickey::drawRoomAnimation() {
 	default:
 
 		// draw crystal
-		if (_game.iRoom == IDI_MSA_XTAL_ROOM_XY[_game.iPlanet][0]) {
-			if (!_game.fHasXtal) {
-				switch (_game.iPlanet) {
+		if (_gameStateMickey.iRoom == IDI_MSA_XTAL_ROOM_XY[_gameStateMickey.iPlanet][0]) {
+			if (!_gameStateMickey.fHasXtal) {
+				switch (_gameStateMickey.iPlanet) {
 				case IDI_MSA_PLANET_VENUS:
-					if (_game.iRmMenu[_game.iRoom] != 2)
+					if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] != 2)
 						break;
 				default:
 					drawObj(
 						IDI_MSA_OBJECT_CRYSTAL,
-						IDI_MSA_XTAL_ROOM_XY[_game.iPlanet][1],
-						IDI_MSA_XTAL_ROOM_XY[_game.iPlanet][2]
+						IDI_MSA_XTAL_ROOM_XY[_gameStateMickey.iPlanet][1],
+						IDI_MSA_XTAL_ROOM_XY[_gameStateMickey.iPlanet][2]
 					);
 					break;
 				}
@@ -852,36 +852,36 @@ void Mickey::drawRoomAnimation() {
 	}
 }
 
-void Mickey::drawRoom() {
+void MickeyEngine::drawRoom() {
 	uint8 buffer[256];
 	int pBuf = 0;
 	int nObjs;
 
 	// Draw room picture
-	if (_game.iRoom == IDI_MSA_PIC_TITLE) {
+	if (_gameStateMickey.iRoom == IDI_MSA_PIC_TITLE) {
 		drawPic(IDI_MSA_PIC_TITLE);
 	} else {
-		drawPic(_game.iRmPic[_game.iRoom]);
+		drawPic(_gameStateMickey.iRmPic[_gameStateMickey.iRoom]);
 
-		if (_game.iRoom == IDI_MSA_PIC_SHIP_CONTROLS) {
+		if (_gameStateMickey.iRoom == IDI_MSA_PIC_SHIP_CONTROLS) {
 			// Draw ship control room window
-			if (_game.fFlying) {
+			if (_gameStateMickey.fFlying) {
 				drawObj(IDI_MSA_OBJECT_W_SPACE, 0, 0);
 			} else {
-				drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_W_EARTH + _game.iPlanet), 0, 1);
+				drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_W_EARTH + _gameStateMickey.iPlanet), 0, 1);
 			}
 		}
 	}
 
 	// Draw room objects
-	if (_game.iRoom >= IDI_MSA_MAX_PIC_ROOM) {
+	if (_gameStateMickey.iRoom >= IDI_MSA_MAX_PIC_ROOM) {
 		drawRoomAnimation();
 		return;
 	}
 
-	if (_game.iRmObj[_game.iRoom] != IDI_MSA_OBJECT_NONE) {
+	if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] != IDI_MSA_OBJECT_NONE) {
 		readOfsData(IDO_MSA_ROOM_OBJECT_XY_OFFSETS,
-			_game.iRmObj[_game.iRoom], buffer, sizeof(buffer));
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom], buffer, sizeof(buffer));
 
 		nObjs = buffer[pBuf++];
 
@@ -914,7 +914,7 @@ const uint8 colorBCG[16][2] = {
 	{ 0xFF,	0xFF }	// F (white, white)
 };
 
-void Mickey::drawLogo() {
+void MickeyEngine::drawLogo() {
 	// TODO: clean this up and make it work properly, the logo is drawn way off to the right
 #if 0
 	char szFile[256] = {0};
@@ -937,7 +937,7 @@ void Mickey::drawLogo() {
 	// draw logo bitmap
 	memcpy(bitmap, buffer, sizeof(bitmap));
 
-	_vm->_picture->setDimensions(w, h);
+	_picture->setDimensions(w, h);
 
 	// Show BCG picture
 	for (int y = 0; y < h; y++) {
@@ -947,40 +947,40 @@ void Mickey::drawLogo() {
 			color3 = colorBCG[ bitmap[y][x] & 0x0f][0];			// foreground
 			color4 = colorBCG[ bitmap[y][x] & 0x0f][1];			// foreground
 
-			_vm->_picture->putPixel(x * 4 - xoffset,			y,		color);
-			_vm->_picture->putPixel(x * 4 + 1 - xoffset,		y,		color2);
-			_vm->_picture->putPixel(x * 4 + 2 - xoffset,		y,		color3);
-			_vm->_picture->putPixel(x * 4 + 3 - xoffset,		y,		color4);
-			_vm->_picture->putPixel(x * 4 - xoffset,			y + 1,	color);
-			_vm->_picture->putPixel(x * 4 + 1 - xoffset,		y + 1,	color2);
-			_vm->_picture->putPixel(x * 4 + 2 - xoffset,		y + 1,	color3);
-			_vm->_picture->putPixel(x * 4 + 3 - xoffset,		y + 1,	color4);
+			_picture->putPixel(x * 4 - xoffset,			y,		color);
+			_picture->putPixel(x * 4 + 1 - xoffset,		y,		color2);
+			_picture->putPixel(x * 4 + 2 - xoffset,		y,		color3);
+			_picture->putPixel(x * 4 + 3 - xoffset,		y,		color4);
+			_picture->putPixel(x * 4 - xoffset,			y + 1,	color);
+			_picture->putPixel(x * 4 + 1 - xoffset,		y + 1,	color2);
+			_picture->putPixel(x * 4 + 2 - xoffset,		y + 1,	color3);
+			_picture->putPixel(x * 4 + 3 - xoffset,		y + 1,	color4);
 		}
 	}
 
-	_vm->_picture->showPic(10, 10, w, h);
+	_picture->showPic(10, 10, w, h);
 
 	delete[] buffer;
 #endif
 }
 
-void Mickey::animate() {
-	_vm->_system->delayMillis(IDI_MSA_ANIM_DELAY);
+void MickeyEngine::animate() {
+	_system->delayMillis(IDI_MSA_ANIM_DELAY);
 	drawRoomAnimation();
 }
 
-void Mickey::printRoomDesc() {
+void MickeyEngine::printRoomDesc() {
 	// print room description
-	printDesc(_game.iRoom);
+	printDesc(_gameStateMickey.iRoom);
 	waitAnyKey(true);
 
 	// print extended room description
-	if (_game.oRmTxt[_game.iRoom]) {
-		printExeMsg(_game.oRmTxt[_game.iRoom] + IDI_MSA_OFS_EXE);
+	if (_gameStateMickey.oRmTxt[_gameStateMickey.iRoom]) {
+		printExeMsg(_gameStateMickey.oRmTxt[_gameStateMickey.iRoom] + IDI_MSA_OFS_EXE);
 	}
 }
 
-bool Mickey::loadGame() {
+bool MickeyEngine::loadGame() {
 	Common::InSaveFile *infile;
 	char szFile[256] = {0};
 	bool diskerror = true;
@@ -994,15 +994,15 @@ bool Mickey::loadGame() {
 			return false;
 
 		// load game
-		sprintf(szFile, "%s.s%02d", _vm->getTargetName().c_str(), sel);
-		if (!(infile = _vm->getSaveFileMan()->openForLoading(szFile))) {
+		sprintf(szFile, "%s.s%02d", getTargetName().c_str(), sel);
+		if (!(infile = getSaveFileMan()->openForLoading(szFile))) {
 			printLine("PLEASE CHECK THE DISK DRIVE");
 
-			if (_vm->getSelection(kSelAnyKey) == 0)
+			if (getSelection(kSelAnyKey) == 0)
 				return false;
 		} else {
 			if (infile->readUint32BE() != MKTAG('M','I','C','K')) {
-				warning("Mickey::loadGame wrong save game format");
+				warning("MickeyEngine::loadGame wrong save game format");
 				return false;
 			}
 
@@ -1015,61 +1015,61 @@ bool Mickey::loadGame() {
 			if (saveVersion != MSA_SAVEGAME_VERSION)
 				warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, MSA_SAVEGAME_VERSION);
 
-			_game.iRoom = infile->readByte();
-			_game.iPlanet = infile->readByte();
-			_game.iDisk = infile->readByte();
+			_gameStateMickey.iRoom = infile->readByte();
+			_gameStateMickey.iPlanet = infile->readByte();
+			_gameStateMickey.iDisk = infile->readByte();
 
-			_game.nAir = infile->readByte();
-			_game.nButtons = infile->readByte();
-			_game.nRocks = infile->readByte();
+			_gameStateMickey.nAir = infile->readByte();
+			_gameStateMickey.nButtons = infile->readByte();
+			_gameStateMickey.nRocks = infile->readByte();
 
-			_game.nXtals = infile->readByte();
+			_gameStateMickey.nXtals = infile->readByte();
 
 			for (i = 0; i < IDI_MSA_MAX_DAT; i++)
-				_game.iPlanetXtal[i] = infile->readByte();
+				_gameStateMickey.iPlanetXtal[i] = infile->readByte();
 
 			for (i = 0; i < IDI_MSA_MAX_PLANET; i++)
-				_game.iClue[i] = infile->readUint16LE();
+				_gameStateMickey.iClue[i] = infile->readUint16LE();
 
-			infile->read(_game.szAddr, IDI_MSA_MAX_BUTTON + 1);
+			infile->read(_gameStateMickey.szAddr, IDI_MSA_MAX_BUTTON + 1);
 
-			_game.fHasXtal = infile->readByte() == 1;
-			_game.fIntro = infile->readByte() == 1;
-			_game.fSuit = infile->readByte() == 1;
-			_game.fShipDoorOpen = infile->readByte() == 1;
-			_game.fFlying = infile->readByte() == 1;
-			_game.fStoryShown = infile->readByte() == 1;
-			_game.fPlanetsInitialized = infile->readByte() == 1;
-			_game.fTempleDoorOpen = infile->readByte() == 1;
-			_game.fAnimXL30 = infile->readByte() == 1;
+			_gameStateMickey.fHasXtal = infile->readByte() == 1;
+			_gameStateMickey.fIntro = infile->readByte() == 1;
+			_gameStateMickey.fSuit = infile->readByte() == 1;
+			_gameStateMickey.fShipDoorOpen = infile->readByte() == 1;
+			_gameStateMickey.fFlying = infile->readByte() == 1;
+			_gameStateMickey.fStoryShown = infile->readByte() == 1;
+			_gameStateMickey.fPlanetsInitialized = infile->readByte() == 1;
+			_gameStateMickey.fTempleDoorOpen = infile->readByte() == 1;
+			_gameStateMickey.fAnimXL30 = infile->readByte() == 1;
 
 			for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
-				_game.fItem[i] = infile->readByte() == 1;
+				_gameStateMickey.fItem[i] = infile->readByte() == 1;
 
 			for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
-				_game.fItemUsed[i] = infile->readByte() == 1;
+				_gameStateMickey.fItemUsed[i] = infile->readByte() == 1;
 
 			for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
-				_game.iItem[i] = infile->readSByte();
+				_gameStateMickey.iItem[i] = infile->readSByte();
 
-			_game.nItems = infile->readByte();
+			_gameStateMickey.nItems = infile->readByte();
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				_game.iRmObj[i] = infile->readSByte();
+				_gameStateMickey.iRmObj[i] = infile->readSByte();
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				_game.iRmPic[i] = infile->readByte();
+				_gameStateMickey.iRmPic[i] = infile->readByte();
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				_game.oRmTxt[i] = infile->readUint16LE();
+				_gameStateMickey.oRmTxt[i] = infile->readUint16LE();
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				_game.iRmMenu[i] = infile->readByte();
+				_gameStateMickey.iRmMenu[i] = infile->readByte();
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				_game.nRmMenu[i] = infile->readByte();
+				_gameStateMickey.nRmMenu[i] = infile->readByte();
 
-			_game.nFrame = infile->readSByte();
+			_gameStateMickey.nFrame = infile->readSByte();
 
 			diskerror = false;
 			delete infile;
@@ -1080,7 +1080,7 @@ bool Mickey::loadGame() {
 	return true;
 }
 
-void Mickey::saveGame() {
+void MickeyEngine::saveGame() {
 	Common::OutSaveFile* outfile;
 	char szFile[256] = {0};
 	bool diskerror = true;
@@ -1094,7 +1094,7 @@ void Mickey::saveGame() {
 	else
 		printExeStr(IDO_MSA_SAVE_GAME[2]);
 
-	if (_vm->getSelection(kSelAnyKey) == 0)
+	if (getSelection(kSelAnyKey) == 0)
 		return;
 
 	while (diskerror) {
@@ -1107,75 +1107,75 @@ void Mickey::saveGame() {
 		else
 			printExeStr(IDO_MSA_SAVE_GAME[4]);
 
-		if (_vm->getSelection(kSelAnyKey) == 0)
+		if (getSelection(kSelAnyKey) == 0)
 			return;
 
 		// save game
-		sprintf(szFile, "%s.s%02d", _vm->getTargetName().c_str(), sel);
-		if (!(outfile = _vm->getSaveFileMan()->openForSaving(szFile))) {
+		sprintf(szFile, "%s.s%02d", getTargetName().c_str(), sel);
+		if (!(outfile = getSaveFileMan()->openForSaving(szFile))) {
 			printLine("PLEASE CHECK THE DISK DRIVE");
 
-			if (_vm->getSelection(kSelAnyKey) == 0)
+			if (getSelection(kSelAnyKey) == 0)
 				return;
 		} else {
 			outfile->writeUint32BE(MKTAG('M','I','C','K'));	// header
 			outfile->writeByte(MSA_SAVEGAME_VERSION);
 
-			outfile->writeByte(_game.iRoom);
-			outfile->writeByte(_game.iPlanet);
-			outfile->writeByte(_game.iDisk);
+			outfile->writeByte(_gameStateMickey.iRoom);
+			outfile->writeByte(_gameStateMickey.iPlanet);
+			outfile->writeByte(_gameStateMickey.iDisk);
 
-			outfile->writeByte(_game.nAir);
-			outfile->writeByte(_game.nButtons);
-			outfile->writeByte(_game.nRocks);
+			outfile->writeByte(_gameStateMickey.nAir);
+			outfile->writeByte(_gameStateMickey.nButtons);
+			outfile->writeByte(_gameStateMickey.nRocks);
 
-			outfile->writeByte(_game.nXtals);
+			outfile->writeByte(_gameStateMickey.nXtals);
 
 			for (i = 0; i < IDI_MSA_MAX_DAT; i++)
-				outfile->writeByte(_game.iPlanetXtal[i]);
+				outfile->writeByte(_gameStateMickey.iPlanetXtal[i]);
 
 			for (i = 0; i < IDI_MSA_MAX_PLANET; i++)
-				outfile->writeUint16LE(_game.iClue[i]);
+				outfile->writeUint16LE(_gameStateMickey.iClue[i]);
 
-			outfile->write(_game.szAddr, IDI_MSA_MAX_BUTTON + 1);
+			outfile->write(_gameStateMickey.szAddr, IDI_MSA_MAX_BUTTON + 1);
 
-			outfile->writeByte(_game.fHasXtal ? 1 : 0);
-			outfile->writeByte(_game.fIntro ? 1 : 0);
-			outfile->writeByte(_game.fSuit ? 1 : 0);
-			outfile->writeByte(_game.fShipDoorOpen ? 1 : 0);
-			outfile->writeByte(_game.fFlying ? 1 : 0);
-			outfile->writeByte(_game.fStoryShown ? 1 : 0);
-			outfile->writeByte(_game.fPlanetsInitialized ? 1 : 0);
-			outfile->writeByte(_game.fTempleDoorOpen ? 1 : 0);
-			outfile->writeByte(_game.fAnimXL30 ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fHasXtal ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fIntro ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fSuit ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fShipDoorOpen ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fFlying ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fStoryShown ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fPlanetsInitialized ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fTempleDoorOpen ? 1 : 0);
+			outfile->writeByte(_gameStateMickey.fAnimXL30 ? 1 : 0);
 
 			for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
-				outfile->writeByte(_game.fItem[i] ? 1 : 0);
+				outfile->writeByte(_gameStateMickey.fItem[i] ? 1 : 0);
 
 			for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
-				outfile->writeByte(_game.fItemUsed[i] ? 1 : 0);
+				outfile->writeByte(_gameStateMickey.fItemUsed[i] ? 1 : 0);
 
 			for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
-				outfile->writeSByte(_game.iItem[i]);
+				outfile->writeSByte(_gameStateMickey.iItem[i]);
 
-			outfile->writeByte(_game.nItems);
+			outfile->writeByte(_gameStateMickey.nItems);
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				outfile->writeSByte(_game.iRmObj[i]);
+				outfile->writeSByte(_gameStateMickey.iRmObj[i]);
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				outfile->writeByte(_game.iRmPic[i]);
+				outfile->writeByte(_gameStateMickey.iRmPic[i]);
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				outfile->writeUint16LE(_game.oRmTxt[i]);
+				outfile->writeUint16LE(_gameStateMickey.oRmTxt[i]);
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				outfile->writeByte(_game.iRmMenu[i]);
+				outfile->writeByte(_gameStateMickey.iRmMenu[i]);
 
 			for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
-				outfile->writeByte(_game.nRmMenu[i]);
+				outfile->writeByte(_gameStateMickey.nRmMenu[i]);
 
-			outfile->writeSByte(_game.nFrame);
+			outfile->writeSByte(_gameStateMickey.nFrame);
 
 			outfile->finalize();
 
@@ -1190,14 +1190,14 @@ void Mickey::saveGame() {
 	printExeMsg(IDO_MSA_SAVE_GAME[6]);
 }
 
-void Mickey::showPlanetInfo() {
+void MickeyEngine::showPlanetInfo() {
 	for (int i = 0; i < 4; i++) {
-		printExeStr(IDO_MSA_PLANET_INFO[_game.iPlanet][i]);
+		printExeStr(IDO_MSA_PLANET_INFO[_gameStateMickey.iPlanet][i]);
 		waitAnyKey();
 	}
 }
 
-void Mickey::printStory() {
+void MickeyEngine::printStory() {
 	char buffer[IDI_MSA_LEN_STORY] = {0};
 	char szLine[41] = {0};
 	int iRow;
@@ -1205,37 +1205,37 @@ void Mickey::printStory() {
 
 	readExe(IDO_MSA_GAME_STORY, (uint8 *)buffer, sizeof(buffer));
 
-	_vm->clearScreen(IDA_DEFAULT);
+	clearScreen(IDA_DEFAULT);
 	for (iRow = 0; iRow < 25; iRow++) {
 		strcpy(szLine, buffer + pBuf);
-		_vm->drawStr(iRow, 0, IDA_DEFAULT, szLine);
+		drawStr(iRow, 0, IDA_DEFAULT, szLine);
 		pBuf += strlen(szLine) + 1;
 	}
 	waitAnyKey();
 
-	_vm->clearScreen(IDA_DEFAULT);
+	clearScreen(IDA_DEFAULT);
 	for (iRow = 0; iRow < 21; iRow++) {
 		strcpy(szLine, buffer + pBuf);
-		_vm->drawStr(iRow, 0, IDA_DEFAULT, szLine);
+		drawStr(iRow, 0, IDA_DEFAULT, szLine);
 		pBuf += strlen(szLine) + 1;
 	}
 	waitAnyKey();
 
 	//Set back to black
-	_vm->_gfx->clearScreen(0);
-	_vm->_gfx->doUpdate();
+	_gfx->clearScreen(0);
+	_gfx->doUpdate();
 
 	drawRoom();
 
-	_game.fStoryShown = true;
+	_gameStateMickey.fStoryShown = true;
 }
 
-int Mickey::getPlanet() {
-	if (!_game.nButtons)
+int MickeyEngine::getPlanet() {
+	if (!_gameStateMickey.nButtons)
 		return -1;
 
 	for (int iPlanet = 0; iPlanet < IDI_MSA_MAX_DAT - 1; iPlanet++) {
-		if (!strcmp(IDS_MSA_ADDR_PLANET[iPlanet], _game.szAddr)) {
+		if (!strcmp(IDS_MSA_ADDR_PLANET[iPlanet], _gameStateMickey.szAddr)) {
 			return iPlanet;
 		}
 	}
@@ -1243,49 +1243,49 @@ int Mickey::getPlanet() {
 	return -1;
 }
 
-void Mickey::pressOB(int iButton) {
+void MickeyEngine::pressOB(int iButton) {
 	char szButtons[12] = {0};
 
 	// check if too many buttons pressed
-	if (_game.nButtons == IDI_MSA_MAX_BUTTON) {
-		_game.nButtons = 0;
-		memset(_game.szAddr, 0, sizeof(_game.szAddr));
+	if (_gameStateMickey.nButtons == IDI_MSA_MAX_BUTTON) {
+		_gameStateMickey.nButtons = 0;
+		memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
 		printExeMsg(IDO_MSA_TOO_MANY_BUTTONS_PRESSED);
 		return;
 	}
 
 	// add button press to address
-	_game.nButtons++;
-	_game.szAddr[_game.nButtons - 1] = (char)iButton;
+	_gameStateMickey.nButtons++;
+	_gameStateMickey.szAddr[_gameStateMickey.nButtons - 1] = (char)iButton;
 
 	// format buttons string
 	for (int i = 0; i < IDI_MSA_MAX_BUTTON; i++) {
-		szButtons[i * 2] = _game.szAddr[i];
-		if (_game.szAddr[i + 1]) szButtons[(i * 2) + 1] = ',';
+		szButtons[i * 2] = _gameStateMickey.szAddr[i];
+		if (_gameStateMickey.szAddr[i + 1]) szButtons[(i * 2) + 1] = ',';
 	}
 
 	// print pressed buttons
 	printLine("MICKEY HAS PRESSED:                  ");
-	_vm->drawStr(20, 22, IDA_DEFAULT, szButtons);
+	drawStr(20, 22, IDA_DEFAULT, szButtons);
 	waitAnyKey();
 }
 
-void Mickey::insertDisk(int iDisk) {
-	_vm->clearTextArea();
-	_vm->drawStr(IDI_MSA_ROW_INSERT_DISK, IDI_MSA_COL_INSERT_DISK, IDA_DEFAULT, (const char *)IDS_MSA_INSERT_DISK[iDisk]);
+void MickeyEngine::insertDisk(int iDisk) {
+	clearTextArea();
+	drawStr(IDI_MSA_ROW_INSERT_DISK, IDI_MSA_COL_INSERT_DISK, IDA_DEFAULT, (const char *)IDS_MSA_INSERT_DISK[iDisk]);
 	waitAnyKey();
 }
 
-void Mickey::gameOver() {
+void MickeyEngine::gameOver() {
 	// We shouldn't run the game over segment if we're quitting.
-	if (_vm->shouldQuit())
+	if (shouldQuit())
 		return;
 
 	drawPic(IDI_MSA_PIC_EARTH_SHIP_LEAVING);
 	printExeMsg(IDO_MSA_GAME_OVER[3]);
 	playSound(IDI_MSA_SND_GAME_OVER);
 
-	if (_game.fItemUsed[IDI_MSA_ITEM_LETTER]) {
+	if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER]) {
 		drawPic(IDI_MSA_PIC_EARTH_MINNIE);
 		printExeMsg(IDO_MSA_GAME_OVER[4]);
 		printExeMsg(IDO_MSA_GAME_OVER[5]);
@@ -1297,74 +1297,74 @@ void Mickey::gameOver() {
 	waitAnyKey();
 }
 
-void Mickey::flipSwitch() {
-	if (_game.fHasXtal || _game.nXtals) {
-		if (!_game.fStoryShown)
+void MickeyEngine::flipSwitch() {
+	if (_gameStateMickey.fHasXtal || _gameStateMickey.nXtals) {
+		if (!_gameStateMickey.fStoryShown)
 			printStory();
 
 		// Initialize planet data
-		if (!_game.fPlanetsInitialized) {
+		if (!_gameStateMickey.fPlanetsInitialized) {
 			int iHint = 0;
 			int iPlanet = 0;
 
-			memset(_game.iPlanetXtal, 0, sizeof(_game.iPlanetXtal));
-			memset(_game.iClue, 0, sizeof(_game.iClue));
+			memset(_gameStateMickey.iPlanetXtal, 0, sizeof(_gameStateMickey.iPlanetXtal));
+			memset(_gameStateMickey.iClue, 0, sizeof(_gameStateMickey.iClue));
 
-			_game.iPlanetXtal[0] = IDI_MSA_PLANET_EARTH;
-			_game.iPlanetXtal[8] = IDI_MSA_PLANET_URANUS;
+			_gameStateMickey.iPlanetXtal[0] = IDI_MSA_PLANET_EARTH;
+			_gameStateMickey.iPlanetXtal[8] = IDI_MSA_PLANET_URANUS;
 
 			for (int i = 1; i < IDI_MSA_MAX_PLANET; i++) {
 				if (i < 8) {
 					do {
 						// Earth (planet 0) and Uranus (planet 8) are excluded
-						iPlanet = _vm->rnd(IDI_MSA_MAX_PLANET - 2);
+						iPlanet = rnd(IDI_MSA_MAX_PLANET - 2);
 					} while (planetIsAlreadyAssigned(iPlanet));
 				} else {
 					iPlanet = IDI_MSA_PLANET_URANUS;	// Uranus is always last
 				}
 
-				_game.iPlanetXtal[i] = iPlanet;
-				iHint = _vm->rnd(5) - 1;	// clues are 0-4
-				_game.iClue[i] = IDO_MSA_NEXT_PIECE[iPlanet][iHint];
+				_gameStateMickey.iPlanetXtal[i] = iPlanet;
+				iHint = rnd(5) - 1;	// clues are 0-4
+				_gameStateMickey.iClue[i] = IDO_MSA_NEXT_PIECE[iPlanet][iHint];
 			}
 
-			_game.fPlanetsInitialized = true;
+			_gameStateMickey.fPlanetsInitialized = true;
 		}
 
 		// activate screen animation
-		_game.fAnimXL30 = true;
+		_gameStateMickey.fAnimXL30 = true;
 
-		_vm->clearTextArea();
+		clearTextArea();
 		playSound(IDI_MSA_SND_XL30);
 		printExeMsg(IDO_MSA_XL30_SPEAKING);
 
-		if (_game.fHasXtal) {
-			_game.fHasXtal = false;
+		if (_gameStateMickey.fHasXtal) {
+			_gameStateMickey.fHasXtal = false;
 			printExeMsg(IDO_MSA_CRYSTAL_PIECE_FOUND);
 		}
 
-		if (_game.nXtals == IDI_MSA_MAX_PLANET) {
+		if (_gameStateMickey.nXtals == IDI_MSA_MAX_PLANET) {
 			printExeMsg(IDO_MSA_GAME_OVER[0]);
 			printExeMsg(IDO_MSA_GAME_OVER[1]);
 			printExeMsg(IDO_MSA_GAME_OVER[2]);
 
 #if 0
 			// DEBUG
-			strcpy(_game.szAddr, (char *)IDS_MSA_ADDR_PLANET[IDI_MSA_PLANET_EARTH]);
-			_game.nButtons = strlen(_game.szAddr);
+			strcpy(_gameStateMickey.szAddr, (char *)IDS_MSA_ADDR_PLANET[IDI_MSA_PLANET_EARTH]);
+			_gameStateMickey.nButtons = strlen(_gameStateMickey.szAddr);
 #endif
 
 		} else {
-			printExeStr(_game.iClue[_game.nXtals]);
+			printExeStr(_gameStateMickey.iClue[_gameStateMickey.nXtals]);
 
 #if 0
 			// DEBUG
-			_vm->drawStr(24, 12, IDA_DEFAULT, (char *)IDS_MSA_NAME_PLANET_2[_game.iPlanetXtal[_game.nXtals]]);
-			_vm->drawStr(24, 22, IDA_DEFAULT, (char *)IDS_MSA_ADDR_PLANET[_game.iPlanetXtal[_game.nXtals]]);
-			strcpy(_game.szAddr, (char *)IDS_MSA_ADDR_PLANET[_game.iPlanetXtal[_game.nXtals]]);
-			_game.nButtons = strlen(_game.szAddr);
-			_vm->_gfx->doUpdate();
-			_vm->_system->updateScreen();	// TODO: this should go in the game's main loop
+			drawStr(24, 12, IDA_DEFAULT, (char *)IDS_MSA_NAME_PLANET_2[_gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]]);
+			drawStr(24, 22, IDA_DEFAULT, (char *)IDS_MSA_ADDR_PLANET[_gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]]);
+			strcpy(_gameStateMickey.szAddr, (char *)IDS_MSA_ADDR_PLANET[_gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]]);
+			_gameStateMickey.nButtons = strlen(_gameStateMickey.szAddr);
+			_gfx->doUpdate();
+			_system->updateScreen();	// TODO: this should go in the game's main loop
 #endif
 
 			waitAnyKey(true);
@@ -1374,73 +1374,73 @@ void Mickey::flipSwitch() {
 	}
 }
 
-void Mickey::inventory() {
+void MickeyEngine::inventory() {
 	int iRow = IDI_MSA_ROW_INV_ITEMS;
 	char szCrystals[12] = {0};
 
-	sprintf(szCrystals, IDS_MSA_CRYSTALS, IDS_MSA_CRYSTAL_NO[_game.nXtals]);
+	sprintf(szCrystals, IDS_MSA_CRYSTALS, IDS_MSA_CRYSTAL_NO[_gameStateMickey.nXtals]);
 
 	CursorMan.showMouse(false);
 
-	_vm->clearScreen(IDA_DEFAULT);
-	_vm->drawStr(IDI_MSA_ROW_INV_TITLE, IDI_MSA_COL_INV_TITLE, IDA_DEFAULT, IDS_MSA_INVENTORY);
-	_vm->drawStr(IDI_MSA_ROW_INV_CRYSTALS, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, szCrystals);
+	clearScreen(IDA_DEFAULT);
+	drawStr(IDI_MSA_ROW_INV_TITLE, IDI_MSA_COL_INV_TITLE, IDA_DEFAULT, IDS_MSA_INVENTORY);
+	drawStr(IDI_MSA_ROW_INV_CRYSTALS, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, szCrystals);
 
 	for (int iItem = 0; iItem < IDI_MSA_MAX_ITEM; iItem++) {
-		if (_game.fItem[_game.iItem[iItem]] && (_game.iItem[iItem] != IDI_MSA_OBJECT_NONE)) {
-			_vm->drawStr(iRow++, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, (const char *)IDS_MSA_NAME_ITEM[_game.iItem[iItem]]);
+		if (_gameStateMickey.fItem[_gameStateMickey.iItem[iItem]] && (_gameStateMickey.iItem[iItem] != IDI_MSA_OBJECT_NONE)) {
+			drawStr(iRow++, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, (const char *)IDS_MSA_NAME_ITEM[_gameStateMickey.iItem[iItem]]);
 		}
 	}
 
 	waitAnyKey();
 
-	_vm->clearScreen(IDA_DEFAULT);
+	clearScreen(IDA_DEFAULT);
 
 	CursorMan.showMouse(true);
 }
 
-void Mickey::intro() {
+void MickeyEngine::intro() {
 	// Draw Sierra logo
 	//drawLogo();		// Original does not even show this, so we skip it too
 	//waitAnyKey();		// Not in the original, but needed so that the logo is visible
 
 	// draw title picture
-	_game.iRoom = IDI_MSA_PIC_TITLE;
+	_gameStateMickey.iRoom = IDI_MSA_PIC_TITLE;
 	drawRoom();
 
 	// show copyright and play theme
 	printExeMsg(IDO_MSA_COPYRIGHT);
 
 	// Quit if necessary
-	if (_vm->shouldQuit())
+	if (shouldQuit())
 		return;
 
 	playSound(IDI_MSA_SND_THEME);
 
 	// load game
-	_game.fIntro = true;
+	_gameStateMickey.fIntro = true;
 	if (chooseY_N(IDO_MSA_LOAD_GAME[0], true)) {
 		if (loadGame()) {
-			_game.iPlanet = IDI_MSA_PLANET_EARTH;
-			_game.fIntro = false;
-			_game.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
+			_gameStateMickey.iPlanet = IDI_MSA_PLANET_EARTH;
+			_gameStateMickey.fIntro = false;
+			_gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
 			return;
 		}
 	}
 
 	// Quit if necessary
-	if (_vm->shouldQuit())
+	if (shouldQuit())
 		return;
 
 	// play spaceship landing scene
-	_game.iPlanet = IDI_MSA_PLANET_EARTH;
-	_game.iRoom = IDI_MSA_PIC_EARTH_ROAD_4;
+	_gameStateMickey.iPlanet = IDI_MSA_PLANET_EARTH;
+	_gameStateMickey.iRoom = IDI_MSA_PIC_EARTH_ROAD_4;
 
 	drawRoom();
 	printRoomDesc();
 
 	// Quit if necessary
-	if (_vm->shouldQuit())
+	if (shouldQuit())
 		return;
 
 	playSound(IDI_MSA_SND_SHIP_LAND);
@@ -1450,48 +1450,48 @@ void Mickey::intro() {
 		playSound(IDI_MSA_SND_PRESS_BLUE);
 
 		//Set screen to white
-		_vm->_gfx->clearScreen(15);
-		_vm->_gfx->doUpdate();
-		_vm->_system->updateScreen();
+		_gfx->clearScreen(15);
+		_gfx->doUpdate();
+		_system->updateScreen();
 
-		_vm->_system->delayMillis(IDI_MSA_ANIM_DELAY);
+		_system->delayMillis(IDI_MSA_ANIM_DELAY);
 
 		//Set back to black
-		_vm->_gfx->clearScreen(0);
-		_vm->_gfx->doUpdate();
-		_vm->_system->updateScreen();
+		_gfx->clearScreen(0);
+		_gfx->doUpdate();
+		_system->updateScreen();
 
 		drawRoom();
-		printDesc(_game.iRoom);
+		printDesc(_gameStateMickey.iRoom);
 	}
 
 	printExeMsg(IDO_MSA_INTRO);
 }
 
-void Mickey::getItem(ENUM_MSA_ITEM iItem) {
-	_game.fItem[iItem] = true;
-	_game.iItem[_game.nItems++] = iItem;
-	_game.oRmTxt[_game.iRoom] = 0;
+void MickeyEngine::getItem(ENUM_MSA_ITEM iItem) {
+	_gameStateMickey.fItem[iItem] = true;
+	_gameStateMickey.iItem[_gameStateMickey.nItems++] = iItem;
+	_gameStateMickey.oRmTxt[_gameStateMickey.iRoom] = 0;
 	playSound(IDI_MSA_SND_TAKE);
 	drawRoom();
 }
 
-void Mickey::getXtal(int iStr) {
-	_game.oRmTxt[_game.iRoom] = 0;
-	_game.fHasXtal = true;
-	_game.nXtals++;
+void MickeyEngine::getXtal(int iStr) {
+	_gameStateMickey.oRmTxt[_gameStateMickey.iRoom] = 0;
+	_gameStateMickey.fHasXtal = true;
+	_gameStateMickey.nXtals++;
 	playSound(IDI_MSA_SND_CRYSTAL);
 	drawRoom();
 	printDatMessage(iStr);
 }
 
-bool Mickey::parse(int cmd, int arg) {
+bool MickeyEngine::parse(int cmd, int arg) {
 	switch (cmd) {
 
 	// BASIC
 
 	case IDI_MSA_ACTION_GOTO_ROOM:
-		_game.iRoom = arg;
+		_gameStateMickey.iRoom = arg;
 		return true;
 	case IDI_MSA_ACTION_SHOW_INT_STR:
 		printLine(IDS_MSA_ERRORS[arg]);
@@ -1515,291 +1515,291 @@ bool Mickey::parse(int cmd, int arg) {
 	// EARTH
 
 	case IDI_MSA_ACTION_GET_ROPE:
-		if (_game.iRmMenu[_game.iRoom] == 2) {
-			_game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
-			_game.iRmMenu[_game.iRoom] = 3;
+		if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] == 2) {
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 3;
 			getItem(IDI_MSA_ITEM_ROPE);
 			printLine("MICKEY TAKES THE ROPE");
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 			printDatMessage(11);
 		}
 		break;
 	case IDI_MSA_ACTION_UNTIE_ROPE:
-		_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_TIRE_SWING_1;
-		_game.iRmObj[_game.iRoom] = 0;
-		_game.iRmMenu[_game.iRoom] = 2;
+		_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_TIRE_SWING_1;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 0;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
 		drawRoom();
 		printDatMessage(12);
 		break;
 	case IDI_MSA_ACTION_GET_BONE:
-		_game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
-		_game.iRmMenu[_game.iRoom] = 1;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 		getItem(IDI_MSA_ITEM_BONE);
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_GET_XTAL_EARTH:
-		_game.iRmMenu[_game.iRoom] = 1;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 		getXtal(arg);
 		break;
 	case IDI_MSA_ACTION_LOOK_DESK:
-		_game.iRmMenu[_game.iRoom] = 1;
-		_game.iRmObj[_game.iRoom] = 2;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 2;
 		drawRoom();
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_WRITE_LETTER:
-		_game.iRmMenu[_game.iRoom] = 3;
-		_game.iRmMenu[IDI_MSA_PIC_EARTH_MAILBOX] = 1;
-		_game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 3;
+		_gameStateMickey.iRmMenu[IDI_MSA_PIC_EARTH_MAILBOX] = 1;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
 		getItem(IDI_MSA_ITEM_LETTER);
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_MAIL_LETTER:
-		_game.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
-		_game.fItem[IDI_MSA_ITEM_LETTER] = false;
-		_game.iRmMenu[_game.iRoom] = 0;
+		_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
+		_gameStateMickey.fItem[IDI_MSA_ITEM_LETTER] = false;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_OPEN_MAILBOX:
-		if (_game.fItemUsed[IDI_MSA_ITEM_LETTER]) {
+		if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER]) {
 			printDatMessage(110);
 		} else {
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_OPEN_CUPBOARD:
-		if (_game.iRmMenu[_game.iRoom]) {
-			if (_game.iRmObj[_game.iRoom] == IDI_MSA_OBJECT_NONE) {
+		if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
+			if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] == IDI_MSA_OBJECT_NONE) {
 				printDatMessage(78);
 			} else {
 				printDatMessage(arg);
 			}
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_KITCHEN_1;
-			_game.iRmObj[_game.iRoom] = 3;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_KITCHEN_1;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 3;
 			drawRoom();
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_FLASHLIGHT:
 		if (!mickeyHasItem(IDI_MSA_ITEM_FLASHLIGHT)) {
-			_game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
 			getItem(IDI_MSA_ITEM_FLASHLIGHT);
 			drawRoom();
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_OPEN_CABINET:
-		if (_game.iRmMenu[_game.iRoom]) {
+		if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
 			printDatMessage(109);
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_GARAGE_1;
-			_game.iRmObj[_game.iRoom] = 15;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_GARAGE_1;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 15;
 			drawRoom();
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_CROWBAR:
 		if (!mickeyHasItem(IDI_MSA_ITEM_CROWBAR)) {
-			_game.iRmObj[_game.iRoom]--;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom]--;
 			getItem(IDI_MSA_ITEM_CROWBAR);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_WRENCH:
 		if (!mickeyHasItem(IDI_MSA_ITEM_WRENCH)) {
-			_game.iRmObj[_game.iRoom] -= 2;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] -= 2;
 			getItem(IDI_MSA_ITEM_WRENCH);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_OPEN_CLOSET:
-		if (_game.iRmMenu[_game.iRoom]) {
+		if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
 			printDatMessage(99);
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_BEDROOM_1;
-			_game.iRmObj[_game.iRoom] = 7;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_BEDROOM_1;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 7;
 			drawRoom();
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_MATTRESS:
 		if (!mickeyHasItem(IDI_MSA_ITEM_MATTRESS)) {
-			_game.iRmObj[_game.iRoom]--;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom]--;
 			getItem(IDI_MSA_ITEM_MATTRESS);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_SCARF:
 		if (!mickeyHasItem(IDI_MSA_ITEM_SCARF)) {
-			_game.iRmObj[_game.iRoom] -= 2;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] -= 2;
 			getItem(IDI_MSA_ITEM_SCARF);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_SUNGLASSES:
 		if (!mickeyHasItem(IDI_MSA_ITEM_SUNGLASSES)) {
-			_game.iRmObj[_game.iRoom]--;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom]--;
 			getItem(IDI_MSA_ITEM_SUNGLASSES);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_SCALE:
 		if (!mickeyHasItem(IDI_MSA_ITEM_SCALE)) {
-			_game.iRmMenu[IDI_MSA_PIC_VENUS_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_NEPTUNE_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_MERCURY_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_SATURN_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_PLUTO_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_JUPITER_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_MARS_WEIGH] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_URANUS_WEIGH] = 1;
-			_game.iRmObj[_game.iRoom] -= 2;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_VENUS_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_NEPTUNE_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_MERCURY_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_PLUTO_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_JUPITER_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_MARS_WEIGH] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_URANUS_WEIGH] = 1;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] -= 2;
 			getItem(IDI_MSA_ITEM_SCALE);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GOTO_SPACESHIP:
-		_game.iRoom = IDI_MSA_PIC_SHIP_AIRLOCK;
-		if (_game.iPlanet != IDI_MSA_PLANET_EARTH)
+		_gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_AIRLOCK;
+		if (_gameStateMickey.iPlanet != IDI_MSA_PLANET_EARTH)
 			insertDisk(0);
 		return true;
 
 	// VENUS
 
 	case IDI_MSA_ACTION_DOWN_CHASM:
-		if (_game.fItem[IDI_MSA_ITEM_ROPE]) {
-			_game.iRmMenu[_game.iRoom] = 1;
+		if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROPE]) {
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 		}
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_DOWN_ROPE:
-		if (_game.fItemUsed[IDI_MSA_ITEM_ROPE]) {
-			_game.iRoom = IDI_MSA_PIC_VENUS_PROBE;
+		if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_ROPE]) {
+			_gameStateMickey.iRoom = IDI_MSA_PIC_VENUS_PROBE;
 			return true;
 		} else {
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_USE_ROPE:
-		if (_game.fItemUsed[IDI_MSA_ITEM_ROPE]) {
+		if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_ROPE]) {
 			printDatMessage(22);
 		} else {
-			_game.fItemUsed[IDI_MSA_ITEM_ROPE] = true;
-			_game.fItem[IDI_MSA_ITEM_ROPE] = false;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_VENUS_CHASM_1;
+			_gameStateMickey.fItemUsed[IDI_MSA_ITEM_ROPE] = true;
+			_gameStateMickey.fItem[IDI_MSA_ITEM_ROPE] = false;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_VENUS_CHASM_1;
 			drawRoom();
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_OPEN_HATCH:
-		if (_game.fItemUsed[IDI_MSA_ITEM_WRENCH]) {
-			if ((_game.iRmMenu[_game.iRoom] == 3) || (_game.iRmPic[_game.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1))
+		if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_WRENCH]) {
+			if ((_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] == 3) || (_gameStateMickey.iRmPic[_gameStateMickey.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1))
 				printDatMessage(39);
 			else {
-				_game.iRmMenu[_game.iRoom] = 2;
-				_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_VENUS_PROBE_1;
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
+				_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_VENUS_PROBE_1;
 				drawRoom();
 				printDatMessage(24);
 			}
 		} else {
-			if (_game.fItem[IDI_MSA_ITEM_WRENCH]) {
-				_game.iRmMenu[_game.iRoom] = 1;
+			if (_gameStateMickey.fItem[IDI_MSA_ITEM_WRENCH]) {
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 			}
 
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_USE_WRENCH:
-		_game.fItemUsed[IDI_MSA_ITEM_WRENCH] = true;
+		_gameStateMickey.fItemUsed[IDI_MSA_ITEM_WRENCH] = true;
 		printDatString(arg);
 
-		if (_game.iRmPic[_game.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1) {
-			_vm->clearRow(22);
+		if (_gameStateMickey.iRmPic[_gameStateMickey.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1) {
+			clearRow(22);
 		}
 
 		waitAnyKey();
 		break;
 	case IDI_MSA_ACTION_GET_XTAL_VENUS:
-		_game.iRmMenu[_game.iRoom] = 3;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 3;
 		getXtal(arg);
 		break;
 
 	// TRITON (NEPTUNE)
 
 	case IDI_MSA_ACTION_LOOK_CASTLE:
-		if (!_game.iRmMenu[_game.iRoom]) {
-			_game.iRmMenu[_game.iRoom] = 1;
+		if (!_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 		}
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_ENTER_OPENING:
-		if (_game.fItemUsed[IDI_MSA_ITEM_CROWBAR]) {
-			_game.iRoom = IDI_MSA_PIC_NEPTUNE_CASTLE_4;
+		if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_CROWBAR]) {
+			_gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_CASTLE_4;
 
 			return true;
 		} else {
-			if (_game.fItem[IDI_MSA_ITEM_CROWBAR]) {
-				_game.iRmMenu[_game.iRoom] = 2;
+			if (_gameStateMickey.fItem[IDI_MSA_ITEM_CROWBAR]) {
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
 			}
 
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_USE_CROWBAR:
-		_game.fItemUsed[IDI_MSA_ITEM_CROWBAR] = true;
-		_game.iRmMenu[_game.iRoom] = 1;
-		_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_NEPTUNE_ENTRANCE_1;
+		_gameStateMickey.fItemUsed[IDI_MSA_ITEM_CROWBAR] = true;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+		_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_NEPTUNE_ENTRANCE_1;
 		drawRoom();
 		printDatMessage(arg);
 		break;
 	case IDI_MSA_ACTION_GET_XTAL_NEPTUNE:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(71);
 		} else {
-			if (_game.fItem[IDI_MSA_ITEM_SCARF]) {
-				_game.iRmMenu[_game.iRoom] = 1;
+			if (_gameStateMickey.fItem[IDI_MSA_ITEM_SCARF]) {
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 			}
 
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_TALK_LEADER:
-		_game.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
+		_gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
 
 		printDatMessage(arg);
 		return true;
 	case IDI_MSA_ACTION_GIVE_SCARF:
-		_game.iRmObj[_game.iRoom] = 18;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 18;
 		getXtal(arg);
-		_game.fItem[IDI_MSA_ITEM_SCARF] = false;
-		_game.iRmMenu[_game.iRoom] = 0;
-		_game.iRmMenu[IDI_MSA_PIC_EARTH_BEDROOM] = 2;
-		_game.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
+		_gameStateMickey.fItem[IDI_MSA_ITEM_SCARF] = false;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
+		_gameStateMickey.iRmMenu[IDI_MSA_PIC_EARTH_BEDROOM] = 2;
+		_gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
 
 		return true;
 
 	// MERCURY
 
 	case IDI_MSA_ACTION_GET_XTAL_MERCURY:
-		if (_game.fHasXtal) {
-			_game.iRmMenu[_game.iRoom] = 2;
+		if (_gameStateMickey.fHasXtal) {
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
 			printDatMessage(32);
 		} else {
-			if (_game.fItem[IDI_MSA_ITEM_SUNGLASSES]) {
-				_game.iRmMenu[_game.iRoom] = 1;
+			if (_gameStateMickey.fItem[IDI_MSA_ITEM_SUNGLASSES]) {
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 			}
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GIVE_SUNGLASSES:
-		_game.iRmObj[_game.iRoom] = 17;
-		_game.iRmMenu[_game.iRoom] = 2;
-		_game.fItem[IDI_MSA_ITEM_SUNGLASSES] = false;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 17;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
+		_gameStateMickey.fItem[IDI_MSA_ITEM_SUNGLASSES] = false;
 
 		getXtal(arg);
 
@@ -1808,30 +1808,30 @@ bool Mickey::parse(int cmd, int arg) {
 	// TITAN (SATURN)
 
 	case IDI_MSA_ACTION_CROSS_LAKE:
-		if (_game.fItem[IDI_MSA_ITEM_MATTRESS]) {
-			_game.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_0] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_1] = 1;
-			_game.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_2] = 1;
+		if (_gameStateMickey.fItem[IDI_MSA_ITEM_MATTRESS]) {
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_0] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_1] = 1;
+			_gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_2] = 1;
 		}
 
 		printDatMessage(arg);
 
 		break;
 	case IDI_MSA_ACTION_USE_MATTRESS:
-		_game.iRoom = IDI_MSA_PIC_SATURN_ISLAND;
+		_gameStateMickey.iRoom = IDI_MSA_PIC_SATURN_ISLAND;
 
 		printDatMessage(arg);
 
 		return true;
 	case IDI_MSA_ACTION_GET_XTAL_SATURN:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(29);
 		} else {
 			getXtal(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_LEAVE_ISLAND:
-		_game.iRoom = IDI_MSA_PIC_SATURN_LAKE_1;
+		_gameStateMickey.iRoom = IDI_MSA_PIC_SATURN_LAKE_1;
 
 		printDatMessage(arg);
 
@@ -1840,19 +1840,19 @@ bool Mickey::parse(int cmd, int arg) {
 	// PLUTO
 
 	case IDI_MSA_ACTION_GET_XTAL_PLUTO:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(19);
 		} else {
-			if (_game.fItem[IDI_MSA_ITEM_BONE]) {
-				_game.iRmMenu[_game.iRoom] = 1;
+			if (_gameStateMickey.fItem[IDI_MSA_ITEM_BONE]) {
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 			}
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GIVE_BONE:
-		_game.fItem[IDI_MSA_ITEM_BONE] = false;
-		_game.iRmMenu[_game.iRoom] = 0;
-		_game.iRmObj[_game.iRoom] = 16;
+		_gameStateMickey.fItem[IDI_MSA_ITEM_BONE] = false;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 16;
 
 		getXtal(arg);
 
@@ -1862,29 +1862,29 @@ bool Mickey::parse(int cmd, int arg) {
 
 	case IDI_MSA_ACTION_GET_ROCK_0:
 	case IDI_MSA_ACTION_GET_ROCK_1:
-		if (_game.fItem[IDI_MSA_ITEM_ROCK]) {
+		if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK]) {
 			printDatMessage(38);
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
-			_game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+			_gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
 			getItem(IDI_MSA_ITEM_ROCK);
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_XTAL_JUPITER:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(15);
 		} else {
-			switch (_game.nRocks) {
+			switch (_gameStateMickey.nRocks) {
 			case 0:
-				if (_game.fItem[IDI_MSA_ITEM_ROCK]) {
-					_game.iRmMenu[_game.iRoom] = 1;
+				if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK]) {
+					_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 				}
 				printDatMessage(arg);
 				break;
 			case 1:
-				if (_game.fItem[IDI_MSA_ITEM_ROCK]) {
-					_game.iRmMenu[_game.iRoom] = 1;
+				if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK]) {
+					_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 				}
 				printDatMessage(34);
 				break;
@@ -1895,47 +1895,47 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_THROW_ROCK:
-		_game.fItem[IDI_MSA_ITEM_ROCK] = false;
-		_game.nItems--;
-		_game.iRmObj[_game.iRoom]++;
-		_game.iRmMenu[_game.iRoom] = 0;
+		_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK] = false;
+		_gameStateMickey.nItems--;
+		_gameStateMickey.iRmObj[_gameStateMickey.iRoom]++;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
 
 		drawRoom();
 
-		if (_game.nRocks) {
+		if (_gameStateMickey.nRocks) {
 			printDatMessage(37);
 		} else {
 			printDatMessage(arg);
 		}
 
-		_game.nRocks++;
+		_gameStateMickey.nRocks++;
 		break;
 
 	// MARS
 
 	case IDI_MSA_ACTION_GO_TUBE:
-		if (_game.fItem[IDI_MSA_ITEM_FLASHLIGHT]) {
-			_game.iRmMenu[_game.iRoom] = 1;
+		if (_gameStateMickey.fItem[IDI_MSA_ITEM_FLASHLIGHT]) {
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 		}
 
 		printDatMessage(arg);
 
 		break;
 	case IDI_MSA_ACTION_USE_FLASHLIGHT:
-		_game.iRoom = IDI_MSA_PIC_MARS_TUBE_1;
+		_gameStateMickey.iRoom = IDI_MSA_PIC_MARS_TUBE_1;
 
 		printDatMessage(15);
 
 		return true;
 	case IDI_MSA_ACTION_PLUTO_DIG:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(21);
 		} else {
 			getXtal(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_GET_XTAL_MARS:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(23);
 		} else {
 			printDatMessage(arg);
@@ -1945,29 +1945,29 @@ bool Mickey::parse(int cmd, int arg) {
 	// OBERON (URANUS)
 
 	case IDI_MSA_ACTION_ENTER_TEMPLE:
-		_game.iRoom = IDI_MSA_PIC_URANUS_TEMPLE;
+		_gameStateMickey.iRoom = IDI_MSA_PIC_URANUS_TEMPLE;
 
 		return true;
 	case IDI_MSA_ACTION_USE_CRYSTAL:
-		if (_game.iRmMenu[_game.iRoom]) {
+		if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
 			printDatMessage(25);
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_1;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_1;
 
 			drawRoom();
 
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE;
 
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_OPEN_DOOR:
-		if (_game.fTempleDoorOpen) {
+		if (_gameStateMickey.fTempleDoorOpen) {
 			printDatMessage(36);
 		} else {
-			_game.fTempleDoorOpen = 1;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_2;
+			_gameStateMickey.fTempleDoorOpen = 1;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_2;
 
 			drawRoom();
 
@@ -1975,8 +1975,8 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_ENTER_DOOR:
-		if (_game.fTempleDoorOpen) {
-			_game.iRoom = IDI_MSA_PIC_URANUS_STEPS;
+		if (_gameStateMickey.fTempleDoorOpen) {
+			_gameStateMickey.iRoom = IDI_MSA_PIC_URANUS_STEPS;
 
 			return true;
 		} else {
@@ -1984,17 +1984,17 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_GET_XTAL_URANUS:
-		if (_game.fHasXtal) {
+		if (_gameStateMickey.fHasXtal) {
 			printDatMessage(34);
 		} else {
-			if (_game.fItem[IDI_MSA_ITEM_CROWBAR]) {
-				_game.iRmMenu[_game.iRoom] = 1;
+			if (_gameStateMickey.fItem[IDI_MSA_ITEM_CROWBAR]) {
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
 			}
 			printDatMessage(arg);
 		}
 		break;
 	case IDI_MSA_ACTION_USE_CROWBAR_1:
-		_game.iRmMenu[_game.iRoom] = 0;
+		_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
 
 		getXtal(arg);
 
@@ -2003,11 +2003,11 @@ bool Mickey::parse(int cmd, int arg) {
 	// SPACESHIP
 
 	case IDI_MSA_ACTION_GO_NORTH:
-		if (_game.fShipDoorOpen) {
-			if (_game.fSuit) {
+		if (_gameStateMickey.fShipDoorOpen) {
+			if (_gameStateMickey.fSuit) {
 				printDatMessage(45);
 			} else {
-				_game.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
+				_gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
 				return true;
 			}
 		} else {
@@ -2015,19 +2015,19 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_GO_PLANET:
-		if (!_game.fShipDoorOpen) {
-			if ((_game.nXtals == IDI_MSA_MAX_PLANET) && (_game.iPlanet == IDI_MSA_PLANET_EARTH))
+		if (!_gameStateMickey.fShipDoorOpen) {
+			if ((_gameStateMickey.nXtals == IDI_MSA_MAX_PLANET) && (_gameStateMickey.iPlanet == IDI_MSA_PLANET_EARTH))
 				gameOver();
-			if ((_game.iPlanet == _game.iPlanetXtal[_game.nXtals]) || (_game.iPlanet == IDI_MSA_PLANET_EARTH)) {
-				_game.fHasXtal = false;
-				_game.iRoom = IDI_MSA_HOME_PLANET[_game.iPlanet];
+			if ((_gameStateMickey.iPlanet == _gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]) || (_gameStateMickey.iPlanet == IDI_MSA_PLANET_EARTH)) {
+				_gameStateMickey.fHasXtal = false;
+				_gameStateMickey.iRoom = IDI_MSA_HOME_PLANET[_gameStateMickey.iPlanet];
 
-				if (_game.iPlanet != IDI_MSA_PLANET_EARTH)
+				if (_gameStateMickey.iPlanet != IDI_MSA_PLANET_EARTH)
 					insertDisk(1);
 
 				return true;
 			} else {
-				_game.iRoom = IDI_MSA_SHIP_PLANET[_game.iPlanet];
+				_gameStateMickey.iRoom = IDI_MSA_SHIP_PLANET[_gameStateMickey.iPlanet];
 
 				return true;
 			}
@@ -2036,20 +2036,20 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_PRESS_BUTTON:
-		if (_game.fShipDoorOpen) {		// inner door open
-			if (_game.iPlanet && !_game.fSuit) {
+		if (_gameStateMickey.fShipDoorOpen) {		// inner door open
+			if (_gameStateMickey.iPlanet && !_gameStateMickey.fSuit) {
 				printDatMessage(arg);
 			} else {
-				_game.fShipDoorOpen = false;
-				_game.iRmPic[_game.iRoom]--;
+				_gameStateMickey.fShipDoorOpen = false;
+				_gameStateMickey.iRmPic[_gameStateMickey.iRoom]--;
 
 				drawRoom();
 
 				printDatMessage(2);
 			}
 		} else {
-			_game.fShipDoorOpen = true;
-			_game.iRmPic[_game.iRoom]++;
+			_gameStateMickey.fShipDoorOpen = true;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom]++;
 
 			drawRoom();
 
@@ -2057,11 +2057,11 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_WEAR_SPACESUIT:
-		if (_game.fSuit) {
-			if (_game.fShipDoorOpen) {
-				_game.fSuit = false;
-				_game.iRmMenu[_game.iRoom] = 0;
-				_game.iRmPic[_game.iRoom] -= 2;
+		if (_gameStateMickey.fSuit) {
+			if (_gameStateMickey.fShipDoorOpen) {
+				_gameStateMickey.fSuit = false;
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
+				_gameStateMickey.iRmPic[_gameStateMickey.iRoom] -= 2;
 
 				drawRoom();
 
@@ -2070,10 +2070,10 @@ bool Mickey::parse(int cmd, int arg) {
 				printDatMessage(3);
 			}
 		} else {
-			if (_game.iPlanet) {
-				_game.fSuit = true;
-				_game.iRmMenu[_game.iRoom] = 1;
-				_game.iRmPic[_game.iRoom] += 2;
+			if (_gameStateMickey.iPlanet) {
+				_gameStateMickey.fSuit = true;
+				_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+				_gameStateMickey.iRmPic[_gameStateMickey.iRoom] += 2;
 
 				drawRoom();
 
@@ -2085,14 +2085,14 @@ bool Mickey::parse(int cmd, int arg) {
 		break;
 	case IDI_MSA_ACTION_READ_GAUGE:
 		printDatString(arg);
-		_vm->drawStr(21, 15, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_C[_game.iPlanet]);
-		_vm->drawStr(21, 23, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_F[_game.iPlanet]);
+		drawStr(21, 15, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_C[_gameStateMickey.iPlanet]);
+		drawStr(21, 23, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_F[_gameStateMickey.iPlanet]);
 
 		waitAnyKey();
 
 		break;
 	case IDI_MSA_ACTION_PRESS_ORANGE:
-		if (_game.fFlying) {
+		if (_gameStateMickey.fFlying) {
 			printDatMessage(4);
 		} else {
 			playSound(IDI_MSA_SND_PRESS_ORANGE);
@@ -2101,7 +2101,7 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_PRESS_BLUE:
-		if (_game.fFlying) {
+		if (_gameStateMickey.fFlying) {
 			printDatMessage(4);
 		} else {
 			playSound(IDI_MSA_SND_PRESS_BLUE);
@@ -2113,18 +2113,18 @@ bool Mickey::parse(int cmd, int arg) {
 		flipSwitch();
 		break;
 	case IDI_MSA_ACTION_PUSH_THROTTLE:
-		if (_game.fFlying) {
-			_game.fFlying = false;
-			_game.nButtons = 0;
+		if (_gameStateMickey.fFlying) {
+			_gameStateMickey.fFlying = false;
+			_gameStateMickey.nButtons = 0;
 
-			memset(_game.szAddr, 0, sizeof(_game.szAddr));
+			memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
 
 			drawRoom();
 
 			printDatString(22);
 
-			_vm->drawStr(IDI_MSA_ROW_PLANET, IDI_MSA_COL_PLANET, IDA_DEFAULT,
-						(const char *)IDS_MSA_PLANETS[_game.iPlanet]);
+			drawStr(IDI_MSA_ROW_PLANET, IDI_MSA_COL_PLANET, IDA_DEFAULT,
+						(const char *)IDS_MSA_PLANETS[_gameStateMickey.iPlanet]);
 
 			waitAnyKey(true);
 
@@ -2134,39 +2134,39 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_PULL_THROTTLE:
-		if (_game.fFlying) {
+		if (_gameStateMickey.fFlying) {
 			printDatMessage(18);
 		} else {
 			if (getPlanet() != -1) {
-				_game.fFlying = true;
-				_game.iPlanet = getPlanet();
+				_gameStateMickey.fFlying = true;
+				_gameStateMickey.iPlanet = getPlanet();
 
 				drawRoom();
 
 				printDatMessage(16);
 			} else {
-				_game.nButtons = 0;
+				_gameStateMickey.nButtons = 0;
 
-				memset(_game.szAddr, 0, sizeof(_game.szAddr));
+				memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
 
 				printDatMessage(17);
 			}
 		}
 		break;
 	case IDI_MSA_ACTION_LEAVE_ROOM:
-		if (_game.fFlying) {
+		if (_gameStateMickey.fFlying) {
 			printDatMessage(24);
 		} else {
-			_game.iRoom = arg;
+			_gameStateMickey.iRoom = arg;
 			return true;
 		}
 		break;
 	case IDI_MSA_ACTION_OPEN_CABINET_1:
-		if (_game.iRmMenu[_game.iRoom]) {
+		if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
 			printLine("THE CABINET IS ALREADY OPEN");
 		} else {
-			_game.iRmMenu[_game.iRoom] = 1;
-			_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_SHIP_KITCHEN_1;
+			_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+			_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_SHIP_KITCHEN_1;
 
 			drawRoom();
 
@@ -2174,7 +2174,7 @@ bool Mickey::parse(int cmd, int arg) {
 		}
 		break;
 	case IDI_MSA_ACTION_READ_MAP:
-		_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_STAR_MAP;
+		_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_STAR_MAP;
 
 		drawRoom();
 
@@ -2182,16 +2182,16 @@ bool Mickey::parse(int cmd, int arg) {
 		printDatMessage(47);
 		printDatMessage(48);
 
-		_game.iRmPic[_game.iRoom] = IDI_MSA_PIC_SHIP_BEDROOM;
+		_gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_SHIP_BEDROOM;
 
 		drawRoom();
 		break;
 	case IDI_MSA_ACTION_GO_WEST:
-		_game.nButtons = 0;
+		_gameStateMickey.nButtons = 0;
 
-		memset(_game.szAddr, 0, sizeof(_game.szAddr));
+		memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
 
-		_game.iRoom = arg;
+		_gameStateMickey.iRoom = arg;
 
 		return true;
 	}
@@ -2201,14 +2201,14 @@ bool Mickey::parse(int cmd, int arg) {
 
 // Keyboard
 
-void Mickey::waitAnyKey(bool anim) {
+void MickeyEngine::waitAnyKey(bool anim) {
 	Common::Event event;
 
 	if (!anim)
-		_vm->_gfx->doUpdate();
+		_gfx->doUpdate();
 
-	while (!_vm->shouldQuit()) {
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
+	while (!shouldQuit()) {
+		while (_system->getEventManager()->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_RTL:
 			case Common::EVENT_QUIT:
@@ -2223,134 +2223,137 @@ void Mickey::waitAnyKey(bool anim) {
 
 		if (anim) {
 			animate();
-			_vm->_gfx->doUpdate();
+			_gfx->doUpdate();
 		}
 
-		_vm->_system->updateScreen();
-		_vm->_system->delayMillis(10);
+		_system->updateScreen();
+		_system->delayMillis(10);
 	}
 }
 
 // Console-related functions
 
-void Mickey::debugCurRoom() {
-	_vm->_console->DebugPrintf("Current Room = %d\n", _game.iRoom);
+void MickeyEngine::debugCurRoom() {
+	_console->DebugPrintf("Current Room = %d\n", _gameStateMickey.iRoom);
 
-	if (_game.iRmObj[_game.iRoom] != IDI_MSA_OBJECT_NONE) {
-		_vm->_console->DebugPrintf("Object %d is in the room\n", _game.iRmObj[_game.iRoom]);
+	if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] != IDI_MSA_OBJECT_NONE) {
+		_console->DebugPrintf("Object %d is in the room\n", _gameStateMickey.iRmObj[_gameStateMickey.iRoom]);
 	}
 }
 
-void Mickey::debugGotoRoom(int room) {
-	_game.iRoom = room;
+void MickeyEngine::debugGotoRoom(int room) {
+	_gameStateMickey.iRoom = room;
 	drawRoom();
 }
 
-Mickey::Mickey(PreAgiEngine *vm) : _vm(vm) {
-	_vm->_console = new Mickey_Console(_vm, this);
+MickeyEngine::MickeyEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
+	_console = new Mickey_Console(this);
 }
 
-Mickey::~Mickey() {
+MickeyEngine::~MickeyEngine() {
 }
 
-void Mickey::init() {
+void MickeyEngine::init() {
 	uint8 buffer[512];
 
 	// clear game struct
-	memset(&_game, 0, sizeof(_game));
-	memset(&_game.iItem, IDI_MSA_OBJECT_NONE, sizeof(_game.iItem));
+	memset(&_gameStateMickey, 0, sizeof(_gameStateMickey));
+	memset(&_gameStateMickey.iItem, IDI_MSA_OBJECT_NONE, sizeof(_gameStateMickey.iItem));
 	// read room extended desc flags
 	//readExe(IDO_MSA_ROOM_TEXT, buffer, sizeof(buffer));
-	//memcpy(_game.fRmTxt, buffer, sizeof(_game.fRmTxt));
+	//memcpy(_gameStateMickey.fRmTxt, buffer, sizeof(_gameStateMickey.fRmTxt));
 
 	// read room extended desc offsets
 	readExe(IDO_MSA_ROOM_TEXT_OFFSETS, buffer, sizeof(buffer));
-	memcpy(_game.oRmTxt, buffer, sizeof(_game.oRmTxt));
+	memcpy(_gameStateMickey.oRmTxt, buffer, sizeof(_gameStateMickey.oRmTxt));
 	for (int i = 0; i < IDI_MSA_MAX_ROOM; i++)
-		_game.oRmTxt[i] = buffer[i*2] + 256 * buffer[i*2+1];
+		_gameStateMickey.oRmTxt[i] = buffer[i*2] + 256 * buffer[i*2+1];
 
 	// read room object indices
 	//readExe(IDO_MSA_ROOM_OBJECT, buffer, sizeof(buffer));
-	//memcpy(_game.iRmObj, buffer, sizeof(_game.iRmObj));
+	//memcpy(_gameStateMickey.iRmObj, buffer, sizeof(_gameStateMickey.iRmObj));
 
 	// read room picture indices
 	//readExe(IDO_MSA_ROOM_PICTURE, buffer, sizeof(buffer));
-	//memcpy(_game.iRmPic, buffer, sizeof(_game.iRmPic));
+	//memcpy(_gameStateMickey.iRmPic, buffer, sizeof(_gameStateMickey.iRmPic));
 
 	// read room menu patch indices
 	readExe(IDO_MSA_ROOM_MENU_FIX, buffer, sizeof(buffer));
-	memcpy(_game.nRmMenu, buffer, sizeof(_game.nRmMenu));
+	memcpy(_gameStateMickey.nRmMenu, buffer, sizeof(_gameStateMickey.nRmMenu));
 
 	// set room picture and room object indices
 	for (int i = 0; i < IDI_MSA_MAX_ROOM; i++) {
-		_game.iRmPic[i] = i;
-		_game.iRmObj[i] = -1;
+		_gameStateMickey.iRmPic[i] = i;
+		_gameStateMickey.iRmObj[i] = -1;
 	}
-	_game.iRmPic[IDI_MSA_PIC_SHIP_AIRLOCK] = IDI_MSA_PIC_SHIP_AIRLOCK_0;
-	_game.iRmObj[IDI_MSA_PIC_EARTH_BATHROOM] = 11;
-	_game.iRmObj[IDI_MSA_PIC_JUPITER_LAVA] = 21;
-	_game.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_0] = 20;
-	_game.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_1] = 19;
-	_game.iRmObj[IDI_MSA_PIC_EARTH_IN_DOGHOUSE] = 1;
+	_gameStateMickey.iRmPic[IDI_MSA_PIC_SHIP_AIRLOCK] = IDI_MSA_PIC_SHIP_AIRLOCK_0;
+	_gameStateMickey.iRmObj[IDI_MSA_PIC_EARTH_BATHROOM] = 11;
+	_gameStateMickey.iRmObj[IDI_MSA_PIC_JUPITER_LAVA] = 21;
+	_gameStateMickey.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_0] = 20;
+	_gameStateMickey.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_1] = 19;
+	_gameStateMickey.iRmObj[IDI_MSA_PIC_EARTH_IN_DOGHOUSE] = 1;
 
 #if 0
 	// DEBUG
-	_game.iPlanet = IDI_MSA_PLANET_EARTH;
-	_game.iRoom = IDI_MSA_PIC_SHIP_CONTROLS;
-	_game.fHasXtal = true;
-	_game.nXtals = 9;
-	_game.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
+	_gameStateMickey.iPlanet = IDI_MSA_PLANET_EARTH;
+	_gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_CONTROLS;
+	_gameStateMickey.fHasXtal = true;
+	_gameStateMickey.nXtals = 9;
+	_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
 
 #endif
 }
 
-void Mickey::run() {
-	bool done;
+Common::Error MickeyEngine::go() {
+	init();
 
 	// Game intro
 	intro();
 
 	// Game loop
-	while (!_vm->shouldQuit()) {
+	while (!shouldQuit()) {
 		drawRoom();
 
-		if (_game.fIntro) {
-			_game.fIntro = false;
+		if (_gameStateMickey.fIntro) {
+			_gameStateMickey.fIntro = false;
 		} else {
 			printRoomDesc();
 		}
 
-		if (_game.iRoom == IDI_MSA_PIC_NEPTUNE_GUARD) {
-			_game.iRoom = IDI_MSA_PIC_NEPTUNE_LEADER;
+		bool done;
+		if (_gameStateMickey.iRoom == IDI_MSA_PIC_NEPTUNE_GUARD) {
+			_gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_LEADER;
 			done = true;
 		} else {
 			done = false;
 		}
 
-		while (!done && !_vm->shouldQuit()) {
+		while (!done && !shouldQuit()) {
 			// Check air supply
-			if (_game.fSuit) {
-				_game.nAir -= 1;
+			if (_gameStateMickey.fSuit) {
+				_gameStateMickey.nAir -= 1;
 				for (int i = 0; i < 4; i++) {
-					if (_game.nAir == IDI_MSA_AIR_SUPPLY[i]) {
+					if (_gameStateMickey.nAir == IDI_MSA_AIR_SUPPLY[i]) {
 						playSound(IDI_MSA_SND_XL30);
 						printExeMsg(IDO_MSA_XL30_SPEAKING);
 						printExeMsg(IDO_MSA_AIR_SUPPLY[i]);
 						if (i == 3)
-							return;
+							return Common::kNoError;
 					}
 				}
 			} else {
-				_game.nAir = 50;	// max air supply
+				_gameStateMickey.nAir = 50;	// max air supply
 			}
 
 			done = checkMenu();
 		}
 
-		_game.nFrame = 0;
+		_gameStateMickey.nFrame = 0;
 	}
 
 	gameOver();
-}
 
+	return Common::kNoError;
 }
+
+} // End of namespace Agi
diff --git a/engines/agi/preagi_mickey.h b/engines/agi/preagi_mickey.h
index 6298137..788cfab 100644
--- a/engines/agi/preagi_mickey.h
+++ b/engines/agi/preagi_mickey.h
@@ -676,13 +676,13 @@ struct MSA_GAME {
 
 class PreAgiEngine;
 
-class Mickey {
+class MickeyEngine : public PreAgiEngine {
 public:
-	Mickey(PreAgiEngine *vm);
-	~Mickey();
+	MickeyEngine(OSystem *syst, const AGIGameDescription *gameDesc);
+	~MickeyEngine();
 
 	void init();
-	void run();
+	Common::Error go();
 
 	void debugCurRoom();
 	void debugGotoRoom(int);
@@ -690,9 +690,7 @@ public:
 	void drawObj(ENUM_MSA_OBJECT, int, int);
 
 protected:
-	PreAgiEngine *_vm;
-
-	MSA_GAME _game;
+	MSA_GAME _gameStateMickey;
 	bool _clickToMove;
 
 	int getDat(int);
@@ -741,14 +739,14 @@ protected:
 
 	bool planetIsAlreadyAssigned(int planet) {
 		for (int j = 0; j < IDI_MSA_MAX_PLANET; j++) {
-			if (_game.iPlanetXtal[j] == planet)
+			if (_gameStateMickey.iPlanetXtal[j] == planet)
 				return true;
 		}
 		return false;
 	}
 
 	bool mickeyHasItem(int item) {
-		if (_game.fItem[item]) {
+		if (_gameStateMickey.fItem[item]) {
 			printDatMessage(90);	// Mickey already has item
 			return true;
 		} else {


Commit: 6a9d4b3e5b39bf6260b1b393038f822d2831f1ca
    https://github.com/scummvm/scummvm/commit/6a9d4b3e5b39bf6260b1b393038f822d2831f1ca
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2011-08-15T08:55:03-07:00

Commit Message:
AGI: Make Troll inherit from PreAgiEngine

Changed paths:
    engines/agi/detection.cpp
    engines/agi/preagi.cpp
    engines/agi/preagi.h
    engines/agi/preagi_troll.cpp
    engines/agi/preagi_troll.h
    engines/agi/preagi_winnie.cpp



diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 72fd1bc..5141ab7 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -37,6 +37,7 @@
 #include "agi/agi.h"
 #include "agi/preagi.h"
 #include "agi/preagi_mickey.h"
+#include "agi/preagi_troll.h"
 #include "agi/preagi_winnie.h"
 #include "agi/wagparser.h"
 
@@ -197,12 +198,12 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
 		case GID_MICKEY:
 			*engine = new Agi::MickeyEngine(syst, gd);
 			break;
+		case GID_TROLL:
+			*engine = new Agi::TrollEngine(syst, gd);
+			break;
 		case GID_WINNIE:
 			*engine = new Agi::WinnieEngine(syst, gd);
 			break;
-		default:
-			*engine = new Agi::PreAgiEngine(syst, gd);
-			break;
 		}
 		break;
 	case Agi::GType_V1:
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index b1c9b53..5bbf072 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -30,11 +30,6 @@
 #include "agi/preagi.h"
 #include "agi/graphics.h"
 
-// preagi engines
-#include "agi/preagi_mickey.h"
-#include "agi/preagi_troll.h"
-#include "agi/preagi_winnie.h"
-
 namespace Agi {
 
 PreAgiEngine::PreAgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBase(syst, gameDesc) {
@@ -137,32 +132,6 @@ PreAgiEngine::~PreAgiEngine() {
 	delete _speakerStream;
 }
 
-
-Common::Error PreAgiEngine::go() {
-	setflag(fSoundOn, true);	// enable sound
-
-//
-// FIXME (Fingolfin asks): Why are Mickey and Troll standalone classes
-// instead of being subclasses of PreAgiEngine ?
-//
-
-	// run preagi engine main loop
-	switch (getGameID()) {
-	case GID_TROLL:
-		{
-			Troll *troll = new Troll(this);
-			troll->init();
-			troll->run();
-			delete troll;
-		}
-		break;
-	default:
-		error("Unknown preagi engine");
-		break;
-	}
-	return Common::kNoError;
-}
-
 int PreAgiEngine::rnd(int hi) {
 	return (_rnd->getRandomNumber(hi - 1) + 1);
 }
diff --git a/engines/agi/preagi.h b/engines/agi/preagi.h
index 1e752fb..4734b92 100644
--- a/engines/agi/preagi.h
+++ b/engines/agi/preagi.h
@@ -34,7 +34,6 @@ class PreAgiEngine : public AgiBase {
 	int _gameId;
 
 protected:
-	virtual Common::Error go();
 	void initialize();
 
 public:
diff --git a/engines/agi/preagi_troll.cpp b/engines/agi/preagi_troll.cpp
index 445a9e3..c2e2bef 100644
--- a/engines/agi/preagi_troll.cpp
+++ b/engines/agi/preagi_troll.cpp
@@ -31,32 +31,35 @@
 
 namespace Agi {
 
-Troll::Troll(PreAgiEngine* vm) : _vm(vm) {
+TrollEngine::TrollEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
+}
+
+TrollEngine::~TrollEngine() {
 }
 
 // User Interface
 
-void Troll::pressAnyKey(int col) {
-	_vm->drawStr(24, col, kColorDefault, IDS_TRO_PRESSANYKEY);
-	_vm->_gfx->doUpdate();
-	_vm->getSelection(kSelAnyKey);
+void TrollEngine::pressAnyKey(int col) {
+	drawStr(24, col, kColorDefault, IDS_TRO_PRESSANYKEY);
+	_gfx->doUpdate();
+	getSelection(kSelAnyKey);
 }
 
-void Troll::drawMenu(const char *szMenu, int iSel) {
-	_vm->clearTextArea();
-	_vm->drawStr(21, 0, kColorDefault, szMenu);
-	_vm->drawStr(22 + iSel, 0, kColorDefault, " *");
-	_vm->_gfx->doUpdate();
+void TrollEngine::drawMenu(const char *szMenu, int iSel) {
+	clearTextArea();
+	drawStr(21, 0, kColorDefault, szMenu);
+	drawStr(22 + iSel, 0, kColorDefault, " *");
+	_gfx->doUpdate();
 }
 
-bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
+bool TrollEngine::getMenuSel(const char *szMenu, int *iSel, int nSel) {
 	Common::Event event;
 	int y;
 
 	drawMenu(szMenu, *iSel);
 
-	while (!_vm->shouldQuit()) {
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
+	while (!shouldQuit()) {
+		while (_system->getEventManager()->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_RTL:
 			case Common::EVENT_QUIT:
@@ -117,8 +120,8 @@ bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
 				break;
 			}
 		}
-		_vm->_system->updateScreen();
-		_vm->_system->delayMillis(10);
+		_system->updateScreen();
+		_system->delayMillis(10);
 	}
 
 	return true;
@@ -126,18 +129,18 @@ bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
 
 // Graphics
 
-void Troll::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
-	_vm->_picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
+void TrollEngine::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
+	_picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
 
 	if (clr) {
-		_vm->clearScreen(0x0f, false);
-		_vm->_picture->clear();
+		clearScreen(0x0f, false);
+		_picture->clear();
 	}
 
-	_vm->_picture->setPictureData(_gameData + IDO_TRO_FRAMEPIC);
-	_vm->_picture->drawPicture();
+	_picture->setPictureData(_gameData + IDO_TRO_FRAMEPIC);
+	_picture->drawPicture();
 
-	_vm->_picture->setPictureData(_gameData + _pictureOffsets[iPic]);
+	_picture->setPictureData(_gameData + _pictureOffsets[iPic]);
 
 	int addFlag = 0;
 
@@ -145,26 +148,26 @@ void Troll::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
 		addFlag = kPicFTrollMode;
 
 	if (f3IsCont) {
-		_vm->_picture->setPictureFlags(kPicFf3Cont | addFlag);
+		_picture->setPictureFlags(kPicFf3Cont | addFlag);
 	} else {
-		_vm->_picture->setPictureFlags(kPicFf3Stop | addFlag);
+		_picture->setPictureFlags(kPicFf3Stop | addFlag);
 	}
 
-	_vm->_picture->drawPicture();
+	_picture->drawPicture();
 
-	_vm->_picture->showPic();
-	_vm->_gfx->doUpdate();
+	_picture->showPic();
+	_gfx->doUpdate();
 }
 
 // Game Logic
 
-void Troll::inventory() {
+void TrollEngine::inventory() {
 	char tmp[40];
 	int n;
 
-	_vm->clearScreen(0x07);
-	_vm->drawStr(1, 12, kColorDefault, IDS_TRO_TREASURE_0);
-	_vm->drawStr(2, 12, kColorDefault, IDS_TRO_TREASURE_1);
+	clearScreen(0x07);
+	drawStr(1, 12, kColorDefault, IDS_TRO_TREASURE_0);
+	drawStr(2, 12, kColorDefault, IDS_TRO_TREASURE_1);
 
 
 	for (int i = 0; i < IDI_TRO_MAX_TREASURE - _treasuresLeft; i++) {
@@ -172,36 +175,36 @@ void Troll::inventory() {
 
 		sprintf(tmp, " %2d ", i + 1);
 
-		_vm->drawStr(2 + i, 10, _items[n].bg << 4 | 0x0f,  tmp);
-		_vm->drawStr(2 + i, 14, _items[n].bg << 4 | _items[n].fg,  _items[n].name);
+		drawStr(2 + i, 10, _items[n].bg << 4 | 0x0f,  tmp);
+		drawStr(2 + i, 14, _items[n].bg << 4 | _items[n].fg,  _items[n].name);
 	}
 
 
 	switch (_treasuresLeft) {
 	case 1:
 		sprintf(tmp, IDS_TRO_TREASURE_5, _treasuresLeft);
-		_vm->drawStr(20, 10, kColorDefault, tmp);
+		drawStr(20, 10, kColorDefault, tmp);
 		break;
 	case 0:
-		_vm->drawStr(20, 1, kColorDefault, IDS_TRO_TREASURE_6);
+		drawStr(20, 1, kColorDefault, IDS_TRO_TREASURE_6);
 		break;
 	case IDI_TRO_MAX_TREASURE:
-		_vm->drawStr(3, 17, kColorDefault, IDS_TRO_TREASURE_2);
+		drawStr(3, 17, kColorDefault, IDS_TRO_TREASURE_2);
 	default:
 		sprintf(tmp, IDS_TRO_TREASURE_4, _treasuresLeft);
-		_vm->drawStr(20, 10, kColorDefault, tmp);
+		drawStr(20, 10, kColorDefault, tmp);
 		break;
 	}
 
 	pressAnyKey(6);
 }
 
-void Troll::waitAnyKeyIntro() {
+void TrollEngine::waitAnyKeyIntro() {
 	Common::Event event;
 	int iMsg = 0;
 
-	while (!_vm->shouldQuit()) {
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
+	while (!shouldQuit()) {
+		while (_system->getEventManager()->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_RTL:
 			case Common::EVENT_QUIT:
@@ -217,26 +220,26 @@ void Troll::waitAnyKeyIntro() {
 		case 200:
 			iMsg = 0;
 		case 0:
-			_vm->drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_2);
-			_vm->_gfx->doUpdate();
+			drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_2);
+			_gfx->doUpdate();
 			break;
 		case 100:
-			_vm->drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_3);
-			_vm->_gfx->doUpdate();
+			drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_3);
+			_gfx->doUpdate();
 			break;
 		}
 
 		iMsg++;
 
-		_vm->_system->updateScreen();
-		_vm->_system->delayMillis(10);
+		_system->updateScreen();
+		_system->delayMillis(10);
 	}
 }
 
-void Troll::credits() {
-	_vm->clearScreen(0x07);
+void TrollEngine::credits() {
+	clearScreen(0x07);
 
-	_vm->drawStr(1, 2, kColorDefault, IDS_TRO_CREDITS_0);
+	drawStr(1, 2, kColorDefault, IDS_TRO_CREDITS_0);
 
 	int color = 10;
 	char str[2];
@@ -245,49 +248,49 @@ void Troll::credits() {
 
 	for (uint i = 0; i < strlen(IDS_TRO_CREDITS_1); i++) {
 		str[0] = IDS_TRO_CREDITS_1[i];
-		_vm->drawStr(7, 19 + i, color++, str);
+		drawStr(7, 19 + i, color++, str);
 		if (color > 15)
 			color = 9;
 	}
 
-	_vm->drawStr(8, 19, kColorDefault, IDS_TRO_CREDITS_2);
+	drawStr(8, 19, kColorDefault, IDS_TRO_CREDITS_2);
 
-	_vm->drawStr(13, 11, 9, IDS_TRO_CREDITS_3);
-	_vm->drawStr(15, 8, 10, IDS_TRO_CREDITS_4);
-	_vm->drawStr(17, 7, 12, IDS_TRO_CREDITS_5);
-	_vm->drawStr(19, 2, 14, IDS_TRO_CREDITS_6);
+	drawStr(13, 11, 9, IDS_TRO_CREDITS_3);
+	drawStr(15, 8, 10, IDS_TRO_CREDITS_4);
+	drawStr(17, 7, 12, IDS_TRO_CREDITS_5);
+	drawStr(19, 2, 14, IDS_TRO_CREDITS_6);
 
-	_vm->_gfx->doUpdate();
+	_gfx->doUpdate();
 
 	pressAnyKey();
 }
 
-void Troll::tutorial() {
+void TrollEngine::tutorial() {
 	bool done = false;
 	int iSel = 0;
 	//char szTreasure[16] = {0};
 
-	while (!_vm->shouldQuit()) {
-		_vm->clearScreen(0xFF);
+	while (!shouldQuit()) {
+		clearScreen(0xFF);
 
-		_vm->printStr(IDS_TRO_TUTORIAL_0);
-		_vm->getSelection(kSelSpace);
+		printStr(IDS_TRO_TUTORIAL_0);
+		getSelection(kSelSpace);
 
-		_vm->clearScreen(0x55);
-		_vm->setDefaultTextColor(0x0F);
+		clearScreen(0x55);
+		setDefaultTextColor(0x0F);
 
 		done = false;
-		while (!done && !_vm->shouldQuit()) {
+		while (!done && !shouldQuit()) {
 			getMenuSel(IDS_TRO_TUTORIAL_1, &iSel, IDI_TRO_MAX_OPTION);
 
 			switch (iSel) {
 			case IDI_TRO_SEL_OPTION_1:
-				_vm->clearScreen(0x22, false);
-				_vm->_gfx->doUpdate();
+				clearScreen(0x22, false);
+				_gfx->doUpdate();
 				break;
 			case IDI_TRO_SEL_OPTION_2:
-				_vm->clearScreen(0x00, false);
-				_vm->_gfx->doUpdate();
+				clearScreen(0x00, false);
+				_gfx->doUpdate();
 				break;
 			case IDI_TRO_SEL_OPTION_3:
 				done = true;
@@ -296,102 +299,102 @@ void Troll::tutorial() {
 		}
 
 		// do you need more practice ?
-		_vm->clearScreen(0x4F);
-		_vm->drawStr(7, 4, kColorDefault, IDS_TRO_TUTORIAL_5);
-		_vm->drawStr(9, 4, kColorDefault, IDS_TRO_TUTORIAL_6);
-		_vm->_gfx->doUpdate();
+		clearScreen(0x4F);
+		drawStr(7, 4, kColorDefault, IDS_TRO_TUTORIAL_5);
+		drawStr(9, 4, kColorDefault, IDS_TRO_TUTORIAL_6);
+		_gfx->doUpdate();
 
-		if (!_vm->getSelection(kSelYesNo))
+		if (!getSelection(kSelYesNo))
 			break;
 	}
 
 	// show info texts
-	_vm->clearScreen(0x5F);
-	_vm->drawStr(4, 1, kColorDefault, IDS_TRO_TUTORIAL_7);
-	_vm->drawStr(5, 1, kColorDefault, IDS_TRO_TUTORIAL_8);
-	_vm->_gfx->doUpdate();
+	clearScreen(0x5F);
+	drawStr(4, 1, kColorDefault, IDS_TRO_TUTORIAL_7);
+	drawStr(5, 1, kColorDefault, IDS_TRO_TUTORIAL_8);
+	_gfx->doUpdate();
 	pressAnyKey();
 
-	_vm->clearScreen(0x2F);
-	_vm->drawStr(6, 1, kColorDefault, IDS_TRO_TUTORIAL_9);
-	_vm->_gfx->doUpdate();
+	clearScreen(0x2F);
+	drawStr(6, 1, kColorDefault, IDS_TRO_TUTORIAL_9);
+	_gfx->doUpdate();
 	pressAnyKey();
 
-	_vm->clearScreen(0x19);
-	_vm->drawStr(7, 1, kColorDefault, IDS_TRO_TUTORIAL_10);
-	_vm->drawStr(8, 1, kColorDefault, IDS_TRO_TUTORIAL_11);
-	_vm->_gfx->doUpdate();
+	clearScreen(0x19);
+	drawStr(7, 1, kColorDefault, IDS_TRO_TUTORIAL_10);
+	drawStr(8, 1, kColorDefault, IDS_TRO_TUTORIAL_11);
+	_gfx->doUpdate();
 	pressAnyKey();
 
-	_vm->clearScreen(0x6E);
-	_vm->drawStr(9, 1, kColorDefault, IDS_TRO_TUTORIAL_12);
-	_vm->drawStr(10, 1, kColorDefault, IDS_TRO_TUTORIAL_13);
-	_vm->_gfx->doUpdate();
+	clearScreen(0x6E);
+	drawStr(9, 1, kColorDefault, IDS_TRO_TUTORIAL_12);
+	drawStr(10, 1, kColorDefault, IDS_TRO_TUTORIAL_13);
+	_gfx->doUpdate();
 	pressAnyKey();
 
-	_vm->clearScreen(0x4C);
-	_vm->drawStr(11, 1, kColorDefault, IDS_TRO_TUTORIAL_14);
-	_vm->drawStr(12, 1, kColorDefault, IDS_TRO_TUTORIAL_15);
-	_vm->_gfx->doUpdate();
+	clearScreen(0x4C);
+	drawStr(11, 1, kColorDefault, IDS_TRO_TUTORIAL_14);
+	drawStr(12, 1, kColorDefault, IDS_TRO_TUTORIAL_15);
+	_gfx->doUpdate();
 	pressAnyKey();
 
-	_vm->clearScreen(0x5D);
-	_vm->drawStr(13, 1, kColorDefault, IDS_TRO_TUTORIAL_16);
-	_vm->drawStr(14, 1, kColorDefault, IDS_TRO_TUTORIAL_17);
-	_vm->drawStr(15, 1, kColorDefault, IDS_TRO_TUTORIAL_18);
-	_vm->_gfx->doUpdate();
+	clearScreen(0x5D);
+	drawStr(13, 1, kColorDefault, IDS_TRO_TUTORIAL_16);
+	drawStr(14, 1, kColorDefault, IDS_TRO_TUTORIAL_17);
+	drawStr(15, 1, kColorDefault, IDS_TRO_TUTORIAL_18);
+	_gfx->doUpdate();
 	pressAnyKey();
 
 	// show treasures
-	_vm->clearScreen(0x2A);
-	_vm->drawStr(2, 1, kColorDefault, IDS_TRO_TUTORIAL_19);
+	clearScreen(0x2A);
+	drawStr(2, 1, kColorDefault, IDS_TRO_TUTORIAL_19);
 	for (int i = 0; i < IDI_TRO_MAX_TREASURE; i++)
-		_vm->drawStr(19 - i, 11, kColorDefault, _items[i].name);
+		drawStr(19 - i, 11, kColorDefault, _items[i].name);
 
-	_vm->_gfx->doUpdate();
+	_gfx->doUpdate();
 
 	pressAnyKey();
 }
 
-void Troll::intro() {
+void TrollEngine::intro() {
 	// sierra on-line presents
-	_vm->clearScreen(0x2F);
-	_vm->drawStr(9, 10, kColorDefault, IDS_TRO_INTRO_0);
-	_vm->drawStr(14, 15, kColorDefault, IDS_TRO_INTRO_1);
-	_vm->_gfx->doUpdate();
-	_vm->_system->updateScreen();
-	_vm->_system->delayMillis(3200);
+	clearScreen(0x2F);
+	drawStr(9, 10, kColorDefault, IDS_TRO_INTRO_0);
+	drawStr(14, 15, kColorDefault, IDS_TRO_INTRO_1);
+	_gfx->doUpdate();
+	_system->updateScreen();
+	_system->delayMillis(3200);
 
 	CursorMan.showMouse(true);
 
 	// Draw logo
-	_vm->setDefaultTextColor(0x0f);
+	setDefaultTextColor(0x0f);
 	drawPic(45, false, true);
-	_vm->_gfx->doUpdate();
+	_gfx->doUpdate();
 
 	// wait for keypress and alternate message
 	waitAnyKeyIntro();
 
 	// have you played this game before?
-	_vm->drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_4);
-	_vm->drawStr(23, 6, kColorDefault, IDS_TRO_INTRO_5);
-	_vm->_gfx->doUpdate();
+	drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_4);
+	drawStr(23, 6, kColorDefault, IDS_TRO_INTRO_5);
+	_gfx->doUpdate();
 
-	if (!_vm->getSelection(kSelYesNo))
+	if (!getSelection(kSelYesNo))
 		tutorial();
 
 	credits();
 }
 
-void Troll::gameOver() {
+void TrollEngine::gameOver() {
 	// We do a check to see if the game should quit. Without this, the game show the picture, plays the
 	// music, and then quits. So if the game is quitting, we shouldn't run the "game over" part.
-	if (_vm->shouldQuit())
+	if (shouldQuit())
 		return;
 
 	char szMoves[40];
 
-	_vm->clearTextArea();
+	clearTextArea();
 	drawPic(42, true, true);
 
 	playTune(4, 25);
@@ -400,19 +403,19 @@ void Troll::gameOver() {
 
 	printUserMessage(33);
 
-	_vm->clearTextArea();
+	clearTextArea();
 
 	drawPic(46, true, true);
 
 	sprintf(szMoves, IDS_TRO_GAMEOVER_0, _moves);
-	_vm->drawStr(21, 1, kColorDefault, szMoves);
-	_vm->drawStr(22, 1, kColorDefault, IDS_TRO_GAMEOVER_1);
-	_vm->_gfx->doUpdate();
+	drawStr(21, 1, kColorDefault, szMoves);
+	drawStr(22, 1, kColorDefault, IDS_TRO_GAMEOVER_1);
+	_gfx->doUpdate();
 
 	pressAnyKey();
 }
 
-void Troll::drawTroll() {
+void TrollEngine::drawTroll() {
 	for (int i = 0; i < IDI_TRO_NUM_NONTROLL; i++)
 		if (_currentRoom == _nonTrollRooms[i]) {
 			_isTrollAway = true;
@@ -422,14 +425,14 @@ void Troll::drawTroll() {
 	drawPic(43, false, false, true);
 }
 
-int Troll::drawRoom(char *menu) {
+int TrollEngine::drawRoom(char *menu) {
 	int n = 0;
 	bool contFlag = false;
 
 	if (_currentRoom == 1) {
-		_vm->_picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
-		_vm->clearScreen(0x00, false);
-		_vm->_picture->clear();
+		_picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
+		clearScreen(0x00, false);
+		_picture->clear();
 	} else {
 
 		if (_currentRoom != 42) {
@@ -439,7 +442,7 @@ int Troll::drawRoom(char *menu) {
 		}
 
 		drawPic(_currentRoom, contFlag, true);
-		_vm->_gfx->doUpdate();
+		_gfx->doUpdate();
 
 		if (_currentRoom == 42) {
 			drawPic(44, false, false); // don't clear
@@ -450,7 +453,7 @@ int Troll::drawRoom(char *menu) {
 		}
 	}
 
-	_vm->_gfx->doUpdate();
+	_gfx->doUpdate();
 
 	char tmp[10];
 	strncat(menu, (char*)_gameData + _locMessagesIdx[_currentRoom], 39);
@@ -469,7 +472,7 @@ int Troll::drawRoom(char *menu) {
 	return n;
 }
 
-void Troll::playTune(int tune, int len) {
+void TrollEngine::playTune(int tune, int len) {
 	if (!_soundOn)
 		return;
 
@@ -482,34 +485,34 @@ void Troll::playTune(int tune, int len) {
 		duration = READ_LE_UINT16(_gameData + ptr);
 		ptr += 2;
 
-		_vm->playNote(freq, duration);
+		playNote(freq, duration);
 	}
 }
 
-void Troll::pickupTreasure(int treasureId) {
+void TrollEngine::pickupTreasure(int treasureId) {
 	char tmp[40];
 
 	_inventory[IDI_TRO_MAX_TREASURE - _treasuresLeft] = treasureId;
 
 	if (_currentRoom != 24) {
-		_vm->clearTextArea();
+		clearTextArea();
 		drawPic(_currentRoom, false, true);
-		_vm->_gfx->doUpdate();
+		_gfx->doUpdate();
 	}
 
 	printUserMessage(treasureId + 16);
 
-	_vm->clearTextArea();
+	clearTextArea();
 
 	_treasuresLeft--;
 
 	switch (_treasuresLeft) {
 	case 1:
-		_vm->drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_7);
+		drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_7);
 		break;
 	case 0:
-		_vm->drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_8);
-		_vm->drawStr(23, 4, kColorDefault, IDS_TRO_TREASURE_9);
+		drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_8);
+		drawStr(23, 4, kColorDefault, IDS_TRO_TREASURE_9);
 
 		_roomStates[6] = 1;
 
@@ -517,20 +520,20 @@ void Troll::pickupTreasure(int treasureId) {
 		break;
 	default:
 		sprintf(tmp, IDS_TRO_TREASURE_3, _treasuresLeft);
-		_vm->drawStr(22, 1, kColorDefault, tmp);
+		drawStr(22, 1, kColorDefault, tmp);
 		break;
 	}
 
 	pressAnyKey();
 }
 
-void Troll::printUserMessage(int msgId) {
+void TrollEngine::printUserMessage(int msgId) {
 	int i;
 
-	_vm->clearTextArea();
+	clearTextArea();
 
 	for (i = 0; i < _userMessages[msgId - 1].num; i++) {
-		_vm->drawStr(21 + i, 1, kColorDefault, _userMessages[msgId - 1].msg[i]);
+		drawStr(21 + i, 1, kColorDefault, _userMessages[msgId - 1].msg[i]);
 	}
 
 	if (msgId == 34) {
@@ -540,7 +543,7 @@ void Troll::printUserMessage(int msgId) {
 	pressAnyKey();
 }
 
-void Troll::gameLoop() {
+void TrollEngine::gameLoop() {
 	bool done = false;
 	char menu[160+5];
 	int currentOption, numberOfOptions;
@@ -559,7 +562,7 @@ void Troll::gameLoop() {
 
 	memset(_inventory, 0, sizeof(_inventory));
 
-	while (!done && !_vm->shouldQuit()) {
+	while (!done && !shouldQuit()) {
 		*menu = 0;
 
 		currentOption = 0;
@@ -589,7 +592,7 @@ void Troll::gameLoop() {
 			if (_currentRoom < 6 || _treasuresLeft == 0) {
 				_isTrollAway = true;
 			} else { // make odd 1:3
-				_isTrollAway = (_vm->rnd(3) != 2);
+				_isTrollAway = (rnd(3) != 2);
 			}
 			break;
 		case OT_GET:
@@ -634,7 +637,7 @@ void Troll::gameLoop() {
 
 }
 
-void Troll::fillOffsets() {
+void TrollEngine::fillOffsets() {
 	int i;
 
 	for (i = 0; i < IDI_TRO_PICNUM; i++)
@@ -721,8 +724,8 @@ void Troll::fillOffsets() {
 
 // Init
 
-void Troll::init() {
-	_vm->_picture->setPictureVersion(AGIPIC_V15);
+void TrollEngine::init() {
+	_picture->setPictureVersion(AGIPIC_V15);
 	//SetScreenPar(320, 200, (char*)ibm_fontdata);
 
 	const int gaps[] = { 0x3A40,  0x4600,  0x4800,  0x5800,  0x5a00,  0x6a00,
@@ -762,12 +765,16 @@ void Troll::init() {
 	fillOffsets();
 }
 
-void Troll::run() {
-	while (!_vm->shouldQuit()) {
+Common::Error TrollEngine::go() {
+	init();
+
+	while (!shouldQuit()) {
 		intro();
 		gameLoop();
 		gameOver();
 	}
+
+	return Common::kNoError;
 }
 
 } // End of namespace Agi
diff --git a/engines/agi/preagi_troll.h b/engines/agi/preagi_troll.h
index d9a9950..c14a787 100644
--- a/engines/agi/preagi_troll.h
+++ b/engines/agi/preagi_troll.h
@@ -157,16 +157,14 @@ struct Item {
 	char name[16];
 };
 
-class Troll {
+class TrollEngine : public PreAgiEngine {
 public:
-	Troll(PreAgiEngine *vm);
+	TrollEngine(OSystem *syst, const AGIGameDescription *gameDesc);
+	~TrollEngine();
 
-	void init();
-	void run();
+	Common::Error go();
 
 private:
-	PreAgiEngine *_vm;
-
 	int _roomPicture;
 	int _treasuresLeft;
 	int _currentRoom;
@@ -180,6 +178,7 @@ private:
 
 	byte *_gameData;
 
+	void init();
 	void intro();
 	void drawPic(int iPic, bool f3IsCont, bool clear, bool troll = false);
 	void drawTroll();
@@ -205,9 +204,7 @@ private:
 
 	void fillOffsets();
 
-private:
 	// These are come from game data
-
 	int _pictureOffsets[IDI_TRO_PICNUM];
 	int _roomPicStartIdx[IDI_TRO_NUM_NUMROOMS];
 	int _roomPicDeltas[IDI_TRO_NUM_NUMROOMS];
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 7b86ca4..016f268 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -1312,6 +1312,8 @@ WinnieEngine::~WinnieEngine() {
 }
 
 void WinnieEngine::init() {
+	setflag(fSoundOn, true); // enable sound
+
 	memset(&_gameStateWinnie, 0, sizeof(_gameStateWinnie));
 	_gameStateWinnie.fSound = 1;
 	_gameStateWinnie.nObjMiss = IDI_WTP_MAX_OBJ_MISSING;


Commit: 62aabc57e446efcf15353a49209ce1d99c567fa4
    https://github.com/scummvm/scummvm/commit/62aabc57e446efcf15353a49209ce1d99c567fa4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2011-08-15T08:55:03-07:00

Commit Message:
AGI: Reorganize the PreAGI code a bit

Changed paths:
  R engines/agi/preagi_common.cpp
  R engines/agi/preagi_common.h
    engines/agi/module.mk
    engines/agi/preagi.cpp
    engines/agi/preagi.h
    engines/agi/preagi_winnie.cpp



diff --git a/engines/agi/module.mk b/engines/agi/module.mk
index cd901c5..68d86f7 100644
--- a/engines/agi/module.mk
+++ b/engines/agi/module.mk
@@ -25,7 +25,6 @@ MODULE_OBJS := \
 	op_test.o \
 	picture.o \
 	preagi.o \
-	preagi_common.o \
 	preagi_mickey.o \
 	preagi_troll.o \
 	preagi_winnie.o \
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index 5bbf072..065b93e 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -22,13 +22,13 @@
 
 #include "common/config-manager.h"
 #include "common/debug-channels.h"
+#include "common/events.h"
 #include "common/random.h"
 #include "common/textconsole.h"
 
-#include "audio/mididrv.h"
-
 #include "agi/preagi.h"
 #include "agi/graphics.h"
+#include "agi/keyboard.h"
 
 namespace Agi {
 
@@ -54,22 +54,6 @@ PreAgiEngine::PreAgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) :
 }
 
 void PreAgiEngine::initialize() {
-	// TODO: Some sound emulation modes do not fit our current music
-	//       drivers, and I'm not sure what they are. For now, they might
-	//       as well be called "PC Speaker" and "Not PC Speaker".
-
-	switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK|MDT_PCJR))) {
-	case MT_PCSPK:
-		_soundemu = SOUND_EMU_PC;
-		break;
-	case MT_PCJR:
-		_soundemu = SOUND_EMU_PCJR;
-		break;
-	default:
-		_soundemu = SOUND_EMU_NONE;
-		break;
-	}
-
 	if (ConfMan.hasKey("render_mode")) {
 		_renderMode = Common::parseRenderMode(ConfMan.get("render_mode").c_str());
 	} else if (ConfMan.hasKey("platform")) {
@@ -87,7 +71,6 @@ void PreAgiEngine::initialize() {
 	}
 
 	_gfx = new GfxMgr(this);
-	_sound = new SoundMgr(this, _mixer);
 	_picture = new PictureMgr(this, _gfx);
 
 	_gfx->initMachine();
@@ -108,7 +91,6 @@ void PreAgiEngine::initialize() {
 	_game.lineMinPrint = 0; // hardcoded
 
 	_gfx->initVideo();
-	_sound->initSound();
 
 	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
@@ -123,8 +105,6 @@ void PreAgiEngine::initialize() {
 		memset(&_game.dirPic[i], 0, sizeof(struct AgiDir));
 		memset(&_game.dirSound[i], 0, sizeof(struct AgiDir));
 	}
-
-	debugC(2, kDebugLevelMain, "Init sound");
 }
 
 PreAgiEngine::~PreAgiEngine() {
@@ -136,4 +116,176 @@ int PreAgiEngine::rnd(int hi) {
 	return (_rnd->getRandomNumber(hi - 1) + 1);
 }
 
+// Screen functions
+void PreAgiEngine::clearScreen(int attr, bool overrideDefault) {
+	if (overrideDefault)
+		_defaultColor = attr;
+
+	_gfx->clearScreen((attr & 0xF0) / 0x10);
+}
+
+void PreAgiEngine::clearGfxScreen(int attr) {
+	_gfx->drawRectangle(0, 0, GFX_WIDTH - 1, IDI_MAX_ROW_PIC * 8 -1, (attr & 0xF0) / 0x10);
+}
+
+// String functions
+
+void PreAgiEngine::drawStr(int row, int col, int attr, const char *buffer) {
+	int code;
+
+	if (attr == kColorDefault)
+		attr = _defaultColor;
+
+	for (int iChar = 0; iChar < (int)strlen(buffer); iChar++) {
+		code = buffer[iChar];
+
+		switch (code) {
+		case '\n':
+		case 0x8D:
+			if (++row == 200 / 8) return;
+			col = 0;
+			break;
+
+		case '|':
+			// swap attribute nibbles
+			break;
+
+		default:
+			_gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, getGameID() == GID_MICKEY ? mickey_fontdata : ibm_fontdata);
+
+			if (++col == 320 / 8) {
+				col = 0;
+				if (++row == 200 / 8) return;
+			}
+		}
+	}
+}
+
+void PreAgiEngine::drawStrMiddle(int row, int attr, const char *buffer) {
+	int col = (25 / 2) - (strlen(buffer) / 2);	// 25 = 320 / 8 (maximum column)
+	drawStr(row, col, attr, buffer);
+}
+
+void PreAgiEngine::clearTextArea() {
+	int start = IDI_MAX_ROW_PIC;
+
+	if (getGameID() == GID_TROLL)
+		start = 21;
+
+	for (int row = start; row < 200 / 8; row++) {
+		clearRow(row);
+	}
+}
+
+void PreAgiEngine::clearRow(int row) {
+	drawStr(row, 0, IDA_DEFAULT, "                                        ");	// 40 spaces
+}
+
+void PreAgiEngine::printStr(const char* szMsg) {
+	clearTextArea();
+	drawStr(21, 0, IDA_DEFAULT, szMsg);
+	_gfx->doUpdate();
+	_system->updateScreen();
+}
+
+void PreAgiEngine::XOR80(char *buffer) {
+	for (size_t i = 0; i < strlen(buffer); i++)
+		if (buffer[i] & 0x80)
+			buffer[i] ^= 0x80;
+}
+
+void PreAgiEngine::printStrXOR(char *szMsg) {
+	XOR80(szMsg);
+	printStr(szMsg);
+}
+
+// Input functions
+
+int PreAgiEngine::getSelection(SelectionTypes type) {
+	Common::Event event;
+
+	while (!shouldQuit()) {
+		while (_eventMan->pollEvent(event)) {
+			switch (event.type) {
+			case Common::EVENT_RTL:
+			case Common::EVENT_QUIT:
+				return 0;
+			case Common::EVENT_RBUTTONUP:
+				return 0;
+			case Common::EVENT_LBUTTONUP:
+				if (type == kSelYesNo || type == kSelAnyKey)
+					return 1;
+			case Common::EVENT_KEYDOWN:
+				if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
+					_console->attach();
+					_console->onFrame();
+					//FIXME: If not cleared, clicking again will start the console
+					event.kbd.keycode = Common::KEYCODE_INVALID;
+					event.kbd.flags = 0;
+					continue;
+				}
+				switch (event.kbd.keycode) {
+				case Common::KEYCODE_y:
+					if (type == kSelYesNo)
+						return 1;
+				case Common::KEYCODE_n:
+					if (type == kSelYesNo)
+						return 0;
+				case Common::KEYCODE_ESCAPE:
+					if (type == kSelNumber || type == kSelAnyKey)
+						return 0;
+				case Common::KEYCODE_1:
+				case Common::KEYCODE_2:
+				case Common::KEYCODE_3:
+				case Common::KEYCODE_4:
+				case Common::KEYCODE_5:
+				case Common::KEYCODE_6:
+				case Common::KEYCODE_7:
+				case Common::KEYCODE_8:
+				case Common::KEYCODE_9:
+					if (type == kSelNumber)
+						return event.kbd.keycode - Common::KEYCODE_1 + 1;
+				case Common::KEYCODE_SPACE:
+					if (type == kSelSpace)
+						return 1;
+				case Common::KEYCODE_BACKSPACE:
+					if (type == kSelBackspace)
+						return 0;
+				default:
+					if (event.kbd.flags & Common::KBD_CTRL)
+						break;
+					if (type == kSelYesNo) {
+						return 2;
+					} else if (type == kSelNumber) {
+						return 10;
+					} else if (type == kSelAnyKey || type == kSelBackspace) {
+						return 1;
+					}
+				}
+				break;
+			default:
+				break;
+			}
+		}
+		_system->updateScreen();
+		_system->delayMillis(10);
+	}
+	return 0;
+}
+
+void PreAgiEngine::playNote(int16 frequency, int32 length) {
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length);
+	waitForTimer(length);
+}
+
+void PreAgiEngine::waitForTimer(int msec_delay) {
+	uint32 start_time = _system->getMillis();
+
+	while (_system->getMillis() < start_time + msec_delay) {
+		_gfx->doUpdate();
+		_system->updateScreen();
+		_system->delayMillis(10);
+	}
+}
+
 } // End of namespace Agi
diff --git a/engines/agi/preagi.h b/engines/agi/preagi.h
index 4734b92..d0aea0e 100644
--- a/engines/agi/preagi.h
+++ b/engines/agi/preagi.h
@@ -24,19 +24,36 @@
 #define AGI_PREAGI_H
 
 #include "agi/agi.h"
-#include "agi/preagi_common.h"
 
 #include "audio/softsynth/pcspk.h"
 
 namespace Agi {
 
+// default attributes
+#define IDA_DEFAULT		0x0F
+#define IDA_DEFAULT_REV	0xF0
+
+#define IDI_SND_OSCILLATOR_FREQUENCY	1193180
+#define IDI_SND_TIMER_RESOLUTION		0.0182
+
+#define kColorDefault 0x1337
+
+#define IDI_MAX_ROW_PIC	20
+
+enum SelectionTypes {
+	kSelYesNo,
+	kSelNumber,
+	kSelSpace,
+	kSelAnyKey,
+	kSelBackspace
+};
+
 class PreAgiEngine : public AgiBase {
 	int _gameId;
 
 protected:
 	void initialize();
 
-public:
 	void pollTimer() {}
 	int getKeypress() { return 0; }
 	bool isKeypress() { return false; }
diff --git a/engines/agi/preagi_common.cpp b/engines/agi/preagi_common.cpp
deleted file mode 100644
index d437dc0..0000000
--- a/engines/agi/preagi_common.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/* 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.
- *
- */
-
-#include "agi/preagi.h"
-#include "agi/graphics.h"
-#include "agi/keyboard.h"
-
-#include "agi/preagi_common.h"
-
-#include "common/events.h"
-
-namespace Agi {
-
-// Screen functions
-void PreAgiEngine::clearScreen(int attr, bool overrideDefault) {
-	if (overrideDefault)
-		_defaultColor = attr;
-
-	_gfx->clearScreen((attr & 0xF0) / 0x10);
-}
-
-void PreAgiEngine::clearGfxScreen(int attr) {
-	_gfx->drawRectangle(0, 0, GFX_WIDTH - 1, IDI_MAX_ROW_PIC * 8 -1, (attr & 0xF0) / 0x10);
-}
-
-// String functions
-
-void PreAgiEngine::drawStr(int row, int col, int attr, const char *buffer) {
-	int code;
-
-	if (attr == kColorDefault)
-		attr = _defaultColor;
-
-	for (int iChar = 0; iChar < (int)strlen(buffer); iChar++) {
-		code = buffer[iChar];
-
-		switch (code) {
-		case '\n':
-		case 0x8D:
-			if (++row == 200 / 8) return;
-			col = 0;
-			break;
-
-		case '|':
-			// swap attribute nibbles
-			break;
-
-		default:
-			_gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, getGameID() == GID_MICKEY ? mickey_fontdata : ibm_fontdata);
-
-			if (++col == 320 / 8) {
-				col = 0;
-				if (++row == 200 / 8) return;
-			}
-		}
-	}
-}
-
-void PreAgiEngine::drawStrMiddle(int row, int attr, const char *buffer) {
-	int col = (25 / 2) - (strlen(buffer) / 2);	// 25 = 320 / 8 (maximum column)
-	drawStr(row, col, attr, buffer);
-}
-
-void PreAgiEngine::clearTextArea() {
-	int start = IDI_MAX_ROW_PIC;
-
-	if (getGameID() == GID_TROLL)
-		start = 21;
-
-	for (int row = start; row < 200 / 8; row++) {
-		clearRow(row);
-	}
-}
-
-void PreAgiEngine::clearRow(int row) {
-	drawStr(row, 0, IDA_DEFAULT, "                                        ");	// 40 spaces
-}
-
-void PreAgiEngine::printStr(const char* szMsg) {
-	clearTextArea();
-	drawStr(21, 0, IDA_DEFAULT, szMsg);
-	_gfx->doUpdate();
-	_system->updateScreen();
-}
-
-void PreAgiEngine::XOR80(char *buffer) {
-	for (size_t i = 0; i < strlen(buffer); i++)
-		if (buffer[i] & 0x80)
-			buffer[i] ^= 0x80;
-}
-
-void PreAgiEngine::printStrXOR(char *szMsg) {
-	XOR80(szMsg);
-	printStr(szMsg);
-}
-
-// Input functions
-
-int PreAgiEngine::getSelection(SelectionTypes type) {
-	Common::Event event;
-
-	while (!shouldQuit()) {
-		while (_eventMan->pollEvent(event)) {
-			switch (event.type) {
-			case Common::EVENT_RTL:
-			case Common::EVENT_QUIT:
-				return 0;
-			case Common::EVENT_RBUTTONUP:
-				return 0;
-			case Common::EVENT_LBUTTONUP:
-				if (type == kSelYesNo || type == kSelAnyKey)
-					return 1;
-			case Common::EVENT_KEYDOWN:
-				if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
-					_console->attach();
-					_console->onFrame();
-					//FIXME: If not cleared, clicking again will start the console
-					event.kbd.keycode = Common::KEYCODE_INVALID;
-					event.kbd.flags = 0;
-					continue;
-				}
-				switch (event.kbd.keycode) {
-				case Common::KEYCODE_y:
-					if (type == kSelYesNo)
-						return 1;
-				case Common::KEYCODE_n:
-					if (type == kSelYesNo)
-						return 0;
-				case Common::KEYCODE_ESCAPE:
-					if (type == kSelNumber || type == kSelAnyKey)
-						return 0;
-				case Common::KEYCODE_1:
-				case Common::KEYCODE_2:
-				case Common::KEYCODE_3:
-				case Common::KEYCODE_4:
-				case Common::KEYCODE_5:
-				case Common::KEYCODE_6:
-				case Common::KEYCODE_7:
-				case Common::KEYCODE_8:
-				case Common::KEYCODE_9:
-					if (type == kSelNumber)
-						return event.kbd.keycode - Common::KEYCODE_1 + 1;
-				case Common::KEYCODE_SPACE:
-					if (type == kSelSpace)
-						return 1;
-				case Common::KEYCODE_BACKSPACE:
-					if (type == kSelBackspace)
-						return 0;
-				default:
-					if (event.kbd.flags & Common::KBD_CTRL)
-						break;
-					if (type == kSelYesNo) {
-						return 2;
-					} else if (type == kSelNumber) {
-						return 10;
-					} else if (type == kSelAnyKey || type == kSelBackspace) {
-						return 1;
-					}
-				}
-				break;
-			default:
-				break;
-			}
-		}
-		_system->updateScreen();
-		_system->delayMillis(10);
-	}
-	return 0;
-}
-
-void PreAgiEngine::playNote(int16 frequency, int32 length) {
-	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length);
-	waitForTimer(length);
-}
-
-void PreAgiEngine::waitForTimer(int msec_delay) {
-	uint32 start_time = _system->getMillis();
-
-	while (_system->getMillis() < start_time + msec_delay) {
-		_gfx->doUpdate();
-		_system->updateScreen();
-		_system->delayMillis(10);
-	}
-}
-
-}
diff --git a/engines/agi/preagi_common.h b/engines/agi/preagi_common.h
deleted file mode 100644
index a557f69..0000000
--- a/engines/agi/preagi_common.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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.
- *
- */
-
-
-
-#ifndef AGI_PREAGI_COMMON_H
-#define AGI_PREAGI_COMMON_H
-
-namespace Agi {
-
-// default attributes
-#define IDA_DEFAULT		0x0F
-#define IDA_DEFAULT_REV	0xF0
-
-#define IDI_SND_OSCILLATOR_FREQUENCY	1193180
-#define IDI_SND_TIMER_RESOLUTION		0.0182
-
-#define kColorDefault 0x1337
-
-#define IDI_MAX_ROW_PIC	20
-
-enum SelectionTypes {
-	kSelYesNo,
-	kSelNumber,
-	kSelSpace,
-	kSelAnyKey,
-	kSelBackspace
-};
-
-} // End of namespace Agi
-
-#endif
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 016f268..2c7f50c 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -31,6 +31,8 @@
 #include "common/savefile.h"
 #include "common/textconsole.h"
 
+#include "audio/mididrv.h"
+
 namespace Agi {
 
 void WinnieEngine::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
@@ -1312,6 +1314,22 @@ WinnieEngine::~WinnieEngine() {
 }
 
 void WinnieEngine::init() {
+	// Initialize sound
+
+	switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK|MDT_PCJR))) {
+	case MT_PCSPK:
+		_soundemu = SOUND_EMU_PC;
+		break;
+	case MT_PCJR:
+		_soundemu = SOUND_EMU_PCJR;
+		break;
+	default:
+		_soundemu = SOUND_EMU_NONE;
+		break;
+	}
+
+	_sound = new SoundMgr(this, _mixer);
+	_sound->initSound();
 	setflag(fSoundOn, true); // enable sound
 
 	memset(&_gameStateWinnie, 0, sizeof(_gameStateWinnie));






More information about the Scummvm-git-logs mailing list