[Scummvm-git-logs] scummvm master -> 42a2cfa015de1cc59c1b58a0401665c8bb2c67dd

dreammaster paulfgilbert at gmail.com
Sat Apr 18 22:28:03 UTC 2020


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

Summary:
8d58aa2f6b ULTIMA4: Cleanup of tile rendering code
8995742dac ULTIMA4: Clarify mouse cursor methods and variables
d95e7642d7 ULTIMA4: Moving screen methods into Screen class
8f9cbfcbb1 ULTIMA4: Moving fields into Screen class
e6419f918a ULTIMA4: Renaming new Screen fields
42a2cfa015 ULTIMA4: Merge screen_scummvm.cpp into screen.cpp


Commit: 8d58aa2f6bfbf8c89d8302e0a29976dff3100917
    https://github.com/scummvm/scummvm/commit/8d58aa2f6bfbf8c89d8302e0a29976dff3100917
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-18T15:25:22-07:00

Commit Message:
ULTIMA4: Cleanup of tile rendering code

Changed paths:
    engines/ultima/ultima4/map/tileview.cpp


diff --git a/engines/ultima/ultima4/map/tileview.cpp b/engines/ultima/ultima4/map/tileview.cpp
index d360ebb7af..04c47fcc8c 100644
--- a/engines/ultima/ultima4/map/tileview.cpp
+++ b/engines/ultima/ultima4/map/tileview.cpp
@@ -37,21 +37,21 @@ namespace Ultima {
 namespace Ultima4 {
 
 TileView::TileView(int x, int y, int columns, int rows) : View(x, y, columns * TILE_WIDTH, rows * TILE_HEIGHT) {
-	this->_columns = columns;
-	this->_rows = rows;
-	this->_tileWidth = TILE_WIDTH;
-	this->_tileHeight = TILE_HEIGHT;
-	this->_tileset = Tileset::get("base");
+	_columns = columns;
+	_rows = rows;
+	_tileWidth = TILE_WIDTH;
+	_tileHeight = TILE_HEIGHT;
+	_tileset = Tileset::get("base");
 	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), false, Image::HARDWARE);
 }
 
 TileView::TileView(int x, int y, int columns, int rows, const Common::String &tileset) :
-	View(x, y, columns * TILE_WIDTH, rows * TILE_HEIGHT) {
-	this->_columns = columns;
-	this->_rows = rows;
-	this->_tileWidth = TILE_WIDTH;
-	this->_tileHeight = TILE_HEIGHT;
-	this->_tileset = Tileset::get(tileset);
+		View(x, y, columns * TILE_WIDTH, rows * TILE_HEIGHT) {
+	_columns = columns;
+	_rows = rows;
+	_tileWidth = TILE_WIDTH;
+	_tileHeight = TILE_HEIGHT;
+	_tileset = Tileset::get(tileset);
 	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), false, Image::HARDWARE);
 }
 
@@ -63,7 +63,7 @@ void TileView::reinit() {
 	View::reinit();
 	_tileset = Tileset::get("base");
 
-	//Scratchpad needs to be re-inited if we rescale...
+	// Scratchpad needs to be re-inited if we rescale...
 	if (_animated) {
 		delete _animated;
 		_animated = NULL;
@@ -72,12 +72,12 @@ void TileView::reinit() {
 }
 
 void TileView::loadTile(MapTile &mapTile) {
-	//This attempts to preload tiles in advance
+	// This attempts to preload tiles in advance
 	Tile *tile = _tileset->get(mapTile._id);
 	if (tile) {
 		tile->getImage();
 	}
-	//But may fail if the tiles don't exist directly in the expected imagesets
+	// But may fail if the tiles don't exist directly in the expected imagesets
 }
 
 void TileView::drawTile(MapTile &mapTile, bool focus, int x, int y) {
@@ -87,17 +87,15 @@ void TileView::drawTile(MapTile &mapTile, bool focus, int x, int y) {
 	ASSERT(x < _columns, "x value of %d out of range", x);
 	ASSERT(y < _rows, "y value of %d out of range", y);
 
-	//Blank scratch pad
+	// Blank scratch pad
 	_animated->fillRect(0, 0, SCALED(_tileWidth), SCALED(_tileHeight), 0, 0, 0, 255);
-	//Draw blackness on the tile.
+
+	// Draw blackness on the tile.
 	_animated->drawSubRect(SCALED(x * _tileWidth + this->_x),
-	                       SCALED(y * _tileHeight + this->_y),
-	                       0,
-	                       0,
-	                       SCALED(_tileWidth),
-	                       SCALED(_tileHeight));
+	    SCALED(y * _tileHeight + this->_y), 0, 0,
+	    SCALED(_tileWidth), SCALED(_tileHeight));
 
-	// draw the tile to the screen
+	// Draw the tile to the screen
 	if (tile->getAnim()) {
 		// First, create our animated version of the tile
 #ifdef IOS
@@ -107,21 +105,16 @@ void TileView::drawTile(MapTile &mapTile, bool focus, int x, int y) {
 
 		// Then draw it to the screen
 		_animated->drawSubRect(SCALED(x * _tileWidth + this->_x),
-		                       SCALED(y * _tileHeight + this->_y),
-		                       0,
-		                       0,
-		                       SCALED(_tileWidth),
-		                       SCALED(_tileHeight));
+			SCALED(y * _tileHeight + this->_y), 0, 0,
+			SCALED(_tileWidth), SCALED(_tileHeight));
 	} else {
 		image->drawSubRect(SCALED(x * _tileWidth + this->_x),
-		                   SCALED(y * _tileHeight + this->_y),
-		                   0,
-		                   SCALED(_tileHeight * mapTile._frame),
-		                   SCALED(_tileWidth),
-		                   SCALED(_tileHeight));
+			SCALED(y * _tileHeight + this->_y),
+			0, SCALED(_tileHeight * mapTile._frame),
+			SCALED(_tileWidth), SCALED(_tileHeight));
 	}
 
-	// draw the focus around the tile if it has the focus
+	// Draw the focus around the tile if it has the focus
 	if (focus)
 		drawFocus(x, y);
 }
@@ -130,52 +123,49 @@ void TileView::drawTile(Std::vector<MapTile> &tiles, bool focus, int x, int y) {
 	ASSERT(x < _columns, "x value of %d out of range", x);
 	ASSERT(y < _rows, "y value of %d out of range", y);
 
+	// Clear tile contents
 	_animated->fillRect(0, 0, SCALED(_tileWidth), SCALED(_tileHeight), 0, 0, 0, 255);
-	_animated->drawSubRect(SCALED(x * _tileWidth + this->_x),
-	                       SCALED(y * _tileHeight + this->_y),
-	                       0,
-	                       0,
-	                       SCALED(_tileWidth),
-	                       SCALED(_tileHeight));
-
-	//int layer = 0;
-
-	for (Std::vector<MapTile>::reverse_iterator t = tiles.rbegin(); t != tiles.rend(); ++t) {
+	_animated->drawSubRect(
+		SCALED(x * _tileWidth + this->_x), SCALED(y * _tileHeight + this->_y),
+		0, 0,
+		SCALED(_tileWidth), SCALED(_tileHeight)
+	);
+
+	// Iterate through rendering each of the needed tiles
+ 	for (Std::vector<MapTile>::reverse_iterator t = tiles.rbegin(); t != tiles.rend(); ++t) {
 		MapTile &frontTile = *t;
 		Tile *frontTileType = _tileset->get(frontTile._id);
 
 		if (!frontTileType) {
-			//TODO, this leads to an error. It happens after graphics mode changes.
+			// TODO: This leads to an error. It happens after graphics mode changes.
 			return;
 		}
 
+		// Get the image for the tile
 		Image *image = frontTileType->getImage();
 
-
-		// draw the tile to the screen
+		// Draw the tile to the screen
 		if (frontTileType->getAnim()) {
 			// First, create our animated version of the tile
 			frontTileType->getAnim()->draw(_animated, frontTileType, frontTile, DIR_NONE);
 		} else {
 			if (!image)
-				return; //This is a problem //FIXME, error message it.
-			image->drawSubRectOn(_animated,
-			                     0, 0,
-			                     0, SCALED(_tileHeight * frontTile._frame),
-			                     SCALED(_tileWidth),  SCALED(_tileHeight));
+				// FIXME: This is a problem, error message it.
+				return;
+			image->drawSubRectOn(_animated, 0, 0,
+				0, SCALED(_tileHeight * frontTile._frame),
+				SCALED(_tileWidth),  SCALED(_tileHeight)
+			);
 		}
 
 		// Then draw it to the screen
 		_animated->drawSubRect(SCALED(x * _tileWidth + this->_x),
-		                       SCALED(y * _tileHeight + this->_y),
-		                       0,
-		                       0,
-		                       SCALED(_tileWidth),
-		                       SCALED(_tileHeight));
+			SCALED(y * _tileHeight + this->_y), 0, 0,
+				SCALED(_tileWidth), SCALED(_tileHeight)
+		);
 	}
 
-
-	// draw the focus around the tile if it has the focus
+	// Draw the focus around the tile if it has the focus
 	if (focus)
 		drawFocus(x, y);
 }
@@ -184,37 +174,30 @@ void TileView::drawFocus(int x, int y) {
 	ASSERT(x < _columns, "x value of %d out of range", x);
 	ASSERT(y < _rows, "y value of %d out of range", y);
 
-	/*
-	 * draw the focus rectangle around the tile
-	 */
+	// Draw the focus rectangle around the tile
 	if ((screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND) % 2) {
-		/* left edge */
+		// left edge
 		_screen->fillRect(SCALED(x * _tileWidth + this->_x),
-		                  SCALED(y * _tileHeight + this->_y),
-		                  SCALED(2),
-		                  SCALED(_tileHeight),
-		                  0xff, 0xff, 0xff);
+			SCALED(y * _tileHeight + this->_y),
+			SCALED(2), SCALED(_tileHeight), 0xff, 0xff, 0xff);
 
-		/* top edge */
+		// top edge
 		_screen->fillRect(SCALED(x * _tileWidth + this->_x),
-		                  SCALED(y * _tileHeight + this->_y),
-		                  SCALED(_tileWidth),
-		                  SCALED(2),
-		                  0xff, 0xff, 0xff);
+			SCALED(y * _tileHeight + this->_y),
+			SCALED(_tileWidth), SCALED(2),
+			0xff, 0xff, 0xff);
 
-		/* right edge */
+		// Right edge
 		_screen->fillRect(SCALED((x + 1) * _tileWidth + this->_x - 2),
-		                  SCALED(y * _tileHeight + this->_y),
-		                  SCALED(2),
-		                  SCALED(_tileHeight),
-		                  0xff, 0xff, 0xff);
+		    SCALED(y * _tileHeight + this->_y),
+			SCALED(2), SCALED(_tileHeight),
+		    0xff, 0xff, 0xff);
 
-		/* bottom edge */
+		// Bottom edge
 		_screen->fillRect(SCALED(x * _tileWidth + this->_x),
-		                  SCALED((y + 1) * _tileHeight + this->_y - 2),
-		                  SCALED(_tileWidth),
-		                  SCALED(2),
-		                  0xff, 0xff, 0xff);
+			SCALED((y + 1) * _tileHeight + this->_y - 2),
+			SCALED(_tileWidth), SCALED(2),
+			0xff, 0xff, 0xff);
 	}
 }
 


Commit: 8995742dac0f33df84431663320fd93a8a5bf20b
    https://github.com/scummvm/scummvm/commit/8995742dac0f33df84431663320fd93a8a5bf20b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-18T15:25:23-07:00

Commit Message:
ULTIMA4: Clarify mouse cursor methods and variables

Changed paths:
    engines/ultima/ultima4/events/event_scummvm.cpp
    engines/ultima/ultima4/gfx/screen.cpp
    engines/ultima/ultima4/gfx/screen.h


