[Scummvm-git-logs] scummvm master -> f091b03c8a94622ce3296ff42cb2719a62433e6c

bluegr noreply at scummvm.org
Sat May 2 15:39:36 UTC 2026


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

Summary:
f091b03c8a NANCY: Refactor most uses of friend class


Commit: f091b03c8a94622ce3296ff42cb2719a62433e6c
    https://github.com/scummvm/scummvm/commit/f091b03c8a94622ce3296ff42cb2719a62433e6c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-05-02T18:38:58+03:00

Commit Message:
NANCY: Refactor most uses of friend class

Add appropriate getters and setters, where needed

Changed paths:
    engines/nancy/action/actionmanager.cpp
    engines/nancy/action/actionmanager.h
    engines/nancy/action/actionrecord.h
    engines/nancy/action/conversation.cpp
    engines/nancy/action/conversation.h
    engines/nancy/action/datarecords.h
    engines/nancy/action/interactivevideo.cpp
    engines/nancy/action/interactivevideo.h
    engines/nancy/action/inventoryrecords.h
    engines/nancy/action/navigationrecords.h
    engines/nancy/action/overlay.h
    engines/nancy/action/puzzle/angletosspuzzle.h
    engines/nancy/action/puzzle/arcadepuzzle.h
    engines/nancy/action/puzzle/assemblypuzzle.h
    engines/nancy/action/puzzle/bballpuzzle.h
    engines/nancy/action/puzzle/bombpuzzle.h
    engines/nancy/action/puzzle/bulpuzzle.h
    engines/nancy/action/puzzle/collisionpuzzle.h
    engines/nancy/action/puzzle/cubepuzzle.h
    engines/nancy/action/puzzle/cuttingpuzzle.h
    engines/nancy/action/puzzle/hamradiopuzzle.h
    engines/nancy/action/puzzle/leverpuzzle.h
    engines/nancy/action/puzzle/matchpuzzle.h
    engines/nancy/action/puzzle/mazechasepuzzle.h
    engines/nancy/action/puzzle/memorypuzzle.h
    engines/nancy/action/puzzle/mouselightpuzzle.h
    engines/nancy/action/puzzle/multibuildpuzzle.h
    engines/nancy/action/puzzle/onebuildpuzzle.h
    engines/nancy/action/puzzle/orderingpuzzle.h
    engines/nancy/action/puzzle/overridelockpuzzle.h
    engines/nancy/action/puzzle/passwordpuzzle.h
    engines/nancy/action/puzzle/peepholepuzzle.h
    engines/nancy/action/puzzle/raycastpuzzle.h
    engines/nancy/action/puzzle/riddlepuzzle.h
    engines/nancy/action/puzzle/rippedletterpuzzle.h
    engines/nancy/action/puzzle/rotatinglockpuzzle.h
    engines/nancy/action/puzzle/safedialpuzzle.h
    engines/nancy/action/puzzle/setplayerclock.h
    engines/nancy/action/puzzle/sliderpuzzle.h
    engines/nancy/action/puzzle/soundequalizerpuzzle.h
    engines/nancy/action/puzzle/soundmatchpuzzle.h
    engines/nancy/action/puzzle/spigotpuzzle.h
    engines/nancy/action/puzzle/tangrampuzzle.cpp
    engines/nancy/action/puzzle/tangrampuzzle.h
    engines/nancy/action/puzzle/telephone.h
    engines/nancy/action/puzzle/towerpuzzle.h
    engines/nancy/action/puzzle/turningpuzzle.h
    engines/nancy/action/puzzle/twodialpuzzle.h
    engines/nancy/action/puzzle/whalesurvivorpuzzle.h
    engines/nancy/action/secondarymovie.h
    engines/nancy/action/secondaryvideo.h
    engines/nancy/action/soundrecords.h
    engines/nancy/cif.h
    engines/nancy/console.cpp
    engines/nancy/console.h
    engines/nancy/cursor.h
    engines/nancy/graphics.cpp
    engines/nancy/graphics.h
    engines/nancy/iff.h
    engines/nancy/input.h
    engines/nancy/misc/mousefollow.h
    engines/nancy/nancy.cpp
    engines/nancy/nancy.h
    engines/nancy/renderobject.h
    engines/nancy/resource.cpp
    engines/nancy/resource.h
    engines/nancy/sound.cpp
    engines/nancy/sound.h
    engines/nancy/state/map.h
    engines/nancy/state/scene.cpp
    engines/nancy/state/scene.h
    engines/nancy/ui/clock.h
    engines/nancy/ui/inventorybox.h
    engines/nancy/video.cpp
    engines/nancy/video.h


diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index c22e8063bcf..83d6858fdef 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -340,19 +340,9 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
 		case DependencyType::kInventory:
 			if (dep.condition == g_nancy->_false) {
 				// Item not in possession or held
-				if (NancySceneState._flags.items[dep.label] == g_nancy->_false &&
-					dep.label != NancySceneState._flags.heldItem) {
-					dep.satisfied = true;
-				} else {
-					dep.satisfied = false;
-				}
+				dep.satisfied = !NancySceneState.hasItem(dep.label);
 			} else {
-				if (NancySceneState._flags.items[dep.label] == g_nancy->_true ||
-					dep.label == NancySceneState._flags.heldItem) {
-					dep.satisfied = true;
-				} else {
-					dep.satisfied = false;
-				}
+				dep.satisfied = NancySceneState.hasItem(dep.label);
 			}
 
 			break;
