[Scummvm-git-logs] scummvm master -> 4541d085ca54e71f66be358165984b2a56b8b53b

fracturehill noreply at scummvm.org
Sat Feb 10 23:41:45 UTC 2024


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

Summary:
3a6e2562dd NANCY: Implement nancy8 TileMove puzzle
4d5c4fcfcc NANCY: Rename graphics and cursor managers
ad21d8b566 NANCY: Fix ResourceManager memory leak
0c2e54416e NANCY: Update engine status comment
3d9a61f904 NANCY: Fix memory leak in Conversation
758db1bfb1 NANCY: Fix memory leak when reading .dat file
01eefffad6 NANCY: Fix memory leak in ResourceManager
5695018cd3 NANCY: Implement InteractiveVideo
4541d085ca NANCY: Disable buttons/save when a Movie is active


Commit: 3a6e2562dd23ecf269bd916460e3e318ea01efe8
    https://github.com/scummvm/scummvm/commit/3a6e2562dd23ecf269bd916460e3e318ea01efe8
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:29+01:00

Commit Message:
NANCY: Implement nancy8 TileMove puzzle

Added support for the changes nancy8 made to the
TileMove puzzle type. Specifically, an optional exit button,
and a timer with graphics that indicate how much time the
player has left.

Changed paths:
    engines/nancy/action/puzzle/collisionpuzzle.cpp
    engines/nancy/action/puzzle/collisionpuzzle.h