diff --git a/engines/ultima/ultima4/events/event_scummvm.cpp b/engines/ultima/ultima4/events/event_scummvm.cpp
index 0c0e309e83..144d395765 100644
--- a/engines/ultima/ultima4/events/event_scummvm.cpp
+++ b/engines/ultima/ultima4/events/event_scummvm.cpp
@@ -44,9 +44,9 @@ static void handleMouseMotionEvent(const Common::Event &event) {
 	const MouseArea *area;
 	area = eventHandler->mouseAreaForPoint(event.mouse.x, event.mouse.y);
 	if (area)
-		g_screen->setCursor(area->_cursor);
+		g_screen->setMouseCursor(area->_cursor);
 	else
-		g_screen->setCursor(MC_DEFAULT);
+		g_screen->setMouseCursor(MC_DEFAULT);
 }
 
 static void handleMouseButtonDownEvent(const Common::Event &event, Controller *controller, updateScreenCallback updateScreen) {
diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index 47ce06dc65..0de8eea17f 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -52,16 +52,16 @@ namespace Ultima4 {
 
 Screen *g_screen;
 
-Screen::Screen() : _filterScaler(nullptr), _currentCursor(-1) {
+Screen::Screen() : _filterScaler(nullptr), _currentMouseCursor(-1) {
 	g_screen = this;
-	Common::fill(&_cursors[0], &_cursors[5], (Cursor *)nullptr);
+	Common::fill(&_cursors[0], &_cursors[5], (MouseCursorSurface *)nullptr);
 
 	Graphics::PixelFormat SCREEN_FORMAT(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	Common::Point size(SCREEN_WIDTH * settings._scale, SCREEN_HEIGHT * settings._scale);
 	initGraphics(size.x, size.y, &SCREEN_FORMAT);
 
 	create(size.x, size.y, SCREEN_FORMAT);
-	loadCursors();
+	loadMouseCursors();
 }
 
 Screen::~Screen() {
@@ -85,7 +85,7 @@ void Screen::clear() {
 	ImageMgr::destroy();
 }
 
-void Screen::loadCursors() {
+void Screen::loadMouseCursors() {
 	// enable or disable the mouse cursor
 	if (settings._mouseOptions._enabled) {
 		g_system->showMouse(true);
@@ -93,7 +93,7 @@ void Screen::loadCursors() {
 		Shared::File cursorsFile("data/graphics/cursors.txt");
 
 		for (int idx = 0; idx < 5; ++idx)
-			_cursors[idx] = loadCursor(cursorsFile);
+			_cursors[idx] = loadMouseCursor(cursorsFile);
 
 	} else {
 		g_system->showMouse(false);
@@ -104,11 +104,11 @@ void Screen::loadCursors() {
 		errorFatal("%s is not a valid filter", settings._filter.c_str());
 }
 
-void Screen::setCursor(MouseCursor cursor) {
-	const Cursor *c = _cursors[cursor];
+void Screen::setMouseCursor(MouseCursor cursor) {
+	const MouseCursorSurface *c = _cursors[cursor];
 
-	if (c && cursor != _currentCursor) {
-		_currentCursor = cursor;
+	if (c && cursor != _currentMouseCursor) {
+		_currentMouseCursor = cursor;
 
 		const uint TRANSPARENT = g_screen->format.RGBToColor(0x80, 0x80, 0x80);
 		CursorMan.replaceCursor(c->getPixels(), CURSOR_SIZE, CURSOR_SIZE,
@@ -119,7 +119,7 @@ void Screen::setCursor(MouseCursor cursor) {
 
 #define CURSOR_SIZE 20
 
-Cursor *Screen::loadCursor(Shared::File &src) {
+MouseCursorSurface *Screen::loadMouseCursor(Shared::File &src) {
 	uint row, col, endCol, pixel;
 	int hotX, hotY;
 	Common::String line;
@@ -130,7 +130,7 @@ Cursor *Screen::loadCursor(Shared::File &src) {
 	int bpp = g_screen->format.bytesPerPixel;
 	assert(bpp >= 2);
 
-	Cursor *c = new Cursor();
+	MouseCursorSurface *c = new MouseCursorSurface();
 	c->create(CURSOR_SIZE, CURSOR_SIZE, g_screen->format);
 	c->clear(TRANSPARENT);
 
diff --git a/engines/ultima/ultima4/gfx/screen.h b/engines/ultima/ultima4/gfx/screen.h
index 67cc999728..a8d5fbdd76 100644
--- a/engines/ultima/ultima4/gfx/screen.h
+++ b/engines/ultima/ultima4/gfx/screen.h
@@ -77,7 +77,7 @@ class Tile;
 class TileView;
 class Coords;
 
-struct Cursor : public Graphics::ManagedSurface {
+struct MouseCursorSurface : public Graphics::ManagedSurface {
 	Common::Point _hotspot;
 };
 
@@ -99,18 +99,18 @@ struct Layout {
 
 class Screen : public Graphics::Screen {
 private:
-	Cursor *_cursors[5];
-	int _currentCursor;
+	MouseCursorSurface *_cursors[5];
+	int _currentMouseCursor;
 private:
 	/**
 	 * Load the cursors
 	 */
-	void loadCursors();
+	void loadMouseCursors();
 
 	/**
 	 * Loads the data for a single cursor from the passed file
 	 */
-	Cursor *loadCursor(Shared::File &src);
+	MouseCursorSurface *loadMouseCursor(Shared::File &src);
 public:
 	Std::vector<Layout *> _layouts;
 	Scaler _filterScaler;
@@ -128,7 +128,7 @@ public:
 	/**
 	 * Sets a given mouse cursor
 	 */
-	void setCursor(MouseCursor cursor);
+	void setMouseCursor(MouseCursor cursor);
 };
 
 extern Screen *g_screen;


Commit: d95e7642d70f807b17fc5e937f4ccf91b3c0e009
    https://github.com/scummvm/scummvm/commit/d95e7642d70f807b17fc5e937f4ccf91b3c0e009
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-18T15:25:23-07:00

Commit Message:
ULTIMA4: Moving screen methods into Screen class

Changed paths:
    engines/ultima/ultima4/controllers/alpha_action_controller.cpp
    engines/ultima/ultima4/controllers/camp_controller.cpp
    engines/ultima/ultima4/controllers/combat_controller.cpp
    engines/ultima/ultima4/controllers/game_controller.cpp
    engines/ultima/ultima4/controllers/inn_controller.cpp
    engines/ultima/ultima4/controllers/intro_controller.cpp
    engines/ultima/ultima4/controllers/read_choice_controller.cpp
    engines/ultima/ultima4/controllers/read_string_controller.cpp
    engines/ultima/ultima4/core/debugger.cpp
    engines/ultima/ultima4/core/debugger_actions.cpp
    engines/ultima/ultima4/events/event_scummvm.cpp
    engines/ultima/ultima4/game/codex.cpp
    engines/ultima/ultima4/game/creature.cpp
    engines/ultima/ultima4/game/death.cpp
    engines/ultima/ultima4/game/game.cpp
    engines/ultima/ultima4/game/item.cpp
    engines/ultima/ultima4/game/object.cpp
    engines/ultima/ultima4/game/portal.cpp
    engines/ultima/ultima4/game/script.cpp
    engines/ultima/ultima4/game/spell.cpp
    engines/ultima/ultima4/gfx/imagemgr.cpp
    engines/ultima/ultima4/gfx/screen.cpp
    engines/ultima/ultima4/gfx/screen.h
    engines/ultima/ultima4/gfx/screen_scummvm.cpp
    engines/ultima/ultima4/map/dungeon.cpp
    engines/ultima/ultima4/map/dungeonview.cpp
    engines/ultima/ultima4/map/shrine.cpp
    engines/ultima/ultima4/ultima4.cpp


diff --git a/engines/ultima/ultima4/controllers/alpha_action_controller.cpp b/engines/ultima/ultima4/controllers/alpha_action_controller.cpp
index 48d62058be..92d4ec108e 100644
--- a/engines/ultima/ultima4/controllers/alpha_action_controller.cpp
+++ b/engines/ultima/ultima4/controllers/alpha_action_controller.cpp
@@ -35,11 +35,11 @@ bool AlphaActionController::keyPressed(int key) {
 		_value = key - 'A';
 		doneWaiting();
 	} else if (key == U4_SPACE || key == U4_ESC || key == U4_ENTER) {
-		screenMessage("\n");
+		g_screen->screenMessage("\n");
 		_value = -1;
 		doneWaiting();
 	} else {
-		screenMessage("\n%s", _prompt.c_str());
+		g_screen->screenMessage("\n%s", _prompt.c_str());
 		g_screen->update();
 		return KeyHandler::defaultHandler(key, NULL);
 	}
diff --git a/engines/ultima/ultima4/controllers/camp_controller.cpp b/engines/ultima/ultima4/controllers/camp_controller.cpp
index 4630c4f166..f9319d5e8d 100644
--- a/engines/ultima/ultima4/controllers/camp_controller.cpp
+++ b/engines/ultima/ultima4/controllers/camp_controller.cpp
@@ -56,19 +56,19 @@ void CampController::begin() {
 
 	g_music->camp();
 
-	screenMessage("Resting...\n");
-	screenDisableCursor();
+	g_screen->screenMessage("Resting...\n");
+	g_screen->screenDisableCursor();
 
 	EventHandler::wait_msecs(settings._campTime * 1000);
 
-	screenEnableCursor();
+	g_screen->screenEnableCursor();
 
 	/* Is the party ambushed during their rest? */
 	if (settings._campingAlwaysCombat || (xu4_random(8) == 0)) {
 		const Creature *m = creatureMgr->randomAmbushing();
 
 		g_music->play();
-		screenMessage("Ambushed!\n");
+		g_screen->screenMessage("Ambushed!\n");
 
 		/* create an ambushing creature (so it leaves a chest) */
 		setCreature(g_context->_location->_prev->_map->addCreature(m, g_context->_location->_prev->_coords));
@@ -90,7 +90,7 @@ void CampController::begin() {
 		        (((g_ultima->_saveGame->_moves / CAMP_HEAL_INTERVAL) & 0xffff) != g_ultima->_saveGame->_lastCamp))
 			healed = heal();
 
-		screenMessage(healed ? "Party Healed!\n" : "No effect.\n");
+		g_screen->screenMessage(healed ? "Party Healed!\n" : "No effect.\n");
 		g_ultima->_saveGame->_lastCamp = (g_ultima->_saveGame->_moves / CAMP_HEAL_INTERVAL) & 0xffff;
 
 		eventHandler->popController();
diff --git a/engines/ultima/ultima4/controllers/combat_controller.cpp b/engines/ultima/ultima4/controllers/combat_controller.cpp
index c39e6b1168..200baeb346 100644
--- a/engines/ultima/ultima4/controllers/combat_controller.cpp
+++ b/engines/ultima/ultima4/controllers/combat_controller.cpp
@@ -260,13 +260,13 @@ void CombatController::begin() {
 
 	/* if we entered an altar room, show the name */
 	if (_map->isAltarRoom()) {
-		screenMessage("\nThe Altar Room of %s\n", getBaseVirtueName(_map->getAltarRoom()));
+		g_screen->screenMessage("\nThe Altar Room of %s\n", getBaseVirtueName(_map->getAltarRoom()));
 		g_context->_location->_context = static_cast<LocationContext>(g_context->_location->_context | CTX_ALTAR_ROOM);
 	}
 
 	/* if there are creatures around, start combat! */
 	if (_showMessage && _placeCreaturesOnMap && _winOrLose)
-		screenMessage("\n%c****%c COMBAT %c****%c\n", FG_GREY, FG_WHITE, FG_GREY, FG_WHITE);
+		g_screen->screenMessage("\n%c****%c COMBAT %c****%c\n", FG_GREY, FG_WHITE, FG_GREY, FG_WHITE);
 
 	/* FIXME: there should be a better way to accomplish this */
 	if (!_camping) {
@@ -315,11 +315,11 @@ void CombatController::end(bool adjustKarma) {
 					awardLoot();
 				}
 
-				screenMessage("\nVictory!\n\n");
+				g_screen->screenMessage("\nVictory!\n\n");
 			} else if (!g_context->_party->isDead()) {
 				/* minus points for fleeing from evil creatures */
 				if (adjustKarma && _creature && _creature->isEvil()) {
-					screenMessage("\nBattle is lost!\n\n");
+					g_screen->screenMessage("\nBattle is lost!\n\n");
 					g_context->_party->adjustKarma(KA_FLED_EVIL);
 				} else if (adjustKarma && _creature && _creature->isGood())
 					g_context->_party->adjustKarma(KA_FLED_GOOD);
@@ -328,7 +328,7 @@ void CombatController::end(bool adjustKarma) {
 
 		/* exiting a dungeon room */
 		if (_map->isDungeonRoom()) {
-			screenMessage("Leave Room!\n");
+			g_screen->screenMessage("Leave Room!\n");
 			if (_map->isAltarRoom()) {
 				PortalTriggerAction action = ACTION_NONE;
 
@@ -357,7 +357,7 @@ void CombatController::end(bool adjustKarma) {
 
 				if (action != ACTION_NONE)
 					usePortalAt(g_context->_location, g_context->_location->_coords, action);
-			} else screenMessage("\n");
+			} else g_screen->screenMessage("\n");
 
 			if (_exitDir != DIR_NONE) {
 				g_ultima->_saveGame->_orientation = _exitDir;  /* face the direction exiting the room */
@@ -513,7 +513,7 @@ bool CombatController::setActivePlayer(int player) {
 		p->setFocus();
 		_focus = player;
 
-		screenMessage("\n%s with %s\n\020", p->getName().c_str(), p->getWeapon()->getName().c_str());
+		g_screen->screenMessage("\n%s with %s\n\020", p->getName().c_str(), p->getWeapon()->getName().c_str());
 		g_context->_stats->highlightPlayer(_focus);
 		return true;
 	}
@@ -576,7 +576,7 @@ bool CombatController::attackAt(const Coords &coords, PartyMember *attacker, int
 	/* Did the weapon miss? */
 	if ((g_context->_location->_prev->_map->_id == MAP_ABYSS && !weapon->isMagic()) || /* non-magical weapon in the Abyss */
 	        !attackHit(attacker, creature)) { /* player naturally missed */
-		screenMessage("Missed!\n");
+		g_screen->screenMessage("Missed!\n");
 
 		/* show the 'miss' tile */
 		GameController::flashTile(coords, misstile, 1);
@@ -624,7 +624,7 @@ bool CombatController::rangedAttack(const Coords &coords, Creature *attacker) {
 	case EFFECT_ELECTRICITY:
 		/* FIXME: are there any special effects here? */
 		soundPlay(SOUND_PC_STRUCK, false);
-		screenMessage("\n%s %cElectrified%c!\n", target->getName().c_str(), FG_BLUE, FG_WHITE);
+		g_screen->screenMessage("\n%s %cElectrified%c!\n", target->getName().c_str(), FG_BLUE, FG_WHITE);
 		attacker->dealDamage(target, attacker->getDamage());
 		break;
 
@@ -634,10 +634,10 @@ bool CombatController::rangedAttack(const Coords &coords, Creature *attacker) {
 		if ((xu4_random(2) == 0) && (target->getStatus() != STAT_POISONED)) {
 			// POISON_EFFECT, ranged hit
 			soundPlay(SOUND_POISON_EFFECT, false);
-			screenMessage("\n%s %cPoisoned%c!\n", target->getName().c_str(), FG_GREEN, FG_WHITE);
+			g_screen->screenMessage("\n%s %cPoisoned%c!\n", target->getName().c_str(), FG_GREEN, FG_WHITE);
 			target->addStatus(STAT_POISONED);
 		}
-		// else screenMessage("Failed.\n");
+		// else g_screen->screenMessage("Failed.\n");
 		break;
 
 	case EFFECT_SLEEP:
@@ -645,17 +645,17 @@ bool CombatController::rangedAttack(const Coords &coords, Creature *attacker) {
 		if (xu4_random(2) == 0) {
 			// SLEEP, ranged hit, plays even if sleep failed or PC already asleep
 			soundPlay(SOUND_SLEEP, false);
-			screenMessage("\n%s %cSlept%c!\n", target->getName().c_str(), FG_PURPLE, FG_WHITE);
+			g_screen->screenMessage("\n%s %cSlept%c!\n", target->getName().c_str(), FG_PURPLE, FG_WHITE);
 			target->putToSleep();
 		}
-		// else screenMessage("Failed.\n");
+		// else g_screen->screenMessage("Failed.\n");
 		break;
 
 	case EFFECT_LAVA:
 	case EFFECT_FIRE:
 		/* FIXME: are there any special effects here? */
 		soundPlay(SOUND_PC_STRUCK, false);
-		screenMessage("\n%s %c%s Hit%c!\n", target->getName().c_str(), FG_RED,
+		g_screen->screenMessage("\n%s %c%s Hit%c!\n", target->getName().c_str(), FG_RED,
 		              effect == EFFECT_LAVA ? "Lava" : "Fiery", FG_WHITE);
 		attacker->dealDamage(target, attacker->getDamage());
 		break;
@@ -664,8 +664,8 @@ bool CombatController::rangedAttack(const Coords &coords, Creature *attacker) {
 		/* show the appropriate 'hit' message */
 		// soundPlay(SOUND_PC_STRUCK, false);
 		if (hittile == Tileset::findTileByName("magic_flash")->getId())
-			screenMessage("\n%s %cMagical Hit%c!\n", target->getName().c_str(), FG_BLUE, FG_WHITE);
-		else screenMessage("\n%s Hit!\n", target->getName().c_str());
+			g_screen->screenMessage("\n%s %cMagical Hit%c!\n", target->getName().c_str(), FG_BLUE, FG_WHITE);
+		else g_screen->screenMessage("\n%s Hit!\n", target->getName().c_str());
 		attacker->dealDamage(target, attacker->getDamage());
 		break;
 	}
@@ -815,16 +815,16 @@ void CombatController::movePartyMember(MoveEvent &event) {
 		}
 	}
 
-	screenMessage("%s\n", getDirectionName(event._dir));
+	g_screen->screenMessage("%s\n", getDirectionName(event._dir));
 	if (event._result & MOVE_MUST_USE_SAME_EXIT) {
 		soundPlay(SOUND_ERROR);                                                // ERROR move, all PCs must use the same exit
-		screenMessage("All must use same exit!\n");
+		g_screen->screenMessage("All must use same exit!\n");
 	} else if (event._result & MOVE_BLOCKED) {
 		soundPlay(SOUND_BLOCKED);                                              // BLOCKED move
-		screenMessage("%cBlocked!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cBlocked!%c\n", FG_GREY, FG_WHITE);
 	} else if (event._result & MOVE_SLOWED) {
 		soundPlay(SOUND_WALK_SLOWED);                                          // WALK_SLOWED move
-		screenMessage("%cSlow progress!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cSlow progress!%c\n", FG_GREY, FG_WHITE);
 	} else if (_winOrLose && getCreature()->isEvil() && (event._result & (MOVE_EXIT_TO_PARENT | MOVE_MAP_CHANGE))) {
 		soundPlay(SOUND_FLEE);                                                 // FLEE move
 	} else {
@@ -848,12 +848,12 @@ bool CombatController::keyPressed(int key) {
 	case U4_ESC:
 		if (settings._debug)
 			end(false);         /* don't adjust karma */
-		else screenMessage("Bad command\n");
+		else g_screen->screenMessage("Bad command\n");
 
 		break;
 
 	case ' ':
-		screenMessage("Pass\n");
+		g_screen->screenMessage("Pass\n");
 		break;
 
 	case U4_FKEY: {
@@ -877,12 +877,12 @@ bool CombatController::keyPressed(int key) {
 
 		if (old_speed != settings._battleSpeed) {
 			if (settings._battleSpeed == DEFAULT_BATTLE_SPEED)
-				screenMessage("Battle Speed:\nNormal\n");
+				g_screen->screenMessage("Battle Speed:\nNormal\n");
 			else if (key == '+')
-				screenMessage("Battle Speed:\nUp (%d)\n", settings._battleSpeed);
-			else screenMessage("Battle Speed:\nDown (%d)\n", settings._battleSpeed);
+				g_screen->screenMessage("Battle Speed:\nUp (%d)\n", settings._battleSpeed);
+			else g_screen->screenMessage("Battle Speed:\nDown (%d)\n", settings._battleSpeed);
 		} else if (settings._battleSpeed == DEFAULT_BATTLE_SPEED)
-			screenMessage("Battle Speed:\nNormal\n");
+			g_screen->screenMessage("Battle Speed:\nNormal\n");
 	}
 
 	valid = false;
@@ -891,25 +891,25 @@ bool CombatController::keyPressed(int key) {
 	/* handle music volume adjustments */
 	case ',':
 		// decrease the volume if possible
-		screenMessage("Music: %d%s\n", g_music->decreaseMusicVolume(), "%");
+		g_screen->screenMessage("Music: %d%s\n", g_music->decreaseMusicVolume(), "%");
 		endTurn = false;
 		break;
 	case '.':
 		// increase the volume if possible
-		screenMessage("Music: %d%s\n", g_music->increaseMusicVolume(), "%");
+		g_screen->screenMessage("Music: %d%s\n", g_music->increaseMusicVolume(), "%");
 		endTurn = false;
 		break;
 
 	/* handle sound volume adjustments */
 	case '<':
 		// decrease the volume if possible
-		screenMessage("Sound: %d%s\n", g_music->decreaseSoundVolume(), "%");
+		g_screen->screenMessage("Sound: %d%s\n", g_music->decreaseSoundVolume(), "%");
 		soundPlay(SOUND_FLEE);
 		endTurn = false;
 		break;
 	case '>':
 		// increase the volume if possible
-		screenMessage("Sound: %d%s\n", g_music->increaseSoundVolume(), "%");
+		g_screen->screenMessage("Sound: %d%s\n", g_music->increaseSoundVolume(), "%");
 		soundPlay(SOUND_FLEE);
 		endTurn = false;
 		break;
@@ -919,7 +919,7 @@ bool CombatController::keyPressed(int key) {
 		break;
 
 	case 'c':
-		screenMessage("Cast Spell!\n");
+		g_screen->screenMessage("Cast Spell!\n");
 		g_debugger->castSpell(_focus);
 		break;
 
@@ -927,18 +927,18 @@ bool CombatController::keyPressed(int key) {
 	case U4_ENTER: // Fall through and get the chest.
 #endif
 	case 'g':
-		screenMessage("Get Chest!\n");
+		g_screen->screenMessage("Get Chest!\n");
 		g_debugger->getChest(_focus);
 		break;
 
 	case 'l':
 		if (settings._debug) {
 			Coords coords = getCurrentPlayer()->getCoords();
-			screenMessage("\nLocation:\nx:%d\ny:%d\nz:%d\n", coords.x, coords.y, coords.z);
-			screenPrompt();
+			g_screen->screenMessage("\nLocation:\nx:%d\ny:%d\nz:%d\n", coords.x, coords.y, coords.z);
+			g_screen->screenPrompt();
 			valid = false;
 		} else
-			screenMessage("Not here!\n");
+			g_screen->screenMessage("Not here!\n");
 		break;
 
 	case 'r':
@@ -951,25 +951,25 @@ bool CombatController::keyPressed(int key) {
 			Trigger *triggers = dungeon->_rooms[dungeon->_currentRoom]._triggers;
 			int i;
 
-			screenMessage("Triggers!\n");
+			g_screen->screenMessage("Triggers!\n");
 
 			for (i = 0; i < 4; i++) {
-				screenMessage("%.1d)xy tile xy xy\n", i + 1);
-				screenMessage("  %.1X%.1X  %.3d %.1X%.1X %.1X%.1X\n",
+				g_screen->screenMessage("%.1d)xy tile xy xy\n", i + 1);
+				g_screen->screenMessage("  %.1X%.1X  %.3d %.1X%.1X %.1X%.1X\n",
 				              triggers[i].x, triggers[i].y,
 				              triggers[i]._tile,
 				              triggers[i]._changeX1, triggers[i]._changeY1,
 				              triggers[i].changeX2, triggers[i].changeY2);
 			}
-			screenPrompt();
+			g_screen->screenPrompt();
 			valid = false;
 
 		} else
-			screenMessage("Not here!\n");
+			g_screen->screenMessage("Not here!\n");
 		break;
 
 	case 'u':
-		screenMessage("Use which item:\n");
+		g_screen->screenMessage("Use which item:\n");
 		g_context->_stats->setView(STATS_ITEMS);
 #ifdef IOS
 		U4IOS::IOSConversationHelper::setIntroString("Use which item?");
@@ -979,9 +979,9 @@ bool CombatController::keyPressed(int key) {
 
 	case 'v':
 		if (g_music->toggle())
-			screenMessage("Volume On!\n");
+			g_screen->screenMessage("Volume On!\n");
 		else
-			screenMessage("Volume Off!\n");
+			g_screen->screenMessage("Volume Off!\n");
 		endTurn = false;
 		break;
 
@@ -992,7 +992,7 @@ bool CombatController::keyPressed(int key) {
 		   and hide reagents that you don't have */
 		g_context->_stats->resetReagentsMenu();
 
-		screenMessage("Ztats\n");
+		g_screen->screenMessage("Ztats\n");
 		ZtatsController ctrl;
 		eventHandler->pushController(&ctrl);
 		ctrl.waitFor();
@@ -1016,7 +1016,7 @@ bool CombatController::keyPressed(int key) {
 	case 'w':
 	case 'x':
 	case 'y':
-		screenMessage("Not here!\n");
+		g_screen->screenMessage("Not here!\n");
 		break;
 
 	case '0':
@@ -1031,7 +1031,7 @@ bool CombatController::keyPressed(int key) {
 	case '9':
 		if (settings._enhancements && settings._enhancementsOptions._activePlayer)
 			gameSetActivePlayer(key - '1');
-		else screenMessage("Bad command\n");
+		else g_screen->screenMessage("Bad command\n");
 
 		break;
 
@@ -1050,7 +1050,7 @@ bool CombatController::keyPressed(int key) {
 }
 
 void CombatController::attack() {
-	screenMessage("Dir: ");
+	g_screen->screenMessage("Dir: ");
 
 	ReadDirController dirController;
 #ifdef IOS
@@ -1060,18 +1060,18 @@ void CombatController::attack() {
 	Direction dir = dirController.waitFor();
 	if (dir == DIR_NONE)
 		return;
-	screenMessage("%s\n", getDirectionName(dir));
+	g_screen->screenMessage("%s\n", getDirectionName(dir));
 
 	PartyMember *attacker = getCurrentPlayer();
 
 	const Weapon *weapon = attacker->getWeapon();
 	int range = weapon->getRange();
 	if (weapon->canChooseDistance()) {
-		screenMessage("Range: ");
+		g_screen->screenMessage("Range: ");
 		int choice = ReadChoiceController::get("123456789");
 		if ((choice - '0') >= 1 && (choice - '0') <= weapon->getRange()) {
 			range = choice - '0';
-			screenMessage("%d\n", range);
+			g_screen->screenMessage("%d\n", range);
 		} else {
 			return;
 		}
@@ -1108,7 +1108,7 @@ void CombatController::attack() {
 	if (weapon->loseWhenUsed() ||
 	        (weapon->loseWhenRanged() && (!foundTarget || targetDistance > 1))) {
 		if (!attacker->loseWeapon())
-			screenMessage("Last One!\n");
+			g_screen->screenMessage("Last One!\n");
 	}
 
 	// does weapon leave a tile behind? (e.g. flaming oil)
@@ -1120,7 +1120,7 @@ void CombatController::attack() {
 	if (!foundTarget) {
 		GameController::flashTile(targetCoords, weapon->getMissTile(), 1);
 		/* This goes here so messages are shown in the original order */
-		screenMessage("Missed!\n");
+		g_screen->screenMessage("Missed!\n");
 	}
 
 	// does weapon returns to its owner? (e.g. magic axe)
@@ -1130,7 +1130,7 @@ void CombatController::attack() {
 
 void CombatController::update(Party *party, PartyEvent &event) {
 	if (event._type == PartyEvent::PLAYER_KILLED)
-		screenMessage("\n%c%s is Killed!%c\n", FG_RED, event._player->getName().c_str(), FG_WHITE);
+		g_screen->screenMessage("\n%c%s is Killed!%c\n", FG_RED, event._player->getName().c_str(), FG_WHITE);
 }
 
 /*-------------------------------------------------------------------*/
diff --git a/engines/ultima/ultima4/controllers/game_controller.cpp b/engines/ultima/ultima4/controllers/game_controller.cpp
index 123857618f..8d930d7537 100644
--- a/engines/ultima/ultima4/controllers/game_controller.cpp
+++ b/engines/ultima/ultima4/controllers/game_controller.cpp
@@ -71,8 +71,8 @@ void GameController::initScreenWithoutReloadingState() {
 	imageMgr->get(BKGD_BORDERS)->_image->draw(0, 0);
 	g_context->_stats->update(); /* draw the party stats */
 
-	screenMessage("Press Alt-h for help\n");
-	screenPrompt();
+	g_screen->screenMessage("Press Alt-h for help\n");
+	g_screen->screenPrompt();
 
 	eventHandler->pushMouseAreaSet(MOUSE_AREAS);
 
@@ -208,8 +208,8 @@ void GameController::finishTurn() {
 		/* update party stats */
 		//c->stats->setView(STATS_PARTY_OVERVIEW);
 
-		screenUpdate(&this->_mapArea, true, false);
-		screenWait(1);
+		g_screen->screenUpdate(&this->_mapArea, true, false);
+		g_screen->screenWait(1);
 
 		/* Creatures cannot spawn, move or attack while the avatar is on the balloon */
 		if (!g_context->_party->isFlying()) {
@@ -242,15 +242,15 @@ void GameController::finishTurn() {
 			deathStart(0);
 			return;
 		} else {
-			screenMessage("Zzzzzz\n");
-			screenWait(4);
+			g_screen->screenMessage("Zzzzzz\n");
+			g_screen->screenWait(4);
 		}
 	}
 
 	if (g_context->_location->_context == CTX_DUNGEON) {
 		Dungeon *dungeon = dynamic_cast<Dungeon *>(g_context->_location->_map);
 		if (g_context->_party->getTorchDuration() <= 0)
-			screenMessage("It's Dark!\n");
+			g_screen->screenMessage("It's Dark!\n");
 		else g_context->_party->burnTorch();
 
 		/* handle dungeon traps */
@@ -269,19 +269,19 @@ void GameController::finishTurn() {
 
 
 	/* draw a prompt */
-	screenPrompt();
-	//screenRedrawTextArea(TEXT_AREA_X, TEXT_AREA_Y, TEXT_AREA_W, TEXT_AREA_H);
+	g_screen->screenPrompt();
+	//g_screen->screenRedrawTextArea(TEXT_AREA_X, TEXT_AREA_Y, TEXT_AREA_W, TEXT_AREA_H);
 }
 
 void GameController::flashTile(const Coords &coords, MapTile tile, int frames) {
 	g_context->_location->_map->_annotations->add(coords, tile, true);
 
-	screenTileUpdate(&g_game->_mapArea, coords);
+	g_screen->screenTileUpdate(&g_game->_mapArea, coords);
 
-	screenWait(frames);
+	g_screen->screenWait(frames);
 	g_context->_location->_map->_annotations->remove(coords, tile);
 
-	screenTileUpdate(&g_game->_mapArea, coords, false);
+	g_screen->screenTileUpdate(&g_game->_mapArea, coords, false);
 }
 
 void GameController::flashTile(const Coords &coords, const Common::String &tilename, int timeFactor) {
@@ -296,14 +296,14 @@ void GameController::update(Party *party, PartyEvent &event) {
 	switch (event._type) {
 	case PartyEvent::LOST_EIGHTH:
 		// inform a player he has lost zero or more eighths of avatarhood.
-		screenMessage("\n %cThou hast lost\n  an eighth!%c\n", FG_YELLOW, FG_WHITE);
+		g_screen->screenMessage("\n %cThou hast lost\n  an eighth!%c\n", FG_YELLOW, FG_WHITE);
 		break;
 	case PartyEvent::ADVANCED_LEVEL:
-		screenMessage("\n%c%s\nThou art now Level %d%c\n", FG_YELLOW, event._player->getName().c_str(), event._player->getRealLevel(), FG_WHITE);
+		g_screen->screenMessage("\n%c%s\nThou art now Level %d%c\n", FG_YELLOW, event._player->getName().c_str(), event._player->getRealLevel(), FG_WHITE);
 		gameSpellEffect('r', -1, SOUND_MAGIC); // Same as resurrect spell
 		break;
 	case PartyEvent::STARVING:
-		screenMessage("\n%cStarving!!!%c\n", FG_YELLOW, FG_WHITE);
+		g_screen->screenMessage("\n%cStarving!!!%c\n", FG_YELLOW, FG_WHITE);
 		/* FIXME: add sound effect here */
 
 		// 2 damage to each party member for starving!
@@ -415,14 +415,14 @@ bool GameController::keyPressed(int key) {
 	}
 
 	if ((g_context->_location->_context & CTX_DUNGEON) && strchr("abefjlotxy", key))
-		screenMessage("%cNot here!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cNot here!%c\n", FG_GREY, FG_WHITE);
 
 	if (valid && endTurn) {
 		if (eventHandler->getController() == g_game)
 			g_context->_location->_turnCompleter->finishTurn();
 	} else if (!endTurn) {
 		/* if our turn did not end, then manually redraw the text prompt */
-		screenPrompt();
+		g_screen->screenPrompt();
 	}
 
 	return valid || KeyHandler::defaultHandler(key, NULL);
@@ -529,18 +529,18 @@ void GameController::avatarMoved(MoveEvent &event) {
 			switch (g_context->_transportContext) {
 			case TRANSPORT_FOOT:
 			case TRANSPORT_HORSE:
-				screenMessage("%s\n", getDirectionName(event._dir));
+				g_screen->screenMessage("%s\n", getDirectionName(event._dir));
 				break;
 			case TRANSPORT_SHIP:
 				if (event._result & MOVE_TURNED)
-					screenMessage("Turn %s!\n", getDirectionName(event._dir));
+					g_screen->screenMessage("Turn %s!\n", getDirectionName(event._dir));
 				else if (event._result & MOVE_SLOWED)
-					screenMessage("%cSlow progress!%c\n", FG_GREY, FG_WHITE);
+					g_screen->screenMessage("%cSlow progress!%c\n", FG_GREY, FG_WHITE);
 				else
-					screenMessage("Sail %s!\n", getDirectionName(event._dir));
+					g_screen->screenMessage("Sail %s!\n", getDirectionName(event._dir));
 				break;
 			case TRANSPORT_BALLOON:
-				screenMessage("%cDrift Only!%c\n", FG_GREY, FG_WHITE);
+				g_screen->screenMessage("%cDrift Only!%c\n", FG_GREY, FG_WHITE);
 				break;
 			default:
 				error("bad transportContext %d in avatarMoved()", g_context->_transportContext);
@@ -573,13 +573,13 @@ void GameController::avatarMoved(MoveEvent &event) {
 			/* if we're still blocked */
 			if ((event._result & MOVE_BLOCKED) && !settings._filterMoveMessages) {
 				soundPlay(SOUND_BLOCKED, false);
-				screenMessage("%cBlocked!%c\n", FG_GREY, FG_WHITE);
+				g_screen->screenMessage("%cBlocked!%c\n", FG_GREY, FG_WHITE);
 			}
 		} else if (g_context->_transportContext == TRANSPORT_FOOT || g_context->_transportContext == TRANSPORT_HORSE) {
 			/* movement was slowed */
 			if (event._result & MOVE_SLOWED) {
 				soundPlay(SOUND_WALK_SLOWED);
-				screenMessage("%cSlow progress!%c\n", FG_GREY, FG_WHITE);
+				g_screen->screenMessage("%cSlow progress!%c\n", FG_GREY, FG_WHITE);
 			} else {
 				soundPlay(SOUND_WALK_NORMAL);
 			}
@@ -588,7 +588,7 @@ void GameController::avatarMoved(MoveEvent &event) {
 
 	/* exited map */
 	if (event._result & MOVE_EXIT_TO_PARENT) {
-		screenMessage("%cLeaving...%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cLeaving...%c\n", FG_GREY, FG_WHITE);
 		exitToParentMap();
 		g_music->play();
 	}
@@ -612,20 +612,20 @@ void GameController::avatarMovedInDungeon(MoveEvent &event) {
 		if (event._userEvent) {
 			if (event._result & MOVE_TURNED) {
 				if (dirRotateCCW((Direction)g_ultima->_saveGame->_orientation) == realDir)
-					screenMessage("Turn Left\n");
-				else screenMessage("Turn Right\n");
+					g_screen->screenMessage("Turn Left\n");
+				else g_screen->screenMessage("Turn Right\n");
 			}
 			/* show 'Advance' or 'Retreat' in dungeons */
-			else screenMessage("%s\n", realDir == g_ultima->_saveGame->_orientation ? "Advance" : "Retreat");
+			else g_screen->screenMessage("%s\n", realDir == g_ultima->_saveGame->_orientation ? "Advance" : "Retreat");
 		}
 
 		if (event._result & MOVE_BLOCKED)
-			screenMessage("%cBlocked!%c\n", FG_GREY, FG_WHITE);
+			g_screen->screenMessage("%cBlocked!%c\n", FG_GREY, FG_WHITE);
 	}
 
 	/* if we're exiting the map, do this */
 	if (event._result & MOVE_EXIT_TO_PARENT) {
-		screenMessage("%cLeaving...%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cLeaving...%c\n", FG_GREY, FG_WHITE);
 		exitToParentMap();
 		g_music->play();
 	}
@@ -678,7 +678,7 @@ void GameController::timerFired() {
 
 		updateMoons(true);
 
-		screenCycle();
+		g_screen->screenCycle();
 
 		/*
 		 * force pass if no commands within last 20 seconds
@@ -690,7 +690,7 @@ void GameController::timerFired() {
 
 			/* pass the turn, and redraw the text area so the prompt is shown */
 			MetaEngine::executeAction(KEYBIND_PASS);
-			screenRedrawTextArea(TEXT_AREA_X, TEXT_AREA_Y, TEXT_AREA_W, TEXT_AREA_H);
+			g_screen->screenRedrawTextArea(TEXT_AREA_X, TEXT_AREA_Y, TEXT_AREA_W, TEXT_AREA_H);
 		}
 	}
 
@@ -819,7 +819,7 @@ void GameController::checkBridgeTrolls() {
 	        xu4_random(8) != 0)
 		return;
 
-	screenMessage("\nBridge Trolls!\n");
+	g_screen->screenMessage("\nBridge Trolls!\n");
 
 	Creature *m = g_context->_location->_map->addCreature(creatureMgr->getById(TROLL_ID), g_context->_location->_coords);
 	CombatController *cc = new CombatController(MAP_BRIDGE_CON);
diff --git a/engines/ultima/ultima4/controllers/inn_controller.cpp b/engines/ultima/ultima4/controllers/inn_controller.cpp
index 75b511c836..8d4f3184d2 100644
--- a/engines/ultima/ultima4/controllers/inn_controller.cpp
+++ b/engines/ultima/ultima4/controllers/inn_controller.cpp
@@ -54,11 +54,11 @@ void InnController::begin() {
 	g_context->_party->setTransport(g_context->_location->_map->_tileset->getByName("corpse")->getId());
 	gameUpdateScreen();
 
-	screenDisableCursor();
+	g_screen->screenDisableCursor();
 
 	EventHandler::wait_msecs(settings._innTime * 1000);
 
-	screenEnableCursor();
+	g_screen->screenEnableCursor();
 
 	/* restore the avatar to normal */
 	g_context->_party->setTransport(g_context->_location->_map->_tileset->getByName("avatar")->getId());
@@ -79,8 +79,8 @@ void InnController::begin() {
 		}
 	}
 
-	screenMessage("\nMorning!\n");
-	screenPrompt();
+	g_screen->screenMessage("\nMorning!\n");
+	g_screen->screenPrompt();
 
 	g_music->fadeIn(INN_FADE_IN_TIME, true);
 }
@@ -155,7 +155,7 @@ void InnController::maybeAmbush() {
 			/* While strolling down the street, attacked by rogues! */
 			mapid = MAP_INN_CON;
 			creature = g_context->_location->_map->addCreature(creatureMgr->getById(ROGUE_ID), g_context->_location->_coords);
-			screenMessage("\nIn the middle of the night while out on a stroll...\n\n");
+			g_screen->screenMessage("\nIn the middle of the night while out on a stroll...\n\n");
 			showMessage = false;
 		}
 
diff --git a/engines/ultima/ultima4/controllers/intro_controller.cpp b/engines/ultima/ultima4/controllers/intro_controller.cpp
index f01aa7dfec..3f13a5b11b 100644
--- a/engines/ultima/ultima4/controllers/intro_controller.cpp
+++ b/engines/ultima/ultima4/controllers/intro_controller.cpp
@@ -404,9 +404,9 @@ bool IntroController::keyPressed(int key) {
 			_errorMessage.clear();
 			// Make a copy of our settings so we can change them
 			settingsChanged = settings;
-			screenDisableCursor();
+			g_screen->screenDisableCursor();
 			runMenu(&_confMenu, &_extendedMenuArea, true);
-			screenEnableCursor();
+			g_screen->screenEnableCursor();
 			updateScreen();
 			break;
 		}
@@ -594,7 +594,7 @@ void IntroController::drawAbacusBeads(int row, int selectedVirtue, int rejectedV
 }
 
 void IntroController::updateScreen() {
-	screenHideCursor();
+	g_screen->screenHideCursor();
 
 	switch (_mode) {
 	case INTRO_MAP:
@@ -603,7 +603,7 @@ void IntroController::updateScreen() {
 		drawBeasties();
 		// display the profile name if a local profile is being used
 		if (useProfile)
-			screenTextAt(40 - profileName.size(), 24, "%s", profileName.c_str());
+			g_screen->screenTextAt(40 - profileName.size(), 24, "%s", profileName.c_str());
 		break;
 
 	case INTRO_MENU:
@@ -634,21 +634,21 @@ void IntroController::updateScreen() {
 		drawBeasties();
 
 		// draw the cursor last
-		screenSetCursorPos(24, 16);
-		screenShowCursor();
+		g_screen->screenSetCursorPos(24, 16);
+		g_screen->screenShowCursor();
 		break;
 
 	default:
 		error("bad mode in updateScreen");
 	}
 
-	screenUpdateCursor();
+	g_screen->screenUpdateCursor();
 	g_screen->update();
 }
 
 void IntroController::initiateNewGame() {
 	// disable the screen cursor because a text cursor will now be used
-	screenDisableCursor();
+	g_screen->screenDisableCursor();
 
 	// draw the extended background for all option screens
 	_backgroundArea.draw(BKGD_INTRO);
@@ -671,7 +671,7 @@ void IntroController::initiateNewGame() {
 	if (nameBuffer.empty()) {
 		// the user didn't enter a name
 		_menuArea.disableCursor();
-		screenEnableCursor();
+		g_screen->screenEnableCursor();
 		updateScreen();
 		return;
 	}
@@ -721,7 +721,7 @@ void IntroController::finishInitiateGame(const Common::String &nameBuffer, SexTy
 	strcpy(avatar.name, nameBuffer.c_str());
 	avatar._sex = sex;
 	saveGame.init(&avatar);
-	screenHideCursor();
+	g_screen->screenHideCursor();
 	initPlayers(&saveGame);
 	saveGame._food = 30000;
 	saveGame._gold = 200;
@@ -821,7 +821,7 @@ void IntroController::startQuestions() {
 		eventHandler->pushController(&pauseController);
 		pauseController.waitFor();
 
-		screenEnableCursor();
+		g_screen->screenEnableCursor();
 		// show the question to choose between virtues
 		showText(getQuestion(_questionTree[_questionRound * 2], _questionTree[_questionRound * 2 + 1]));
 
@@ -885,14 +885,14 @@ void IntroController::about() {
 	_backgroundArea.draw(BKGD_INTRO);
 	_backgroundArea.draw(BKGD_OPTIONS_BTM, 0, 120);
 
-	screenHideCursor();
+	g_screen->screenHideCursor();
 	_menuArea.textAt(11, 1, "ScummVM Ultima IV");
 	_menuArea.textAt(1, 3, "Based on the xu4 project");
 	drawBeasties();
 
 	ReadChoiceController::get("");
 
-	screenShowCursor();
+	g_screen->screenShowCursor();
 	updateScreen();
 }
 
@@ -933,8 +933,8 @@ void IntroController::runMenu(Menu *menu, TextView *view, bool withBeasties) {
 }
 
 void IntroController::timerFired() {
-	screenCycle();
-	screenUpdateCursor();
+	g_screen->screenCycle();
+	g_screen->screenUpdateCursor();
 
 	if (_mode == INTRO_TITLES)
 		if (updateTitle() == false) {
@@ -1041,7 +1041,7 @@ void IntroController::updateVideoMenu(MenuEvent &event) {
 				settings.write();
 
 				/* FIXME: resize images, etc. */
-				screenReInit();
+				g_screen->screenReInit();
 
 				// go back to menu mode
 				_mode = INTRO_MENU;
@@ -1566,7 +1566,7 @@ void IntroController::getTitleSourceData() {
 			    _transparentColor.b);
 
 			Image *scaled;      // the scaled and filtered image
-			scaled = screenScale(_titles[i]._srcImage, settings._scale / info->_prescale, 1, 1);
+			scaled = g_screen->screenScale(_titles[i]._srcImage, settings._scale / info->_prescale, 1, 1);
 			if (_transparentIndex >= 0)
 				scaled->setTransparentIndex(_transparentIndex);
 
@@ -1605,7 +1605,7 @@ void IntroController::getTitleSourceData() {
 	}
 
 	// scale the original image now
-	Image *scaled = screenScale(info->_image,
+	Image *scaled = g_screen->screenScale(info->_image,
 	                            settings._scale / info->_prescale,
 	                            info->_image->isIndexed(),
 	                            1);
@@ -1920,7 +1920,7 @@ void IntroController::drawTitle() {
 	if (_title->_prescaled)
 		scaled = _title->_destImage;
 	else
-		scaled = screenScale(_title->_destImage, settings._scale, 1, 1);
+		scaled = g_screen->screenScale(_title->_destImage, settings._scale, 1, 1);
 
 	scaled->setTransparentIndex(_transparentIndex);
 	scaled->drawSubRect(
diff --git a/engines/ultima/ultima4/controllers/read_choice_controller.cpp b/engines/ultima/ultima4/controllers/read_choice_controller.cpp
index 105df96473..ebc5f82233 100644
--- a/engines/ultima/ultima4/controllers/read_choice_controller.cpp
+++ b/engines/ultima/ultima4/controllers/read_choice_controller.cpp
@@ -41,7 +41,7 @@ bool ReadChoiceController::keyPressed(int key) {
 	if (_choices.empty() || _choices.findFirstOf(_value) < _choices.size()) {
 		// If the value is printable, display it
 		if (!Common::isSpace(key))
-			screenMessage("%c", toupper(key));
+			g_screen->screenMessage("%c", toupper(key));
 		doneWaiting();
 		return true;
 	}
diff --git a/engines/ultima/ultima4/controllers/read_string_controller.cpp b/engines/ultima/ultima4/controllers/read_string_controller.cpp
index 8380ea1c3b..a819a52a97 100644
--- a/engines/ultima/ultima4/controllers/read_string_controller.cpp
+++ b/engines/ultima/ultima4/controllers/read_string_controller.cpp
@@ -60,10 +60,10 @@ bool ReadStringController::keyPressed(int key) {
 					_view->textAt(_screenX + len - 1, _screenY, " ");
 					_view->setCursorPos(_screenX + len - 1, _screenY, true);
 				} else {
-					screenHideCursor();
-					screenTextAt(_screenX + len - 1, _screenY, " ");
-					screenSetCursorPos(_screenX + len - 1, _screenY);
-					screenShowCursor();
+					g_screen->screenHideCursor();
+					g_screen->screenTextAt(_screenX + len - 1, _screenY, " ");
+					g_screen->screenSetCursorPos(_screenX + len - 1, _screenY);
+					g_screen->screenShowCursor();
 				}
 			}
 		} else if (key == '\n' || key == '\r') {
@@ -75,11 +75,11 @@ bool ReadStringController::keyPressed(int key) {
 			if (_view) {
 				_view->textAt(_screenX + len, _screenY, "%c", key);
 			} else {
-				screenHideCursor();
-				screenTextAt(_screenX + len, _screenY, "%c", key);
-				screenSetCursorPos(_screenX + len + 1, _screenY);
+				g_screen->screenHideCursor();
+				g_screen->screenTextAt(_screenX + len, _screenY, "%c", key);
+				g_screen->screenSetCursorPos(_screenX + len + 1, _screenY);
 				g_context->col = len + 1;
-				screenShowCursor();
+				g_screen->screenShowCursor();
 			}
 		}
 	} else valid = false;
diff --git a/engines/ultima/ultima4/core/debugger.cpp b/engines/ultima/ultima4/core/debugger.cpp
index 8982fbae21..bb9c82e349 100644
--- a/engines/ultima/ultima4/core/debugger.cpp
+++ b/engines/ultima/ultima4/core/debugger.cpp
@@ -143,7 +143,7 @@ void Debugger::printN(const char *fmt, ...) {
 
 		debugPrintf("%s", s.c_str());
 	} else {
-		screenMessage("%s", str.c_str());
+		g_screen->screenMessage("%s", str.c_str());
 	}
 }
 
@@ -576,7 +576,7 @@ bool Debugger::cmdGet(int argc, const char **argv) {
 
 		print("The Chest Holds: %d Gold", g_context->_party->getChest());
 
-		screenPrompt();
+		g_screen->screenPrompt();
 
 		if (isCity(g_context->_location->_map) && obj == NULL)
 			g_context->_party->adjustKarma(KA_STOLE_CHEST);
@@ -1276,7 +1276,7 @@ bool Debugger::cmdGoto(int argc, const char **argv) {
 bool Debugger::cmdHelp(int argc, const char **argv) {
 	if (!isDebuggerActive()) {
 		print("Help!");
-		screenPrompt();
+		g_screen->screenPrompt();
 	}
 
 	// Help! send me to Lord British
@@ -1437,7 +1437,7 @@ bool Debugger::cmdSummon(int argc, const char **argv) {
 bool Debugger::cmdTorch(int argc, const char **argv) {
 	print("Torch: %d\n", g_context->_party->getTorchDuration());
 	if (!isDebuggerActive())
-		screenPrompt();
+		g_screen->screenPrompt();
 
 	return isDebuggerActive();
 }
diff --git a/engines/ultima/ultima4/core/debugger_actions.cpp b/engines/ultima/ultima4/core/debugger_actions.cpp
index c8ec780f08..91600162ce 100644
--- a/engines/ultima/ultima4/core/debugger_actions.cpp
+++ b/engines/ultima/ultima4/core/debugger_actions.cpp
@@ -91,14 +91,14 @@ bool DebuggerActions::destroyAt(const Coords &coords) {
 	if (obj) {
 		if (isCreature(obj)) {
 			Creature *c = dynamic_cast<Creature *>(obj);
-			screenMessage("%s Destroyed!\n", c->getName().c_str());
+			g_screen->screenMessage("%s Destroyed!\n", c->getName().c_str());
 		} else {
 			Tile *t = g_context->_location->_map->_tileset->get(obj->getTile()._id);
-			screenMessage("%s Destroyed!\n", t->getName().c_str());
+			g_screen->screenMessage("%s Destroyed!\n", t->getName().c_str());
 		}
 
 		g_context->_location->_map->removeObject(obj);
-		screenPrompt();
+		g_screen->screenPrompt();
 
 		return true;
 	}
@@ -175,13 +175,13 @@ bool DebuggerActions::getChestTrapHandler(int player) {
 
 		/* apply the effects from the trap */
 		if (trapType == EFFECT_FIRE)
-			screenMessage("%cAcid%c Trap!\n", FG_RED, FG_WHITE);
+			g_screen->screenMessage("%cAcid%c Trap!\n", FG_RED, FG_WHITE);
 		else if (trapType == EFFECT_POISON)
-			screenMessage("%cPoison%c Trap!\n", FG_GREEN, FG_WHITE);
+			g_screen->screenMessage("%cPoison%c Trap!\n", FG_GREEN, FG_WHITE);
 		else if (trapType == EFFECT_SLEEP)
-			screenMessage("%cSleep%c Trap!\n", FG_PURPLE, FG_WHITE);
+			g_screen->screenMessage("%cSleep%c Trap!\n", FG_PURPLE, FG_WHITE);
 		else if (trapType == EFFECT_LAVA)
-			screenMessage("%cBomb%c Trap!\n", FG_RED, FG_WHITE);
+			g_screen->screenMessage("%cBomb%c Trap!\n", FG_RED, FG_WHITE);
 
 		// player is < 0 during the 'O'pen spell (immune to traps)
 		//
@@ -193,7 +193,7 @@ bool DebuggerActions::getChestTrapHandler(int player) {
 			if (trapType == EFFECT_LAVA) /* bomb trap */
 				g_context->_party->applyEffect(trapType);
 			else g_context->_party->member(player)->applyEffect(trapType);
-		} else screenMessage("Evaded!\n");
+		} else g_screen->screenMessage("Evaded!\n");
 
 		return true;
 	}
@@ -212,9 +212,9 @@ bool DebuggerActions::jimmyAt(const Coords &coords) {
 		ASSERT(door, "no door tile found in tileset");
 		g_ultima->_saveGame->_keys--;
 		g_context->_location->_map->_annotations->add(coords, door->getId());
-		screenMessage("\nUnlocked!\n");
+		g_screen->screenMessage("\nUnlocked!\n");
 	} else
-		screenMessage("%cNo keys left!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cNo keys left!%c\n", FG_GREY, FG_WHITE);
 
 	return true;
 }
@@ -222,7 +222,7 @@ bool DebuggerActions::jimmyAt(const Coords &coords) {
 bool DebuggerActions::mixReagentsForSpellU4(int spell) {
 	Ingredients ingredients;
 
-	screenMessage("Reagent: ");
+	g_screen->screenMessage("Reagent: ");
 
 	while (1) {
 		int choice = ReadChoiceController::get("abcdefgh\n\r \033");
@@ -230,12 +230,12 @@ bool DebuggerActions::mixReagentsForSpellU4(int spell) {
 		// done selecting reagents? mix it up and prompt to mix
 		// another spell
 		if (choice == '\n' || choice == '\r' || choice == ' ') {
-			screenMessage("\n\nYou mix the Reagents, and...\n");
+			g_screen->screenMessage("\n\nYou mix the Reagents, and...\n");
 
 			if (spellMix(spell, &ingredients))
-				screenMessage("Success!\n\n");
+				g_screen->screenMessage("Success!\n\n");
 			else
-				screenMessage("It Fizzles!\n\n");
+				g_screen->screenMessage("It Fizzles!\n\n");
 
 			return false;
 		}
@@ -246,10 +246,10 @@ bool DebuggerActions::mixReagentsForSpellU4(int spell) {
 			return true;
 		}
 
-		screenMessage("%c\n", toupper(choice));
+		g_screen->screenMessage("%c\n", toupper(choice));
 		if (!ingredients.addReagent((Reagent)(choice - 'a')))
-			screenMessage("%cNone Left!%c\n", FG_GREY, FG_WHITE);
-		screenMessage("Reagent: ");
+			g_screen->screenMessage("%cNone Left!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("Reagent: ");
 	}
 
 	return true;
@@ -258,7 +258,7 @@ bool DebuggerActions::mixReagentsForSpellU4(int spell) {
 bool DebuggerActions::mixReagentsForSpellU5(int spell) {
 	Ingredients ingredients;
 
-	screenDisableCursor();
+	g_screen->screenDisableCursor();
 
 	g_context->_stats->getReagentsMenu()->reset(); // reset the menu, highlighting the first item
 	ReagentsMenuController getReagentsController(g_context->_stats->getReagentsMenu(), &ingredients, g_context->_stats->getMainArea());
@@ -266,7 +266,7 @@ bool DebuggerActions::mixReagentsForSpellU5(int spell) {
 	getReagentsController.waitFor();
 
 	g_context->_stats->getMainArea()->disableCursor();
-	screenEnableCursor();
+	g_screen->screenEnableCursor();
 
 	printN("How many? ");
 
@@ -323,7 +323,7 @@ bool DebuggerActions::openAt(const Coords &coords) {
 		return false;
 
 	if (tile->isLockedDoor()) {
-		screenMessage("%cCan't!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cCan't!%c\n", FG_GREY, FG_WHITE);
 		return true;
 	}
 
@@ -331,7 +331,7 @@ bool DebuggerActions::openAt(const Coords &coords) {
 	ASSERT(floor, "no floor tile found in tileset");
 	g_context->_location->_map->_annotations->add(coords, floor->getId(), false, true)->setTTL(4);
 
-	screenMessage("\nOpened!\n");
+	g_screen->screenMessage("\nOpened!\n");
 
 	return true;
 }
@@ -343,7 +343,7 @@ void DebuggerActions::gameCastSpell(unsigned int spell, int caster, int param) {
 	if (!spellCast(spell, caster, param, &spellError, true)) {
 		msg = spellGetErrorMessage(spell, spellError);
 		if (!msg.empty())
-			screenMessage("%s", msg.c_str());
+			g_screen->screenMessage("%s", msg.c_str());
 	}
 }
 
@@ -353,7 +353,7 @@ bool DebuggerActions::talkAt(const Coords &coords) {
 
 	/* can't have any conversations outside of town */
 	if (!isCity(g_context->_location->_map)) {
-		screenMessage("Funny, no response!\n");
+		g_screen->screenMessage("Funny, no response!\n");
 		return true;
 	}
 
@@ -373,7 +373,7 @@ bool DebuggerActions::talkAt(const Coords &coords) {
 	/* if we're talking to Lord British and the avatar is dead, LB resurrects them! */
 	if (talker->getNpcType() == NPC_LORD_BRITISH &&
 		g_context->_party->member(0)->getStatus() == STAT_DEAD) {
-		screenMessage("%s, Thou shalt live again!\n", g_context->_party->member(0)->getName().c_str());
+		g_screen->screenMessage("%s, Thou shalt live again!\n", g_context->_party->member(0)->getName().c_str());
 
 		g_context->_party->member(0)->setStatus(STAT_GOOD);
 		g_context->_party->member(0)->heal(HT_FULLHEAL);
@@ -397,7 +397,7 @@ void DebuggerActions::talkRunConversation(Conversation &conv, Person *talker, bo
 		// TODO: instead of calculating linesused again, cache the
 		// result in person.cpp somewhere.
 		int linesused = linecount(conv._reply.front(), TEXT_AREA_W);
-		screenMessage("%s", conv._reply.front().c_str());
+		g_screen->screenMessage("%s", conv._reply.front().c_str());
 		conv._reply.pop_front();
 
 		/* if all chunks haven't been shown, wait for a key and process next chunk*/
@@ -452,7 +452,7 @@ void DebuggerActions::talkRunConversation(Conversation &conv, Person *talker, bo
 					ReadChoiceController::get("");
 				}
 
-				screenMessage("%s", prompt.c_str());
+				g_screen->screenMessage("%s", prompt.c_str());
 			}
 		}
 
@@ -462,7 +462,7 @@ void DebuggerActions::talkRunConversation(Conversation &conv, Person *talker, bo
 		{
 			conv._playerInput = gameGetInput(maxlen);
 #ifdef IOS
-			screenMessage("%s", conv.playerInput.c_str()); // Since we put this in a different window, we need to show it again.
+			g_screen->screenMessage("%s", conv.playerInput.c_str()); // Since we put this in a different window, we need to show it again.
 #endif
 			conv._reply = talker->getConversationText(&conv, conv._playerInput.c_str());
 			conv._playerInput.clear();
@@ -495,7 +495,7 @@ void DebuggerActions::talkRunConversation(Conversation &conv, Person *talker, bo
 		}
 	}
 	if (conv._reply.size() > 0)
-		screenMessage("%s", conv._reply.front().c_str());
+		g_screen->screenMessage("%s", conv._reply.front().c_str());
 }
 
 void DebuggerActions::gameLordBritishCheckLevels() {
@@ -508,14 +508,14 @@ void DebuggerActions::gameLordBritishCheckLevels() {
 
 			// add an extra space to separate messages
 			if (!advanced) {
-				screenMessage("\n");
+				g_screen->screenMessage("\n");
 				advanced = true;
 			}
 
 		player->advanceLevel();
 	}
 
-	screenMessage("\nWhat would thou\nask of me?\n");
+	g_screen->screenMessage("\nWhat would thou\nask of me?\n");
 }
 
 } // End of namespace Ultima4
diff --git a/engines/ultima/ultima4/events/event_scummvm.cpp b/engines/ultima/ultima4/events/event_scummvm.cpp
index 144d395765..4b86286e1d 100644
--- a/engines/ultima/ultima4/events/event_scummvm.cpp
+++ b/engines/ultima/ultima4/events/event_scummvm.cpp
@@ -200,7 +200,7 @@ const MouseArea *EventHandler::mouseAreaForPoint(int x, int y) {
 		return NULL;
 
 	for (i = 0; areas[i]._nPoints != 0; i++) {
-		if (screenPointInMouseArea(x, y, &(areas[i]))) {
+		if (g_screen->screenPointInMouseArea(x, y, &(areas[i]))) {
 			return &(areas[i]);
 		}
 	}
diff --git a/engines/ultima/ultima4/game/codex.cpp b/engines/ultima/ultima4/game/codex.cpp
index d2a9dca12e..b36a4b9f4b 100644
--- a/engines/ultima/ultima4/game/codex.cpp
+++ b/engines/ultima/ultima4/game/codex.cpp
@@ -94,8 +94,8 @@ void codexStart() {
 #ifdef IOS
 	U4IOS::IOSHideGameControllerHelper hideControllsHelper;
 #endif
-	screenDisableCursor();
-	screenUpdate(&g_game->_mapArea, false, true);
+	g_screen->screenDisableCursor();
+	g_screen->screenUpdate(&g_game->_mapArea, false, true);
 
 	/**
 	 * make the avatar alone
@@ -109,7 +109,7 @@ void codexStart() {
 	 */
 	gameSetViewMode(VIEW_CODEX);
 
-	screenMessage("\n\n\n\nThere is a sudden darkness, and you find yourself alone in an empty chamber.\n");
+	g_screen->screenMessage("\n\n\n\nThere is a sudden darkness, and you find yourself alone in an empty chamber.\n");
 	EventHandler::sleep(4000);
 
 	/**
@@ -120,13 +120,13 @@ void codexStart() {
 		return;
 	}
 
-	screenDrawImageInMapArea(BKGD_KEY);
-	screenRedrawMapArea();
+	g_screen->screenDrawImageInMapArea(BKGD_KEY);
+	g_screen->screenRedrawMapArea();
 
-	screenMessage("\nYou use your key of Three Parts.\n");
+	g_screen->screenMessage("\nYou use your key of Three Parts.\n");
 	EventHandler::sleep(3000);
 
-	screenMessage("\nA voice rings out:\n\"What is the Word of Passage?\"\n\n");
+	g_screen->screenMessage("\nA voice rings out:\n\"What is the Word of Passage?\"\n\n");
 
 	/**
 	 * Get the Word of Passage
@@ -157,20 +157,20 @@ void codexEject(CodexEjectCode code) {
 
 	switch (code) {
 	case CODEX_EJECT_NO_3_PART_KEY:
-		screenMessage("\nThou dost not have the Key of Three Parts.\n\n");
+		g_screen->screenMessage("\nThou dost not have the Key of Three Parts.\n\n");
 		break;
 	case CODEX_EJECT_NO_FULL_PARTY:
-		screenMessage("\nThou hast not proved thy leadership in all eight virtues.\n\n");
+		g_screen->screenMessage("\nThou hast not proved thy leadership in all eight virtues.\n\n");
 		EventHandler::sleep(2000);
-		screenMessage("\nPassage is not granted.\n\n");
+		g_screen->screenMessage("\nPassage is not granted.\n\n");
 		break;
 	case CODEX_EJECT_NO_FULL_AVATAR:
-		screenMessage("\nThou art not ready.\n");
+		g_screen->screenMessage("\nThou art not ready.\n");
 		EventHandler::sleep(2000);
-		screenMessage("\nPassage is not granted.\n\n");
+		g_screen->screenMessage("\nPassage is not granted.\n\n");
 		break;
 	case CODEX_EJECT_BAD_WOP:
-		screenMessage("\nPassage is not granted.\n\n");
+		g_screen->screenMessage("\nPassage is not granted.\n\n");
 		break;
 	case CODEX_EJECT_HONESTY:
 	case CODEX_EJECT_COMPASSION:
@@ -183,13 +183,13 @@ void codexEject(CodexEjectCode code) {
 	case CODEX_EJECT_TRUTH:
 	case CODEX_EJECT_LOVE:
 	case CODEX_EJECT_COURAGE:
-		screenMessage("\nThy quest is not yet complete.\n\n");
+		g_screen->screenMessage("\nThy quest is not yet complete.\n\n");
 		break;
 	case CODEX_EJECT_BAD_INFINITY:
-		screenMessage("\nThou dost not know the true nature of the Universe.\n\n");
+		g_screen->screenMessage("\nThou dost not know the true nature of the Universe.\n\n");
 		break;
 	default:
-		screenMessage("\nOops, you just got too close to beating the game.\nBAD AVATAR!\n");
+		g_screen->screenMessage("\nOops, you just got too close to beating the game.\nBAD AVATAR!\n");
 		break;
 	}
 
@@ -199,8 +199,8 @@ void codexEject(CodexEjectCode code) {
 	codexDelete();
 
 	/* re-enable the cursor and show it */
-	screenEnableCursor();
-	screenShowCursor();
+	g_screen->screenEnableCursor();
+	g_screen->screenShowCursor();
 
 	/* return view to normal and exit the Abyss */
 	gameSetViewMode(VIEW_NORMAL);
@@ -233,8 +233,8 @@ void codexHandleWOP(const Common::String &word) {
 	eventHandler->popKeyHandler();
 
 	/* slight pause before continuing */
-	screenMessage("\n");
-	screenDisableCursor();
+	g_screen->screenMessage("\n");
+	g_screen->screenDisableCursor();
 	EventHandler::sleep(1000);
 
 	/* entered correctly */
@@ -255,16 +255,16 @@ void codexHandleWOP(const Common::String &word) {
 			}
 		}
 
-		screenMessage("\nPassage is granted.\n");
+		g_screen->screenMessage("\nPassage is granted.\n");
 		EventHandler::sleep(4000);
 
-		screenEraseMapArea();
-		screenRedrawMapArea();
+		g_screen->screenEraseMapArea();
+		g_screen->screenRedrawMapArea();
 
 		/* Ask the Virtue questions */
-		screenMessage("\n\nThe voice asks:\n");
+		g_screen->screenMessage("\n\nThe voice asks:\n");
 		EventHandler::sleep(2000);
-		screenMessage("\n%s\n\n", codexVirtueQuestions[0].c_str());
+		g_screen->screenMessage("\n%s\n\n", codexVirtueQuestions[0].c_str());
 
 		codexHandleVirtues(gameGetInput());
 
@@ -274,7 +274,7 @@ void codexHandleWOP(const Common::String &word) {
 	/* entered incorrectly - give 3 tries before ejecting */
 	else if (tries++ < 3) {
 		codexImpureThoughts();
-		screenMessage("\"What is the Word of Passage?\"\n\n");
+		g_screen->screenMessage("\"What is the Word of Passage?\"\n\n");
 #ifdef IOS
 		U4IOS::IOSConversationHelper::setIntroString("Which virtue?");
 #endif
@@ -304,16 +304,16 @@ void codexHandleVirtues(const Common::String &virtue) {
 	eventHandler->popKeyHandler();
 
 	/* slight pause before continuing */
-	screenMessage("\n");
-	screenDisableCursor();
+	g_screen->screenMessage("\n");
+	g_screen->screenDisableCursor();
 	EventHandler::sleep(1000);
 
 	/* answered with the correct one of eight virtues */
 	if ((current < VIRT_MAX) &&
 	        (scumm_stricmp(virtue.c_str(), getVirtueName(static_cast<Virtue>(current))) == 0)) {
 
-		screenDrawImageInMapArea(codexImageNames[current]);
-		screenRedrawMapArea();
+		g_screen->screenDrawImageInMapArea(codexImageNames[current]);
+		g_screen->screenRedrawMapArea();
 
 		current++;
 		tries = 1;
@@ -321,13 +321,13 @@ void codexHandleVirtues(const Common::String &virtue) {
 		EventHandler::sleep(2000);
 
 		if (current == VIRT_MAX) {
-			screenMessage("\nThou art well versed in the virtues of the Avatar.\n");
+			g_screen->screenMessage("\nThou art well versed in the virtues of the Avatar.\n");
 			EventHandler::sleep(5000);
 		}
 
-		screenMessage("\n\nThe voice asks:\n");
+		g_screen->screenMessage("\n\nThe voice asks:\n");
 		EventHandler::sleep(2000);
-		screenMessage("\n%s\n\n", codexVirtueQuestions[current].c_str());
+		g_screen->screenMessage("\n%s\n\n", codexVirtueQuestions[current].c_str());
 #ifdef IOS
 		U4IOS::IOSConversationHelper::setIntroString((current != VIRT_MAX) ? "Which virtue?" : "Which principle?");
 #endif
@@ -338,28 +338,28 @@ void codexHandleVirtues(const Common::String &virtue) {
 	else if ((current >= VIRT_MAX) &&
 	         (scumm_stricmp(virtue.c_str(), getBaseVirtueName(static_cast<BaseVirtue>(1 << (current - VIRT_MAX)))) == 0)) {
 
-		screenDrawImageInMapArea(codexImageNames[current]);
-		screenRedrawMapArea();
+		g_screen->screenDrawImageInMapArea(codexImageNames[current]);
+		g_screen->screenRedrawMapArea();
 
 		current++;
 		tries = 1;
 
 		if (current < VIRT_MAX + 3) {
-			screenMessage("\n\nThe voice asks:\n");
+			g_screen->screenMessage("\n\nThe voice asks:\n");
 			EventHandler::sleep(2000);
-			screenMessage("\n%s\n\n", codexVirtueQuestions[current].c_str());
+			g_screen->screenMessage("\n%s\n\n", codexVirtueQuestions[current].c_str());
 #ifdef IOS
 			U4IOS::IOSConversationHelper::setIntroString("Which principle?");
 #endif
 			codexHandleVirtues(gameGetInput());
 		} else {
-			screenMessage("\nThe ground rumbles beneath your feet.\n");
+			g_screen->screenMessage("\nThe ground rumbles beneath your feet.\n");
 			EventHandler::sleep(1000);
-			screenShake(10);
+			g_screen->screenShake(10);
 
 			EventHandler::sleep(3000);
-			screenEnableCursor();
-			screenMessage("\nAbove the din, the voice asks:\n\nIf all eight virtues of the Avatar combine into and are derived from the Three Principles of Truth, Love and Courage...");
+			g_screen->screenEnableCursor();
+			g_screen->screenMessage("\nAbove the din, the voice asks:\n\nIf all eight virtues of the Avatar combine into and are derived from the Three Principles of Truth, Love and Courage...");
 #ifdef IOS
 			// Ugh, we now enter happy callback land, so I know how to do these things manually. Good thing I kept these separate functions.
 			U4IOS::beginChoiceConversation();
@@ -372,7 +372,7 @@ void codexHandleVirtues(const Common::String &virtue) {
 	/* give them 3 tries to enter the correct virtue, then eject them! */
 	else if (tries++ < 3) {
 		codexImpureThoughts();
-		screenMessage("%s\n\n", codexVirtueQuestions[current].c_str());
+		g_screen->screenMessage("%s\n\n", codexVirtueQuestions[current].c_str());
 #ifdef IOS
 		U4IOS::IOSConversationHelper::setIntroString("Which virtue?");
 #endif
@@ -391,7 +391,7 @@ void codexHandleVirtues(const Common::String &virtue) {
 bool codexHandleInfinityAnyKey(int key, void *data) {
 	eventHandler->popKeyHandler();
 
-	screenMessage("\n\nThen what is the one thing which encompasses and is the whole of all undeniable Truth, unending Love, and unyielding Courage?\n\n");
+	g_screen->screenMessage("\n\nThen what is the one thing which encompasses and is the whole of all undeniable Truth, unending Love, and unyielding Courage?\n\n");
 #ifdef IOS
 	U4IOS::endChoiceConversation();
 	U4IOS::IOSConversationHelper::setIntroString("What is the whole of all undeniable Truth, unending Love, and unyielding Courage?");
@@ -408,16 +408,16 @@ void codexHandleInfinity(const Common::String &answer) {
 	U4IOS::IOSHideGameControllerHelper hideControllsHelper;
 #endif
 	/* slight pause before continuing */
-	screenMessage("\n");
-	screenDisableCursor();
+	g_screen->screenMessage("\n");
+	g_screen->screenDisableCursor();
 	EventHandler::sleep(1000);
 
 	if (scumm_stricmp(answer.c_str(), "infinity") == 0) {
 		EventHandler::sleep(2000);
-		screenShake(10);
+		g_screen->screenShake(10);
 
-		screenEnableCursor();
-		screenMessage("\n%s", codexEndgameText1[0].c_str());
+		g_screen->screenEnableCursor();
+		g_screen->screenMessage("\n%s", codexEndgameText1[0].c_str());
 #ifdef IOS
 		// Ugh, we now enter happy callback land, so I know how to do these things manually. Good thing I kept these separate functions.
 		U4IOS::hideGameButtons();
@@ -428,7 +428,7 @@ void codexHandleInfinity(const Common::String &answer) {
 		eventHandler->pushKeyHandler(&codexHandleEndgameAnyKey);
 	} else if (tries++ < 3) {
 		codexImpureThoughts();
-		screenMessage("\nAbove the din, the voice asks:\n\nIf all eight virtues of the Avatar combine into and are derived from the Three Principles of Truth, Love and Courage...");
+		g_screen->screenMessage("\nAbove the din, the voice asks:\n\nIf all eight virtues of the Avatar combine into and are derived from the Three Principles of Truth, Love and Courage...");
 		eventHandler->pushKeyHandler(&codexHandleInfinityAnyKey);
 	} else codexEject(CODEX_EJECT_BAD_INFINITY);
 }
@@ -442,23 +442,23 @@ bool codexHandleEndgameAnyKey(int key, void *data) {
 
 		if (index < 7) {
 			if (index == 6) {
-				screenEraseMapArea();
-				screenRedrawMapArea();
+				g_screen->screenEraseMapArea();
+				g_screen->screenRedrawMapArea();
 			}
-			screenMessage("%s", codexEndgameText1[index].c_str());
+			g_screen->screenMessage("%s", codexEndgameText1[index].c_str());
 		} else if (index == 7) {
-			screenDrawImageInMapArea(BKGD_STONCRCL);
-			screenRedrawMapArea();
-			screenMessage("\n\n%s", codexEndgameText2[index - 7].c_str());
+			g_screen->screenDrawImageInMapArea(BKGD_STONCRCL);
+			g_screen->screenRedrawMapArea();
+			g_screen->screenMessage("\n\n%s", codexEndgameText2[index - 7].c_str());
 		} else if (index > 7)
-			screenMessage("%s", codexEndgameText2[index - 7].c_str());
+			g_screen->screenMessage("%s", codexEndgameText2[index - 7].c_str());
 
 		index++;
 		eventHandler->pushKeyHandler(&codexHandleEndgameAnyKey);
 	} else {
 		/* CONGRATULATIONS!... you have completed the game in x turns */
-		screenDisableCursor();
-		screenMessage("%s%d%s", codexEndgameText2[index - 7].c_str(), g_ultima->_saveGame->_moves, codexEndgameText2[index - 6].c_str());
+		g_screen->screenDisableCursor();
+		g_screen->screenMessage("%s%d%s", codexEndgameText2[index - 7].c_str(), g_ultima->_saveGame->_moves, codexEndgameText2[index - 6].c_str());
 #ifdef IOS
 		U4IOS::endChoiceConversation();
 #endif
@@ -472,7 +472,7 @@ bool codexHandleEndgameAnyKey(int key, void *data) {
  * Pretty self-explanatory
  */
 void codexImpureThoughts() {
-	screenMessage("\nThy thoughts are not pure.\nI ask again.\n");
+	g_screen->screenMessage("\nThy thoughts are not pure.\nI ask again.\n");
 	EventHandler::sleep(2000);
 }
 
diff --git a/engines/ultima/ultima4/game/creature.cpp b/engines/ultima/ultima4/game/creature.cpp
index 489142653f..a97a39ba6b 100644
--- a/engines/ultima/ultima4/game/creature.cpp
+++ b/engines/ultima/ultima4/game/creature.cpp
@@ -541,7 +541,7 @@ void Creature::act(CombatController *controller) {
 		break;
 
 	case CA_CAST_SLEEP: {
-		screenMessage("\nSleep!\n");
+		g_screen->screenMessage("\nSleep!\n");
 
 		gameSpellEffect('s', -1, static_cast<Sound>(SOUND_MAGIC)); /* show the sleep spell effect */
 
@@ -620,7 +620,7 @@ void Creature::act(CombatController *controller) {
 			Coords coords = getCoords();
 
 			if (MAP_IS_OOB(map, coords)) {
-				screenMessage("\n%c%s Flees!%c\n", FG_YELLOW, _name.c_str(), FG_WHITE);
+				g_screen->screenMessage("\n%c%s Flees!%c\n", FG_YELLOW, _name.c_str(), FG_WHITE);
 
 				/* Congrats, you have a heart! */
 				if (isGood())
@@ -697,7 +697,7 @@ bool Creature::divide() {
 	if (d != DIR_NONE) {
 		MapCoords coords(getCoords());
 
-		screenMessage("%s Divides!\n", _name.c_str());
+		g_screen->screenMessage("%s Divides!\n", _name.c_str());
 
 		/* find a spot to put our new creature */
 		coords.move(d, map);
@@ -834,9 +834,9 @@ bool Creature::applyDamage(int damage, bool byplayer) {
 
 	case MSTAT_DEAD:
 		if (byplayer)
-			screenMessage("%c%s Killed!%c\nExp. %d\n", FG_RED, _name.c_str(), FG_WHITE, _xp);
+			g_screen->screenMessage("%c%s Killed!%c\nExp. %d\n", FG_RED, _name.c_str(), FG_WHITE, _xp);
 		else
-			screenMessage("%c%s Killed!%c\n", FG_RED, _name.c_str(), FG_WHITE);
+			g_screen->screenMessage("%c%s Killed!%c\n", FG_RED, _name.c_str(), FG_WHITE);
 
 		/*
 		 * the creature is dead; let it spawns something else on
@@ -851,23 +851,23 @@ bool Creature::applyDamage(int damage, bool byplayer) {
 		return false;
 
 	case MSTAT_FLEEING:
-		screenMessage("%c%s Fleeing!%c\n", FG_YELLOW, _name.c_str(), FG_WHITE);
+		g_screen->screenMessage("%c%s Fleeing!%c\n", FG_YELLOW, _name.c_str(), FG_WHITE);
 		break;
 
 	case MSTAT_CRITICAL:
-		screenMessage("%s Critical!\n", _name.c_str());
+		g_screen->screenMessage("%s Critical!\n", _name.c_str());
 		break;
 
 	case MSTAT_HEAVILYWOUNDED:
-		screenMessage("%s Heavily Wounded!\n", _name.c_str());
+		g_screen->screenMessage("%s Heavily Wounded!\n", _name.c_str());
 		break;
 
 	case MSTAT_LIGHTLYWOUNDED:
-		screenMessage("%s Lightly Wounded!\n", _name.c_str());
+		g_screen->screenMessage("%s Lightly Wounded!\n", _name.c_str());
 		break;
 
 	case MSTAT_BARELYWOUNDED:
-		screenMessage("%s Barely Wounded!\n", _name.c_str());
+		g_screen->screenMessage("%s Barely Wounded!\n", _name.c_str());
 		break;
 	}
 
diff --git a/engines/ultima/ultima4/game/death.cpp b/engines/ultima/ultima4/game/death.cpp
index f40a432c69..2530ff192d 100644
--- a/engines/ultima/ultima4/game/death.cpp
+++ b/engines/ultima/ultima4/game/death.cpp
@@ -88,7 +88,7 @@ void deathStart(int delay) {
 	gameSetViewMode(VIEW_DEAD);
 
 	eventHandler->pushKeyHandler(&KeyHandler::ignoreKeys);
-	screenDisableCursor();
+	g_screen->screenDisableCursor();
 
 	eventHandler->getTimer()->add(&deathTimer, settings._gameCyclesPerSecond);
 }
@@ -98,8 +98,8 @@ void deathTimer(void *data) {
 	timerCount++;
 	if ((timerMsg < N_MSGS) && (timerCount > deathMsgs[timerMsg].timeout)) {
 
-		screenMessage(deathMsgs[timerMsg].text, g_context->_party->member(0)->getName().c_str());
-		screenHideCursor();
+		g_screen->screenMessage(deathMsgs[timerMsg].text, g_context->_party->member(0)->getName().c_str());
+		g_screen->screenHideCursor();
 
 		timerCount = 0;
 		timerMsg++;
@@ -138,8 +138,8 @@ void deathRevive() {
 
 	g_context->_party->reviveParty();
 
-	screenEnableCursor();
-	screenShowCursor();
+	g_screen->screenEnableCursor();
+	g_screen->screenShowCursor();
 	g_context->_stats->setView(STATS_PARTY_OVERVIEW);
 	g_screen->update();
 }
diff --git a/engines/ultima/ultima4/game/game.cpp b/engines/ultima/ultima4/game/game.cpp
index 00839ee2f8..914d4897a8 100644
--- a/engines/ultima/ultima4/game/game.cpp
+++ b/engines/ultima/ultima4/game/game.cpp
@@ -104,19 +104,19 @@ void gameSetViewMode(ViewMode newMode) {
 void gameUpdateScreen() {
 	switch (g_context->_location->_viewMode) {
 	case VIEW_NORMAL:
-		screenUpdate(&g_game->_mapArea, true, false);
+		g_screen->screenUpdate(&g_game->_mapArea, true, false);
 		break;
 	case VIEW_GEM:
-		screenGemUpdate();
+		g_screen->screenGemUpdate();
 		break;
 	case VIEW_RUNE:
-		screenUpdate(&g_game->_mapArea, false, false);
+		g_screen->screenUpdate(&g_game->_mapArea, false, false);
 		break;
 	case VIEW_DUNGEON:
-		screenUpdate(&g_game->_mapArea, true, false);
+		g_screen->screenUpdate(&g_game->_mapArea, true, false);
 		break;
 	case VIEW_DEAD:
-		screenUpdate(&g_game->_mapArea, true, true);
+		g_screen->screenUpdate(&g_game->_mapArea, true, true);
 		break;
 	case VIEW_CODEX: /* the screen updates will be handled elsewhere */
 		break;
@@ -165,7 +165,7 @@ void gameSpellEffect(int spell, int player, Sound sound) {
 		if (effect == Spell::SFX_TREMOR) {
 			gameUpdateScreen();
 			soundPlay(SOUND_RUMBLE, false);
-			screenShake(8);
+			g_screen->screenShake(8);
 
 		}
 
@@ -174,8 +174,8 @@ void gameSpellEffect(int spell, int player, Sound sound) {
 }
 
 Common::String gameGetInput(int maxlen) {
-	screenEnableCursor();
-	screenShowCursor();
+	g_screen->screenEnableCursor();
+	g_screen->screenShowCursor();
 #ifdef IOS
 	U4IOS::IOSConversationHelper helper;
 	helper.beginConversation(U4IOS::UIKeyboardTypeDefault);
@@ -198,18 +198,18 @@ int gameGetPlayer(bool canBeDisabled, bool canBeActivePlayer) {
 		}
 
 		if (player == -1) {
-			screenMessage("None\n");
+			g_screen->screenMessage("None\n");
 			return -1;
 		}
 	}
 
 	g_context->col--;// display the selected character name, in place of the number
 	if ((player >= 0) && (player < 8)) {
-		screenMessage("%s\n", g_ultima->_saveGame->_players[player].name); //Write player's name after prompt
+		g_screen->screenMessage("%s\n", g_ultima->_saveGame->_players[player].name); //Write player's name after prompt
 	}
 
 	if (!canBeDisabled && g_context->_party->member(player)->isDisabled()) {
-		screenMessage("%cDisabled!%c\n", FG_GREY, FG_WHITE);
+		g_screen->screenMessage("%cDisabled!%c\n", FG_GREY, FG_WHITE);
 		return -1;
 	}
 
@@ -220,7 +220,7 @@ int gameGetPlayer(bool canBeDisabled, bool canBeActivePlayer) {
 Direction gameGetDirection() {
 	ReadDirController dirController;
 
-	screenMessage("Dir?");
+	g_screen->screenMessage("Dir?");
 #ifdef IOS
 	U4IOS::IOSDirectionHelper directionPopup;
 #endif
@@ -228,13 +228,13 @@ Direction gameGetDirection() {
 	eventHandler->pushController(&dirController);
 	Direction dir = dirController.waitFor();
 
-	screenMessage("\b\b\b\b");
+	g_screen->screenMessage("\b\b\b\b");
 
 	if (dir == DIR_NONE) {
-		screenMessage("    \n");
+		g_screen->screenMessage("    \n");
 		return dir;
 	} else {
-		screenMessage("%s\n", getDirectionName(dir));
+		g_screen->screenMessage("%s\n", getDirectionName(dir));
 		return dir;
 	}
 }
@@ -311,7 +311,7 @@ bool gamePeerCity(int city, void *data) {
 		g_game->_paused = true;
 		g_game->_pausedTimer = 0;
 
-		screenDisableCursor();
+		g_screen->screenDisableCursor();
 #ifdef IOS
 		U4IOS::IOSConversationChoiceHelper continueHelper;
 		continueHelper.updateChoices(" ");
@@ -320,7 +320,7 @@ bool gamePeerCity(int city, void *data) {
 		ReadChoiceController::get("\015 \033");
 
 		g_game->exitToParentMap();
-		screenEnableCursor();
+		g_screen->screenEnableCursor();
 		g_game->_paused = false;
 
 		return true;
@@ -335,17 +335,17 @@ void peer(bool useGem) {
 
 	if (useGem) {
 		if (g_ultima->_saveGame->_gems <= 0) {
-			screenMessage("%cPeer at What?%c\n", FG_GREY, FG_WHITE);
+			g_screen->screenMessage("%cPeer at What?%c\n", FG_GREY, FG_WHITE);
 			return;
 		}
 
 		g_ultima->_saveGame->_gems--;
-		screenMessage("Peer at a Gem!\n");
+		g_screen->screenMessage("Peer at a Gem!\n");
 	}
 
 	g_game->_paused = true;
 	g_game->_pausedTimer = 0;
-	screenDisableCursor();
+	g_screen->screenDisableCursor();
 
 	g_context->_location->_viewMode = VIEW_GEM;
 #ifdef IOS
@@ -355,7 +355,7 @@ void peer(bool useGem) {
 #endif
 	ReadChoiceController::get("\015 \033");
 
-	screenEnableCursor();
+	g_screen->screenEnableCursor();
 	g_context->_location->_viewMode = VIEW_NORMAL;
 	g_game->_paused = false;
 }
@@ -370,7 +370,7 @@ void gameCheckHullIntegrity() {
 	bool killAll = false;
 	/* see if the ship has sunk */
 	if ((g_context->_transportContext == TRANSPORT_SHIP) && g_ultima->_saveGame->_shipHull <= 0) {
-		screenMessage("\nThy ship sinks!\n\n");
+		g_screen->screenMessage("\nThy ship sinks!\n\n");
 		killAll = true;
 	}
 
@@ -379,7 +379,7 @@ void gameCheckHullIntegrity() {
 	        g_context->_location->_map->tileTypeAt(g_context->_location->_coords, WITHOUT_OBJECTS)->isSailable() &&
 	        !g_context->_location->_map->tileTypeAt(g_context->_location->_coords, WITH_GROUND_OBJECTS)->isShip() &&
 	        !g_context->_location->_map->getValidMoves(g_context->_location->_coords, g_context->_party->getTransport())) {
-		screenMessage("\nTrapped at sea without thy ship, thou dost drown!\n\n");
+		g_screen->screenMessage("\nTrapped at sea without thy ship, thou dost drown!\n\n");
 		killAll = true;
 	}
 
@@ -442,7 +442,7 @@ void gameCreatureAttack(Creature *m) {
 	Object *under;
 	const Tile *ground;
 
-	screenMessage("\nAttacked by %s\n", m->getName().c_str());
+	g_screen->screenMessage("\nAttacked by %s\n", m->getName().c_str());
 
 	/// TODO: CHEST: Make a user option to not make chests change battlefield
 	/// map (2 of 2)
@@ -583,7 +583,7 @@ void gameDamageParty(int minDamage, int maxDamage) {
 		}
 	}
 
-	screenShake(1);
+	g_screen->screenShake(1);
 
 	// Un-highlight the last player
 	if (lastdmged != -1) g_context->_stats->highlightPlayer(lastdmged);
@@ -602,7 +602,7 @@ void gameDamageShip(int minDamage, int maxDamage) {
 		         xu4_random((maxDamage + 1) - minDamage) + minDamage :
 		         maxDamage;
 
-		screenShake(1);
+		g_screen->screenShake(1);
 
 		g_context->_party->damageShip(damage);
 		gameCheckHullIntegrity();
@@ -615,11 +615,11 @@ void gameDamageShip(int minDamage, int maxDamage) {
 void gameSetActivePlayer(int player) {
 	if (player == -1) {
 		g_context->_party->setActivePlayer(-1);
-		screenMessage("Set Active Player: None!\n");
+		g_screen->screenMessage("Set Active Player: None!\n");
 	} else if (player < g_context->_party->size()) {
-		screenMessage("Set Active Player: %s!\n", g_context->_party->member(player)->getName().c_str());
+		g_screen->screenMessage("Set Active Player: %s!\n", g_context->_party->member(player)->getName().c_str());
 		if (g_context->_party->member(player)->isDisabled())
-			screenMessage("Disabled!\n");
+			g_screen->screenMessage("Disabled!\n");
 		else
 			g_context->_party->setActivePlayer(player);
 	}
@@ -759,32 +759,32 @@ const int colors[] = {
 };
 
 void showMixturesSuper(int page = 0) {
-	screenTextColor(FG_WHITE);
+	g_screen->screenTextColor(FG_WHITE);
 	for (int i = 0; i < 13; i++) {
 		char buf[4];
 
 		const Spell *s = getSpell(i + 13 * page);
 		int line = i + 8;
-		screenTextAt(2, line, "%s", s->_name);
+		g_screen->screenTextAt(2, line, "%s", s->_name);
 
 		snprintf(buf, 4, "%3d", g_ultima->_saveGame->_mixtures[i + 13 * page]);
-		screenTextAt(6, line, "%s", buf);
+		g_screen->screenTextAt(6, line, "%s", buf);
 
-		screenShowChar(32, 9, line);
+		g_screen->screenShowChar(32, 9, line);
 		int comp = s->_components;
 		for (int j = 0; j < 8; j++) {
-			screenTextColor(colors[j]);
-			screenShowChar(comp & (1 << j) ? CHARSET_BULLET : ' ', 10 + j, line);
+			g_screen->screenTextColor(colors[j]);
+			g_screen->screenShowChar(comp & (1 << j) ? CHARSET_BULLET : ' ', 10 + j, line);
 		}
-		screenTextColor(FG_WHITE);
+		g_screen->screenTextColor(FG_WHITE);
 
 		snprintf(buf, 3, "%2d", s->_mp);
-		screenTextAt(19, line, "%s", buf);
+		g_screen->screenTextAt(19, line, "%s", buf);
 	}
 }
 
 void mixReagentsSuper() {
-	screenMessage("Mix reagents\n");
+	g_screen->screenMessage("Mix reagents\n");
 
 	static int page = 0;
 
@@ -802,43 +802,43 @@ void mixReagentsSuper() {
 
 	int oldlocation = g_context->_location->_viewMode;
 	g_context->_location->_viewMode = VIEW_MIXTURES;
-	screenUpdate(&g_game->_mapArea, true, true);
+	g_screen->screenUpdate(&g_game->_mapArea, true, true);
 
-	screenTextAt(16, 2, "%s", "<-Shops");
+	g_screen->screenTextAt(16, 2, "%s", "<-Shops");
 
 	g_context->_stats->setView(StatsView(STATS_REAGENTS));
-	screenTextColor(FG_PURPLE);
-	screenTextAt(2, 7, "%s", "SPELL # Reagents MP");
+	g_screen->screenTextColor(FG_PURPLE);
+	g_screen->screenTextAt(2, 7, "%s", "SPELL # Reagents MP");
 
 	for (int i = 0; i < shopcount; i++) {
 		int line = i + 1;
 		ReagentShop *s = &shops[i];
-		screenTextColor(FG_WHITE);
-		screenTextAt(2, line, "%s", s->name);
+		g_screen->screenTextColor(FG_WHITE);
+		g_screen->screenTextAt(2, line, "%s", s->name);
 		for (int j = 0; j < 6; j++) {
-			screenTextColor(colors[j]);
-			screenShowChar('0' + s->price[j], 10 + j, line);
+			g_screen->screenTextColor(colors[j]);
+			g_screen->screenShowChar('0' + s->price[j], 10 + j, line);
 		}
 	}
 
 	for (int i = 0; i < 8; i++) {
-		screenTextColor(colors[i]);
-		screenShowChar('A' + i, 10 + i, 6);
+		g_screen->screenTextColor(colors[i]);
+		g_screen->screenShowChar('A' + i, 10 + i, 6);
 	}
 
 	bool done = false;
 	while (!done) {
 		showMixturesSuper(page);
-		screenMessage("For Spell: ");
+		g_screen->screenMessage("For Spell: ");
 
 		int spell = ReadChoiceController::get("abcdefghijklmnopqrstuvwxyz \033\n\r");
 		if (spell < 'a' || spell > 'z') {
-			screenMessage("\nDone.\n");
+			g_screen->screenMessage("\nDone.\n");
 			done = true;
 		} else {
 			spell -= 'a';
 			const Spell *s = getSpell(spell);
-			screenMessage("%s\n", s->_name);
+			g_screen->screenMessage("%s\n", s->_name);
 			page = (spell >= 13);
 			showMixturesSuper(page);
 
@@ -853,17 +853,17 @@ void mixReagentsSuper() {
 						ingQty = reagentQty;
 				}
 			}
-			screenMessage("You can make %d.\n", (mixQty > ingQty) ? ingQty : mixQty);
-			screenMessage("How many? ");
+			g_screen->screenMessage("You can make %d.\n", (mixQty > ingQty) ? ingQty : mixQty);
+			g_screen->screenMessage("How many? ");
 
 			int howmany = ReadIntController::get(2, TEXT_AREA_X + g_context->col, TEXT_AREA_Y + g_context->_line);
 
 			if (howmany == 0) {
-				screenMessage("\nNone mixed!\n");
+				g_screen->screenMessage("\nNone mixed!\n");
 			} else if (howmany > mixQty) {
-				screenMessage("\n%cYou cannot mix that much more of that spell!%c\n", FG_GREY, FG_WHITE);
+				g_screen->screenMessage("\n%cYou cannot mix that much more of that spell!%c\n", FG_GREY, FG_WHITE);
 			} else if (howmany > ingQty) {
-				screenMessage("\n%cYou don't have enough reagents to mix %d spells!%c\n", FG_GREY, howmany, FG_WHITE);
+				g_screen->screenMessage("\n%cYou don't have enough reagents to mix %d spells!%c\n", FG_GREY, howmany, FG_WHITE);
 			} else {
 				g_ultima->_saveGame->_mixtures[spell] += howmany;
 				for (int i = 0; i < 8; i++) {
@@ -871,7 +871,7 @@ void mixReagentsSuper() {
 						g_ultima->_saveGame->_reagents[i] -= howmany;
 					}
 				}
-				screenMessage("\nSuccess!\n\n");
+				g_screen->screenMessage("\nSuccess!\n\n");
 			}
 		}
 		g_context->_stats->setView(StatsView(STATS_REAGENTS));
diff --git a/engines/ultima/ultima4/game/item.cpp b/engines/ultima/ultima4/game/item.cpp
index 91abf712a5..f6b15b21f8 100644
--- a/engines/ultima/ultima4/game/item.cpp
+++ b/engines/ultima/ultima4/game/item.cpp
@@ -360,7 +360,7 @@ void useBBC(int item) {
 #ifdef IOS
 			U4IOS::testFlightPassCheckPoint("The Bell rings on and on!");
 #endif
-			screenMessage("\nThe Bell rings on and on!\n");
+			g_screen->screenMessage("\nThe Bell rings on and on!\n");
 			g_ultima->_saveGame->_items |= ITEM_BELL_USED;
 		}
 		/* then the book */
@@ -368,27 +368,27 @@ void useBBC(int item) {
 #ifdef IOS
 			U4IOS::testFlightPassCheckPoint("The words resonate with the ringing!");
 #endif
-			screenMessage("\nThe words resonate with the ringing!\n");
+			g_screen->screenMessage("\nThe words resonate with the ringing!\n");
 			g_ultima->_saveGame->_items |= ITEM_BOOK_USED;
 		}
 		/* then the candle */
 		else if ((item == ITEM_CANDLE) && (g_ultima->_saveGame->_items & ITEM_BOOK_USED)) {
-			screenMessage("\nAs you light the Candle the Earth Trembles!\n");
+			g_screen->screenMessage("\nAs you light the Candle the Earth Trembles!\n");
 #ifdef IOS
 			U4IOS::testFlightPassCheckPoint("As you light the Candle the Earth Trembles!");
 #endif
 			g_ultima->_saveGame->_items |= ITEM_CANDLE_USED;
-		} else screenMessage("\nHmm...No effect!\n");
+		} else g_screen->screenMessage("\nHmm...No effect!\n");
 	}
 	/* somewhere else */
-	else screenMessage("\nHmm...No effect!\n");
+	else g_screen->screenMessage("\nHmm...No effect!\n");
 }
 
 /**
  * Uses the silver horn
  */
 void useHorn(int item) {
-	screenMessage("\nThe Horn sounds an eerie tone!\n");
+	g_screen->screenMessage("\nThe Horn sounds an eerie tone!\n");
 	g_context->_aura->set(Aura::HORN, 10);
 }
 
@@ -397,9 +397,9 @@ void useHorn(int item) {
  */
 void useWheel(int item) {
 	if ((g_context->_transportContext == TRANSPORT_SHIP) && (g_ultima->_saveGame->_shipHull == 50)) {
-		screenMessage("\nOnce mounted, the Wheel glows with a blue light!\n");
+		g_screen->screenMessage("\nOnce mounted, the Wheel glows with a blue light!\n");
 		g_context->_party->setShipHull(99);
-	} else screenMessage("\nHmm...No effect!\n");
+	} else g_screen->screenMessage("\nHmm...No effect!\n");
 }
 
 /**
@@ -412,13 +412,13 @@ void useSkull(int item) {
 	/* We do the check here instead of in the table, because we need to distinguish between a
 	   never-found skull and a destroyed skull. */
 	if (g_ultima->_saveGame->_items & ITEM_SKULL_DESTROYED) {
-		screenMessage("\nNone owned!\n");
+		g_screen->screenMessage("\nNone owned!\n");
 		return;
 	}
 
 	/* destroy the skull! pat yourself on the back */
 	if (g_context->_location->_coords.x == 0xe9 && g_context->_location->_coords.y == 0xe9) {
-		screenMessage("\n\nYou cast the Skull of Mondain into the Abyss!\n");
+		g_screen->screenMessage("\n\nYou cast the Skull of Mondain into the Abyss!\n");
 #ifdef IOS
 		U4IOS::testFlightPassCheckPoint("You cast the Skull of Mondain into the Abyss!");
 #endif
@@ -429,7 +429,7 @@ void useSkull(int item) {
 
 	/* use the skull... bad, very bad */
 	else {
-		screenMessage("\n\nYou hold the evil Skull of Mondain the Wizard aloft...\n");
+		g_screen->screenMessage("\n\nYou hold the evil Skull of Mondain the Wizard aloft...\n");
 #ifdef IOS
 		U4IOS::testFlightPassCheckPoint("You hold the evil Skull of Mondain the Wizard aloft...");
 #endif
@@ -489,7 +489,7 @@ void useStone(int item) {
 						stoneMask |= stone;
 					/* we already used that stone! */
 					else if (stone & stoneMask) {
-						screenMessage("\nAlready used!\n");
+						g_screen->screenMessage("\nAlready used!\n");
 						needStoneNames = 0;
 						stoneMask = 0; /* reset the mask so you can try again */
 						return;
@@ -498,7 +498,7 @@ void useStone(int item) {
 
 				/* see if we have all the stones, if not, get more names! */
 				if (attr && needStoneNames) {
-					screenMessage("\n%c:", 'E' - needStoneNames);
+					g_screen->screenMessage("\n%c:", 'E' - needStoneNames);
 #ifdef IOS
 					U4IOS::IOSConversationHelper::setIntroString("Which Color?");
 #endif
@@ -538,9 +538,9 @@ void useStone(int item) {
 						}
 						U4IOS::testFlightPassCheckPoint("Receive a key: " + keyName);
 #endif
-						screenMessage("\nThou doth find one third of the Three Part Key!\n");
+						g_screen->screenMessage("\nThou doth find one third of the Three Part Key!\n");
 						g_ultima->_saveGame->_items |= key;
-					} else screenMessage("\nHmm...No effect!\n");
+					} else g_screen->screenMessage("\nHmm...No effect!\n");
 
 					stoneMask = 0; /* reset the mask so you can try again */
 				}
@@ -553,7 +553,7 @@ void useStone(int item) {
 					if (g_context->_location->_coords.z < 7) {
 						/* replace the altar with a down-ladder */
 						MapCoords pos;
-						screenMessage("\n\nThe altar changes before thyne eyes!\n");
+						g_screen->screenMessage("\n\nThe altar changes before thyne eyes!\n");
 						g_context->_location->getCurrentPosition(&pos);
 						g_context->_location->_map->_annotations->add(pos, g_context->_location->_map->_tileset->getByName("down_ladder")->getId());
 					}
@@ -561,10 +561,10 @@ void useStone(int item) {
 					else {
 						codexStart();
 					}
-				} else screenMessage("\nHmm...No effect!\n");
+				} else g_screen->screenMessage("\nHmm...No effect!\n");
 			}
 		} else {
-			screenMessage("\nNot a Usable Item!\n");
+			g_screen->screenMessage("\nNot a Usable Item!\n");
 			stoneMask = 0; /* reset the mask so you can try again */
 		}
 	}
@@ -578,8 +578,8 @@ void useStone(int item) {
 
 		int virtueMask = getBaseVirtues((Virtue)g_context->_location->_coords.z);
 		if (virtueMask > 0)
-			screenMessage("\n\nAs thou doth approach, a voice rings out: What virtue dost stem from %s?\n\n", getBaseVirtueName(virtueMask));
-		else screenMessage("\n\nA voice rings out:  What virtue exists independently of Truth, Love, and Courage?\n\n");
+			g_screen->screenMessage("\n\nAs thou doth approach, a voice rings out: What virtue dost stem from %s?\n\n", getBaseVirtueName(virtueMask));
+		else g_screen->screenMessage("\n\nA voice rings out:  What virtue exists independently of Truth, Love, and Courage?\n\n");
 #ifdef IOS
 		U4IOS::IOSConversationHelper::setIntroString("Which virtue?");
 #endif
@@ -587,14 +587,14 @@ void useStone(int item) {
 
 		if (scumm_strnicmp(virtue.c_str(), getVirtueName((Virtue)g_context->_location->_coords.z), 6) == 0) {
 			/* now ask for stone */
-			screenMessage("\n\nThe Voice says: Use thy Stone.\n\nColor:\n");
+			g_screen->screenMessage("\n\nThe Voice says: Use thy Stone.\n\nColor:\n");
 			needStoneNames = 1;
 #ifdef IOS
 			U4IOS::IOSConversationHelper::setIntroString("Which color?");
 #endif
 			itemHandleStones(gameGetInput());
 		} else {
-			screenMessage("\nHmm...No effect!\n");
+			g_screen->screenMessage("\nHmm...No effect!\n");
 		}
 	}
 
@@ -604,18 +604,18 @@ void useStone(int item) {
 	else if ((g_context->_location->_context & CTX_ALTAR_ROOM) &&
 	         coords.x == 5 && coords.y == 5) {
 		needStoneNames = 4;
-		screenMessage("\n\nThere are holes for 4 stones.\nWhat colors:\nA:");
+		g_screen->screenMessage("\n\nThere are holes for 4 stones.\nWhat colors:\nA:");
 #ifdef IOS
 		U4IOS::IOSConversationHelper::setIntroString("Which color?");
 #endif
 		itemHandleStones(gameGetInput());
-	} else screenMessage("\nNo place to Use them!\n");
+	} else g_screen->screenMessage("\nNo place to Use them!\n");
 	// This used to say "\nNo place to Use them!\nHmm...No effect!\n"
 	// That doesn't match U4DOS; does it match another?
 }
 
 void useKey(int item) {
-	screenMessage("\nNo place to Use them!\n");
+	g_screen->screenMessage("\nNo place to Use them!\n");
 }
 
 bool isMysticInInventory(int mystic) {
@@ -667,7 +667,7 @@ void putWeaponInInventory(int weapon) {
 }
 
 void useTelescope(int notused) {
-	screenMessage("You see a knob\non the telescope\nmarked A-P\nYou Select:");
+	g_screen->screenMessage("You see a knob\non the telescope\nmarked A-P\nYou Select:");
 #ifdef IOS
 	U4IOS::IOSConversationChoiceHelper telescopeHelper;
 	telescopeHelper.updateChoices("abcdefghijklmnop ");
@@ -691,7 +691,7 @@ void putReagentInInventory(int reag) {
 
 	if (g_ultima->_saveGame->_reagents[reag] > 99) {
 		g_ultima->_saveGame->_reagents[reag] = 99;
-		screenMessage("Dropped some!\n");
+		g_screen->screenMessage("Dropped some!\n");
 	}
 }
 
@@ -746,11 +746,11 @@ void itemUse(const Common::String &shortname) {
 
 				/* use the item, if we can! */
 				if (!item || !item->_useItem)
-					screenMessage("\nNot a Usable item!\n");
+					g_screen->screenMessage("\nNot a Usable item!\n");
 				else
 					(*item->_useItem)(ITEMS[i]._data);
 			} else
-				screenMessage("\nNone owned!\n");
+				g_screen->screenMessage("\nNone owned!\n");
 
 			/* we found the item, no need to keep searching */
 			break;
@@ -759,7 +759,7 @@ void itemUse(const Common::String &shortname) {
 
 	/* item was not found */
 	if (!item)
-		screenMessage("\nNot a Usable item!\n");
+		g_screen->screenMessage("\nNot a Usable item!\n");
 }
 
 /**
@@ -771,7 +771,7 @@ bool isAbyssOpened(const Portal *p) {
 	int isopened = (items & ITEM_BELL_USED) && (items & ITEM_BOOK_USED) && (items & ITEM_CANDLE_USED);
 
 	if (!isopened)
-		screenMessage("Enter Can't!\n");
+		g_screen->screenMessage("Enter Can't!\n");
 	return isopened;
 }
 
@@ -790,7 +790,7 @@ void itemHandleStones(const Common::String &color) {
 	}
 
 	if (!found) {
-		screenMessage("\nNone owned!\n");
+		g_screen->screenMessage("\nNone owned!\n");
 		stoneMask = 0; /* make sure stone mask is reset */
 	}
 }
diff --git a/engines/ultima/ultima4/game/object.cpp b/engines/ultima/ultima4/game/object.cpp
index a7ad4b0e3b..2e9f63124f 100644
--- a/engines/ultima/ultima4/game/object.cpp
+++ b/engines/ultima/ultima4/game/object.cpp
@@ -57,9 +57,9 @@ void Object::remove() {
 
 void Object::animateMovement() {
 	//TODO abstract movement - also make screen.h and game.h not required
-	screenTileUpdate(&g_game->_mapArea, _prevCoords, false);
-	if (screenTileUpdate(&g_game->_mapArea, _coords, false))
-		screenWait(1);
+	g_screen->screenTileUpdate(&g_game->_mapArea, _prevCoords, false);
+	if (g_screen->screenTileUpdate(&g_game->_mapArea, _coords, false))
+		g_screen->screenWait(1);
 }
 
 } // End of namespace Ultima4
diff --git a/engines/ultima/ultima4/game/portal.cpp b/engines/ultima/ultima4/game/portal.cpp
index 1ca6a87787..ea3611e56c 100644
--- a/engines/ultima/ultima4/game/portal.cpp
+++ b/engines/ultima/ultima4/game/portal.cpp
@@ -81,7 +81,7 @@ int usePortalAt(Location *location, MapCoords coords, PortalTriggerAction action
 		return 0;
 	/* must klimb or descend on foot! */
 	else if (g_context->_transportContext & ~TRANSPORT_FOOT && (action == ACTION_KLIMB || action == ACTION_DESCEND)) {
-		screenMessage("%sOnly on foot!\n", action == ACTION_KLIMB ? "Klimb\n" : "");
+		g_screen->screenMessage("%sOnly on foot!\n", action == ACTION_KLIMB ? "Klimb\n" : "");
 		return 1;
 	}
 
@@ -102,17 +102,17 @@ int usePortalAt(Location *location, MapCoords coords, PortalTriggerAction action
 			switch (destination->_type) {
 			case Map::CITY: {
 				City *city = dynamic_cast<City *>(destination);
-				screenMessage("Enter %s!\n\n%s\n\n", city->_type.c_str(), city->getName().c_str());
+				g_screen->screenMessage("Enter %s!\n\n%s\n\n", city->_type.c_str(), city->getName().c_str());
 			}
 			break;
 			case Map::SHRINE:
-				screenMessage("Enter the %s!\n\n", destination->getName().c_str());
+				g_screen->screenMessage("Enter the %s!\n\n", destination->getName().c_str());
 				break;
 			case Map::DUNGEON:
 #ifdef IOS
 				U4IOS::testFlightPassCheckPoint("Enter " + destination->getName());
 #endif
-				screenMessage("Enter dungeon!\n\n%s\n\n", destination->getName().c_str());
+				g_screen->screenMessage("Enter dungeon!\n\n%s\n\n", destination->getName().c_str());
 				break;
 			default:
 				break;
@@ -126,12 +126,12 @@ int usePortalAt(Location *location, MapCoords coords, PortalTriggerAction action
 
 	/* check the transportation requisites of the portal */
 	if (g_context->_transportContext & ~portal->_portalTransportRequisites) {
-		screenMessage("Only on foot!\n");
+		g_screen->screenMessage("Only on foot!\n");
 		return 1;
 	}
 	/* ok, we know the portal is going to work -- now display the custom message, if any */
 	else if (!portal->_message.empty() || strlen(msg))
-		screenMessage("%s", portal->_message.empty() ? msg : portal->_message.c_str());
+		g_screen->screenMessage("%s", portal->_message.empty() ? msg : portal->_message.c_str());
 
 	/* portal just exits to parent map */
 	if (portal->_exitPortal) {
diff --git a/engines/ultima/ultima4/game/script.cpp b/engines/ultima/ultima4/game/script.cpp
index f427655881..aa119b97e8 100644
--- a/engines/ultima/ultima4/game/script.cpp
+++ b/engines/ultima/ultima4/game/script.cpp
@@ -290,7 +290,7 @@ Script::ReturnCode Script::execute(Shared::XMLNode *script, Shared::XMLNode *cur
 		else {
 			if (_debug)
 				debug("A script with no children found (nowhere to go). Ending script...");
-			screenMessage("\n");
+			g_screen->screenMessage("\n");
 			_state = STATE_DONE;
 		}
 	}
@@ -323,7 +323,7 @@ Script::ReturnCode Script::execute(Shared::XMLNode *script, Shared::XMLNode *cur
 			if (output)
 				*output += content;
 			else
-				screenMessage("%s", content.c_str());
+				g_screen->screenMessage("%s", content.c_str());
 
 			if (_debug && content.size())
 				debug("Output: \n====================\n%s\n====================", content.c_str());
@@ -1006,9 +1006,9 @@ Script::ReturnCode Script::sleep(Shared::XMLNode *script, Shared::XMLNode *curre
 Script::ReturnCode Script::cursor(Shared::XMLNode *script, Shared::XMLNode *current) {
 	bool enable = current->getPropertyBool("enable");
 	if (enable)
-		screenEnableCursor();
+		g_screen->screenEnableCursor();
 	else
-		screenDisableCursor();
+		g_screen->screenDisableCursor();
 
 	return RET_OK;
 }
diff --git a/engines/ultima/ultima4/game/spell.cpp b/engines/ultima/ultima4/game/spell.cpp
index 226a71f1b7..4619dcc6da 100644
--- a/engines/ultima/ultima4/game/spell.cpp
+++ b/engines/ultima/ultima4/game/spell.cpp
@@ -766,7 +766,7 @@ static int spellWinds(int fromdir) {
 
 static int spellXit(int unused) {
 	if (!g_context->_location->_map->isWorldMap()) {
-		screenMessage("Leaving...\n");
+		g_screen->screenMessage("Leaving...\n");
 		g_game->exitToParentMap();
 		g_music->play();
 		return 1;
@@ -792,7 +792,7 @@ static int spellYup(int unused) {
 		}
 		/* exiting the dungeon */
 	} else {
-		screenMessage("Leaving...\n");
+		g_screen->screenMessage("Leaving...\n");
 		g_game->exitToParentMap();
 		g_music->play();
 		return 1;
diff --git a/engines/ultima/ultima4/gfx/imagemgr.cpp b/engines/ultima/ultima4/gfx/imagemgr.cpp
index f2df213d70..94796e4ce7 100644
--- a/engines/ultima/ultima4/gfx/imagemgr.cpp
+++ b/engines/ultima/ultima4/gfx/imagemgr.cpp
@@ -37,8 +37,6 @@ using Std::map;
 using Common::String;
 using Std::vector;
 
-Image *screenScale(Image *src, int scale, int n, int filter);
-
 bool ImageInfo::hasBlackBackground() {
 	return this->_filetype == "image/x-u4raw";
 }
@@ -649,7 +647,7 @@ ImageInfo *ImageMgr::get(const Common::String &name, bool returnUnscaled) {
 	}
 	imageScale /= info->_prescale;
 
-	info->_image = screenScale(unscaled, imageScale, info->_tiles, 1);
+	info->_image = g_screen->screenScale(unscaled, imageScale, info->_tiles, 1);
 
 	delete unscaled;
 	return info;
diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index 0de8eea17f..3f4c64ff31 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -48,13 +48,34 @@
 namespace Ultima {
 namespace Ultima4 {
 
-#define CURSOR_SIZE 20
+#define MOUSE_CURSOR_SIZE 20
+#define DBL_MAX 1e99
 
 Screen *g_screen;
 
+Std::vector<TileAnimSet *> tileanimSets;
+Std::vector<Common::String> gemLayoutNames;
+Std::vector<Common::String> filterNames;
+Std::vector<Common::String> lineOfSightStyles;
+Layout *gemlayout = NULL;
+Std::map<Common::String, int> dungeonTileChars;
+TileAnimSet *tileanims = NULL;
+ImageInfo *charsetInfo = NULL;
+ImageInfo *gemTilesInfo = NULL;
+
+int screenNeedPrompt = 1;
+int screenCurrentCycle = 0;
+int screenCursorX = 0;
+int screenCursorY = 0;
+int screenCursorStatus = 0;
+int screenCursorEnabled = 1;
+int screenLos[VIEWPORT_W][VIEWPORT_H];
+
+static const int BufferSize = 1024;
+
 Screen::Screen() : _filterScaler(nullptr), _currentMouseCursor(-1) {
 	g_screen = this;
-	Common::fill(&_cursors[0], &_cursors[5], (MouseCursorSurface *)nullptr);
+	Common::fill(&_mouseCursors[0], &_mouseCursors[5], (MouseCursorSurface *)nullptr);
 
 	Graphics::PixelFormat SCREEN_FORMAT(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	Common::Point size(SCREEN_WIDTH * settings._scale, SCREEN_HEIGHT * settings._scale);
@@ -70,7 +91,7 @@ Screen::~Screen() {
 
 	// Delete cursors
 	for (int idx = 0; idx < 5; ++idx)
-		delete _cursors[idx];
+		delete _mouseCursors[idx];
 }
 
 void Screen::init() {
@@ -93,7 +114,7 @@ void Screen::loadMouseCursors() {
 		Shared::File cursorsFile("data/graphics/cursors.txt");
 
 		for (int idx = 0; idx < 5; ++idx)
-			_cursors[idx] = loadMouseCursor(cursorsFile);
+			_mouseCursors[idx] = loadMouseCursor(cursorsFile);
 
 	} else {
 		g_system->showMouse(false);
@@ -105,39 +126,36 @@ void Screen::loadMouseCursors() {
 }
 
 void Screen::setMouseCursor(MouseCursor cursor) {
-	const MouseCursorSurface *c = _cursors[cursor];
+	const MouseCursorSurface *c = _mouseCursors[cursor];
 
 	if (c && cursor != _currentMouseCursor) {
 		_currentMouseCursor = cursor;
 
-		const uint TRANSPARENT = g_screen->format.RGBToColor(0x80, 0x80, 0x80);
-		CursorMan.replaceCursor(c->getPixels(), CURSOR_SIZE, CURSOR_SIZE,
-			c->_hotspot.x, c->_hotspot.y, TRANSPARENT, false, &g_screen->format);
+		const uint TRANSPARENT = format.RGBToColor(0x80, 0x80, 0x80);
+		CursorMan.replaceCursor(c->getPixels(), MOUSE_CURSOR_SIZE, MOUSE_CURSOR_SIZE,
+			c->_hotspot.x, c->_hotspot.y, TRANSPARENT, false, &format);
 	}
 }
 
-
-#define CURSOR_SIZE 20
-
 MouseCursorSurface *Screen::loadMouseCursor(Shared::File &src) {
 	uint row, col, endCol, pixel;
 	int hotX, hotY;
 	Common::String line;
 	byte *destP;
-	const uint WHITE = g_screen->format.RGBToColor(0xff, 0xff, 0xff);
-	const uint BLACK = g_screen->format.RGBToColor(0, 0, 0);
-	const uint TRANSPARENT = g_screen->format.RGBToColor(0x80, 0x80, 0x80);
-	int bpp = g_screen->format.bytesPerPixel;
+	const uint WHITE = format.RGBToColor(0xff, 0xff, 0xff);
+	const uint BLACK = format.RGBToColor(0, 0, 0);
+	const uint TRANSPARENT = format.RGBToColor(0x80, 0x80, 0x80);
+	int bpp = format.bytesPerPixel;
 	assert(bpp >= 2);
 
 	MouseCursorSurface *c = new MouseCursorSurface();
-	c->create(CURSOR_SIZE, CURSOR_SIZE, g_screen->format);
+	c->create(MOUSE_CURSOR_SIZE, MOUSE_CURSOR_SIZE, format);
 	c->clear(TRANSPARENT);
 
-	for (row = 0; row < CURSOR_SIZE; row++) {
+	for (row = 0; row < MOUSE_CURSOR_SIZE; row++) {
 		line = src.readLine();
 		destP = (byte *)c->getBasePtr(0, row);
-		endCol = MIN(line.size(), (uint)CURSOR_SIZE);
+		endCol = MIN(line.size(), (uint)MOUSE_CURSOR_SIZE);
 
 		for (col = 0; col < endCol; ++col, destP += bpp) {
 			pixel = TRANSPARENT;
@@ -162,39 +180,7 @@ MouseCursorSurface *Screen::loadMouseCursor(Shared::File &src) {
 	return c;
 }
 
-/*-------------------------------------------------------------------*/
-
-#define DBL_MAX 1e99
-
-void screenLoadGraphicsFromConf(void);
-Layout *screenLoadLayoutFromConf(const ConfigElement &conf);
-void screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus, int x, int y);
-
-Std::vector<TileAnimSet *> tileanimSets;
-Std::vector<Common::String> gemLayoutNames;
-Std::vector<Common::String> filterNames;
-Std::vector<Common::String> lineOfSightStyles;
-Layout *gemlayout = NULL;
-Std::map<Common::String, int> dungeonTileChars;
-TileAnimSet *tileanims = NULL;
-ImageInfo *charsetInfo = NULL;
-ImageInfo *gemTilesInfo = NULL;
-
-void screenFindLineOfSight(Std::vector<MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]);
-void screenFindLineOfSightDOS(Std::vector<MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]);
-void screenFindLineOfSightEnhanced(Std::vector<MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]);
-
-int screenNeedPrompt = 1;
-int screenCurrentCycle = 0;
-int screenCursorX = 0;
-int screenCursorY = 0;
-int screenCursorStatus = 0;
-int screenCursorEnabled = 1;
-int screenLos[VIEWPORT_W][VIEWPORT_H];
-
-static const int BufferSize = 1024;
-
-void screenInit() {
+void Screen::screenInit() {
 	filterNames.clear();
 	filterNames.push_back("point");
 	filterNames.push_back("2xBi");
@@ -253,20 +239,17 @@ void screenInit() {
 	dungeonTileChars["sleep_field"] = '^';
 }
 
-/**
- * Re-initializes the screen and implements any changes made in settings
- */
-void screenReInit() {
+void Screen::screenReInit() {
 	intro->deleteIntro();       /* delete intro stuff */
 	Tileset::unloadAllImages(); /* unload tilesets, which will be reloaded lazily as needed */
 	ImageMgr::destroy();
 	tileanims = NULL;
-	g_screen->clear();
-	g_screen->init();           // re-init screen stuff (loading new backgrounds, etc.)
+	clear();
+	init();           // re-init screen stuff (loading new backgrounds, etc.)
 	intro->init();    /* re-fix the backgrounds loaded and scale images, etc. */
 }
 
-void screenTextAt(int x, int y, const char *fmt, ...) {
+void Screen::screenTextAt(int x, int y, const char *fmt, ...) {
 	char buffer[BufferSize];
 	unsigned int i;
 
@@ -279,14 +262,14 @@ void screenTextAt(int x, int y, const char *fmt, ...) {
 		screenShowChar(buffer[i], x + i, y);
 }
 
-void screenPrompt() {
+void Screen::screenPrompt() {
 	if (screenNeedPrompt && screenCursorEnabled && g_context->col == 0) {
 		screenMessage("%c", CHARSET_PROMPT);
 		screenNeedPrompt = 0;
 	}
 }
 
-void screenMessage(const char *fmt, ...) {
+void Screen::screenMessage(const char *fmt, ...) {
 #ifdef IOS
 	static bool recursed = false;
 #endif
@@ -374,33 +357,21 @@ void screenMessage(const char *fmt, ...) {
 	screenNeedPrompt = 1;
 }
 
-const Std::vector<Common::String> &screenGetFilterNames() {
-	return filterNames;
-}
-
-const Std::vector<Common::String> &screenGetGemLayoutNames() {
-	return gemLayoutNames;
-}
-
-const Std::vector<Common::String> &screenGetLineOfSightStyles() {
-	return lineOfSightStyles;
-}
-
-void screenLoadGraphicsFromConf() {
+void Screen::screenLoadGraphicsFromConf() {
 	const Config *config = Config::getInstance();
 
 	Std::vector<ConfigElement> graphicsConf = config->getElement("graphics").getChildren();
 	for (Std::vector<ConfigElement>::iterator conf = graphicsConf.begin(); conf != graphicsConf.end(); conf++) {
 
 		if (conf->getName() == "layout")
-			g_screen->_layouts.push_back(screenLoadLayoutFromConf(*conf));
+			_layouts.push_back(screenLoadLayoutFromConf(*conf));
 		else if (conf->getName() == "tileanimset")
 			tileanimSets.push_back(new TileAnimSet(*conf));
 	}
 
 	gemLayoutNames.clear();
 	Std::vector<Layout *>::const_iterator i;
-	for (i = g_screen->_layouts.begin(); i != g_screen->_layouts.end(); i++) {
+	for (i = _layouts.begin(); i != _layouts.end(); i++) {
 		Layout *layout = *i;
 		if (layout->_type == LAYOUT_GEM) {
 			gemLayoutNames.push_back(layout->_name);
@@ -410,7 +381,7 @@ void screenLoadGraphicsFromConf() {
 	/*
 	 * Find gem layout to use.
 	 */
-	for (i = g_screen->_layouts.begin(); i != g_screen->_layouts.end(); i++) {
+	for (i = _layouts.begin(); i != _layouts.end(); i++) {
 		Layout *layout = *i;
 
 		if (layout->_type == LAYOUT_GEM && layout->_name == settings._gemLayout) {
@@ -422,7 +393,7 @@ void screenLoadGraphicsFromConf() {
 		errorFatal("no gem layout named %s found!\n", settings._gemLayout.c_str());
 }
 
-Layout *screenLoadLayoutFromConf(const ConfigElement &conf) {
+Layout *Screen::screenLoadLayoutFromConf(const ConfigElement &conf) {
 	Layout *layout;
 	static const char *typeEnumStrings[] = { "standard", "gem", "dungeon_gem", NULL };
 
@@ -447,8 +418,7 @@ Layout *screenLoadLayoutFromConf(const ConfigElement &conf) {
 }
 
 
-
-Std::vector<MapTile> screenViewportTile(unsigned int width, unsigned int height, int x, int y, bool &focus) {
+Std::vector<MapTile> Screen::screenViewportTile(unsigned int width, unsigned int height, int x, int y, bool &focus) {
 	MapCoords center = g_context->_location->_coords;
 	static MapTile grass = g_context->_location->_map->_tileset->getByName("grass")->getId();
 
@@ -477,7 +447,7 @@ Std::vector<MapTile> screenViewportTile(unsigned int width, unsigned int height,
 	return g_context->_location->tilesAt(tc, focus);
 }
 
-bool screenTileUpdate(TileView *view, const Coords &coords, bool redraw) {
+bool Screen::screenTileUpdate(TileView *view, const Coords &coords, bool redraw) {
 	if (g_context->_location->_map->_flags & FIRST_PERSON)
 		return false;
 
@@ -509,12 +479,7 @@ bool screenTileUpdate(TileView *view, const Coords &coords, bool redraw) {
 	return false;
 }
 
-/**
- * Redraw the screen.  If showmap is set, the normal map is drawn in
- * the map area.  If blackout is set, the map area is blacked out. If
- * neither is set, the map area is left untouched.
- */
-void screenUpdate(TileView *view, bool showmap, bool blackout) {
+void Screen::screenUpdate(TileView *view, bool showmap, bool blackout) {
 	ASSERT(g_context != NULL, "context has not yet been initialized");
 
 	if (blackout) {
@@ -555,10 +520,7 @@ void screenUpdate(TileView *view, bool showmap, bool blackout) {
 	screenUpdateWind();
 }
 
-/**
- * Draw an image or subimage on the screen.
- */
-void screenDrawImage(const Common::String &name, int x, int y) {
+void Screen::screenDrawImage(const Common::String &name, int x, int y) {
 	ImageInfo *info = imageMgr->get(name);
 	if (info) {
 		info->_image->alphaOn();
@@ -585,7 +547,7 @@ void screenDrawImage(const Common::String &name, int x, int y) {
 	errorFatal("ERROR 1006: Unable to load the image \"%s\".\t\n\nIs %s installed?\n\nVisit the XU4 website for additional information.\n\thttp://xu4.sourceforge.net/", name.c_str(), settings._game.c_str());
 }
 
-void screenDrawImageInMapArea(const Common::String &name) {
+void Screen::screenDrawImageInMapArea(const Common::String &name) {
 	ImageInfo *info;
 
 	info = imageMgr->get(name);
@@ -598,11 +560,7 @@ void screenDrawImageInMapArea(const Common::String &name) {
 	                          VIEWPORT_H * TILE_HEIGHT * settings._scale);
 }
 
-
-/**
- * Change the current text color
- */
-void screenTextColor(int color) {
+void Screen::screenTextColor(int color) {
 	if (charsetInfo == NULL) {
 		charsetInfo = imageMgr->get(BKGD_CHARSET);
 		if (!charsetInfo)
@@ -625,10 +583,7 @@ void screenTextColor(int color) {
 	}
 }
 
-/**
- * Draw a character from the charset onto the screen.
- */
-void screenShowChar(int chr, int x, int y) {
+void Screen::screenShowChar(int chr, int x, int y) {
 	if (charsetInfo == NULL) {
 		charsetInfo = imageMgr->get(BKGD_CHARSET);
 		if (!charsetInfo)
@@ -640,10 +595,7 @@ void screenShowChar(int chr, int x, int y) {
 	                                 charsetInfo->_image->width(), CHAR_HEIGHT * settings._scale);
 }
 
-/**
- * Scroll the text in the message area up one position.
- */
-void screenScrollMessageArea() {
+void Screen::screenScrollMessageArea() {
 	ASSERT(charsetInfo != NULL && charsetInfo->_image != NULL, "charset not initialized!");
 
 	Image *screen = imageMgr->get("screen")->_image;
@@ -663,16 +615,16 @@ void screenScrollMessageArea() {
 	                 CHAR_HEIGHT * settings._scale,
 	                 0, 0, 0);
 
-	g_screen->update();
+	update();
 }
 
-void screenCycle() {
+void Screen::screenCycle() {
 	if (++screenCurrentCycle >= SCR_CYCLE_MAX)
 		screenCurrentCycle = 0;
-	g_screen->update();
+	update();
 }
 
-void screenUpdateCursor() {
+void Screen::screenUpdateCursor() {
 	int phase = screenCurrentCycle * SCR_CYCLE_PER_SECOND / SCR_CYCLE_MAX;
 
 	ASSERT(phase >= 0 && phase < 4, "derived an invalid cursor phase: %d", phase);
@@ -683,7 +635,7 @@ void screenUpdateCursor() {
 	}
 }
 
-void screenUpdateMoons() {
+void Screen::screenUpdateMoons() {
 	int trammelChar, feluccaChar;
 
 	/* show "L?" for the dungeon level */
@@ -707,7 +659,7 @@ void screenUpdateMoons() {
 	screenRedrawTextArea(11, 0, 2, 1);
 }
 
-void screenUpdateWind() {
+void Screen::screenUpdateWind() {
 
 	/* show the direction we're facing in the dungeon */
 	if (g_context->_location->_context == CTX_DUNGEON) {
@@ -722,14 +674,14 @@ void screenUpdateWind() {
 	screenRedrawTextArea(WIND_AREA_X, WIND_AREA_Y, WIND_AREA_W, WIND_AREA_H);
 }
 
-void screenShowCursor() {
+void Screen::screenShowCursor() {
 	if (!screenCursorStatus && screenCursorEnabled) {
 		screenCursorStatus = 1;
 		screenUpdateCursor();
 	}
 }
 
-void screenHideCursor() {
+void Screen::screenHideCursor() {
 	if (screenCursorStatus) {
 		screenEraseTextArea(screenCursorX, screenCursorY, 1, 1);
 		screenRedrawTextArea(screenCursorX, screenCursorY, 1, 1);
@@ -737,25 +689,21 @@ void screenHideCursor() {
 	screenCursorStatus = 0;
 }
 
-void screenEnableCursor(void) {
+void Screen::screenEnableCursor(void) {
 	screenCursorEnabled = 1;
 }
 
-void screenDisableCursor(void) {
+void Screen::screenDisableCursor(void) {
 	screenHideCursor();
 	screenCursorEnabled = 0;
 }
 
-void screenSetCursorPos(int x, int y) {
+void Screen::screenSetCursorPos(int x, int y) {
 	screenCursorX = x;
 	screenCursorY = y;
 }
 
-/**
- * Finds which tiles in the viewport are visible from the avatars
- * location in the middle. (original DOS algorithm)
- */
-void screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
+void Screen::screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
 	int x, y;
 
 	if (!g_context)
@@ -790,12 +738,7 @@ void screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWP
 		errorFatal("unknown line of sight style %s!\n", settings._lineOfSight.c_str());
 }
 
-
-/**
- * Finds which tiles in the viewport are visible from the avatars
- * location in the middle. (original DOS algorithm)
- */
-void screenFindLineOfSightDOS(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
+void Screen::screenFindLineOfSightDOS(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
 	int x, y;
 
 	screenLos[VIEWPORT_W / 2][VIEWPORT_H / 2] = 1;
@@ -875,25 +818,7 @@ void screenFindLineOfSightDOS(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VI
 	}
 }
 
-/**
- * Finds which tiles in the viewport are visible from the avatars
- * location in the middle.
- *
- * A new, more accurate LOS function
- *
- * Based somewhat off Andy McFadden's 1994 article,
- *   "Improvements to a Fast Algorithm for Calculating Shading
- *   and Visibility in a Two-Dimensional Field"
- *   -----
- *   http://www.fadden.com/techmisc/fast-los.html
- *
- * This function uses a lookup table to get the correct shadowmap,
- * therefore, the table will need to be updated if the viewport
- * dimensions increase. Also, the function assumes that the
- * viewport width and height are odd values and that the player
- * is always at the center of the screen.
- */
-void screenFindLineOfSightEnhanced(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
+void Screen::screenFindLineOfSightEnhanced(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
 	int x, y;
 
 	/*
@@ -1121,13 +1046,7 @@ void screenFindLineOfSightEnhanced(Std::vector <MapTile> viewportTiles[VIEWPORT_
 	}
 }
 
-/**
- * Generates terms a and b for equation "ax + b = y" that defines the
- * line containing the two given points.  Vertical lines are special
- * cased to return DBL_MAX for a and the x coordinate as b since they
- * cannot be represented with the above formula.
- */
-static void screenGetLineTerms(int x1, int y1, int x2, int y2, double *a, double *b) {
+void Screen::screenGetLineTerms(int x1, int y1, int x2, int y2, double *a, double *b) {
 	if (x2 - x1 == 0) {
 		*a = DBL_MAX;
 		*b = x1;
@@ -1137,12 +1056,7 @@ static void screenGetLineTerms(int x1, int y1, int x2, int y2, double *a, double
 	}
 }
 
-/**
- * Determine if two points are on the same side of a line (or both on
- * the line).  The line is defined by the terms a and b of the
- * equation "ax + b = y".
- */
-static int screenPointsOnSameSideOfLine(int x1, int y1, int x2, int y2, double a, double b) {
+int Screen::screenPointsOnSameSideOfLine(int x1, int y1, int x2, int y2, double a, double b) {
 	double p1, p2;
 
 	if (a == DBL_MAX) {
@@ -1161,7 +1075,7 @@ static int screenPointsOnSameSideOfLine(int x1, int y1, int x2, int y2, double a
 	return 0;
 }
 
-static int screenPointInTriangle(int x, int y, int tx1, int ty1, int tx2, int ty2, int tx3, int ty3) {
+int Screen::screenPointInTriangle(int x, int y, int tx1, int ty1, int tx2, int ty2, int tx3, int ty3) {
 	double a[3], b[3];
 
 	screenGetLineTerms(tx1, ty1, tx2, ty2, &(a[0]), &(b[0]));
@@ -1178,10 +1092,7 @@ static int screenPointInTriangle(int x, int y, int tx1, int ty1, int tx2, int ty
 	return 1;
 }
 
-/**
- * Determine if the given point is within a mouse area.
- */
-int screenPointInMouseArea(int x, int y, const MouseArea *area) {
+int Screen::screenPointInMouseArea(int x, int y, const MouseArea *area) {
 	ASSERT(area->_nPoints == 2 || area->_nPoints == 3, "unsupported number of points in area: %d", area->_nPoints);
 
 	/* two points define a rectangle */
@@ -1205,11 +1116,11 @@ int screenPointInMouseArea(int x, int y, const MouseArea *area) {
 	return 0;
 }
 
-void screenRedrawMapArea() {
+void Screen::screenRedrawMapArea() {
 	g_game->_mapArea.update();
 }
 
-void screenEraseMapArea() {
+void Screen::screenEraseMapArea() {
 	Image *screen = imageMgr->get("screen")->_image;
 	screen->fillRect(BORDER_WIDTH * settings._scale,
 	                 BORDER_WIDTH * settings._scale,
@@ -1218,7 +1129,7 @@ void screenEraseMapArea() {
 	                 0, 0, 0);
 }
 
-void screenEraseTextArea(int x, int y, int width, int height) {
+void Screen::screenEraseTextArea(int x, int y, int width, int height) {
 	Image *screen = imageMgr->get("screen")->_image;
 	screen->fillRect(x * CHAR_WIDTH * settings._scale,
 	                 y * CHAR_HEIGHT * settings._scale,
@@ -1227,10 +1138,7 @@ void screenEraseTextArea(int x, int y, int width, int height) {
 	                 0, 0, 0);
 }
 
-/**
- * Do the tremor spell effect where the screen shakes.
- */
-void screenShake(int iterations) {
+void Screen::screenShake(int iterations) {
 	int shakeOffset;
 	unsigned short i;
 	Image *screen = imageMgr->get("screen")->_image;
@@ -1256,13 +1164,13 @@ void screenShake(int iterations) {
 			screen->drawSubRectOn(screen, 0, SCALED(shakeOffset), 0, 0, SCALED(320), SCALED(200 - (shakeOffset + 1)));
 			bottom->drawOn(screen, 0, SCALED(200 - (shakeOffset)));
 			screen->fillRect(0, 0, SCALED(320), SCALED(shakeOffset), 0, 0, 0);
-			g_screen->update();
+			update();
 			EventHandler::sleep(settings._shakeInterval);
 
 			// shift the screen back up, and replace the bottom row
 			screen->drawOn(screen, 0, 0 - SCALED(shakeOffset));
 			bottom->drawOn(screen, 0, SCALED(200 - (shakeOffset + 1)));
-			g_screen->update();
+			update();
 			EventHandler::sleep(settings._shakeInterval);
 		}
 		// free the bottom row image
@@ -1270,10 +1178,7 @@ void screenShake(int iterations) {
 	}
 }
 
-/**
- * Draw a tile graphic on the screen.
- */
-void screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus, int x, int y) {
+void Screen::screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus, int x, int y) {
 	// Make sure we account for tiles that look like other tiles (dungeon tiles, mainly)
 	Common::String looks_like = t.getTileType()->getLooksLike();
 	if (!looks_like.empty())
@@ -1317,10 +1222,10 @@ void screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus, int x,
 	}
 }
 
-Layout *screenGetGemLayout(const Map *map) {
+Layout *Screen::screenGetGemLayout(const Map *map) {
 	if (map->_type == Map::DUNGEON) {
 		Std::vector<Layout *>::const_iterator i;
-		for (i = g_screen->_layouts.begin(); i != g_screen->_layouts.end(); i++) {
+		for (i = _layouts.begin(); i != _layouts.end(); i++) {
 			Layout *layout = *i;
 
 			if (layout->_type == LAYOUT_DUNGEONGEM)
@@ -1333,7 +1238,7 @@ Layout *screenGetGemLayout(const Map *map) {
 }
 
 
-void screenGemUpdate() {
+void Screen::screenGemUpdate() {
 	MapTile tile;
 	int x, y;
 	Image *screen = imageMgr->get("screen")->_image;
@@ -1445,5 +1350,18 @@ void inline screenUnlock() {};
 void inline screenWait(int numberOfAnimationFrames) {};
 #endif
 
+
+const Std::vector<Common::String> &screenGetFilterNames() {
+	return filterNames;
+}
+
+const Std::vector<Common::String> &screenGetGemLayoutNames() {
+	return gemLayoutNames;
+}
+
+const Std::vector<Common::String> &screenGetLineOfSightStyles() {
+	return lineOfSightStyles;
+}
+
 } // End of namespace Ultima4
 } // End of namespace Ultima
diff --git a/engines/ultima/ultima4/gfx/screen.h b/engines/ultima/ultima4/gfx/screen.h
index a8d5fbdd76..159fb03bb2 100644
--- a/engines/ultima/ultima4/gfx/screen.h
+++ b/engines/ultima/ultima4/gfx/screen.h
@@ -24,6 +24,7 @@
 #define ULTIMA4_GFX_SCREEN_H
 
 #include "graphics/screen.h"
+#include "ultima/ultima4/core/config.h"
 #include "ultima/ultima4/core/types.h"
 #include "ultima/ultima4/filesys/u4file.h"
 #include "ultima/ultima4/gfx/scale.h"
@@ -99,7 +100,7 @@ struct Layout {
 
 class Screen : public Graphics::Screen {
 private:
-	MouseCursorSurface *_cursors[5];
+	MouseCursorSurface *_mouseCursors[5];
 	int _currentMouseCursor;
 private:
 	/**
@@ -111,6 +112,64 @@ private:
 	 * Loads the data for a single cursor from the passed file
 	 */
 	MouseCursorSurface *loadMouseCursor(Shared::File &src);
+
+	void screenLoadGraphicsFromConf();
+	Layout *screenLoadLayoutFromConf(const ConfigElement &conf);
+
+	/**
+	 * Draw a tile graphic on the screen.
+	 */
+	void screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus, int x, int y);
+
+	/**
+	 * Finds which tiles in the viewport are visible from the avatars
+	 * location in the middle. (original DOS algorithm)
+	 */
+	void screenFindLineOfSight(Std::vector<MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]);
+
+	/**
+	 * Finds which tiles in the viewport are visible from the avatars
+	 * location in the middle. (original DOS algorithm)
+	 */
+	void screenFindLineOfSightDOS(Std::vector<MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]);
+
+	/**
+	 * Finds which tiles in the viewport are visible from the avatars
+	 * location in the middle.
+	 *
+	 * A new, more accurate LOS function
+	 *
+	 * Based somewhat off Andy McFadden's 1994 article,
+	 *   "Improvements to a Fast Algorithm for Calculating Shading
+	 *   and Visibility in a Two-Dimensional Field"
+	 *   -----
+	 *   http://www.fadden.com/techmisc/fast-los.html
+	 *
+	 * This function uses a lookup table to get the correct shadowmap,
+	 * therefore, the table will need to be updated if the viewport
+	 * dimensions increase. Also, the function assumes that the
+	 * viewport width and height are odd values and that the player
+	 * is always at the center of the screen.
+	 */
+	void screenFindLineOfSightEnhanced(Std::vector<MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]);
+
+	/**
+	 * Generates terms a and b for equation "ax + b = y" that defines the
+	 * line containing the two given points.  Vertical lines are special
+	 * cased to return DBL_MAX for a and the x coordinate as b since they
+	 * cannot be represented with the above formula.
+	 */
+	void screenGetLineTerms(int x1, int y1, int x2, int y2, double *a, double *b);
+
+	/**
+	 * Determine if two points are on the same side of a line (or both on
+	 * the line).  The line is defined by the terms a and b of the
+	 * equation "ax + b = y".
+	 */
+	int screenPointsOnSameSideOfLine(int x1, int y1, int x2, int y2, double a, double b);
+
+	int screenPointInTriangle(int x, int y, int tx1, int ty1, int tx2, int ty2, int tx3, int ty3);
+	Layout *screenGetGemLayout(const Map *map);
 public:
 	Std::vector<Layout *> _layouts;
 	Scaler _filterScaler;
@@ -129,57 +188,89 @@ public:
 	 * Sets a given mouse cursor
 	 */
 	void setMouseCursor(MouseCursor cursor);
+
+	void screenInit(void);
+	void screenRefreshTimerInit(void);
+
+	/**
+	 * Re-initializes the screen and implements any changes made in settings
+	 */
+	void screenReInit(void);
+	void screenWait(int numberOfAnimationFrames);
+
+	/**
+	 * Draw an image or subimage on the screen.
+	 */
+	void screenDrawImage(const Common::String &name, int x = 0, int y = 0);
+	void screenDrawImageInMapArea(const Common::String &bkgd);
+
+	void screenCycle(void);
+	void screenEraseMapArea(void);
+	void screenEraseTextArea(int x, int y, int width, int height);
+	void screenGemUpdate(void);
+
+	void screenMessage(const char *fmt, ...) GCC_PRINTF(1, 2);
+	void screenPrompt(void);
+	void screenRedrawMapArea(void);
+	void screenRedrawTextArea(int x, int y, int width, int height);
+
+	/**
+	 * Scroll the text in the message area up one position.
+	 */
+	void screenScrollMessageArea(void);
+
+	/**
+	 * Do the tremor spell effect where the screen shakes.
+	 */
+	void screenShake(int iterations);
+
+	/**
+	 * Draw a character from the charset onto the screen.
+	 */
+	void screenShowChar(int chr, int x, int y);
+	void screenShowCharMasked(int chr, int x, int y, unsigned char mask);
+	void screenTextAt(int x, int y, const char *fmt, ...) GCC_PRINTF(3, 4);
+
+	/**
+	 * Change the current text color
+	 */
+	void screenTextColor(int color);
+	bool screenTileUpdate(TileView *view, const Coords &coords, bool redraw = true); //Returns true if the screen was affected
+
+	/**
+	 * Redraw the screen.  If showmap is set, the normal map is drawn in
+	 * the map area.  If blackout is set, the map area is blacked out. If
+	 * neither is set, the map area is left untouched.
+	 */
+	void screenUpdate(TileView *view, bool showmap, bool blackout);
+	void screenUpdateCursor(void);
+	void screenUpdateMoons(void);
+	void screenUpdateWind(void);
+	Std::vector<MapTile> screenViewportTile(unsigned int width, unsigned int height, int x, int y, bool &focus);
+
+	void screenShowCursor(void);
+	void screenHideCursor(void);
+	void screenEnableCursor(void);
+	void screenDisableCursor(void);
+	void screenSetCursorPos(int x, int y);
+
+	/**
+	 * Determine if the given point is within a mouse area.
+	 */
+	int screenPointInMouseArea(int x, int y, const MouseArea *area);
+
+	Image *screenScale(Image *src, int scale, int n, int filter);
+	Image *screenScaleDown(Image *src, int scale);
 };
 
 extern Screen *g_screen;
 
-void screenInit(void);
-void screenRefreshTimerInit(void);
-void screenReInit(void);
-void screenWait(int numberOfAnimationFrames);
-
-const Std::vector<Common::String> &screenGetGemLayoutNames();
-const Std::vector<Common::String> &screenGetFilterNames();
-const Std::vector<Common::String> &screenGetLineOfSightStyles();
-
-void screenDrawImage(const Common::String &name, int x = 0, int y = 0);
-void screenDrawImageInMapArea(const Common::String &bkgd);
-
-void screenCycle(void);
-void screenEraseMapArea(void);
-void screenEraseTextArea(int x, int y, int width, int height);
-void screenGemUpdate(void);
-
-void screenMessage(const char *fmt, ...) GCC_PRINTF(1, 2);
-void screenPrompt(void);
-void screenRedrawMapArea(void);
-void screenRedrawTextArea(int x, int y, int width, int height);
-void screenScrollMessageArea(void);
-void screenShake(int iterations);
-void screenShowChar(int chr, int x, int y);
-void screenShowCharMasked(int chr, int x, int y, unsigned char mask);
-void screenTextAt(int x, int y, const char *fmt, ...) GCC_PRINTF(3, 4);
-void screenTextColor(int color);
-bool screenTileUpdate(TileView *view, const Coords &coords, bool redraw = true); //Returns true if the screen was affected
-void screenUpdate(TileView *view, bool showmap, bool blackout);
-void screenUpdateCursor(void);
-void screenUpdateMoons(void);
-void screenUpdateWind(void);
-Std::vector<MapTile> screenViewportTile(unsigned int width, unsigned int height, int x, int y, bool &focus);
-
-void screenShowCursor(void);
-void screenHideCursor(void);
-void screenEnableCursor(void);
-void screenDisableCursor(void);
-void screenSetCursorPos(int x, int y);
-
-int screenPointInMouseArea(int x, int y, const MouseArea *area);
-
-Image *screenScale(Image *src, int scale, int n, int filter);
-Image *screenScaleDown(Image *src, int scale);
-
 extern int screenCurrentCycle;
 
+extern const Std::vector<Common::String> &screenGetGemLayoutNames();
+extern const Std::vector<Common::String> &screenGetFilterNames();
+extern const Std::vector<Common::String> &screenGetLineOfSightStyles();
+
 } // End of namespace Ultima4
 } // End of namespace Ultima
 
diff --git a/engines/ultima/ultima4/gfx/screen_scummvm.cpp b/engines/ultima/ultima4/gfx/screen_scummvm.cpp
index b96bb804b6..c9aaba1104 100644
--- a/engines/ultima/ultima4/gfx/screen_scummvm.cpp
+++ b/engines/ultima/ultima4/gfx/screen_scummvm.cpp
@@ -47,6 +47,8 @@ namespace Ultima4 {
 
 using Std::vector;
 
+//Image *screenScale(Image *src, int scale, int n, int filter);
+
 /**
  * Force a redraw.
  */
@@ -54,11 +56,11 @@ using Std::vector;
 //SDL_mutex *screenLockMutex = NULL;
 int frameDuration = 0;
 
-void screenRedrawTextArea(int x, int y, int width, int height) {
+void Screen::screenRedrawTextArea(int x, int y, int width, int height) {
 	g_system->updateScreen();
 }
 
-void screenWait(int numberOfAnimationFrames) {
+void Screen::screenWait(int numberOfAnimationFrames) {
 	g_system->delayMillis(numberOfAnimationFrames * frameDuration);
 }
 
@@ -71,7 +73,7 @@ bool continueScreenRefresh = true;
  * seperately. filter determines whether or not to filter the
  * resulting image.
  */
-Image *screenScale(Image *src, int scale, int n, int filter) {
+Image *Screen::screenScale(Image *src, int scale, int n, int filter) {
 	Image *dest = NULL;
 	bool isTransparent;
 	unsigned int transparentIndex;
@@ -83,13 +85,13 @@ Image *screenScale(Image *src, int scale, int n, int filter) {
 	isTransparent = src->getTransparentIndex(transparentIndex);
 	src->alphaOff();
 
-	while (filter && g_screen->_filterScaler && (scale % 2 == 0)) {
-		dest = (*g_screen->_filterScaler)(src, 2, n);
+	while (filter && _filterScaler && (scale % 2 == 0)) {
+		dest = (*_filterScaler)(src, 2, n);
 		src = dest;
 		scale /= 2;
 	}
 	if (scale == 3 && scaler3x(settings._filter)) {
-		dest = (*g_screen->_filterScaler)(src, 3, n);
+		dest = (*_filterScaler)(src, 3, n);
 		src = dest;
 		scale /= 3;
 	}
@@ -113,7 +115,7 @@ Image *screenScale(Image *src, int scale, int n, int filter) {
  * Scale an image down.  The resulting image will be 1/scale * the
  * original dimensions.  The original image is no longer deleted.
  */
-Image *screenScaleDown(Image *src, int scale) {
+Image *Screen::screenScaleDown(Image *src, int scale) {
 	int x, y;
 	Image *dest;
 	bool isTransparent;
diff --git a/engines/ultima/ultima4/map/dungeon.cpp b/engines/ultima/ultima4/map/dungeon.cpp
index 5e5a61ba91..93df4775fe 100644
--- a/engines/ultima/ultima4/map/dungeon.cpp
+++ b/engines/ultima/ultima4/map/dungeon.cpp
@@ -110,11 +110,11 @@ void dungeonSearch(void) {
 	if (a.size() > 0)
 		token = DUNGEON_CORRIDOR;
 
-	screenMessage("Search...\n");
+	g_screen->screenMessage("Search...\n");
 
 	switch (token) {
 	case DUNGEON_MAGIC_ORB: /* magic orb */
-		screenMessage("You find a Magical Ball...\nWho touches? ");
+		g_screen->screenMessage("You find a Magical Ball...\nWho touches? ");
 		dungeonTouchOrb();
 		break;
 
@@ -127,14 +127,14 @@ void dungeonSearch(void) {
 		item = itemAtLocation(dungeon, g_context->_location->_coords);
 		if (item) {
 			if (*item->_isItemInInventory != NULL && (*item->_isItemInInventory)(item->_data))
-				screenMessage("Nothing Here!\n");
+				g_screen->screenMessage("Nothing Here!\n");
 			else {
 				if (item->_name)
-					screenMessage("You find...\n%s!\n", item->_name);
+					g_screen->screenMessage("You find...\n%s!\n", item->_name);
 				(*item->_putItemInInventory)(item->_data);
 			}
 		} else
-			screenMessage("\nYou find Nothing!\n");
+			g_screen->screenMessage("\nYou find Nothing!\n");
 	}
 
 	break;
@@ -145,7 +145,7 @@ void dungeonSearch(void) {
  * Drink from the fountain at the current location
  */
 void dungeonDrinkFountain() {
-	screenMessage("You find a Fountain.\nWho drinks? ");
+	g_screen->screenMessage("You find a Fountain.\nWho drinks? ");
 	int player = gameGetPlayer(false, false);
 	if (player == -1)
 		return;
@@ -156,27 +156,27 @@ void dungeonDrinkFountain() {
 	switch (type) {
 	/* plain fountain */
 	case FOUNTAIN_NORMAL:
-		screenMessage("\nHmmm--No Effect!\n");
+		g_screen->screenMessage("\nHmmm--No Effect!\n");
 		break;
 
 	/* healing fountain */
 	case FOUNTAIN_HEALING:
 		if (g_context->_party->member(player)->heal(HT_FULLHEAL))
-			screenMessage("\nAhh-Refreshing!\n");
-		else screenMessage("\nHmmm--No Effect!\n");
+			g_screen->screenMessage("\nAhh-Refreshing!\n");
+		else g_screen->screenMessage("\nHmmm--No Effect!\n");
 		break;
 
 	/* acid fountain */
 	case FOUNTAIN_ACID:
 		g_context->_party->member(player)->applyDamage(100); /* 100 damage to drinker */
-		screenMessage("\nBleck--Nasty!\n");
+		g_screen->screenMessage("\nBleck--Nasty!\n");
 		break;
 
 	/* cure fountain */
 	case FOUNTAIN_CURE:
 		if (g_context->_party->member(player)->heal(HT_CURE))
-			screenMessage("\nHmmm--Delicious!\n");
-		else screenMessage("\nHmmm--No Effect!\n");
+			g_screen->screenMessage("\nHmmm--Delicious!\n");
+		else g_screen->screenMessage("\nHmmm--No Effect!\n");
 		break;
 
 	/* poison fountain */
@@ -185,8 +185,8 @@ void dungeonDrinkFountain() {
 			soundPlay(SOUND_POISON_DAMAGE);
 			g_context->_party->member(player)->applyEffect(EFFECT_POISON);
 			g_context->_party->member(player)->applyDamage(100); /* 100 damage to drinker also */
-			screenMessage("\nArgh-Choke-Gasp!\n");
-		} else screenMessage("\nHmm--No Effect!\n");
+			g_screen->screenMessage("\nArgh-Choke-Gasp!\n");
+		} else g_screen->screenMessage("\nHmm--No Effect!\n");
 		break;
 
 	default:
@@ -198,7 +198,7 @@ void dungeonDrinkFountain() {
  * Touch the magical ball at the current location
  */
 void dungeonTouchOrb() {
-	screenMessage("You find a Magical Ball...\nWho touches? ");
+	g_screen->screenMessage("You find a Magical Ball...\nWho touches? ");
 	int player = gameGetPlayer(false, false);
 	if (player == -1)
 		return;
@@ -238,17 +238,17 @@ void dungeonTouchOrb() {
 
 	/* give stats bonuses */
 	if (stats & STATSBONUS_STR) {
-		screenMessage("Strength + 5\n");
+		g_screen->screenMessage("Strength + 5\n");
 		AdjustValueMax(g_ultima->_saveGame->_players[player]._str, 5, 50);
 		damage += 200;
 	}
 	if (stats & STATSBONUS_DEX) {
-		screenMessage("Dexterity + 5\n");
+		g_screen->screenMessage("Dexterity + 5\n");
 		AdjustValueMax(g_ultima->_saveGame->_players[player]._dex, 5, 50);
 		damage += 200;
 	}
 	if (stats & STATSBONUS_INT) {
-		screenMessage("Intelligence + 5\n");
+		g_screen->screenMessage("Intelligence + 5\n");
 		AdjustValueMax(g_ultima->_saveGame->_players[player]._intel, 5, 50);
 		damage += 200;
 	}
@@ -266,17 +266,17 @@ bool dungeonHandleTrap(TrapType trap) {
 	Dungeon *dungeon = dynamic_cast<Dungeon *>(g_context->_location->_map);
 	switch ((TrapType)dungeon->currentSubToken()) {
 	case TRAP_WINDS:
-		screenMessage("\nWinds!\n");
+		g_screen->screenMessage("\nWinds!\n");
 		g_context->_party->quenchTorch();
 		break;
 	case TRAP_FALLING_ROCK:
 		// Treat falling rocks and pits like bomb traps
 		// XXX: That's a little harsh.
-		screenMessage("\nFalling Rocks!\n");
+		g_screen->screenMessage("\nFalling Rocks!\n");
 		g_context->_party->applyEffect(EFFECT_LAVA);
 		break;
 	case TRAP_PIT:
-		screenMessage("\nPit!\n");
+		g_screen->screenMessage("\nPit!\n");
 		g_context->_party->applyEffect(EFFECT_LAVA);
 		break;
 	default:
diff --git a/engines/ultima/ultima4/map/dungeonview.cpp b/engines/ultima/ultima4/map/dungeonview.cpp
index 9264f59979..69e9e6c262 100644
--- a/engines/ultima/ultima4/map/dungeonview.cpp
+++ b/engines/ultima/ultima4/map/dungeonview.cpp
@@ -58,7 +58,7 @@ void DungeonView::display(Context *c, TileView *view) {
 
 		Std::vector<MapTile> tiles;
 
-		screenEraseMapArea();
+		g_screen->screenEraseMapArea();
 		if (c->_party->getTorchDuration() > 0) {
 			for (y = 3; y >= 0; y--) {
 				DungeonGraphicType type;
@@ -159,9 +159,9 @@ void DungeonView::drawInDungeon(Tile *tile, int x_offset, int distance, Directio
 	if (dscale[distance] == 0)
 		return;
 	else if (dscale[distance] == 1)
-		scaled = screenScaleDown(_animated, 2);
+		scaled = g_screen->screenScaleDown(_animated, 2);
 	else {
-		scaled = screenScale(_animated, dscale[distance] / 2, 1, 0);
+		scaled = g_screen->screenScale(_animated, dscale[distance] / 2, 1, 0);
 	}
 
 	if (tiledWall) {
@@ -436,17 +436,17 @@ void DungeonView::drawWall(int xoffset, int distance, Direction orientation, Dun
 		y = subimage->y;
 	}
 
-	screenDrawImage(dngGraphicInfo[index].subimage, (BORDER_WIDTH + x) * settings._scale,
+	g_screen->screenDrawImage(dngGraphicInfo[index].subimage, (BORDER_WIDTH + x) * settings._scale,
 	                (BORDER_HEIGHT + y) * settings._scale);
 
 	if (dngGraphicInfo[index].subimage2 != NULL) {
 		// FIXME: subimage2 is a horrible hack, needs to be cleaned up
 		if (settings._videoType == "EGA")
-			screenDrawImage(dngGraphicInfo[index].subimage2,
+			g_screen->screenDrawImage(dngGraphicInfo[index].subimage2,
 			                (8 + dngGraphicInfo[index].ega_x2) * settings._scale,
 			                (8 + dngGraphicInfo[index].ega_y2) * settings._scale);
 		else
-			screenDrawImage(dngGraphicInfo[index].subimage2,
+			g_screen->screenDrawImage(dngGraphicInfo[index].subimage2,
 			                (8 + dngGraphicInfo[index].vga_x2) * settings._scale,
 			                (8 + dngGraphicInfo[index].vga_y2) * settings._scale);
 	}
diff --git a/engines/ultima/ultima4/map/shrine.cpp b/engines/ultima/ultima4/map/shrine.cpp
index 3c9f623913..25aac77c49 100644
--- a/engines/ultima/ultima4/map/shrine.cpp
+++ b/engines/ultima/ultima4/map/shrine.cpp
@@ -58,7 +58,7 @@ Std::vector<Common::String> shrineAdvice;
 bool shrineCanEnter(const Portal *p) {
 	Shrine *shrine = dynamic_cast<Shrine *>(mapMgr->get(p->_destid));
 	if (!g_context->_party->canEnterShrine(shrine->getVirtue())) {
-		screenMessage("Thou dost not bear the rune of entry!  A strange force keeps you out!\n");
+		g_screen->screenMessage("Thou dost not bear the rune of entry!  A strange force keeps you out!\n");
 		return 0;
 	}
 	return 1;
@@ -118,9 +118,9 @@ void Shrine::enter() {
 	if (settings._enhancements && settings._enhancementsOptions._u5shrines)
 		enhancedSequence();
 	else
-		screenMessage("You enter the ancient shrine and sit before the altar...");
+		g_screen->screenMessage("You enter the ancient shrine and sit before the altar...");
 
-	screenMessage("\nUpon which virtue dost thou meditate?\n");
+	g_screen->screenMessage("\nUpon which virtue dost thou meditate?\n");
 	Common::String virtue;
 #ifdef IOS
 	{
@@ -133,7 +133,7 @@ void Shrine::enter() {
 #endif
 
 	int choice;
-	screenMessage("\n\nFor how many Cycles (0-3)? ");
+	g_screen->screenMessage("\n\nFor how many Cycles (0-3)? ");
 #ifdef IOS
 	{
 		U4IOS::IOSConversationChoiceHelper cyclesChoice;
@@ -149,21 +149,21 @@ void Shrine::enter() {
 		cycles = choice - '0';
 	completedCycles = 0;
 
-	screenMessage("\n\n");
+	g_screen->screenMessage("\n\n");
 
 	// ensure the player chose the right virtue and entered a valid number for cycles
 	if (scumm_strnicmp(virtue.c_str(), getVirtueName(getVirtue()), 6) != 0 || cycles == 0) {
-		screenMessage("Thou art unable to focus thy thoughts on this subject!\n");
+		g_screen->screenMessage("Thou art unable to focus thy thoughts on this subject!\n");
 		eject();
 		return;
 	}
 
 	if (((g_ultima->_saveGame->_moves / SHRINE_MEDITATION_INTERVAL) >= 0x10000) ||
 	        (((g_ultima->_saveGame->_moves / SHRINE_MEDITATION_INTERVAL) & 0xffff) != g_ultima->_saveGame->_lastMeditation)) {
-		screenMessage("Begin Meditation\n");
+		g_screen->screenMessage("Begin Meditation\n");
 		meditationCycle();
 	} else {
-		screenMessage("Thy mind is still weary from thy last Meditation!\n");
+		g_screen->screenMessage("Thy mind is still weary from thy last Meditation!\n");
 		eject();
 	}
 }
@@ -172,8 +172,8 @@ void Shrine::enhancedSequence() {
 	/* replace the 'static' avatar tile with grass */
 	_annotations->add(Coords(5, 6, g_context->_location->_coords.z), _tileset->getByName("grass")->getId(), false, true);
 
-	screenDisableCursor();
-	screenMessage("You approach\nthe ancient\nshrine...\n");
+	g_screen->screenDisableCursor();
+	g_screen->screenMessage("You approach\nthe ancient\nshrine...\n");
 	gameUpdateScreen();
 	EventHandler::wait_cycles(settings._gameCyclesPerSecond);
 
@@ -197,9 +197,9 @@ void Shrine::enhancedSequence() {
 	obj->setTile(creatureMgr->getById(BEGGAR_ID)->getTile());
 	gameUpdateScreen();
 
-	screenMessage("\n...and kneel before the altar.\n");
+	g_screen->screenMessage("\n...and kneel before the altar.\n");
 	EventHandler::wait_cycles(settings._gameCyclesPerSecond);
-	screenEnableCursor();
+	g_screen->screenEnableCursor();
 }
 
 void Shrine::meditationCycle() {
@@ -212,20 +212,20 @@ void Shrine::meditationCycle() {
 
 	g_ultima->_saveGame->_lastMeditation = (g_ultima->_saveGame->_moves / SHRINE_MEDITATION_INTERVAL) & 0xffff;
 
-	screenDisableCursor();
+	g_screen->screenDisableCursor();
 	for (int i = 0; i < MEDITATION_MANTRAS_PER_CYCLE; i++) {
 		WaitController controller(interval);
 		eventHandler->pushController(&controller);
 		controller.wait();
-		screenMessage(".");
+		g_screen->screenMessage(".");
 		g_screen->update();
 	}
 	askMantra();
 }
 
 void Shrine::askMantra() {
-	screenEnableCursor();
-	screenMessage("\nMantra: ");
+	g_screen->screenEnableCursor();
+	g_screen->screenMessage("\nMantra: ");
 	g_screen->update();       // FIXME: needed?
 	Common::String mantra;
 #ifdef IOS
@@ -234,14 +234,14 @@ void Shrine::askMantra() {
 		mantraHelper.beginConversation(U4IOS::UIKeyboardTypeASCIICapable, "Mantra?");
 #endif
 		mantra = ReadStringController::get(4, TEXT_AREA_X + g_context->col, TEXT_AREA_Y + g_context->_line);
-		screenMessage("\n");
+		g_screen->screenMessage("\n");
 #ifdef IOS
 	}
 #endif
 
 	if (scumm_stricmp(mantra.c_str(), getMantra().c_str()) != 0) {
 		g_context->_party->adjustKarma(KA_BAD_MANTRA);
-		screenMessage("Thou art not able to focus thy thoughts with that Mantra!\n");
+		g_screen->screenMessage("Thou art not able to focus thy thoughts with that Mantra!\n");
 		eject();
 	} else if (--cycles > 0) {
 		completedCycles++;
@@ -253,10 +253,10 @@ void Shrine::askMantra() {
 
 		bool elevated = completedCycles == 3 && g_context->_party->attemptElevation(getVirtue());
 		if (elevated)
-			screenMessage("\nThou hast achieved partial Avatarhood in the Virtue of %s\n\n",
+			g_screen->screenMessage("\nThou hast achieved partial Avatarhood in the Virtue of %s\n\n",
 			              getVirtueName(getVirtue()));
 		else
-			screenMessage("\nThy thoughts are pure. "
+			g_screen->screenMessage("\nThy thoughts are pure. "
 			              "Thou art granted a vision!\n");
 
 #ifdef IOS
@@ -280,11 +280,11 @@ void Shrine::showVision(bool elevated) {
 	};
 
 	if (elevated) {
-		screenMessage("Thou art granted a vision!\n");
+		g_screen->screenMessage("Thou art granted a vision!\n");
 		gameSetViewMode(VIEW_RUNE);
-		screenDrawImageInMapArea(visionImageNames[getVirtue()]);
+		g_screen->screenDrawImageInMapArea(visionImageNames[getVirtue()]);
 	} else {
-		screenMessage("\n%s", shrineAdvice[getVirtue() * 3 + completedCycles - 1].c_str());
+		g_screen->screenMessage("\n%s", shrineAdvice[getVirtue() * 3 + completedCycles - 1].c_str());
 	}
 }
 
diff --git a/engines/ultima/ultima4/ultima4.cpp b/engines/ultima/ultima4/ultima4.cpp
index cbc3385cc4..79f913b92f 100644
--- a/engines/ultima/ultima4/ultima4.cpp
+++ b/engines/ultima/ultima4/ultima4.cpp
@@ -168,7 +168,7 @@ Common::Error Ultima4Engine::saveGameState(int slot, const Common::String &desc,
 
 Common::Error Ultima4Engine::loadGameStream(Common::SeekableReadStream *stream) {
 	g_ultima->_saveGame->load(stream);
-	screenUpdate(&g_game->_mapArea, true, false);
+	g_screen->screenUpdate(&g_game->_mapArea, true, false);
 	return Common::kNoError;
 }
 


Commit: 8f9cbfcbb17aa4105894a07121243dc4dbd77c33
    https://github.com/scummvm/scummvm/commit/8f9cbfcbb17aa4105894a07121243dc4dbd77c33
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-18T15:25:23-07:00

Commit Message:
ULTIMA4: Moving fields into Screen class

Changed paths:
    engines/ultima/ultima4/gfx/screen.cpp
    engines/ultima/ultima4/gfx/screen.h
    engines/ultima/ultima4/map/tile.cpp
    engines/ultima/ultima4/map/tileanim.cpp
    engines/ultima/ultima4/map/tileview.cpp


diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index 3f4c64ff31..f3d20f7d57 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -53,29 +53,16 @@ namespace Ultima4 {
 
 Screen *g_screen;
 
-Std::vector<TileAnimSet *> tileanimSets;
-Std::vector<Common::String> gemLayoutNames;
-Std::vector<Common::String> filterNames;
-Std::vector<Common::String> lineOfSightStyles;
-Layout *gemlayout = NULL;
-Std::map<Common::String, int> dungeonTileChars;
-TileAnimSet *tileanims = NULL;
-ImageInfo *charsetInfo = NULL;
-ImageInfo *gemTilesInfo = NULL;
-
-int screenNeedPrompt = 1;
-int screenCurrentCycle = 0;
-int screenCursorX = 0;
-int screenCursorY = 0;
-int screenCursorStatus = 0;
-int screenCursorEnabled = 1;
-int screenLos[VIEWPORT_W][VIEWPORT_H];
-
 static const int BufferSize = 1024;
 
-Screen::Screen() : _filterScaler(nullptr), _currentMouseCursor(-1) {
+Screen::Screen() : _filterScaler(nullptr), _currentMouseCursor(-1),
+		gemlayout(nullptr), tileanims(nullptr), charsetInfo(nullptr),
+		gemTilesInfo(nullptr), screenNeedPrompt(1),
+		screenCurrentCycle(0), screenCursorX(0), screenCursorY(0),
+		screenCursorStatus(0), screenCursorEnabled(1) {
 	g_screen = this;
 	Common::fill(&_mouseCursors[0], &_mouseCursors[5], (MouseCursorSurface *)nullptr);
+	Common::fill(&screenLos[0][0], &screenLos[VIEWPORT_W][0], 0);
 
 	Graphics::PixelFormat SCREEN_FORMAT(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	Common::Point size(SCREEN_WIDTH * settings._scale, SCREEN_HEIGHT * settings._scale);
@@ -1352,15 +1339,15 @@ void inline screenWait(int numberOfAnimationFrames) {};
 
 
 const Std::vector<Common::String> &screenGetFilterNames() {
-	return filterNames;
+	return g_screen->filterNames;
 }
 
 const Std::vector<Common::String> &screenGetGemLayoutNames() {
-	return gemLayoutNames;
+	return g_screen->gemLayoutNames;
 }
 
 const Std::vector<Common::String> &screenGetLineOfSightStyles() {
-	return lineOfSightStyles;
+	return g_screen->lineOfSightStyles;
 }
 
 } // End of namespace Ultima4
diff --git a/engines/ultima/ultima4/gfx/screen.h b/engines/ultima/ultima4/gfx/screen.h
index 159fb03bb2..e8507ee697 100644
--- a/engines/ultima/ultima4/gfx/screen.h
+++ b/engines/ultima/ultima4/gfx/screen.h
@@ -77,6 +77,8 @@ class Map;
 class Tile;
 class TileView;
 class Coords;
+class TileAnimSet;
+class ImageInfo;
 
 struct MouseCursorSurface : public Graphics::ManagedSurface {
 	Common::Point _hotspot;
@@ -102,6 +104,25 @@ class Screen : public Graphics::Screen {
 private:
 	MouseCursorSurface *_mouseCursors[5];
 	int _currentMouseCursor;
+
+	Std::vector<TileAnimSet *> tileanimSets;
+	Layout *gemlayout;
+	Std::map<Common::String, int> dungeonTileChars;
+	ImageInfo *charsetInfo;
+	ImageInfo *gemTilesInfo;
+
+	int screenNeedPrompt;
+	int screenCursorX;
+	int screenCursorY;
+	int screenCursorStatus;
+	int screenCursorEnabled;
+	int screenLos[VIEWPORT_W][VIEWPORT_H];
+public:
+	Std::vector<Common::String> gemLayoutNames;
+	Std::vector<Common::String> filterNames;
+	Std::vector<Common::String> lineOfSightStyles;
+	int screenCurrentCycle;
+	TileAnimSet *tileanims;
 private:
 	/**
 	 * Load the cursors
@@ -265,8 +286,6 @@ public:
 
 extern Screen *g_screen;
 
-extern int screenCurrentCycle;
-
 extern const Std::vector<Common::String> &screenGetGemLayoutNames();
 extern const Std::vector<Common::String> &screenGetFilterNames();
 extern const Std::vector<Common::String> &screenGetLineOfSightStyles();
diff --git a/engines/ultima/ultima4/map/tile.cpp b/engines/ultima/ultima4/map/tile.cpp
index ef1d024c8f..f63d022d26 100644
--- a/engines/ultima/ultima4/map/tile.cpp
+++ b/engines/ultima/ultima4/map/tile.cpp
@@ -27,6 +27,7 @@
 #include "ultima/ultima4/core/error.h"
 #include "ultima/ultima4/gfx/image.h"
 #include "ultima/ultima4/gfx/imagemgr.h"
+#include "ultima/ultima4/gfx/screen.h"
 #include "ultima/ultima4/map/location.h"
 #include "ultima/ultima4/core/settings.h"
 #include "ultima/ultima4/map/tileanim.h"
@@ -37,8 +38,6 @@
 namespace Ultima {
 namespace Ultima4 {
 
-extern TileAnimSet *tileanims;
-
 TileId Tile::_nextId = 0;
 
 Tile::Tile(Tileset *tileset)
@@ -171,8 +170,8 @@ void Tile::loadImage() {
 
 		if (_animationRule.size() > 0) {
 			_anim = NULL;
-			if (tileanims)
-				_anim = tileanims->getByName(_animationRule);
+			if (g_screen->tileanims)
+				_anim = g_screen->tileanims->getByName(_animationRule);
 			if (_anim == NULL)
 				errorWarning("Warning: animation style '%s' not found", _animationRule.c_str());
 		}
diff --git a/engines/ultima/ultima4/map/tileanim.cpp b/engines/ultima/ultima4/map/tileanim.cpp
index 99876bc5d6..39442f4def 100644
--- a/engines/ultima/ultima4/map/tileanim.cpp
+++ b/engines/ultima/ultima4/map/tileanim.cpp
@@ -158,7 +158,7 @@ void TileAnimScrollTransform::draw(Image *dest, Tile *tile, MapTile &mapTile) {
 	if (_increment == 0)
 		_increment = tile->getScale();
 
-	int offset = screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND * tile->getScale();
+	int offset = g_screen->screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND * tile->getScale();
 	if (_lastOffset != offset) {
 		_lastOffset = offset;
 		_current += _increment;
diff --git a/engines/ultima/ultima4/map/tileview.cpp b/engines/ultima/ultima4/map/tileview.cpp
index 04c47fcc8c..eb22f25d03 100644
--- a/engines/ultima/ultima4/map/tileview.cpp
+++ b/engines/ultima/ultima4/map/tileview.cpp
@@ -175,7 +175,7 @@ void TileView::drawFocus(int x, int y) {
 	ASSERT(y < _rows, "y value of %d out of range", y);
 
 	// Draw the focus rectangle around the tile
-	if ((screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND) % 2) {
+	if ((g_screen->screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND) % 2) {
 		// left edge
 		_screen->fillRect(SCALED(x * _tileWidth + this->_x),
 			SCALED(y * _tileHeight + this->_y),


Commit: e6419f918a08203fabd234e043b4e6454da52793
    https://github.com/scummvm/scummvm/commit/e6419f918a08203fabd234e043b4e6454da52793
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-18T15:25:23-07:00

Commit Message:
ULTIMA4: Renaming new Screen fields

Changed paths:
    engines/ultima/ultima4/gfx/screen.cpp
    engines/ultima/ultima4/gfx/screen.h
    engines/ultima/ultima4/map/tile.cpp
    engines/ultima/ultima4/map/tileanim.cpp
    engines/ultima/ultima4/map/tileview.cpp


diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index f3d20f7d57..55d2e778e0 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -56,13 +56,12 @@ Screen *g_screen;
 static const int BufferSize = 1024;
 
 Screen::Screen() : _filterScaler(nullptr), _currentMouseCursor(-1),
-		gemlayout(nullptr), tileanims(nullptr), charsetInfo(nullptr),
-		gemTilesInfo(nullptr), screenNeedPrompt(1),
-		screenCurrentCycle(0), screenCursorX(0), screenCursorY(0),
-		screenCursorStatus(0), screenCursorEnabled(1) {
+		_gemLayout(nullptr), _tileAnims(nullptr), _charSetInfo(nullptr),
+		_gemTilesInfo(nullptr), _needPrompt(1), _currentCycle(0),
+		_cursorStatus(0), _cursorEnabled(1) {
 	g_screen = this;
 	Common::fill(&_mouseCursors[0], &_mouseCursors[5], (MouseCursorSurface *)nullptr);
-	Common::fill(&screenLos[0][0], &screenLos[VIEWPORT_W][0], 0);
+	Common::fill(&_los[0][0], &_los[VIEWPORT_W][0], 0);
 
 	Graphics::PixelFormat SCREEN_FORMAT(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	Common::Point size(SCREEN_WIDTH * settings._scale, SCREEN_HEIGHT * settings._scale);
@@ -168,18 +167,18 @@ MouseCursorSurface *Screen::loadMouseCursor(Shared::File &src) {
 }
 
 void Screen::screenInit() {
-	filterNames.clear();
-	filterNames.push_back("point");
-	filterNames.push_back("2xBi");
-	filterNames.push_back("2xSaI");
-	filterNames.push_back("Scale2x");
+	_filterNames.clear();
+	_filterNames.push_back("point");
+	_filterNames.push_back("2xBi");
+	_filterNames.push_back("2xSaI");
+	_filterNames.push_back("Scale2x");
 
-	lineOfSightStyles.clear();
-	lineOfSightStyles.push_back("DOS");
-	lineOfSightStyles.push_back("Enhanced");
+	_lineOfSightStyles.clear();
+	_lineOfSightStyles.push_back("DOS");
+	_lineOfSightStyles.push_back("Enhanced");
 
-	charsetInfo = NULL;
-	gemTilesInfo = NULL;
+	_charSetInfo = NULL;
+	_gemTilesInfo = NULL;
 
 	screenLoadGraphicsFromConf();
 
@@ -193,44 +192,44 @@ void Screen::screenInit() {
 	KeyHandler::setKeyRepeat(settings._keydelay, settings._keyinterval);
 
 	/* find the tile animations for our tileset */
-	tileanims = NULL;
-	for (Std::vector<TileAnimSet *>::const_iterator i = tileanimSets.begin(); i != tileanimSets.end(); i++) {
+	_tileAnims = NULL;
+	for (Std::vector<TileAnimSet *>::const_iterator i = _tileAnimSets.begin(); i != _tileAnimSets.end(); i++) {
 		TileAnimSet *set = *i;
 		if (set->_name == settings._videoType)
-			tileanims = set;
+			_tileAnims = set;
 	}
-	if (!tileanims)
+	if (!_tileAnims)
 		errorFatal("unable to find tile animations for \"%s\" video mode in graphics.xml", settings._videoType.c_str());
 
-	dungeonTileChars.clear();
-	dungeonTileChars["brick_floor"] = CHARSET_FLOOR;
-	dungeonTileChars["up_ladder"] = CHARSET_LADDER_UP;
-	dungeonTileChars["down_ladder"] = CHARSET_LADDER_DOWN;
-	dungeonTileChars["up_down_ladder"] = CHARSET_LADDER_UPDOWN;
-	dungeonTileChars["chest"] = '$';
-	dungeonTileChars["ceiling_hole"] = CHARSET_FLOOR;
-	dungeonTileChars["floor_hole"] = CHARSET_FLOOR;
-	dungeonTileChars["magic_orb"] = CHARSET_ORB;
-	dungeonTileChars["ceiling_hole"] = 'T';
-	dungeonTileChars["floor_hole"] = 'T';
-	dungeonTileChars["fountain"] = 'F';
-	dungeonTileChars["secret_door"] = CHARSET_SDOOR;
-	dungeonTileChars["brick_wall"] = CHARSET_WALL;
-	dungeonTileChars["dungeon_door"] = CHARSET_ROOM;
-	dungeonTileChars["avatar"] = CHARSET_REDDOT;
-	dungeonTileChars["dungeon_room"] = CHARSET_ROOM;
-	dungeonTileChars["dungeon_altar"] = CHARSET_ANKH;
-	dungeonTileChars["energy_field"] = '^';
-	dungeonTileChars["fire_field"] = '^';
-	dungeonTileChars["poison_field"] = '^';
-	dungeonTileChars["sleep_field"] = '^';
+	_dungeonTileChars.clear();
+	_dungeonTileChars["brick_floor"] = CHARSET_FLOOR;
+	_dungeonTileChars["up_ladder"] = CHARSET_LADDER_UP;
+	_dungeonTileChars["down_ladder"] = CHARSET_LADDER_DOWN;
+	_dungeonTileChars["up_down_ladder"] = CHARSET_LADDER_UPDOWN;
+	_dungeonTileChars["chest"] = '$';
+	_dungeonTileChars["ceiling_hole"] = CHARSET_FLOOR;
+	_dungeonTileChars["floor_hole"] = CHARSET_FLOOR;
+	_dungeonTileChars["magic_orb"] = CHARSET_ORB;
+	_dungeonTileChars["ceiling_hole"] = 'T';
+	_dungeonTileChars["floor_hole"] = 'T';
+	_dungeonTileChars["fountain"] = 'F';
+	_dungeonTileChars["secret_door"] = CHARSET_SDOOR;
+	_dungeonTileChars["brick_wall"] = CHARSET_WALL;
+	_dungeonTileChars["dungeon_door"] = CHARSET_ROOM;
+	_dungeonTileChars["avatar"] = CHARSET_REDDOT;
+	_dungeonTileChars["dungeon_room"] = CHARSET_ROOM;
+	_dungeonTileChars["dungeon_altar"] = CHARSET_ANKH;
+	_dungeonTileChars["energy_field"] = '^';
+	_dungeonTileChars["fire_field"] = '^';
+	_dungeonTileChars["poison_field"] = '^';
+	_dungeonTileChars["sleep_field"] = '^';
 }
 
 void Screen::screenReInit() {
 	intro->deleteIntro();       /* delete intro stuff */
 	Tileset::unloadAllImages(); /* unload tilesets, which will be reloaded lazily as needed */
 	ImageMgr::destroy();
-	tileanims = NULL;
+	_tileAnims = NULL;
 	clear();
 	init();           // re-init screen stuff (loading new backgrounds, etc.)
 	intro->init();    /* re-fix the backgrounds loaded and scale images, etc. */
@@ -250,9 +249,9 @@ void Screen::screenTextAt(int x, int y, const char *fmt, ...) {
 }
 
 void Screen::screenPrompt() {
-	if (screenNeedPrompt && screenCursorEnabled && g_context->col == 0) {
+	if (_needPrompt && _cursorEnabled && g_context->col == 0) {
 		screenMessage("%c", CHARSET_PROMPT);
-		screenNeedPrompt = 0;
+		_needPrompt = 0;
 	}
 }
 
@@ -341,7 +340,7 @@ void Screen::screenMessage(const char *fmt, ...) {
 	screenSetCursorPos(TEXT_AREA_X + g_context->col, TEXT_AREA_Y + g_context->_line);
 	screenShowCursor();
 
-	screenNeedPrompt = 1;
+	_needPrompt = 1;
 }
 
 void Screen::screenLoadGraphicsFromConf() {
@@ -353,15 +352,15 @@ void Screen::screenLoadGraphicsFromConf() {
 		if (conf->getName() == "layout")
 			_layouts.push_back(screenLoadLayoutFromConf(*conf));
 		else if (conf->getName() == "tileanimset")
-			tileanimSets.push_back(new TileAnimSet(*conf));
+			_tileAnimSets.push_back(new TileAnimSet(*conf));
 	}
 
-	gemLayoutNames.clear();
+	_gemLayoutNames.clear();
 	Std::vector<Layout *>::const_iterator i;
 	for (i = _layouts.begin(); i != _layouts.end(); i++) {
 		Layout *layout = *i;
 		if (layout->_type == LAYOUT_GEM) {
-			gemLayoutNames.push_back(layout->_name);
+			_gemLayoutNames.push_back(layout->_name);
 		}
 	}
 
@@ -372,11 +371,11 @@ void Screen::screenLoadGraphicsFromConf() {
 		Layout *layout = *i;
 
 		if (layout->_type == LAYOUT_GEM && layout->_name == settings._gemLayout) {
-			gemlayout = layout;
+			_gemLayout = layout;
 			break;
 		}
 	}
-	if (!gemlayout)
+	if (!_gemLayout)
 		errorFatal("no gem layout named %s found!\n", settings._gemLayout.c_str());
 }
 
@@ -455,7 +454,7 @@ bool Screen::screenTileUpdate(TileView *view, const Coords &coords, bool redraw)
 	}
 
 	// Draw if it is on screen
-	if (x >= 0 && y >= 0 && x < VIEWPORT_W && y < VIEWPORT_H && screenLos[x][y]) {
+	if (x >= 0 && y >= 0 && x < VIEWPORT_W && y < VIEWPORT_H && _los[x][y]) {
 		view->drawTile(tiles, focus, x, y);
 
 		if (redraw) {
@@ -493,7 +492,7 @@ void Screen::screenUpdate(TileView *view, bool showmap, bool blackout) {
 
 		for (y = 0; y < VIEWPORT_H; y++) {
 			for (x = 0; x < VIEWPORT_W; x++) {
-				if (screenLos[x][y]) {
+				if (_los[x][y]) {
 					view->drawTile(viewportTiles[x][y], viewportFocus[x][y], x, y);
 				} else
 					view->drawTile(black, false, x, y);
@@ -548,9 +547,9 @@ void Screen::screenDrawImageInMapArea(const Common::String &name) {
 }
 
 void Screen::screenTextColor(int color) {
-	if (charsetInfo == NULL) {
-		charsetInfo = imageMgr->get(BKGD_CHARSET);
-		if (!charsetInfo)
+	if (_charSetInfo == NULL) {
+		_charSetInfo = imageMgr->get(BKGD_CHARSET);
+		if (!_charSetInfo)
 			errorFatal("ERROR 1003: Unable to load the \"%s\" data file.\t\n\nIs %s installed?\n\nVisit the XU4 website for additional information.\n\thttp://xu4.sourceforge.net/", BKGD_CHARSET, settings._game.c_str());
 	}
 
@@ -566,39 +565,39 @@ void Screen::screenTextColor(int color) {
 	case FG_RED:
 	case FG_YELLOW:
 	case FG_WHITE:
-		charsetInfo->_image->setFontColorFG((ColorFG)color);
+		_charSetInfo->_image->setFontColorFG((ColorFG)color);
 	}
 }
 
 void Screen::screenShowChar(int chr, int x, int y) {
-	if (charsetInfo == NULL) {
-		charsetInfo = imageMgr->get(BKGD_CHARSET);
-		if (!charsetInfo)
+	if (_charSetInfo == NULL) {
+		_charSetInfo = imageMgr->get(BKGD_CHARSET);
+		if (!_charSetInfo)
 			error("ERROR 1001: Unable to load the \"%s\" data file", BKGD_CHARSET);
 	}
 
-	charsetInfo->_image->drawSubRect(x * charsetInfo->_image->width(), y * (CHAR_HEIGHT * settings._scale),
+	_charSetInfo->_image->drawSubRect(x * _charSetInfo->_image->width(), y * (CHAR_HEIGHT * settings._scale),
 	                                 0, chr * (CHAR_HEIGHT * settings._scale),
-	                                 charsetInfo->_image->width(), CHAR_HEIGHT * settings._scale);
+	                                 _charSetInfo->_image->width(), CHAR_HEIGHT * settings._scale);
 }
 
 void Screen::screenScrollMessageArea() {
-	ASSERT(charsetInfo != NULL && charsetInfo->_image != NULL, "charset not initialized!");
+	ASSERT(_charSetInfo != NULL && _charSetInfo->_image != NULL, "charset not initialized!");
 
 	Image *screen = imageMgr->get("screen")->_image;
 
 	screen->drawSubRectOn(screen,
-	                      TEXT_AREA_X * charsetInfo->_image->width(),
+	                      TEXT_AREA_X * _charSetInfo->_image->width(),
 	                      TEXT_AREA_Y * CHAR_HEIGHT * settings._scale,
-	                      TEXT_AREA_X * charsetInfo->_image->width(),
+	                      TEXT_AREA_X * _charSetInfo->_image->width(),
 	                      (TEXT_AREA_Y + 1) * CHAR_HEIGHT * settings._scale,
-	                      TEXT_AREA_W * charsetInfo->_image->width(),
+	                      TEXT_AREA_W * _charSetInfo->_image->width(),
 	                      (TEXT_AREA_H - 1) * CHAR_HEIGHT * settings._scale);
 
 
-	screen->fillRect(TEXT_AREA_X * charsetInfo->_image->width(),
+	screen->fillRect(TEXT_AREA_X * _charSetInfo->_image->width(),
 	                 TEXT_AREA_Y * CHAR_HEIGHT * settings._scale + (TEXT_AREA_H - 1) * CHAR_HEIGHT * settings._scale,
-	                 TEXT_AREA_W * charsetInfo->_image->width(),
+	                 TEXT_AREA_W * _charSetInfo->_image->width(),
 	                 CHAR_HEIGHT * settings._scale,
 	                 0, 0, 0);
 
@@ -606,19 +605,19 @@ void Screen::screenScrollMessageArea() {
 }
 
 void Screen::screenCycle() {
-	if (++screenCurrentCycle >= SCR_CYCLE_MAX)
-		screenCurrentCycle = 0;
+	if (++_currentCycle >= SCR_CYCLE_MAX)
+		_currentCycle = 0;
 	update();
 }
 
 void Screen::screenUpdateCursor() {
-	int phase = screenCurrentCycle * SCR_CYCLE_PER_SECOND / SCR_CYCLE_MAX;
+	int phase = _currentCycle * SCR_CYCLE_PER_SECOND / SCR_CYCLE_MAX;
 
 	ASSERT(phase >= 0 && phase < 4, "derived an invalid cursor phase: %d", phase);
 
-	if (screenCursorStatus) {
-		screenShowChar(31 - phase, screenCursorX, screenCursorY);
-		screenRedrawTextArea(screenCursorX, screenCursorY, 1, 1);
+	if (_cursorStatus) {
+		screenShowChar(31 - phase, _cursorPos.x, _cursorPos.y);
+		screenRedrawTextArea(_cursorPos.x, _cursorPos.y, 1, 1);
 	}
 }
 
@@ -662,32 +661,32 @@ void Screen::screenUpdateWind() {
 }
 
 void Screen::screenShowCursor() {
-	if (!screenCursorStatus && screenCursorEnabled) {
-		screenCursorStatus = 1;
+	if (!_cursorStatus && _cursorEnabled) {
+		_cursorStatus = 1;
 		screenUpdateCursor();
 	}
 }
 
 void Screen::screenHideCursor() {
-	if (screenCursorStatus) {
-		screenEraseTextArea(screenCursorX, screenCursorY, 1, 1);
-		screenRedrawTextArea(screenCursorX, screenCursorY, 1, 1);
+	if (_cursorStatus) {
+		screenEraseTextArea(_cursorPos.x, _cursorPos.y, 1, 1);
+		screenRedrawTextArea(_cursorPos.x, _cursorPos.y, 1, 1);
 	}
-	screenCursorStatus = 0;
+	_cursorStatus = 0;
 }
 
 void Screen::screenEnableCursor(void) {
-	screenCursorEnabled = 1;
+	_cursorEnabled = 1;
 }
 
 void Screen::screenDisableCursor(void) {
 	screenHideCursor();
-	screenCursorEnabled = 0;
+	_cursorEnabled = 0;
 }
 
 void Screen::screenSetCursorPos(int x, int y) {
-	screenCursorX = x;
-	screenCursorY = y;
+	_cursorPos.x = x;
+	_cursorPos.y = y;
 }
 
 void Screen::screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
@@ -702,7 +701,7 @@ void Screen::screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_
 	if (g_context->_location->_map->_flags & NO_LINE_OF_SIGHT) {
 		for (y = 0; y < VIEWPORT_H; y++) {
 			for (x = 0; x < VIEWPORT_W; x++) {
-				screenLos[x][y] = 1;
+				_los[x][y] = 1;
 			}
 		}
 		return;
@@ -713,7 +712,7 @@ void Screen::screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_
 	 */
 	for (y = 0; y < VIEWPORT_H; y++) {
 		for (x = 0; x < VIEWPORT_W; x++) {
-			screenLos[x][y] = 0;
+			_los[x][y] = 0;
 		}
 	}
 
@@ -728,79 +727,79 @@ void Screen::screenFindLineOfSight(Std::vector <MapTile> viewportTiles[VIEWPORT_
 void Screen::screenFindLineOfSightDOS(Std::vector <MapTile> viewportTiles[VIEWPORT_W][VIEWPORT_H]) {
 	int x, y;
 
-	screenLos[VIEWPORT_W / 2][VIEWPORT_H / 2] = 1;
+	_los[VIEWPORT_W / 2][VIEWPORT_H / 2] = 1;
 
 	for (x = VIEWPORT_W / 2 - 1; x >= 0; x--)
-		if (screenLos[x + 1][VIEWPORT_H / 2] &&
+		if (_los[x + 1][VIEWPORT_H / 2] &&
 		        !viewportTiles[x + 1][VIEWPORT_H / 2].front().getTileType()->isOpaque())
-			screenLos[x][VIEWPORT_H / 2] = 1;
+			_los[x][VIEWPORT_H / 2] = 1;
 
 	for (x = VIEWPORT_W / 2 + 1; x < VIEWPORT_W; x++)
-		if (screenLos[x - 1][VIEWPORT_H / 2] &&
+		if (_los[x - 1][VIEWPORT_H / 2] &&
 		        !viewportTiles[x - 1][VIEWPORT_H / 2].front().getTileType()->isOpaque())
-			screenLos[x][VIEWPORT_H / 2] = 1;
+			_los[x][VIEWPORT_H / 2] = 1;
 
 	for (y = VIEWPORT_H / 2 - 1; y >= 0; y--)
-		if (screenLos[VIEWPORT_W / 2][y + 1] &&
+		if (_los[VIEWPORT_W / 2][y + 1] &&
 		        !viewportTiles[VIEWPORT_W / 2][y + 1].front().getTileType()->isOpaque())
-			screenLos[VIEWPORT_W / 2][y] = 1;
+			_los[VIEWPORT_W / 2][y] = 1;
 
 	for (y = VIEWPORT_H / 2 + 1; y < VIEWPORT_H; y++)
-		if (screenLos[VIEWPORT_W / 2][y - 1] &&
+		if (_los[VIEWPORT_W / 2][y - 1] &&
 		        !viewportTiles[VIEWPORT_W / 2][y - 1].front().getTileType()->isOpaque())
-			screenLos[VIEWPORT_W / 2][y] = 1;
+			_los[VIEWPORT_W / 2][y] = 1;
 
 	for (y = VIEWPORT_H / 2 - 1; y >= 0; y--) {
 
 		for (x = VIEWPORT_W / 2 - 1; x >= 0; x--) {
-			if (screenLos[x][y + 1] &&
+			if (_los[x][y + 1] &&
 			        !viewportTiles[x][y + 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x + 1][y] &&
+				_los[x][y] = 1;
+			else if (_los[x + 1][y] &&
 			         !viewportTiles[x + 1][y].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x + 1][y + 1] &&
+				_los[x][y] = 1;
+			else if (_los[x + 1][y + 1] &&
 			         !viewportTiles[x + 1][y + 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
+				_los[x][y] = 1;
 		}
 
 		for (x = VIEWPORT_W / 2 + 1; x < VIEWPORT_W; x++) {
-			if (screenLos[x][y + 1] &&
+			if (_los[x][y + 1] &&
 			        !viewportTiles[x][y + 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x - 1][y] &&
+				_los[x][y] = 1;
+			else if (_los[x - 1][y] &&
 			         !viewportTiles[x - 1][y].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x - 1][y + 1] &&
+				_los[x][y] = 1;
+			else if (_los[x - 1][y + 1] &&
 			         !viewportTiles[x - 1][y + 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
+				_los[x][y] = 1;
 		}
 	}
 
 	for (y = VIEWPORT_H / 2 + 1; y < VIEWPORT_H; y++) {
 
 		for (x = VIEWPORT_W / 2 - 1; x >= 0; x--) {
-			if (screenLos[x][y - 1] &&
+			if (_los[x][y - 1] &&
 			        !viewportTiles[x][y - 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x + 1][y] &&
+				_los[x][y] = 1;
+			else if (_los[x + 1][y] &&
 			         !viewportTiles[x + 1][y].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x + 1][y - 1] &&
+				_los[x][y] = 1;
+			else if (_los[x + 1][y - 1] &&
 			         !viewportTiles[x + 1][y - 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
+				_los[x][y] = 1;
 		}
 
 		for (x = VIEWPORT_W / 2 + 1; x < VIEWPORT_W; x++) {
-			if (screenLos[x][y - 1] &&
+			if (_los[x][y - 1] &&
 			        !viewportTiles[x][y - 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x - 1][y] &&
+				_los[x][y] = 1;
+			else if (_los[x - 1][y] &&
 			         !viewportTiles[x - 1][y].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
-			else if (screenLos[x - 1][y - 1] &&
+				_los[x][y] = 1;
+			else if (_los[x - 1][y - 1] &&
 			         !viewportTiles[x - 1][y - 1].front().getTileType()->isOpaque())
-				screenLos[x][y] = 1;
+				_los[x][y] = 1;
 		}
 	}
 }
@@ -1005,9 +1004,9 @@ void Screen::screenFindLineOfSightEnhanced(Std::vector <MapTile> viewportTiles[V
 						for (int currentShadow = 1; currentShadow <= shadowLength; currentShadow++) {
 							// apply the shadow to the shadowMap
 							if (reflect) {
-								screenLos[xTile + ((yTileOffset) * ySign)][yTile + ((currentShadow + xTileOffset) * xSign)] |= shadowType;
+								_los[xTile + ((yTileOffset) * ySign)][yTile + ((currentShadow + xTileOffset) * xSign)] |= shadowType;
 							} else {
-								screenLos[xTile + ((currentShadow + xTileOffset) * xSign)][yTile + ((yTileOffset) * ySign)] |= shadowType;
+								_los[xTile + ((currentShadow + xTileOffset) * xSign)][yTile + ((yTileOffset) * ySign)] |= shadowType;
 							}
 						}
 						xTileOffset += shadowLength;
@@ -1024,10 +1023,10 @@ void Screen::screenFindLineOfSightEnhanced(Std::vector <MapTile> viewportTiles[V
 		for (x = 0; x < VIEWPORT_W; x++) {
 			// if the shadow flags equal __VCH, hide it, otherwise it's fully visible
 			//
-			if ((screenLos[x][y] & __VCH) == __VCH) {
-				screenLos[x][y] = 0;
+			if ((_los[x][y] & __VCH) == __VCH) {
+				_los[x][y] = 0;
 			} else {
-				screenLos[x][y] = 1;
+				_los[x][y] = 1;
 			}
 		}
 	}
@@ -1174,10 +1173,10 @@ void Screen::screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus,
 	unsigned int tile = map->translateToRawTileIndex(t);
 
 	if (map->_type == Map::DUNGEON) {
-		ASSERT(charsetInfo, "charset not initialized");
-		Std::map<Common::String, int>::iterator charIndex = dungeonTileChars.find(t.getTileType()->getName());
-		if (charIndex != dungeonTileChars.end()) {
-			charsetInfo->_image->drawSubRect((layout->_viewport.left + (x * layout->_tileShape.x)) * settings._scale,
+		ASSERT(_charSetInfo, "charset not initialized");
+		Std::map<Common::String, int>::iterator charIndex = _dungeonTileChars.find(t.getTileType()->getName());
+		if (charIndex != _dungeonTileChars.end()) {
+			_charSetInfo->_image->drawSubRect((layout->_viewport.left + (x * layout->_tileShape.x)) * settings._scale,
 			                                 (layout->_viewport.top + (y * layout->_tileShape.y)) * settings._scale,
 			                                 0,
 			                                 charIndex->_value * layout->_tileShape.y * settings._scale,
@@ -1185,14 +1184,14 @@ void Screen::screenShowGemTile(Layout *layout, Map *map, MapTile &t, bool focus,
 			                                 layout->_tileShape.y * settings._scale);
 		}
 	} else {
-		if (gemTilesInfo == NULL) {
-			gemTilesInfo = imageMgr->get(BKGD_GEMTILES);
-			if (!gemTilesInfo)
+		if (_gemTilesInfo == NULL) {
+			_gemTilesInfo = imageMgr->get(BKGD_GEMTILES);
+			if (!_gemTilesInfo)
 				errorFatal("ERROR 1002: Unable to load the \"%s\" data file.\t\n\nIs %s installed?\n\nVisit the XU4 website for additional information.\n\thttp://xu4.sourceforge.net/", BKGD_GEMTILES, settings._game.c_str());
 		}
 
 		if (tile < 128) {
-			gemTilesInfo->_image->drawSubRect((layout->_viewport.left + (x * layout->_tileShape.x)) * settings._scale,
+			_gemTilesInfo->_image->drawSubRect((layout->_viewport.left + (x * layout->_tileShape.x)) * settings._scale,
 			                                  (layout->_viewport.top + (y * layout->_tileShape.y)) * settings._scale,
 			                                  0,
 			                                  tile * layout->_tileShape.y * settings._scale,
@@ -1221,7 +1220,7 @@ Layout *Screen::screenGetGemLayout(const Map *map) {
 		errorFatal("no dungeon gem layout found!\n");
 		return NULL;
 	} else
-		return gemlayout;
+		return _gemLayout;
 }
 
 
@@ -1339,15 +1338,15 @@ void inline screenWait(int numberOfAnimationFrames) {};
 
 
 const Std::vector<Common::String> &screenGetFilterNames() {
-	return g_screen->filterNames;
+	return g_screen->_filterNames;
 }
 
 const Std::vector<Common::String> &screenGetGemLayoutNames() {
-	return g_screen->gemLayoutNames;
+	return g_screen->_gemLayoutNames;
 }
 
 const Std::vector<Common::String> &screenGetLineOfSightStyles() {
-	return g_screen->lineOfSightStyles;
+	return g_screen->_lineOfSightStyles;
 }
 
 } // End of namespace Ultima4
diff --git a/engines/ultima/ultima4/gfx/screen.h b/engines/ultima/ultima4/gfx/screen.h
index e8507ee697..a4654728f2 100644
--- a/engines/ultima/ultima4/gfx/screen.h
+++ b/engines/ultima/ultima4/gfx/screen.h
@@ -105,24 +105,23 @@ private:
 	MouseCursorSurface *_mouseCursors[5];
 	int _currentMouseCursor;
 
-	Std::vector<TileAnimSet *> tileanimSets;
-	Layout *gemlayout;
-	Std::map<Common::String, int> dungeonTileChars;
-	ImageInfo *charsetInfo;
-	ImageInfo *gemTilesInfo;
-
-	int screenNeedPrompt;
-	int screenCursorX;
-	int screenCursorY;
-	int screenCursorStatus;
-	int screenCursorEnabled;
-	int screenLos[VIEWPORT_W][VIEWPORT_H];
+	Std::vector<TileAnimSet *> _tileAnimSets;
+	Layout *_gemLayout;
+	Std::map<Common::String, int> _dungeonTileChars;
+	ImageInfo *_charSetInfo;
+	ImageInfo *_gemTilesInfo;
+
+	int _needPrompt;
+	Common::Point _cursorPos;
+	int _cursorStatus;
+	int _cursorEnabled;
+	int _los[VIEWPORT_W][VIEWPORT_H];
 public:
-	Std::vector<Common::String> gemLayoutNames;
-	Std::vector<Common::String> filterNames;
-	Std::vector<Common::String> lineOfSightStyles;
-	int screenCurrentCycle;
-	TileAnimSet *tileanims;
+	Std::vector<Common::String> _gemLayoutNames;
+	Std::vector<Common::String> _filterNames;
+	Std::vector<Common::String> _lineOfSightStyles;
+	int _currentCycle;
+	TileAnimSet *_tileAnims;
 private:
 	/**
 	 * Load the cursors
@@ -249,7 +248,6 @@ public:
 	 * Draw a character from the charset onto the screen.
 	 */
 	void screenShowChar(int chr, int x, int y);
-	void screenShowCharMasked(int chr, int x, int y, unsigned char mask);
 	void screenTextAt(int x, int y, const char *fmt, ...) GCC_PRINTF(3, 4);
 
 	/**
diff --git a/engines/ultima/ultima4/map/tile.cpp b/engines/ultima/ultima4/map/tile.cpp
index f63d022d26..53525f510d 100644
--- a/engines/ultima/ultima4/map/tile.cpp
+++ b/engines/ultima/ultima4/map/tile.cpp
@@ -170,8 +170,8 @@ void Tile::loadImage() {
 
 		if (_animationRule.size() > 0) {
 			_anim = NULL;
-			if (g_screen->tileanims)
-				_anim = g_screen->tileanims->getByName(_animationRule);
+			if (g_screen->_tileAnims)
+				_anim = g_screen->_tileAnims->getByName(_animationRule);
 			if (_anim == NULL)
 				errorWarning("Warning: animation style '%s' not found", _animationRule.c_str());
 		}
diff --git a/engines/ultima/ultima4/map/tileanim.cpp b/engines/ultima/ultima4/map/tileanim.cpp
index 39442f4def..abd2b1617b 100644
--- a/engines/ultima/ultima4/map/tileanim.cpp
+++ b/engines/ultima/ultima4/map/tileanim.cpp
@@ -158,7 +158,7 @@ void TileAnimScrollTransform::draw(Image *dest, Tile *tile, MapTile &mapTile) {
 	if (_increment == 0)
 		_increment = tile->getScale();
 
-	int offset = g_screen->screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND * tile->getScale();
+	int offset = g_screen->_currentCycle * 4 / SCR_CYCLE_PER_SECOND * tile->getScale();
 	if (_lastOffset != offset) {
 		_lastOffset = offset;
 		_current += _increment;
diff --git a/engines/ultima/ultima4/map/tileview.cpp b/engines/ultima/ultima4/map/tileview.cpp
index eb22f25d03..7bcb849744 100644
--- a/engines/ultima/ultima4/map/tileview.cpp
+++ b/engines/ultima/ultima4/map/tileview.cpp
@@ -175,7 +175,7 @@ void TileView::drawFocus(int x, int y) {
 	ASSERT(y < _rows, "y value of %d out of range", y);
 
 	// Draw the focus rectangle around the tile
-	if ((g_screen->screenCurrentCycle * 4 / SCR_CYCLE_PER_SECOND) % 2) {
+	if ((g_screen->_currentCycle * 4 / SCR_CYCLE_PER_SECOND) % 2) {
 		// left edge
 		_screen->fillRect(SCALED(x * _tileWidth + this->_x),
 			SCALED(y * _tileHeight + this->_y),


Commit: 42a2cfa015de1cc59c1b58a0401665c8bb2c67dd
    https://github.com/scummvm/scummvm/commit/42a2cfa015de1cc59c1b58a0401665c8bb2c67dd
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-18T15:25:23-07:00

Commit Message:
ULTIMA4: Merge screen_scummvm.cpp into screen.cpp

Changed paths:
  R engines/ultima/ultima4/gfx/screen_scummvm.cpp
    engines/ultima/module.mk
    engines/ultima/ultima4/gfx/screen.cpp
    engines/ultima/ultima4/gfx/screen.h


diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 113ebdd5ab..8dfb33e5dc 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -203,7 +203,6 @@ MODULE_OBJS := \
 	ultima4/gfx/imageview.o \
 	ultima4/gfx/scale.o \
 	ultima4/gfx/screen.o \
-	ultima4/gfx/screen_scummvm.o \
 	ultima4/map/annotation.o \
 	ultima4/map/city.o \
 	ultima4/map/direction.o \
diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index 55d2e778e0..ae8aeb5b86 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -50,15 +50,15 @@ namespace Ultima4 {
 
 #define MOUSE_CURSOR_SIZE 20
 #define DBL_MAX 1e99
-
+#define BUFFER_SIZE 1024
+ 
 Screen *g_screen;
 
-static const int BufferSize = 1024;
-
 Screen::Screen() : _filterScaler(nullptr), _currentMouseCursor(-1),
 		_gemLayout(nullptr), _tileAnims(nullptr), _charSetInfo(nullptr),
 		_gemTilesInfo(nullptr), _needPrompt(1), _currentCycle(0),
-		_cursorStatus(0), _cursorEnabled(1) {
+		_cursorStatus(0), _cursorEnabled(1), _frameDuration(0),
+		_continueScreenRefresh(true) {
 	g_screen = this;
 	Common::fill(&_mouseCursors[0], &_mouseCursors[5], (MouseCursorSurface *)nullptr);
 	Common::fill(&_los[0][0], &_los[VIEWPORT_W][0], 0);
@@ -236,12 +236,12 @@ void Screen::screenReInit() {
 }
 
 void Screen::screenTextAt(int x, int y, const char *fmt, ...) {
-	char buffer[BufferSize];
+	char buffer[BUFFER_SIZE];
 	unsigned int i;
 
 	va_list args;
 	va_start(args, fmt);
-	vsnprintf(buffer, BufferSize, fmt, args);
+	vsnprintf(buffer, BUFFER_SIZE, fmt, args);
 	va_end(args);
 
 	for (i = 0; i < strlen(buffer); i++)
@@ -262,13 +262,13 @@ void Screen::screenMessage(const char *fmt, ...) {
 
 	if (!g_context)
 		return; //Because some cases (like the intro) don't have the context initiated.
-	char buffer[BufferSize];
+	char buffer[BUFFER_SIZE];
 	unsigned int i;
 	int wordlen;
 
 	va_list args;
 	va_start(args, fmt);
-	vsnprintf(buffer, BufferSize, fmt, args);
+	vsnprintf(buffer, BUFFER_SIZE, fmt, args);
 	va_end(args);
 #ifdef IOS
 	if (recursed)
@@ -1223,7 +1223,6 @@ Layout *Screen::screenGetGemLayout(const Map *map) {
 		return _gemLayout;
 }
 
-
 void Screen::screenGemUpdate() {
 	MapTile tile;
 	int x, y;
@@ -1329,6 +1328,91 @@ void Screen::screenGemUpdate() {
 	screenUpdateWind();
 }
 
+
+void Screen::screenRedrawTextArea(int x, int y, int width, int height) {
+	g_system->updateScreen();
+}
+
+void Screen::screenWait(int numberOfAnimationFrames) {
+	g_system->delayMillis(numberOfAnimationFrames * _frameDuration);
+}
+
+Image *Screen::screenScale(Image *src, int scale, int n, int filter) {
+	Image *dest = NULL;
+	bool isTransparent;
+	unsigned int transparentIndex;
+	bool alpha = src->isAlphaOn();
+
+	if (n == 0)
+		n = 1;
+
+	isTransparent = src->getTransparentIndex(transparentIndex);
+	src->alphaOff();
+
+	while (filter && _filterScaler && (scale % 2 == 0)) {
+		dest = (*_filterScaler)(src, 2, n);
+		src = dest;
+		scale /= 2;
+	}
+	if (scale == 3 && scaler3x(settings._filter)) {
+		dest = (*_filterScaler)(src, 3, n);
+		src = dest;
+		scale /= 3;
+	}
+
+	if (scale != 1)
+		dest = (*scalerGet("point"))(src, scale, n);
+
+	if (!dest)
+		dest = Image::duplicate(src);
+
+	if (isTransparent)
+		dest->setTransparentIndex(transparentIndex);
+
+	if (alpha)
+		src->alphaOn();
+
+	return dest;
+}
+
+Image *Screen::screenScaleDown(Image *src, int scale) {
+	int x, y;
+	Image *dest;
+	bool isTransparent;
+	unsigned int transparentIndex;
+	bool alpha = src->isAlphaOn();
+
+	isTransparent = src->getTransparentIndex(transparentIndex);
+
+	src->alphaOff();
+
+	dest = Image::create(src->width() / scale, src->height() / scale, src->isIndexed(), Image::HARDWARE);
+	if (!dest)
+		return NULL;
+
+	if (!dest)
+		dest = Image::duplicate(src);
+
+	if (dest->isIndexed())
+		dest->setPaletteFromImage(src);
+
+	for (y = 0; y < src->height(); y += scale) {
+		for (x = 0; x < src->width(); x += scale) {
+			unsigned int index;
+			src->getPixelIndex(x, y, index);
+			dest->putPixelIndex(x / scale, y / scale, index);
+		}
+	}
+
+	if (isTransparent)
+		dest->setTransparentIndex(transparentIndex);
+
+	if (alpha)
+		src->alphaOn();
+
+	return dest;
+}
+
 #ifdef IOS
 //Unsure if implementation required in iOS.
 void inline screenLock() {};
diff --git a/engines/ultima/ultima4/gfx/screen.h b/engines/ultima/ultima4/gfx/screen.h
index a4654728f2..f40b2bb471 100644
--- a/engines/ultima/ultima4/gfx/screen.h
+++ b/engines/ultima/ultima4/gfx/screen.h
@@ -116,6 +116,8 @@ private:
 	int _cursorStatus;
 	int _cursorEnabled;
 	int _los[VIEWPORT_W][VIEWPORT_H];
+	int _frameDuration;
+	bool _continueScreenRefresh;
 public:
 	Std::vector<Common::String> _gemLayoutNames;
 	Std::vector<Common::String> _filterNames;
@@ -278,7 +280,19 @@ public:
 	 */
 	int screenPointInMouseArea(int x, int y, const MouseArea *area);
 
+	/**
+	 * Scale an image up.  The resulting image will be scale * the
+	 * original dimensions.  The original image is no longer deleted.
+	 * n is the number of tiles in the image; each tile is filtered
+	 * seperately. filter determines whether or not to filter the
+	 * resulting image.
+	 */
 	Image *screenScale(Image *src, int scale, int n, int filter);
+
+	/**
+	 * Scale an image down.  The resulting image will be 1/scale * the
+	 * original dimensions.  The original image is no longer deleted.
+	 */
 	Image *screenScaleDown(Image *src, int scale);
 };
 
diff --git a/engines/ultima/ultima4/gfx/screen_scummvm.cpp b/engines/ultima/ultima4/gfx/screen_scummvm.cpp
deleted file mode 100644
index c9aaba1104..0000000000
--- a/engines/ultima/ultima4/gfx/screen_scummvm.cpp
+++ /dev/null
@@ -1,157 +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 "ultima/ultima4/controllers/intro_controller.h"
-#include "ultima/ultima4/core/config.h"
-#include "ultima/ultima4/core/error.h"
-#include "ultima/ultima4/core/settings.h"
-#include "ultima/ultima4/core/utils.h"
-#include "ultima/ultima4/events/event.h"
-#include "ultima/ultima4/filesys/savegame.h"
-#include "ultima/ultima4/filesys/u4file.h"
-#include "ultima/ultima4/game/context.h"
-#include "ultima/ultima4/gfx/scale.h"
-#include "ultima/ultima4/gfx/screen.h"
-#include "ultima/ultima4/gfx/image.h"
-#include "ultima/ultima4/gfx/imagemgr.h"
-#include "ultima/ultima4/map/tileanim.h"
-#include "ultima/ultima4/map/tileset.h"
-#include "ultima/ultima4/map/dungeonview.h"
-#include "ultima/shared/core/file.h"
-#include "ultima/ultima4/ultima4.h"
-#include "common/system.h"
-#include "engines/util.h"
-#include "graphics/cursorman.h"
-
-namespace Ultima {
-namespace Ultima4 {
-
-using Std::vector;
-
-//Image *screenScale(Image *src, int scale, int n, int filter);
-
-/**
- * Force a redraw.
- */
-
-//SDL_mutex *screenLockMutex = NULL;
-int frameDuration = 0;
-
-void Screen::screenRedrawTextArea(int x, int y, int width, int height) {
-	g_system->updateScreen();
-}
-
-void Screen::screenWait(int numberOfAnimationFrames) {
-	g_system->delayMillis(numberOfAnimationFrames * frameDuration);
-}
-
-bool continueScreenRefresh = true;
-
-/**
- * Scale an image up.  The resulting image will be scale * the
- * original dimensions.  The original image is no longer deleted.
- * n is the number of tiles in the image; each tile is filtered
- * seperately. filter determines whether or not to filter the
- * resulting image.
- */
-Image *Screen::screenScale(Image *src, int scale, int n, int filter) {
-	Image *dest = NULL;
-	bool isTransparent;
-	unsigned int transparentIndex;
-	bool alpha = src->isAlphaOn();
-
-	if (n == 0)
-		n = 1;
-
-	isTransparent = src->getTransparentIndex(transparentIndex);
-	src->alphaOff();
-
-	while (filter && _filterScaler && (scale % 2 == 0)) {
-		dest = (*_filterScaler)(src, 2, n);
-		src = dest;
-		scale /= 2;
-	}
-	if (scale == 3 && scaler3x(settings._filter)) {
-		dest = (*_filterScaler)(src, 3, n);
-		src = dest;
-		scale /= 3;
-	}
-
-	if (scale != 1)
-		dest = (*scalerGet("point"))(src, scale, n);
-
-	if (!dest)
-		dest = Image::duplicate(src);
-
-	if (isTransparent)
-		dest->setTransparentIndex(transparentIndex);
-
-	if (alpha)
-		src->alphaOn();
-
-	return dest;
-}
-
-/**
- * Scale an image down.  The resulting image will be 1/scale * the
- * original dimensions.  The original image is no longer deleted.
- */
-Image *Screen::screenScaleDown(Image *src, int scale) {
-	int x, y;
-	Image *dest;
-	bool isTransparent;
-	unsigned int transparentIndex;
-	bool alpha = src->isAlphaOn();
-
-	isTransparent = src->getTransparentIndex(transparentIndex);
-
-	src->alphaOff();
-
-	dest = Image::create(src->width() / scale, src->height() / scale, src->isIndexed(), Image::HARDWARE);
-	if (!dest)
-		return NULL;
-
-	if (!dest)
-		dest = Image::duplicate(src);
-
-	if (dest->isIndexed())
-		dest->setPaletteFromImage(src);
-
-	for (y = 0; y < src->height(); y += scale) {
-		for (x = 0; x < src->width(); x += scale) {
-			unsigned int index;
-			src->getPixelIndex(x, y, index);
-			dest->putPixelIndex(x / scale, y / scale, index);
-		}
-	}
-
-	if (isTransparent)
-		dest->setTransparentIndex(transparentIndex);
-
-	if (alpha)
-		src->alphaOn();
-
-	return dest;
-}
-
-} // End of namespace Ultima4
-} // End of namespace Ultima




More information about the Scummvm-git-logs mailing list