@@ -372,7 +362,7 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
 				// other way around here. So, we need to check for inequality
 				if (!NancySceneState.getLogicCondition(dep.label, dep.condition)) {
 					// Wait for specified time before satisfying dependency condition
-					Time elapsed = NancySceneState._timers.lastTotalTime - NancySceneState._flags.logicConditions[dep.label].timestamp;
+					Time elapsed = NancySceneState._timers.lastTotalTime - NancySceneState.getLogicConditionTimestamp(dep.label);
 
 					if (elapsed >= dep.timeData) {
 						dep.satisfied = true;
@@ -405,8 +395,8 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
 			break;
 		case DependencyType::kElapsedPlayerTime: {
 			// We're only interested in the hours and minutes
-			Time playerTime = NancySceneState._timers.playerTime.getHours() * 3600000 +
-								NancySceneState._timers.playerTime.getMinutes() * 60000;
+			Time playerTime = NancySceneState.getPlayerTime().getHours() * 3600000 +
+								NancySceneState.getPlayerTime().getMinutes() * 60000;
 			switch (dep.condition) {
 			case 0:
 				dep.satisfied = dep.timeData < playerTime;
@@ -424,8 +414,7 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
 			// Check how many times a scene has been visited.
 			// This dependency type keeps its data in the time variables
 			// Note: nancy7 completely flipped the meaning of 1 and 2
-			int count = NancySceneState._flags.sceneCounts.contains(dep.hours) ?
-				NancySceneState._flags.sceneCounts[dep.hours] : 0;
+			int count = NancySceneState.getSceneCounts(dep.hours);
 			switch (dep.milliseconds) {
 			case 1:
 				if (	(dep.minutes < count && g_nancy->getGameType() <= kGameTypeNancy6) ||
@@ -459,13 +448,13 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
 		}
 		case DependencyType::kElapsedPlayerDay:
 			if (record._days == -1) {
-				record._days = NancySceneState._timers.playerTime.getDays();
+				record._days = NancySceneState.getPlayerTime().getDays();
 				dep.satisfied = true;
 				break;
 			}
 
-			if (record._days < NancySceneState._timers.playerTime.getDays()) {
-				record._days = NancySceneState._timers.playerTime.getDays();
+			if (record._days < NancySceneState.getPlayerTime().getDays()) {
+				record._days = NancySceneState.getPlayerTime().getDays();
 
 				// This is not used in nancy3 and up, so it's a safe assumption that we
 				// do not need to check types recursively
@@ -542,7 +531,7 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
 
 			break;
 		case DependencyType::kDifficultyLevel:
-			if (dep.condition == NancySceneState._difficulty) {
+			if (dep.condition == NancySceneState.getDifficulty()) {
 				dep.satisfied = true;
 			} else {
 				dep.satisfied = false;
diff --git a/engines/nancy/action/actionmanager.h b/engines/nancy/action/actionmanager.h
index 09dc47d897a..4aa946963d7 100644
--- a/engines/nancy/action/actionmanager.h
+++ b/engines/nancy/action/actionmanager.h
@@ -46,9 +46,6 @@ struct DependencyRecord;
 
 // The class that handles ActionRecords and their execution
 class ActionManager {
-	friend class State::Scene;
-	friend class NancyConsole;
-
 public:
 	static const byte kCursInvHolding			= 0;
 	static const byte kCursInvNotHolding		= 1;
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index fd76528f0bb..e30e8f542ec 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -95,9 +95,6 @@ struct DependencyRecord {
 // Does _not_ support drawing to screen, records that need this functionality
 // will have to subclass RenderActionRecord.
 class ActionRecord {
-	friend class ActionManager;
-	friend class NancyConsole;
-
 public:
 	enum ExecutionState { kBegin, kRun, kActionTrigger };
 	enum ExecutionType { kOneShot = 1, kRepeating = 2 };
@@ -122,9 +119,11 @@ public:
 	// Used for debugging
 	virtual Common::String getRecordTypeName() const = 0;
 
+	// Used for handling kCursorType dependency
+	virtual bool canHaveHotspot() const { return false; }
+
 protected:
 	void finishExecution();
-	virtual bool canHaveHotspot() const { return false; } // Used for handling kCursorType dependency
 
 public:
 	Common::String _description;
diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index 1936b1da533..58b3a7e5631 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -767,7 +767,7 @@ void ConversationCel::init() {
 
 void ConversationCel::registerGraphics() {
 	for (uint i = 0; i < _celRObjects.size(); ++i) {
-		_celRObjects[i]._z = 9 + _drawingOrder[i];
+		_celRObjects[i].setZOrder(9 + _drawingOrder[i]);
 		_celRObjects[i].setVisible(true);
 		_celRObjects[i].setTransparent(true);
 		_celRObjects[i].registerGraphics();
diff --git a/engines/nancy/action/conversation.h b/engines/nancy/action/conversation.h
index 254cbd87544..a24f1183d3f 100644
--- a/engines/nancy/action/conversation.h
+++ b/engines/nancy/action/conversation.h
@@ -49,6 +49,7 @@ public:
 	void execute() override;
 
 	virtual bool isVideoDonePlaying() { return true; }
+	bool isViewportRelative() const override { return true; }
 
 protected:
 	struct ConversationFlag {
@@ -98,7 +99,6 @@ protected:
 	static const byte kNoPopNextScene			= 2;
 
 	Common::String getRecordTypeName() const override { return "ConversationSound"; }
-	bool isViewportRelative() const override { return true; }
 
 	// Functions for reading captions are virtual to allow easier support for the terse Conversation variants
 	virtual void readCaptionText(Common::SeekableReadStream &stream);
@@ -182,7 +182,6 @@ protected:
 	};
 
 	class RenderedCel : public RenderObject {
-		friend class ConversationCel;
 	public:
 		RenderedCel() : RenderObject(9) {}
 		bool isViewportRelative() const override { return true; }
diff --git a/engines/nancy/action/datarecords.h b/engines/nancy/action/datarecords.h
index ab322c60b01..d8a5700ab42 100644
--- a/engines/nancy/action/datarecords.h
+++ b/engines/nancy/action/datarecords.h
@@ -127,8 +127,9 @@ public:
 
 	bool _isCursor;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override { return _isCursor ? (_isTerse ? "EventFlagsHSTerse" : "EventFlagsCursorHS") : "EventFlagsMultiHS"; }
 };
 
diff --git a/engines/nancy/action/interactivevideo.cpp b/engines/nancy/action/interactivevideo.cpp
index 3f38e696f7e..3ee0cd42bd4 100644
--- a/engines/nancy/action/interactivevideo.cpp
+++ b/engines/nancy/action/interactivevideo.cpp
@@ -87,7 +87,7 @@ void InteractiveVideo::execute() {
 
 		break;
 	case kRun:
-		if (_movieAR->_state == kActionTrigger || _movieAR->_isFinished) {
+		if (_movieAR->_state == kActionTrigger || _movieAR->getIsFinished()) {
 			_state = kActionTrigger;
 		}
 
diff --git a/engines/nancy/action/interactivevideo.h b/engines/nancy/action/interactivevideo.h
index 774c6c43d25..3f55b1c0189 100644
--- a/engines/nancy/action/interactivevideo.h
+++ b/engines/nancy/action/interactivevideo.h
@@ -31,8 +31,6 @@ class ActionManager;
 class PlaySecondaryMovie;
 
 class InteractiveVideo : public ActionRecord {
-	friend class ActionManager;
-	friend class PlaySecondaryMovie;
 public:
 	InteractiveVideo() {}
 	virtual ~InteractiveVideo() {}
diff --git a/engines/nancy/action/inventoryrecords.h b/engines/nancy/action/inventoryrecords.h
index 43588c37345..eeb26dff73b 100644
--- a/engines/nancy/action/inventoryrecords.h
+++ b/engines/nancy/action/inventoryrecords.h
@@ -73,10 +73,11 @@ public:
 	int16 _drawnFrameID = -1;
 	Graphics::ManagedSurface _fullSurface;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
-	Common::String getRecordTypeName() const override { return "ShowInventoryItem"; }
 	bool isViewportRelative() const override { return true; }
+
+protected:
+	Common::String getRecordTypeName() const override { return "ShowInventoryItem"; }
 };
 
 // When clicking an ActionRecord hotspot with a kItem dependency, the engine
diff --git a/engines/nancy/action/navigationrecords.h b/engines/nancy/action/navigationrecords.h
index f7e67fc3f3e..37c43b28c28 100644
--- a/engines/nancy/action/navigationrecords.h
+++ b/engines/nancy/action/navigationrecords.h
@@ -55,10 +55,11 @@ public:
 
 	HotspotDescription _sceneHotspot;
 
+	bool canHaveHotspot() const override { return true; }
+
 protected:
 	CursorManager::CursorType _hoverCursor;
 
-	bool canHaveHotspot() const override { return true; }
 	Common::String getRecordTypeName() const override { return "HotSingleFrameSceneChange"; }
 };
 
@@ -79,8 +80,9 @@ public:
 	Common::Array<HotspotDescription> _hotspots;
 	bool _isTerse = false;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override {
 		if (_isTerse)
 			return "HotMultiframeSceneChangeTerse";
@@ -118,8 +120,9 @@ public:
 	bool _isTerse = false;
 	bool _dynamicCursor = false;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override {
 		if (_isTerse)
 			return "HotSceneChangeTerse";
@@ -162,8 +165,9 @@ public:
 	byte _conditionPayload;
 	Common::Array<HotspotDescription> _hotspots;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override { return "HotMultiframeMultisceneChange"; }
 };
 
@@ -205,8 +209,9 @@ public:
 
 	HotspotDescription _hotspotDesc;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override { return "MapCallHot1Fr"; }
 };
 
@@ -218,8 +223,9 @@ public:
 
 	Common::Array<HotspotDescription> _hotspots;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override { return "MapCallHotMultiframe"; }
 };
 
diff --git a/engines/nancy/action/overlay.h b/engines/nancy/action/overlay.h
index b953f315edb..3ae78e8f549 100644
--- a/engines/nancy/action/overlay.h
+++ b/engines/nancy/action/overlay.h
@@ -82,11 +82,12 @@ public:
 	bool _isInterruptible;
 	bool _usesAutotext;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
-	Common::String getRecordTypeName() const override;
 	bool isViewportRelative() const override { return true; }
 
+protected:
+	Common::String getRecordTypeName() const override;
+
 	Graphics::ManagedSurface _fullSurface;
 };
 
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.h b/engines/nancy/action/puzzle/angletosspuzzle.h
index 43b550f8bdc..95b5a94026c 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.h
+++ b/engines/nancy/action/puzzle/angletosspuzzle.h
@@ -54,9 +54,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "AngleTossPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 
diff --git a/engines/nancy/action/puzzle/arcadepuzzle.h b/engines/nancy/action/puzzle/arcadepuzzle.h
index bf63634151c..bfc1c638633 100644
--- a/engines/nancy/action/puzzle/arcadepuzzle.h
+++ b/engines/nancy/action/puzzle/arcadepuzzle.h
@@ -47,9 +47,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "ArcadePuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	// ---------- Inner types ----------
 
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.h b/engines/nancy/action/puzzle/assemblypuzzle.h
index b24756e5de9..1a6b373cc01 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.h
+++ b/engines/nancy/action/puzzle/assemblypuzzle.h
@@ -47,9 +47,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "AssemblyPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void rotateBase(bool ccw);
 
diff --git a/engines/nancy/action/puzzle/bballpuzzle.h b/engines/nancy/action/puzzle/bballpuzzle.h
index 5647d735ad6..ab6100f96c7 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.h
+++ b/engines/nancy/action/puzzle/bballpuzzle.h
@@ -39,9 +39,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "BBallPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 
diff --git a/engines/nancy/action/puzzle/bombpuzzle.h b/engines/nancy/action/puzzle/bombpuzzle.h
index cb4fd8a1ee7..7ddd5e7c314 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.h
+++ b/engines/nancy/action/puzzle/bombpuzzle.h
@@ -39,9 +39,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "BombPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 	Common::Array<Common::Rect> _wireSrcs;
diff --git a/engines/nancy/action/puzzle/bulpuzzle.h b/engines/nancy/action/puzzle/bulpuzzle.h
index f970031df70..c6df9d9f143 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.h
+++ b/engines/nancy/action/puzzle/bulpuzzle.h
@@ -40,6 +40,8 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	enum BulAction { kNone, kRoll, kPass, kReset, kCapture };
 
@@ -47,7 +49,6 @@ protected:
 	void reset(bool capture);
 
 	Common::String getRecordTypeName() const override { return "BulPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.h b/engines/nancy/action/puzzle/collisionpuzzle.h
index e4146f240d2..034d0566d61 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.h
+++ b/engines/nancy/action/puzzle/collisionpuzzle.h
@@ -49,6 +49,8 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	// numbers 1-5 are home IDs, 0 is empty cell
 	enum WallType { kWallLeft = 6, kWallUp = 7, kWallDown = 8, kWallRight = 9, kBlock = 10 };
@@ -64,12 +66,10 @@ protected:
 		uint _w = 1;
 		uint _h = 1;
 
-	protected:
 		bool isViewportRelative() const override { return true; }
 	};
 
 	Common::String getRecordTypeName() const override { return _puzzleType == kCollision ? "CollisionPuzzle" : "TileMovePuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Point movePiece(uint pieceID, WallType direction);
 	Common::Rect getScreenPosition(Common::Point gridPos);
diff --git a/engines/nancy/action/puzzle/cubepuzzle.h b/engines/nancy/action/puzzle/cubepuzzle.h
index 7b4bc26288d..587bc7b381d 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.h
+++ b/engines/nancy/action/puzzle/cubepuzzle.h
@@ -43,9 +43,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "CubePuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void rotateBase(int dir);
 
diff --git a/engines/nancy/action/puzzle/cuttingpuzzle.h b/engines/nancy/action/puzzle/cuttingpuzzle.h
index 95cded5c982..b56f43a7733 100644
--- a/engines/nancy/action/puzzle/cuttingpuzzle.h
+++ b/engines/nancy/action/puzzle/cuttingpuzzle.h
@@ -52,6 +52,8 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	enum SubState {
 		kIdle           = 0, // waiting for player input, or checking solution
@@ -61,7 +63,6 @@ protected:
 	};
 
 	Common::String getRecordTypeName() const override { return "CuttingPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void redrawSurface();
 	int grooveTypeForIndex(int i) const;
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.h b/engines/nancy/action/puzzle/hamradiopuzzle.h
index 47f11f4125e..cb598a205b9 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.h
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.h
@@ -41,9 +41,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "HamRadioPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void setFrequency(const Common::Array<uint16> &freq);
 
diff --git a/engines/nancy/action/puzzle/leverpuzzle.h b/engines/nancy/action/puzzle/leverpuzzle.h
index d5d6a48c1d0..d7f4007c3ff 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.h
+++ b/engines/nancy/action/puzzle/leverpuzzle.h
@@ -57,9 +57,10 @@ public:
 	Time _solveSoundPlayTime;
 	SolveState _solveState = kNotSolved;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "LeverPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawLever(uint id);
 };
diff --git a/engines/nancy/action/puzzle/matchpuzzle.h b/engines/nancy/action/puzzle/matchpuzzle.h
index c3cdd886b35..1218a30d63d 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.h
+++ b/engines/nancy/action/puzzle/matchpuzzle.h
@@ -49,9 +49,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "MatchPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	// ---------- Inner types ----------
 
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.h b/engines/nancy/action/puzzle/mazechasepuzzle.h
index 4b62b479319..da50ddf5f9d 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.h
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.h
@@ -58,7 +58,6 @@ protected:
 		Common::Point _gridPos;
 		Common::Point _lastPos;
 
-	protected:
 		bool isViewportRelative() const override { return true; }
 	};
 
diff --git a/engines/nancy/action/puzzle/memorypuzzle.h b/engines/nancy/action/puzzle/memorypuzzle.h
index 0c17f967754..5de2b030556 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.h
+++ b/engines/nancy/action/puzzle/memorypuzzle.h
@@ -43,9 +43,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "MemoryPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	// File data
 
diff --git a/engines/nancy/action/puzzle/mouselightpuzzle.h b/engines/nancy/action/puzzle/mouselightpuzzle.h
index 96bb3cd885b..d8960f52941 100644
--- a/engines/nancy/action/puzzle/mouselightpuzzle.h
+++ b/engines/nancy/action/puzzle/mouselightpuzzle.h
@@ -44,9 +44,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "MouseLightPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 	byte _radius = 0;
diff --git a/engines/nancy/action/puzzle/multibuildpuzzle.h b/engines/nancy/action/puzzle/multibuildpuzzle.h
index 6bf2be774ed..28696aa1d23 100644
--- a/engines/nancy/action/puzzle/multibuildpuzzle.h
+++ b/engines/nancy/action/puzzle/multibuildpuzzle.h
@@ -47,9 +47,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "MultiBuildPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	// A single puzzle piece. Each piece is its own RenderObject.
 	// Unplaced: _drawSurface shows srcRect from primary image.
@@ -77,7 +78,6 @@ protected:
 
 		void setZ(uint16 z) { _z = z; _needsRedraw = true; }
 
-	protected:
 		bool isViewportRelative() const override { return true; }
 	};
 
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.h b/engines/nancy/action/puzzle/onebuildpuzzle.h
index 4cfa69a7f42..c4b1f2d5e97 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.h
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.h
@@ -45,9 +45,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "OneBuildPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	struct Piece : RenderObject {
 		Piece() : RenderObject(0) {}
@@ -70,7 +71,6 @@ protected:
 
 		void setZ(uint16 z) { _z = z; _needsRedraw = true; }
 
-	protected:
 		bool isViewportRelative() const override { return true; }
 	};
 
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.h b/engines/nancy/action/puzzle/orderingpuzzle.h
index ab957711f24..3f9dbfa7f99 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.h
+++ b/engines/nancy/action/puzzle/orderingpuzzle.h
@@ -49,9 +49,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override;
-	bool isViewportRelative() const override { return true; }
 
 	void pushDown(uint id);
 	void setToSecondState(uint id);
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.h b/engines/nancy/action/puzzle/overridelockpuzzle.h
index fe8bb6b0837..021d0799331 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.h
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.h
@@ -43,9 +43,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "OverrideLockPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawButton(uint buttonID, bool clear);
 	void drawLights();
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.h b/engines/nancy/action/puzzle/passwordpuzzle.h
index 4713b0e0da1..af7fa8690b4 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.h
+++ b/engines/nancy/action/puzzle/passwordpuzzle.h
@@ -65,9 +65,10 @@ public:
 	uint _maxNameLength = 0;
 	uint _maxPassLength = 0;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "PasswordPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawText();
 };
diff --git a/engines/nancy/action/puzzle/peepholepuzzle.h b/engines/nancy/action/puzzle/peepholepuzzle.h
index f646afa18e0..fbd4bce43ee 100644
--- a/engines/nancy/action/puzzle/peepholepuzzle.h
+++ b/engines/nancy/action/puzzle/peepholepuzzle.h
@@ -40,9 +40,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "PeepholePuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawInner();
 	void checkButtons();
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.h b/engines/nancy/action/puzzle/raycastpuzzle.h
index c708513fc9b..22ead7fb3ac 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.h
+++ b/engines/nancy/action/puzzle/raycastpuzzle.h
@@ -36,7 +36,6 @@ class RaycastLevelBuilder;
 // Action record implementing nancy3's maze minigame
 class RaycastPuzzle : public RenderActionRecord {
 	friend class RaycastDeferredLoader;
-	friend class RaycastLevelBuilder;
 public:
 	RaycastPuzzle() : RenderActionRecord(7), _map(7) {}
 	~RaycastPuzzle() override;
@@ -50,9 +49,10 @@ public:
 	void handleInput(NancyInput &input) override;
 	void updateGraphics() override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "RaycastPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void validateMap();
 
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.h b/engines/nancy/action/puzzle/riddlepuzzle.h
index 22baf52fde0..061aa67b4d1 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.h
+++ b/engines/nancy/action/puzzle/riddlepuzzle.h
@@ -43,6 +43,8 @@ public:
 	void onPause(bool paused) override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	struct Riddle {
 		Common::String text;
@@ -55,7 +57,6 @@ protected:
 	};
 
 	Common::String getRecordTypeName() const override { return "RiddlePuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawText();
 
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.h b/engines/nancy/action/puzzle/rippedletterpuzzle.h
index 808073d4b7b..771bee0bb2d 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.h
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.h
@@ -85,9 +85,10 @@ public:
 	SolveState _solveState = kNotSolved;
 	RippedLetterPuzzleData *_puzzleState = nullptr;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "RippedLetterPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawPiece(const uint pos, const byte rotation, const int pieceID = -1);
 	bool checkOrder(bool useAlt);
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.h b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
index 4b7c9fea395..fa7e7e406fe 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.h
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
@@ -57,9 +57,10 @@ public:
 	Common::Array<byte> _currentSequence;
 	Time _solveSoundPlayTime;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "RotatingLockPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawDial(uint id);
 };
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.h b/engines/nancy/action/puzzle/safedialpuzzle.h
index de16056c6f3..910bebf8905 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.h
+++ b/engines/nancy/action/puzzle/safedialpuzzle.h
@@ -41,10 +41,11 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	enum AnimState { kNone, kSpin, kSelect, kReset, kResetAnim };
 	Common::String getRecordTypeName() const override { return "SafeDialPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawDialFrame(uint frame);
 	void pushSequence(uint id);
diff --git a/engines/nancy/action/puzzle/setplayerclock.h b/engines/nancy/action/puzzle/setplayerclock.h
index 711adfd8587..65f56187437 100644
--- a/engines/nancy/action/puzzle/setplayerclock.h
+++ b/engines/nancy/action/puzzle/setplayerclock.h
@@ -40,9 +40,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "SetPlayerClock"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawTime(uint16 hours, uint16 minutes);
 
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.h b/engines/nancy/action/puzzle/sliderpuzzle.h
index 88af4490326..10fb0daaf32 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.h
+++ b/engines/nancy/action/puzzle/sliderpuzzle.h
@@ -63,9 +63,10 @@ public:
 	SolveState _solveState = kNotSolved;
 	Graphics::ManagedSurface _image;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "SliderPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawTile(int tileID, uint posX, uint posY);
 	void undrawTile(uint posX, uint posY);
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.h b/engines/nancy/action/puzzle/soundequalizerpuzzle.h
index 901d63cfc28..9e86eaf5d9b 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.h
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.h
@@ -86,9 +86,10 @@ public:
 
 	SoundEqualizerPuzzleData *_puzzleState = nullptr;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "SoundEqualizerPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void updateSlider(uint sliderID);
 };
diff --git a/engines/nancy/action/puzzle/soundmatchpuzzle.h b/engines/nancy/action/puzzle/soundmatchpuzzle.h
index 8a0cca6aa9b..81a7786f0cd 100644
--- a/engines/nancy/action/puzzle/soundmatchpuzzle.h
+++ b/engines/nancy/action/puzzle/soundmatchpuzzle.h
@@ -43,9 +43,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "SoundMatchPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	// File data
 
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.h b/engines/nancy/action/puzzle/spigotpuzzle.h
index 12923c4efbe..91ab7430264 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.h
+++ b/engines/nancy/action/puzzle/spigotpuzzle.h
@@ -40,9 +40,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "SpigotPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.cpp b/engines/nancy/action/puzzle/tangrampuzzle.cpp
index 50e7469151b..7085279e557 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.cpp
+++ b/engines/nancy/action/puzzle/tangrampuzzle.cpp
@@ -276,11 +276,11 @@ void TangramPuzzle::handleInput(NancyInput &input) {
 
 void TangramPuzzle::drawToBuffer(const Tile &tile, Common::Rect subRect) {
 	if (subRect.isEmpty()) {
-		subRect = tile._screenPosition;
+		subRect = tile.getScreenPositionRaw();
 	}
 
-	uint16 xDiff = subRect.left - tile._screenPosition.left;
-	uint16 yDiff = subRect.top - tile._screenPosition.top;
+	uint16 xDiff = subRect.left - tile.getScreenPositionRaw().left;
+	uint16 yDiff = subRect.top - tile.getScreenPositionRaw().top;
 
 	for (int y = 0; y < subRect.height(); ++y) {
 		byte *src = &tile._mask[(y + yDiff) * tile._drawSurface.w + xDiff];
@@ -303,7 +303,7 @@ void TangramPuzzle::pickUpTile(uint id) {
 
 	moveToTop(id);
 	_pickedUpTile = id;
-	redrawBuffer(tileToPickUp._screenPosition);
+	redrawBuffer(tileToPickUp.getScreenPositionRaw());
 	tileToPickUp.pickUp();
 
 	// Make sure we don't have a frame with the correct zOrder, but wrong position
@@ -339,7 +339,7 @@ void TangramPuzzle::rotateTile(uint id) {
 
 	moveToTop(id);
 
-	Common::Rect oldPos = tileToRotate._screenPosition;
+	Common::Rect oldPos = tileToRotate.getScreenPositionRaw();
 
 	if (_pickedUpTile != -1 && checkBuffer(tileToRotate)) {
 		tileToRotate.setHighlighted(true);
@@ -353,7 +353,7 @@ void TangramPuzzle::rotateTile(uint id) {
 	_needsRedraw = true;
 
 	tileToRotate.drawMask();
-	tileToRotate._needsRedraw = true;
+	tileToRotate.setNeedsRedraw(true);
 
 	if (_pickedUpTile == -1) {
 		redrawBuffer(oldPos);
@@ -365,8 +365,8 @@ void TangramPuzzle::rotateTile(uint id) {
 void TangramPuzzle::moveToTop(uint id) {
 	for (uint i = 1; i < _tiles.size(); ++i) {
 		Tile &tile = _tiles[i];
-		if (tile._z > _tiles[id]._z) {
-			tile.setZ(tile._z - 1);
+		if (tile.getZOrder() > _tiles[id].getZOrder()) {
+			tile.setZ(tile.getZOrder() - 1);
 			tile.registerGraphics();
 		}
 	}
@@ -385,9 +385,9 @@ void TangramPuzzle::redrawBuffer(const Common::Rect &rect) {
 	for (uint z = _z + 1; z < _z + _tiles.size(); ++z) {
 		for (uint i = 0; i < _tiles.size() - 1; ++i) {
 			Tile &tile = _tiles[i];
-			if (tile._z == z) {
-				if (tile._screenPosition.intersects(rect)) {
-					drawToBuffer(tile, tile._screenPosition.findIntersectingRect(rect));
+			if (tile.getZOrder() == z) {
+				if (tile.getScreenPositionRaw().intersects(rect)) {
+					drawToBuffer(tile, tile.getScreenPositionRaw().findIntersectingRect(rect));
 				}
 
 				break;
@@ -401,7 +401,7 @@ bool TangramPuzzle::checkBuffer(const Tile &tile) const {
 	// In other words, this checks if we're placing on a valid empty spot
 	for (int y = 0; y < tile._drawSurface.h; ++y) {
 		const byte *tilePtr = &tile._mask[y * tile._drawSurface.w];
-		const byte *bufPtr = &_zBuffer[(y + tile._screenPosition.top) * _drawSurface.w + tile._screenPosition.left];
+		const byte *bufPtr = &_zBuffer[(y + tile.getScreenPositionRaw().top) * _drawSurface.w + tile.getScreenPositionRaw().left];
 		for (int x = 0; x < tile._drawSurface.w; ++x) {
 			if (*tilePtr != (byte)-1 && *bufPtr != 0) {
 				return false;
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.h b/engines/nancy/action/puzzle/tangrampuzzle.h
index e101f05ad34..13c5a3b56e1 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.h
+++ b/engines/nancy/action/puzzle/tangrampuzzle.h
@@ -43,12 +43,12 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "TangramPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	class Tile : public Misc::MouseFollowObject {
-		friend class TangramPuzzle;
 	public:
 		Tile();
 		virtual ~Tile();
@@ -65,7 +65,6 @@ protected:
 		byte _rotation;
 		bool _isHighlighted;
 
-	protected:
 		bool isViewportRelative() const override { return true; }
 	};
 
diff --git a/engines/nancy/action/puzzle/telephone.h b/engines/nancy/action/puzzle/telephone.h
index c2b34bcbd0b..9e1511395df 100644
--- a/engines/nancy/action/puzzle/telephone.h
+++ b/engines/nancy/action/puzzle/telephone.h
@@ -62,9 +62,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return _isNewPhone ? "NewPhone" : "Telephone"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 	Common::Array<Common::Rect> _srcRects;
diff --git a/engines/nancy/action/puzzle/towerpuzzle.h b/engines/nancy/action/puzzle/towerpuzzle.h
index 84ec1cbe31f..23e7ac362d1 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.h
+++ b/engines/nancy/action/puzzle/towerpuzzle.h
@@ -43,9 +43,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "TowerPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawRing(uint poleID, uint position, uint ringID, bool clear = false);
 
diff --git a/engines/nancy/action/puzzle/turningpuzzle.h b/engines/nancy/action/puzzle/turningpuzzle.h
index dcbe384a3b3..06fcfb138d0 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.h
+++ b/engines/nancy/action/puzzle/turningpuzzle.h
@@ -43,9 +43,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "TurningPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	void drawObject(uint objectID, uint faceID, uint frameID);
 	void turnLogic(uint objectID);
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.h b/engines/nancy/action/puzzle/twodialpuzzle.h
index 6685ad9a73b..b4ae24c33d2 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.h
+++ b/engines/nancy/action/puzzle/twodialpuzzle.h
@@ -40,9 +40,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "TwoDialPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 	Common::Path _imageName;
 
diff --git a/engines/nancy/action/puzzle/whalesurvivorpuzzle.h b/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
index 053d96d060c..f08c0b7ec8b 100644
--- a/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
+++ b/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
@@ -45,9 +45,10 @@ public:
 	void execute() override;
 	void handleInput(NancyInput &input) override;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "WhaleSurvivorPuzzle"; }
-	bool isViewportRelative() const override { return true; }
 
 private:
 	// ---- Constants ----
diff --git a/engines/nancy/action/secondarymovie.h b/engines/nancy/action/secondarymovie.h
index 93520580805..92078cd92fb 100644
--- a/engines/nancy/action/secondarymovie.h
+++ b/engines/nancy/action/secondarymovie.h
@@ -44,7 +44,6 @@ class InteractiveVideo;
 // - 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;
@@ -69,6 +68,8 @@ public:
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
 
+	bool getIsFinished() const { return _isFinished; }
+
 	Common::Path _videoName;
 	Common::Path _paletteName;
 	Common::Path _bitmapOverlayName;
@@ -90,9 +91,10 @@ public:
 
 	Common::ScopedPtr<Video::VideoDecoder> _decoder;
 
+	bool isViewportRelative() const override { return true; }
+
 protected:
 	Common::String getRecordTypeName() const override { return "PlaySecondaryMovie"; }
-	bool isViewportRelative() const override { return true; }
 
 	Graphics::ManagedSurface _fullFrame;
 	int _curViewportFrame = -1;
diff --git a/engines/nancy/action/secondaryvideo.h b/engines/nancy/action/secondaryvideo.h
index d90f659786e..aab64bf0f3b 100644
--- a/engines/nancy/action/secondaryvideo.h
+++ b/engines/nancy/action/secondaryvideo.h
@@ -68,11 +68,12 @@ public:
 
 	Common::Array<SecondaryVideoDescription> _videoDescs;
 
-protected:
 	bool canHaveHotspot() const override { return true; }
-	Common::String getRecordTypeName() const override { return "PlaySecondaryVideo"; }
 	bool isViewportRelative() const override { return true; }
 
+protected:
+	Common::String getRecordTypeName() const override { return "PlaySecondaryVideo"; }
+
 	Graphics::ManagedSurface _fullFrame;
 	HoverState _hoverState = kNoHover;
 	AVFDecoder _decoder;
diff --git a/engines/nancy/action/soundrecords.h b/engines/nancy/action/soundrecords.h
index 85762a8eaf6..f1bf6703b23 100644
--- a/engines/nancy/action/soundrecords.h
+++ b/engines/nancy/action/soundrecords.h
@@ -119,8 +119,9 @@ public:
 	FlagDescription _flag; // 0x2A
 	Common::Array<HotspotDescription> _hotspots; // 0x31
 
-protected:
 	bool canHaveHotspot() const override { return true; }
+
+protected:
 	Common::String getRecordTypeName() const override { return "PlaySoundMultiHS"; }
 };
 
diff --git a/engines/nancy/cif.h b/engines/nancy/cif.h
index db5b5650af1..78e1b1b236f 100644
--- a/engines/nancy/cif.h
+++ b/engines/nancy/cif.h
@@ -60,32 +60,30 @@ struct CifInfo {
 
 // Wrapper for a single file. Exclusively used for scene IFFs, though it can contain anything.
 class CifFile {
-private:
-friend class ResourceManager;
-	CifFile() : _stream(nullptr) {}
 public:
+	CifFile() : _stream(nullptr) {}
+	CifFile(const CifInfo &info) : _stream(nullptr), _info(info) {}
 	CifFile(Common::SeekableReadStream *stream, const Common::Path &name);
 	~CifFile();
 
 	Common::SeekableReadStream *createReadStream() const;
-
-private:
-	bool sync(Common::Serializer &ser);
 	Common::SeekableReadStream *createReadStreamRaw() const;
+	bool sync(Common::Serializer &ser);
+	CifInfo getInfo() const { return _info; }
 
+private:
 	Common::SeekableReadStream *_stream;
 	CifInfo _info;
 };
 
 // Container type comprising of multiple CIF files. Contrary to its name it contains no tree structure.
 class CifTree : public Common::Archive {
-protected:
-friend class ResourceManager;
+	friend class ResourceManager;
+public:
 	CifTree() : _stream(nullptr) {}
 	CifTree(Common::SeekableReadStream *stream, const Common::Path &name);
 	virtual ~CifTree();
 
-public:
 	// Used for extracting additional image data for conversation cels (nancy2 and up)
 	const CifInfo &getCifInfo(const Common::Path &name) const;
 
@@ -99,11 +97,12 @@ public:
 	Common::Path getName() const { return _name; }
 
 	static CifTree *makeCifTreeArchive(const Common::String &name, const Common::String &ext);
-
-private:
-	bool sync(Common::Serializer &ser);
 	Common::SeekableReadStream *createReadStreamRaw(const Common::Path &path) const;
+	bool sync(Common::Serializer &ser);
 
+	void addInfo(const CifInfo &info) { _writeFileMap.push_back(info); }
+
+private:
 	Common::Path _name;
 	Common::SeekableReadStream *_stream;
 	Common::HashMap<Common::Path, CifInfo, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> _fileMap;
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 192798a15d0..13a601c3ee1 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -451,7 +451,7 @@ bool NancyConsole::Cmd_loadScene(int argc, const char **argv) {
 		return true;
 	}
 
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -472,7 +472,7 @@ bool NancyConsole::Cmd_loadScene(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_sceneID(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -601,7 +601,7 @@ bool NancyConsole::Cmd_listActionRecords(int argc, const char **argv) {
 
 	if (argc == 1) {
 		// Print the current scene
-		if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		if (g_nancy->getState() != NancyState::kScene) {
 			debugPrintf("Not in the kScene state\n");
 			return true;
 		}
@@ -770,7 +770,7 @@ bool NancyConsole::Cmd_scanForActionRecordType(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -840,7 +840,7 @@ bool NancyConsole::Cmd_setEventFlags(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -886,7 +886,7 @@ bool NancyConsole::Cmd_setInventory(int argc, const char **argv) {
 	auto *inventoryData = GetEngineData(INV);
 	assert(inventoryData);
 
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -924,12 +924,12 @@ bool NancyConsole::Cmd_setInventory(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_getPlayerTime(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
 
-	Time time = NancySceneState._timers.playerTime;
+	Time time = NancySceneState.getPlayerTime();
 	debugPrintf("Player time: %u days, %u hours, %u minutes; %u\n",
 		time.getDays(),
 		time.getHours(),
@@ -939,7 +939,7 @@ bool NancyConsole::Cmd_getPlayerTime(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_setPlayerTime(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -970,7 +970,7 @@ bool NancyConsole::Cmd_setPlayerTime(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_getDifficulty(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -981,7 +981,7 @@ bool NancyConsole::Cmd_getDifficulty(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_setDifficulty(int argc, const char **argv) {
-	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+	if (g_nancy->getState() != NancyState::kScene) {
 		debugPrintf("Not in the kScene state\n");
 		return true;
 	}
@@ -1008,7 +1008,7 @@ bool NancyConsole::Cmd_setDifficulty(int argc, const char **argv) {
 bool NancyConsole::Cmd_soundInfo(int argc, const char **argv) {
 	if (g_nancy->getGameType() >= kGameTypeNancy3) {
 		const Math::Vector3d &pos = NancySceneState.getSceneSummary().listenerPosition;
-		const Math::Vector3d &ori = g_nancy->_sound->_orientation;
+		const Math::Vector3d &ori = g_nancy->_sound->getOrientation();
 		debugPrintf("3D listener position: %f, %f, %f\n", pos.x(), pos.y(), pos.z());
 		debugPrintf("3D listener orientation: %f, %f, %f\n\n", ori.x(), ori.y(), ori.z());
 	}
@@ -1027,22 +1027,7 @@ bool NancyConsole::Cmd_soundInfo(int argc, const char **argv) {
 	}
 
 	for (byte channelID : channelIDs) {
-		const auto &chan = g_nancy->_sound->_channels[channelID];
-
-		if (g_nancy->_sound->isSoundPlaying(channelID)) {
-			debugPrintf("Channel %u, filename %s\n", channelID, chan.name.c_str());
-			debugPrintf("Source rate %i, playing at %i\n", chan.stream->getRate(), g_nancy->_sound->_mixer->getChannelRate(chan.handle));
-			debugPrintf("Volume: %u, pan: %i, numLoops: %u\n\n", chan.volume, g_nancy->_sound->_mixer->getChannelBalance(chan.handle), chan.numLoops);
-
-			if (chan.playCommands != SoundManager::kPlaySequential) {
-				debugPrintf("\tPlay commands 0x%08x\n", chan.playCommands);
-
-				if (chan.effectData) {
-					debugPrintf("\tPosition: %f, %f, %f, ", chan.position.x(), chan.position.y(), chan.position.z());
-					debugPrintf("delta: %f, %f, %f\n\n", chan.positionDelta.x(), chan.positionDelta.y(), chan.positionDelta.z());
-				}
-			}
-		}
+		debugPrintf(g_nancy->_sound->getChannelInfo(channelID).c_str());
 	}
 
 	return true;
diff --git a/engines/nancy/console.h b/engines/nancy/console.h
index 746276050f0..849f8430d72 100644
--- a/engines/nancy/console.h
+++ b/engines/nancy/console.h
@@ -25,9 +25,6 @@
 #include "gui/debugger.h"
 
 namespace Nancy {
-namespace State {
-class Scene;
-}
 
 namespace Action {
 class ActionRecord;
@@ -37,7 +34,6 @@ struct DependencyRecord;
 class NancyEngine;
 
 class NancyConsole : public GUI::Debugger {
-	friend class State::Scene;
 public:
 	NancyConsole();
 	virtual ~NancyConsole(void);
diff --git a/engines/nancy/cursor.h b/engines/nancy/cursor.h
index 16c88371d41..0c696e4db72 100644
--- a/engines/nancy/cursor.h
+++ b/engines/nancy/cursor.h
@@ -29,10 +29,7 @@
 
 namespace Nancy {
 
-class NancyEngine;
-
 class CursorManager {
-	friend class NancyEngine;
 
 public:
 	enum CursorType {
@@ -87,6 +84,7 @@ public:
 	void setCursor(CursorType type, int16 itemID);
 	void setCursorType(CursorType type);
 	void setCursorItemID(int16 itemID);
+	void showCursor(bool shouldShow);
 
 	void warpCursor(const Common::Point &pos);
 
@@ -100,8 +98,6 @@ public:
 	const CursorType _puzzleExitCursor;
 
 private:
-	void showCursor(bool shouldShow);
-
 	void adjustCursorHotspot();
 
 	struct Cursor {
diff --git a/engines/nancy/graphics.cpp b/engines/nancy/graphics.cpp
index ca3e640640b..3d6c6312e2f 100644
--- a/engines/nancy/graphics.cpp
+++ b/engines/nancy/graphics.cpp
@@ -79,8 +79,8 @@ void GraphicsManager::draw(bool updateScreen) {
 
 		current.updateGraphics();
 
-		if (current._needsRedraw) {
-			if (current._isVisible) {
+		if (current.needsRedraw()) {
+			if (current.isVisible()) {
 				if (current.hasMoved() && !current.getPreviousScreenPosition().isEmpty()) {
 					// Object moved to a new location on screen, update the previous one
 					_dirtyRects.push_back(current.getPreviousScreenPosition());
@@ -94,9 +94,9 @@ void GraphicsManager::draw(bool updateScreen) {
 			}
 		}
 
-		current._needsRedraw = false;
-		current._hasMoved = false;
-		current._previousScreenPosition = current._screenPosition;
+		current.setNeedsRedraw(false);
+		current.setHasMoved(false);
+		current.updatePreviousScreenPosition();
 	}
 
 	// Filter out dirty rects that are completely inside others to reduce overdraw
@@ -115,7 +115,7 @@ void GraphicsManager::draw(bool updateScreen) {
 		for (RenderObject **it = _objects.begin(); it < _objects.end(); ++it) {
 			RenderObject &current = **it;
 
-			if (!current._isVisible || current.getScreenPosition().isEmpty()) {
+			if (!current.isVisible() || current.getScreenPosition().isEmpty()) {
 				continue;
 			}
 
@@ -128,7 +128,7 @@ void GraphicsManager::draw(bool updateScreen) {
 				for (auto it2 = it + 1; it2 < _objects.end(); ++it2) {
 					RenderObject &other = **it2;
 
-					if (!other._isVisible || other.getScreenPosition().isEmpty()) {
+					if (!other.isVisible() || other.getScreenPosition().isEmpty()) {
 						continue;
 					}
 
@@ -206,7 +206,7 @@ void GraphicsManager::clearObjects() {
 
 void GraphicsManager::redrawAll() {
 	for (auto &obj : _objects) {
-		obj->_needsRedraw = true;
+		obj->setNeedsRedraw(true);
 	}
 }
 
diff --git a/engines/nancy/graphics.h b/engines/nancy/graphics.h
index bde9a4cc283..a7116528f2e 100644
--- a/engines/nancy/graphics.h
+++ b/engines/nancy/graphics.h
@@ -30,12 +30,10 @@
 
 namespace Nancy {
 
-class NancyEngine;
 class RenderObject;
 
 // Graphics class that handles multilayered surface rendering with minimal redraw
 class GraphicsManager {
-	friend class NancyEngine;
 public:
 	GraphicsManager();
 
@@ -72,6 +70,8 @@ public:
 	static void rotateBlit(const Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest, byte rotation);
 	static void crossDissolve(const Graphics::ManagedSurface &from, const Graphics::ManagedSurface &to, byte alpha, const Common::Rect &rect, Graphics::ManagedSurface &inResult);
 
+	bool getIsSuppressed() const { return _isSuppressed; }
+
 	// Debug
 	void debugDrawToScreen(const Graphics::ManagedSurface &surf);
 
diff --git a/engines/nancy/iff.h b/engines/nancy/iff.h
index c47e0e15cc9..7402724f4c8 100644
--- a/engines/nancy/iff.h
+++ b/engines/nancy/iff.h
@@ -31,15 +31,9 @@ class SeekableReadStream;
 
 namespace Nancy {
 
-class NancyEngine;
-class ResourceManager;
-
 class IFF {
-	friend class ResourceManager;
-private:
-	IFF(Common::SeekableReadStream *stream);
-
 public:
+	IFF(Common::SeekableReadStream *stream);
 	~IFF();
 
 	const byte *getChunk(uint32 id, uint &size, uint index = 0) const;
diff --git a/engines/nancy/input.h b/engines/nancy/input.h
index 7d12c2282e7..5f232f3e149 100644
--- a/engines/nancy/input.h
+++ b/engines/nancy/input.h
@@ -68,21 +68,20 @@ struct NancyInput {
 // This class handles collecting events and translating them to a NancyInput object,
 // which can then be pulled by interested classes through getInput()
 class InputManager {
-	friend class NancyConsole;
-
-enum NancyAction {
-	kNancyActionMoveUp,
-	kNancyActionMoveDown,
-	kNancyActionMoveLeft,
-	kNancyActionMoveRight,
-	kNancyActionMoveFast,
-	kNancyActionLeftClick,
-	kNancyActionRightClick,
-	kNancyActionOpenMainMenu,
-	kNancyActionShowRaycastMap
-};
 
 public:
+	enum NancyAction {
+		kNancyActionMoveUp,
+		kNancyActionMoveDown,
+		kNancyActionMoveLeft,
+		kNancyActionMoveRight,
+		kNancyActionMoveFast,
+		kNancyActionLeftClick,
+		kNancyActionRightClick,
+		kNancyActionOpenMainMenu,
+		kNancyActionShowRaycastMap
+	};
+
 	InputManager() :
 		_inputs(0),
 		_mouseEnabled(true),
diff --git a/engines/nancy/misc/mousefollow.h b/engines/nancy/misc/mousefollow.h
index f46144c3156..1e0eef08ff0 100644
--- a/engines/nancy/misc/mousefollow.h
+++ b/engines/nancy/misc/mousefollow.h
@@ -51,9 +51,9 @@ public:
 
 	void setZ(uint16 z) { _z = z; _needsRedraw = true; }
 	void handleInput(NancyInput &input);
+	bool isViewportRelative() const override { return true; }
 
 protected:
-	bool isViewportRelative() const override { return true; }
 
 	bool _isPickedUp = false;
 	byte _rotation = 0;
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 282f1f1903a..ebd256af8c5 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -325,7 +325,7 @@ Common::Error NancyEngine::run() {
 			s->process();
 		}
 
-		graphicsWereSuppressed = _graphics->_isSuppressed;
+		graphicsWereSuppressed = _graphics->getIsSuppressed();
 
 		_graphics->draw();
 
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 5dd080cf913..b9d9d15f773 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -73,8 +73,6 @@ class State;
 
 class NancyEngine : public Engine {
 public:
-	friend class NancyConsole;
-
 	NancyEngine(OSystem *syst, const NancyGameDescription *gd);
 	~NancyEngine();
 
diff --git a/engines/nancy/renderobject.h b/engines/nancy/renderobject.h
index 790ff4bfcd6..5f437d86738 100644
--- a/engines/nancy/renderobject.h
+++ b/engines/nancy/renderobject.h
@@ -34,7 +34,6 @@ class GraphicsManager;
 // A subclass of this will be automatically updated and drawn from the graphics manager,
 // but initialization needs to be done manually.
 class RenderObject {
-	friend class GraphicsManager;
 public:
 	RenderObject(uint16 zOrder);
 	RenderObject(uint16 zOrder, Graphics::ManagedSurface &surface, const Common::Rect &srcBounds, const Common::Rect &destBounds);
@@ -53,13 +52,21 @@ public:
 	void setTransparent(bool isTransparent);
 	bool isVisible() const { return _isVisible; }
 
+	bool needsRedraw() const { return _needsRedraw; }
+	void setNeedsRedraw(bool needsRedraw) { _needsRedraw = needsRedraw; }
+
+	void setHasMoved(bool hasMoved) { _hasMoved = hasMoved; }
+
 	// Only used by The Vampire Diaries
 	void grabPalette(byte *colors, uint paletteStart = 0, uint paletteSize = 256);
 	void setPalette(const Common::Path &paletteName, uint paletteStart = 0, uint paletteSize = 256);
 	void setPalette(const byte *colors, uint paletteStart = 0, uint paletteSize = 256);
 
 	bool hasMoved() const { return _previousScreenPosition != _screenPosition; }
+	void updatePreviousScreenPosition() { _previousScreenPosition = _screenPosition; }
+
 	Common::Rect getScreenPosition() const;
+	Common::Rect getScreenPositionRaw() const { return _screenPosition; }
 	Common::Rect getPreviousScreenPosition() const;
 
 	// Given a screen-space rect, convert it to the _drawSurface's local space
@@ -69,13 +76,14 @@ public:
 
 	Common::Rect getBounds() const { return Common::Rect(_screenPosition.width(), _screenPosition.height()); }
 	uint16 getZOrder() const { return _z; }
+	void setZOrder(uint16 z) { _z = z; }
 
 	Graphics::ManagedSurface _drawSurface;
 
-protected:
 	// Needed for proper handling of objects inside the viewport
 	virtual bool isViewportRelative() const { return false; }
 
+protected:
 	bool _needsRedraw;
 	bool _isVisible;
 	bool _hasMoved;
diff --git a/engines/nancy/resource.cpp b/engines/nancy/resource.cpp
index 0e9b7fe5361..f779fe3cf28 100644
--- a/engines/nancy/resource.cpp
+++ b/engines/nancy/resource.cpp
@@ -94,7 +94,7 @@ bool ResourceManager::loadImage(const Common::Path &name, Graphics::ManagedSurfa
 			// .cifs are compressed, so we need to extract
 			CifFile cifFile(stream, name); // cifFile takes ownership of the current stream
 			stream = cifFile.createReadStream();
-			info = cifFile._info;
+			info = cifFile.getInfo();
 		}
 	}
 
@@ -325,7 +325,7 @@ bool ResourceManager::exportCif(const Common::String &treeName, const Common::Pa
 		// .cifs are compressed, so we need to extract
 		CifFile cifFile(stream, name); // cifFile takes ownership of the current stream
 		stream = cifFile.createReadStreamRaw();
-		info = cifFile._info;
+		info = cifFile.getInfo();
 	}
 
 	if (!stream) {
@@ -368,8 +368,7 @@ bool ResourceManager::exportCif(const Common::String &treeName, const Common::Pa
 		}
 	}
 
-	CifFile file;
-	file._info = info;
+	CifFile file(info);
 
 	Common::DumpFile dump;
 	dump.open(name.append(".cif"));
@@ -413,7 +412,7 @@ bool ResourceManager::exportCifTree(const Common::String &treeName, const Common
 			// .cifs are compressed, so we need to extract
 			CifFile cifFile(stream, path); // cifFile takes ownership of the current stream
 			stream = cifFile.createReadStreamRaw();
-			info = cifFile._info;
+			info = cifFile.getInfo();
 		}
 
 		if (!stream) {
@@ -457,7 +456,7 @@ bool ResourceManager::exportCifTree(const Common::String &treeName, const Common
 		}
 
 		resStreams.push_back(stream);
-		file._writeFileMap.push_back(info);
+		file.addInfo(info);
 	}
 
 	uint16 dataOffset = headerSize + file._writeFileMap.size() * infoSize; // Initial offset after header/infos
diff --git a/engines/nancy/resource.h b/engines/nancy/resource.h
index 70e460c814d..3db7e6bf5ae 100644
--- a/engines/nancy/resource.h
+++ b/engines/nancy/resource.h
@@ -34,8 +34,6 @@ namespace Nancy {
 class IFF;
 
 class ResourceManager {
-	friend class NancyConsole;
-	friend class NancyEngine;
 public:
 	ResourceManager() = default;
 	~ResourceManager() = default;
@@ -52,7 +50,6 @@ public:
 	bool readCifTree(const Common::String &name, const Common::String &ext, int priority);
 	PatchTree *readPatchTree(Common::SeekableReadStream *stream, const Common::String &name, int priority);
 
-private:
 	// Debug functions
 
 	// Return a human-readable description of a single CIF file.
diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index 00db42190dc..1d5f606cef3 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -904,4 +904,27 @@ void SoundManager::soundEffectMaintenance(uint16 channelID, bool force) {
 	}
 }
 
+Common::String SoundManager::getChannelInfo(uint16 channelID) {
+	Common::String result;
+
+	const auto &chan = _channels[channelID];
+
+	if (isSoundPlaying(channelID)) {
+		result += Common::String::format("Channel %u, filename %s\n", channelID, chan.name.c_str());
+		result += Common::String::format("Source rate %i, playing at %i\n", chan.stream->getRate(), _mixer->getChannelRate(chan.handle));
+		result += Common::String::format("Volume: %u, pan: %i, numLoops: %u\n\n", chan.volume, _mixer->getChannelBalance(chan.handle), chan.numLoops);
+
+		if (chan.playCommands != kPlaySequential) {
+			result += Common::String::format("\tPlay commands 0x%08x\n", chan.playCommands);
+
+			if (chan.effectData) {
+				result += Common::String::format("\tPosition: %f, %f, %f, ", chan.position.x(), chan.position.y(), chan.position.z());
+				result += Common::String::format("delta: %f, %f, %f\n\n", chan.positionDelta.x(), chan.positionDelta.y(), chan.positionDelta.z());
+			}
+		}
+	}
+
+	return result;
+}
+
 } // End of namespace Nancy
diff --git a/engines/nancy/sound.h b/engines/nancy/sound.h
index 68bb1c6bc7f..6f6d219081c 100644
--- a/engines/nancy/sound.h
+++ b/engines/nancy/sound.h
@@ -42,7 +42,6 @@ class NancyConsole;
 class NancyEngine;
 
 class SoundManager {
-	friend class NancyConsole;
 public:
 	// Settings for playing a sound, used in nancy3 and up
 	// Older versions had a different, non-bitflag enum, but testing
@@ -114,6 +113,9 @@ public:
 	void soundEffectMaintenance();
 	void recalculateSoundEffects();
 
+	Math::Vector3d &getOrientation() { return _orientation; }
+	Common::String getChannelInfo(uint16 channelID);
+
 	// Used when changing scenes
 	void stopAndUnloadSceneSpecificSounds();
 	void pauseSceneSpecificSounds(bool pause);
diff --git a/engines/nancy/state/map.h b/engines/nancy/state/map.h
index dc6725c99a8..319e60a5876 100644
--- a/engines/nancy/state/map.h
+++ b/engines/nancy/state/map.h
@@ -94,8 +94,6 @@ protected:
 };
 
 class TVDMap : public Map {
-	friend class MapGlobe;
-
 public:
 	TVDMap();
 	virtual ~TVDMap() = default;
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index bc0ed7aa336..d3b0594b0a5 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -698,9 +698,9 @@ void Scene::synchronize(Common::Serializer &ser) {
 		ser.syncAsUint32LE((uint32 &)_flags.logicConditions[i].timestamp);
 	}
 
-	auto &order = getInventoryBox()._order;
-	uint prevSize = getInventoryBox()._order.size();
-	getInventoryBox()._order.resize(g_nancy->getStaticData().numItems);
+	auto &order = getInventoryBox().getOrder();
+	uint prevSize = order.size();
+	order.resize(g_nancy->getStaticData().numItems);
 
 	if (ser.isSaving()) {
 		for (uint i = prevSize; i < order.size(); ++i) {
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index ff0c1e12a6f..6cbaedab79b 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -73,11 +73,6 @@ namespace State {
 
 // The game state that handles all of the gameplay
 class Scene : public State, public Common::Singleton<Scene> {
-	friend class Action::ActionRecord;
-	friend class Action::ActionManager;
-	friend class NancyConsole;
-	friend class NancyEngine;
-
 public:
 	struct SceneSummary {
 		// SSUM and TSUM
@@ -123,6 +118,9 @@ public:
 	void changeScene(const SceneChangeDescription &sceneDescription);
 	void pushScene(int16 itemID = -1);
 	void popScene(bool inventory = false);
+	uint16 getSceneCounts(int16 hours) const {
+		return _flags.sceneCounts.contains(hours) ? _flags.sceneCounts[hours] : 0;
+	}
 
 	void setPlayerTime(Time time, byte relative);
 	Time getPlayerTime() const { return _timers.playerTime; }
@@ -149,6 +147,9 @@ public:
 	void setLogicCondition(int16 label, byte flag);
 	bool getLogicCondition(int16 label, byte flag) const;
 	void clearLogicConditions();
+	Time getLogicConditionTimestamp(int16 label) const {
+		return _flags.logicConditions[label].timestamp;	
+	}
 
 	void setDifficulty(uint difficulty) { _difficulty = difficulty; }
 	uint16 getDifficulty() const { return _difficulty; }
@@ -220,6 +221,8 @@ public:
 
 	Timers _timers;
 
+	RenderObject _hotspotDebug;
+
 private:
 	void init();
 	void load(bool fromSaveFile = false);
@@ -306,8 +309,6 @@ private:
 	// Contains a screenshot of the Scene state from the last time it was exited
 	Graphics::ManagedSurface _lastScreenshot;
 
-	RenderObject _hotspotDebug;
-
 	bool _destroyOnExit;
 	bool _isRunningAd;
 
diff --git a/engines/nancy/ui/clock.h b/engines/nancy/ui/clock.h
index 2e9ae903b4b..59576f04252 100644
--- a/engines/nancy/ui/clock.h
+++ b/engines/nancy/ui/clock.h
@@ -35,7 +35,6 @@ struct NancyInput;
 namespace UI {
 
 class Clock : public RenderObject {
-	friend class ClockAnim;
 public:
 	Clock();
 	virtual ~Clock() = default;
diff --git a/engines/nancy/ui/inventorybox.h b/engines/nancy/ui/inventorybox.h
index b7c7f176a20..f14d4a41cc1 100644
--- a/engines/nancy/ui/inventorybox.h
+++ b/engines/nancy/ui/inventorybox.h
@@ -40,8 +40,6 @@ class Scene;
 namespace UI {
 
 class InventoryBox : public RenderObject {
-	friend class State::Scene;
-
 public:
 	struct ItemDescription {
 		Common::String name; // 0x00
@@ -58,12 +56,15 @@ public:
 
 	void onScrollbarMove();
 
-private:
-	// These are private since they should only be called from Scene
 	void addItem(const int16 itemID);
 	void removeItem(const int16 itemID);
-
 	void onReorder();
+
+	Common::Array<int16> &getOrder() { return _order; }
+
+private:
+	// These are private since they should only be called from Scene
+
 	void setHotspots(const uint pageNr);
 	void drawItemInSlot(const uint itemID, const uint slotID, const bool highlighted = false);
 
diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index 159b9631978..f83488d3e11 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -111,16 +111,16 @@ bool AVFDecoder::loadStream(Common::SeekableReadStream *stream) {
 }
 
 const Graphics::Surface *AVFDecoder::decodeFrame(uint frameNr) {
-	return ((AVFDecoder::AVFVideoTrack *)getTrack(0))->decodeFrame(frameNr);
+	return ((AVFVideoTrack *)getTrack(0))->decodeFrame(frameNr);
 }
 
 void AVFDecoder::addFrameTime(const uint16 timeToAdd) {
-	((AVFDecoder::AVFVideoTrack *)getTrack(0))->_frameTime += timeToAdd;
+	((AVFVideoTrack *)getTrack(0))->addFrameTime(timeToAdd);
 }
 
 // Custom function to allow the last frame of the video to play correctly
 bool AVFDecoder::atEnd() const {
-	const AVFDecoder::AVFVideoTrack *track = ((const AVFDecoder::AVFVideoTrack *)getTrack(0));
+	const AVFVideoTrack *track = ((const AVFVideoTrack *)getTrack(0));
 	if (!track) {
 		return true;
 	}
diff --git a/engines/nancy/video.h b/engines/nancy/video.h
index 93db53aa6c4..62093ab0549 100644
--- a/engines/nancy/video.h
+++ b/engines/nancy/video.h
@@ -54,7 +54,6 @@ public:
 private:
 	CacheHint _cacheHint;
 	class AVFVideoTrack : public FixedRateVideoTrack {
-	friend class AVFDecoder;
 	friend class VideoCacheLoader;
 	public:
 		AVFVideoTrack(Common::SeekableReadStream *stream, uint32 chunkFileFormat, CacheHint cacheHint);
@@ -72,6 +71,7 @@ private:
 		bool endOfTrack() const override;
 		const Graphics::Surface *decodeNextFrame() override;
 		const Graphics::Surface *decodeFrame(uint frameNr);
+		void addFrameTime(const uint16 timeToAdd) { _frameTime += timeToAdd; }
 
 	protected:
 		Common::Rational getFrameRate() const override { return Common::Rational(1000, _frameTime); }




More information about the Scummvm-git-logs mailing list