diff --git a/engines/nancy/action/puzzle/collisionpuzzle.cpp b/engines/nancy/action/puzzle/collisionpuzzle.cpp
index e7bb12a3a02..139745b414e 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.cpp
+++ b/engines/nancy/action/puzzle/collisionpuzzle.cpp
@@ -129,43 +129,57 @@ void CollisionPuzzle::registerGraphics() {
 }
 
 void CollisionPuzzle::updateGraphics() {
-	if (_state == kRun && _currentlyAnimating != -1) {
-		// Framerate-dependent animation. Should be fine since we limit the engine to ~60fps
-		++_currentAnimFrame;
-		bool horizontal = _lastPosition.x != _pieces[_currentlyAnimating]._gridPos.x;
-		int diff = horizontal ?
-				_lastPosition.x - _pieces[_currentlyAnimating]._gridPos.x :
-				_lastPosition.y - _pieces[_currentlyAnimating]._gridPos.y;
-
-		int maxFrames = _framesPerMove * abs(diff);
-		if (_currentAnimFrame > maxFrames) {
-			if (_puzzleType == kCollision && _grid[_pieces[_currentlyAnimating]._gridPos.y][_pieces[_currentlyAnimating]._gridPos.x] == _currentlyAnimating + 1) {
-				g_nancy->_sound->playSound(_homeSound);
-			} else {
-				g_nancy->_sound->playSound(_wallHitSound);
+	if (_state == kRun) {
+		if (_timerSrcs.size()) {
+			uint32 currentTime = g_nancy->getTotalPlayTime() - _puzzleStartTime;
+			int graphicForTime = currentTime / ((_timerTime * 1000) / _timerSrcs.size());
+			if (graphicForTime != _currentTimerGraphic) {
+				_drawSurface.fillRect(_timerDest, _drawSurface.getTransparentColor());
+				_drawSurface.blitFrom(_image, _timerSrcs[graphicForTime], _timerDest);
+				_needsRedraw = true;
+				_currentTimerGraphic = graphicForTime;
+				NancySceneState.setEventFlag(_timerFlagIds[graphicForTime], g_nancy->_true);
 			}
-
-			_currentlyAnimating = -1;
-			_currentAnimFrame = -1;
-			return;
 		}
 
-		Common::Rect destRect = getScreenPosition(_lastPosition);
-		Common::Rect endPos = getScreenPosition(_pieces[_currentlyAnimating]._gridPos);
+		if (_currentlyAnimating != -1) {
+			// Framerate-dependent animation. Should be fine since we limit the engine to ~60fps
+			++_currentAnimFrame;
+			bool horizontal = _lastPosition.x != _pieces[_currentlyAnimating]._gridPos.x;
+			int diff = horizontal ?
+					_lastPosition.x - _pieces[_currentlyAnimating]._gridPos.x :
+					_lastPosition.y - _pieces[_currentlyAnimating]._gridPos.y;
+
+			int maxFrames = _framesPerMove * abs(diff);
+			if (_currentAnimFrame > maxFrames) {
+				if (_puzzleType == kCollision && _grid[_pieces[_currentlyAnimating]._gridPos.y][_pieces[_currentlyAnimating]._gridPos.x] == _currentlyAnimating + 1) {
+					g_nancy->_sound->playSound(_homeSound);
+				} else {
+					g_nancy->_sound->playSound(_wallHitSound);
+				}
 
-		if (_lineWidth == 6) {
-			destRect.translate(-1, 0); // Improvement
-			endPos.translate(-1, 0); // Improvement
-		}
+				_currentlyAnimating = -1;
+				_currentAnimFrame = -1;
+				return;
+			}
 
-		Common::Point dest(destRect.left, destRect.top);
-		if (horizontal) {
-			dest.x = destRect.left + (endPos.left - dest.x) * _currentAnimFrame / maxFrames;
-		} else {
-			dest.y = destRect.top + (endPos.top - dest.y) * _currentAnimFrame / maxFrames;
-		}
+			Common::Rect destRect = getScreenPosition(_lastPosition);
+			Common::Rect endPos = getScreenPosition(_pieces[_currentlyAnimating]._gridPos);
+
+			if (_lineWidth == 6) {
+				destRect.translate(-1, 0); // Improvement
+				endPos.translate(-1, 0); // Improvement
+			}
 
-		_pieces[_currentlyAnimating].moveTo(dest);
+			Common::Point dest(destRect.left, destRect.top);
+			if (horizontal) {
+				dest.x = destRect.left + (endPos.left - dest.x) * _currentAnimFrame / maxFrames;
+			} else {
+				dest.y = destRect.top + (endPos.top - dest.y) * _currentAnimFrame / maxFrames;
+			}
+
+			_pieces[_currentlyAnimating].moveTo(dest);
+		}
 	}
 }
 
@@ -210,6 +224,12 @@ void CollisionPuzzle::readData(Common::SeekableReadStream &stream) {
 		readRect(stream, _blockSrc);
 	} else {
 		readRectArray(stream, _pieceSrcs, 6);
+
+		if (g_nancy->getGameType() >= kGameTypeNancy8) {
+			_usesExitButton = stream.readByte();
+			readRect(stream, _exitButtonSrc);
+			readRect(stream, _exitButtonDest);
+		}
 	}
 
 	_gridPos.x = stream.readUint32LE();
@@ -218,13 +238,28 @@ void CollisionPuzzle::readData(Common::SeekableReadStream &stream) {
 	_lineWidth = stream.readUint16LE();
 	_framesPerMove = stream.readUint16LE();
 
-	stream.skip(3);
+	if (g_nancy->getGameType() <= kGameTypeNancy7) {
+		stream.skip(3);
+	} else if (_puzzleType == kTileMove) {
+		uint16 numTimerGraphics = stream.readUint16LE();
+		_timerTime = stream.readUint32LE();
+		readRectArray(stream, _timerSrcs, numTimerGraphics, 10);
+		_timerFlagIds.resize(numTimerGraphics);
+		for (uint i = 0; i < numTimerGraphics; ++i) {
+			_timerFlagIds[i] = stream.readSint16LE();
+		}
+		stream.skip((10 - numTimerGraphics) * 2);
+		readRect(stream, _timerDest);
+	}	
 
 	_moveSound.readNormal(stream);
 	if (_puzzleType == kCollision) {
 		_homeSound.readNormal(stream);
 	}
 	_wallHitSound.readNormal(stream);
+	if (_puzzleType == kTileMove && g_nancy->getGameType() >= kGameTypeNancy8) {
+		_exitButtonSound.readNormal(stream);
+	}
 
 	_solveScene.readData(stream);
 	_solveSoundDelay = stream.readUint16LE();
@@ -249,6 +284,14 @@ void CollisionPuzzle::execute() {
 			return;
 		}
 
+		// Check timer
+		if (_timerSrcs.size()) {
+			if ((g_nancy->getTotalPlayTime() - _puzzleStartTime) > _timerTime * 1000) {
+				_state = kActionTrigger;
+				return;
+			}
+		}
+
 		if (_puzzleType == kCollision) {
 			// Check if every tile is in its "home"
 			for (uint i = 0; i < _pieces.size(); ++i) {
@@ -292,6 +335,9 @@ void CollisionPuzzle::execute() {
 				NancySceneState.changeScene(_solveScene._sceneChange);
 			}			
 		} else {
+			if (g_nancy->_sound->isSoundPlaying(_exitButtonSound)) {
+				return;
+			}
 			_exitScene.execute();
 		}
 
@@ -516,13 +562,28 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 		return;
 	}
 
-	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+	if (_usesExitButton) {
+		if (NancySceneState.getViewport().convertViewportToScreen(_exitButtonDest).contains(input.mousePos)) {
+			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
 
-		if (input.input & NancyInput::kLeftMouseButtonUp) {
-			_state = kActionTrigger;
+			if (input.input & NancyInput::kLeftMouseButtonUp) {
+				_drawSurface.blitFrom(_image, _exitButtonSrc, _exitButtonDest);
+				_needsRedraw = true;
+				g_nancy->_sound->loadSound(_exitButtonSound);
+				g_nancy->_sound->playSound(_exitButtonSound);
+				_state = kActionTrigger;
+			}
+			return;
+		}
+	} else {
+		if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
+			g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+
+			if (input.input & NancyInput::kLeftMouseButtonUp) {
+				_state = kActionTrigger;
+			}
+			return;
 		}
-		return;
 	}
 
 	if (_currentlyAnimating != -1) {
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.h b/engines/nancy/action/puzzle/collisionpuzzle.h
index 72075ba34d0..29cda0e24ad 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.h
+++ b/engines/nancy/action/puzzle/collisionpuzzle.h
@@ -88,14 +88,24 @@ protected:
 	Common::Point _tileMoveExitPos = Common::Point(-1, -1);
 	uint _tileMoveExitSize = 0;
 
+	bool _usesExitButton = false;
+	Common::Rect _exitButtonSrc;
+	Common::Rect _exitButtonDest;
+
 	Common::Point _gridPos;
 
 	uint16 _lineWidth = 0;
 	uint16 _framesPerMove = 0;
 
+	uint32 _timerTime = 0; // in seconds
+	Common::Array<Common::Rect> _timerSrcs;
+	Common::Array<int16> _timerFlagIds;
+	Common::Rect _timerDest;
+
 	SoundDescription _moveSound;
 	SoundDescription _homeSound;
 	SoundDescription _wallHitSound;
+	SoundDescription _exitButtonSound;
 
 	SceneChangeWithFlag _solveScene;
 	uint16 _solveSoundDelay = 0;
@@ -113,6 +123,9 @@ protected:
 
 	uint32 _solveSoundPlayTime = 0;
 	bool _solved = false;
+
+	uint32 _puzzleStartTime = 0;
+	int _currentTimerGraphic = -1;
 	
 	PuzzleType _puzzleType;
 };


Commit: 4d5c4fcfcc708d333cf4415305e5fd4d11abcc68
    https://github.com/scummvm/scummvm/commit/4d5c4fcfcc708d333cf4415305e5fd4d11abcc68
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:29+01:00

Commit Message:
NANCY: Rename graphics and cursor managers

Changed the names of the pointers to GraphicsManager
and CursorManager to be shorter, since they were
inconsistent with the rest of the managers, and typing
them out is a chore.

Changed paths:
    engines/nancy/action/actionmanager.cpp
    engines/nancy/action/autotext.cpp
    engines/nancy/action/conversation.cpp
    engines/nancy/action/overlay.cpp
    engines/nancy/action/puzzle/assemblypuzzle.cpp
    engines/nancy/action/puzzle/bballpuzzle.cpp
    engines/nancy/action/puzzle/bombpuzzle.cpp
    engines/nancy/action/puzzle/bulpuzzle.cpp
    engines/nancy/action/puzzle/collisionpuzzle.cpp
    engines/nancy/action/puzzle/cubepuzzle.cpp
    engines/nancy/action/puzzle/hamradiopuzzle.cpp
    engines/nancy/action/puzzle/leverpuzzle.cpp
    engines/nancy/action/puzzle/mazechasepuzzle.cpp
    engines/nancy/action/puzzle/mouselightpuzzle.cpp
    engines/nancy/action/puzzle/orderingpuzzle.cpp
    engines/nancy/action/puzzle/overridelockpuzzle.cpp
    engines/nancy/action/puzzle/passwordpuzzle.cpp
    engines/nancy/action/puzzle/peepholepuzzle.cpp
    engines/nancy/action/puzzle/raycastpuzzle.cpp
    engines/nancy/action/puzzle/riddlepuzzle.cpp
    engines/nancy/action/puzzle/rippedletterpuzzle.cpp
    engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
    engines/nancy/action/puzzle/safedialpuzzle.cpp
    engines/nancy/action/puzzle/setplayerclock.cpp
    engines/nancy/action/puzzle/sliderpuzzle.cpp
    engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
    engines/nancy/action/puzzle/spigotpuzzle.cpp
    engines/nancy/action/puzzle/tangrampuzzle.cpp
    engines/nancy/action/puzzle/telephone.cpp
    engines/nancy/action/puzzle/towerpuzzle.cpp
    engines/nancy/action/puzzle/turningpuzzle.cpp
    engines/nancy/action/puzzle/twodialpuzzle.cpp
    engines/nancy/action/secondarymovie.cpp
    engines/nancy/action/secondaryvideo.cpp
    engines/nancy/console.cpp
    engines/nancy/cursor.cpp
    engines/nancy/enginedata.cpp
    engines/nancy/font.cpp
    engines/nancy/graphics.cpp
    engines/nancy/metaengine.cpp
    engines/nancy/misc/hypertext.cpp
    engines/nancy/misc/lightning.cpp
    engines/nancy/misc/specialeffect.cpp
    engines/nancy/nancy.cpp
    engines/nancy/nancy.h
    engines/nancy/renderobject.cpp
    engines/nancy/resource.cpp
    engines/nancy/state/credits.cpp
    engines/nancy/state/help.cpp
    engines/nancy/state/loadsave.cpp
    engines/nancy/state/mainmenu.cpp
    engines/nancy/state/map.cpp
    engines/nancy/state/savedialog.cpp
    engines/nancy/state/scene.cpp
    engines/nancy/state/setupmenu.cpp
    engines/nancy/ui/animatedbutton.cpp
    engines/nancy/ui/button.cpp
    engines/nancy/ui/clock.cpp
    engines/nancy/ui/inventorybox.cpp
    engines/nancy/ui/ornaments.cpp
    engines/nancy/ui/scrollbar.cpp
    engines/nancy/ui/textbox.cpp
    engines/nancy/ui/viewport.cpp
    engines/nancy/video.cpp


diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 67ece7a8d07..40924a6b58f 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -64,7 +64,7 @@ void ActionManager::handleInput(NancyInput &input) {
 			if (!setHoverCursor) {
 				// Hotspots may overlap, but we want the hover cursor for the first one we encounter
 				// This fixes the stairs in nancy3
-				g_nancy->_cursorManager->setCursorType(rec->getHoverCursor());
+				g_nancy->_cursor->setCursorType(rec->getHoverCursor());
 				setHoverCursor = true;
 			}
 
@@ -679,7 +679,7 @@ void ActionManager::debugDrawHotspots() {
 	// the smallest one available in the engine.
 	RenderObject &obj = NancySceneState._hotspotDebug;
 	if (ConfMan.getBool("debug_hotspots", Common::ConfigManager::kTransientDomain)) {
-		const Font *font = g_nancy->_graphicsManager->getFont(0);
+		const Font *font = g_nancy->_graphics->getFont(0);
 		assert(font);
 		uint16 yOffset = NancySceneState.getViewport().getCurVerticalScroll();
 		obj.setVisible(true);
diff --git a/engines/nancy/action/autotext.cpp b/engines/nancy/action/autotext.cpp
index aad4f5c0984..9b8a66b352a 100644
--- a/engines/nancy/action/autotext.cpp
+++ b/engines/nancy/action/autotext.cpp
@@ -147,23 +147,23 @@ void Autotext::execute() {
 		// Guesstimate the height of the surface
 		uint surfHeight = _textLines[0].size() / 144 * _surfWidth;
 		surfHeight = MAX<uint>(surfHeight, _surfHeight + 20);
-		Graphics::ManagedSurface &surf = g_nancy->_graphicsManager->getAutotextSurface(_surfaceID);
-		Common::Rect &surfBounds = g_nancy->_graphicsManager->getAutotextSurfaceBounds(_surfaceID);
-		surf.create(_surfWidth + 1, surfHeight, g_nancy->_graphicsManager->getInputPixelFormat());
+		Graphics::ManagedSurface &surf = g_nancy->_graphics->getAutotextSurface(_surfaceID);
+		Common::Rect &surfBounds = g_nancy->_graphics->getAutotextSurfaceBounds(_surfaceID);
+		surf.create(_surfWidth + 1, surfHeight, g_nancy->_graphics->getInputPixelFormat());
 		if (_transparency) {
-			surf.clear(g_nancy->_graphicsManager->getTransColor());
+			surf.clear(g_nancy->_graphics->getTransColor());
 		}
 
 		_fullSurface.create(surf, surf.getBounds());
 		if(_transparency == kPlayOverlayTransparent) {
-			_fullSurface.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+			_fullSurface.setTransparentColor(g_nancy->_graphics->getTransColor());
 		}
 
 		Common::Rect textBounds = surf.getBounds();
 		textBounds.left += _offset.x;
 		textBounds.top += _offset.y;
 
-		const Font *font = g_nancy->_graphicsManager->getFont(_fontID);
+		const Font *font = g_nancy->_graphics->getFont(_fontID);
 		assert(font);
 		uint d = (font->getFontHeight() + 1) / 2 + 1;
 
diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index 357d3ce7ff4..c9c64493c56 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -223,21 +223,21 @@ void ConversationSound::execute() {
 		NancySceneState.setNoHeldItem();
 
 		// Move the mouse to the default position defined in CURS
-		const Common::Point initialMousePos = g_nancy->_cursorManager->getPrimaryVideoInitialPos();
-		const Common::Point cursorHotspot = g_nancy->_cursorManager->getCurrentCursorHotspot();
+		const Common::Point initialMousePos = g_nancy->_cursor->getPrimaryVideoInitialPos();
+		const Common::Point cursorHotspot = g_nancy->_cursor->getCurrentCursorHotspot();
 		Common::Point adjustedMousePos = g_nancy->_input->getInput().mousePos;
 		adjustedMousePos.x -= cursorHotspot.x;
 		adjustedMousePos.y -= cursorHotspot.y - 1;
-		if (g_nancy->_cursorManager->getPrimaryVideoInactiveZone().bottom > adjustedMousePos.y) {
-			g_nancy->_cursorManager->warpCursor(Common::Point(initialMousePos.x + cursorHotspot.x, initialMousePos.y + cursorHotspot.y));
-			g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+		if (g_nancy->_cursor->getPrimaryVideoInactiveZone().bottom > adjustedMousePos.y) {
+			g_nancy->_cursor->warpCursor(Common::Point(initialMousePos.x + cursorHotspot.x, initialMousePos.y + cursorHotspot.y));
+			g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 		}
 
 		_state = kRun;
 		NancySceneState.setActiveConversation(this);
 
 		// Do not draw first frame since video won't be loaded yet
-		g_nancy->_graphicsManager->suppressNextDraw();
+		g_nancy->_graphics->suppressNextDraw();
 
 		if (g_nancy->getGameType() < kGameTypeNancy6) {
 			// Do not fall through to give the execution one loop for event flag changes
@@ -744,7 +744,7 @@ bool ConversationCelLoader::loadInner() {
 ConversationCel::~ConversationCel() {
 	// Make sure there isn't a single-frame gap between conversation scenes where
 	// the character is invisible
-	g_nancy->_graphicsManager->suppressNextDraw();
+	g_nancy->_graphics->suppressNextDraw();
 }
 
 void ConversationCel::init() {
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 327debb637a..e7409d004d4 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -59,7 +59,7 @@ void Overlay::handleInput(NancyInput &input) {
 	if (g_nancy->getGameType() >= kGameTypeNancy3) {
 		if (_hasHotspot) {
 			if (NancySceneState.getViewport().convertViewportToScreen(_hotspot).contains(input.mousePos)) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.cpp b/engines/nancy/action/puzzle/assemblypuzzle.cpp
index 5ead404fb33..50dec5db18b 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.cpp
+++ b/engines/nancy/action/puzzle/assemblypuzzle.cpp
@@ -163,7 +163,7 @@ void AssemblyPuzzle::handleInput(NancyInput &input) {
 	}
 	
 	if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -173,7 +173,7 @@ void AssemblyPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_cwCursorDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kRotateCW);
+		g_nancy->_cursor->setCursorType(CursorManager::kRotateCW);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp && !g_nancy->_sound->isSoundPlaying(_rotateSound)) {
 			g_nancy->_sound->playSound(_rotateSound);
@@ -183,7 +183,7 @@ void AssemblyPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_ccwCursorDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kRotateCCW);
+		g_nancy->_cursor->setCursorType(CursorManager::kRotateCCW);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp && !g_nancy->_sound->isSoundPlaying(_rotateSound)) {
 			g_nancy->_sound->playSound(_rotateSound);
@@ -202,7 +202,7 @@ void AssemblyPuzzle::handleInput(NancyInput &input) {
 				return;
 			}
 
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				if (_pickedUpPiece != -1) {
@@ -251,7 +251,7 @@ void AssemblyPuzzle::handleInput(NancyInput &input) {
 
 		if (!otherIsPlaced && (!isWrong || (_allowWrongPieceHotspot && _layersAssembled + 1 == pickedUpPiece.layer))) {
 			if (NancySceneState.getViewport().convertViewportToScreen(pickedUpPiece.destRects[0]).contains(input.mousePos)) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					if (!isWrong) {
diff --git a/engines/nancy/action/puzzle/bballpuzzle.cpp b/engines/nancy/action/puzzle/bballpuzzle.cpp
index 8371926d594..c2bcea97b3c 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bballpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void BBallPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -224,7 +224,7 @@ void BBallPuzzle::handleInput(NancyInput &input) {
 	localMousePos -= { vpPos.left, vpPos.top };
 
 	if (_exitHotspot.contains(localMousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (!_pressedButton &&input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -235,7 +235,7 @@ void BBallPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i < _angleSliderHotspots.size(); ++i) {
 		if (_curAngle != i && _angleSliderHotspots[i].contains(localMousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
 				_drawSurface.fillRect(_angleDest, _drawSurface.getTransparentColor());
@@ -253,7 +253,7 @@ void BBallPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_curPower > 0 && _minusButtonDest.contains(localMousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
 			--_curPower;
@@ -267,7 +267,7 @@ void BBallPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if ((int)_curPower < _powers - 1 && _plusButtonDest.contains(localMousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
 			++_curPower;
@@ -281,7 +281,7 @@ void BBallPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_shootButtonDest.contains(localMousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
 			_drawSurface.blitFrom(_image, _shootButtonSrc, _shootButtonDest);
diff --git a/engines/nancy/action/puzzle/bombpuzzle.cpp b/engines/nancy/action/puzzle/bombpuzzle.cpp
index 8f5fa89687c..e644e7f39d6 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bombpuzzle.cpp
@@ -39,8 +39,8 @@ void BombPuzzle::init() {
 		_screenPosition.extend(r);
 	}
 
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 
@@ -253,7 +253,7 @@ void BombPuzzle::handleInput(NancyInput &input) {
 				}
 			}
 
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				if (NancySceneState.getHeldItem() == _toolID) {
diff --git a/engines/nancy/action/puzzle/bulpuzzle.cpp b/engines/nancy/action/puzzle/bulpuzzle.cpp
index f1926b62c82..d665aba2753 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bulpuzzle.cpp
@@ -37,8 +37,8 @@ namespace Action {
 
 void BulPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -326,7 +326,7 @@ void BulPuzzle::execute() {
 
 void BulPuzzle::handleInput(NancyInput &input) {
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -343,7 +343,7 @@ void BulPuzzle::handleInput(NancyInput &input) {
 	bool canClick = _currentAction == kNone && !g_nancy->_sound->isSoundPlaying(_moveSound);
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_rollButtonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 			_drawSurface.blitFrom(_image, _rollButtonSrc, _rollButtonDest);
@@ -358,7 +358,7 @@ void BulPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if ((_turn % _numRolls) && NancySceneState.getViewport().convertViewportToScreen(_passButtonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 			_drawSurface.blitFrom(_image, _passButtonSrc, _passButtonDest);
@@ -373,7 +373,7 @@ void BulPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_resetButtonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 			_drawSurface.blitFrom(_image, _resetButtonSrc, _resetButtonDest);
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.cpp b/engines/nancy/action/puzzle/collisionpuzzle.cpp
index 139745b414e..6d56ed8604b 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.cpp
+++ b/engines/nancy/action/puzzle/collisionpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void CollisionPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -564,7 +564,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 
 	if (_usesExitButton) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_exitButtonDest).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				_drawSurface.blitFrom(_image, _exitButtonSrc, _exitButtonDest);
@@ -577,7 +577,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 		}
 	} else {
 		if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+			g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				_state = kActionTrigger;
@@ -628,7 +628,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 			if (left.contains(input.mousePos)) {
 				checkPos = movePiece(i, kWallLeft);
 				if (checkPos != _pieces[i]._gridPos) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kMoveLeft);
+					g_nancy->_cursor->setCursorType(CursorManager::kMoveLeft);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						_lastPosition = _pieces[i]._gridPos;
@@ -646,7 +646,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 			if (right.contains(input.mousePos)) {
 				checkPos = movePiece(i, kWallRight);
 				if (checkPos != _pieces[i]._gridPos) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kMoveRight);
+					g_nancy->_cursor->setCursorType(CursorManager::kMoveRight);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						_lastPosition = _pieces[i]._gridPos;
@@ -664,7 +664,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 			if (up.contains(input.mousePos)) {
 				checkPos = movePiece(i, kWallUp);
 				if (checkPos != _pieces[i]._gridPos) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kMoveUp);
+					g_nancy->_cursor->setCursorType(CursorManager::kMoveUp);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						_lastPosition = _pieces[i]._gridPos;
@@ -682,7 +682,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
 			if (down.contains(input.mousePos)) {
 				checkPos = movePiece(i, kWallDown);
 				if (checkPos != _pieces[i]._gridPos) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kMoveDown);
+					g_nancy->_cursor->setCursorType(CursorManager::kMoveDown);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						_lastPosition = _pieces[i]._gridPos;
diff --git a/engines/nancy/action/puzzle/cubepuzzle.cpp b/engines/nancy/action/puzzle/cubepuzzle.cpp
index 75c3dcd8d11..2c86841a02e 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cubepuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void CubePuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -150,7 +150,7 @@ void CubePuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -160,7 +160,7 @@ void CubePuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_cwCursorDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kRotateCW);
+		g_nancy->_cursor->setCursorType(CursorManager::kRotateCW);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp && !g_nancy->_sound->isSoundPlaying(_rotateSound)) {
 			g_nancy->_sound->playSound(_rotateSound);
@@ -170,7 +170,7 @@ void CubePuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_ccwCursorDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kRotateCCW);
+		g_nancy->_cursor->setCursorType(CursorManager::kRotateCCW);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp && !g_nancy->_sound->isSoundPlaying(_rotateSound)) {
 			g_nancy->_sound->playSound(_rotateSound);
@@ -185,7 +185,7 @@ void CubePuzzle::handleInput(NancyInput &input) {
 				return;
 			}
 			
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				if (_pickedUpPiece != -1) {
@@ -239,7 +239,7 @@ void CubePuzzle::handleInput(NancyInput &input) {
 
 		if (canPlace) {
 			if (NancySceneState.getViewport().convertViewportToScreen(_placedDest).contains(input.mousePos)) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					_placedPieces[_pickedUpPiece] = true;
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.cpp b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
index 4e7cab73d75..0f4afa2dc62 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.cpp
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
@@ -48,8 +48,8 @@ static const char *morseCodeTable[] = {
 
 void HamRadioPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -410,7 +410,7 @@ void HamRadioPuzzle::handleInput(NancyInput &input) {
 
 	// Handle exit button
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitButtonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -428,7 +428,7 @@ void HamRadioPuzzle::handleInput(NancyInput &input) {
 	for (uint i = 0; i < _buttonDests.size(); ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_buttonDests[i]).contains(input.mousePos)) {
 			if (i >= 10 || _pressedButton == kNone) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					_pressedButton = i;
diff --git a/engines/nancy/action/puzzle/leverpuzzle.cpp b/engines/nancy/action/puzzle/leverpuzzle.cpp
index 0499107b533..a8d055c046e 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.cpp
+++ b/engines/nancy/action/puzzle/leverpuzzle.cpp
@@ -34,8 +34,8 @@ namespace Nancy {
 namespace Action {
 
 void LeverPuzzle::init() {
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 
@@ -156,7 +156,7 @@ void LeverPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -166,7 +166,7 @@ void LeverPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i < 3; ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_destRects[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				bool isMoving = false;
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.cpp b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
index 5a701dedd80..57f7869f27c 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.cpp
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void MazeChasePuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -268,7 +268,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -285,7 +285,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
 
 	if (NancySceneState.getViewport().convertViewportToScreen(buttonHotspot).contains(input.mousePos)) {
 		if (canMove(0, kWallUp)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				--_pieces[0]._gridPos.y;
@@ -304,7 +304,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
 
 	if (NancySceneState.getViewport().convertViewportToScreen(buttonHotspot).contains(input.mousePos)) {
 		if (canMove(0, kWallRight)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				++_pieces[0]._gridPos.x;
@@ -323,7 +323,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
 
 	if (NancySceneState.getViewport().convertViewportToScreen(buttonHotspot).contains(input.mousePos)) {
 		if (canMove(0, kWallDown)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				++_pieces[0]._gridPos.y;
@@ -342,7 +342,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
 
 	if (NancySceneState.getViewport().convertViewportToScreen(buttonHotspot).contains(input.mousePos)) {
 		if (canMove(0, kWallLeft)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				--_pieces[0]._gridPos.x;
@@ -360,7 +360,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
 	buttonHotspot.grow(-10);
 	
 	if (NancySceneState.getViewport().convertViewportToScreen(buttonHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			++_currentAnimFrame;
diff --git a/engines/nancy/action/puzzle/mouselightpuzzle.cpp b/engines/nancy/action/puzzle/mouselightpuzzle.cpp
index 89f9b9e88dd..d92850dff55 100644
--- a/engines/nancy/action/puzzle/mouselightpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mouselightpuzzle.cpp
@@ -38,14 +38,14 @@ void MouseLightPuzzle::init() {
 	Graphics::ManagedSurface baseImage;
 	g_nancy->_resource->loadImage(_imageName, baseImage);
 
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getTransparentPixelFormat());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getTransparentPixelFormat());
 	_drawSurface.blitFrom(baseImage);
 	((Graphics::Surface)_drawSurface).setAlpha(0);
 
 	setVisible(true);
 	moveTo(screenBounds);
 
-	_maskCircle.create(_radius * 2, _radius * 2, g_nancy->_graphicsManager->getInputPixelFormat());
+	_maskCircle.create(_radius * 2, _radius * 2, g_nancy->_graphics->getInputPixelFormat());
 	_maskCircle.clear();
 
 	if (_smoothEdges) {
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.cpp b/engines/nancy/action/puzzle/orderingpuzzle.cpp
index db372ed0530..6834b5910ee 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/orderingpuzzle.cpp
@@ -53,7 +53,7 @@ void OrderingPuzzle::init() {
 	}
 
 	g_nancy->_resource->loadImage(_imageName, _image);
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
 
 	if (_image.hasPalette()) {
 		uint8 palette[256 * 3];
@@ -447,7 +447,7 @@ void OrderingPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -456,7 +456,7 @@ void OrderingPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (_needButtonToCheckSuccess && NancySceneState.getViewport().convertViewportToScreen(_checkButtonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 			_checkButtonPressed = true;
@@ -473,11 +473,11 @@ void OrderingPuzzle::handleInput(NancyInput &input) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_hotspots[i]).contains(input.mousePos)) {
 			// Set the custom cursor for nancy8+ PianoPuzzle
 			if (NancySceneState.getViewport().convertViewportToScreen(_specialCursor1Dest).contains(input.mousePos)) {
-				g_nancy->_cursorManager->setCursorType((CursorManager::CursorType)_specialCursor1Id);
+				g_nancy->_cursor->setCursorType((CursorManager::CursorType)_specialCursor1Id);
 			} else if (NancySceneState.getViewport().convertViewportToScreen(_specialCursor2Dest).contains(input.mousePos)) {
-				g_nancy->_cursorManager->setCursorType((CursorManager::CursorType)_specialCursor2Id);
+				g_nancy->_cursor->setCursorType((CursorManager::CursorType)_specialCursor2Id);
 			} else {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 			}
 
 			if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.cpp b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
index 0ad0b211347..3c364f93910 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
@@ -38,8 +38,8 @@ namespace Action {
 void OverrideLockPuzzle::init() {
 	Common::Rect bounds = NancySceneState.getViewport().getBounds();
 
-	_drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 	setVisible(true);
@@ -171,7 +171,7 @@ void OverrideLockPuzzle::handleInput(NancyInput &input) {
 
 	// Check the exit hotspot
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -194,7 +194,7 @@ void OverrideLockPuzzle::handleInput(NancyInput &input) {
 		}
 
 		if (NancySceneState.getViewport().convertViewportToScreen(_hotspots[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!g_nancy->_sound->isSoundPlaying(_buttonSound) && input.input & NancyInput::kLeftMouseButtonUp) {
 				drawButton(i, false);
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.cpp b/engines/nancy/action/puzzle/passwordpuzzle.cpp
index 83ba2488ec9..d280f10c8c1 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.cpp
+++ b/engines/nancy/action/puzzle/passwordpuzzle.cpp
@@ -37,8 +37,8 @@ PasswordPuzzle::~PasswordPuzzle() {
 }
 
 void PasswordPuzzle::init() {
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 
@@ -197,7 +197,7 @@ void PasswordPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -238,8 +238,8 @@ void PasswordPuzzle::handleInput(NancyInput &input) {
 }
 
 void PasswordPuzzle::drawText() {
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
-	const Graphics::Font *font = g_nancy->_graphicsManager->getFont(_fontID);
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
+	const Graphics::Font *font = g_nancy->_graphics->getFont(_fontID);
 
 	Common::Rect bounds = _nameBounds;
 	bounds = NancySceneState.getViewport().convertViewportToScreen(bounds);
diff --git a/engines/nancy/action/puzzle/peepholepuzzle.cpp b/engines/nancy/action/puzzle/peepholepuzzle.cpp
index f04aa2c8ab3..619daf91a76 100644
--- a/engines/nancy/action/puzzle/peepholepuzzle.cpp
+++ b/engines/nancy/action/puzzle/peepholepuzzle.cpp
@@ -35,7 +35,7 @@ namespace Action {
 
 void PeepholePuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
 	moveTo(screenBounds);
 
 	Common::Rect innerImageContentBounds;
@@ -106,7 +106,7 @@ void PeepholePuzzle::handleInput(NancyInput &input) {
 	bool justReleased = false;
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -119,7 +119,7 @@ void PeepholePuzzle::handleInput(NancyInput &input) {
 			if (NancySceneState.getViewport().convertViewportToScreen(_buttonDests[_pressedButton]).contains(input.mousePos)) {
 				if (!_disabledButtons[_pressedButton]) {
 					// Do not show hover cursor on disabled button
-					g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+					g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 				}
 
 				if (_pressStart == 0) {
@@ -136,7 +136,7 @@ void PeepholePuzzle::handleInput(NancyInput &input) {
 
 			// Avoid single frame with non-highlighted cursor
 			if (NancySceneState.getViewport().convertViewportToScreen(_buttonDests[_pressedButton]).contains(input.mousePos) && !_disabledButtons[_pressedButton]) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 			}
 
 			_pressedButton = -1;
@@ -148,7 +148,7 @@ void PeepholePuzzle::handleInput(NancyInput &input) {
 		for (uint i = 0; i < 4; ++i) {
 			if (!_disabledButtons[i]) {
 				if (NancySceneState.getViewport().convertViewportToScreen(_buttonDests[i]).contains(input.mousePos)) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+					g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 					if (input.input & NancyInput::kLeftMouseButtonDown) {
 						if (_pressedButton == -1) {
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index 912dab13977..07d9bfdb775 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -901,7 +901,7 @@ bool RaycastDeferredLoader::loadInner() {
 		
 		Common::Rect viewport = viewportData->bounds;
 		_owner.moveTo(viewport);
-		_owner._drawSurface.create(viewport.width(), viewport.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+		_owner._drawSurface.create(viewport.width(), viewport.height(), g_nancy->_graphics->getInputPixelFormat());
 		_owner.setTransparent(true);
 
 		_loadState = kInitPlayerLocationRotation;
@@ -1048,7 +1048,7 @@ bool RaycastDeferredLoader::loadInner() {
 		if (!shouldBreak) {
 			for (auto &a : _owner._specialWallTextures) {
 				for (auto &tex : a._value) {
-					tex.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+					tex.setTransparentColor(g_nancy->_graphics->getTransColor());
 				}
 			}
 
@@ -1369,8 +1369,8 @@ void RaycastPuzzle::drawMap() {
 	auto *bootSummary = GetEngineData(BSUM);
 	assert(bootSummary);
 
-	_mapBaseSurface.create(_mapFullWidth, _mapFullHeight, g_nancy->_graphicsManager->getInputPixelFormat());
-	_map._drawSurface.create(_mapFullWidth, _mapFullHeight, g_nancy->_graphicsManager->getInputPixelFormat());
+	_mapBaseSurface.create(_mapFullWidth, _mapFullHeight, g_nancy->_graphics->getInputPixelFormat());
+	_map._drawSurface.create(_mapFullWidth, _mapFullHeight, g_nancy->_graphics->getInputPixelFormat());
 	Common::Rect mapPos(bootSummary->textboxScreenPosition);
 	mapPos.setWidth(_mapFullWidth * 2);
 	mapPos.setHeight(_mapFullHeight * 2);
@@ -1448,10 +1448,10 @@ void RaycastPuzzle::updateMap() {
 }
 
 void RaycastPuzzle::createTextureLightSourcing(Common::Array<Graphics::ManagedSurface> *array, const Common::Path &textureName) {
-	Graphics::PixelFormat format = g_nancy->_graphicsManager->getInputPixelFormat();
+	Graphics::PixelFormat format = g_nancy->_graphics->getInputPixelFormat();
 	array->resize(8);
 
-	uint16 transColor = g_nancy->_graphicsManager->getTransColor();
+	uint16 transColor = g_nancy->_graphics->getTransColor();
 
 	g_nancy->_resource->loadImage(textureName, (*array)[0]);
 
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.cpp b/engines/nancy/action/puzzle/riddlepuzzle.cpp
index c8210d9dac4..a817a6fbfa2 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.cpp
+++ b/engines/nancy/action/puzzle/riddlepuzzle.cpp
@@ -40,8 +40,8 @@ RiddlePuzzle::~RiddlePuzzle() {
 }
 
 void RiddlePuzzle::init() {
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 	setVisible(true);
@@ -276,7 +276,7 @@ void RiddlePuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -326,8 +326,8 @@ void RiddlePuzzle::handleInput(NancyInput &input) {
 }
 
 void RiddlePuzzle::drawText() {
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
-	const Graphics::Font *font = g_nancy->_graphicsManager->getFont(_viewportTextFontID);
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
+	const Graphics::Font *font = g_nancy->_graphics->getFont(_viewportTextFontID);
 
 	Common::Rect bounds = getBounds();
 	Common::Point destPoint(bounds.left, bounds.bottom - font->getFontHeight());
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
index 5170c09597c..1560ed31318 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
@@ -38,8 +38,8 @@ namespace Action {
 
 void RippedLetterPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -49,7 +49,7 @@ void RippedLetterPuzzle::init() {
 	if (_useCustomPickUpTile) {
 		_pickedUpPiece._drawSurface.create(_image, _customPickUpTileSrc);
 	} else {
-		_pickedUpPiece._drawSurface.create(_destRects[0].width(), _destRects[0].height(), g_nancy->_graphicsManager->getInputPixelFormat());
+		_pickedUpPiece._drawSurface.create(_destRects[0].width(), _destRects[0].height(), g_nancy->_graphics->getInputPixelFormat());
 	}
 
 	_pickedUpPiece.setVisible(false);
@@ -228,7 +228,7 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
 				insideRect.translate(screenHotspot.left, screenHotspot.top);
 
 				if (_rotationType != kRotationNone && insideRect.contains(input.mousePos)) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kRotateCW);
+					g_nancy->_cursor->setCursorType(CursorManager::kRotateCW);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						// Player has clicked, rotate the piece
@@ -249,14 +249,14 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
 				insideRect.translate(screenHotspot.left, screenHotspot.top);
 
 				if (insideRect.contains(input.mousePos)) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+					g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						// Player has clicked, take the piece
 
 						// First, copy the graphic from the full drawSurface...
 						if (!_useCustomPickUpTile) {
-							_pickedUpPiece._drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+							_pickedUpPiece._drawSurface.clear(g_nancy->_graphics->getTransColor());
 							_pickedUpPiece._drawSurface.blitFrom(_drawSurface, _destRects[i], Common::Point());
 						}
 						
@@ -285,7 +285,7 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
 				insideRect.translate(screenHotspot.left, screenHotspot.top);
 
 				if (insideRect.contains(input.mousePos)) {
-					g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+					g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						// Player has clicked, drop the piece and pick up a new one
@@ -297,7 +297,7 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
 						} else {
 							// Yes, change the picked piece graphic
 							if (!_useCustomPickUpTile) {
-								_pickedUpPiece._drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+								_pickedUpPiece._drawSurface.clear(g_nancy->_graphics->getTransColor());
 								_pickedUpPiece._drawSurface.blitFrom(_drawSurface, _destRects[i], Common::Point());
 							}
 							
@@ -325,7 +325,7 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
 	if (_pickedUpPieceID == -1) {
 		// No piece picked up, check the exit hotspot
 		if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+			g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				// Player has clicked, exit
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp b/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
index 357ad6929eb..4cb6628ebdc 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
@@ -36,8 +36,8 @@ namespace Nancy {
 namespace Action {
 
 void RotatingLockPuzzle::init() {
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 
@@ -167,7 +167,7 @@ void RotatingLockPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -178,7 +178,7 @@ void RotatingLockPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i < _upHotspots.size(); ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_upHotspots[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!g_nancy->_sound->isSoundPlaying(_clickSound) && input.input & NancyInput::kLeftMouseButtonUp) {
 				g_nancy->_sound->playSound(_clickSound);
@@ -193,7 +193,7 @@ void RotatingLockPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i < _downHotspots.size(); ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_downHotspots[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!g_nancy->_sound->isSoundPlaying(_clickSound) && input.input & NancyInput::kLeftMouseButtonUp) {
 				g_nancy->_sound->playSound(_clickSound);
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.cpp b/engines/nancy/action/puzzle/safedialpuzzle.cpp
index f0f30e3d31b..91ef060c1bd 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/safedialpuzzle.cpp
@@ -41,8 +41,8 @@ void SafeDialPuzzle::init() {
 	g_nancy->_resource->loadImage(_resetImageName, _resetImage);
 
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -206,7 +206,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -218,7 +218,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
 			return;
 		}
 
-		g_nancy->_cursorManager->setCursorType(_useMoveArrows ? CursorManager::kMoveLeft : CursorManager::kRotateCCW);
+		g_nancy->_cursor->setCursorType(_useMoveArrows ? CursorManager::kMoveLeft : CursorManager::kRotateCCW);
 
 		if (!g_nancy->_sound->isSoundPlaying(_spinSound) && input.input & NancyInput::kLeftMouseButtonUp && _nextAnim < g_nancy->getTotalPlayTime() &&
 				_animState != kReset && _animState != kResetAnim) {
@@ -241,7 +241,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
 			return;
 		}
 
-		g_nancy->_cursorManager->setCursorType(_useMoveArrows ? CursorManager::kMoveRight : CursorManager::kRotateCW);
+		g_nancy->_cursor->setCursorType(_useMoveArrows ? CursorManager::kMoveRight : CursorManager::kRotateCW);
 
 		if (!g_nancy->_sound->isSoundPlaying(_spinSound) && input.input & NancyInput::kLeftMouseButtonUp && _nextAnim < g_nancy->getTotalPlayTime() &&
 				_animState != kReset && _animState != kResetAnim) {
@@ -266,7 +266,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
 	}
 	
 	if (NancySceneState.getViewport().convertViewportToScreen(_arrowDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!g_nancy->_sound->isSoundPlaying(_selectSound) && input.input & NancyInput::kLeftMouseButtonUp) {
 			g_nancy->_sound->playSound(_selectSound);
@@ -279,7 +279,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
 
 		return;
 	} else if (NancySceneState.getViewport().convertViewportToScreen(_resetDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!g_nancy->_sound->isSoundPlaying(_resetSound) && input.input & NancyInput::kLeftMouseButtonUp) {
 			_drawSurface.blitFrom(_image1, _resetSrc, _resetDest);
diff --git a/engines/nancy/action/puzzle/setplayerclock.cpp b/engines/nancy/action/puzzle/setplayerclock.cpp
index 556c07a78c0..fc5b0ef8122 100644
--- a/engines/nancy/action/puzzle/setplayerclock.cpp
+++ b/engines/nancy/action/puzzle/setplayerclock.cpp
@@ -42,8 +42,8 @@ SetPlayerClock::~SetPlayerClock() {
 
 void SetPlayerClock::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -186,7 +186,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
 
 	// Cancel button is active in both time and alarm mode
 	if (NancySceneState.getViewport().convertViewportToScreen(_cancelButtonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!_clearButton && input.input & NancyInput::kLeftMouseButtonUp) {
 			// Cancel button pressed
@@ -203,7 +203,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
 	if (_alarmState == kTimeMode) {
 		// Alarm button is active only in time mode
 		if (NancySceneState.getViewport().convertViewportToScreen(_alarmButtonDest).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!_clearButton && input.input & NancyInput::kLeftMouseButtonUp) {
 				// Alarm button pressed
@@ -221,7 +221,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
 	} else {
 		if (NancySceneState.getViewport().convertViewportToScreen(_timeButtonDest).contains(input.mousePos)) {
 			// Time button is active only in alarm mode
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!_clearButton && input.input & NancyInput::kLeftMouseButtonUp) {
 				// Alarm button pressed
@@ -236,7 +236,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
 			}
 		} else if (NancySceneState.getViewport().convertViewportToScreen(_upButtonDest).contains(input.mousePos)) {
 			// Up button is active only in alarm mode
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!_clearButton && input.input & NancyInput::kLeftMouseButtonUp) {
 				// Up button pressed
@@ -251,7 +251,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
 			}
 		} else if (NancySceneState.getViewport().convertViewportToScreen(_downButtonDest).contains(input.mousePos)) {
 			// Down button is active only in alarm mode
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!_clearButton && input.input & NancyInput::kLeftMouseButtonUp) {
 				// Down button pressed
@@ -266,7 +266,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
 			}
 		} else if (NancySceneState.getViewport().convertViewportToScreen(_setButtonDest).contains(input.mousePos)) {
 			// Set button is active only in alarm mode
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (!_clearButton && input.input & NancyInput::kLeftMouseButtonUp) {
 				// Down button pressed
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.cpp b/engines/nancy/action/puzzle/sliderpuzzle.cpp
index 38d3f2ffbc9..ac96648279e 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sliderpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Nancy {
 namespace Action {
 
 void SliderPuzzle::init() {
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 
@@ -171,7 +171,7 @@ void SliderPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -227,7 +227,7 @@ void SliderPuzzle::handleInput(NancyInput &input) {
 	}
 
 	if (currentTileX != -1) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (!g_nancy->_sound->isSoundPlaying(_clickSound) && input.input & NancyInput::kLeftMouseButtonUp) {
 			g_nancy->_sound->playSound(_clickSound);
@@ -284,7 +284,7 @@ void SliderPuzzle::drawTile(int tileID, uint posX, uint posY) {
 void SliderPuzzle::undrawTile(uint posX, uint posY) {
 	Common::Rect bounds = _destRects[posY][posX];
 	bounds.translate(-_screenPosition.left, -_screenPosition.top);
-	_drawSurface.fillRect(bounds, g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.fillRect(bounds, g_nancy->_graphics->getTransColor());
 
 	_needsRedraw = true;
 }
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
index d342f5833fc..d5f2bfa56c5 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
@@ -46,7 +46,7 @@ public:
 
 			Scrollbar::handleInput(input);
 
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 			return true;
 		}
 
@@ -62,8 +62,8 @@ SoundEqualizerPuzzle::~SoundEqualizerPuzzle() {
 
 void SoundEqualizerPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -226,14 +226,14 @@ void SoundEqualizerPuzzle::execute() {
 
 void SoundEqualizerPuzzle::handleInput(NancyInput &input) {
 	if (_state == kActionTrigger) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 		return;
 	} else if (_state == kBegin) {
 		return;
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_buttonDest).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			// Exit button pressed
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.cpp b/engines/nancy/action/puzzle/spigotpuzzle.cpp
index b3351c48fa3..b225bcdfdaa 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.cpp
+++ b/engines/nancy/action/puzzle/spigotpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void SpigotPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -262,7 +262,7 @@ void SpigotPuzzle::handleInput(NancyInput &input) {
 	mousePos -= { vpScreenPos.left, vpScreenPos.top };
 
 	if (_exitHotspot.contains(mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -273,7 +273,7 @@ void SpigotPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i < _numSpigots; ++i) {
 		if (_spigotHotspots[i].contains(mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				g_nancy->_sound->playSound(_spigotSound);
@@ -283,7 +283,7 @@ void SpigotPuzzle::handleInput(NancyInput &input) {
 		}
 
 		if (_numPulls[i] && _buttonDests[i].contains(mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				g_nancy->_sound->playSound(_buttonSound);
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.cpp b/engines/nancy/action/puzzle/tangrampuzzle.cpp
index be70e73a6a3..7a7eb5542cd 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.cpp
+++ b/engines/nancy/action/puzzle/tangrampuzzle.cpp
@@ -39,8 +39,8 @@ TangramPuzzle::~TangramPuzzle() {
 
 void TangramPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -85,7 +85,7 @@ void TangramPuzzle::init() {
 		for (int y = 0; y < curTile->_highlightedSrcImage.h; ++y) {
 			uint16 *p = (uint16 *)curTile->_highlightedSrcImage.getBasePtr(0, y);
 			for (int x = 0; x < curTile->_highlightedSrcImage.w; ++x) {
-				if (*p != g_nancy->_graphicsManager->getTransColor()) {
+				if (*p != g_nancy->_graphics->getTransColor()) {
 					// I'm not sure *3/2 is the exact formula but it's close enough
 					byte r, g, b;
 					format.colorToRGB(*p, r, g, b);
@@ -220,7 +220,7 @@ void TangramPuzzle::handleInput(NancyInput &input) {
 
 		if (idUnderMouse != 0 && idUnderMouse != (byte)-1) {
 			// A tile is under the cursor
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				pickUpTile(idUnderMouse);
@@ -235,7 +235,7 @@ void TangramPuzzle::handleInput(NancyInput &input) {
 
 		// No tile under cursor, check exit hotspot
 		if (_exitHotspot.contains(mousePos)) {
-			g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+			g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				_state = kActionTrigger;
@@ -426,7 +426,7 @@ void TangramPuzzle::Tile::drawMask() {
 		_mask = new byte[_drawSurface.w * _drawSurface.h];
 	}
 
-	uint16 transColor = g_nancy->_graphicsManager->getTransColor();
+	uint16 transColor = g_nancy->_graphics->getTransColor();
 	for (int y = 0; y < _drawSurface.h; ++y) {
 		uint16 *src = (uint16 *)_drawSurface.getBasePtr(0, y);
 		for (int x = 0; x < _drawSurface.w; ++x) {
diff --git a/engines/nancy/action/puzzle/telephone.cpp b/engines/nancy/action/puzzle/telephone.cpp
index 184ffb56aab..0e4d05c9660 100644
--- a/engines/nancy/action/puzzle/telephone.cpp
+++ b/engines/nancy/action/puzzle/telephone.cpp
@@ -34,8 +34,8 @@ namespace Nancy {
 namespace Action {
 
 void Telephone::init() {
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	setTransparent(true);
 
@@ -276,7 +276,7 @@ void Telephone::handleInput(NancyInput &input) {
 	// Cursor gets changed regardless of state
 	for (uint i = 0; i < 12; ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_destRects[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 			buttonNr = i;
 			break;
 		}
@@ -287,7 +287,7 @@ void Telephone::handleInput(NancyInput &input) {
 	}
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			g_nancy->_sound->loadSound(_hangUpSound);
@@ -334,7 +334,7 @@ void Telephone::undrawButton(uint id) {
 	Common::Rect bounds = _destRects[id];
 	bounds.translate(-_screenPosition.left, -_screenPosition.top);
 
-	_drawSurface.fillRect(bounds, g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.fillRect(bounds, g_nancy->_graphics->getTransColor());
 	_needsRedraw = true;
 }
 
diff --git a/engines/nancy/action/puzzle/towerpuzzle.cpp b/engines/nancy/action/puzzle/towerpuzzle.cpp
index cc7758b4f40..39a0d1bda8a 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/towerpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void TowerPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -182,7 +182,7 @@ void TowerPuzzle::handleInput(NancyInput &input) {
 	int hoveredPoleID = -1;
 	for (uint poleID = 0; poleID < 3; ++poleID) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_hotspots[poleID]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 			hoveredPoleID = poleID;
 			break;
 		}
@@ -193,7 +193,7 @@ void TowerPuzzle::handleInput(NancyInput &input) {
 
 		// First, check the exit hotspot
 		if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+			g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 			if (input.input & NancyInput::kLeftMouseButtonUp) {
 				// Player has clicked, exit
diff --git a/engines/nancy/action/puzzle/turningpuzzle.cpp b/engines/nancy/action/puzzle/turningpuzzle.cpp
index 75b8e4e8ed9..301d1363b70 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.cpp
+++ b/engines/nancy/action/puzzle/turningpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void TurningPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -257,7 +257,7 @@ void TurningPuzzle::execute() {
 
 void TurningPuzzle::handleInput(NancyInput &input) {
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -268,7 +268,7 @@ void TurningPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i < _hotspots.size(); ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_hotspots[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 			if (_objectCurrentlyTurning != -1) {
 				break;
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.cpp b/engines/nancy/action/puzzle/twodialpuzzle.cpp
index 759ea77942e..b0b4cfb73d2 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/twodialpuzzle.cpp
@@ -35,8 +35,8 @@ namespace Action {
 
 void TwoDialPuzzle::init() {
 	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
-	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 	setVisible(true);
 	moveTo(screenBounds);
@@ -141,7 +141,7 @@ void TwoDialPuzzle::handleInput(NancyInput &input) {
 	bool canClick = (_state == kRun) && !g_nancy->_sound->isSoundPlaying(_rotateSounds[0]) && !g_nancy->_sound->isSoundPlaying(_rotateSounds[1]);
 
 	if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+		g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
 
 		if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 			_state = kActionTrigger;
@@ -152,7 +152,7 @@ void TwoDialPuzzle::handleInput(NancyInput &input) {
 
 	for (uint i = 0; i <= 1; ++i) {
 		if (NancySceneState.getViewport().convertViewportToScreen(_hotspots[i]).contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(_isClockwise[i] ? CursorManager::kRotateCW : CursorManager::kRotateCCW);
+			g_nancy->_cursor->setCursorType(_isClockwise[i] ? CursorManager::kRotateCW : CursorManager::kRotateCCW);
 
 			if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
 				_currentPositions[i] += _isClockwise[i] ? -1 : 1;
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 4dfa65d6f37..81cb115eb2e 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -151,7 +151,7 @@ void PlaySecondaryMovie::execute() {
 		_state = kRun;
 
 		if (Common::Rect(_decoder->getWidth(), _decoder->getHeight()) == NancySceneState.getViewport().getBounds()) {
-			g_nancy->_graphicsManager->suppressNextDraw();
+			g_nancy->_graphics->suppressNextDraw();
 			break;
 		}
 
diff --git a/engines/nancy/action/secondaryvideo.cpp b/engines/nancy/action/secondaryvideo.cpp
index 0e9aaf5cc10..dfbcd6783b8 100644
--- a/engines/nancy/action/secondaryvideo.cpp
+++ b/engines/nancy/action/secondaryvideo.cpp
@@ -45,7 +45,7 @@ void PlaySecondaryVideo::init() {
 	// Every secondary video frame (in nancy1) plays exactly 12ms slower than what its metadata says.
 	// I'm still not sure how/why that happens so for now I'm using this hack to fix the timings
 	_decoder.addFrameTime(12);
-	_drawSurface.create(_decoder.getWidth(), _decoder.getHeight(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(_decoder.getWidth(), _decoder.getHeight(), g_nancy->_graphics->getInputPixelFormat());
 
 	if (!_paletteFilename.empty()) {
 		GraphicsManager::loadSurfacePalette(_fullFrame, _paletteFilename);
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index d7172e4ca87..b1cb70bdb11 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -112,14 +112,14 @@ void NancyConsole::postEnter() {
 					const Graphics::Surface *frame = dec->decodeNextFrame();
 					if (frame) {
 						GraphicsManager::copyToManaged(*frame, surf, !_paletteFile.empty());
-						g_nancy->_graphicsManager->debugDrawToScreen(surf);
+						g_nancy->_graphics->debugDrawToScreen(surf);
 					}
 				}
 
 				g_system->delayMillis(10);
 			}
 
-			g_nancy->_graphicsManager->redrawAll();
+			g_nancy->_graphics->redrawAll();
 		}
 
 		_videoFile.clear();
@@ -134,7 +134,7 @@ void NancyConsole::postEnter() {
 				GraphicsManager::loadSurfacePalette(surf, _paletteFile);
 			}
 
-			g_nancy->_graphicsManager->debugDrawToScreen(surf);
+			g_nancy->_graphics->debugDrawToScreen(surf);
 
 			Common::EventManager *ev = g_system->getEventManager();
 			while (!g_nancy->shouldQuit()) {
@@ -150,7 +150,7 @@ void NancyConsole::postEnter() {
 				g_system->delayMillis(10);
 			}
 
-			g_nancy->_graphicsManager->redrawAll();
+			g_nancy->_graphics->redrawAll();
 		} else {
 			debugPrintf("Failed to load image '%s'\n", _imageFile.toString().c_str());
 		}
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index f90932684a7..058aef34cf8 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -279,12 +279,12 @@ void CursorManager::applyCursor() {
 			surf = &_invCursorsSurface;
 
 		} else {
-			surf = &g_nancy->_graphicsManager->_object0;
+			surf = &g_nancy->_graphics->_object0;
 		}
 
 		Graphics::ManagedSurface temp(*surf, bounds);
 
-		CursorMan.replaceCursor(temp, hotspot.x, hotspot.y, g_nancy->_graphicsManager->getTransColor(), false);
+		CursorMan.replaceCursor(temp, hotspot.x, hotspot.y, g_nancy->_graphics->getTransColor(), false);
 		if (g_nancy->getGameType() == kGameTypeVampire) {
 			byte palette[3 * 256];
 			surf->grabPalette(palette, 0, 256);
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 0f3114e5b0b..4d253fada34 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -242,7 +242,7 @@ TBOX::TBOX(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 	tabWidth = chunkStream->readUint16LE();
 	pageScrollPercent = chunkStream->readUint16LE(); // Not implemented yet
 
-	Graphics::PixelFormat format = g_nancy->_graphicsManager->getInputPixelFormat();
+	Graphics::PixelFormat format = g_nancy->_graphics->getInputPixelFormat();
 	if (g_nancy->getGameType() >= kGameTypeNancy2) {
 		byte r, g, b;
 		r = chunkStream->readByte();
diff --git a/engines/nancy/font.cpp b/engines/nancy/font.cpp
index bd3e3e2912e..969a4c7fd9b 100644
--- a/engines/nancy/font.cpp
+++ b/engines/nancy/font.cpp
@@ -29,7 +29,7 @@
 namespace Nancy {
 
 void Font::read(Common::SeekableReadStream &stream) {
-	_transColor = g_nancy->_graphicsManager->getTransColor();
+	_transColor = g_nancy->_graphics->getTransColor();
 	_maxCharWidth = 0;
 	_fontHeight = 0;
 	uint16 numCharacters = 78;
@@ -38,7 +38,7 @@ void Font::read(Common::SeekableReadStream &stream) {
 	readFilename(stream, imageName);
 
 	g_nancy->_resource->loadImage(imageName, _image);
-	_image.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+	_image.setTransparentColor(g_nancy->_graphics->getTransColor());
 
 	char desc[31];
 	stream.read(desc, 30);
diff --git a/engines/nancy/graphics.cpp b/engines/nancy/graphics.cpp
index ab12ee24e30..cd070e88dda 100644
--- a/engines/nancy/graphics.cpp
+++ b/engines/nancy/graphics.cpp
@@ -70,7 +70,7 @@ void GraphicsManager::draw(bool updateScreen) {
 		return;
 	}
 
-	g_nancy->_cursorManager->applyCursor();
+	g_nancy->_cursor->applyCursor();
 
 	// Update graphics for all RenderObjects and determine
 	// the areas of the screen that need to be redrawn
diff --git a/engines/nancy/metaengine.cpp b/engines/nancy/metaengine.cpp
index 0d1f5cd5609..1ce915dcd15 100644
--- a/engines/nancy/metaengine.cpp
+++ b/engines/nancy/metaengine.cpp
@@ -172,7 +172,7 @@ void NancyMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
 
 	// Make sure we always trigger a screen redraw to support second chance saves
 	Graphics::ManagedSurface screenshotSurf;
-	Nancy::g_nancy->_graphicsManager->screenshotScreen(screenshotSurf);
+	Nancy::g_nancy->_graphics->screenshotScreen(screenshotSurf);
 	if (!screenshotSurf.empty() && createThumbnail(&thumb, &screenshotSurf)) {
 		return;
 	}
diff --git a/engines/nancy/misc/hypertext.cpp b/engines/nancy/misc/hypertext.cpp
index bcd97a82ed2..f0bb5c3f714 100644
--- a/engines/nancy/misc/hypertext.cpp
+++ b/engines/nancy/misc/hypertext.cpp
@@ -194,8 +194,8 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
 			currentLine += curToken;
 		}
 		
-		font = g_nancy->_graphicsManager->getFont(curFontID);
-		highlightFont = g_nancy->_graphicsManager->getFont(highlightFontID);
+		font = g_nancy->_graphics->getFont(curFontID);
+		highlightFont = g_nancy->_graphics->getFont(highlightFontID);
 		assert(font && highlightFont);
 
 		// Do word wrapping on the text, sans tokens. This assumes
@@ -277,7 +277,7 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
 					switch (change.type) {
 					case MetaInfo::kFont:
 						curFontID = change.index;
-						font = g_nancy->_graphicsManager->getFont(curFontID);
+						font = g_nancy->_graphics->getFont(curFontID);
 						break;
 					case MetaInfo::kColor:
 						colorID = change.index;
@@ -303,7 +303,7 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
 								textBounds.top + _numDrawnLines * font->getFontHeight() + _imageVerticalOffset - 4);
 
 						// For now we do not check if we need to go to new line; neither does the original
-						_fullSurface.blitFrom(g_nancy->_graphicsManager->_object0, markSrc, markDest);
+						_fullSurface.blitFrom(g_nancy->_graphics->_object0, markSrc, markDest);
 
 						horizontalOffset += markDest.width() + 2;
 					}
diff --git a/engines/nancy/misc/lightning.cpp b/engines/nancy/misc/lightning.cpp
index 5058f5b3f25..1a46366d670 100644
--- a/engines/nancy/misc/lightning.cpp
+++ b/engines/nancy/misc/lightning.cpp
@@ -104,7 +104,7 @@ void Lightning::run() {
 		break;
 	}
 	case kBegin:
-		g_nancy->_graphicsManager->grabViewportObjects(_viewportObjs);
+		g_nancy->_graphics->grabViewportObjects(_viewportObjs);
 
 		for (RenderObject *obj : _viewportObjs) {
 			if (!obj) {
diff --git a/engines/nancy/misc/specialeffect.cpp b/engines/nancy/misc/specialeffect.cpp
index cc7a663a468..3ee199e23cb 100644
--- a/engines/nancy/misc/specialeffect.cpp
+++ b/engines/nancy/misc/specialeffect.cpp
@@ -54,7 +54,7 @@ void SpecialEffect::init() {
 		}
 	}
 
-	_drawSurface.create(_rect.width(), _rect.height(), g_nancy->_graphicsManager->getScreenPixelFormat());
+	_drawSurface.create(_rect.width(), _rect.height(), g_nancy->_graphics->getScreenPixelFormat());
 	moveTo(_rect);
 	setTransparent(false);
 
@@ -112,7 +112,7 @@ void SpecialEffect::updateGraphics() {
 				_throughBlackStarted2nd = true;
 				_fadeFrom.clear();
 				setVisible(false);
-				g_nancy->_graphicsManager->screenshotScreen(_fadeTo);
+				g_nancy->_graphics->screenshotScreen(_fadeTo);
 				setVisible(true);
 				_startTime = g_nancy->getTotalPlayTime();
 				_currentFrame = 0;
@@ -122,7 +122,7 @@ void SpecialEffect::updateGraphics() {
 }
 
 void SpecialEffect::onSceneChange() {
-	g_nancy->_graphicsManager->screenshotScreen(_fadeFrom);
+	g_nancy->_graphics->screenshotScreen(_fadeFrom);
 	_drawSurface.rawBlitFrom(_fadeFrom, _rect, Common::Point());
 }
 
@@ -132,7 +132,7 @@ void SpecialEffect::afterSceneChange() {
 	}
 
 	if (_type == kCrossDissolve) {
-		g_nancy->_graphicsManager->screenshotScreen(_fadeTo);
+		g_nancy->_graphics->screenshotScreen(_fadeTo);
 	} else {
 		_fadeTo.create(640, 480, _drawSurface.format);
 		_fadeTo.clear();
@@ -143,7 +143,7 @@ void SpecialEffect::afterSceneChange() {
 	// the two default values transBlitFrom uses for transColor. By doing this,
 	// transColor gets set to the one color guaranteed to not appear in any scene,
 	// and transparency works correctly
-	_fadeTo.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+	_fadeTo.setTransparentColor(g_nancy->_graphics->getTransColor());
 
 	registerGraphics();
 	_nextFrameTime = g_nancy->getTotalPlayTime() + _frameTime;
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 283711ff744..f6631d7cd62 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -69,8 +69,8 @@ NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
 
 	_input = new InputManager();
 	_sound = new SoundManager();
-	_graphicsManager = new GraphicsManager();
-	_cursorManager = new CursorManager();
+	_graphics = new GraphicsManager();
+	_cursor = new CursorManager();
 
 	_resource = nullptr;
 
@@ -90,8 +90,8 @@ NancyEngine::~NancyEngine() {
 
 	delete _randomSource;
 
-	delete _graphicsManager;
-	delete _cursorManager;
+	delete _graphics;
+	delete _cursor;
 	delete _input;
 	delete _sound;
 
@@ -245,7 +245,7 @@ void NancyEngine::setToPreviousState() {
 }
 
 void NancyEngine::setMouseEnabled(bool enabled) {
-	_cursorManager->showCursor(enabled); _input->setMouseInputEnabled(enabled);
+	_cursor->showCursor(enabled); _input->setMouseInputEnabled(enabled);
 }
 
 void NancyEngine::addDeferredLoader(Common::SharedPtr<DeferredLoader> &loaderPtr) {
@@ -279,7 +279,7 @@ Common::Error NancyEngine::run() {
 		uint32 frameEndTime = _system->getMillis() + 16;
 
 		if (!graphicsWereSuppressed) {
-			_cursorManager->setCursorType(CursorManager::kNormalArrow);
+			_cursor->setCursorType(CursorManager::kNormalArrow);
 		}
 
 		State::State *s;
@@ -301,12 +301,12 @@ Common::Error NancyEngine::run() {
 			s->process();
 		}
 
-		graphicsWereSuppressed = _graphicsManager->_isSuppressed;
+		graphicsWereSuppressed = _graphics->_isSuppressed;
 
-		_graphicsManager->draw();
+		_graphics->draw();
 
 		if (_gameFlow.changingState) {
-			_graphicsManager->clearObjects();
+			_graphics->clearObjects();
 
 			s = getStateObject(_gameFlow.curState);
 			if (s) {
@@ -463,10 +463,10 @@ void NancyEngine::bootGameEngine() {
 		LOAD_BOOT_L(LOAD_v2, "LOAD")
 	}
 
-	_cursorManager->init(iff->getChunkStream("CURS"));
+	_cursor->init(iff->getChunkStream("CURS"));
 
-	_graphicsManager->init();
-	_graphicsManager->loadFonts(iff->getChunkStream("FONT"));
+	_graphics->init();
+	_graphics->loadFonts(iff->getChunkStream("FONT"));
 
 	preloadCals();
 
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 784248ff3ed..c18166a484c 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -114,8 +114,8 @@ public:
 
 	// Managers
 	ResourceManager *_resource;
-	GraphicsManager *_graphicsManager;
-	CursorManager *_cursorManager;
+	GraphicsManager *_graphics;
+	CursorManager *_cursor;
 	InputManager *_input;
 	SoundManager *_sound;
 
diff --git a/engines/nancy/renderobject.cpp b/engines/nancy/renderobject.cpp
index 0ec90398d59..bde35d17477 100644
--- a/engines/nancy/renderobject.cpp
+++ b/engines/nancy/renderobject.cpp
@@ -44,11 +44,11 @@ void RenderObject::init() {
 }
 
 void RenderObject::registerGraphics() {
-	g_nancy->_graphicsManager->addObject(this);
+	g_nancy->_graphics->addObject(this);
 }
 
 RenderObject::~RenderObject() {
-	g_nancy->_graphicsManager->removeObject(this);
+	g_nancy->_graphics->removeObject(this);
 	if (_drawSurface.getPixels()) {
 		_drawSurface.free();
 	}
@@ -83,7 +83,7 @@ void RenderObject::setVisible(bool visible) {
 
 void RenderObject::setTransparent(bool isTransparent) {
 	if (isTransparent) {
-		_drawSurface.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+		_drawSurface.setTransparentColor(g_nancy->_graphics->getTransColor());
 	} else {
 		_drawSurface.clearTransparentColor();
 	}
diff --git a/engines/nancy/resource.cpp b/engines/nancy/resource.cpp
index 69e53a6608d..d80eb838694 100644
--- a/engines/nancy/resource.cpp
+++ b/engines/nancy/resource.cpp
@@ -50,12 +50,12 @@ bool ResourceManager::loadImage(const Common::Path &name, Graphics::ManagedSurfa
 		}
 
 		if (surfID >= 0) {
-			surf.copyFrom(g_nancy->_graphicsManager->getAutotextSurface(surfID));
+			surf.copyFrom(g_nancy->_graphics->getAutotextSurface(surfID));
 			if (outSrc) {
 				// Slightly hacky, but we pass the size of the drawn text using the outSrc parameter;
 				// value is only guaranteed to be valid for an active surface.
 				// This is used for PeepholePuzzle scrolling.
-				*outSrc = g_nancy->_graphicsManager->getAutotextSurfaceBounds(surfID);
+				*outSrc = g_nancy->_graphics->getAutotextSurfaceBounds(surfID);
 			}
 
 			return true;
@@ -169,7 +169,7 @@ bool ResourceManager::loadImage(const Common::Path &name, Graphics::ManagedSurfa
 	}
 	#endif
 
-	GraphicsManager::copyToManaged(buf, surf, info.width, info.height, g_nancy->_graphicsManager->getInputPixelFormat());
+	GraphicsManager::copyToManaged(buf, surf, info.width, info.height, g_nancy->_graphics->getInputPixelFormat());
 	delete[] buf;
 	return true;
 }
diff --git a/engines/nancy/state/credits.cpp b/engines/nancy/state/credits.cpp
index 14756f90273..e4352372230 100644
--- a/engines/nancy/state/credits.cpp
+++ b/engines/nancy/state/credits.cpp
@@ -138,8 +138,8 @@ void Credits::drawTextSurface(uint id) {
 	Graphics::ManagedSurface image;
 	uint surfaceHeight = _textSurface.getBounds().height();
 	g_nancy->_resource->loadImage(_creditsData->textNames[id], image);
-	_fullTextSurface.create(image.w, image.h + (surfaceHeight * 2), g_nancy->_graphicsManager->getInputPixelFormat());
-	_fullTextSurface.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+	_fullTextSurface.create(image.w, image.h + (surfaceHeight * 2), g_nancy->_graphics->getInputPixelFormat());
+	_fullTextSurface.setTransparentColor(g_nancy->_graphics->getTransColor());
 	_fullTextSurface.clear(_fullTextSurface.getTransparentColor());
 	_fullTextSurface.blitFrom(image, Common::Point(0, surfaceHeight));
 
diff --git a/engines/nancy/state/help.cpp b/engines/nancy/state/help.cpp
index 9b244146ab9..79f9a105195 100644
--- a/engines/nancy/state/help.cpp
+++ b/engines/nancy/state/help.cpp
@@ -100,7 +100,7 @@ void Help::begin() {
 	_button->registerGraphics();
 	_image.setVisible(true);
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 
 	_state = kRun;
 }
diff --git a/engines/nancy/state/loadsave.cpp b/engines/nancy/state/loadsave.cpp
index eaeaf8f5fb5..eb463877429 100644
--- a/engines/nancy/state/loadsave.cpp
+++ b/engines/nancy/state/loadsave.cpp
@@ -96,7 +96,7 @@ void LoadSaveMenu::process() {
 		stop();
 	}
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 }
 
 void LoadSaveMenu::onStateEnter(const NancyState::NancyState prevState) {
@@ -141,7 +141,7 @@ void LoadSaveMenu::registerGraphics() {
 	_blinkingCursorOverlay.registerGraphics();
 	_successOverlay.registerGraphics();
 
-	g_nancy->_graphicsManager->redrawAll();
+	g_nancy->_graphics->redrawAll();
 }
 
 void LoadSaveMenu::init() {
@@ -150,11 +150,11 @@ void LoadSaveMenu::init() {
 
 	_background.init(_loadSaveData->_imageName);
 
-	_baseFont = g_nancy->_graphicsManager->getFont(_loadSaveData->_mainFontID);
+	_baseFont = g_nancy->_graphics->getFont(_loadSaveData->_mainFontID);
 
 	if (_loadSaveData->_highlightFontID != -1) {
-		_highlightFont = g_nancy->_graphicsManager->getFont(_loadSaveData->_highlightFontID);
-		_disabledFont = g_nancy->_graphicsManager->getFont(_loadSaveData->_disabledFontID);
+		_highlightFont = g_nancy->_graphics->getFont(_loadSaveData->_highlightFontID);
+		_disabledFont = g_nancy->_graphics->getFont(_loadSaveData->_disabledFontID);
 	} else {
 		_highlightFont = _disabledFont = _baseFont;
 	}
@@ -167,8 +167,8 @@ void LoadSaveMenu::init() {
 		RenderObject *newTb = new RenderObject(5);
 		_textboxes[i] = newTb;
 		const Common::Rect &bounds = _loadSaveData->_textboxBounds[i];
-		newTb->_drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphicsManager->getScreenPixelFormat());
-		newTb->_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+		newTb->_drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphics->getScreenPixelFormat());
+		newTb->_drawSurface.clear(g_nancy->_graphics->getTransColor());
 		newTb->moveTo(bounds);
 		newTb->setTransparent(true);
 		newTb->setVisible(true);
@@ -233,12 +233,12 @@ void LoadSaveMenu::init() {
 	// Load the blinking cursor graphic that appears while typing a filename
 	_blinkingCursorOverlay._drawSurface.create(_loadSaveData->_blinkingCursorSrc.width(),
 		_loadSaveData->_blinkingCursorSrc.height(),
-		g_nancy->_graphicsManager->getScreenPixelFormat());
+		g_nancy->_graphics->getScreenPixelFormat());
 	_blinkingCursorOverlay.setTransparent(true);
 	_blinkingCursorOverlay.setVisible(false);
 	_blinkingCursorOverlay._drawSurface.clear(_blinkingCursorOverlay._drawSurface.getTransparentColor());
 	_blinkingCursorOverlay._drawSurface.transBlitFrom(_highlightFont->getImageSurface(), _loadSaveData->_blinkingCursorSrc,
-		Common::Point(), g_nancy->_graphicsManager->getTransColor());
+		Common::Point(), g_nancy->_graphics->getTransColor());
 
 	// Load the "Your game has been saved" popup graphic
 	if (!_loadSaveData->_gameSavedPopup.empty()) {
@@ -477,7 +477,7 @@ void LoadSaveMenu::save() {
 				return;
 			} else {
 				// Dialog has returned
-				g_nancy->_graphicsManager->suppressNextDraw();
+				g_nancy->_graphics->suppressNextDraw();
 				_destroyOnExit = true;
 				uint ret = ConfMan.getInt("sdlg_return", Common::ConfigManager::kTransientDomain);
 				ConfMan.removeKey("sdlg_return", Common::ConfigManager::kTransientDomain);
@@ -570,7 +570,7 @@ void LoadSaveMenu::load() {
 		} else {
 			// Dialog has returned
 			_destroyOnExit = true;
-			g_nancy->_graphicsManager->suppressNextDraw();
+			g_nancy->_graphics->suppressNextDraw();
 			uint ret = ConfMan.getInt("sdlg_return", Common::ConfigManager::kTransientDomain);
 			ConfMan.removeKey("sdlg_return", Common::ConfigManager::kTransientDomain);
 			switch (ret) {
@@ -624,7 +624,7 @@ void LoadSaveMenu::stop() {
 uint16 LoadSaveMenu::writeToTextbox(uint textboxID, const Common::String &text, const Font *font) {
 	assert(font);
 
-	_textboxes[textboxID]->_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_textboxes[textboxID]->_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	Common::Point destPoint(_loadSaveData->_fontXOffset, _loadSaveData->_fontYOffset + _textboxes[textboxID]->_drawSurface.h - font->getFontHeight());
 	font->drawString(&_textboxes[textboxID]->_drawSurface, text, destPoint.x, destPoint.y, _textboxes[textboxID]->_drawSurface.w, 0);
 	_textboxes[textboxID]->setVisible(true);
diff --git a/engines/nancy/state/mainmenu.cpp b/engines/nancy/state/mainmenu.cpp
index a08fa7e6a2d..1e18c49347b 100644
--- a/engines/nancy/state/mainmenu.cpp
+++ b/engines/nancy/state/mainmenu.cpp
@@ -74,7 +74,7 @@ void MainMenu::registerGraphics() {
 		button->registerGraphics();
 	}
 
-	g_nancy->_graphicsManager->redrawAll();
+	g_nancy->_graphics->redrawAll();
 }
 
 void MainMenu::clearButtonState() {
@@ -90,7 +90,7 @@ void MainMenu::init() {
 	_background.init(_menuData->_imageName);
 	_background.registerGraphics();
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 	g_nancy->setMouseEnabled(true);
 
 	if (!g_nancy->_sound->isSoundPlaying("MSND")) {
@@ -163,7 +163,7 @@ void MainMenu::run() {
 		}
 	}
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 }
 
 void MainMenu::stop() {
@@ -212,7 +212,7 @@ void MainMenu::stop() {
 			} else {
 				// Dialog has returned
 				_destroyOnExit = true;
-				g_nancy->_graphicsManager->suppressNextDraw();
+				g_nancy->_graphics->suppressNextDraw();
 				uint ret = ConfMan.getInt("sdlg_return", Common::ConfigManager::kTransientDomain);
 				ConfMan.removeKey("sdlg_return", Common::ConfigManager::kTransientDomain);
 				switch (ret) {
diff --git a/engines/nancy/state/map.cpp b/engines/nancy/state/map.cpp
index aa8888189e1..ea58daa7f3d 100644
--- a/engines/nancy/state/map.cpp
+++ b/engines/nancy/state/map.cpp
@@ -93,7 +93,7 @@ bool Map::onStateExit(const NancyState::NancyState nextState) {
 			_viewport._decoder.pauseVideo(true);
 		}
 	} else {
-		g_nancy->_graphicsManager->clearObjects();
+		g_nancy->_graphics->clearObjects();
 		_viewport.unloadVideo();
 		_state = kLoad;
 	}
@@ -108,7 +108,7 @@ const SoundDescription &Map::getSound() {
 void Map::load() {
 	// Get a screenshot of the Scene state and set it as the background
 	// to allow the labels to clear when not hovered
-	const Graphics::ManagedSurface *screen = g_nancy->_graphicsManager->getScreen();
+	const Graphics::ManagedSurface *screen = g_nancy->_graphics->getScreen();
 	_background._drawSurface.create(screen->w, screen->h, screen->format);
 	_background._drawSurface.blitFrom(*screen);
 	_background.moveTo(_background._drawSurface.getBounds());
@@ -135,7 +135,7 @@ void Map::setLabel(int labelID) {
 		_closedLabel.setVisible(false);
 	} else {
 		_label.moveTo(_locationLabelDests[labelID]);
-		_label._drawSurface.create(g_nancy->_graphicsManager->_object0, _mapData->locations[labelID].labelSrc);
+		_label._drawSurface.create(g_nancy->_graphics->_object0, _mapData->locations[labelID].labelSrc);
 		_label.setVisible(true);
 		_label.setTransparent(true);
 
@@ -150,7 +150,7 @@ void Map::MapViewport::init() {
 	assert(viewportData);
 
 	moveTo(viewportData->screenPosition);
-	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphics->getInputPixelFormat());
 
 	RenderObject::init();
 }
@@ -197,7 +197,7 @@ void TVDMap::init() {
 	assert(bootSummary);
 
 	Common::Rect textboxScreenPosition = bootSummary->textboxScreenPosition;
-	_closedLabel._drawSurface.create(g_nancy->_graphicsManager->_object0, _mapData->closedLabelSrc);
+	_closedLabel._drawSurface.create(g_nancy->_graphics->_object0, _mapData->closedLabelSrc);
 
 	Common::Rect closedScreenRect;
 	closedScreenRect.left = textboxScreenPosition.left + ((textboxScreenPosition.width() - _mapData->closedLabelSrc.width()) / 2);
@@ -242,7 +242,7 @@ void TVDMap::load() {
 
 	_viewport.loadVideo(_mapData->mapNames[_mapID], _mapData->mapPaletteNames[_mapID]);
 
-	g_nancy->_cursorManager->setCursorItemID(-1);
+	g_nancy->_cursor->setCursorItemID(-1);
 
 	_viewport.setVisible(false);
 	_globe.setOpen(true);
@@ -278,7 +278,7 @@ void TVDMap::run() {
 	}
 
 	setLabel(-1);
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormal);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormal);
 
 	if (!_globe.isPlaying()) {
 		NancyInput input = g_nancy->_input->getInput();
@@ -290,7 +290,7 @@ void TVDMap::run() {
 				setLabel(i);
 
 				if (_activeLocations[i]){
-					g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+					g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
 
 					if (input.input & NancyInput::kLeftMouseButtonUp) {
 						_pickedLocationID = i;
@@ -317,7 +317,7 @@ void TVDMap::MapGlobe::init() {
 	_frameTime = _owner->_mapData->globeFrameTime;
 	_srcRects = _owner->_mapData->globeSrcs;
 
-	_gargoyleEyes._drawSurface.create(g_nancy->_graphicsManager->_object0, _owner->_mapData->globeGargoyleSrc);
+	_gargoyleEyes._drawSurface.create(g_nancy->_graphics->_object0, _owner->_mapData->globeGargoyleSrc);
 	_gargoyleEyes.moveTo(_owner->_mapData->globeGargoyleDest);
 	_gargoyleEyes.setTransparent(true);
 	_gargoyleEyes.setVisible(false);
@@ -343,7 +343,7 @@ void TVDMap::MapGlobe::onTrigger() {
 		_gargoyleEyes.setVisible(true);
 		_owner->_viewport.setVisible(true);
 		_owner->_viewport.playVideo();
-		g_nancy->_cursorManager->warpCursor(_owner->_mapData->cursorPosition);
+		g_nancy->_cursor->warpCursor(_owner->_mapData->cursorPosition);
 		g_nancy->setMouseEnabled(true);
 	} else {
 		_owner->_state = kExit;
@@ -362,7 +362,7 @@ void Nancy1Map::init() {
 	_label.init();
 
 	Common::Rect textboxScreenPosition = NancySceneState.getTextbox().getScreenPosition();
-	_closedLabel._drawSurface.create(g_nancy->_graphicsManager->_object0, _mapData->closedLabelSrc);
+	_closedLabel._drawSurface.create(g_nancy->_graphics->_object0, _mapData->closedLabelSrc);
 
 	Common::Rect closedScreenRect;
 	closedScreenRect.left = textboxScreenPosition.left + ((textboxScreenPosition.width() - _mapData->closedLabelSrc.width()) / 2);
@@ -382,7 +382,7 @@ void Nancy1Map::init() {
 		_locationLabelDests[i].top = _locationLabelDests[i].bottom - _mapData->locations[i].labelSrc.height() + 1;
 	}
 
-	_button = new UI::Button(9, g_nancy->_graphicsManager->_object0, _mapData->buttonSrc, _mapData->buttonDest);
+	_button = new UI::Button(9, g_nancy->_graphics->_object0, _mapData->buttonSrc, _mapData->buttonDest);
 	_button->init();
 	_button->setVisible(true);
 
@@ -405,8 +405,8 @@ void Nancy1Map::load() {
 	_viewport.loadVideo(_mapData->mapNames[_mapID]);
 
 	setLabel(-1);
-	g_nancy->_cursorManager->setCursorItemID(-1);
-	g_nancy->_cursorManager->warpCursor(_mapData->cursorPosition);
+	g_nancy->_cursor->setCursorItemID(-1);
+	g_nancy->_cursor->warpCursor(_mapData->cursorPosition);
 
 	if (!g_nancy->_sound->isSoundPlaying(getSound())) {
 		g_nancy->_sound->loadSound(getSound());
@@ -438,7 +438,7 @@ void Nancy1Map::run() {
 			setLabel(i);
 
 			if (_activeLocations[i]){
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					_pickedLocationID = i;
diff --git a/engines/nancy/state/savedialog.cpp b/engines/nancy/state/savedialog.cpp
index 75689116a91..bb9b41cb508 100644
--- a/engines/nancy/state/savedialog.cpp
+++ b/engines/nancy/state/savedialog.cpp
@@ -61,7 +61,7 @@ void SaveDialog::process() {
 		break;
 	}
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 }
 
 void SaveDialog::onStateEnter(const NancyState::NancyState prevState) {
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 0f4dd8847e6..1dec0d1af10 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -181,10 +181,10 @@ void Scene::onStateEnter(const NancyState::NancyState prevState) {
 
 		_actionManager.onPause(false);
 
-		g_nancy->_graphicsManager->redrawAll();
+		g_nancy->_graphics->redrawAll();
 
 		if (getHeldItem() != -1) {
-			g_nancy->_cursorManager->setCursorItemID(getHeldItem());
+			g_nancy->_cursor->setCursorItemID(getHeldItem());
 		}
 
 		if (prevState == NancyState::kPause) {
@@ -202,7 +202,7 @@ void Scene::onStateEnter(const NancyState::NancyState prevState) {
 bool Scene::onStateExit(const NancyState::NancyState nextState) {
 	if (_state == kRun) {
 		// Exiting the state outside the kRun state means we've encountered an error
-		g_nancy->_graphicsManager->screenshotScreen(_lastScreenshot);
+		g_nancy->_graphics->screenshotScreen(_lastScreenshot);
 	}
 
 	if (nextState != NancyState::kPause) {
@@ -354,7 +354,7 @@ void Scene::removeItemFromInventory(int16 id, bool pickUp) {
 }
 
 void Scene::setHeldItem(int16 id) {
-	_flags.heldItem = id; g_nancy->_cursorManager->setCursorItemID(id);
+	_flags.heldItem = id; g_nancy->_cursor->setCursorItemID(id);
 }
 
 void Scene::setNoHeldItem() {
@@ -662,7 +662,7 @@ void Scene::synchronize(Common::Serializer &ser) {
 
 	ser.syncArray(_flags.items.data(), g_nancy->getStaticData().numItems, Common::Serializer::Byte);
 	ser.syncAsSint16LE(_flags.heldItem);
-	g_nancy->_cursorManager->setCursorItemID(_flags.heldItem);
+	g_nancy->_cursor->setCursorItemID(_flags.heldItem);
 
 	if (g_nancy->getGameType() >= kGameTypeNancy7) {
 		ser.syncArray(_flags.disabledItems.data(), g_nancy->getStaticData().numItems, Common::Serializer::Byte);
@@ -751,7 +751,7 @@ void Scene::synchronize(Common::Serializer &ser) {
 	_isRunningAd = false;
 	ConfMan.removeKey("restore_after_ad", Common::ConfigManager::kTransientDomain);
 
-	g_nancy->_graphicsManager->suppressNextDraw();
+	g_nancy->_graphics->suppressNextDraw();
 }
 
 UI::Clock *Scene::getClock() {
@@ -823,12 +823,12 @@ void Scene::init() {
 	}
 
 	Common::Rect vpPos = _viewport.getScreenPosition();
-	_hotspotDebug._drawSurface.create(vpPos.width(), vpPos.height(), g_nancy->_graphicsManager->getScreenPixelFormat());
+	_hotspotDebug._drawSurface.create(vpPos.width(), vpPos.height(), g_nancy->_graphics->getScreenPixelFormat());
 	_hotspotDebug.moveTo(vpPos);
 	_hotspotDebug.setTransparent(true);
 
 	registerGraphics();
-	g_nancy->_graphicsManager->redrawAll();
+	g_nancy->_graphics->redrawAll();
 }
 
 void Scene::setActiveConversation(Action::ConversationSound *activeConversation) {
@@ -877,7 +877,7 @@ void Scene::load(bool fromSaveFile) {
 	}
 
 	clearSceneData();
-	g_nancy->_graphicsManager->suppressNextDraw();
+	g_nancy->_graphics->suppressNextDraw();
 
 	// Scene IDs are prefixed with S inside the cif tree; e.g 100 -> S100
 	Common::Path sceneName(Common::String::format("S%u", _sceneState.nextScene.sceneID));
@@ -1022,7 +1022,7 @@ void Scene::run() {
 		if (_specialEffects.front().isInitialized()) {
 			if (_specialEffects.front().isDone()) {
 				_specialEffects.pop();
-				g_nancy->_graphicsManager->redrawAll();
+				g_nancy->_graphics->redrawAll();
 			}
 		} else {
 			_specialEffects.front().afterSceneChange();
@@ -1032,7 +1032,7 @@ void Scene::run() {
 	g_nancy->_sound->soundEffectMaintenance();
 
 	if (_state == kLoad) {
-		g_nancy->_graphicsManager->suppressNextDraw();
+		g_nancy->_graphics->suppressNextDraw();
 	}
 }
 
@@ -1041,21 +1041,21 @@ void Scene::handleInput() {
 
 	// Warp the mouse below the inactive zone during dialogue scenes
 	if (_activeConversation != nullptr) {
-		const Common::Rect &inactiveZone = g_nancy->_cursorManager->getPrimaryVideoInactiveZone();
+		const Common::Rect &inactiveZone = g_nancy->_cursor->getPrimaryVideoInactiveZone();
 
 		if (g_nancy->getGameType() == kGameTypeVampire) {
-			const Common::Point cursorHotspot = g_nancy->_cursorManager->getCurrentCursorHotspot();
+			const Common::Point cursorHotspot = g_nancy->_cursor->getCurrentCursorHotspot();
 			Common::Point adjustedMousePos = input.mousePos;
 			adjustedMousePos.y -= cursorHotspot.y;
 
 			if (inactiveZone.bottom > adjustedMousePos.y) {
 				input.mousePos.y = inactiveZone.bottom + cursorHotspot.y;
-				g_nancy->_cursorManager->warpCursor(input.mousePos);
+				g_nancy->_cursor->warpCursor(input.mousePos);
 			}
 		} else {
 			if (inactiveZone.bottom > input.mousePos.y) {
 				input.mousePos.y = inactiveZone.bottom;
-				g_nancy->_cursorManager->warpCursor(input.mousePos);
+				g_nancy->_cursor->warpCursor(input.mousePos);
 			}
 		}
 	} else {
@@ -1076,7 +1076,7 @@ void Scene::handleInput() {
 	for (uint16 id : g_nancy->getStaticData().mapAccessSceneIDs) {
 		if ((int)_sceneState.currentScene.sceneID == id) {
 			if (_mapHotspot.contains(input.mousePos)) {
-				g_nancy->_cursorManager->setCursorType(g_nancy->getGameType() == kGameTypeVampire ? CursorManager::kHotspot : CursorManager::kHotspotArrow);
+				g_nancy->_cursor->setCursorType(g_nancy->getGameType() == kGameTypeVampire ? CursorManager::kHotspot : CursorManager::kHotspotArrow);
 
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					requestStateChange(NancyState::kMap);
@@ -1167,8 +1167,8 @@ void Scene::initStaticData() {
 		_mapHotspot = mapData->buttonDest;
 	}
 
-	_menuButton = new UI::Button(5, g_nancy->_graphicsManager->_object0, bootSummary->menuButtonSrc, bootSummary->menuButtonDest, bootSummary->menuButtonHighlightSrc);
-	_helpButton = new UI::Button(5, g_nancy->_graphicsManager->_object0, bootSummary->helpButtonSrc, bootSummary->helpButtonDest, bootSummary->helpButtonHighlightSrc);
+	_menuButton = new UI::Button(5, g_nancy->_graphics->_object0, bootSummary->menuButtonSrc, bootSummary->menuButtonDest, bootSummary->menuButtonHighlightSrc);
+	_helpButton = new UI::Button(5, g_nancy->_graphics->_object0, bootSummary->helpButtonSrc, bootSummary->helpButtonDest, bootSummary->helpButtonHighlightSrc);
 	g_nancy->setMouseEnabled(true);
 
 	// Init ornaments and clock (TVD only)
diff --git a/engines/nancy/state/setupmenu.cpp b/engines/nancy/state/setupmenu.cpp
index c5adcfe0360..af2139800f5 100644
--- a/engines/nancy/state/setupmenu.cpp
+++ b/engines/nancy/state/setupmenu.cpp
@@ -141,7 +141,7 @@ void SetupMenu::init() {
 
 	_background.registerGraphics();
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 	g_nancy->setMouseEnabled(true);
 
 	g_nancy->_sound->stopSound("MSND");
@@ -242,7 +242,7 @@ void SetupMenu::run() {
 		}
 	}
 
-	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
+	g_nancy->_cursor->setCursorType(CursorManager::kNormalArrow);
 }
 
 void SetupMenu::stop() {
diff --git a/engines/nancy/ui/animatedbutton.cpp b/engines/nancy/ui/animatedbutton.cpp
index 2b395e14b96..c69c974e269 100644
--- a/engines/nancy/ui/animatedbutton.cpp
+++ b/engines/nancy/ui/animatedbutton.cpp
@@ -69,7 +69,7 @@ void AnimatedButton::updateGraphics() {
 void AnimatedButton::handleInput(NancyInput &input) {
 	if (_hotspot.contains(input.mousePos)) {
 		if (_alwaysHighlightCursor || _currentFrame == -1 || _currentFrame == (int)_srcRects.size()) {
-			g_nancy->_cursorManager->setCursorType(g_nancy->getGameType() == kGameTypeVampire ? CursorManager::kHotspot : CursorManager::kHotspotArrow);
+			g_nancy->_cursor->setCursorType(g_nancy->getGameType() == kGameTypeVampire ? CursorManager::kHotspot : CursorManager::kHotspotArrow);
 		}
 
 		if (isPlaying()) {
@@ -77,7 +77,7 @@ void AnimatedButton::handleInput(NancyInput &input) {
 		}
 
 		if (!_highlightSrcRect.isEmpty() && !isVisible()) {
-			_drawSurface.create(g_nancy->_graphicsManager->_object0, _highlightSrcRect);
+			_drawSurface.create(g_nancy->_graphics->_object0, _highlightSrcRect);
 			moveTo(_highlightDestRect);
 			setVisible(true);
 		}
@@ -103,7 +103,7 @@ void AnimatedButton::handleInput(NancyInput &input) {
 
 void AnimatedButton::setFrame(int frame) {
 	if (frame > -1 && frame < (int)_srcRects.size()) {
-		_drawSurface.create(g_nancy->_graphicsManager->_object0, _srcRects[frame]);
+		_drawSurface.create(g_nancy->_graphics->_object0, _srcRects[frame]);
 		setTransparent(true);
 
 		if (_destRects.size()) {
diff --git a/engines/nancy/ui/button.cpp b/engines/nancy/ui/button.cpp
index 98811c9826b..4d5ae291d5e 100644
--- a/engines/nancy/ui/button.cpp
+++ b/engines/nancy/ui/button.cpp
@@ -51,7 +51,7 @@ void Button::handleInput(NancyInput &input) {
 	}
 	
 	if (_screenPosition.contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 
 		if (!_hoverSrc.isEmpty() && !_isClicked) {
 			_drawSurface.create(surf, _hoverSrc);
@@ -100,7 +100,7 @@ void Toggle::handleInput(NancyInput &input) {
 	_stateChanged = false;
 
 	if (_screenPosition.contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 
 		if (input.input & NancyInput::kLeftMouseButtonUp) {
 			setState(!_toggleState);
diff --git a/engines/nancy/ui/clock.cpp b/engines/nancy/ui/clock.cpp
index f4c6fc4b72e..b1cc21eb955 100644
--- a/engines/nancy/ui/clock.cpp
+++ b/engines/nancy/ui/clock.cpp
@@ -41,7 +41,7 @@ Clock::Clock() : 	RenderObject(g_nancy->getGameType() == kGameTypeVampire ? 11 :
 					_locked(false) {}
 
 void Clock::init() {
-	Graphics::ManagedSurface &object0 = g_nancy->_graphicsManager->_object0;
+	Graphics::ManagedSurface &object0 = g_nancy->_graphics->_object0;
 
 	_clockData = (const CLOK *)g_nancy->getEngineData("CLOK");
 	assert(_clockData);
@@ -58,7 +58,7 @@ void Clock::init() {
 		clockSurfaceScreenBounds.extend(r);
 	}
 
-	_drawSurface.create(clockSurfaceScreenBounds.width(), clockSurfaceScreenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(clockSurfaceScreenBounds.width(), clockSurfaceScreenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
 	moveTo(clockSurfaceScreenBounds);
 
 	_staticImage._drawSurface.create(object0, _clockData->staticImageSrc);
@@ -106,7 +106,7 @@ void Clock::handleInput(NancyInput &input) {
 }
 
 void Clock::drawClockHands() {
-	Graphics::ManagedSurface &object0 = g_nancy->_graphicsManager->_object0;
+	Graphics::ManagedSurface &object0 = g_nancy->_graphics->_object0;
 	uint hours = _playerTime.getHours();
 	if (hours >= 12) {
 		hours -= 12;
@@ -119,7 +119,7 @@ void Clock::drawClockHands() {
 	hoursDest.translate(-_screenPosition.left, -_screenPosition.top);
 	minutesDest.translate(-_screenPosition.left, -_screenPosition.top);
 
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	_drawSurface.blitFrom(object0, _clockData->hoursHandSrcs[hours], hoursDest);
 	_drawSurface.blitFrom(object0, _clockData->minutesHandSrcs[minutesHand], minutesDest);
 }
@@ -198,19 +198,19 @@ void Nancy5Clock::updateGraphics() {
 	if (_currentDay < 3) {
 		if (NancySceneState.getEventFlag(59, true) && _currentDay == 1) {
 			_currentDay = 2;
-			_drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->daySrcs[2]);
+			_drawSurface.create(g_nancy->_graphics->_object0, _clockData->daySrcs[2]);
 			moveTo(_clockData->staticImageDest);
 			setVisible(true);
 			setTransparent(true);
 		} else if (NancySceneState.getEventFlag(58, true) && _currentDay == 0) {
 			_currentDay = 1;
-			_drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->daySrcs[1]);
+			_drawSurface.create(g_nancy->_graphics->_object0, _clockData->daySrcs[1]);
 			moveTo(_clockData->staticImageDest);
 			setVisible(true);
 			setTransparent(true);
 		} else if (NancySceneState.getEventFlag(57, true) && _currentDay == -1) {
 			_currentDay = 0;
-			_drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->daySrcs[0]);
+			_drawSurface.create(g_nancy->_graphics->_object0, _clockData->daySrcs[0]);
 			moveTo(_clockData->staticImageDest);
 			setVisible(true);
 			setTransparent(true);
@@ -225,7 +225,7 @@ void Nancy5Clock::updateGraphics() {
 		if (countdownFrameID != _countdownProgress) {
 			_countdownProgress = countdownFrameID;
 
-			_drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->countdownSrcs[_countdownProgress]);
+			_drawSurface.create(g_nancy->_graphics->_object0, _clockData->countdownSrcs[_countdownProgress]);
 			moveTo(_clockData->staticImageDest);
 			setVisible(true);
 		}
diff --git a/engines/nancy/ui/inventorybox.cpp b/engines/nancy/ui/inventorybox.cpp
index c12b86b1f52..1ef5e823164 100644
--- a/engines/nancy/ui/inventorybox.cpp
+++ b/engines/nancy/ui/inventorybox.cpp
@@ -60,7 +60,7 @@ void InventoryBox::init() {
 	moveTo(bootSummary->inventoryBoxScreenPosition);
 	g_nancy->_resource->loadImage(_inventoryData->inventoryBoxIconsImageName, _iconsSurface);
 
-	_fullInventorySurface.create(_screenPosition.width(), _screenPosition.height() * ((g_nancy->getStaticData().numItems / 4) + 1), g_nancy->_graphicsManager->getScreenPixelFormat());
+	_fullInventorySurface.create(_screenPosition.width(), _screenPosition.height() * ((g_nancy->getStaticData().numItems / 4) + 1), g_nancy->_graphics->getScreenPixelFormat());
 	Common::Rect sourceRect = _screenPosition;
 	sourceRect.moveTo(0, 0);
 	_drawSurface.create(_fullInventorySurface, sourceRect);
@@ -112,13 +112,13 @@ void InventoryBox::handleInput(NancyInput &input) {
 	for (uint i = 0; i < 4; ++i) {
 		if (_itemHotspots[i].hotspot.contains(input.mousePos)) {
 			if (NancySceneState.getHeldItem() != -1) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 				if (input.input & NancyInput::kLeftMouseButtonUp) {
 					NancySceneState.addItemToInventory(NancySceneState.getHeldItem());
 					g_nancy->_sound->playSound("BULS");
 				}
 			} else if (_itemHotspots[i].itemID != -1) {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+				g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 
 				hoveredHotspot = i;
 
@@ -264,11 +264,11 @@ void InventoryBox::Curtains::init() {
 	moveTo(inventoryData->curtainsScreenPosition);
 	Common::Rect bounds = _screenPosition;
 	bounds.moveTo(0, 0);
-	_drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphics->getInputPixelFormat());
 
 	if (g_nancy->getGameType() == kGameTypeVampire) {
 		uint8 palette[256 * 3];
-		g_nancy->_graphicsManager->_object0.grabPalette(palette, 0, 256);
+		g_nancy->_graphics->_object0.grabPalette(palette, 0, 256);
 		_drawSurface.setPalette(palette, 0, 256);
 	}
 
@@ -316,7 +316,7 @@ void InventoryBox::Curtains::updateGraphics() {
 }
 
 void InventoryBox::Curtains::setAnimationFrame(uint frame) {
-	Graphics::ManagedSurface &_object0 = g_nancy->_graphicsManager->_object0;
+	Graphics::ManagedSurface &_object0 = g_nancy->_graphics->_object0;
 	Common::Rect srcRect;
 	Common::Point destPoint;
 
@@ -334,7 +334,7 @@ void InventoryBox::Curtains::setAnimationFrame(uint frame) {
 	auto *inventoryData = GetEngineData(INV);
 	assert(inventoryData);
 
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 
 	// Draw left curtain
 	srcRect = inventoryData->curtainAnimationSrcs[frame * 2];
diff --git a/engines/nancy/ui/ornaments.cpp b/engines/nancy/ui/ornaments.cpp
index 6691114fd0f..691124a0285 100644
--- a/engines/nancy/ui/ornaments.cpp
+++ b/engines/nancy/ui/ornaments.cpp
@@ -35,9 +35,9 @@ void ViewportOrnaments::init() {
 	Common::Rect viewportBounds = viewportData->bounds;
 	moveTo(viewportData->screenPosition);
 
-	Graphics::ManagedSurface &object0 = g_nancy->_graphicsManager->_object0;
+	Graphics::ManagedSurface &object0 = g_nancy->_graphics->_object0;
 
-	_drawSurface.create(viewportBounds.width(), viewportBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(viewportBounds.width(), viewportBounds.height(), g_nancy->_graphics->getInputPixelFormat());
 
 	uint8 palette[256 * 3];
 	object0.grabPalette(palette, 0, 256);
@@ -53,7 +53,7 @@ void ViewportOrnaments::init() {
 		{ 33, 39, 40, 59 }
 	};
 
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 
 	// Top left
@@ -83,15 +83,15 @@ void TextboxOrnaments::init() {
 	Common::Rect textboxBounds = _screenPosition;
 	textboxBounds.moveTo(0, 0);
 
-	Graphics::ManagedSurface &object0 = g_nancy->_graphicsManager->_object0;
+	Graphics::ManagedSurface &object0 = g_nancy->_graphics->_object0;
 
-	_drawSurface.create(textboxBounds.width(), textboxBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(textboxBounds.width(), textboxBounds.height(), g_nancy->_graphics->getInputPixelFormat());
 
 	uint8 palette[256 * 3];
 	object0.grabPalette(palette, 0, 256);
 	_drawSurface.setPalette(palette, 0, 256);
 
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 
 	for (uint i = 0; i < 14; ++i) {
@@ -114,15 +114,15 @@ void InventoryBoxOrnaments::init() {
 	Common::Rect invBoxBounds = _screenPosition;
 	invBoxBounds.moveTo(0, 0);
 
-	Graphics::ManagedSurface &object0 = g_nancy->_graphicsManager->_object0;
+	Graphics::ManagedSurface &object0 = g_nancy->_graphics->_object0;
 
-	_drawSurface.create(invBoxBounds.width(), invBoxBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.create(invBoxBounds.width(), invBoxBounds.height(), g_nancy->_graphics->getInputPixelFormat());
 
 	uint8 palette[256 * 3];
 	object0.grabPalette(palette, 0, 256);
 	_drawSurface.setPalette(palette, 0, 256);
 
-	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	_drawSurface.clear(g_nancy->_graphics->getTransColor());
 	setTransparent(true);
 
 	for (uint i = 0; i < 6; ++i) {
diff --git a/engines/nancy/ui/scrollbar.cpp b/engines/nancy/ui/scrollbar.cpp
index 3b28febebcb..c59b45a7d6c 100644
--- a/engines/nancy/ui/scrollbar.cpp
+++ b/engines/nancy/ui/scrollbar.cpp
@@ -30,7 +30,7 @@ namespace Nancy {
 namespace UI {
 
 Scrollbar::Scrollbar(uint16 zOrder, const Common::Rect &srcBounds, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical) :
-	Scrollbar(zOrder, srcBounds, g_nancy->_graphicsManager->_object0, topPosition, scrollDistance, isVertical) {}
+	Scrollbar(zOrder, srcBounds, g_nancy->_graphics->_object0, topPosition, scrollDistance, isVertical) {}
 
 Scrollbar::Scrollbar(uint16 zOrder, const Common::Rect &srcBounds, Graphics::ManagedSurface &srcSurf, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical) :
 		RenderObject(zOrder),
@@ -61,7 +61,7 @@ void Scrollbar::handleInput(NancyInput &input) {
 	// the hotspot (happens if we remove the _isClicked check below). This doesn't make
 	// for great UX, however, so it has been fixed.
 	if (_screenPosition.contains(input.mousePos) || _isClicked) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+		g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 
 		if (input.input & NancyInput::kLeftMouseButtonDown && !_isClicked) {
 			// Begin click and hold
diff --git a/engines/nancy/ui/textbox.cpp b/engines/nancy/ui/textbox.cpp
index 092214b8de4..80e2a051440 100644
--- a/engines/nancy/ui/textbox.cpp
+++ b/engines/nancy/ui/textbox.cpp
@@ -56,7 +56,7 @@ void Textbox::init() {
 
 	moveTo(bsum->textboxScreenPosition);
 	_highlightRObj.moveTo(bsum->textboxScreenPosition);
-	initSurfaces(tbox->innerBoundingBox.width(), tbox->innerBoundingBox.height(), g_nancy->_graphicsManager->getScreenPixelFormat(),
+	initSurfaces(tbox->innerBoundingBox.width(), tbox->innerBoundingBox.height(), g_nancy->_graphics->getScreenPixelFormat(),
 		tbox->textBackground, tbox->highlightTextBackground);
 
 	Common::Rect outerBoundingBox = _screenPosition;
@@ -107,7 +107,7 @@ void Textbox::handleInput(NancyInput &input) {
 		hotspot.translate(0, -_drawSurface.getOffsetFromOwner().y);
 		Common::Rect hotspotOnScreen = convertToScreen(hotspot).findIntersectingRect(_screenPosition);
 		if (hotspotOnScreen.contains(input.mousePos)) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
+			g_nancy->_cursor->setCursorType(CursorManager::kHotspotArrow);
 
 			// Highlight the selected response
 			if (g_nancy->getGameType() >= kGameTypeNancy2) {
@@ -144,7 +144,7 @@ void Textbox::drawTextbox() {
 	textBounds.left += tbox->leftOffset;
 	textBounds.right -= tbox->rightOffset;
 
-	const Font *font = g_nancy->_graphicsManager->getFont(_fontIDOverride != -1 ? _fontIDOverride : tbox->defaultFontID);
+	const Font *font = g_nancy->_graphics->getFont(_fontIDOverride != -1 ? _fontIDOverride : tbox->defaultFontID);
 	textBounds.top -= font->getFontHeight();
 
 	HypertextParser::drawAllText(	textBounds,	0,													// bounds of text within full surface
diff --git a/engines/nancy/ui/viewport.cpp b/engines/nancy/ui/viewport.cpp
index 573ccae5e84..b7199aaade0 100644
--- a/engines/nancy/ui/viewport.cpp
+++ b/engines/nancy/ui/viewport.cpp
@@ -70,21 +70,21 @@ void Viewport::handleInput(NancyInput &input) {
 	if (	g_nancy->getGameType() != kGameTypeVampire &&
 			input.input & (NancyInput::kLeftMouseButton | NancyInput::kRightMouseButton)
 			&& _stickyCursorPos.x > -1) {
-		g_nancy->_cursorManager->warpCursor(_stickyCursorPos);
+		g_nancy->_cursor->warpCursor(_stickyCursorPos);
 		input.mousePos = _stickyCursorPos;
 	}
 
 	Common::Rect viewportActiveZone;
 
 	if (g_nancy->getGameType() == kGameTypeVampire) {
-		viewportActiveZone = g_nancy->_graphicsManager->getScreen()->getBounds();
+		viewportActiveZone = g_nancy->_graphics->getScreen()->getBounds();
 		viewportActiveZone.bottom = _screenPosition.bottom;
 	} else {
 		viewportActiveZone = _screenPosition;
 	}
 
 	if (viewportActiveZone.contains(input.mousePos)) {
-		g_nancy->_cursorManager->setCursorType(CursorManager::kNormal);
+		g_nancy->_cursor->setCursorType(CursorManager::kNormal);
 
 		if (input.mousePos.x < _nonScrollZone.left) {
 			direction |= kLeft;
@@ -133,21 +133,21 @@ void Viewport::handleInput(NancyInput &input) {
 		if (direction & kLeft) {
 			if (summary.fastMoveTimeDelta == kInvertedNode) {
 				// Support nancy6+ inverted rotation scenes
-				g_nancy->_cursorManager->setCursorType(CursorManager::kInvertedRotateLeft);
+				g_nancy->_cursor->setCursorType(CursorManager::kInvertedRotateLeft);
 			} else {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kRotateLeft);
+				g_nancy->_cursor->setCursorType(CursorManager::kRotateLeft);
 			}
 		} else if (direction & kRight) {
 			if (summary.fastMoveTimeDelta == kInvertedNode) {
 				// Support nancy6+ inverted rotation scenes
-				g_nancy->_cursorManager->setCursorType(CursorManager::kInvertedRotateRight);
+				g_nancy->_cursor->setCursorType(CursorManager::kInvertedRotateRight);
 			} else {
-				g_nancy->_cursorManager->setCursorType(CursorManager::kRotateRight);
+				g_nancy->_cursor->setCursorType(CursorManager::kRotateRight);
 			}
 		} else if (direction & kUp) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kMoveUp);
+			g_nancy->_cursor->setCursorType(CursorManager::kMoveUp);
 		} else if (direction & kDown) {
-			g_nancy->_cursorManager->setCursorType(CursorManager::kMoveDown);
+			g_nancy->_cursor->setCursorType(CursorManager::kMoveDown);
 		}
 
 		if (input.input & NancyInput::kRightMouseButton) {
diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index 6f55f7706f2..ed420e87b9f 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -152,7 +152,7 @@ AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uin
 	if (comp != 1 && comp != 2)
 		error("Unknown compression type %d found in AVF", comp);
 
-	_pixelFormat = g_nancy->_graphicsManager->getInputPixelFormat();
+	_pixelFormat = g_nancy->_graphics->getInputPixelFormat();
 	_frameSize = _width * _height * _pixelFormat.bytesPerPixel;
 
 	_chunkInfo.reserve(_frameCount);
@@ -349,7 +349,7 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 #ifdef SCUMM_BIG_ENDIAN
 				// Convert from BE back to LE so the decode step below works correctly
 				byte *buf = (byte *)frameInCache.getPixels();
-				if (g_nancy->_graphicsManager->getInputPixelFormat().bytesPerPixel == 2) {
+				if (g_nancy->_graphics->getInputPixelFormat().bytesPerPixel == 2) {
 					for (int i = 0; i < frameInCache.pitch * frameInCache.h / 2; ++i) {
 						((uint16 *)buf)[i] = SWAP_BYTES_16(((uint16 *)buf)[i]);
 					}
@@ -368,7 +368,7 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 
 #ifdef SCUMM_BIG_ENDIAN
 	byte *buf = (byte *)frameInCache.getPixels();
-	if (g_nancy->_graphicsManager->getInputPixelFormat().bytesPerPixel == 2) {
+	if (g_nancy->_graphics->getInputPixelFormat().bytesPerPixel == 2) {
 		for (int i = 0; i < frameInCache.pitch * frameInCache.h / 2; ++i) {
 			((uint16 *)buf)[i] = SWAP_BYTES_16(((uint16 *)buf)[i]);
 		}


Commit: ad21d8b566481e76e5d5c966df289bf308f2f4de
    https://github.com/scummvm/scummvm/commit/ad21d8b566481e76e5d5c966df289bf308f2f4de
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Fix ResourceManager memory leak

The ResourceManager was never getting deleted on
engine exit. Also, it is now instantiated in the engine
constructor, just like the other managers.

Changed paths:
    engines/nancy/nancy.cpp
    engines/nancy/resource.h


diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index f6631d7cd62..ae86b248333 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -71,8 +71,7 @@ NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
 	_sound = new SoundManager();
 	_graphics = new GraphicsManager();
 	_cursor = new CursorManager();
-
-	_resource = nullptr;
+	_resource = new ResourceManager();
 
 	_hasJustSaved = false;
 }
@@ -94,6 +93,7 @@ NancyEngine::~NancyEngine() {
 	delete _cursor;
 	delete _input;
 	delete _sound;
+	delete _resource;
 
 	for (auto &data : _engineData) {
 		delete data._value;
@@ -398,7 +398,6 @@ void NancyEngine::bootGameEngine() {
 		}
 	}
 
-	_resource = new ResourceManager();
 	_resource->readCifTree("ciftree", "dat", 1);
 	_resource->readCifTree("promotree", "dat", 1);
 
diff --git a/engines/nancy/resource.h b/engines/nancy/resource.h
index 515f92dd593..d5c242ad39b 100644
--- a/engines/nancy/resource.h
+++ b/engines/nancy/resource.h
@@ -37,8 +37,8 @@ class ResourceManager {
 	friend class NancyConsole;
 	friend class NancyEngine;
 public:
-	ResourceManager() {}
-	~ResourceManager();
+	ResourceManager() = default;
+	~ResourceManager() = default;
 
 	// Load an image resource. Can be either external .bmp file, or raw image data embedded inside a ciftree
 	// Ciftree images may have additional data dictating how they need to be blitted on screen (see ConversationCel).


Commit: 0c2e54416e296e1788dbfb1a000567b5e36182a1
    https://github.com/scummvm/scummvm/commit/0c2e54416e296e1788dbfb1a000567b5e36182a1
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Update engine status comment

Changed paths:
    engines/nancy/nancy.h


diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index c18166a484c..7f21c5c5406 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -42,8 +42,9 @@ class Serializer;
  * This is the namespace of the Nancy engine.
  *
  * Status of this engine:
- * The Vampire Diaries and Nancy Drew: Secrets can Kill are completable.
- * Every other game is untested but definitely unplayable
+ * The Vampire Diaries and all Nancy Drew games up to and including
+ * Nancy Drew: Ghost Dogs of Moon Lake are fully completable.
+ * Every other game is untested but definitely unplayable.
  *
  * Games using this engine:
  *	- The Vampire Diaries (1996)


Commit: 3d9a61f904d9e5a30f4f98edcea0a9ef3973e972
    https://github.com/scummvm/scummvm/commit/3d9a61f904d9e5a30f4f98edcea0a9ef3973e972
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Fix memory leak in Conversation

Changed paths:
    engines/nancy/action/conversation.cpp


diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index c9c64493c56..3bb4c98f4f4 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -856,6 +856,8 @@ void ConversationCel::readXSheet(Common::SeekableReadStream &stream, const Commo
 		// 4 unknown values
 		xsheet->skip(8);
 	}
+
+	delete xsheet;
 }
 
 bool ConversationCel::isVideoDonePlaying() {


Commit: 758db1bfb1d983535d8fba00f5dd100967c13c0c
    https://github.com/scummvm/scummvm/commit/758db1bfb1d983535d8fba00f5dd100967c13c0c
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Fix memory leak when reading .dat file

Changed paths:
    engines/nancy/nancy.cpp


diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index ae86b248333..0cf73434626 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -635,6 +635,8 @@ void NancyEngine::readDatFile() {
 	datFile->seek(thisGameOffset);
 
 	_staticData.readData(*datFile, _gameDescription->desc.language, nextGameOffset, major, minor);
+
+	delete datFile;
 }
 
 Common::Error NancyEngine::synchronize(Common::Serializer &ser) {


Commit: 01eefffad6623036f01d87ec67afc03b9011029a
    https://github.com/scummvm/scummvm/commit/01eefffad6623036f01d87ec67afc03b9011029a
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Fix memory leak in ResourceManager

Changed paths:
    engines/nancy/resource.cpp


diff --git a/engines/nancy/resource.cpp b/engines/nancy/resource.cpp
index d80eb838694..c549e0cd3aa 100644
--- a/engines/nancy/resource.cpp
+++ b/engines/nancy/resource.cpp
@@ -171,6 +171,7 @@ bool ResourceManager::loadImage(const Common::Path &name, Graphics::ManagedSurfa
 
 	GraphicsManager::copyToManaged(buf, surf, info.width, info.height, g_nancy->_graphics->getInputPixelFormat());
 	delete[] buf;
+	delete stream;
 	return true;
 }
 


Commit: 5695018cd3bbdfdcd695ed3d65770cba38fd33ad
    https://github.com/scummvm/scummvm/commit/5695018cd3bbdfdcd695ed3d65770cba38fd33ad
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Implement InteractiveVideo

Implemented an action record type that adds hotspots
on top of a SecondaryMovie.

Changed paths:
  A engines/nancy/action/interactivevideo.cpp
  A engines/nancy/action/interactivevideo.h
    engines/nancy/action/arfactory.cpp
    engines/nancy/action/secondarymovie.cpp
    engines/nancy/action/secondarymovie.h
    engines/nancy/module.mk
    engines/nancy/state/scene.cpp
    engines/nancy/state/scene.h


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index aad9a948fba..6be4f83cd8f 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -27,6 +27,7 @@
 
 #include "engines/nancy/action/autotext.h"
 #include "engines/nancy/action/conversation.h"
+#include "engines/nancy/action/interactivevideo.h"
 #include "engines/nancy/action/overlay.h"
 #include "engines/nancy/action/secondaryvideo.h"
 #include "engines/nancy/action/secondarymovie.h"
@@ -119,6 +120,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 		newRec->_isTerse = true;
 		return newRec;
 	}
+	case 26:
+		return new InteractiveVideo();
 	case 40:
 		if (g_nancy->getGameType() < kGameTypeNancy2) {
 			// Only used in TVD
diff --git a/engines/nancy/action/interactivevideo.cpp b/engines/nancy/action/interactivevideo.cpp
new file mode 100644
index 00000000000..2bbf50d8ff1
--- /dev/null
+++ b/engines/nancy/action/interactivevideo.cpp
@@ -0,0 +1,148 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "engines/nancy/nancy.h"
+#include "engines/nancy/util.h"
+#include "engines/nancy/resource.h"
+#include "engines/nancy/video.h"
+#include "engines/nancy/input.h"
+
+#include "engines/nancy/action/interactivevideo.h"
+#include "engines/nancy/action/secondarymovie.h"
+#include "engines/nancy/state/scene.h"
+
+namespace Nancy {
+namespace Action {
+
+void InteractiveVideo::readData(Common::SeekableReadStream &stream) {
+	Common::Path ivFilename;
+	readFilename(stream, ivFilename);
+
+	stream.skip(2);
+
+	_flags.resize(15);
+	_cursors.resize(5);
+
+	for (uint i = 0; i < 15; ++i) {
+		_flags[i].label = stream.readSint16LE();
+		_flags[i].flag = stream.readSint16LE();
+	}
+
+	for (uint i = 0; i < 5; ++ i) {
+		_cursors[i] = stream.readSint16LE();
+	}
+
+	Common::SeekableReadStream *ivFile = SearchMan.createReadStreamForMember(ivFilename.append(".iv"));
+	assert(ivFile);
+
+	readFilename(*ivFile, _videoName);
+
+	uint32 numFrames = ivFile->readUint32LE();
+	_frames.resize(numFrames);
+	for (uint i = 0; i < numFrames; ++i) {
+		InteractiveFrame &frame = _frames[i];
+		frame.frameID = ivFile->readUint16LE();
+		uint16 numHotspots = ivFile->readUint16LE();
+		frame.triggerOnNoHotspot = ivFile->readByte();
+		frame.noHSFlagID = ivFile->readSint16LE();
+		frame.noHSCursorID = ivFile->readSint16LE();
+		
+		frame.hotspots.resize(numHotspots);
+		for (uint j = 0; j < numHotspots; ++j) {
+			ivFile->skip(4);
+			readRect(*ivFile, frame.hotspots[j].hotspot);
+			frame.hotspots[j].flagID = ivFile->readSint16LE();
+			frame.hotspots[j].cursorID = ivFile->readSint16LE();
+		}
+	}
+
+	delete ivFile;
+}
+
+void InteractiveVideo::execute() {
+	switch (_state) {
+	case kBegin:
+		_movieAR = NancySceneState.getActiveMovie();
+		if (!_movieAR || _movieAR->_state == kRun) {
+			_state = kRun;
+		}
+
+		break;
+	case kRun:
+		if (_movieAR->_state == kActionTrigger || _movieAR->_isFinished) {
+			_state = kActionTrigger;
+		}
+
+		break;
+	case kActionTrigger:
+		finishExecution();
+		break;
+	}
+}
+
+void InteractiveVideo::handleInput(NancyInput &input) {
+	if (_state != kRun) {
+		return;
+	}
+
+	int curFrame = _movieAR->_decoder->getCurFrame();
+	if (curFrame < 0) {
+		return;
+	}
+
+	for (auto &frame : _frames) {
+		if (frame.frameID == curFrame) {
+			// Found data for the current video frame
+
+			// First, look through the hotspots for the frame
+			for (auto &hotspot : frame.hotspots) {
+				if (NancySceneState.getViewport().convertViewportToScreen(hotspot.hotspot).contains(input.mousePos)) {
+					// Mouse is in a hotspot, change cursor and set flag if clicked
+					if (hotspot.cursorID >= 0 && _cursors[hotspot.cursorID] >= 0) {
+						g_nancy->_cursor->setCursorType((CursorManager::CursorType)_cursors[hotspot.cursorID]);
+					}
+
+					if (input.input & NancyInput::kLeftMouseButtonUp) {
+						NancySceneState.setEventFlag(_flags[hotspot.flagID]);
+					}
+
+					return;
+				}
+			}
+
+			// Mouse is not in a hotspot for the frame, check if we have a default action
+			if (frame.triggerOnNoHotspot) {
+				if (frame.noHSCursorID >= 0 && _cursors[frame.noHSCursorID] >= 0) {
+					g_nancy->_cursor->setCursorType((CursorManager::CursorType)_cursors[frame.noHSCursorID]);
+				}
+
+				if (input.input & NancyInput::kLeftMouseButtonUp) {
+					NancySceneState.setEventFlag(_flags[frame.noHSFlagID]);
+				}
+			}
+
+			return;
+		}
+	}
+}
+
+} // End of namespace Action
+} // End of namespace Nancy
diff --git a/engines/nancy/action/interactivevideo.h b/engines/nancy/action/interactivevideo.h
new file mode 100644
index 00000000000..774c6c43d25
--- /dev/null
+++ b/engines/nancy/action/interactivevideo.h
@@ -0,0 +1,76 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef NANCY_ACTION_INTERACTIVEVIDEO_H
+#define NANCY_ACTION_INTERACTIVEVIDEO_H
+
+#include "engines/nancy/action/actionrecord.h"
+
+namespace Nancy {
+namespace Action {
+
+class ActionManager;
+class PlaySecondaryMovie;
+
+class InteractiveVideo : public ActionRecord {
+	friend class ActionManager;
+	friend class PlaySecondaryMovie;
+public:
+	InteractiveVideo() {}
+	virtual ~InteractiveVideo() {}
+
+	void readData(Common::SeekableReadStream &stream) override;
+	void execute() override;
+
+	void handleInput(NancyInput &input) override;
+
+protected:
+	Common::String getRecordTypeName() const override { return "InteractiveVideo"; }
+
+	struct InteractiveHotspot {
+		Common::Rect hotspot;
+		int16 flagID = -1;
+		int16 cursorID = -1;
+	};
+
+	struct InteractiveFrame {
+		uint16 frameID = 0;
+		bool triggerOnNoHotspot = false;
+		int16 noHSFlagID = -1;
+		int16 noHSCursorID = -1;
+		Common::Array<InteractiveHotspot> hotspots;
+	};
+
+	Common::Array<FlagDescription> _flags;
+	Common::Array<int16> _cursors;
+
+	// IV file data
+	Common::Path _videoName;
+	Common::Array<InteractiveFrame> _frames;
+
+	// Pointer to a movie AR
+	PlaySecondaryMovie *_movieAR = nullptr;
+};
+
+} // End of namespace Action
+} // End of namespace Nancy
+
+#endif // NANCY_ACTION_INTERACTIVEVIDEO_H
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 81cb115eb2e..90a1c43bfc2 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -38,6 +38,10 @@ namespace Action {
 PlaySecondaryMovie::~PlaySecondaryMovie() {
 	delete _decoder;
 
+	if (NancySceneState.getActiveMovie() == this) {
+		NancySceneState.setActiveMovie(nullptr);
+	}
+
 	if (_playerCursorAllowed == kNoPlayerCursorAllowed) {
 		g_nancy->setMouseEnabled(true);
 	}
@@ -148,6 +152,8 @@ void PlaySecondaryMovie::execute() {
 			g_nancy->setMouseEnabled(false);
 		}
 
+		NancySceneState.setActiveMovie(this);
+
 		_state = kRun;
 
 		if (Common::Rect(_decoder->getWidth(), _decoder->getHeight()) == NancySceneState.getViewport().getBounds()) {
@@ -243,6 +249,7 @@ void PlaySecondaryMovie::execute() {
 			}
 		}
 
+		NancySceneState.setActiveMovie(nullptr);
 		finishExecution();
 
 		// Allow looping
diff --git a/engines/nancy/action/secondarymovie.h b/engines/nancy/action/secondarymovie.h
index 05e2acb917e..351bcdde1a3 100644
--- a/engines/nancy/action/secondarymovie.h
+++ b/engines/nancy/action/secondarymovie.h
@@ -31,6 +31,8 @@ class VideoDecoder;
 namespace Nancy {
 namespace Action {
 
+class InteractiveVideo;
+
 // Plays an AVF or Bink video. Optionally supports:
 // - playing a sound;
 // - reverse playback;
@@ -40,6 +42,7 @@ namespace Action {
 // - changing the scene after playback ends
 // Mostly used for cinematics, with some occasional uses for background animations
 class PlaySecondaryMovie : public RenderActionRecord {
+	friend class InteractiveVideo;
 public:
 	static const byte kMovieSceneChange			= 5;
 	static const byte kMovieNoSceneChange		= 6;
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index 288a1a80e5f..0f949472312 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -11,6 +11,7 @@ MODULE_OBJS = \
   action/soundrecords.o \
   action/miscrecords.o \
   action/conversation.o \
+  action/interactivevideo.o \
   action/overlay.o \
   action/secondarymovie.o \
   action/secondaryvideo.o \
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 1dec0d1af10..9d394a19ac6 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -126,6 +126,7 @@ Scene::Scene() :
 		_clock(nullptr),
 		_actionManager(),
 		_difficulty(0),
+		_activeMovie(nullptr),
 		_activeConversation(nullptr),
 		_lightning(nullptr),
 		_destroyOnExit(false),
@@ -831,6 +832,14 @@ void Scene::init() {
 	g_nancy->_graphics->redrawAll();
 }
 
+void Scene::setActiveMovie(Action::PlaySecondaryMovie *activeMovie) {
+	_activeMovie = activeMovie;
+}
+
+Action::PlaySecondaryMovie *Scene::getActiveMovie() {
+	return _activeMovie;
+}
+
 void Scene::setActiveConversation(Action::ConversationSound *activeConversation) {
 	_activeConversation = activeConversation;
 }
@@ -1225,6 +1234,9 @@ void Scene::clearSceneData() {
 		// Hopefully this doesn't cause issues with earlier games.
 		_textbox.clear();
 	}
+
+	_activeConversation = nullptr;
+	_activeMovie = nullptr;
 }
 
 void Scene::clearPuzzleData() {
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 9d2a8ea7076..04358e2578a 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -50,6 +50,7 @@ struct SceneChangeDescription;
 
 namespace Action {
 class ConversationSound;
+class PlaySecondaryMovie;
 }
 
 namespace Misc {
@@ -176,6 +177,8 @@ public:
 	SceneChangeDescription &getNextSceneInfo() { return _sceneState.nextScene; }
 	const SceneSummary &getSceneSummary() const { return _sceneState.summary; }
 
+	void setActiveMovie(Action::PlaySecondaryMovie *activeMovie);
+	Action::PlaySecondaryMovie *getActiveMovie();
 	void setActiveConversation(Action::ConversationSound *activeConversation);
 	Action::ConversationSound *getActiveConversation();
 
@@ -286,6 +289,7 @@ private:
 	Common::HashMap<uint32, PuzzleData *> _puzzleData;
 
 	Action::ActionManager _actionManager;
+	Action::PlaySecondaryMovie *_activeMovie;
 	Action::ConversationSound *_activeConversation;
 
 	// Contains a screenshot of the Scene state from the last time it was exited


Commit: 4541d085ca54e71f66be358165984b2a56b8b53b
    https://github.com/scummvm/scummvm/commit/4541d085ca54e71f66be358165984b2a56b8b53b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T00:41:30+01:00

Commit Message:
NANCY: Disable buttons/save when a Movie is active

The original engine specifically disables exiting the Scene
when a SecondaryMovie is playing.

Changed paths:
    engines/nancy/nancy.cpp
    engines/nancy/state/scene.cpp


diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 0cf73434626..8eaba0f8c3e 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -124,10 +124,10 @@ bool NancyEngine::canLoadGameStateCurrently(Common::U32String *msg) {
 }
 
 bool NancyEngine::canSaveGameStateCurrently(Common::U32String *msg) {
-	// TODO also disable during secondary movie
 	return State::Scene::hasInstance() &&
 			NancySceneState._state == State::Scene::kRun &&
 			NancySceneState.getActiveConversation() == nullptr &&
+			NancySceneState.getActiveMovie() == nullptr &&
 			!NancySceneState.isRunningAd();
 }
 
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 9d394a19ac6..4e3d740d57c 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -1067,7 +1067,7 @@ void Scene::handleInput() {
 				g_nancy->_cursor->warpCursor(input.mousePos);
 			}
 		}
-	} else {
+	} else if (!_activeMovie) {
 		// Check if player has pressed esc
 		if (input.input & NancyInput::kOpenMainMenu) {
 			g_nancy->setState(NancyState::kMainMenu);
@@ -1118,38 +1118,41 @@ void Scene::handleInput() {
 
 	_actionManager.handleInput(input);
 
-	if (_menuButton) {
-		_menuButton->handleInput(input);
-
-		if (_menuButton->_isClicked) {
-			if (_buttonPressActivationTime == 0) {
-				auto *bootSummary = GetEngineData(BSUM);
-				assert(bootSummary);
-
-				g_nancy->_sound->playSound("BUOK");
-				_buttonPressActivationTime = g_system->getMillis() + bootSummary->buttonPressTimeDelay;
-			} else if (g_system->getMillis() > _buttonPressActivationTime) {
-				_menuButton->_isClicked = false;
-				requestStateChange(NancyState::kMainMenu);
-				_buttonPressActivationTime = 0;
+	// Menu/help are disabled when a movie is active
+	if (!_activeMovie) {	
+		if (_menuButton) {
+			_menuButton->handleInput(input);
+
+			if (_menuButton->_isClicked) {
+				if (_buttonPressActivationTime == 0) {
+					auto *bootSummary = GetEngineData(BSUM);
+					assert(bootSummary);
+
+					g_nancy->_sound->playSound("BUOK");
+					_buttonPressActivationTime = g_system->getMillis() + bootSummary->buttonPressTimeDelay;
+				} else if (g_system->getMillis() > _buttonPressActivationTime) {
+					_menuButton->_isClicked = false;
+					requestStateChange(NancyState::kMainMenu);
+					_buttonPressActivationTime = 0;
+				}
 			}
 		}
-	}
 
-	if (_helpButton) {
-		_helpButton->handleInput(input);
-
-		if (_helpButton->_isClicked) {
-			if (_buttonPressActivationTime == 0) {
-				auto *bootSummary = GetEngineData(BSUM);
-				assert(bootSummary);
-
-				g_nancy->_sound->playSound("BUOK");
-				_buttonPressActivationTime = g_system->getMillis() + bootSummary->buttonPressTimeDelay;
-			} else if (g_system->getMillis() > _buttonPressActivationTime) {
-				_helpButton->_isClicked = false;
-				requestStateChange(NancyState::kHelp);
-				_buttonPressActivationTime = 0;
+		if (_helpButton) {
+			_helpButton->handleInput(input);
+
+			if (_helpButton->_isClicked) {
+				if (_buttonPressActivationTime == 0) {
+					auto *bootSummary = GetEngineData(BSUM);
+					assert(bootSummary);
+
+					g_nancy->_sound->playSound("BUOK");
+					_buttonPressActivationTime = g_system->getMillis() + bootSummary->buttonPressTimeDelay;
+				} else if (g_system->getMillis() > _buttonPressActivationTime) {
+					_helpButton->_isClicked = false;
+					requestStateChange(NancyState::kHelp);
+					_buttonPressActivationTime = 0;
+				}
 			}
 		}
 	}




More information about the Scummvm-git-logs mailing list