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

yinsimei roseline.yin at gmail.com
Thu Jul 20 00:43:55 CEST 2017


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

Summary:
53542073b9 SLUDGE: Objectify object manager
0e7d9b4eb2 SLUDGE: Objectify parallex and create graphics manager
e617a53608 SLUDGE: Objectify graphic classes


Commit: 53542073b9d9516396b1de1d883dc0192a66043b
    https://github.com/scummvm/scummvm/commit/53542073b9d9516396b1de1d883dc0192a66043b
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2017-07-20T00:43:16+02:00

Commit Message:
SLUDGE: Objectify object manager

Changed paths:
    engines/sludge/builtin.cpp
    engines/sludge/main_loop.cpp
    engines/sludge/objtypes.cpp
    engines/sludge/objtypes.h
    engines/sludge/people.cpp
    engines/sludge/people.h
    engines/sludge/region.cpp
    engines/sludge/region.h
    engines/sludge/sludge.cpp
    engines/sludge/sludge.h
    engines/sludge/talk.cpp
    engines/sludge/variable.cpp


diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index 8358938..7d5dadd 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -992,7 +992,7 @@ builtIn(callEvent) {
 		return BR_ERROR;
 	trimStack(fun->stack);
 
-	int fNum = getCombinationFunction(obj1, obj2);
+	int fNum = g_sludge->_objMan->getCombinationFunction(obj1, obj2);
 
 	// Return value
 	if (fNum) {
@@ -1366,7 +1366,7 @@ builtIn(rename) {
 	if (!getValueType(objT, SVT_OBJTYPE, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	objectType *o = findObjectType(objT);
+	ObjectType *o = g_sludge->_objMan->findObjectType(objT);
 	o->screenName.clear();
 	o->screenName = newText;
 	return BR_CONTINUE;
@@ -2124,7 +2124,7 @@ builtIn(fetchEvent) {
 		return BR_ERROR;
 	trimStack(fun->stack);
 
-	int fNum = getCombinationFunction(obj1, obj2);
+	int fNum = g_sludge->_objMan->getCombinationFunction(obj1, obj2);
 
 	// Return value
 	if (fNum) {
@@ -2503,7 +2503,7 @@ builtIn(hasFlag) {
 	if (!getValueType(objNum, SVT_OBJTYPE, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	objectType *objT = findObjectType(objNum);
+	ObjectType *objT = g_sludge->_objMan->findObjectType(objNum);
 	if (!objT)
 		return BR_ERROR;
 	setVariable(fun->reg, SVT_INT, objT->flags & (1 << flagIndex));
diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp
index 8f31167..bc29209 100644
--- a/engines/sludge/main_loop.cpp
+++ b/engines/sludge/main_loop.cpp
@@ -173,7 +173,7 @@ int main_loop(const char *filename)
 		return fatal("Couldn't initialise people stuff");
 	if (!initFloor())
 		return fatal("Couldn't initialise floor stuff");
-	if (!initObjectTypes())
+	if (!g_sludge->_objMan->initObjectTypes())
 		return fatal("Couldn't initialise object type stuff");
 	initSpeech();
 	initStatusBar();
diff --git a/engines/sludge/objtypes.cpp b/engines/sludge/objtypes.cpp
index 57365e2..3bea21a 100644
--- a/engines/sludge/objtypes.cpp
+++ b/engines/sludge/objtypes.cpp
@@ -31,31 +31,37 @@
 
 namespace Sludge {
 
-objectType *allObjectTypes = NULL;
+ObjectManager::~ObjectManager() {
+	ObjectTypeList::iterator it;
+	for (it = _allObjectTypes.begin(); it != _allObjectTypes.end(); ++it) {
+		delete [](*it)->allCombis;
+		delete (*it);
+		(*it) = nullptr;
+	}
+}
 
-bool initObjectTypes() {
+bool ObjectManager::initObjectTypes() {
 	return true;
 }
 
-objectType *findObjectType(int i) {
-	objectType *huntType = allObjectTypes;
-
-	while (huntType) {
-		if (huntType->objectNum == i)
-			return huntType;
-		huntType = huntType->next;
+ObjectType *ObjectManager::findObjectType(int i) {
+	ObjectTypeList::iterator it;
+	for (it = _allObjectTypes.begin(); it != _allObjectTypes.end(); ++it) {
+		if ((*it)->objectNum == i) {
+			return (*it);
+		}
 	}
-
 	return loadObjectType(i);
 }
 
-objectType *loadObjectType(int i) {
+ObjectType *ObjectManager::loadObjectType(int i) {
 	int a, nameNum;
-	objectType *newType = new objectType;
+	ObjectType *newType = new ObjectType;
+	ResourceManager *rm = _vm->_resMan;
 
 	if (checkNew(newType)) {
-		if (g_sludge->_resMan->openObjectSlice(i)) {
-			Common::SeekableReadStream *readStream = g_sludge->_resMan->getData();
+		if (rm->openObjectSlice(i)) {
+			Common::SeekableReadStream *readStream = rm->getData();
 			nameNum = readStream->readUint16BE();
 			newType->r = (byte)readStream->readByte();
 			newType->g = (byte)readStream->readByte();
@@ -79,7 +85,7 @@ objectType *loadObjectType(int i) {
 			}
 
 			newType->numCom = readStream->readUint16BE();
-			newType->allCombis = (newType->numCom) ? new combination[newType->numCom] : NULL;
+			newType->allCombis = (newType->numCom) ? new Combination[newType->numCom] : nullptr;
 
 
 			for (a = 0; a < newType->numCom; a++) {
@@ -87,33 +93,32 @@ objectType *loadObjectType(int i) {
 				newType->allCombis[a].funcNum = readStream->readUint16BE();
 			}
 
-			g_sludge->_resMan->finishAccess();
-			newType->screenName = g_sludge->_resMan->getNumberedString(nameNum);
+			rm->finishAccess();
+			newType->screenName = rm->getNumberedString(nameNum);
 			newType->objectNum = i;
-			newType->next = allObjectTypes;
-			allObjectTypes = newType;
+			_allObjectTypes.push_back(newType);
 			return newType;
 		}
 	}
 
-	return NULL;
+	return nullptr;
 }
 
-objectType *loadObjectRef(Common::SeekableReadStream *stream) {
-	objectType *r = loadObjectType(stream->readUint16BE());
+ObjectType *ObjectManager::loadObjectRef(Common::SeekableReadStream *stream) {
+	ObjectType *r = loadObjectType(stream->readUint16BE());
 	r->screenName.clear();
 	r->screenName = readString(stream);
 	return r;
 }
 
-void saveObjectRef(objectType *r, Common::WriteStream *stream) {
+void ObjectManager::saveObjectRef(ObjectType *r, Common::WriteStream *stream) {
 	stream->writeUint16BE(r->objectNum);
 	writeString(r->screenName, stream);
 }
 
-int getCombinationFunction(int withThis, int thisObject) {
+int ObjectManager::getCombinationFunction(int withThis, int thisObject) {
 	int i, num = 0;
-	objectType *obj = findObjectType(thisObject);
+	ObjectType *obj = findObjectType(thisObject);
 
 	for (i = 0; i < obj->numCom; i++) {
 		if (obj->allCombis[i].withObj == withThis) {
@@ -125,20 +130,11 @@ int getCombinationFunction(int withThis, int thisObject) {
 	return num;
 }
 
-void removeObjectType(objectType *oT) {
-	objectType **huntRegion = &allObjectTypes;
-
-	while (*huntRegion) {
-		if ((*huntRegion) == oT) {
-			*huntRegion = oT->next;
-			delete []oT->allCombis;
-			delete oT;
-			return;
-		} else {
-			huntRegion = &((*huntRegion)->next);
-		}
-	}
-	fatal("Can't delete object type: bad pointer");
+void ObjectManager::removeObjectType(ObjectType *oT) {
+	_allObjectTypes.remove(oT);
+	delete []oT->allCombis;
+	delete oT;
+	oT = nullptr;
 }
 
 } // End of namespace Sludge
diff --git a/engines/sludge/objtypes.h b/engines/sludge/objtypes.h
index 3958301..f0f5125 100644
--- a/engines/sludge/objtypes.h
+++ b/engines/sludge/objtypes.h
@@ -24,28 +24,41 @@
 
 namespace Sludge {
 
-struct combination {
+class SludgeEngine;
+
+struct Combination {
 	int withObj, funcNum;
 };
 
-struct objectType {
+struct ObjectType {
 	Common::String screenName;
 	int objectNum;
-	objectType *next;
 	byte r, g, b;
 	int numCom;
 	int speechGap, walkSpeed, wrapSpeech, spinSpeed;
 	uint16 flags;
-	combination *allCombis;
+	Combination *allCombis;
 };
 
-bool initObjectTypes();
-objectType *findObjectType(int i);
-objectType *loadObjectType(int i);
-int getCombinationFunction(int a, int b);
-void removeObjectType(objectType *oT);
-void saveObjectRef(objectType *r, Common::WriteStream *stream);
-objectType *loadObjectRef(Common::SeekableReadStream *stream);
+typedef Common::List<ObjectType *> ObjectTypeList;
+
+class ObjectManager {
+public:
+	ObjectManager(SludgeEngine *vm) : _vm(vm) {}
+	~ObjectManager();
+
+	bool initObjectTypes();
+	ObjectType *findObjectType(int i);
+	ObjectType *loadObjectType(int i);
+	int getCombinationFunction(int a, int b);
+	void removeObjectType(ObjectType *oT);
+	void saveObjectRef(ObjectType *r, Common::WriteStream *stream);
+	ObjectType *loadObjectRef(Common::SeekableReadStream *stream);
+
+private:
+	ObjectTypeList _allObjectTypes;
+	SludgeEngine *_vm;
+};
 
 } // End of namespace Sludge
 
diff --git a/engines/sludge/people.cpp b/engines/sludge/people.cpp
index 7d15086..ad5a234 100644
--- a/engines/sludge/people.cpp
+++ b/engines/sludge/people.cpp
@@ -34,6 +34,7 @@
 #include "sludge/loadsave.h"
 #include "sludge/floor.h"
 #include "sludge/zbuffer.h"
+#include "sludge/sludge.h"
 #include "sludge/sound.h"
 #include "sludge/version.h"
 
@@ -811,7 +812,7 @@ bool addPerson(int x, int y, int objNum, persona *p) {
 		return false;
 
 	// EASY STUFF
-	newPerson->thisType = loadObjectType(objNum);
+	newPerson->thisType = g_sludge->_objMan->loadObjectType(objNum);
 	newPerson->scale = 1;
 	newPerson->extra = 0;
 	newPerson->continueAfterWalking = NULL;
@@ -909,7 +910,7 @@ void killAllPeople() {
 		allPeople->continueAfterWalking = NULL;
 		killPeople = allPeople;
 		allPeople = allPeople->next;
-		removeObjectType(killPeople->thisType);
+		g_sludge->_objMan->removeObjectType(killPeople->thisType);
 		delete killPeople;
 	}
 }
@@ -931,7 +932,7 @@ void killMostPeople() {
 			if (killPeople->continueAfterWalking)
 				abortFunction(killPeople->continueAfterWalking);
 			killPeople->continueAfterWalking = NULL;
-			removeObjectType(killPeople->thisType);
+			g_sludge->_objMan->removeObjectType(killPeople->thisType);
 			delete killPeople;
 		}
 	}
@@ -955,7 +956,7 @@ void removeOneCharacter(int i) {
 		}
 
 		*killPeople = p->next;
-		removeObjectType(p->thisType);
+		g_sludge->_objMan->removeObjectType(p->thisType);
 		delete p;
 	}
 }
@@ -1089,7 +1090,7 @@ bool savePeople(Common::WriteStream *stream) {
 		stream->writeByte(me->colourmix);
 		stream->writeByte(me->transparency);
 
-		saveObjectRef(me->thisType, stream);
+		g_sludge->_objMan->saveObjectRef(me->thisType, stream);
 
 		me = me->next;
 	}
@@ -1171,7 +1172,7 @@ bool loadPeople(Common::SeekableReadStream *stream) {
 		} else {
 			setMyDrawMode(me, stream->readUint16BE());
 		}
-		me->thisType = loadObjectRef(stream);
+		me->thisType = g_sludge->_objMan->loadObjectRef(stream);
 
 		// Anti-aliasing settings
 		if (ssgVersion >= VERSION(1, 6)) {
diff --git a/engines/sludge/people.h b/engines/sludge/people.h
index 87f6170..f11ac2f 100644
--- a/engines/sludge/people.h
+++ b/engines/sludge/people.h
@@ -65,7 +65,7 @@ struct onScreenPerson {
 	int frameNum, frameTick, angle, wantAngle, angleOffset;
 	bool show;
 	int direction, directionWhenDoneWalking;
-	struct objectType *thisType;
+	struct ObjectType *thisType;
 	int extra, spinSpeed;
 	byte r, g, b, colourmix, transparency;
 };
diff --git a/engines/sludge/region.cpp b/engines/sludge/region.cpp
index e43cd57..9e81809 100644
--- a/engines/sludge/region.cpp
+++ b/engines/sludge/region.cpp
@@ -26,6 +26,7 @@
 #include "sludge/newfatal.h"
 #include "sludge/objtypes.h"
 #include "sludge/region.h"
+#include "sludge/sludge.h"
 #include "sludge/sludger.h"
 
 namespace Sludge {
@@ -55,7 +56,7 @@ void removeScreenRegion(int objectNum) {
 		if ((*huntRegion)->thisType->objectNum == objectNum) {
 			killMe = *huntRegion;
 			*huntRegion = killMe->next;
-			removeObjectType(killMe->thisType);
+			g_sludge->_objMan->removeObjectType(killMe->thisType);
 			if (killMe == overRegion)
 				overRegion = NULL;
 			delete killMe;
@@ -83,7 +84,7 @@ void saveRegions(Common::WriteStream *stream) {
 		stream->writeUint16BE(thisRegion->sX);
 		stream->writeUint16BE(thisRegion->sY);
 		stream->writeUint16BE(thisRegion->di);
-		saveObjectRef(thisRegion->thisType, stream);
+		g_sludge->_objMan->saveObjectRef(thisRegion->thisType, stream);
 
 		thisRegion = thisRegion->next;
 	}
@@ -107,7 +108,7 @@ void loadRegions(Common::SeekableReadStream *stream) {
 		newRegion->sX = stream->readUint16BE();
 		newRegion->sY = stream->readUint16BE();
 		newRegion->di = stream->readUint16BE();
-		newRegion->thisType = loadObjectRef(stream);
+		newRegion->thisType = g_sludge->_objMan->loadObjectRef(stream);
 	}
 	*pointy = NULL;
 }
@@ -117,7 +118,7 @@ void killAllRegions() {
 	while (allScreenRegions) {
 		killRegion = allScreenRegions;
 		allScreenRegions = allScreenRegions->next;
-		removeObjectType(killRegion->thisType);
+		g_sludge->_objMan->removeObjectType(killRegion->thisType);
 		delete killRegion;
 	}
 	overRegion = NULL;
@@ -135,7 +136,7 @@ bool addScreenRegion(int x1, int y1, int x2, int y2, int sX, int sY, int di,
 	newRegion->y2 = y2;
 	newRegion->sX = sX;
 	newRegion->sY = sY;
-	newRegion->thisType = loadObjectType(objectNum);
+	newRegion->thisType = g_sludge->_objMan->loadObjectType(objectNum);
 	newRegion->next = allScreenRegions;
 	allScreenRegions = newRegion;
 	return (bool) (newRegion->thisType != NULL);
diff --git a/engines/sludge/region.h b/engines/sludge/region.h
index 4cefd85..ce4157f 100644
--- a/engines/sludge/region.h
+++ b/engines/sludge/region.h
@@ -26,7 +26,7 @@ namespace Sludge {
 
 struct screenRegion {
 	int x1, y1, x2, y2, sX, sY, di;
-	objectType *thisType;
+	ObjectType *thisType;
 	screenRegion *next;
 };
 
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index ff62459..34992ae 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -64,6 +64,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
 	// Init managers
 	_resMan = new ResourceManager();
 	_languageMan = new LanguageManager();
+	_objMan = new ObjectManager(this);
 }
 
 SludgeEngine::~SludgeEngine() {
@@ -86,6 +87,8 @@ SludgeEngine::~SludgeEngine() {
 	_pixelFormat = nullptr;
 
 	// Dispose managers
+	delete _objMan;
+	_objMan = nullptr;
 	delete _languageMan;
 	_languageMan = nullptr;
 	delete _resMan;
diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h
index 8d41b5c..cb2a509 100644
--- a/engines/sludge/sludge.h
+++ b/engines/sludge/sludge.h
@@ -31,6 +31,7 @@
 #include "sludge/console.h"
 #include "sludge/fileset.h"
 #include "sludge/language.h"
+#include "sludge/objtypes.h"
 #include "sludge/timing.h"
 
 namespace Sludge {
@@ -70,6 +71,7 @@ public:
 	// managers
 	ResourceManager *_resMan;
 	LanguageManager *_languageMan;
+	ObjectManager *_objMan;
 
 	SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc);
 	virtual ~SludgeEngine();
diff --git a/engines/sludge/talk.cpp b/engines/sludge/talk.cpp
index e92cd00..bdfe431 100644
--- a/engines/sludge/talk.cpp
+++ b/engines/sludge/talk.cpp
@@ -29,6 +29,7 @@
 #include "sludge/sprbanks.h"
 #include "sludge/people.h"
 #include "sludge/talk.h"
+#include "sludge/sludge.h"
 #include "sludge/sound.h"
 #include "sludge/fonttext.h"
 #include "sludge/newfatal.h"
@@ -71,7 +72,7 @@ void killAllSpeech() {
 	}
 }
 
-inline void setObjFontColour(objectType *t) {
+inline void setObjFontColour(ObjectType *t) {
 	setFontColour(speech->talkCol, t->r, t->g, t->b);
 }
 
@@ -188,7 +189,7 @@ int wrapSpeech(const Common::String &theText, int objT, int sampleFile, bool ani
 					thisRegion->y1 - thisRegion->thisType->speechGap - cameraY,
 					thisRegion->thisType->wrapSpeech, sampleFile);
 		} else {
-			objectType *temp = findObjectType(objT);
+			ObjectType *temp = g_sludge->_objMan->findObjectType(objT);
 			setObjFontColour(temp);
 			i = wrapSpeechXY(theText, winWidth >> 1, 10, temp->wrapSpeech,
 					sampleFile);
diff --git a/engines/sludge/variable.cpp b/engines/sludge/variable.cpp
index b445095..5b03dad 100644
--- a/engines/sludge/variable.cpp
+++ b/engines/sludge/variable.cpp
@@ -310,7 +310,7 @@ Common::String getTextFromAnyVar(const variable &from) {
 		}
 
 		case SVT_OBJTYPE: {
-			objectType *thisType = findObjectType(from.varData.intValue);
+			ObjectType *thisType = g_sludge->_objMan->findObjectType(from.varData.intValue);
 			if (thisType)
 				return thisType->screenName;
 			break;


Commit: 0e7d9b4eb2c647843a24e090ff71678beb07716f
    https://github.com/scummvm/scummvm/commit/0e7d9b4eb2c647843a24e090ff71678beb07716f
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2017-07-20T00:43:16+02:00

Commit Message:
SLUDGE: Objectify parallex and create graphics manager

Changed paths:
  A engines/sludge/graphics.cpp
  A engines/sludge/graphics.h
    engines/sludge/backdrop.cpp
    engines/sludge/backdrop.h
    engines/sludge/builtin.cpp
    engines/sludge/freeze.cpp
    engines/sludge/freeze.h
    engines/sludge/loadsave.cpp
    engines/sludge/module.mk
    engines/sludge/sludge.cpp
    engines/sludge/sludge.h


diff --git a/engines/sludge/backdrop.cpp b/engines/sludge/backdrop.cpp
index 0f94f56..6fc4bc7 100644
--- a/engines/sludge/backdrop.cpp
+++ b/engines/sludge/backdrop.cpp
@@ -30,6 +30,7 @@
 #include "sludge/allfiles.h"
 #include "sludge/newfatal.h"
 #include "sludge/fileset.h"
+#include "sludge/graphics.h"
 #include "sludge/backdrop.h"
 #include "sludge/moreio.h"
 #include "sludge/statusba.h"
@@ -61,7 +62,6 @@ float snapTexH = 1.0;
 
 uint winWidth, winHeight;
 int lightMapMode = LIGHTMAPMODE_PIXEL;
-parallaxLayer *parallaxStuff = NULL;
 int cameraPX = 0, cameraPY = 0;
 
 uint sceneWidth, sceneHeight;
@@ -71,6 +71,121 @@ uint currentBlankColour = TS_ARGB(255, 0, 0, 0);
 extern int cameraX, cameraY;
 extern float cameraZoom;
 
+Parallax::~Parallax() {
+	kill();
+}
+
+void Parallax::kill() {
+	ParallaxLayers::iterator it;
+	for (it = _parallaxLayers.begin(); it != _parallaxLayers.end(); ++it) {
+		(*it)->surface.free();
+		delete (*it);
+		(*it) = nullptr;
+	}
+	_parallaxLayers.clear();
+}
+
+bool Parallax::add(uint16 v, uint16 fracX, uint16 fracY) {
+	setResourceForFatal(v);
+	if (!g_sludge->_resMan->openFileFromNum(v))
+		return fatal("Can't open parallax image");
+
+	ParallaxLayer *nP = new ParallaxLayer;
+	if (!checkNew(nP))
+		return false;
+
+	_parallaxLayers.push_back(nP);
+
+	if (!ImgLoader::loadImage(g_sludge->_resMan->getData(), &nP->surface, 0))
+		return false;
+
+	nP->fileNum = v;
+	nP->fractionX = fracX;
+	nP->fractionY = fracY;
+
+	// 65535 is the value of AUTOFIT constant in Sludge
+	if (fracX == 65535) {
+		nP->wrapS = false;
+		if (nP->surface.w < winWidth) {
+			fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen.");
+			return false;
+		}
+	} else {
+		nP->wrapS = true;
+	}
+
+	if (fracY == 65535) {
+		nP->wrapT = false;
+		if (nP->surface.h < winHeight) {
+			fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen.");
+			return false;
+		}
+	} else {
+		nP->wrapT = true;
+	}
+
+	// TODO: reinterpret this part
+#if 0
+	if (nP->wrapS)
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	else
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	if (nP->wrapT)
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	else
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#endif
+
+	g_sludge->_resMan->finishAccess();
+	setResourceForFatal(-1);
+	return true;
+}
+
+void Parallax::draw() {
+	// draw parallaxStuff
+	if (!_parallaxLayers.empty()) {
+		// TODO: simulate image repeating effect
+		warning("Drawing parallaxStuff");
+#if 0
+		// display parallax from bottom to top
+		ParallaxLayers::iterator it;
+		for (it = _parallax.begin(); it != _parallax.end(); ++it) {
+			(*it)->cameraX = sortOutPCamera(cameraX, (*it)->fractionX, (int)(sceneWidth - (float)winWidth / cameraZoom), (int)((*it)->surface.w - (float)winWidth / cameraZoom));
+			(*it)->cameraY = sortOutPCamera(cameraY, (*it)->fractionY, (int)(sceneHeight - (float)winHeight / cameraZoom), (int)((*it)->surface.h - (float)winHeight / cameraZoom));
+
+			uint w = ((*it)->wrapS) ? sceneWidth : (*it)->surface.w;
+			uint h = ((*it)->wrapT) ? sceneHeight : (*it)->surface.h;
+
+			const GLfloat vertices[] = {
+				(GLfloat) - (*it)->cameraX, (GLfloat) - (*it)->cameraY, 0.1f,
+				w - (*it)->cameraX, (GLfloat) - (*it)->cameraY, 0.1f,
+				(GLfloat) - (*it)->cameraX, h - (*it)->cameraY, 0.1f,
+				w - (*it)->cameraX, h - (*it)->cameraY, 0.1f
+			};
+
+			const GLfloat texCoords[] = {
+				0.0f, 0.0f,
+				texw, 0.0f,
+				0.0f, texh,
+				texw, texh
+			};
+			drawQuad(shader.smartScaler, vertices, 1, texCoords);
+
+		}
+#endif
+	}
+}
+
+void Parallax::save(Common::WriteStream *stream) {
+	ParallaxLayers::iterator it;
+	for (it = _parallaxLayers.begin(); it != _parallaxLayers.end(); ++it) {
+		stream->writeByte(1);
+		stream->writeUint16BE((*it)->fileNum);
+		stream->writeUint16BE((*it)->fractionX);
+		stream->writeUint16BE((*it)->fractionY);
+	}
+}
+
 void nosnapshot() {
 	if (snapshotSurface.getPixels())
 		snapshotSurface.free();
@@ -122,16 +237,6 @@ void killLightMap() {
 	lightMapNumber = 0;
 }
 
-void killParallax() {
-	while (parallaxStuff) {
-		parallaxLayer *k = parallaxStuff;
-		parallaxStuff = k->next;
-		k->surface.free();
-		delete k;
-		k = NULL;
-	}
-}
-
 bool reserveBackdrop() {
 	cameraX = 0;
 	cameraY = 0;
@@ -147,7 +252,7 @@ bool reserveBackdrop() {
 void killAllBackDrop() {
 	killLightMap();
 	killBackDrop();
-	killParallax();
+	g_sludge->_gfxMan->killParallax();
 	killZBuffer();
 }
 
@@ -265,44 +370,6 @@ void drawBackDrop() {
 
 	// TODO: apply lightmap shader
 
-	// draw parallaxStuff
-	if (parallaxStuff) {
-		// TODO: simulate image repeating effect
-		warning("Drawing parallaxStuff");
-#if 0
-		parallaxLayer *ps = parallaxStuff;
-
-		// go to the parallax at bottom
-		while (ps->next) ps = ps->next;
-
-		// draw parallax one by one
-		while (ps) {
-			ps->cameraX = sortOutPCamera(cameraX, ps->fractionX, (int)(sceneWidth - (float)winWidth / cameraZoom), (int)(ps->surface.w - (float)winWidth / cameraZoom));
-			ps->cameraY = sortOutPCamera(cameraY, ps->fractionY, (int)(sceneHeight - (float)winHeight / cameraZoom), (int)(ps->surface.h - (float)winHeight / cameraZoom));
-
-			uint w = (ps->wrapS) ? sceneWidth : ps->surface.w;
-			uint h = (ps->wrapT) ? sceneHeight : ps->surface.h;
-
-			const GLfloat vertices[] = {
-				(GLfloat) - ps->cameraX, (GLfloat) - ps->cameraY, 0.1f,
-				w - ps->cameraX, (GLfloat) - ps->cameraY, 0.1f,
-				(GLfloat) - ps->cameraX, h - ps->cameraY, 0.1f,
-				w - ps->cameraX, h - ps->cameraY, 0.1f
-			};
-
-			const GLfloat texCoords[] = {
-				0.0f, 0.0f,
-				texw, 0.0f,
-				0.0f, texh,
-				texw, texh
-			};
-			drawQuad(shader.smartScaler, vertices, 1, texCoords);
-
-			ps = ps->prev;
-		}
-#endif
-	}
-
 	// draw backdrop
 	Graphics::TransparentSurface tmp(backdropSurface, false);
 	tmp.blit(renderSurface, 0, 0);
@@ -331,67 +398,6 @@ bool loadLightMap(int v) {
 	return true;
 }
 
-bool loadParallax(uint16 v, uint16 fracX, uint16 fracY) {
-	setResourceForFatal(v);
-	if (!g_sludge->_resMan->openFileFromNum(v))
-		return fatal("Can't open parallax image");
-
-	parallaxLayer *nP = new parallaxLayer;
-	if (!checkNew(nP))
-		return false;
-
-	nP->next = parallaxStuff;
-	parallaxStuff = nP;
-	if (nP->next) {
-		nP->next->prev = nP;
-	}
-	nP->prev = NULL;
-
-	if (!ImgLoader::loadImage(g_sludge->_resMan->getData(), &nP->surface, 0))
-		return false;
-
-	nP->fileNum = v;
-	nP->fractionX = fracX;
-	nP->fractionY = fracY;
-
-	// 65535 is the value of AUTOFIT constant in Sludge
-	if (fracX == 65535) {
-		nP->wrapS = false;
-		if (nP->surface.w < winWidth) {
-			fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen.");
-			return false;
-		}
-	} else {
-		nP->wrapS = true;
-	}
-
-	if (fracY == 65535) {
-		nP->wrapT = false;
-		if (nP->surface.h < winHeight) {
-			fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen.");
-			return false;
-		}
-	} else {
-		nP->wrapT = true;
-	}
-
-	// TODO: reinterpret this part
-#if 0
-	if (nP->wrapS)
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-	else
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-	if (nP->wrapT)
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-	else
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#endif
-
-	g_sludge->_resMan->finishAccess();
-	setResourceForFatal(-1);
-	return true;
-}
-
 bool loadHSI(Common::SeekableReadStream *stream, int x, int y, bool reserve) {
 	debug(kSludgeDebugGraphics, "Load HSI");
 	if (reserve) {
@@ -452,15 +458,6 @@ void saveHSI(Common::WriteStream *stream) {
 	Image::writePNG(*stream, backdropSurface);
 }
 
-void saveParallaxRecursive(parallaxLayer *me, Common::WriteStream *stream) {
-	if (me) {
-		saveParallaxRecursive(me->next, stream);
-		stream->writeByte(1);
-		stream->writeUint16BE(me->fileNum);
-		stream->writeUint16BE(me->fractionX);
-		stream->writeUint16BE(me->fractionY);
-	}
-}
 
 bool getRGBIntoStack(uint x, uint y, stackHandler *sH) {
 	if (x >= sceneWidth || y >= sceneHeight) {
diff --git a/engines/sludge/backdrop.h b/engines/sludge/backdrop.h
index d239356..5c406f5 100644
--- a/engines/sludge/backdrop.h
+++ b/engines/sludge/backdrop.h
@@ -23,6 +23,8 @@
 #ifndef SLUDGE_BACKDROP_H
 #define SLUDGE_BACKDROP_H
 
+#include "common/stream.h"
+
 #include "graphics/surface.h"
 
 #include "sludge/variable.h"
@@ -35,24 +37,33 @@ enum {
 	LIGHTMAPMODE_PIXEL,
 	LIGHTMAPMODE_NUM
 };
-
 extern uint winWidth, winHeight, sceneWidth, sceneHeight;
 extern int lightMapMode;
 
-
 /**
  * parallax layers can scroll at different speeds
  * to the background image, giving the illusion of
  * depth to a scene as it moves.
  */
-struct parallaxLayer {
-	Graphics::Surface surface;
-	int speedX, speedY;
-	bool wrapS, wrapT;
-	uint16 fileNum, fractionX, fractionY;
-	int cameraX, cameraY;
-	parallaxLayer *next;
-	parallaxLayer *prev;
+class Parallax {
+public:
+	struct ParallaxLayer {
+		Graphics::Surface surface;
+		int speedX, speedY;
+		bool wrapS, wrapT;
+		uint16 fileNum, fractionX, fractionY;
+		int cameraX, cameraY;
+	};
+	typedef Common::List<ParallaxLayer *> ParallaxLayers;
+
+	~Parallax();
+
+	void kill();
+	bool add(uint16 v, uint16 fracX, uint16 fracY);
+	void save(Common::WriteStream *fp);
+	void draw();
+private:
+	ParallaxLayers _parallaxLayers;
 };
 
 void killAllBackDrop();
@@ -73,18 +84,11 @@ void hardScroll(int distance);
 bool getRGBIntoStack(uint x, uint y, stackHandler *sH);
 
 // Also the light map stuff
-
 void killLightMap();
 bool loadLightMap(int v);
 
 extern Graphics::Surface lightMap;
 
-// And background parallax scrolling
-
-void killParallax();
-bool loadParallax(uint16 v, uint16 fracX, uint16 fracY);
-void saveParallaxRecursive(parallaxLayer *me, Common::WriteStream *fp);
-
 void nosnapshot();
 bool snapshot();
 void saveSnapshot(Common::WriteStream *stream);
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index 7d5dadd..02c68c0 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -50,6 +50,7 @@
 #include "sludge/thumbnail.h"
 #include "sludge/sludge.h"
 #include "sludge/utf8.h"
+#include "sludge/graphics.h"
 
 namespace Sludge {
 
@@ -2358,7 +2359,7 @@ builtIn(parallaxAdd) {
 			return BR_ERROR;
 		trimStack(fun->stack);
 
-		if (!loadParallax(v, wrapX, wrapY))
+		if (!g_sludge->_gfxMan->loadParallax(v, wrapX, wrapY))
 			return BR_ERROR;
 		setVariable(fun->reg, SVT_INT, 1);
 	}
@@ -2367,7 +2368,7 @@ builtIn(parallaxAdd) {
 
 builtIn(parallaxClear) {
 	UNUSEDALL
-	killParallax();
+	g_sludge->_gfxMan->killParallax();
 	setVariable(fun->reg, SVT_INT, 1);
 	return BR_CONTINUE;
 }
diff --git a/engines/sludge/freeze.cpp b/engines/sludge/freeze.cpp
index 35dcd56..080ced6 100644
--- a/engines/sludge/freeze.cpp
+++ b/engines/sludge/freeze.cpp
@@ -33,6 +33,7 @@
 #include "sludge/fonttext.h"
 #include "sludge/statusba.h"
 #include "sludge/freeze.h"
+#include "sludge/graphics.h"
 #include "sludge/zbuffer.h"
 
 namespace Sludge {
@@ -44,7 +45,6 @@ extern speechStruct *speech;
 extern inputType input;
 extern Graphics::Surface backdropSurface;
 extern Graphics::Surface renderSurface;
-extern parallaxLayer *parallaxStuff;
 extern int lightMapNumber, zBufferNumber;
 extern eventHandlers *currentEvents;
 extern personaAnimation *mouseCursorAnim;
@@ -96,8 +96,8 @@ bool freeze() {
 	newFreezer->lightMapSurface.copyFrom(lightMap);
 	newFreezer->lightMapNumber = lightMapNumber;
 
-	newFreezer->parallaxStuff = parallaxStuff;
-	parallaxStuff = NULL;
+	newFreezer->parallaxStuff = g_sludge->_gfxMan->_parallaxStuff;
+	g_sludge->_gfxMan->_parallaxStuff = NULL;
 	newFreezer->zBufferSprites = zBuffer.sprites;
 	newFreezer->zBufferNumber = zBuffer.originalNum;
 	newFreezer->zPanels = zBuffer.numPanels;
@@ -196,8 +196,8 @@ void unfreeze(bool killImage) {
 		setZBuffer(zBuffer.originalNum);
 	}
 
-	killParallax();
-	parallaxStuff = frozenStuff->parallaxStuff;
+	g_sludge->_gfxMan->killParallax();
+	g_sludge->_gfxMan->_parallaxStuff = frozenStuff->parallaxStuff;
 
 	deleteAnim(mouseCursorAnim);
 	mouseCursorAnim = frozenStuff->mouseCursorAnim;
diff --git a/engines/sludge/freeze.h b/engines/sludge/freeze.h
index ae9cd6d..ad0d426 100644
--- a/engines/sludge/freeze.h
+++ b/engines/sludge/freeze.h
@@ -33,7 +33,7 @@ struct frozenStuffStruct {
 	Graphics::Surface lightMapSurface;
 	Graphics::Surface *zBufferSprites;
 	int zPanels;
-	parallaxLayer *parallaxStuff;
+	Parallax *parallaxStuff;
 	int lightMapNumber, zBufferNumber;
 	speechStruct *speech;
 	statusStuff *frozenStatus;
diff --git a/engines/sludge/graphics.cpp b/engines/sludge/graphics.cpp
new file mode 100644
index 0000000..93295b4
--- /dev/null
+++ b/engines/sludge/graphics.cpp
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sludge/backdrop.h"
+#include "sludge/graphics.h"
+
+namespace Sludge {
+
+GraphicsManager::GraphicsManager() {
+	_parallaxStuff = new Parallax;
+}
+
+GraphicsManager::~GraphicsManager() {
+	delete _parallaxStuff;
+	_parallaxStuff = nullptr;
+}
+
+bool GraphicsManager::loadParallax(uint16 v, uint16 fracX, uint16 fracY) {
+	if (!_parallaxStuff)
+		_parallaxStuff = new Parallax;
+	return _parallaxStuff->add(v, fracX, fracY);
+}
+
+void GraphicsManager::killParallax() {
+	if (!_parallaxStuff)
+		return;
+	_parallaxStuff->kill();
+}
+
+void GraphicsManager::saveParallax(Common::WriteStream *fp) {
+	if (_parallaxStuff)
+		_parallaxStuff->save(fp);
+}
+
+void GraphicsManager::drawParallax() {
+	if (_parallaxStuff)
+		_parallaxStuff->draw();
+}
+
+
+
+} // End of namespace Sludge
diff --git a/engines/sludge/graphics.h b/engines/sludge/graphics.h
new file mode 100644
index 0000000..d866d94
--- /dev/null
+++ b/engines/sludge/graphics.h
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SLUDGE_GRAPHICS_H
+#define SLUDGE_GRAPHICS_H
+
+namespace Sludge {
+
+class Parallax;
+
+class GraphicsManager {
+public:
+	GraphicsManager();
+	virtual ~GraphicsManager();
+
+	// Parallax
+	Parallax *_parallaxStuff;
+	bool loadParallax(uint16 v, uint16 fracX, uint16 fracY);
+	void killParallax();
+	void saveParallax(Common::WriteStream *fp);
+	void drawParallax();
+};
+
+} // End of namespace Sludge
+
+
+#endif // SLUDGE_GRAPHICS_H
diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp
index 0ddb71c..48fcfc3 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -46,6 +46,7 @@
 #include "sludge/thumbnail.h"
 #include "sludge/utf8.h"
 #include "sludge/version.h"
+#include "sludge/graphics.h"
 
 namespace Sludge {
 
@@ -78,7 +79,6 @@ extern bool allowAnyFilename;
 extern uint16 saveEncoding;                 // in savedata.cpp
 extern byte currentBurnR, currentBurnG, currentBurnB;
 extern uint currentBlankColour;             // in backdrop.cpp
-extern parallaxLayer *parallaxStuff;                //      "
 extern int lightMapMode;                    //      "
 
 //----------------------------------------------------------------------
@@ -460,7 +460,7 @@ bool saveGame(const Common::String &fname) {
 	fp->writeByte(currentBurnG);
 	fp->writeByte(currentBurnB);
 
-	saveParallaxRecursive(parallaxStuff, fp);
+	g_sludge->_gfxMan->saveParallax(fp);
 	fp->writeByte(0);
 
 	g_sludge->_languageMan->saveLanguageSetting(fp);
@@ -658,7 +658,7 @@ bool loadGame(const Common::String &fname) {
 			int fx = fp->readUint16BE();
 			int fy = fp->readUint16BE();
 
-			if (!loadParallax(im, fx, fy))
+			if (!g_sludge->_gfxMan->loadParallax(im, fx, fy))
 				return false;
 		}
 
diff --git a/engines/sludge/module.mk b/engines/sludge/module.mk
index 491b17d..ce45549 100644
--- a/engines/sludge/module.mk
+++ b/engines/sludge/module.mk
@@ -11,6 +11,7 @@ MODULE_OBJS := \
 	floor.o \
 	freeze.o \
 	fonttext.o \
+	graphics.o \
 	helpers.o \
 	hsi.o \
 	imgloader.o \
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index 34992ae..4c6c54d 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -25,6 +25,7 @@
 #include "common/debug-channels.h"
 #include "common/error.h"
 
+#include "sludge/graphics.h"
 #include "sludge/sludge.h"
 #include "sludge/main_loop.h"
 
@@ -65,6 +66,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
 	_resMan = new ResourceManager();
 	_languageMan = new LanguageManager();
 	_objMan = new ObjectManager(this);
+	_gfxMan = new GraphicsManager();
 }
 
 SludgeEngine::~SludgeEngine() {
@@ -87,6 +89,8 @@ SludgeEngine::~SludgeEngine() {
 	_pixelFormat = nullptr;
 
 	// Dispose managers
+	delete _gfxMan;
+	_gfxMan = nullptr;
 	delete _objMan;
 	_objMan = nullptr;
 	delete _languageMan;
diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h
index cb2a509..78cf1df 100644
--- a/engines/sludge/sludge.h
+++ b/engines/sludge/sludge.h
@@ -38,6 +38,7 @@ namespace Sludge {
 
 extern SludgeEngine *g_sludge;
 
+class GraphicsManager;
 class SludgeConsole;
 
 struct SludgeGameDescription;
@@ -72,6 +73,7 @@ public:
 	ResourceManager *_resMan;
 	LanguageManager *_languageMan;
 	ObjectManager *_objMan;
+	GraphicsManager *_gfxMan;
 
 	SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc);
 	virtual ~SludgeEngine();


Commit: e617a53608976062073694a0847335a7ea74469e
    https://github.com/scummvm/scummvm/commit/e617a53608976062073694a0847335a7ea74469e
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2017-07-20T00:43:16+02:00

Commit Message:
SLUDGE: Objectify graphic classes

Changed paths:
    engines/sludge/backdrop.cpp
    engines/sludge/backdrop.h
    engines/sludge/builtin.cpp
    engines/sludge/builtin.h
    engines/sludge/cursors.cpp
    engines/sludge/floor.cpp
    engines/sludge/fonttext.cpp
    engines/sludge/fonttext.h
    engines/sludge/freeze.cpp
    engines/sludge/freeze.h
    engines/sludge/graphics.cpp
    engines/sludge/graphics.h
    engines/sludge/loadsave.cpp
    engines/sludge/main_loop.cpp
    engines/sludge/people.cpp
    engines/sludge/people.h
    engines/sludge/region.cpp
    engines/sludge/sludge.cpp
    engines/sludge/sludger.cpp
    engines/sludge/sprbanks.cpp
    engines/sludge/sprbanks.h
    engines/sludge/sprites.cpp
    engines/sludge/sprites.h
    engines/sludge/statusba.cpp
    engines/sludge/talk.cpp
    engines/sludge/talk.h
    engines/sludge/zbuffer.cpp
    engines/sludge/zbuffer.h


diff --git a/engines/sludge/backdrop.cpp b/engines/sludge/backdrop.cpp
index 6fc4bc7..5236ab3 100644
--- a/engines/sludge/backdrop.cpp
+++ b/engines/sludge/backdrop.cpp
@@ -39,37 +39,16 @@
 #include "sludge/sludge.h"
 #include "sludge/sludger.h"
 #include "sludge/variable.h"
+#include "sludge/version.h"
 #include "sludge/imgloader.h"
 
 namespace Sludge {
 
 extern inputType input;
-extern Graphics::Surface renderSurface;
 
-bool freeze();
-void unfreeze(bool);    // Because FREEZE.H needs a load of other includes
-
-bool backdropExists = false;
-extern int zBufferToSet;
-
-Graphics::Surface lightMap;
-Graphics::Surface OrigBackdropSurface;
-Graphics::Surface backdropSurface;
-Graphics::Surface snapshotSurface;
-
-float snapTexW = 1.0;
-float snapTexH = 1.0;
-
-uint winWidth, winHeight;
-int lightMapMode = LIGHTMAPMODE_PIXEL;
-int cameraPX = 0, cameraPY = 0;
-
-uint sceneWidth, sceneHeight;
-int lightMapNumber;
-uint currentBlankColour = TS_ARGB(255, 0, 0, 0);
-
-extern int cameraX, cameraY;
-extern float cameraZoom;
+Parallax::Parallax() {
+	_parallaxLayers.clear();
+}
 
 Parallax::~Parallax() {
 	kill();
@@ -106,20 +85,20 @@ bool Parallax::add(uint16 v, uint16 fracX, uint16 fracY) {
 	// 65535 is the value of AUTOFIT constant in Sludge
 	if (fracX == 65535) {
 		nP->wrapS = false;
-		if (nP->surface.w < winWidth) {
-			fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen.");
-			return false;
-		}
+//		if (nP->surface.w < _winWidth) {
+//			fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen.");
+//			return false;
+//		}
 	} else {
 		nP->wrapS = true;
 	}
 
 	if (fracY == 65535) {
 		nP->wrapT = false;
-		if (nP->surface.h < winHeight) {
-			fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen.");
-			return false;
-		}
+//		if (nP->surface.h < _winHeight) {
+//			fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen.");
+//			return false;
+//		}
 	} else {
 		nP->wrapT = true;
 	}
@@ -186,21 +165,21 @@ void Parallax::save(Common::WriteStream *stream) {
 	}
 }
 
-void nosnapshot() {
-	if (snapshotSurface.getPixels())
-		snapshotSurface.free();
+void GraphicsManager::nosnapshot() {
+	if (_snapshotSurface.getPixels())
+		_snapshotSurface.free();
 }
 
-void saveSnapshot(Common::WriteStream *stream) {
-	if (snapshotSurface.getPixels()) {
+void GraphicsManager::saveSnapshot(Common::WriteStream *stream) {
+	if (_snapshotSurface.getPixels()) {
 		stream->writeByte(1);               // 1 for snapshot follows
-		Image::writePNG(*stream, snapshotSurface);
+		Image::writePNG(*stream, _snapshotSurface);
 	} else {
 		stream->writeByte(0);
 	}
 }
 
-bool snapshot() {
+bool GraphicsManager::snapshot() {
 	nosnapshot();
 	if (!freeze())
 		return false;
@@ -211,63 +190,63 @@ bool snapshot() {
 	drawStatusBar();
 
 	// copy backdrop to snapshot
-	snapshotSurface.copyFrom(backdropSurface);
+	_snapshotSurface.copyFrom(_backdropSurface);
 
 	unfreeze(false);
 	return true;
 }
 
-bool restoreSnapshot(Common::SeekableReadStream *stream) {
-	if (!(ImgLoader::loadImage(stream, &snapshotSurface))) {
+bool GraphicsManager::restoreSnapshot(Common::SeekableReadStream *stream) {
+	if (!(ImgLoader::loadImage(stream, &_snapshotSurface))) {
 		return false;
 	}
 	return true;
 }
 
-void killBackDrop() {
-	if (backdropSurface.getPixels())
-		backdropSurface.free();
-	backdropExists = false;
+void GraphicsManager::killBackDrop() {
+	if (_backdropSurface.getPixels())
+		_backdropSurface.free();
+	_backdropExists = false;
 }
 
-void killLightMap() {
-	if (lightMap.getPixels()) {
-		lightMap.free();
+void GraphicsManager::killLightMap() {
+	if (_lightMap.getPixels()) {
+		_lightMap.free();
 	}
-	lightMapNumber = 0;
+	_lightMapNumber = 0;
 }
 
-bool reserveBackdrop() {
-	cameraX = 0;
-	cameraY = 0;
-	input.mouseX = (int)((float)input.mouseX * cameraZoom);
-	input.mouseY = (int)((float)input.mouseY * cameraZoom);
-	cameraZoom = 1.0;
-	input.mouseX = (int)((float)input.mouseX / cameraZoom);
-	input.mouseY = (int)((float)input.mouseY / cameraZoom);
+bool GraphicsManager::reserveBackdrop() {
+	_cameraX = 0;
+	_cameraY = 0;
+	input.mouseX = (int)((float)input.mouseX * _cameraZoom);
+	input.mouseY = (int)((float)input.mouseY * _cameraZoom);
+	_cameraZoom = 1.0;
+	input.mouseX = (int)((float)input.mouseX / _cameraZoom);
+	input.mouseY = (int)((float)input.mouseY / _cameraZoom);
 
 	return true;
 }
 
-void killAllBackDrop() {
+void GraphicsManager::killAllBackDrop() {
 	killLightMap();
 	killBackDrop();
 	g_sludge->_gfxMan->killParallax();
 	killZBuffer();
 }
 
-bool resizeBackdrop(int x, int y) {
-	sceneWidth = x;
-	sceneHeight = y;
+bool GraphicsManager::resizeBackdrop(int x, int y) {
+	_sceneWidth = x;
+	_sceneHeight = y;
 	return reserveBackdrop();
 }
 
-bool killResizeBackdrop(int x, int y) {
+bool GraphicsManager::killResizeBackdrop(int x, int y) {
 	killAllBackDrop();
 	return resizeBackdrop(x, y);
 }
 
-void loadBackDrop(int fileNum, int x, int y) {
+void GraphicsManager::loadBackDrop(int fileNum, int x, int y) {
 	debug(kSludgeDebugGraphics, "Load back drop");
 	setResourceForFatal(fileNum);
 	if (!g_sludge->_resMan->openFileFromNum(fileNum)) {
@@ -276,7 +255,7 @@ void loadBackDrop(int fileNum, int x, int y) {
 	}
 
 	if (!loadHSI(g_sludge->_resMan->getData(), x, y, false)) {
-		Common::String mess = Common::String::format("Can't paste overlay image outside scene dimensions\n\nX = %i\nY = %i\nWidth = %i\nHeight = %i", x, y, sceneWidth, sceneHeight);
+		Common::String mess = Common::String::format("Can't paste overlay image outside scene dimensions\n\nX = %i\nY = %i\nWidth = %i\nHeight = %i", x, y, _sceneWidth, _sceneHeight);
 		fatal(mess);
 	}
 
@@ -284,13 +263,13 @@ void loadBackDrop(int fileNum, int x, int y) {
 	setResourceForFatal(-1);
 
 	// set zBuffer if it's not set
-	if (zBufferToSet >= 0) {
-		setZBuffer(zBufferToSet);
-		zBufferToSet = -1;
+	if (_zBufferToSet >= 0) {
+		setZBuffer(_zBufferToSet);
+		_zBufferToSet = -1;
 	}
 }
 
-void mixBackDrop(int fileNum, int x, int y) {
+void GraphicsManager::mixBackDrop(int fileNum, int x, int y) {
 	setResourceForFatal(fileNum);
 	if (!g_sludge->_resMan->openFileFromNum(fileNum)) {
 		fatal("Can't load overlay image");
@@ -305,9 +284,9 @@ void mixBackDrop(int fileNum, int x, int y) {
 	setResourceForFatal(-1);
 }
 
-void blankScreen(int x1, int y1, int x2, int y2) {
+void GraphicsManager::blankScreen(int x1, int y1, int x2, int y2) {
 	// in case of no backdrop added at all
-	if (!backdropSurface.getPixels()) {
+	if (!_backdropSurface.getPixels()) {
 		return;
 	}
 
@@ -315,79 +294,83 @@ void blankScreen(int x1, int y1, int x2, int y2) {
 		y1 = 0;
 	if (x1 < 0)
 		x1 = 0;
-	if (x2 > (int)sceneWidth)
-		x2 = (int)sceneWidth;
-	if (y2 > (int)sceneHeight)
-		y2 = (int)sceneHeight;
+	if (x2 > (int)_sceneWidth)
+		x2 = (int)_sceneWidth;
+	if (y2 > (int)_sceneHeight)
+		y2 = (int)_sceneHeight;
 
-	backdropSurface.fillRect(Common::Rect(x1, y1, x2, y2), currentBlankColour);
+	_backdropSurface.fillRect(Common::Rect(x1, y1, x2, y2), _currentBlankColour);
+}
+
+void GraphicsManager::blankAllScreen() {
+	blankScreen(0, 0, _sceneWidth, _sceneHeight);
 }
 
 // This function is very useful for scrolling credits, but very little else
-void hardScroll(int distance) {
+void GraphicsManager::hardScroll(int distance) {
 	// scroll 0 distance, return
 	if (!distance)
 		return;
 
 	// blank screen
-	blankScreen(0, 0, sceneWidth, sceneHeight);
+	blankAllScreen();
 
 	// scroll more than backdrop height, screen stay blank
-	if (ABS(distance) >= (int)sceneHeight) {
+	if (ABS(distance) >= (int)_sceneHeight) {
 		return;
 	}
 
 	// copy part of the backdrop to it
 	if (distance > 0) {
-		backdropSurface.copyRectToSurface(OrigBackdropSurface, 0, 0,
-				Common::Rect(0, distance, backdropSurface.w, backdropSurface.h));
+		_backdropSurface.copyRectToSurface(_origBackdropSurface, 0, 0,
+				Common::Rect(0, distance, _backdropSurface.w, _backdropSurface.h));
 	} else {
-		backdropSurface.copyRectToSurface(OrigBackdropSurface, 0, -distance,
-				Common::Rect(0, 0, backdropSurface.w, backdropSurface.h + distance));
+		_backdropSurface.copyRectToSurface(_origBackdropSurface, 0, -distance,
+				Common::Rect(0, 0, _backdropSurface.w, _backdropSurface.h + distance));
 	}
 }
 
-void drawVerticalLine(uint x, uint y1, uint y2) {
-	backdropSurface.drawLine(x, y1, x, y2, backdropSurface.format.ARGBToColor(255, 0, 0, 0));
+void GraphicsManager::drawLine(uint x1, uint y1, uint x2, uint y2) {
+	_backdropSurface.drawLine(x1, y1, x2, y2, _backdropSurface.format.ARGBToColor(255, 0, 0, 0));
 }
 
-void drawHorizontalLine(uint x1, uint y, uint x2) {
-	backdropSurface.drawLine(x1, y, x2, y, backdropSurface.format.ARGBToColor(255, 0, 0, 0));
+void GraphicsManager::drawVerticalLine(uint x, uint y1, uint y2) {
+	drawLine(x, y1, x, y2);
 }
 
-void darkScreen() {
-	Graphics::TransparentSurface tmp(backdropSurface, false);
-	tmp.blit(backdropSurface, 0, 0, Graphics::FLIP_NONE, nullptr, TS_ARGB(0, 255 >> 1, 0, 0));
+void GraphicsManager::drawHorizontalLine(uint x1, uint y, uint x2) {
+	drawLine(x1, y, x2, y);
 }
 
-inline int sortOutPCamera(int cX, int fX, int sceneMax, int boxMax) {
-	return (fX == 65535) ? (sceneMax ? ((cX * boxMax) / sceneMax) : 0) : ((cX * fX) / 100);
+void GraphicsManager::darkScreen() {
+	Graphics::TransparentSurface tmp(_backdropSurface, false);
+	tmp.blit(_backdropSurface, 0, 0, Graphics::FLIP_NONE, nullptr, TS_ARGB(0, 255 >> 1, 0, 0));
 }
 
-void drawBackDrop() {
-	if (!backdropExists)
-		return;
-
+void GraphicsManager::drawBackDrop() {
 	// TODO: apply lightmap shader
+	drawParallax();
 
+	if (!_backdropExists)
+		return;
 	// draw backdrop
-	Graphics::TransparentSurface tmp(backdropSurface, false);
-	tmp.blit(renderSurface, 0, 0);
+	Graphics::TransparentSurface tmp(_backdropSurface, false);
+	tmp.blit(_renderSurface, 0, 0);
 }
 
-bool loadLightMap(int v) {
+bool GraphicsManager::loadLightMap(int v) {
 	setResourceForFatal(v);
 	if (!g_sludge->_resMan->openFileFromNum(v))
 		return fatal("Can't open light map.");
 
 	killLightMap();
-	lightMapNumber = v;
+	_lightMapNumber = v;
 
-	if (!ImgLoader::loadImage(g_sludge->_resMan->getData(), &lightMap))
+	if (!ImgLoader::loadImage(g_sludge->_resMan->getData(), &_lightMap))
 		return false;
 
-	if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
-		if (lightMap.w != sceneWidth || lightMap.h != sceneHeight) {
+	if (_lightMapMode == LIGHTMAPMODE_HOTSPOT) {
+		if (_lightMap.w != _sceneWidth || _lightMap.h != _sceneHeight) {
 			return fatal("Light map width and height don't match scene width and height. That is required for lightmaps in HOTSPOT mode.");
 		}
 	}
@@ -398,17 +381,40 @@ bool loadLightMap(int v) {
 	return true;
 }
 
-bool loadHSI(Common::SeekableReadStream *stream, int x, int y, bool reserve) {
+void GraphicsManager::saveLightMap(Common::WriteStream *stream) {
+	if (_lightMap.getPixels()) {
+		stream->writeByte(1);
+		stream->writeUint16BE(_lightMapNumber);
+	} else {
+		stream->writeByte(0);
+	}
+	stream->writeByte(_lightMapMode);
+}
+
+bool GraphicsManager::loadLightMap(int ssgVersion, Common::SeekableReadStream *stream) {
+	if (stream->readByte()) {
+		if (!loadLightMap(stream->readUint16BE()))
+			return false;
+	}
+
+	if (ssgVersion >= VERSION(1, 4)) {
+		_lightMapMode = stream->readByte() % 3;
+	}
+
+	return true;
+}
+
+bool GraphicsManager::loadHSI(Common::SeekableReadStream *stream, int x, int y, bool reserve) {
 	debug(kSludgeDebugGraphics, "Load HSI");
 	if (reserve) {
 		killAllBackDrop(); // kill all
 	}
 
-	if (!ImgLoader::loadImage(stream, &backdropSurface, (int)reserve))
+	if (!ImgLoader::loadImage(stream, &_backdropSurface, (int)reserve))
 		return false;
 
-	uint realPicWidth = backdropSurface.w;
-	uint realPicHeight = backdropSurface.h;
+	uint realPicWidth = _backdropSurface.w;
+	uint realPicHeight = _backdropSurface.h;
 
 	// resize backdrop
 	if (reserve) {
@@ -417,21 +423,21 @@ bool loadHSI(Common::SeekableReadStream *stream, int x, int y, bool reserve) {
 	}
 
 	if (x == IN_THE_CENTRE)
-		x = (sceneWidth - realPicWidth) >> 1;
+		x = (_sceneWidth - realPicWidth) >> 1;
 	if (y == IN_THE_CENTRE)
-		y = (sceneHeight - realPicHeight) >> 1;
-	if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight) {
+		y = (_sceneHeight - realPicHeight) >> 1;
+	if (x < 0 || x + realPicWidth > _sceneWidth || y < 0 || y + realPicHeight > _sceneHeight) {
 		debug(kSludgeDebugGraphics, "Illegal back drop size");
 		return false;
 	}
 
-	OrigBackdropSurface.copyFrom(backdropSurface);
-	backdropExists = true;
+	_origBackdropSurface.copyFrom(_backdropSurface);
+	_backdropExists = true;
 
 	return true;
 }
 
-bool mixHSI(Common::SeekableReadStream *stream, int x, int y) {
+bool GraphicsManager::mixHSI(Common::SeekableReadStream *stream, int x, int y) {
 	debug(kSludgeDebugGraphics, "Load mixHSI");
 	Graphics::Surface mixSurface;
 	if (!ImgLoader::loadImage(stream, &mixSurface, 0))
@@ -441,26 +447,26 @@ bool mixHSI(Common::SeekableReadStream *stream, int x, int y) {
 	uint realPicHeight = mixSurface.h;
 
 	if (x == IN_THE_CENTRE)
-		x = (sceneWidth - realPicWidth) >> 1;
+		x = (_sceneWidth - realPicWidth) >> 1;
 	if (y == IN_THE_CENTRE)
-		y = (sceneHeight - realPicHeight) >> 1;
-	if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight)
+		y = (_sceneHeight - realPicHeight) >> 1;
+	if (x < 0 || x + realPicWidth > _sceneWidth || y < 0 || y + realPicHeight > _sceneHeight)
 		return false;
 
 	Graphics::TransparentSurface tmp(mixSurface, false);
-	tmp.blit(backdropSurface, x, y, Graphics::FLIP_NONE, nullptr, TS_ARGB(255, 255 >> 1, 255, 255));
+	tmp.blit(_backdropSurface, x, y, Graphics::FLIP_NONE, nullptr, TS_ARGB(255, 255 >> 1, 255, 255));
 	mixSurface.free();
 
 	return true;
 }
 
-void saveHSI(Common::WriteStream *stream) {
-	Image::writePNG(*stream, backdropSurface);
+void GraphicsManager::saveHSI(Common::WriteStream *stream) {
+	Image::writePNG(*stream, _backdropSurface);
 }
 
 
-bool getRGBIntoStack(uint x, uint y, stackHandler *sH) {
-	if (x >= sceneWidth || y >= sceneHeight) {
+bool GraphicsManager::getRGBIntoStack(uint x, uint y, stackHandler *sH) {
+	if (x >= _sceneWidth || y >= _sceneHeight) {
 		return fatal("Co-ordinates are outside current scene!");
 	}
 
@@ -468,7 +474,7 @@ bool getRGBIntoStack(uint x, uint y, stackHandler *sH) {
 
 	newValue.varType = SVT_NULL;
 
-	byte *target = (byte *)renderSurface.getBasePtr(x, y);
+	byte *target = (byte *)_renderSurface.getBasePtr(x, y);
 
 	setVariable(newValue, SVT_INT, target[1]);
 	if (!addVarToStackQuick(newValue, sH->first)) return false;
diff --git a/engines/sludge/backdrop.h b/engines/sludge/backdrop.h
index 5c406f5..d97f71e 100644
--- a/engines/sludge/backdrop.h
+++ b/engines/sludge/backdrop.h
@@ -31,15 +31,6 @@
 
 namespace Sludge {
 
-enum {
-	LIGHTMAPMODE_NONE = -1,
-	LIGHTMAPMODE_HOTSPOT,
-	LIGHTMAPMODE_PIXEL,
-	LIGHTMAPMODE_NUM
-};
-extern uint winWidth, winHeight, sceneWidth, sceneHeight;
-extern int lightMapMode;
-
 /**
  * parallax layers can scroll at different speeds
  * to the background image, giving the illusion of
@@ -56,6 +47,7 @@ public:
 	};
 	typedef Common::List<ParallaxLayer *> ParallaxLayers;
 
+	Parallax();
 	~Parallax();
 
 	void kill();
@@ -64,35 +56,11 @@ public:
 	void draw();
 private:
 	ParallaxLayers _parallaxLayers;
-};
-
-void killAllBackDrop();
-bool resizeBackdrop(int x, int y);
-bool killResizeBackdrop(int x, int y);
-void killBackDrop();
-void loadBackDrop(int fileNum, int x, int y);
-void mixBackDrop(int fileNum, int x, int y);
-void drawBackDrop();
-void blankScreen(int x1, int y1, int x2, int y2);
-void darkScreen();
-void saveHSI(Common::WriteStream *stream);
-bool loadHSI(Common::SeekableReadStream *stream, int, int, bool);
-bool mixHSI(Common::SeekableReadStream *stream, int x = 0, int y = 0);
-void drawHorizontalLine(uint, uint, uint);
-void drawVerticalLine(uint, uint, uint);
-void hardScroll(int distance);
-bool getRGBIntoStack(uint x, uint y, stackHandler *sH);
 
-// Also the light map stuff
-void killLightMap();
-bool loadLightMap(int v);
-
-extern Graphics::Surface lightMap;
-
-void nosnapshot();
-bool snapshot();
-void saveSnapshot(Common::WriteStream *stream);
-bool restoreSnapshot(Common::SeekableReadStream *stream);
+	inline int sortOutPCamera(int cX, int fX, int sceneMax, int boxMax) {
+		return (fX == 65535) ? (sceneMax ? ((cX * boxMax) / sceneMax) : 0) : ((cX * fX) / 100);
+	}
+};
 
 } // End of namespace Sludge
 
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index 02c68c0..61ee353 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -55,9 +55,7 @@
 namespace Sludge {
 
 int speechMode = 0;
-int cameraX, cameraY;
-float cameraZoom = 1.0;
-spritePalette pastePalette;
+SpritePalette pastePalette;
 
 variable *launchResult = NULL;
 
@@ -69,7 +67,6 @@ extern eventHandlers *currentEvents;
 extern variableStack *noStack;
 extern statusStuff *nowStatus;
 extern screenRegion *overRegion;
-extern uint sceneWidth, sceneHeight;
 extern int numBIFNames, numUserFunc;
 
 extern Common::String *allUserFunc;
@@ -80,8 +77,6 @@ extern float speechSpeed;
 extern byte brightnessLevel;
 extern byte fadeMode;
 extern uint16 saveEncoding;
-extern frozenStuffStruct *frozenStuff;
-extern uint currentBlankColour;
 extern byte currentBurnR, currentBurnG, currentBurnB;
 
 int paramNum[] = { -1, 0, 1, 1, -1, -1, 1, 3, 4, 1, 0, 0, 8, -1,    // SAY->MOVEMOUSE
@@ -186,7 +181,7 @@ builtIn(think) {
 
 builtIn(freeze) {
 	UNUSEDALL
-	freeze();
+	g_sludge->_gfxMan->freeze();
 	freezeSubs();
 	fun->freezerLevel = 0;
 	return BR_CONTINUE;
@@ -194,14 +189,14 @@ builtIn(freeze) {
 
 builtIn(unfreeze) {
 	UNUSEDALL
-	unfreeze();
+	g_sludge->_gfxMan->unfreeze();
 	unfreezeSubs();
 	return BR_CONTINUE;
 }
 
 builtIn(howFrozen) {
 	UNUSEDALL
-	setVariable(fun->reg, SVT_INT, howFrozen());
+	setVariable(fun->reg, SVT_INT, g_sludge->_gfxMan->howFrozen());
 	return BR_CONTINUE;
 }
 
@@ -215,25 +210,25 @@ builtIn(setCursor) {
 
 builtIn(getMouseX) {
 	UNUSEDALL
-	setVariable(fun->reg, SVT_INT, input.mouseX + cameraX);
+	setVariable(fun->reg, SVT_INT, input.mouseX + g_sludge->_gfxMan->getCamX());
 	return BR_CONTINUE;
 }
 
 builtIn(getMouseY) {
 	UNUSEDALL
-	setVariable(fun->reg, SVT_INT, input.mouseY + cameraY);
+	setVariable(fun->reg, SVT_INT, input.mouseY + g_sludge->_gfxMan->getCamY());
 	return BR_CONTINUE;
 }
 
 builtIn(getMouseScreenX) {
 	UNUSEDALL
-	setVariable(fun->reg, SVT_INT, input.mouseX * cameraZoom);
+	setVariable(fun->reg, SVT_INT, input.mouseX * g_sludge->_gfxMan->getCamZoom());
 	return BR_CONTINUE;
 }
 
 builtIn(getMouseScreenY) {
 	UNUSEDALL
-	setVariable(fun->reg, SVT_INT, input.mouseY * cameraZoom);
+	setVariable(fun->reg, SVT_INT, input.mouseY * g_sludge->_gfxMan->getCamZoom());
 	return BR_CONTINUE;
 }
 
@@ -265,7 +260,7 @@ builtIn(getMatchingFiles) {
 builtIn(saveGame) {
 	UNUSEDALL
 
-	if (frozenStuff) {
+	if (g_sludge->_gfxMan->isFrozen()) {
 		fatal("Can't save game state while the engine is frozen");
 	}
 
@@ -326,7 +321,7 @@ builtIn(loadGame) {
 	g_sludge->loadNow.clear();
 	g_sludge->loadNow = encodeFilename(aaaaa);
 
-	if (frozenStuff) {
+	if (g_sludge->_gfxMan->isFrozen()) {
 		fatal("Can't load a saved game while the engine is frozen");
 	}
 	if (failSecurityCheck(g_sludge->loadNow))
@@ -348,7 +343,7 @@ builtIn(loadGame) {
 
 builtIn(blankScreen) {
 	UNUSEDALL
-	blankScreen(0, 0, sceneWidth, sceneHeight);
+	g_sludge->_gfxMan->blankAllScreen();
 	return BR_CONTINUE;
 }
 
@@ -367,13 +362,13 @@ builtIn(blankArea) {
 	if (!getValueType(x1, SVT_INT, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	blankScreen(x1, y1, x2, y2);
+	g_sludge->_gfxMan->blankScreen(x1, y1, x2, y2);
 	return BR_CONTINUE;
 }
 
 builtIn(darkBackground) {
 	UNUSEDALL
-	darkScreen();
+	g_sludge->_gfxMan->darkScreen();
 	return BR_CONTINUE;
 }
 
@@ -389,7 +384,7 @@ builtIn(addOverlay) {
 	if (!getValueType(fileNumber, SVT_FILE, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	loadBackDrop(fileNumber, xPos, yPos);
+	g_sludge->_gfxMan->loadBackDrop(fileNumber, xPos, yPos);
 	return BR_CONTINUE;
 }
 
@@ -405,7 +400,7 @@ builtIn(mixOverlay) {
 	if (!getValueType(fileNumber, SVT_FILE, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	mixBackDrop(fileNumber, xPos, yPos);
+	g_sludge->_gfxMan->mixBackDrop(fileNumber, xPos, yPos);
 	return BR_CONTINUE;
 }
 
@@ -439,8 +434,8 @@ builtIn(setSceneDimensions) {
 	if (!getValueType(x, SVT_INT, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	if (killResizeBackdrop(x, y)) {
-		blankScreen(0, 0, x, y);
+	if (g_sludge->_gfxMan->killResizeBackdrop(x, y)) {
+		g_sludge->_gfxMan->blankScreen(0, 0, x, y);
 		return BR_CONTINUE;
 	}
 	fatal("Out of memory creating new backdrop.");
@@ -449,6 +444,7 @@ builtIn(setSceneDimensions) {
 
 builtIn(aimCamera) {
 	UNUSEDALL
+	int cameraX, cameraY;
 	if (!getValueType(cameraY, SVT_INT, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
@@ -456,17 +452,8 @@ builtIn(aimCamera) {
 		return BR_ERROR;
 	trimStack(fun->stack);
 
-	cameraX -= (float)(winWidth >> 1) / cameraZoom;
-	cameraY -= (float)(winHeight >> 1) / cameraZoom;
+	g_sludge->_gfxMan->aimCamera(cameraX, cameraY);
 
-	if (cameraX < 0)
-		cameraX = 0;
-	else if (cameraX > sceneWidth - (float)winWidth / cameraZoom)
-		cameraX = sceneWidth - (float)winWidth / cameraZoom;
-	if (cameraY < 0)
-		cameraY = 0;
-	else if (cameraY > sceneHeight - (float)winHeight / cameraZoom)
-		cameraY = sceneHeight - (float)winHeight / cameraZoom;
 	return BR_CONTINUE;
 }
 
@@ -477,17 +464,7 @@ builtIn(zoomCamera) {
 		return BR_ERROR;
 	trimStack(fun->stack);
 
-	input.mouseX = input.mouseX * cameraZoom;
-	input.mouseY = input.mouseY * cameraZoom;
-
-	cameraZoom = (float)z * 0.01;
-	if ((float)winWidth / cameraZoom > sceneWidth)
-		cameraZoom = (float)winWidth / sceneWidth;
-	if ((float)winHeight / cameraZoom > sceneHeight)
-		cameraZoom = (float)winHeight / sceneHeight;
-
-	input.mouseX = input.mouseX / cameraZoom;
-	input.mouseY = input.mouseY / cameraZoom;
+	g_sludge->_gfxMan->zoomCamera(z);
 
 	return BR_CONTINUE;
 }
@@ -819,7 +796,7 @@ builtIn(setBlankColour) {
 	if (!getRGBParams(red, green, blue, fun))
 		return BR_ERROR;
 
-	currentBlankColour = g_sludge->getOrigPixelFormat()->RGBToColor(red & 255, green & 255, blue & 255);
+	g_sludge->_gfxMan->setBlankColor(red, green, blue);
 	setVariable(fun->reg, SVT_INT, 1);
 	return BR_CONTINUE;
 }
@@ -831,9 +808,7 @@ builtIn(setBurnColour) {
 	if (!getRGBParams(red, green, blue, fun))
 		return BR_ERROR;
 
-	currentBurnR = red;
-	currentBurnG = green;
-	currentBurnB = blue;
+	g_sludge->_gfxMan->setBurnColor(red, green, blue);
 	setVariable(fun->reg, SVT_INT, 1);
 	return BR_CONTINUE;
 }
@@ -880,7 +855,7 @@ builtIn(pasteString) {
 		return BR_ERROR;
 	trimStack(fun->stack);
 	if (x == IN_THE_CENTRE)
-		x = (winWidth - stringWidth(newText)) >> 1;
+		x = g_sludge->_gfxMan->getCenterX(stringWidth(newText));
 	pasteStringToBackdrop(newText, x, y, pastePalette);
 	return BR_CONTINUE;
 }
@@ -902,7 +877,7 @@ builtIn(anim) {
 	trimStack(fun->stack);
 
 	// Load the required sprite bank
-	loadedSpriteBank *sprBanky = loadBankForAnim(fileNumber);
+	LoadedSpriteBank *sprBanky = loadBankForAnim(fileNumber);
 	if (!sprBanky)
 		return BR_ERROR;    // File not found, fatal done already
 	setBankFile(ba, sprBanky);
@@ -1275,11 +1250,11 @@ builtIn(setZBuffer) {
 		int v;
 		getValueType(v, SVT_FILE, fun->stack->thisVar);
 		trimStack(fun->stack);
-		if (!setZBuffer(v))
+		if (!g_sludge->_gfxMan->setZBuffer(v))
 			return BR_ERROR;
 	} else {
 		trimStack(fun->stack);
-		killZBuffer();
+		g_sludge->_gfxMan->killZBuffer();
 	}
 	return BR_CONTINUE;
 }
@@ -1288,10 +1263,10 @@ builtIn(setLightMap) {
 	UNUSEDALL
 	switch (numParams) {
 		case 2:
-			if (!getValueType(lightMapMode, SVT_INT, fun->stack->thisVar))
+			if (!getValueType(g_sludge->_gfxMan->_lightMapMode, SVT_INT, fun->stack->thisVar))
 				return BR_ERROR;
 			trimStack(fun->stack);
-			lightMapMode %= LIGHTMAPMODE_NUM;
+			g_sludge->_gfxMan->_lightMapMode %= LIGHTMAPMODE_NUM;
 			// No break;
 
 		case 1:
@@ -1299,12 +1274,12 @@ builtIn(setLightMap) {
 				int v;
 				getValueType(v, SVT_FILE, fun->stack->thisVar);
 				trimStack(fun->stack);
-				if (!loadLightMap(v))
+				if (!g_sludge->_gfxMan->loadLightMap(v))
 					return BR_ERROR;
 				setVariable(fun->reg, SVT_INT, 1);
 			} else {
 				trimStack(fun->stack);
-				killLightMap();
+				g_sludge->_gfxMan->killLightMap();
 				setVariable(fun->reg, SVT_INT, 0);
 			}
 			break;
@@ -1610,7 +1585,7 @@ builtIn(pasteCharacter) {
 		}
 
 		int fNum = myAnim->frames[thisPerson->frameNum].frameNum;
-		fixScaleSprite(thisPerson->x, thisPerson->y, myAnim->theSprites->bank.sprites[ABS(fNum)], myAnim->theSprites->bank.myPalette, thisPerson, 0, 0, fNum < 0);
+		g_sludge->_gfxMan->fixScaleSprite(thisPerson->x, thisPerson->y, myAnim->theSprites->bank.sprites[ABS(fNum)], myAnim->theSprites->bank.myPalette, thisPerson, 0, 0, fNum < 0);
 		setVariable(fun->reg, SVT_INT, 1);
 	} else {
 		setVariable(fun->reg, SVT_INT, 0);
@@ -1973,7 +1948,7 @@ builtIn(hardScroll) {
 	if (!getValueType(v, SVT_INT, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	hardScroll(v);
+	g_sludge->_gfxMan->hardScroll(v);
 	return BR_CONTINUE;
 }
 
@@ -2196,7 +2171,7 @@ builtIn(burnString) {
 		return BR_ERROR;
 	trimStack(fun->stack);
 	if (x == IN_THE_CENTRE)
-		x = (winWidth - stringWidth(newText)) >> 1;
+		x = g_sludge->_gfxMan->getCenterX(stringWidth(newText));
 	burnStringToBackdrop(newText, x, y, pastePalette);
 	return BR_CONTINUE;
 }
@@ -2344,7 +2319,7 @@ builtIn(freeSound) {
 
 builtIn(parallaxAdd) {
 	UNUSEDALL
-	if (frozenStuff) {
+	if (g_sludge->_gfxMan->isFrozen()) {
 		fatal("Can't set background parallax image while frozen");
 		return BR_ERROR;
 	} else {
@@ -2391,7 +2366,7 @@ builtIn(getPixelColour) {
 	fun->reg.varData.theStack->first = NULL;
 	fun->reg.varData.theStack->last = NULL;
 	fun->reg.varData.theStack->timesUsed = 1;
-	if (!getRGBIntoStack(x, y, fun->reg.varData.theStack))
+	if (!g_sludge->_gfxMan->getRGBIntoStack(x, y, fun->reg.varData.theStack))
 		return BR_ERROR;
 
 	return BR_CONTINUE;
@@ -2487,7 +2462,7 @@ builtIn(setThumbnailSize) {
 	if (!getValueType(thumbWidth, SVT_INT, fun->stack->thisVar))
 		return BR_ERROR;
 	trimStack(fun->stack);
-	if (thumbWidth < 0 || thumbHeight < 0 || thumbWidth > (int)winWidth || thumbHeight > (int)winHeight) {
+	if (!g_sludge->_gfxMan->checkSizeValide(thumbWidth, thumbHeight)) {
 		Common::String buff = Common::String::format("%i x %i", thumbWidth, thumbWidth);
 		fatal("Invalid thumbnail size", buff);
 		return BR_ERROR;
@@ -2513,12 +2488,12 @@ builtIn(hasFlag) {
 
 builtIn(snapshotGrab) {
 	UNUSEDALL
-	return snapshot() ? BR_CONTINUE : BR_ERROR;
+	return g_sludge->_gfxMan->snapshot() ? BR_CONTINUE : BR_ERROR;
 }
 
 builtIn(snapshotClear) {
 	UNUSEDALL
-	nosnapshot();
+	g_sludge->_gfxMan->nosnapshot();
 	return BR_CONTINUE;
 }
 
diff --git a/engines/sludge/builtin.h b/engines/sludge/builtin.h
index a11d15a..1683b4f 100644
--- a/engines/sludge/builtin.h
+++ b/engines/sludge/builtin.h
@@ -25,6 +25,8 @@
 
 namespace Sludge {
 
+struct loadedFunction;
+
 enum builtReturn {
 	BR_KEEP_AND_PAUSE,
 	BR_ERROR,
diff --git a/engines/sludge/cursors.cpp b/engines/sludge/cursors.cpp
index 232dca8..10e67cf 100644
--- a/engines/sludge/cursors.cpp
+++ b/engines/sludge/cursors.cpp
@@ -22,9 +22,11 @@
 
 #include "sludge/allfiles.h"
 #include "sludge/cursors.h"
+#include "sludge/graphics.h"
 #include "sludge/sprites.h"
 #include "sludge/sprbanks.h"
 #include "sludge/people.h"
+#include "sludge/sludge.h"
 #include "sludge/sludger.h"
 
 namespace Sludge {
@@ -59,8 +61,17 @@ void displayCursor() {
 		}
 
 		if (flipMe != 2) {
-			(flipMe ? flipFontSprite : fontSprite)(input.mouseX, input.mouseY, mouseCursorAnim->theSprites->bank.sprites[spriteNum],
-					mouseCursorAnim->theSprites->bank.myPalette /* ( spritePalette&) NULL*/);
+			if (flipMe) {
+				g_sludge->_gfxMan->flipFontSprite(
+						input.mouseX, input.mouseY,
+						mouseCursorAnim->theSprites->bank.sprites[spriteNum],
+						mouseCursorAnim->theSprites->bank.myPalette /* ( spritePalette&) NULL*/);
+			} else {
+				g_sludge->_gfxMan->fontSprite(
+						input.mouseX, input.mouseY,
+						mouseCursorAnim->theSprites->bank.sprites[spriteNum],
+						mouseCursorAnim->theSprites->bank.myPalette /* ( spritePalette&) NULL*/);
+			}
 		}
 
 		if (++mouseCursorCountUp >= mouseCursorAnim->frames[mouseCursorFrameNum].howMany) {
@@ -73,7 +84,7 @@ void displayCursor() {
 
 void pasteCursor(int x, int y, personaAnimation *c) {
 	if (c->numFrames)
-		pasteSpriteToBackDrop(x, y, c->theSprites->bank.sprites[c->frames[0].frameNum], c->theSprites->bank.myPalette);
+		g_sludge->_gfxMan->pasteSpriteToBackDrop(x, y, c->theSprites->bank.sprites[c->frames[0].frameNum], c->theSprites->bank.myPalette);
 }
 
 } // End of namespace Sludge
diff --git a/engines/sludge/floor.cpp b/engines/sludge/floor.cpp
index 6b8f781..dc40ec7 100644
--- a/engines/sludge/floor.cpp
+++ b/engines/sludge/floor.cpp
@@ -25,14 +25,13 @@
 #include "sludge/allfiles.h"
 #include "sludge/newfatal.h"
 #include "sludge/fileset.h"
+#include "sludge/graphics.h"
 #include "sludge/moreio.h"
 #include "sludge/sludge.h"
 #include "sludge/floor.h"
 
 namespace Sludge {
 
-extern Graphics::Surface backdropSurface;
-
 flor *currentFloor = NULL;
 
 bool pointInFloorPolygon(floorPolygon &floorPoly, int x, int y) {
@@ -107,7 +106,7 @@ bool initFloor() {
 
 void killFloor() {
 	for (int i = 0; i < currentFloor->numPolygons; i++) {
-		delete currentFloor->polygon[i].vertexID;
+		delete []currentFloor->polygon[i].vertexID;
 		delete currentFloor->matrix[i];
 	}
 	delete currentFloor->polygon;
@@ -252,13 +251,11 @@ void drawFloor() {
 		nV = currentFloor->polygon[i].numVertices;
 		if (nV > 1) {
 			for (j = 1; j < nV; j++) {
-				backdropSurface.drawLine(currentFloor->vertex[currentFloor->polygon[i].vertexID[j - 1]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[j - 1]].y,
-						currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].y,
-						backdropSurface.format.ARGBToColor(255, 0, 0, 0));
+				g_sludge->_gfxMan->drawLine(currentFloor->vertex[currentFloor->polygon[i].vertexID[j - 1]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[j - 1]].y,
+						currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].y);
 			}
-			backdropSurface.drawLine(currentFloor->vertex[currentFloor->polygon[i].vertexID[0]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[0]].y,
-					currentFloor->vertex[currentFloor->polygon[i].vertexID[nV - 1]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[nV - 1]].y,
-					backdropSurface.format.ARGBToColor(255, 0, 0, 0));
+			g_sludge->_gfxMan->drawLine(currentFloor->vertex[currentFloor->polygon[i].vertexID[0]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[0]].y,
+					currentFloor->vertex[currentFloor->polygon[i].vertexID[nV - 1]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[nV - 1]].y);
 		}
 	}
 }
diff --git a/engines/sludge/fonttext.cpp b/engines/sludge/fonttext.cpp
index f1394b0..9d38b27 100644
--- a/engines/sludge/fonttext.cpp
+++ b/engines/sludge/fonttext.cpp
@@ -23,13 +23,15 @@
 #include "sludge/allfiles.h"
 #include "sludge/sprites.h"
 #include "sludge/fonttext.h"
+#include "sludge/graphics.h"
 #include "sludge/newfatal.h"
 #include "sludge/moreio.h"
+#include "sludge/sludge.h"
 #include "sludge/utf8.h"
 
 namespace Sludge {
 
-spriteBank theFont;
+SpriteBank theFont;
 int fontHeight = 0, numFontColours, loadedFontNum;
 UTF8Converter fontOrder;
 int16 fontSpace = -1;
@@ -39,8 +41,6 @@ uint fontTableSize = 0;
 
 #define fontInTable(x) ((x<fontTableSize) ? fontTable[(uint32) x] : 0)
 
-extern float cameraZoom;
-
 bool isInFont(const Common::String &theText) {
 	if (!fontTableSize)
 		return 0;
@@ -80,23 +80,23 @@ int stringWidth(const Common::String &theText) {
 	return xOff;
 }
 
-void pasteString(const Common::String &theText, int xOff, int y, spritePalette &thePal) {
+void pasteString(const Common::String &theText, int xOff, int y, SpritePalette &thePal) {
 	if (!fontTableSize)
 		return;
 
-	xOff += (int)((float)(fontSpace >> 1) / cameraZoom);
+	xOff += (int)((float)(fontSpace >> 1) / g_sludge->_gfxMan->getCamZoom());
 
 	Common::U32String str32 = UTF8Converter::convertUtf8ToUtf32(theText);
 
 	for (uint32 i = 0; i < str32.size(); ++i) {
 		uint32 c = str32[i];
-		sprite *mySprite = &theFont.sprites[fontInTable(c)];
-		fontSprite(xOff, y, *mySprite, thePal);
-		xOff += (int)((double)(mySprite->surface.w + fontSpace) / cameraZoom);
+		Sprite *mySprite = &theFont.sprites[fontInTable(c)];
+		g_sludge->_gfxMan->fontSprite(xOff, y, *mySprite, thePal);
+		xOff += (int)((double)(mySprite->surface.w + fontSpace) / g_sludge->_gfxMan->getCamZoom());
 	}
 }
 
-void pasteStringToBackdrop(const Common::String &theText, int xOff, int y, spritePalette &thePal) {
+void pasteStringToBackdrop(const Common::String &theText, int xOff, int y, SpritePalette &thePal) {
 	if (!fontTableSize)
 		return;
 
@@ -105,13 +105,13 @@ void pasteStringToBackdrop(const Common::String &theText, int xOff, int y, sprit
 	xOff += fontSpace >> 1;
 	for (uint32 i = 0; i < str32.size(); ++i) {
 		uint32 c = str32[i];
-		sprite *mySprite = &theFont.sprites[fontInTable(c)];
-		pasteSpriteToBackDrop(xOff, y, *mySprite, thePal);
+		Sprite *mySprite = &theFont.sprites[fontInTable(c)];
+		g_sludge->_gfxMan->pasteSpriteToBackDrop(xOff, y, *mySprite, thePal);
 		xOff += mySprite->surface.w + fontSpace;
 	}
 }
 
-void burnStringToBackdrop(const Common::String &theText, int xOff, int y, spritePalette &thePal) {
+void burnStringToBackdrop(const Common::String &theText, int xOff, int y, SpritePalette &thePal) {
 	if (!fontTableSize)
 		return;
 
@@ -120,13 +120,13 @@ void burnStringToBackdrop(const Common::String &theText, int xOff, int y, sprite
 	xOff += fontSpace >> 1;
 	for (uint i = 0; i < str32.size(); ++i) {
 		uint32 c = str32[i];
-		sprite *mySprite = &theFont.sprites[fontInTable(c)];
-		burnSpriteToBackDrop(xOff, y, *mySprite, thePal);
+		Sprite *mySprite = &theFont.sprites[fontInTable(c)];
+		g_sludge->_gfxMan->burnSpriteToBackDrop(xOff, y, *mySprite, thePal);
 		xOff += mySprite->surface.w + fontSpace;
 	}
 }
 
-void setFontColour(spritePalette &sP, byte r, byte g, byte b) {
+void setFontColour(SpritePalette &sP, byte r, byte g, byte b) {
 	sP.originalRed = r;
 	sP.originalGreen = g;
 	sP.originalBlue = b;
@@ -135,7 +135,7 @@ void setFontColour(spritePalette &sP, byte r, byte g, byte b) {
 bool loadFont(int filenum, const Common::String &charOrder, int h) {
 	fontOrder.setUTF8String(charOrder);
 
-	forgetSpriteBank(theFont);
+	g_sludge->_gfxMan->forgetSpriteBank(theFont);
 
 	loadedFontNum = filenum;
 
@@ -164,7 +164,7 @@ bool loadFont(int filenum, const Common::String &charOrder, int h) {
 		fontTable[c] = i;
 	}
 
-	if (!loadSpriteBank(filenum, theFont, true)) {
+	if (!g_sludge->_gfxMan->loadSpriteBank(filenum, theFont, true)) {
 		fatal("Can't load font");
 		return false;
 	}
diff --git a/engines/sludge/fonttext.h b/engines/sludge/fonttext.h
index 3967770..06cadfd 100644
--- a/engines/sludge/fonttext.h
+++ b/engines/sludge/fonttext.h
@@ -26,13 +26,15 @@
 
 namespace Sludge {
 
+struct SpritePalette;
+
 bool loadFont(int filenum, const Common::String &charOrder, int);
-void pasteString(const Common::String &theText, int, int, spritePalette &);
-void setFontColour(spritePalette &sP, byte r, byte g, byte b);
+void pasteString(const Common::String &theText, int, int, SpritePalette &);
+void setFontColour(SpritePalette &sP, byte r, byte g, byte b);
 int stringWidth(const Common::String &theText);
 int stringLength(const Common::String &theText);
-void pasteStringToBackdrop(const Common::String &theText, int xOff, int y, spritePalette &thePal);
-void burnStringToBackdrop(const Common::String &theText, int xOff, int y, spritePalette &thePal);
+void pasteStringToBackdrop(const Common::String &theText, int xOff, int y, SpritePalette &thePal);
+void burnStringToBackdrop(const Common::String &theText, int xOff, int y, SpritePalette &thePal);
 bool isInFont(const Common::String &theText);
 
 } // End of namespace Sludge
diff --git a/engines/sludge/freeze.cpp b/engines/sludge/freeze.cpp
index 080ced6..ebd91a3 100644
--- a/engines/sludge/freeze.cpp
+++ b/engines/sludge/freeze.cpp
@@ -43,72 +43,51 @@ extern screenRegion *allScreenRegions;
 extern screenRegion *overRegion;
 extern speechStruct *speech;
 extern inputType input;
-extern Graphics::Surface backdropSurface;
-extern Graphics::Surface renderSurface;
-extern int lightMapNumber, zBufferNumber;
 extern eventHandlers *currentEvents;
 extern personaAnimation *mouseCursorAnim;
 extern int mouseCursorFrameNum;
-extern int cameraX, cameraY;
-extern uint sceneWidth, sceneHeight;
-extern float cameraZoom;
-extern zBufferData zBuffer;
-extern bool backdropExists;
-frozenStuffStruct *frozenStuff = NULL;
-extern uint sceneWidth, sceneHeight;
-Graphics::Surface freezeSurface;
 
-void shufflePeople();
+void GraphicsManager::freezeGraphics() {
 
-void freezeGraphics() {
+	int w = _winWidth;
+	int h = _winHeight;
 
-	int w = winWidth;
-	int h = winHeight;
+	_freezeSurface.create(w, h, *g_sludge->getScreenPixelFormat());
 
-	freezeSurface.create(w, h, *g_sludge->getScreenPixelFormat());
-
-	// Temporarily disable AA
-#if 0
-	int antiAlias = gameSettings.antiAlias;
-	gameSettings.antiAlias = 0;
-#endif
 	displayBase();
-	freezeSurface.copyFrom(renderSurface);
-#if 0
-	gameSettings.antiAlias = antiAlias;
-#endif
+	_freezeSurface.copyFrom(_renderSurface);
 }
 
-bool freeze() {
-	frozenStuffStruct *newFreezer = new frozenStuffStruct;
+bool GraphicsManager::freeze() {
+	FrozenStuffStruct *newFreezer = new FrozenStuffStruct;
 	if (!checkNew(newFreezer))
 		return false;
 
 	// Grab a copy of the current scene
 	freezeGraphics();
-	newFreezer->backdropSurface.copyFrom(backdropSurface);
-	newFreezer->sceneWidth = sceneWidth;
-	newFreezer->sceneHeight = sceneHeight;
-	newFreezer->cameraX = cameraX;
-	newFreezer->cameraY = cameraY;
-	newFreezer->cameraZoom = cameraZoom;
-
-	newFreezer->lightMapSurface.copyFrom(lightMap);
-	newFreezer->lightMapNumber = lightMapNumber;
-
-	newFreezer->parallaxStuff = g_sludge->_gfxMan->_parallaxStuff;
-	g_sludge->_gfxMan->_parallaxStuff = NULL;
-	newFreezer->zBufferSprites = zBuffer.sprites;
-	newFreezer->zBufferNumber = zBuffer.originalNum;
-	newFreezer->zPanels = zBuffer.numPanels;
-	zBuffer.sprites = NULL;
+	newFreezer->backdropSurface.copyFrom(_backdropSurface);
+	newFreezer->sceneWidth = _sceneWidth;
+	newFreezer->sceneHeight = _sceneHeight;
+	newFreezer->cameraX = _cameraX;
+	newFreezer->cameraY = _cameraY;
+	newFreezer->cameraZoom = _cameraZoom;
+
+	newFreezer->lightMapSurface.copyFrom(_lightMap);
+	newFreezer->lightMapNumber = _lightMapNumber;
+
+	newFreezer->parallaxStuff = _parallaxStuff;
+	_parallaxStuff = NULL;
+	newFreezer->zBufferSprites = _zBuffer->sprites;
+	newFreezer->zBufferNumber = _zBuffer->originalNum;
+	newFreezer->zPanels = _zBuffer->numPanels;
+	_zBuffer->sprites = NULL;
 	// resizeBackdrop kills parallax stuff, light map, z-buffer...
-	if (!killResizeBackdrop(winWidth, winHeight))
+	if (!killResizeBackdrop(_winWidth, _winHeight))
 		return fatal("Can't create new temporary backdrop buffer");
 
 	// Copy the old scene to the new backdrop
-	backdropSurface.copyFrom(freezeSurface);
-	backdropExists = true;
+	_backdropSurface.copyFrom(_freezeSurface);
+	_backdropExists = true;
 
 	newFreezer->allPeople = allPeople;
 	allPeople = NULL;
@@ -136,15 +115,15 @@ bool freeze() {
 		return false;
 	memset(currentEvents, 0, sizeof(eventHandlers));
 
-	newFreezer->next = frozenStuff;
-	frozenStuff = newFreezer;
+	newFreezer->next = _frozenStuff;
+	_frozenStuff = newFreezer;
 
 	return true;
 }
 
-int howFrozen() {
+int GraphicsManager::howFrozen() {
 	int a = 0;
-	frozenStuffStruct *f = frozenStuff;
+	FrozenStuffStruct *f = _frozenStuff;
 	while (f) {
 		a++;
 		f = f->next;
@@ -152,66 +131,66 @@ int howFrozen() {
 	return a;
 }
 
-void unfreeze(bool killImage) {
-	frozenStuffStruct *killMe = frozenStuff;
+void GraphicsManager::unfreeze(bool killImage) {
+	FrozenStuffStruct *killMe = _frozenStuff;
 
-	if (!frozenStuff)
+	if (!_frozenStuff)
 		return;
 
-	sceneWidth = frozenStuff->sceneWidth;
-	sceneHeight = frozenStuff->sceneHeight;
+	_sceneWidth = _frozenStuff->sceneWidth;
+	_sceneHeight = _frozenStuff->sceneHeight;
 
-	cameraX = frozenStuff->cameraX;
-	cameraY = frozenStuff->cameraY;
-	input.mouseX = (int)(input.mouseX * cameraZoom);
-	input.mouseY = (int)(input.mouseY * cameraZoom);
-	cameraZoom = frozenStuff->cameraZoom;
-	input.mouseX = (int)(input.mouseX / cameraZoom);
-	input.mouseY = (int)(input.mouseY / cameraZoom);
+	_cameraX = _frozenStuff->cameraX;
+	_cameraY = _frozenStuff->cameraY;
+	input.mouseX = (int)(input.mouseX * _cameraZoom);
+	input.mouseY = (int)(input.mouseY * _cameraZoom);
+	_cameraZoom = _frozenStuff->cameraZoom;
+	input.mouseX = (int)(input.mouseX / _cameraZoom);
+	input.mouseY = (int)(input.mouseY / _cameraZoom);
 
 	killAllPeople();
-	allPeople = frozenStuff->allPeople;
+	allPeople = _frozenStuff->allPeople;
 
 	killAllRegions();
-	allScreenRegions = frozenStuff->allScreenRegions;
+	allScreenRegions = _frozenStuff->allScreenRegions;
 
 	killLightMap();
 
-	lightMap.copyFrom(frozenStuff->lightMapSurface);
-	lightMapNumber = frozenStuff->lightMapNumber;
-	if (lightMapNumber) {
-		loadLightMap(lightMapNumber);
+	_lightMap.copyFrom(_frozenStuff->lightMapSurface);
+	_lightMapNumber = _frozenStuff->lightMapNumber;
+	if (_lightMapNumber) {
+		loadLightMap(_lightMapNumber);
 	}
 
 	if (killImage)
 		killBackDrop();
-	backdropSurface.copyFrom(frozenStuff->backdropSurface);
-	backdropExists = true;
+	_backdropSurface.copyFrom(_frozenStuff->backdropSurface);
+	_backdropExists = true;
 
-	zBuffer.sprites = frozenStuff->zBufferSprites;
+	_zBuffer->sprites = _frozenStuff->zBufferSprites;
 	killZBuffer();
-	zBuffer.originalNum = frozenStuff->zBufferNumber;
-	zBuffer.numPanels = frozenStuff->zPanels;
-	if (zBuffer.numPanels) {
-		setZBuffer(zBuffer.originalNum);
+	_zBuffer->originalNum = _frozenStuff->zBufferNumber;
+	_zBuffer->numPanels = _frozenStuff->zPanels;
+	if (_zBuffer->numPanels) {
+		setZBuffer(_zBuffer->originalNum);
 	}
 
-	g_sludge->_gfxMan->killParallax();
-	g_sludge->_gfxMan->_parallaxStuff = frozenStuff->parallaxStuff;
+	killParallax();
+	_parallaxStuff = _frozenStuff->parallaxStuff;
 
 	deleteAnim(mouseCursorAnim);
-	mouseCursorAnim = frozenStuff->mouseCursorAnim;
-	mouseCursorFrameNum = frozenStuff->mouseCursorFrameNum;
+	mouseCursorAnim = _frozenStuff->mouseCursorAnim;
+	mouseCursorFrameNum = _frozenStuff->mouseCursorFrameNum;
 
-	restoreBarStuff(frozenStuff->frozenStatus);
+	restoreBarStuff(_frozenStuff->frozenStatus);
 
 	delete currentEvents;
-	currentEvents = frozenStuff->currentEvents;
+	currentEvents = _frozenStuff->currentEvents;
 	killAllSpeech();
 	delete speech;
 
-	speech = frozenStuff->speech;
-	frozenStuff = frozenStuff->next;
+	speech = _frozenStuff->speech;
+	_frozenStuff = _frozenStuff->next;
 
 	overRegion = NULL;
 
diff --git a/engines/sludge/freeze.h b/engines/sludge/freeze.h
index ad0d426..ff2d67c 100644
--- a/engines/sludge/freeze.h
+++ b/engines/sludge/freeze.h
@@ -26,7 +26,13 @@
 
 namespace Sludge {
 
-struct frozenStuffStruct {
+struct onScreenPerson;
+struct screenRegion;
+struct speechStruct;
+struct statusStuff;
+struct eventHandlers;
+
+struct FrozenStuffStruct {
 	onScreenPerson *allPeople;
 	screenRegion *allScreenRegions;
 	Graphics::Surface backdropSurface;
@@ -43,13 +49,9 @@ struct frozenStuffStruct {
 	int cameraX, cameraY, sceneWidth, sceneHeight;
 	float cameraZoom;
 
-	frozenStuffStruct *next;
+	FrozenStuffStruct *next;
 };
 
-bool freeze();
-void unfreeze(bool killImage = true);
-int howFrozen();
-
 } // End of namespace Sludge
 
 #endif
diff --git a/engines/sludge/graphics.cpp b/engines/sludge/graphics.cpp
index 93295b4..81e8ed2 100644
--- a/engines/sludge/graphics.cpp
+++ b/engines/sludge/graphics.cpp
@@ -20,18 +20,117 @@
  *
  */
 
+#include "engines/util.h"
+
 #include "sludge/backdrop.h"
+#include "sludge/freeze.h"
 #include "sludge/graphics.h"
+#include "sludge/newfatal.h"
+#include "sludge/sludge.h"
+#include "sludge/sludger.h"
+#include "sludge/sprites.h"
+#include "sludge/zbuffer.h"
 
 namespace Sludge {
 
-GraphicsManager::GraphicsManager() {
+extern inputType input;
+
+GraphicsManager::GraphicsManager(SludgeEngine *vm) {
+	_vm = vm;
+
+	// Init screen surface
+	_winWidth = _sceneWidth = 640;
+	_winHeight = _sceneHeight = 480;
+
+	// LightMap
+	_lightMapMode = LIGHTMAPMODE_PIXEL;
+	_lightMapNumber = 0;
+
+	// Parallax
 	_parallaxStuff = new Parallax;
+
+	// Camera
+	_cameraZoom = 1.0;
+	_cameraX = _cameraY = 0;
+
+	// Freeze
+	_frozenStuff = nullptr;
+
+	// Back drop
+	_backdropExists = false;
+
+	// Sprites
+	_spriteLayers = new SpriteLayers;
+	_spriteLayers->numLayers = 0;
+
+	// ZBuffer
+	_zBufferToSet = -1;
+	_zBuffer = new ZBufferData;
+	_zBuffer->sprites = nullptr;
+
+	// Colors
+	_currentBlankColour = _renderSurface.format.ARGBToColor(255, 0, 0, 0);
+	_currentBurnR = 0;
+	_currentBurnG = 0;
+	_currentBurnB = 0;
 }
 
 GraphicsManager::~GraphicsManager() {
+	// kill parallax
+	killParallax();
 	delete _parallaxStuff;
 	_parallaxStuff = nullptr;
+
+	// kill frozen stuff
+	FrozenStuffStruct *killMe = _frozenStuff;
+	while (killMe) {
+		_frozenStuff = _frozenStuff->next;
+		if (killMe->backdropSurface.getPixels())
+			killMe->backdropSurface.free();
+		if (killMe->lightMapSurface.getPixels())
+			killMe->lightMapSurface.free();
+		delete killMe;
+		killMe = nullptr;
+		killMe = _frozenStuff;
+	}
+
+	// kill sprite layers
+	killSpriteLayers();
+	delete _spriteLayers;
+	_spriteLayers = nullptr;
+
+	// kill zbuffer
+	killZBuffer();
+	delete _zBuffer;
+	_zBuffer = nullptr;
+
+	// kill surfaces
+	if (_renderSurface.getPixels())
+		_renderSurface.free();
+
+	if (_snapshotSurface.getPixels())
+		_snapshotSurface.free();
+
+	if (_backdropSurface.getPixels())
+		_backdropSurface.free();
+
+	if (_origBackdropSurface.getPixels())
+		_origBackdropSurface.free();
+}
+
+bool GraphicsManager::init() {
+	initGraphics(_winWidth, _winHeight, true, _vm->getScreenPixelFormat());
+	_renderSurface.create(_winWidth, _winHeight, *_vm->getScreenPixelFormat());
+
+	if (!killResizeBackdrop(_winWidth, _winHeight))
+		return fatal("Couldn't allocate memory for backdrop");
+
+	return true;
+}
+
+void GraphicsManager::display() {
+	g_system->copyRectToScreen((byte *)_renderSurface.getPixels(), _renderSurface.pitch, 0, 0, _renderSurface.w, _renderSurface.h);
+	g_system->updateScreen();
 }
 
 bool GraphicsManager::loadParallax(uint16 v, uint16 fracX, uint16 fracY) {
@@ -56,6 +155,48 @@ void GraphicsManager::drawParallax() {
 		_parallaxStuff->draw();
 }
 
+void GraphicsManager::aimCamera(int cameraX, int cameraY) {
+	_cameraX = cameraX;
+	_cameraY = cameraY;
+	_cameraX -= (float)(_winWidth >> 1) / _cameraZoom;
+	_cameraY -= (float)(_winHeight >> 1) / _cameraZoom;
+
+	if (_cameraX < 0)
+		_cameraX = 0;
+	else if (_cameraX > _sceneWidth - (float)_winWidth / _cameraZoom)
+		_cameraX = _sceneWidth - (float)_winWidth / _cameraZoom;
+	if (_cameraY < 0)
+		_cameraY = 0;
+	else if (_cameraY > _sceneHeight - (float)_winHeight / _cameraZoom)
+		_cameraY = _sceneHeight - (float)_winHeight / _cameraZoom;
+}
+
+void GraphicsManager::zoomCamera(int z) {
+	input.mouseX = input.mouseX * _cameraZoom;
+	input.mouseY = input.mouseY * _cameraZoom;
+
+	_cameraZoom = (float)z * 0.01;
+	if ((float)_winWidth / _cameraZoom > _sceneWidth)
+		_cameraZoom = (float)_winWidth / _sceneWidth;
+	if ((float)_winHeight / _cameraZoom > _sceneHeight)
+		_cameraZoom = (float)_winHeight / _sceneHeight;
+
+	input.mouseX = input.mouseX / _cameraZoom;
+	input.mouseY = input.mouseY / _cameraZoom;
+}
+
+void GraphicsManager::saveColors(Common::WriteStream *stream) {
+	stream->writeUint16BE(_currentBlankColour);
+	stream->writeByte(_currentBurnR);
+	stream->writeByte(_currentBurnG);
+	stream->writeByte(_currentBurnB);
+}
 
+void GraphicsManager::loadColors(Common::SeekableReadStream *stream) {
+	_currentBlankColour = stream->readUint16BE();
+	_currentBurnR = stream->readByte();
+	_currentBurnG = stream->readByte();
+	_currentBurnB = stream->readByte();
+}
 
 } // End of namespace Sludge
diff --git a/engines/sludge/graphics.h b/engines/sludge/graphics.h
index d866d94..024c8ca 100644
--- a/engines/sludge/graphics.h
+++ b/engines/sludge/graphics.h
@@ -23,21 +23,184 @@
 #ifndef SLUDGE_GRAPHICS_H
 #define SLUDGE_GRAPHICS_H
 
+#include "graphics/surface.h"
+#include "graphics/transparent_surface.h"
+
 namespace Sludge {
 
 class Parallax;
+class SludgeEngine;
+class SpritePalette;
+
+struct stackHandler;
+struct FrozenStuffStruct;
+struct onScreenPerson;
+struct SpriteBank;
+struct Sprite;
+struct SpriteLayers;
+struct ZBufferData;
+
+enum ELightMapMode {
+	LIGHTMAPMODE_NONE = -1,
+	LIGHTMAPMODE_HOTSPOT,
+	LIGHTMAPMODE_PIXEL,
+	LIGHTMAPMODE_NUM
+};
 
 class GraphicsManager {
 public:
-	GraphicsManager();
+	GraphicsManager(SludgeEngine *vm);
 	virtual ~GraphicsManager();
 
+	// graphics
+	void setWindowSize(uint winWidth, uint winHeight) { _winWidth = winWidth; _winHeight = winHeight; }
+	bool init();
+	void display();
+
 	// Parallax
-	Parallax *_parallaxStuff;
 	bool loadParallax(uint16 v, uint16 fracX, uint16 fracY);
 	void killParallax();
 	void saveParallax(Common::WriteStream *fp);
 	void drawParallax();
+
+	// Backdrop
+	void killAllBackDrop();
+	bool resizeBackdrop(int x, int y);
+	bool killResizeBackdrop(int x, int y);
+	void killBackDrop();
+	void loadBackDrop(int fileNum, int x, int y);
+	void mixBackDrop(int fileNum, int x, int y);
+	void drawBackDrop();
+	void blankScreen(int x1, int y1, int x2, int y2);
+	void blankAllScreen();
+	void darkScreen();
+	void saveHSI(Common::WriteStream *stream);
+	bool loadHSI(Common::SeekableReadStream *stream, int, int, bool);
+	bool mixHSI(Common::SeekableReadStream *stream, int x = 0, int y = 0);
+	void drawLine(uint, uint, uint, uint);
+	void drawHorizontalLine(uint, uint, uint);
+	void drawVerticalLine(uint, uint, uint);
+	void hardScroll(int distance);
+	bool getRGBIntoStack(uint x, uint y, stackHandler *sH);
+
+	// Lightmap
+	int _lightMapMode;
+	void killLightMap();
+	bool loadLightMap(int v);
+	void saveLightMap(Common::WriteStream *stream);
+	bool loadLightMap(int ssgVersion, Common::SeekableReadStream *stream);
+
+	// Snapshot
+	void nosnapshot();
+	bool snapshot();
+	void saveSnapshot(Common::WriteStream *stream);
+	bool restoreSnapshot(Common::SeekableReadStream *stream);
+
+	// Camera
+	int getCamX() { return _cameraX; }
+	int getCamY() { return _cameraY; }
+	float getCamZoom() { return _cameraZoom; }
+	void setCamera(int camerX, int camerY, float camerZ) {
+		_cameraX = camerX;
+		_cameraY = camerY;
+		_cameraZoom = camerZ;
+	}
+	void aimCamera(int cameraX, int cameraY);
+	void zoomCamera(int z);
+
+	// Screen
+	int getCenterX(int width) { return (_winWidth - width) >> 1; }
+	int checkSizeValide(int width, int height) { return ((width >= 0) && (height >= 0) && (width < (int)_winWidth) && (height > (int)_winHeight)); }
+
+	// Freeze
+	bool freeze();
+	void unfreeze(bool killImage = true);
+	int howFrozen();
+	bool isFrozen() { return (_frozenStuff != nullptr); }
+
+	// Sprites
+	void forgetSpriteBank(SpriteBank &forgetme);
+	bool loadSpriteBank(char *filename, SpriteBank &loadhere);
+	bool loadSpriteBank(int fileNum, SpriteBank &loadhere, bool isFont);
+
+	void fontSprite(int x1, int y1, Sprite &single, const SpritePalette &fontPal);
+	void flipFontSprite(int x1, int y1, Sprite &single, const SpritePalette &fontPal);
+
+	bool scaleSprite(Sprite &single, const SpritePalette &fontPal, onScreenPerson *thisPerson, bool mirror);
+	void pasteSpriteToBackDrop(int x1, int y1, Sprite &single, const SpritePalette &fontPal);
+	bool reserveSpritePal(SpritePalette &sP, int n);
+	void fixScaleSprite(int x1, int y1, Sprite &single, const SpritePalette &fontPal, onScreenPerson *thisPerson, const int camX, const int camY, bool);
+	void burnSpriteToBackDrop(int x1, int y1, Sprite &single, const SpritePalette &fontPal);
+
+	void resetSpriteLayers(ZBufferData *ptrZBuffer, int x, int y, bool upsidedown);
+	void addSpriteDepth(Graphics::Surface *ptr, int depth, int x, int y, Graphics::FLIP_FLAGS flip, int width = -1, int height = -1, uint32 color = TS_ARGB(255, 255, 255, 255));
+	void displaySpriteLayers();
+	void killSpriteLayers();
+
+	// ZBuffer
+	bool setZBuffer(int y);
+	void killZBuffer();
+	void drawZBuffer(int x, int y, bool upsidedown);
+	void saveZBuffer(Common::WriteStream *stream);
+	bool loadZBuffer(Common::SeekableReadStream *stream);
+
+	// Colors
+	void setBlankColor(int r, int g, int b) { _currentBlankColour = _renderSurface.format.RGBToColor(r & 255, g & 255, b & 255);};
+	void setBurnColor(int r, int g, int b) {
+		_currentBurnG = r;
+		_currentBurnG = g;
+		_currentBurnB = b;
+	}
+	void saveColors(Common::WriteStream *stream);
+	void loadColors(Common::SeekableReadStream *stream);
+
+private:
+	SludgeEngine *_vm;
+
+	uint _winWidth, _winHeight, _sceneWidth, _sceneHeight;
+
+	// renderSurface
+	Graphics::Surface _renderSurface;
+
+	// Snapshot
+	Graphics::Surface _snapshotSurface;
+
+	// LightMap
+	int _lightMapNumber;
+	Graphics::Surface _lightMap;
+	byte _curLight[3];
+
+	// Parallax
+	Parallax *_parallaxStuff;
+
+	// Camera
+	float _cameraZoom;
+	int _cameraX, _cameraY;
+
+	// Freeze
+	FrozenStuffStruct *_frozenStuff;
+	Graphics::Surface _freezeSurface;
+	void freezeGraphics();
+
+	// Back drop
+	Graphics::Surface _backdropSurface;
+	Graphics::Surface _origBackdropSurface;
+	bool _backdropExists;
+	bool reserveBackdrop();
+
+	// Sprites
+	SpriteLayers *_spriteLayers;
+	void fontSprite(bool flip, int x, int y, Sprite &single, const SpritePalette &fontPal);
+	uint32 getDrawColor(onScreenPerson *thisPerson);
+
+	// ZBuffer
+	int _zBufferToSet;
+	ZBufferData *_zBuffer;
+	void sortZPal(int *oldpal, int *newpal, int size);
+
+	// Colors
+	uint _currentBlankColour;
+	byte _currentBurnR, _currentBurnG, _currentBurnB;
 };
 
 } // End of namespace Sludge
diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp
index 48fcfc3..1ca12a6 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -59,7 +59,6 @@ extern const char *typeName[];                      // In variable.cpp
 extern int numGlobals;                              // In sludger.cpp
 extern variable *globalVars;                        // In sludger.cpp
 extern flor *currentFloor;                          // In floor.cpp
-extern zBufferData zBuffer;                         // In zbuffer.cpp
 extern speechStruct *speech;                        // In talk.cpp
 extern personaAnimation *mouseCursorAnim;           // In cursor.cpp
 extern int mouseCursorFrameNum;                     // "    "   "
@@ -68,18 +67,12 @@ extern uint fontTableSize;							//
 extern UTF8Converter fontOrder;                       // "    "   "
 extern FILETIME fileTime;                           // In sludger.cpp
 extern int speechMode;                              // "    "   "
-extern int lightMapNumber;                          // In backdrop.cpp
-extern int cameraX, cameraY;                        // "    "   "
-extern float cameraZoom;
 extern byte brightnessLevel;               // "    "   "
 extern int16 fontSpace;                             // in textfont.cpp
 extern byte fadeMode;                      // In transition.cpp
 extern bool captureAllKeys;
 extern bool allowAnyFilename;
 extern uint16 saveEncoding;                 // in savedata.cpp
-extern byte currentBurnR, currentBurnG, currentBurnB;
-extern uint currentBlankColour;             // in backdrop.cpp
-extern int lightMapMode;                    //      "
 
 //----------------------------------------------------------------------
 // Globals (so we know what's saved already and what's a reference
@@ -386,12 +379,12 @@ bool saveGame(const Common::String &fname) {
 	fp->writeSint16LE(fontSpace);
 
 	// Save backdrop
-	fp->writeUint16BE(cameraX);
-	fp->writeUint16BE(cameraY);
-	fp->writeFloatLE(cameraZoom);
+	fp->writeUint16BE(g_sludge->_gfxMan->getCamX());
+	fp->writeUint16BE(g_sludge->_gfxMan->getCamY());
+	fp->writeFloatLE(g_sludge->_gfxMan->getCamZoom());
 
 	fp->writeByte(brightnessLevel);
-	saveHSI(fp);
+	g_sludge->_gfxMan->saveHSI(fp);
 
 	// Save event handlers
 	saveHandlers(fp);
@@ -430,21 +423,10 @@ bool saveGame(const Common::String &fname) {
 		fp->writeByte(0);
 	}
 
-	if (zBuffer.numPanels > 0) {
-		fp->writeByte(1);
-		fp->writeUint16BE(zBuffer.originalNum);
-	} else {
-		fp->writeByte(0);
-	}
+	g_sludge->_gfxMan->saveZBuffer(fp);
 
-	if (lightMap.getPixels()) {
-		fp->writeByte(1);
-		fp->writeUint16BE(lightMapNumber);
-	} else {
-		fp->writeByte(0);
-	}
+	g_sludge->_gfxMan->saveLightMap(fp);
 
-	fp->writeByte(lightMapMode);
 	fp->writeByte(speechMode);
 	fp->writeByte(fadeMode);
 	saveSpeech(speech, fp);
@@ -455,17 +437,14 @@ bool saveGame(const Common::String &fname) {
 
 	blur_saveSettings(fp);
 
-	fp->writeUint16BE(currentBlankColour);
-	fp->writeByte(currentBurnR);
-	fp->writeByte(currentBurnG);
-	fp->writeByte(currentBurnB);
+	g_sludge->_gfxMan->saveColors(fp);
 
 	g_sludge->_gfxMan->saveParallax(fp);
 	fp->writeByte(0);
 
 	g_sludge->_languageMan->saveLanguageSetting(fp);
 
-	saveSnapshot(fp);
+	g_sludge->_gfxMan->saveSnapshot(fp);
 
 	fp->flush();
 	fp->finalize();
@@ -578,7 +557,7 @@ bool loadGame(const Common::String &fname) {
 
 	brightnessLevel = fp->readByte();
 
-	loadHSI(fp, 0, 0, true);
+	g_sludge->_gfxMan->loadHSI(fp, 0, 0, true);
 	loadHandlers(fp);
 	loadRegions(fp);
 
@@ -613,18 +592,11 @@ bool loadGame(const Common::String &fname) {
 	} else
 		setFloorNull();
 
-	if (fp->readByte()) {
-		if (!setZBuffer(fp->readUint16BE()))
-			return false;
-	}
-
-	if (fp->readByte()) {
-		if (!loadLightMap(fp->readUint16BE()))
-			return false;
-	}
+	if (!g_sludge->_gfxMan->loadZBuffer(fp))
+		return false;
 
-	if (ssgVersion >= VERSION(1, 4)) {
-		lightMapMode = fp->readByte() % 3;
+	if (!g_sludge->_gfxMan->loadLightMap(ssgVersion, fp)) {
+		return false;
 	}
 
 	speechMode = fp->readByte();
@@ -647,10 +619,7 @@ bool loadGame(const Common::String &fname) {
 	}
 
 	if (ssgVersion >= VERSION(1, 3)) {
-		currentBlankColour = fp->readUint16BE();
-		currentBurnR = fp->readByte();
-		currentBurnG = fp->readByte();
-		currentBurnB = fp->readByte();
+		g_sludge->_gfxMan->loadColors(fp);
 
 		// Read parallax layers
 		while (fp->readByte()) {
@@ -665,19 +634,17 @@ bool loadGame(const Common::String &fname) {
 		g_sludge->_languageMan->loadLanguageSetting(fp);
 	}
 
-	nosnapshot();
+	g_sludge->_gfxMan->nosnapshot();
 	if (ssgVersion >= VERSION(1, 4)) {
 		if (fp->readByte()) {
-			if (!restoreSnapshot(fp))
+			if (!g_sludge->_gfxMan->restoreSnapshot(fp))
 				return false;
 		}
 	}
 
 	delete fp;
 
-	cameraX = camerX;
-	cameraY = camerY;
-	cameraZoom = camerZ;
+	g_sludge->_gfxMan->setCamera(camerX, camerY, camerZ);
 
 	clearStackLib();
 	return true;
diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp
index bc29209..1d329aa 100644
--- a/engines/sludge/main_loop.cpp
+++ b/engines/sludge/main_loop.cpp
@@ -25,27 +25,24 @@
 #include "common/events.h"
 #include "common/keyboard.h"
 
-#include "engines/util.h"
-
 #include "graphics/surface.h"
 
 #include "sludge/allfiles.h"
-#include "sludge/language.h"
-#include "sludge/sludger.h"
 #include "sludge/backdrop.h"
+#include "sludge/floor.h"
+#include "sludge/graphics.h"
+#include "sludge/helpers.h"
 #include "sludge/language.h"
 #include "sludge/newfatal.h"
-#include "sludge/people.h"
-#include "sludge/floor.h"
 #include "sludge/objtypes.h"
-#include "sludge/talk.h"
+#include "sludge/people.h"
 #include "sludge/statusba.h"
-#include "sludge/transition.h"
-#include "sludge/timing.h"
 #include "sludge/sound.h"
-#include "sludge/sludger.h"
-#include "sludge/helpers.h"
 #include "sludge/sludge.h"
+#include "sludge/sludger.h"
+#include "sludge/talk.h"
+#include "sludge/transition.h"
+#include "sludge/timing.h"
 
 namespace Sludge {
 
@@ -56,19 +53,18 @@ namespace Sludge {
 HWND hMainWindow = NULL;
 
 int realWinWidth = 640, realWinHeight = 480;
-extern float cameraZoom;
 
 extern inputType input;
 extern variableStack *noStack;
-Graphics::Surface renderSurface;
 
 int dialogValue = 0;
 
-extern bool reallyWantToQuit;
-
 int weAreDoneSoQuit;
 
 void checkInput() {
+	int winWidth = g_system->getWidth();
+	int winHeight = g_system->getHeight();
+	float cameraZoom = g_sludge->_gfxMan->getCamZoom();
 #if 0
 	static bool fakeRightclick = false;
 #endif
@@ -148,27 +144,17 @@ void checkInput() {
 	}
 }
 
-int main_loop(const char *filename)
-		{
-	/* Dimensions of our window. */
-	winWidth = 640;
-	winHeight = 480;
+int main_loop(const char *filename) {
 
 	if (!initSludge(filename)) {
 		return 0;
 	}
 
-	initGraphics(winWidth, winHeight, true, g_sludge->getScreenPixelFormat());
-
-	// Init screen surface
-	renderSurface.create(g_system->getWidth(), g_system->getHeight(), g_system->getScreenFormat());
+	g_sludge->_gfxMan->init();
 
 	registerWindowForFatal();
 
-	if (!killResizeBackdrop(winWidth, winHeight))
-		return fatal("Couldn't allocate memory for backdrop");
-
-	blankScreen(0, 0, winWidth, winHeight);
+	g_sludge->_gfxMan->blankAllScreen();
 	if (!initPeople())
 		return fatal("Couldn't initialise people stuff");
 	if (!initFloor())
diff --git a/engines/sludge/people.cpp b/engines/sludge/people.cpp
index ad5a234..6469681 100644
--- a/engines/sludge/people.cpp
+++ b/engines/sludge/people.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "sludge/allfiles.h"
+#include "sludge/graphics.h"
 #include "sludge/sprites.h"
 #include "sludge/sprbanks.h"
 #include "sludge/sludger.h"
@@ -477,7 +478,7 @@ void drawPeople() {
 			}
 			if (m != 2) {
 				bool r = false;
-				r = scaleSprite(myAnim->theSprites->bank.sprites[fNum], myAnim->theSprites->bank.myPalette, thisPerson, m);
+				r = g_sludge->_gfxMan->scaleSprite(myAnim->theSprites->bank.sprites[fNum], myAnim->theSprites->bank.myPalette, thisPerson, m);
 				if (r) {
 					if (!thisPerson->thisType->screenName.empty()) {
 						if (personRegion.thisType != thisPerson->thisType)
diff --git a/engines/sludge/people.h b/engines/sludge/people.h
index f11ac2f..470f352 100644
--- a/engines/sludge/people.h
+++ b/engines/sludge/people.h
@@ -41,7 +41,7 @@ struct animFrame {
 #define EXTRA_RECTANGULAR   64
 
 struct personaAnimation {
-	struct loadedSpriteBank *theSprites;
+	struct LoadedSpriteBank *theSprites;
 	animFrame *frames;
 	int numFrames;
 };
@@ -110,7 +110,7 @@ bool setCharacterWalkSpeed(int f, int objNum);
 void animatePerson(int obj, personaAnimation *);
 void animatePerson(int obj, persona *per);
 personaAnimation *createPersonaAnim(int num, struct variableStack *&stacky);
-inline void setBankFile(personaAnimation *newP, loadedSpriteBank *sB) {
+inline void setBankFile(personaAnimation *newP, LoadedSpriteBank *sB) {
 	newP->theSprites = sB;
 }
 bool setPersonExtra(int f, int newSetting);
diff --git a/engines/sludge/region.cpp b/engines/sludge/region.cpp
index 9e81809..ec4e66a 100644
--- a/engines/sludge/region.cpp
+++ b/engines/sludge/region.cpp
@@ -22,6 +22,7 @@
 
 #include "sludge/allfiles.h"
 #include "sludge/backdrop.h"
+#include "sludge/graphics.h"
 #include "sludge/moreio.h"
 #include "sludge/newfatal.h"
 #include "sludge/objtypes.h"
@@ -34,16 +35,15 @@ namespace Sludge {
 screenRegion *allScreenRegions = NULL;
 screenRegion *overRegion = NULL;
 extern inputType input;
-extern int cameraX, cameraY;
 
 void showBoxes() {
 	screenRegion *huntRegion = allScreenRegions;
 
 	while (huntRegion) {
-		drawVerticalLine(huntRegion->x1, huntRegion->y1, huntRegion->y2);
-		drawVerticalLine(huntRegion->x2, huntRegion->y1, huntRegion->y2);
-		drawHorizontalLine(huntRegion->x1, huntRegion->y1, huntRegion->x2);
-		drawHorizontalLine(huntRegion->x1, huntRegion->y2, huntRegion->x2);
+		g_sludge->_gfxMan->drawVerticalLine(huntRegion->x1, huntRegion->y1, huntRegion->y2);
+		g_sludge->_gfxMan->drawVerticalLine(huntRegion->x2, huntRegion->y1, huntRegion->y2);
+		g_sludge->_gfxMan->drawHorizontalLine(huntRegion->x1, huntRegion->y1, huntRegion->x2);
+		g_sludge->_gfxMan->drawHorizontalLine(huntRegion->x1, huntRegion->y2, huntRegion->x2);
 		huntRegion = huntRegion->next;
 	}
 }
@@ -143,6 +143,8 @@ bool addScreenRegion(int x1, int y1, int x2, int y2, int sX, int sY, int di,
 }
 
 void getOverRegion() {
+	int cameraX = g_sludge->_gfxMan->getCamX();
+	int cameraY = g_sludge->_gfxMan->getCamY();
 	screenRegion *thisRegion = allScreenRegions;
 	while (thisRegion) {
 		if ((input.mouseX >= thisRegion->x1 - cameraX)
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index 4c6c54d..10b9aa3 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -66,7 +66,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
 	_resMan = new ResourceManager();
 	_languageMan = new LanguageManager();
 	_objMan = new ObjectManager(this);
-	_gfxMan = new GraphicsManager();
+	_gfxMan = new GraphicsManager(this);
 }
 
 SludgeEngine::~SludgeEngine() {
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index e1fd3c8..029257c 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -23,32 +23,33 @@
 #include "common/debug.h"
 
 #include "sludge/allfiles.h"
-#include "sludge/sludger.h"
 #include "sludge/backdrop.h"
+#include "sludge/builtin.h"
 #include "sludge/cursors.h"
+#include "sludge/fonttext.h"
+#include "sludge/freeze.h"
+#include "sludge/floor.h"
+#include "sludge/fileset.h"
+#include "sludge/graphics.h"
+#include "sludge/imgloader.h"
+#include "sludge/loadsave.h"
+#include "sludge/language.h"
+#include "sludge/moreio.h"
+#include "sludge/newfatal.h"
 #include "sludge/objtypes.h"
+#include "sludge/people.h"
 #include "sludge/region.h"
+#include "sludge/statusba.h"
 #include "sludge/sprites.h"
 #include "sludge/sprbanks.h"
-#include "sludge/people.h"
-#include "sludge/talk.h"
-#include "sludge/newfatal.h"
-#include "sludge/moreio.h"
-#include "sludge/statusba.h"
-#include "sludge/builtin.h"
-#include "sludge/fonttext.h"
-#include "sludge/freeze.h"
-#include "sludge/floor.h"
-#include "sludge/zbuffer.h"
 #include "sludge/sound.h"
-#include "sludge/loadsave.h"
-#include "sludge/fileset.h"
+#include "sludge/sludge.h"
+#include "sludge/sludger.h"
+#include "sludge/talk.h"
 #include "sludge/transition.h"
-#include "sludge/language.h"
 #include "sludge/variable.h"
-#include "sludge/sludge.h"
 #include "sludge/version.h"
-#include "sludge/imgloader.h"
+#include "sludge/zbuffer.h"
 
 namespace Sludge {
 
@@ -56,8 +57,6 @@ extern personaAnimation *mouseCursorAnim;
 extern int dialogValue;
 extern variable *launchResult;
 
-extern Graphics::Surface renderSurface;
-
 int numBIFNames = 0;
 Common::String *allBIFNames;
 int numUserFunc = 0;
@@ -211,10 +210,12 @@ bool initSludge(const Common::String &filename) {
 		}
 	}
 
-	winWidth = fp->readUint16BE();
+	int winWidth = fp->readUint16BE();
 	debug(kSludgeDebugDataLoad, "winWidth : %i", winWidth);
-	winHeight = fp->readUint16BE();
+	int winHeight = fp->readUint16BE();
 	debug(kSludgeDebugDataLoad, "winHeight : %i", winHeight);
+	g_sludge->_gfxMan->setWindowSize(winWidth, winHeight);
+
 	int specialSettings = fp->readByte();
 	debug(kSludgeDebugDataLoad, "specialSettings : %i", specialSettings);
 	g_sludge->_timer.setDesiredfps(1000 / fp->readByte());
@@ -291,13 +292,11 @@ bool initSludge(const Common::String &filename) {
 	return true;
 }
 
-extern int cameraX, cameraY;
-
 void displayBase() {
-	drawBackDrop();// Draw the room
-	drawZBuffer(cameraX, cameraY, false);
+	g_sludge->_gfxMan->drawBackDrop();// Draw the room
+	g_sludge->_gfxMan->drawZBuffer(g_sludge->_gfxMan->getCamX(), g_sludge->_gfxMan->getCamY(), false);
 	drawPeople();// Then add any moving characters...
-	displaySpriteLayers();
+	g_sludge->_gfxMan->displaySpriteLayers();
 }
 
 void sludgeDisplay() {
@@ -305,8 +304,7 @@ void sludgeDisplay() {
 	viewSpeech();// ...and anything being said
 	drawStatusBar();
 	displayCursor();
-	g_system->copyRectToScreen((byte *)renderSurface.getPixels(), renderSurface.pitch, 0, 0, renderSurface.w, renderSurface.h);
-	g_system->updateScreen();
+	g_sludge->_gfxMan->display();
 	if (brightnessLevel < 255) fixBrightness();// This is for transitionLevel special effects
 }
 
diff --git a/engines/sludge/sprbanks.cpp b/engines/sludge/sprbanks.cpp
index 7c8ee13..d1d63c7 100644
--- a/engines/sludge/sprbanks.cpp
+++ b/engines/sludge/sprbanks.cpp
@@ -23,6 +23,7 @@
 #include "common/textconsole.h"
 
 #include "sludge/allfiles.h"
+#include "sludge/graphics.h"
 #include "sludge/sludge.h"
 #include "sludge/sprites.h"
 #include "sludge/sprbanks.h"
@@ -30,13 +31,13 @@
 
 namespace Sludge {
 
-loadedSpriteBank *allLoadedBanks = NULL;
-extern spriteBank theFont;
+LoadedSpriteBank *allLoadedBanks = NULL;
+extern SpriteBank theFont;
 extern int loadedFontNum;
 extern uint fontTableSize;
 
-loadedSpriteBank *loadBankForAnim(int ID) {
-	loadedSpriteBank *returnMe = allLoadedBanks;
+LoadedSpriteBank *loadBankForAnim(int ID) {
+	LoadedSpriteBank *returnMe = allLoadedBanks;
 	while (returnMe) {
 		if (returnMe->ID == ID) {
 			//debugOut ("loadBankForAnim: Found existing sprite bank with ID %d\n", returnMe -> ID);
@@ -44,10 +45,10 @@ loadedSpriteBank *loadBankForAnim(int ID) {
 		}
 		returnMe = returnMe->next;
 	}
-	returnMe = new loadedSpriteBank;
+	returnMe = new LoadedSpriteBank;
 	if (checkNew(returnMe)) {
 		returnMe->ID = ID;
-		if (loadSpriteBank(ID, returnMe->bank, false)) {
+		if (g_sludge->_gfxMan->loadSpriteBank(ID, returnMe->bank, false)) {
 			returnMe->timesUsed = 0;
 			returnMe->next = allLoadedBanks;
 			allLoadedBanks = returnMe;
@@ -62,18 +63,18 @@ loadedSpriteBank *loadBankForAnim(int ID) {
 }
 
 void reloadSpriteTextures() {
-	loadedSpriteBank *spriteBank = allLoadedBanks;
+	LoadedSpriteBank *spriteBank = allLoadedBanks;
 	while (spriteBank) {
 		//fprintf (stderr, "Reloading bank %d: %s.\n", spriteBank->ID, resourceNameFromNum (spriteBank->ID));
 		delete spriteBank->bank.sprites;
 		spriteBank->bank.sprites = NULL;
-		loadSpriteBank(spriteBank->ID, spriteBank->bank, false);
+		g_sludge->_gfxMan->loadSpriteBank(spriteBank->ID, spriteBank->bank, false);
 		spriteBank = spriteBank->next;
 	}
 	if (fontTableSize) {
 		delete theFont.sprites;
 		theFont.sprites = NULL;
-		loadSpriteBank(loadedFontNum, theFont, true);
+		g_sludge->_gfxMan->loadSpriteBank(loadedFontNum, theFont, true);
 	}
 }
 
diff --git a/engines/sludge/sprbanks.h b/engines/sludge/sprbanks.h
index 6372a82..bbf046a 100644
--- a/engines/sludge/sprbanks.h
+++ b/engines/sludge/sprbanks.h
@@ -26,13 +26,13 @@
 
 namespace Sludge {
 
-struct loadedSpriteBank {
+struct LoadedSpriteBank {
 	int ID, timesUsed;
-	spriteBank bank;
-	loadedSpriteBank *next;
+	SpriteBank bank;
+	LoadedSpriteBank *next;
 };
 
-loadedSpriteBank *loadBankForAnim(int ID);
+LoadedSpriteBank *loadBankForAnim(int ID);
 void reloadSpriteTextures();
 
 } // End of namespace Sludge
diff --git a/engines/sludge/sprites.cpp b/engines/sludge/sprites.cpp
index ce8d61e..7c9f9f1 100644
--- a/engines/sludge/sprites.cpp
+++ b/engines/sludge/sprites.cpp
@@ -25,6 +25,7 @@
 
 #include "sludge/allfiles.h"
 #include "sludge/fileset.h"
+#include "sludge/graphics.h"
 #include "sludge/people.h"
 #include "sludge/sprites.h"
 #include "sludge/moreio.h"
@@ -37,38 +38,8 @@
 
 namespace Sludge {
 
-// Sprite display informations
-struct SpriteDisplay {
-	int x, y;
-	int width, height;
-	uint32 color;
-	Graphics::FLIP_FLAGS flip;
-	Graphics::Surface *surface;
-
-	SpriteDisplay(int xpos, int ypos, Graphics::FLIP_FLAGS f, Graphics::Surface *ptr, int w = -1, int h = 1, uint32 c = TS_ARGB(255, 255, 255, 255)) :
-			x(xpos), y(ypos), flip(f), surface(ptr), width(w), height(h), color(c) {
-	}
-};
-
-// All sprites are sorted into different "layers" (up to 16) according to their relative y position to z-buffer zones
-struct SpriteLayers {
-	int numLayers;
-	Common::List<SpriteDisplay> layer[16];
-};
-
-SpriteLayers spriteLayers;
-
-extern zBufferData zBuffer;
-
 extern inputType input;
-extern int cameraX, cameraY;
-extern float cameraZoom;
-extern Graphics::Surface renderSurface;
-extern Graphics::Surface backdropSurface;
-
-byte currentBurnR = 0, currentBurnG = 0, currentBurnB = 0;
-
-void forgetSpriteBank(spriteBank &forgetme) {
+void GraphicsManager::forgetSpriteBank(SpriteBank &forgetme) {
 	if (forgetme.myPalette.pal) {
 		delete[] forgetme.myPalette.pal;
 		forgetme.myPalette.pal = NULL;
@@ -92,7 +63,7 @@ void forgetSpriteBank(spriteBank &forgetme) {
 	// And add a function call for this function to the scripting language
 }
 
-bool reserveSpritePal(spritePalette &sP, int n) {
+bool GraphicsManager::reserveSpritePal(SpritePalette &sP, int n) {
 	if (sP.pal) {
 		delete[] sP.pal;
 		delete[] sP.r;
@@ -117,7 +88,7 @@ bool reserveSpritePal(spritePalette &sP, int n) {
 	return (bool)(sP.pal != NULL) && (sP.r != NULL) && (sP.g != NULL) && (sP.b != NULL);
 }
 
-bool loadSpriteBank(int fileNum, spriteBank &loadhere, bool isFont) {
+bool GraphicsManager::loadSpriteBank(int fileNum, SpriteBank &loadhere, bool isFont) {
 
 	int total, spriteBankVersion = 0, howmany = 0, startIndex = 0;
 	byte *data;
@@ -145,7 +116,7 @@ bool loadSpriteBank(int fileNum, spriteBank &loadhere, bool isFont) {
 		return fatal("Unsupported sprite bank file format");
 
 	loadhere.total = total;
-	loadhere.sprites = new sprite[total];
+	loadhere.sprites = new Sprite[total];
 	if (!checkNew(loadhere.sprites))
 		return false;
 	byte **spriteData = new byte *[total];
@@ -299,62 +270,60 @@ bool loadSpriteBank(int fileNum, spriteBank &loadhere, bool isFont) {
 }
 
 // pasteSpriteToBackDrop uses the colour specified by the setPasteColour (or setPasteColor)
-void pasteSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal) {
+void GraphicsManager::pasteSpriteToBackDrop(int x1, int y1, Sprite &single, const SpritePalette &fontPal) {
 	//TODO: shader: useLightTexture
 	x1 -= single.xhot;
 	y1 -= single.yhot;
 	Graphics::TransparentSurface tmp(single.surface, false);
-	tmp.blit(backdropSurface, x1, y1, Graphics::FLIP_NONE, nullptr,
+	tmp.blit(_backdropSurface, x1, y1, Graphics::FLIP_NONE, nullptr,
 			TS_RGB(fontPal.originalRed, fontPal.originalGreen, fontPal.originalBlue));
 
 	// reset zBuffer with the new backdrop
-	if (zBuffer.numPanels) {
-		setZBuffer(zBuffer.originalNum);
+	if (_zBuffer->numPanels) {
+		setZBuffer(_zBuffer->originalNum);
 	}
 }
 
 // burnSpriteToBackDrop adds text in the colour specified by setBurnColour
 // using the differing brightness levels of the font to achieve an anti-aliasing effect.
-void burnSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal) {
+void GraphicsManager::burnSpriteToBackDrop(int x1, int y1, Sprite &single, const SpritePalette &fontPal) {
 	//TODO: shader: useLightTexture
 	x1 -= single.xhot;
 	y1 -= single.yhot - 1;
 	Graphics::TransparentSurface tmp(single.surface, false);
-	tmp.blit(backdropSurface, x1, y1, Graphics::FLIP_NONE, nullptr,
-			TS_RGB(currentBurnR, currentBurnG, currentBurnB));
+	tmp.blit(_backdropSurface, x1, y1, Graphics::FLIP_NONE, nullptr,
+			TS_RGB(_currentBurnR, _currentBurnG, _currentBurnB));
 
 	// reset zBuffer with the new backdrop
-	if (zBuffer.numPanels) {
-		setZBuffer(zBuffer.originalNum);
+	if (_zBuffer->numPanels) {
+		setZBuffer(_zBuffer->originalNum);
 	}
 }
 
-void fontSprite(bool flip, int x, int y, sprite &single, const spritePalette &fontPal) {
-	float x1 = (float)x - (float)single.xhot / cameraZoom;
-	float y1 = (float)y - (float)single.yhot / cameraZoom;
+void GraphicsManager::fontSprite(bool flip, int x, int y, Sprite &single, const SpritePalette &fontPal) {
+	float x1 = (float)x - (float)single.xhot / _cameraZoom;
+	float y1 = (float)y - (float)single.yhot / _cameraZoom;
 
 	// Use Transparent surface to scale and blit
 	Graphics::TransparentSurface tmp(single.surface, false);
-	tmp.blit(renderSurface, x1, y1, (flip ? Graphics::FLIP_H : Graphics::FLIP_NONE), 0, TS_RGB(fontPal.originalRed, fontPal.originalGreen, fontPal.originalBlue));
+	tmp.blit(_renderSurface, x1, y1, (flip ? Graphics::FLIP_H : Graphics::FLIP_NONE), 0, TS_RGB(fontPal.originalRed, fontPal.originalGreen, fontPal.originalBlue));
 
 	if (single.burnSurface.getPixels() != nullptr) {
 		Graphics::TransparentSurface tmp2(single.burnSurface, false);
-		tmp2.blit(renderSurface, x1, y1, (flip ? Graphics::FLIP_H : Graphics::FLIP_NONE), 0, TS_RGB(fontPal.originalRed, fontPal.originalGreen, fontPal.originalBlue));
+		tmp2.blit(_renderSurface, x1, y1, (flip ? Graphics::FLIP_H : Graphics::FLIP_NONE), 0, TS_RGB(fontPal.originalRed, fontPal.originalGreen, fontPal.originalBlue));
 
 	}
 }
 
-void fontSprite(int x, int y, sprite &single, const spritePalette &fontPal) {
+void GraphicsManager::fontSprite(int x, int y, Sprite &single, const SpritePalette &fontPal) {
 	fontSprite(false, x, y, single, fontPal);
 }
 
-void flipFontSprite(int x, int y, sprite &single, const spritePalette &fontPal) {
+void GraphicsManager::flipFontSprite(int x, int y, Sprite &single, const SpritePalette &fontPal) {
 	fontSprite(true, x, y, single, fontPal);
 }
 
-byte curLight[3];
-
-uint32 getDrawColor(onScreenPerson *thisPerson) {
+uint32 GraphicsManager::getDrawColor(onScreenPerson *thisPerson) {
 //TODO: how to mix secondary color
 #if 0
 	if (thisPerson->colourmix) {
@@ -364,12 +333,12 @@ uint32 getDrawColor(onScreenPerson *thisPerson) {
 #endif
 
 	return TS_ARGB((uint8)(255 - thisPerson->transparency),
-			(uint8)(curLight[0] * (255 - thisPerson->colourmix) / 255.f),
-			(uint8)(curLight[1] * (255 - thisPerson->colourmix) / 255.f),
-			(uint8)(curLight[2] * (255 - thisPerson->colourmix) / 255.f));
+			(uint8)(_curLight[0] * (255 - thisPerson->colourmix) / 255.f),
+			(uint8)(_curLight[1] * (255 - thisPerson->colourmix) / 255.f),
+			(uint8)(_curLight[2] * (255 - thisPerson->colourmix) / 255.f));
 }
 
-bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, bool mirror) {
+bool GraphicsManager::scaleSprite(Sprite &single, const SpritePalette &fontPal, onScreenPerson *thisPerson, bool mirror) {
 	float x = thisPerson->x;
 	float y = thisPerson->y;
 
@@ -385,18 +354,18 @@ bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *t
 	float x1, y1, x2, y2;
 
 	if (thisPerson->extra & EXTRA_FIXTOSCREEN) {
-		x = x / cameraZoom;
-		y = y / cameraZoom;
+		x = x / _cameraZoom;
+		y = y / _cameraZoom;
 		if (single.xhot < 0)
-			x1 = x - (int)((mirror ? (float)(single.surface.w - single.xhot) : (float)(single.xhot + 1)) * scale / cameraZoom);
+			x1 = x - (int)((mirror ? (float)(single.surface.w - single.xhot) : (float)(single.xhot + 1)) * scale / _cameraZoom);
 		else
-			x1 = x - (int)((mirror ? (float)(single.surface.w - (single.xhot + 1)) : (float)single.xhot) * scale / cameraZoom);
-		y1 = y - (int)((single.yhot - thisPerson->floaty) * scale / cameraZoom);
-		x2 = x1 + (int)(diffX / cameraZoom);
-		y2 = y1 + (int)(diffY / cameraZoom);
+			x1 = x - (int)((mirror ? (float)(single.surface.w - (single.xhot + 1)) : (float)single.xhot) * scale / _cameraZoom);
+		y1 = y - (int)((single.yhot - thisPerson->floaty) * scale / _cameraZoom);
+		x2 = x1 + (int)(diffX / _cameraZoom);
+		y2 = y1 + (int)(diffY / _cameraZoom);
 	} else {
-		x -= cameraX;
-		y -= cameraY;
+		x -= _cameraX;
+		y -= _cameraY;
 		if (single.xhot < 0)
 			x1 = x - (int)((mirror ? (float)(single.surface.w - single.xhot) : (float)(single.xhot + 1)) * scale);
 		else
@@ -407,32 +376,32 @@ bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *t
 	}
 
 	// set light map color
-	if (light && lightMap.getPixels()) {
-		if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
-			int lx = x + cameraX;
-			int ly = y + cameraY;
-			if (lx < 0 || ly < 0 || lx >= (int)sceneWidth || ly >= (int)sceneHeight) {
-				curLight[0] = curLight[1] = curLight[2] = 255;
+	if (light && _lightMap.getPixels()) {
+		if (_lightMapMode == LIGHTMAPMODE_HOTSPOT) {
+			int lx = x + _cameraX;
+			int ly = y + _cameraY;
+			if (lx < 0 || ly < 0 || lx >= (int)_sceneWidth || ly >= (int)_sceneHeight) {
+				_curLight[0] = _curLight[1] = _curLight[2] = 255;
 			} else {
-				byte *target = (byte *)lightMap.getBasePtr(lx, ly);
-				curLight[0] = target[3];
-				curLight[1] = target[2];
-				curLight[2] = target[1];
+				byte *target = (byte *)_lightMap.getBasePtr(lx, ly);
+				_curLight[0] = target[3];
+				_curLight[1] = target[2];
+				_curLight[2] = target[1];
 			}
-		} else if (lightMapMode == LIGHTMAPMODE_PIXEL) {
-			curLight[0] = curLight[1] = curLight[2] = 255;
+		} else if (_lightMapMode == LIGHTMAPMODE_PIXEL) {
+			_curLight[0] = _curLight[1] = _curLight[2] = 255;
 		}
 	} else {
-		curLight[0] = curLight[1] = curLight[2] = 255;
+		_curLight[0] = _curLight[1] = _curLight[2] = 255;
 	}
 
 	// Use Transparent surface to scale and blit
 	uint32 spriteColor = getDrawColor(thisPerson);
-	if (!zBuffer.numPanels) {
+	if (!_zBuffer->numPanels) {
 		Graphics::TransparentSurface tmp(single.surface, false);
-		tmp.blit(renderSurface, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), nullptr, spriteColor, diffX, diffY);
+		tmp.blit(_renderSurface, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), nullptr, spriteColor, diffX, diffY);
 	} else {
-		int d = ((!(thisPerson->extra & EXTRA_NOZB)) && zBuffer.numPanels) ? y + cameraY : sceneHeight + 1;
+		int d = ((!(thisPerson->extra & EXTRA_NOZB)) && _zBuffer->numPanels) ? y + _cameraY : _sceneHeight + 1;
 		addSpriteDepth(&single.surface, d, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), diffX, diffY, spriteColor);
 	}
 
@@ -453,48 +422,48 @@ bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *t
 	return false;
 }
 
-void resetSpriteLayers(zBufferData *pz, int x, int y, bool upsidedown) {
-	if (spriteLayers.numLayers > 0)
+void GraphicsManager::resetSpriteLayers(ZBufferData *pz, int x, int y, bool upsidedown) {
+	if (_spriteLayers->numLayers > 0)
 		killSpriteLayers();
-	spriteLayers.numLayers = pz->numPanels;
-	for (int i = 0; i < spriteLayers.numLayers; ++i) {
+	_spriteLayers->numLayers = pz->numPanels;
+	for (int i = 0; i < _spriteLayers->numLayers; ++i) {
 		SpriteDisplay node(x, y, (upsidedown ? Graphics::FLIP_V : Graphics::FLIP_NONE), &pz->sprites[i], pz->sprites[i].w, pz->sprites[i].h);
-		spriteLayers.layer[i].push_back(node);
+		_spriteLayers->layer[i].push_back(node);
 	}
 }
 
-void addSpriteDepth(Graphics::Surface *ptr, int depth, int x, int y, Graphics::FLIP_FLAGS flip, int width, int height, uint32 color) {
+void GraphicsManager::addSpriteDepth(Graphics::Surface *ptr, int depth, int x, int y, Graphics::FLIP_FLAGS flip, int width, int height, uint32 color) {
 	int i;
-	for (i = 1; i < zBuffer.numPanels; ++i) {
-		if (zBuffer.panel[i] >= depth) {
+	for (i = 1; i < _zBuffer->numPanels; ++i) {
+		if (_zBuffer->panel[i] >= depth) {
 			break;
 		}
 	}
 	--i;
 	SpriteDisplay node(x, y, flip, ptr, width, height, color);
-	spriteLayers.layer[i].push_back(node);
+	_spriteLayers->layer[i].push_back(node);
 }
 
-void displaySpriteLayers() {
-	for (int i = 0; i < spriteLayers.numLayers; ++i) {
+void GraphicsManager::displaySpriteLayers() {
+	for (int i = 0; i < _spriteLayers->numLayers; ++i) {
 		Common::List<SpriteDisplay>::iterator it;
-		for (it = spriteLayers.layer[i].begin(); it != spriteLayers.layer[i].end(); ++it) {
+		for (it = _spriteLayers->layer[i].begin(); it != _spriteLayers->layer[i].end(); ++it) {
 			Graphics::TransparentSurface tmp(*it->surface, false);
-			tmp.blit(renderSurface, it->x, it->y, it->flip, nullptr, it->color, it->width, it->height);
+			tmp.blit(_renderSurface, it->x, it->y, it->flip, nullptr, it->color, it->width, it->height);
 		}
 	}
 	killSpriteLayers();
 }
 
-void killSpriteLayers() {
-	for (int i = 0; i < spriteLayers.numLayers; ++i) {
-		spriteLayers.layer[i].clear();
+void GraphicsManager::killSpriteLayers() {
+	for (int i = 0; i < _spriteLayers->numLayers; ++i) {
+		_spriteLayers->layer[i].clear();
 	}
-	spriteLayers.numLayers = 0;
+	_spriteLayers->numLayers = 0;
 }
 
 // Paste a scaled sprite onto the backdrop
-void fixScaleSprite(int x, int y, sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, int camX, int camY, bool mirror) {
+void GraphicsManager::fixScaleSprite(int x, int y, Sprite &single, const SpritePalette &fontPal, onScreenPerson *thisPerson, int camX, int camY, bool mirror) {
 
 	float scale = thisPerson->scale;
 	bool useZB = !(thisPerson->extra & EXTRA_NOZB);
@@ -513,40 +482,40 @@ void fixScaleSprite(int x, int y, sprite &single, const spritePalette &fontPal,
 	int y1 = y - (int)((single.yhot - thisPerson->floaty) * scale);
 
 	// set light map color
-	if (light && lightMap.getPixels()) {
-		if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
-			int lx = x + cameraX;
-			int ly = y + cameraY;
-			if (lx < 0 || ly < 0 || lx >= (int)sceneWidth || ly >= (int)sceneHeight) {
-				curLight[0] = curLight[1] = curLight[2] = 255;
+	if (light && _lightMap.getPixels()) {
+		if (_lightMapMode == LIGHTMAPMODE_HOTSPOT) {
+			int lx = x + _cameraX;
+			int ly = y + _cameraY;
+			if (lx < 0 || ly < 0 || lx >= (int)_sceneWidth || ly >= (int)_sceneHeight) {
+				_curLight[0] = _curLight[1] = _curLight[2] = 255;
 			} else {
-				byte *target = (byte *)lightMap.getBasePtr(lx, ly);
-				curLight[0] = target[3];
-				curLight[1] = target[2];
-				curLight[2] = target[1];
+				byte *target = (byte *)_lightMap.getBasePtr(lx, ly);
+				_curLight[0] = target[3];
+				_curLight[1] = target[2];
+				_curLight[2] = target[1];
 			}
-		} else if (lightMapMode == LIGHTMAPMODE_PIXEL) {
-			curLight[0] = curLight[1] = curLight[2] = 255;
+		} else if (_lightMapMode == LIGHTMAPMODE_PIXEL) {
+			_curLight[0] = _curLight[1] = _curLight[2] = 255;
 		}
 	} else {
-		curLight[0] = curLight[1] = curLight[2] = 255;
+		_curLight[0] = _curLight[1] = _curLight[2] = 255;
 	}
 
 	// draw backdrop
 	drawBackDrop();
 
 	// draw zBuffer
-	if (zBuffer.numPanels) {
+	if (_zBuffer->numPanels) {
 		drawZBuffer((int)(x1 + camX), (int)(y1 + camY), false);
 	}
 
 	// draw sprite
 	uint32 spriteColor = getDrawColor(thisPerson);
-	if (!zBuffer.numPanels) {
+	if (!_zBuffer->numPanels) {
 		Graphics::TransparentSurface tmp(single.surface, false);
-		tmp.blit(renderSurface, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), nullptr, spriteColor, diffX, diffY);
+		tmp.blit(_renderSurface, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), nullptr, spriteColor, diffX, diffY);
 	} else {
-		int d = useZB ? y + cameraY : sceneHeight + 1;
+		int d = useZB ? y + _cameraY : _sceneHeight + 1;
 		addSpriteDepth(&single.surface, d, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), diffX, diffY, spriteColor);
 	}
 
@@ -554,11 +523,11 @@ void fixScaleSprite(int x, int y, sprite &single, const spritePalette &fontPal,
 	displaySpriteLayers();
 
 	// copy screen to backdrop
-	backdropSurface.copyFrom(renderSurface);
+	_backdropSurface.copyFrom(_renderSurface);
 
 	// reset zBuffer with the new backdrop
-	if (zBuffer.numPanels) {
-		setZBuffer(zBuffer.originalNum);
+	if (_zBuffer->numPanels) {
+		setZBuffer(_zBuffer->originalNum);
 	}
 }
 
diff --git a/engines/sludge/sprites.h b/engines/sludge/sprites.h
index e0ea21a..434b989 100644
--- a/engines/sludge/sprites.h
+++ b/engines/sludge/sprites.h
@@ -27,16 +27,13 @@
 
 namespace Sludge {
 
-struct onScreenPerson;
-struct zBufferData;
-
-struct sprite {
+struct Sprite {
 	int xhot, yhot;
 	Graphics::Surface surface;
 	Graphics::Surface burnSurface;
 };
 
-class spritePalette {
+class SpritePalette {
 public:
 	uint16 *pal;
 	byte *r;
@@ -44,11 +41,11 @@ public:
 	byte *b;
 	byte originalRed, originalGreen, originalBlue, total;
 
-	spritePalette() : pal(0), r(0), g(0), b(0), total(0) {
+	SpritePalette() : pal(0), r(0), g(0), b(0), total(0) {
 		originalRed = originalGreen = originalBlue = 255;
 	}
 
-	~spritePalette() {
+	~SpritePalette() {
 		delete[] pal;
 		delete[] r;
 		delete[] g;
@@ -56,31 +53,32 @@ public:
 	}
 };
 
-struct spriteBank {
+struct SpriteBank {
 	int total;
 	int type;
-	sprite *sprites;
-	spritePalette myPalette;
+	Sprite *sprites;
+	SpritePalette myPalette;
 	bool isFont;
 };
 
-void forgetSpriteBank(spriteBank &forgetme);
-bool loadSpriteBank(char *filename, spriteBank &loadhere);
-bool loadSpriteBank(int fileNum, spriteBank &loadhere, bool isFont);
-
-void fontSprite(int x1, int y1, sprite &single, const spritePalette &fontPal);
-void flipFontSprite(int x1, int y1, sprite &single, const spritePalette &fontPal);
+// Sprite display informations
+struct SpriteDisplay {
+	int x, y;
+	int width, height;
+	uint32 color;
+	Graphics::FLIP_FLAGS flip;
+	Graphics::Surface *surface;
 
-bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, bool mirror);
-void pasteSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal);
-bool reserveSpritePal(spritePalette &sP, int n);
-void fixScaleSprite(int x1, int y1, sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, const int camX, const int camY, bool);
-void burnSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal);
+	SpriteDisplay(int xpos, int ypos, Graphics::FLIP_FLAGS f, Graphics::Surface *ptr, int w = -1, int h = 1, uint32 c = TS_ARGB(255, 255, 255, 255)) :
+			x(xpos), y(ypos), flip(f), surface(ptr), width(w), height(h), color(c) {
+	}
+};
 
-void resetSpriteLayers(zBufferData *ptrZBuffer, int x, int y, bool upsidedown);
-void addSpriteDepth(Graphics::Surface *ptr, int depth, int x, int y, Graphics::FLIP_FLAGS flip, int width = -1, int height = -1, uint32 color = TS_ARGB(255, 255, 255, 255));
-void displaySpriteLayers();
-void killSpriteLayers();
+// All sprites are sorted into different "layers" (up to 16) according to their relative y position to z-buffer zones
+struct SpriteLayers {
+	int numLayers;
+	Common::List<SpriteDisplay> layer[16];
+};
 
 } // End of namespace Sludge
 
diff --git a/engines/sludge/statusba.cpp b/engines/sludge/statusba.cpp
index 79c4f01..04902ed 100644
--- a/engines/sludge/statusba.cpp
+++ b/engines/sludge/statusba.cpp
@@ -26,19 +26,20 @@
 #include "sludge/backdrop.h"
 #include "sludge/sprites.h"
 #include "sludge/fonttext.h"
+#include "sludge/graphics.h"
 #include "sludge/moreio.h"
 #include "sludge/newfatal.h"
+#include "sludge/sludge.h"
 #include "sludge/statusba.h"
 
 namespace Sludge {
 
-spritePalette verbLinePalette;
-spritePalette litVerbLinePalette;
+SpritePalette verbLinePalette;
+SpritePalette litVerbLinePalette;
 
 statusStuff mainStatus;
 statusStuff *nowStatus = & mainStatus;
 extern int fontHeight;
-extern float cameraZoom;
 
 void setLitStatus(int i) {
 	nowStatus->litStatus = i;
@@ -86,16 +87,17 @@ void positionStatus(int x, int y) {
 }
 
 void drawStatusBar() {
+	float cameraZoom = g_sludge->_gfxMan->getCamZoom();
 	int y = nowStatus->statusY, n = 0;
 	statusBar *stat = nowStatus->firstStatusBar;
 	while (stat) {
 		switch (nowStatus->alignStatus) {
 		case IN_THE_CENTRE:
-			pasteString(stat->text, ((winWidth - stringWidth(stat->text)) >> 1) / cameraZoom, y / cameraZoom, (n ++ == nowStatus->litStatus) ? litVerbLinePalette : verbLinePalette);
+			pasteString(stat->text, ((g_system->getWidth() - stringWidth(stat->text)) >> 1) / cameraZoom, y / cameraZoom, (n++ == nowStatus->litStatus) ? litVerbLinePalette : verbLinePalette);
 			break;
 
 		case 1001:
-			pasteString(stat->text, (winWidth - stringWidth(stat->text)) - nowStatus->statusX / cameraZoom, y / cameraZoom, (n ++ == nowStatus->litStatus) ? litVerbLinePalette : verbLinePalette);
+			pasteString(stat->text, (g_system->getWidth() - stringWidth(stat->text)) - nowStatus->statusX / cameraZoom, y / cameraZoom, (n ++ == nowStatus->litStatus) ? litVerbLinePalette : verbLinePalette);
 			break;
 
 		default:
@@ -156,7 +158,7 @@ void initStatusBar() {
 	mainStatus.alignStatus = IN_THE_CENTRE;
 	mainStatus.litStatus = -1;
 	mainStatus.statusX = 10;
-	mainStatus.statusY = winHeight - 15;
+	mainStatus.statusY = g_system->getHeight() - 15;
 	statusBarColour(255, 255, 255);
 	statusBarLitColour(255, 255, 128);
 }
diff --git a/engines/sludge/talk.cpp b/engines/sludge/talk.cpp
index bdfe431..32bad40 100644
--- a/engines/sludge/talk.cpp
+++ b/engines/sludge/talk.cpp
@@ -22,6 +22,7 @@
 
 #include "sludge/allfiles.h"
 #include "sludge/backdrop.h"
+#include "sludge/graphics.h"
 #include "sludge/sprites.h"
 #include "sludge/sludger.h"
 #include "sludge/objtypes.h"
@@ -37,8 +38,7 @@
 
 namespace Sludge {
 
-extern int fontHeight, cameraX, cameraY, speechMode;
-extern float cameraZoom;
+extern int fontHeight, speechMode;
 speechStruct *speech;
 float speechSpeed = 1;
 
@@ -77,6 +77,7 @@ inline void setObjFontColour(ObjectType *t) {
 }
 
 void addSpeechLine(const Common::String &theLine, int x, int &offset) {
+	float cameraZoom = g_sludge->_gfxMan->getCamZoom();
 	int halfWidth = (stringWidth(theLine) >> 1) / cameraZoom;
 	int xx1 = x - (halfWidth);
 	int xx2 = x + (halfWidth);
@@ -90,9 +91,9 @@ void addSpeechLine(const Common::String &theLine, int x, int &offset) {
 	speech->allSpeech = newLine;
 	if ((xx1 < 5) && (offset < (5 - xx1))) {
 		offset = 5 - xx1;
-	} else if ((xx2 >= ((float) winWidth / cameraZoom) - 5)
-			&& (offset > (((float) winWidth / cameraZoom) - 5 - xx2))) {
-		offset = ((float) winWidth / cameraZoom) - 5 - xx2;
+	} else if ((xx2 >= ((float) g_system->getWidth() / cameraZoom) - 5)
+			&& (offset > (((float) g_system->getWidth() / cameraZoom) - 5 - xx2))) {
+		offset = ((float) g_system->getWidth() / cameraZoom) - 5 - xx2;
 	}
 }
 
@@ -101,6 +102,9 @@ int isThereAnySpeechGoingOn() {
 }
 
 int wrapSpeechXY(const Common::String &theText, int x, int y, int wrap, int sampleFile) {
+	float cameraZoom = g_sludge->_gfxMan->getCamZoom();
+	int cameraY = g_sludge->_gfxMan->getCamY();
+
 	int a, offset = 0;
 
 	killAllSpeech();
@@ -143,10 +147,9 @@ int wrapSpeechXY(const Common::String &theText, int x, int y, int wrap, int samp
 
 	if (y < 0)
 		speech->speechY -= y;
-	else if (speech->speechY
-			> cameraY + (float) (winHeight - fontHeight / 3) / cameraZoom)
+	else if (speech->speechY > cameraY + (float) (g_system->getHeight() - fontHeight / 3) / cameraZoom)
 		speech->speechY = cameraY
-				+ (float) (winHeight - fontHeight / 3) / cameraZoom;
+				+ (float) (g_system->getHeight() - fontHeight / 3) / cameraZoom;
 
 	if (offset) {
 		speechLine *viewLine = speech->allSpeech;
@@ -158,8 +161,9 @@ int wrapSpeechXY(const Common::String &theText, int x, int y, int wrap, int samp
 	return speechTime;
 }
 
-int wrapSpeechPerson(const Common::String &theText, onScreenPerson &thePerson, int sampleFile,
-		bool animPerson) {
+int wrapSpeechPerson(const Common::String &theText, onScreenPerson &thePerson, int sampleFile, bool animPerson) {
+	int cameraX = g_sludge->_gfxMan->getCamX();
+	int cameraY = g_sludge->_gfxMan->getCamY();
 	int i = wrapSpeechXY(theText, thePerson.x - cameraX,
 			thePerson.y - cameraY
 					- (thePerson.scale * (thePerson.height - thePerson.floaty))
@@ -174,6 +178,8 @@ int wrapSpeechPerson(const Common::String &theText, onScreenPerson &thePerson, i
 
 int wrapSpeech(const Common::String &theText, int objT, int sampleFile, bool animPerson) {
 	int i;
+	int cameraX = g_sludge->_gfxMan->getCamX();
+	int cameraY = g_sludge->_gfxMan->getCamY();
 
 	speech->lookWhosTalking = objT;
 	onScreenPerson *thisPerson = findPerson(objT);
@@ -191,7 +197,7 @@ int wrapSpeech(const Common::String &theText, int objT, int sampleFile, bool ani
 		} else {
 			ObjectType *temp = g_sludge->_objMan->findObjectType(objT);
 			setObjFontColour(temp);
-			i = wrapSpeechXY(theText, winWidth >> 1, 10, temp->wrapSpeech,
+			i = wrapSpeechXY(theText, g_system->getWidth() >> 1, 10, temp->wrapSpeech,
 					sampleFile);
 		}
 	}
@@ -199,6 +205,7 @@ int wrapSpeech(const Common::String &theText, int objT, int sampleFile, bool ani
 }
 
 void viewSpeech() {
+	float cameraZoom = g_sludge->_gfxMan->getCamZoom();
 	int viewY = speech->speechY;
 	speechLine *viewLine = speech->allSpeech;
 	while (viewLine) {
diff --git a/engines/sludge/talk.h b/engines/sludge/talk.h
index 68c81c4..de535ad 100644
--- a/engines/sludge/talk.h
+++ b/engines/sludge/talk.h
@@ -36,7 +36,7 @@ struct speechStruct {
 	onScreenPerson *currentTalker;
 	speechLine *allSpeech;
 	int speechY, lastFile, lookWhosTalking;
-	spritePalette talkCol;
+	SpritePalette talkCol;
 };
 
 int wrapSpeech(const Common::String &theText, int objT, int sampleFile, bool);
diff --git a/engines/sludge/zbuffer.cpp b/engines/sludge/zbuffer.cpp
index b01bc9f..5b6235a 100644
--- a/engines/sludge/zbuffer.cpp
+++ b/engines/sludge/zbuffer.cpp
@@ -27,6 +27,7 @@
 #include "sludge/allfiles.h"
 #include "sludge/zbuffer.h"
 #include "sludge/fileset.h"
+#include "sludge/graphics.h"
 #include "sludge/moreio.h"
 #include "sludge/newfatal.h"
 #include "sludge/sludge.h"
@@ -34,24 +35,19 @@
 
 namespace Sludge {
 
-int zBufferToSet = -1;
-zBufferData zBuffer;
-extern uint sceneWidth, sceneHeight;
-extern Graphics::Surface backdropSurface;
-
-void killZBuffer() {
-	if (zBuffer.sprites) {
-		for (int i = 0; i < zBuffer.numPanels; ++i) {
-			zBuffer.sprites[i].free();
+void GraphicsManager::killZBuffer() {
+	if (_zBuffer->sprites) {
+		for (int i = 0; i < _zBuffer->numPanels; ++i) {
+			_zBuffer->sprites[i].free();
 		}
-		delete []zBuffer.sprites;
-		zBuffer.sprites = nullptr;
+		delete []_zBuffer->sprites;
+		_zBuffer->sprites = nullptr;
 	}
-	zBuffer.numPanels = 0;
-	zBuffer.originalNum = 0;
+	_zBuffer->numPanels = 0;
+	_zBuffer->originalNum = 0;
 }
 
-void sortZPal(int *oldpal, int *newpal, int size) {
+void GraphicsManager::sortZPal(int *oldpal, int *newpal, int size) {
 	int i, tmp;
 
 	for (i = 0; i < size; i++) {
@@ -71,11 +67,11 @@ void sortZPal(int *oldpal, int *newpal, int size) {
 	}
 }
 
-bool setZBuffer(int num) {
+bool GraphicsManager::setZBuffer(int num) {
 	// if the backdrop has not been set yet
 	// set zbuffer later
-	if (!backdropSurface.getPixels()) {
-		zBufferToSet = num;
+	if (!_backdropSurface.getPixels()) {
+		_zBufferToSet = num;
 		return true;
 	}
 
@@ -87,7 +83,7 @@ bool setZBuffer(int num) {
 
 	setResourceForFatal(num);
 
-	zBuffer.originalNum = num;
+	_zBuffer->originalNum = num;
 	if (!g_sludge->_resMan->openFileFromNum(num))
 		return false;
 	Common::ReadStream *readStream = g_sludge->_resMan->getData();
@@ -113,33 +109,33 @@ bool setZBuffer(int num) {
 		default:
 			return fatal("Extended Z-buffer format not supported in this version of the SLUDGE engine");
 	}
-	if (width != sceneWidth || height != sceneHeight) {
-		Common::String tmp = Common::String::format("Z-w: %d Z-h:%d w: %d, h:%d", width, height, sceneWidth, sceneHeight);
+	if (width != _sceneWidth || height != _sceneHeight) {
+		Common::String tmp = Common::String::format("Z-w: %d Z-h:%d w: %d, h:%d", width, height, _sceneWidth, _sceneHeight);
 		return fatal("Z-buffer width and height don't match scene width and height", tmp);
 	}
 
-	zBuffer.numPanels = readStream->readByte();
-	for (int y = 0; y < zBuffer.numPanels; y++) {
+	_zBuffer->numPanels = readStream->readByte();
+	for (int y = 0; y < _zBuffer->numPanels; y++) {
 		yPalette[y] = readStream->readUint16BE();
 	}
-	sortZPal(yPalette, sorted, zBuffer.numPanels);
-	for (int y = 0; y < zBuffer.numPanels; y++) {
-		zBuffer.panel[y] = yPalette[sorted[y]];
+	sortZPal(yPalette, sorted, _zBuffer->numPanels);
+	for (int y = 0; y < _zBuffer->numPanels; y++) {
+		_zBuffer->panel[y] = yPalette[sorted[y]];
 		sortback[sorted[y]] = y;
 	}
 
-	int picWidth = sceneWidth;
-	int picHeight = sceneHeight;
+	int picWidth = _sceneWidth;
+	int picHeight = _sceneHeight;
 
-	zBuffer.sprites = nullptr;
-	zBuffer.sprites = new Graphics::Surface[zBuffer.numPanels];
+	_zBuffer->sprites = nullptr;
+	_zBuffer->sprites = new Graphics::Surface[_zBuffer->numPanels];
 
-	for (int i = 0; i < zBuffer.numPanels; ++i) {
-		zBuffer.sprites[i].create(picWidth, picHeight, *g_sludge->getScreenPixelFormat());
+	for (int i = 0; i < _zBuffer->numPanels; ++i) {
+		_zBuffer->sprites[i].create(picWidth, picHeight, *g_sludge->getScreenPixelFormat());
 	}
 
-	for (uint y = 0; y < sceneHeight; y++) {
-		for (uint x = 0; x < sceneWidth; x++) {
+	for (uint y = 0; y < _sceneHeight; y++) {
+		for (uint x = 0; x < _sceneWidth; x++) {
 			int n;
 			if (stillToGo == 0) {
 				n = readStream->readByte();
@@ -150,10 +146,10 @@ bool setZBuffer(int num) {
 					stillToGo++;
 				n &= 15;
 			}
-			for (int i = 0; i < zBuffer.numPanels; ++i) {
-				byte *target = (byte *)zBuffer.sprites[i].getBasePtr(x, y);
+			for (int i = 0; i < _zBuffer->numPanels; ++i) {
+				byte *target = (byte *)_zBuffer->sprites[i].getBasePtr(x, y);
 				if (n && (sortback[i] == n || i == 0)) {
-					byte *source = (byte *)backdropSurface.getBasePtr(x, y);
+					byte *source = (byte *)_backdropSurface.getBasePtr(x, y);
 					target[0] = source[0];
 					target[1] = source[1];
 					target[2] = source[2];
@@ -173,11 +169,28 @@ bool setZBuffer(int num) {
 	return true;
 }
 
-void drawZBuffer(int x, int y, bool upsidedown) {
-	if (!zBuffer.numPanels || !zBuffer.sprites)
+void GraphicsManager::drawZBuffer(int x, int y, bool upsidedown) {
+	if (!_zBuffer->numPanels || !_zBuffer->sprites)
 		return;
 
-	resetSpriteLayers(&zBuffer, x, y, upsidedown);
+	g_sludge->_gfxMan->resetSpriteLayers(_zBuffer, x, y, upsidedown);
+}
+
+void GraphicsManager::saveZBuffer(Common::WriteStream *stream) {
+	if (_zBuffer->numPanels > 0) {
+		stream->writeByte(1);
+		stream->writeUint16BE(_zBuffer->originalNum);
+	} else {
+		stream->writeByte(0);
+	}
+}
+
+bool GraphicsManager::loadZBuffer(Common::SeekableReadStream *stream) {
+	if (stream->readByte()) {
+		if (!setZBuffer(stream->readUint16BE()))
+			return false;
+	}
+	return true;
 }
 
 } // End of namespace Sludge
diff --git a/engines/sludge/zbuffer.h b/engines/sludge/zbuffer.h
index 0a53d54..22676a0 100644
--- a/engines/sludge/zbuffer.h
+++ b/engines/sludge/zbuffer.h
@@ -26,7 +26,7 @@
 
 namespace Sludge {
 
-struct zBufferData {
+struct ZBufferData {
 //	bool loaded;
 	int numPanels;
 	int panel[16];
@@ -34,10 +34,6 @@ struct zBufferData {
 	Graphics::Surface *sprites;
 };
 
-bool setZBuffer(int y);
-void killZBuffer();
-void drawZBuffer(int x, int y, bool upsidedown);
-
 } // End of namespace Sludges
 
 #endif





More information about the Scummvm-git-logs mailing list