[Scummvm-git-logs] scummvm master -> 2d36d802f583ec7a01cc8723ce5476af3d9aab4e

bluegr bluegr at gmail.com
Sat Feb 22 18:05:37 UTC 2020


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

Summary:
6fa96182f7 TINSEL: Move font-related code into a new Font class
eed258261a TINSEL: Merge PrimeBackground() and InitBackground()
64b750ab2e TINSEL: Move background related functions into a new Background class
0fef57b924 TINSEL: Move the current background struct to the heap
ae7f5ff95e TINSEL: Some work on the Japanese version of DW1
2d36d802f5 TINSEL: Remove unused process IDs


Commit: 6fa96182f7b48feb75488541553c4c5754fd1a7d
    https://github.com/scummvm/scummvm/commit/6fa96182f7b48feb75488541553c4c5754fd1a7d
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-02-22T18:41:39+02:00

Commit Message:
TINSEL: Move font-related code into a new Font class

Also, remove some wrapper functions in tinlib.cpp

Changed paths:
    engines/tinsel/bg.cpp
    engines/tinsel/bmv.cpp
    engines/tinsel/dialogs.cpp
    engines/tinsel/font.cpp
    engines/tinsel/font.h
    engines/tinsel/pdisplay.cpp
    engines/tinsel/scene.cpp
    engines/tinsel/tinlib.cpp
    engines/tinsel/tinsel.cpp
    engines/tinsel/tinsel.h


diff --git a/engines/tinsel/bg.cpp b/engines/tinsel/bg.cpp
index a702568..e367c49 100644
--- a/engines/tinsel/bg.cpp
+++ b/engines/tinsel/bg.cpp
@@ -220,7 +220,7 @@ static void BGotherProcess(CORO_PARAM, const void *param) {
 void SetBackPal(SCNHANDLE hPal) {
 	g_hBgPal = hPal;
 
-	FettleFontPal(g_hBgPal);
+	_vm->_font->FettleFontPal(g_hBgPal);
 	CreateTranslucentPalette(g_hBgPal);
 }
 
diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp
index cfe97e6..69155a9 100644
--- a/engines/tinsel/bmv.cpp
+++ b/engines/tinsel/bmv.cpp
@@ -497,25 +497,25 @@ void BMVPlayer::MovieText(CORO_PARAM, int stringId, int x, int y, int fontId, CO
 	if (fontId == 1) {
 		// It's a 'print'
 
-		hFont = GetTagFontHandle();
+		hFont = _vm->_font->GetTagFontHandle();
 		index = 0;
 	} else {
 		// It's a 'talk'
 
 		if (pTalkColor != NULL)
 			SetTextPal(*pTalkColor);
-		hFont = GetTalkFontHandle();
+		hFont = _vm->_font->GetTalkFontHandle();
 		index = 1;
 	}
 
 	if (texts[index].pText)
 		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), texts[index].pText);
 
-	LoadSubString(stringId, 0, TextBufferAddr(), TBUFSZ);
+	LoadSubString(stringId, 0, _vm->_font->TextBufferAddr(), TBUFSZ);
 
 	texts[index].dieFrame = currentFrame + duration;
 	texts[index].pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-						TextBufferAddr(),
+						_vm->_font->TextBufferAddr(),
 						0,
 						x, y,
 						hFont,
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 1b7b9f7..ddc9de9 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -1556,7 +1556,7 @@ static bool UpdateString(const Common::KeyState &kbd) {
 		g_sedit[cpos] = CURSOR_CHAR;
 		return true;
 //	} else if (isalnum(c) || c == ',' || c == '.' || c == '\'' || (c == ' ' && cpos != 0)) {
-	} else if (IsCharImage(GetTagFontHandle(), kbd.ascii) || (kbd.ascii == ' ' && cpos != 0)) {
+	} else if (IsCharImage(_vm->_font->GetTagFontHandle(), kbd.ascii) || (kbd.ascii == ' ' && cpos != 0)) {
 		if (cpos == SG_DESC_LEN)
 			return false;
 		g_sedit[cpos] = kbd.ascii;
@@ -1600,7 +1600,7 @@ static bool InvKeyIn(const Common::KeyState &kbd) {
 				GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
 				g_InvD[g_ino].inventoryX + cd.box[cd.selBox].xpos + 2,
 				g_InvD[g_ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
-				GetTagFontHandle(), 0);
+				_vm->_font->GetTagFontHandle(), 0);
 			if (MultiRightmost(g_iconArray[HL3]) > MAX_NAME_RIGHT) {
 				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
 				UpdateString(Common::KeyState(Common::KEYCODE_BACKSPACE));
@@ -1608,7 +1608,7 @@ static bool InvKeyIn(const Common::KeyState &kbd) {
 					GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
 					g_InvD[g_ino].inventoryX + cd.box[cd.selBox].xpos + 2,
 					g_InvD[g_ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
-					GetTagFontHandle(), 0);
+					_vm->_font->GetTagFontHandle(), 0);
 			}
 			MultiSetZPosition(g_iconArray[HL3], Z_INV_ITEXT + 2);
 		}
@@ -1686,7 +1686,7 @@ static void Select(int i, bool force) {
 #else
 				g_InvD[g_ino].inventoryY + cd.box[i].ypos + TYOFF,
 #endif
-				GetTagFontHandle(), 0);
+				_vm->_font->GetTagFontHandle(), 0);
 			MultiSetZPosition(g_iconArray[HL3], Z_INV_ITEXT + 2);
 		} else {
 			MultiSetZPosition(g_iconArray[HL2], Z_INV_ICONS + 1);
@@ -2649,17 +2649,17 @@ static void AddBackground(OBJECT **rect, OBJECT **title, int extraH, int extraV,
 
 	// Create text object using title string
 	if (textFrom == FROM_HANDLE) {
-		LoadStringRes(g_InvD[g_ino].hInvTitle, TextBufferAddr(), TBUFSZ);
-		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
+		LoadStringRes(g_InvD[g_ino].hInvTitle, _vm->_font->TextBufferAddr(), TBUFSZ);
+		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 					g_InvD[g_ino].inventoryX + width/2, g_InvD[g_ino].inventoryY + M_TOFF,
-					GetTagFontHandle(), TXT_CENTER);
+					_vm->_font->GetTagFontHandle(), TXT_CENTER);
 		assert(*title); // Inventory title string produced NULL text
 		MultiSetZPosition(*title, Z_INV_HTEXT);
 	} else if (textFrom == FROM_STRING && cd.ixHeading != NO_HEADING) {
-		LoadStringRes(g_configStrings[cd.ixHeading], TextBufferAddr(), TBUFSZ);
-		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
+		LoadStringRes(g_configStrings[cd.ixHeading], _vm->_font->TextBufferAddr(), TBUFSZ);
+		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 					g_InvD[g_ino].inventoryX + width/2, g_InvD[g_ino].inventoryY + M_TOFF,
-					GetTagFontHandle(), TXT_CENTER);
+					_vm->_font->GetTagFontHandle(), TXT_CENTER);
 		assert(*title); // Inventory title string produced NULL text
 		MultiSetZPosition(*title, Z_INV_HTEXT);
 	}
@@ -2680,10 +2680,10 @@ static void AddTitle(POBJECT *title, int extraH) {
 
 	// Create text object using title string
 	if (g_InvD[g_ino].hInvTitle != (SCNHANDLE)NO_HEADING) {
-		LoadStringRes(g_InvD[g_ino].hInvTitle, TextBufferAddr(), TBUFSZ);
-		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
+		LoadStringRes(g_InvD[g_ino].hInvTitle, _vm->_font->TextBufferAddr(), TBUFSZ);
+		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 					g_InvD[g_ino].inventoryX + (width/2)+NM_BG_POS_X, g_InvD[g_ino].inventoryY + NM_TOFF,
-					GetTagFontHandle(), TXT_CENTER, 0);
+			_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 		assert(*title);
 		MultiSetZPosition(*title, Z_INV_HTEXT);
 	}
@@ -2766,7 +2766,7 @@ static void AddBox(int *pi, const int i) {
 #ifdef JAPAN
 							x + 2, y+2, GetTagFontHandle(), 0);
 #else
-							x + 2, y + TYOFF, GetTagFontHandle(), 0);
+							x + 2, y + TYOFF, _vm->_font->GetTagFontHandle(), 0);
 #endif
 				} else {
 					g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
@@ -2774,7 +2774,7 @@ static void AddBox(int *pi, const int i) {
 // Note: it never seems to go here!
 							x + cd.box[i].w/2, y+2, GetTagFontHandle(), TXT_CENTER);
 #else
-							x + cd.box[i].w / 2, y + TYOFF, GetTagFontHandle(), TXT_CENTER);
+							x + cd.box[i].w / 2, y + TYOFF, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 #endif
 				}
 
@@ -2784,26 +2784,26 @@ static void AddBox(int *pi, const int i) {
 		} else {
 			if (TinselV2) {
 				if (cd.box[i].textMethod == TM_INDEX)
-					LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
+					LoadStringRes(SysString(cd.box[i].ixText), _vm->_font->TextBufferAddr(), TBUFSZ);
 				else {
 					assert(cd.box[i].textMethod == TM_STRINGNUM);
-					LoadStringRes(cd.box[i].ixText, TextBufferAddr(), TBUFSZ);
+					LoadStringRes(cd.box[i].ixText, _vm->_font->TextBufferAddr(), TBUFSZ);
 				}
 			} else {
-				LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+				LoadStringRes(g_configStrings[cd.box[i].ixText], _vm->_font->TextBufferAddr(), TBUFSZ);
 				assert(cd.box[i].boxType != RGROUP); // You'll need to add some code!
 			}
 
 			if (TinselV2 && (cd.box[i].boxType == RGROUP))
-				g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
-						0, x + 2, y + TYOFF, GetTagFontHandle(), 0, 0);
+				g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+						0, x + 2, y + TYOFF, _vm->_font->GetTagFontHandle(), 0, 0);
 			else
 				g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-					TextBufferAddr(), 0,
+					_vm->_font->TextBufferAddr(), 0,
 #ifdef JAPAN
 					x + cd.box[i].w/2, y+2, GetTagFontHandle(), TXT_CENTER);
 #else
-					x + cd.box[i].w / 2, y + TYOFF, GetTagFontHandle(), TXT_CENTER);
+					x + cd.box[i].w / 2, y + TYOFF, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 #endif
 			MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 			*pi += 1;
@@ -2850,13 +2850,13 @@ static void AddBox(int *pi, const int i) {
 		// Stick in the text
 		if (TinselV2) {
 			assert(cd.box[i].textMethod == TM_INDEX);
-			LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
+			LoadStringRes(SysString(cd.box[i].ixText), _vm->_font->TextBufferAddr(), TBUFSZ);
 		} else {
 			assert(cd.box[i].ixText != USE_POINTER);
-			LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+			LoadStringRes(g_configStrings[cd.box[i].ixText], _vm->_font->TextBufferAddr(), TBUFSZ);
 		}
 		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-			TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF, GetTagFontHandle(), TXT_RIGHT);
+			_vm->_font->TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF, _vm->_font->GetTagFontHandle(), TXT_RIGHT);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 		*pi += 1;
 		break;
@@ -2875,20 +2875,20 @@ static void AddBox(int *pi, const int i) {
 		// Stick in the text
 		if (TinselV2) {
 			assert(cd.box[i].textMethod == TM_INDEX);
-			LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
+			LoadStringRes(SysString(cd.box[i].ixText), _vm->_font->TextBufferAddr(), TBUFSZ);
 		} else {
 			assert(cd.box[i].ixText != USE_POINTER);
-			LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+			LoadStringRes(g_configStrings[cd.box[i].ixText], _vm->_font->TextBufferAddr(), TBUFSZ);
 		}
 
 		if (cd.box[i].boxType == TOGGLE2) {
 			g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-				TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
-				GetTagFontHandle(), TXT_CENTER, 0);
+				_vm->_font->TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
+				_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 		} else {
 			g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-				TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF,
-				GetTagFontHandle(), TXT_RIGHT, 0);
+				_vm->_font->TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF,
+				_vm->_font->GetTagFontHandle(), TXT_RIGHT, 0);
 		}
 
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
@@ -2916,13 +2916,13 @@ static void AddBox(int *pi, const int i) {
 		// Stick in the text
 		if (TinselV2) {
 			assert(cd.box[i].textMethod == TM_INDEX);
-			LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
+			LoadStringRes(SysString(cd.box[i].ixText), _vm->_font->TextBufferAddr(), TBUFSZ);
 		} else {
 			assert(cd.box[i].ixText != USE_POINTER);
-			LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+			LoadStringRes(g_configStrings[cd.box[i].ixText], _vm->_font->TextBufferAddr(), TBUFSZ);
 		}
 		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-			TextBufferAddr(), 0, x+MDTEXT_XOFF, y+MDTEXT_YOFF, GetTagFontHandle(), TXT_RIGHT);
+			_vm->_font->TextBufferAddr(), 0, x+MDTEXT_XOFF, y+MDTEXT_YOFF, _vm->_font->GetTagFontHandle(), TXT_RIGHT);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 		*pi += 1;
 		break;
@@ -2945,10 +2945,10 @@ static void AddBox(int *pi, const int i) {
 
 			// Stick in the text
 			assert(cd.box[i].textMethod == TM_INDEX);
-			LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
+			LoadStringRes(SysString(cd.box[i].ixText), _vm->_font->TextBufferAddr(), TBUFSZ);
 			g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-				TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
-				GetTagFontHandle(), TXT_CENTER, 0);
+				_vm->_font->TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
+				_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 			MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 			*pi += 1;
 		}
@@ -2957,9 +2957,9 @@ static void AddBox(int *pi, const int i) {
 		if (LanguageDesc(g_displayedLanguage) == 0)
 			break;
 
-		LoadStringRes(LanguageDesc(g_displayedLanguage), TextBufferAddr(), TBUFSZ);
-		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
-				x + cd.box[i].w / 2, y + ROT_YOFF, GetTagFontHandle(), TXT_CENTER, 0);
+		LoadStringRes(LanguageDesc(g_displayedLanguage), _vm->_font->TextBufferAddr(), TBUFSZ);
+		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
+				x + cd.box[i].w / 2, y + ROT_YOFF, _vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 		*pi += 1;
 
diff --git a/engines/tinsel/font.cpp b/engines/tinsel/font.cpp
index 076bfa8..70ecc60 100644
--- a/engines/tinsel/font.cpp
+++ b/engines/tinsel/font.cpp
@@ -30,85 +30,28 @@
 
 namespace Tinsel {
 
-//----------------- LOCAL GLOBAL DATA --------------------
-
-// FIXME: Avoid non-const global vars
-
-static char g_tBuffer[TBUFSZ];
-
-static SCNHANDLE g_hTagFont = 0, g_hTalkFont = 0;
-static SCNHANDLE g_hRegularTalkFont = 0, g_hRegularTagFont = 0;
-
-
-/**
- * Return address of tBuffer
- */
-char *TextBufferAddr() {
-	return g_tBuffer;
-}
-
-/**
- * Return hTagFont handle.
- */
-SCNHANDLE GetTagFontHandle() {
-	return g_hTagFont;
-}
-
-/**
- * Return hTalkFont handle.
- */
-SCNHANDLE GetTalkFontHandle() {
-	return g_hTalkFont;
-}
-
-/**
- * Called from dec_tagfont() Glitter function. Store the tag font handle.
- */
-void SetTagFontHandle(SCNHANDLE hFont) {
-	g_hTagFont = g_hRegularTagFont = hFont;		// Store the font handle
-}
-
-/**
- * Called from dec_talkfont() Glitter function.
- * Store the talk font handle.
- */
-void SetTalkFontHandle(SCNHANDLE hFont) {
-	g_hTalkFont = g_hRegularTalkFont = hFont;		// Store the font handle
-}
-
-void SetTempTagFontHandle(SCNHANDLE hFont) {
-	g_hTagFont = hFont;
+void Font::SetTagFontHandle(SCNHANDLE hFont) {
+	_hTagFont = _hRegularTagFont = hFont;
+	if (TinselV0)
+		SetTalkFontHandle(hFont);	// Also re-use for talk text
 }
 
-void SetTempTalkFontHandle(SCNHANDLE hFont) {
-	g_hTalkFont = hFont;
-}
-
-void ResetFontHandles() {
-	g_hTagFont = g_hRegularTagFont;
-	g_hTalkFont = g_hRegularTalkFont;
-}
-
-
-/**
- * Poke the background palette into character 0's images.
- */
-void FettleFontPal(SCNHANDLE fontPal) {
+void Font::FettleFontPal(SCNHANDLE fontPal) {
 	const FONT *pFont;
 	IMAGE *pImg;
 
 	assert(fontPal);
-	assert(g_hTagFont); // Tag font not declared
-	assert(g_hTalkFont); // Talk font not declared
+	assert(_hTagFont); // Tag font not declared
+	assert(_hTalkFont); // Talk font not declared
 
-	pFont = (const FONT *)LockMem(g_hTagFont);
+	pFont = (const FONT *)LockMem(_hTagFont);
 	pImg = (IMAGE *)LockMem(FROM_32(pFont->fontInit.hObjImg));	// get image for char 0
 	if (!TinselV2)
 		pImg->hImgPal = TO_32(fontPal);
 	else
 		pImg->hImgPal = 0;
 
-	pFont = (const FONT *)LockMem(g_hTalkFont);
+	pFont = (const FONT *)LockMem(_hTalkFont);
 	pImg = (IMAGE *)LockMem(FROM_32(pFont->fontInit.hObjImg));	// get image for char 0
 	if (!TinselV2)
 		pImg->hImgPal = TO_32(fontPal);
diff --git a/engines/tinsel/font.h b/engines/tinsel/font.h
index d9e25be..a74e7b0 100644
--- a/engines/tinsel/font.h
+++ b/engines/tinsel/font.h
@@ -31,24 +31,71 @@ namespace Tinsel {
 // Accessed using TextBufferAddr(), this is how big it is:
 #define TBUFSZ	512
 
-
-char *TextBufferAddr();
-
-SCNHANDLE GetTagFontHandle();
-
-SCNHANDLE GetTalkFontHandle();
-
-void SetTagFontHandle(SCNHANDLE hFont);
-
-void SetTalkFontHandle(SCNHANDLE hFont);
-
-void SetTempTagFontHandle(SCNHANDLE hFont);
-
-void SetTempTalkFontHandle(SCNHANDLE hFont);
-
-void ResetFontHandles();
-
-void FettleFontPal(SCNHANDLE fontPal);
+class TinselEngine;
+
+class Font {
+public:
+	Font() : _hTagFont(0), _hTalkFont(0), _hRegularTalkFont(0), _hRegularTagFont(0), _tBuffer("") {
+	}
+
+	/**
+	 * Return address of tBuffer
+	 */
+	char* TextBufferAddr() { return _tBuffer; }
+
+	/**
+	 * Return hTagFont handle.
+	 */
+	SCNHANDLE GetTagFontHandle() { return _hTagFont; }
+
+	/**
+	 * Return hTalkFont handle.
+	 */
+	SCNHANDLE GetTalkFontHandle() { return _hTalkFont; }
+
+	/**
+	 * Called from dec_tagfont() Glitter function. Store the tag font handle.
+	 */
+	void SetTagFontHandle(SCNHANDLE hFont);
+
+	/**
+	 * Called from dec_talkfont() Glitter function.
+	 * Store the talk font handle.
+	 */
+	void SetTalkFontHandle(SCNHANDLE hFont) {
+		_hTalkFont = _hRegularTalkFont = hFont;
+	}
+
+	/**
+	 * Declare a temporary text font (DW2 only).
+	 */
+	void SetTempTagFontHandle(SCNHANDLE hFont) {
+		_hTagFont = hFont;
+	}
+
+	/**
+	 * Declare a temporary text font (DW2 only).
+	 */
+	void SetTempTalkFontHandle(SCNHANDLE hFont) {
+		_hTalkFont = hFont;
+	}
+
+	void ResetFontHandles() {
+		_hTagFont = _hRegularTagFont;
+		_hTalkFont = _hRegularTalkFont;
+	}
+
+	/**
+	 * Poke the background palette into character 0's images.
+	 */
+	void FettleFontPal(SCNHANDLE fontPal);
+
+private:
+	char _tBuffer[TBUFSZ];
+
+	SCNHANDLE _hTagFont = 0, _hTalkFont = 0;
+	SCNHANDLE _hRegularTalkFont = 0, _hRegularTagFont = 0;
+};
 
 } // End of namespace Tinsel
 
diff --git a/engines/tinsel/pdisplay.cpp b/engines/tinsel/pdisplay.cpp
index 5454035..191074a 100644
--- a/engines/tinsel/pdisplay.cpp
+++ b/engines/tinsel/pdisplay.cpp
@@ -410,7 +410,7 @@ static bool ActorTag(int curX, int curY, HotSpotTag *pTag, OBJECT **ppText) {
 				// May have buggered cursor
 				EndCursorFollowed();
 				*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), g_tagBuffer,
-						0, tagX, tagY, GetTagFontHandle(), TXT_CENTER, 0);
+						0, tagX, tagY, _vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 				assert(*ppText);
 				MultiSetZPosition(*ppText, Z_TAG_TEXT);
 			} else
@@ -453,9 +453,9 @@ static bool ActorTag(int curX, int curY, HotSpotTag *pTag, OBJECT **ppText) {
 				SaveTaggedPoly(NOPOLY);	// No tagged polygon
 
 				PlayfieldGetPos(FIELD_WORLD, &tagX, &tagY);
-				LoadStringRes(GetActorTag(ano), TextBufferAddr(), TBUFSZ);
-				*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
-							0, xtext - tagX, ytext - tagY, GetTagFontHandle(), TXT_CENTER);
+				LoadStringRes(GetActorTag(ano), _vm->_font->TextBufferAddr(), TBUFSZ);
+				*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+							0, xtext - tagX, ytext - tagY, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 				assert(*ppText); // Actor tag string produced NULL text
 				MultiSetZPosition(*ppText, Z_TAG_TEXT);
 			} else {
@@ -547,9 +547,9 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 
 				int strLen;
 				if (GetPolyTagHandle(hp) != 0)
-					strLen = LoadStringRes(GetPolyTagHandle(hp), TextBufferAddr(), TBUFSZ);
+					strLen = LoadStringRes(GetPolyTagHandle(hp), _vm->_font->TextBufferAddr(), TBUFSZ);
 				else
-					strLen = LoadStringRes(hTagtext, TextBufferAddr(), TBUFSZ);
+					strLen = LoadStringRes(hTagtext, _vm->_font->TextBufferAddr(), TBUFSZ);
 
 				if (strLen == 0)
 					// No valid string returned, so leave ppText as NULL
@@ -559,22 +559,22 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 					EndCursorFollowed();
 
 					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-							TextBufferAddr(), 0, tagx - Loffset, tagy - Toffset,
-							GetTagFontHandle(), TXT_CENTER, 0);
+							_vm->_font->TextBufferAddr(), 0, tagx - Loffset, tagy - Toffset,
+							_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 				} else if (TinselV2) {
 					// Bugger cursor
-					const char *tagPtr = TextBufferAddr();
+					const char *tagPtr = _vm->_font->TextBufferAddr();
 					if (tagPtr[0] < ' ' && tagPtr[1] == EOS_CHAR)
 						StartCursorFollowed();
 
 					GetCursorXYNoWait(&curX, &curY, false);
-					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
-							0, curX, curY, GetTagFontHandle(), TXT_CENTER, 0);
+					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+							0, curX, curY, _vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 				} else {
 					// Handle displaying the tag text on-screen
-					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
+					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 							0, tagx - Loffset, tagy - Toffset,
-							GetTagFontHandle(), TXT_CENTER);
+						_vm->_font->GetTagFontHandle(), TXT_CENTER);
 					assert(*ppText); // Polygon tag string produced NULL text
 				}
 
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 49a8540..1b3ff0d 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -331,7 +331,7 @@ void EndScene() {
 		SetSysVar(SV_MaximumXoffset, 0);
 		SetSysVar(SV_MinimumYoffset, 0);
 		SetSysVar(SV_MaximumYoffset, 0);
-		ResetFontHandles();
+		_vm->_font->ResetFontHandles();
 		NoSoundReels();
 	}
 
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 54dfa5d..a65fa24 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -1026,22 +1026,6 @@ static void DecScale(int actor, int scale,
 }
 
 /**
- * Declare the text font.
- */
-static void DecTagFont(SCNHANDLE hf) {
-	SetTagFontHandle(hf);		// Store the font handle
-	if (TinselV0)
-		SetTalkFontHandle(hf);	// Also re-use for talk text
-}
-
-/**
- * Declare the text font.
- */
-static void DecTalkFont(SCNHANDLE hf) {
-	SetTalkFontHandle(hf);		// Store the font handle
-}
-
-/**
  * Remove an icon from the conversation window.
  */
 static void DelIcon(int icon) {
@@ -1066,13 +1050,6 @@ static void DelTopic(int icon) {
 }
 
 /**
- * DimMusic
- */
-static void DimMusic() {
-	_vm->_pcmMusic->dim(true);
-}
-
-/**
  * Delete the object from inventory 1 or 2.
  */
 static void Drop(int object) {
@@ -1155,20 +1132,6 @@ static void FaceTag(int actor, HPOLYGON hp) {
 }
 
 /**
- * FadeIn
- */
-static void FadeIn() {
-	FadeInMedium();
-}
-
-/**
- * FadeOut
- */
-static void FadeOut() {
-	FadeOutMedium();
-}
-
-/**
  * FadeMidi(in/out)
  */
 static void FadeMidi(CORO_PARAM, int inout) {
@@ -1924,13 +1887,13 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 	}
 
 	// Get the string
-	LoadStringRes(text, TextBufferAddr(), TBUFSZ);
+	LoadStringRes(text, _vm->_font->TextBufferAddr(), TBUFSZ);
 
 	// Calculate display time
 	bJapDoPrintText = false;
 	if (time == 0) {
 		// This is a 'talky' print
-		_ctx->time = TextTime(TextBufferAddr());
+		_ctx->time = TextTime(_vm->_font->TextBufferAddr());
 
 		// Cut short-able if sustain was not set
 		_ctx->myleftEvent = bSustain ? 0 : GetLeftEvents();
@@ -1946,7 +1909,7 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 		int Loffset, Toffset;
 		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 		_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-			TextBufferAddr(), 0, x - Loffset, y - Toffset, GetTagFontHandle(),
+			_vm->_font->TextBufferAddr(), 0, x - Loffset, y - Toffset, _vm->_font->GetTagFontHandle(),
 			TXT_CENTER, 0);
 		assert(_ctx->pText);
 
@@ -1958,9 +1921,9 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 	} else if (bJapDoPrintText || (!isJapanMode() && (_vm->_config->_useSubtitles || !_ctx->bSample))) {
 		int Loffset, Toffset;	// Screen position
 		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
-		_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
+		_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 					0, x - Loffset, y - Toffset,
-					TinselV2 ? GetTagFontHandle() : GetTalkFontHandle(), TXT_CENTER);
+					TinselV2 ? _vm->_font->GetTagFontHandle() : _vm->_font->GetTalkFontHandle(), TXT_CENTER);
 		assert(_ctx->pText); // string produced NULL text
 		if (IsTopWindow())
 			MultiSetZPosition(_ctx->pText, Z_TOPW_TEXT);
@@ -2119,12 +2082,12 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 
 			// Get the text string
 			if (TinselV2)
-				LoadSubString(hText, _ctx->sub, TextBufferAddr(), TBUFSZ);
+				LoadSubString(hText, _ctx->sub, _vm->_font->TextBufferAddr(), TBUFSZ);
 			else
-				LoadStringRes(hText, TextBufferAddr(), TBUFSZ);
+				LoadStringRes(hText, _vm->_font->TextBufferAddr(), TBUFSZ);
 
-			_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
-						0, _ctx->textx, _ctx->texty, GetTagFontHandle(), TXT_CENTER);
+			_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+						0, _ctx->textx, _ctx->texty, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 			assert(_ctx->pText); // PrintObj() string produced NULL text
 
 			MultiSetZPosition(_ctx->pText, Z_INV_ITEXT);
@@ -2174,9 +2137,9 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 							break;
 
 						// Re-display in the same place
-						LoadStringRes(hText, TextBufferAddr(), TBUFSZ);
+						LoadStringRes(hText, _vm->_font->TextBufferAddr(), TBUFSZ);
 						_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-							TextBufferAddr(), 0, _ctx->textx, _ctx->texty, GetTagFontHandle(),
+							_vm->_font->TextBufferAddr(), 0, _ctx->textx, _ctx->texty, _vm->_font->GetTagFontHandle(),
 							TXT_CENTER, 0);
 						assert(_ctx->pText);
 
@@ -2199,7 +2162,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 
 				// Display for a time, but abort if conversation gets hidden
 				if (_ctx->pText)
-					_ctx->ticks = TextTime(TextBufferAddr());
+					_ctx->ticks = TextTime(_vm->_font->TextBufferAddr());
 				_ctx->timeout = SAMPLETIMEOUT;
 
 				for (;;) {
@@ -2291,9 +2254,9 @@ static void PrintObjPointed(CORO_PARAM, const SCNHANDLE text, const INV_OBJECT *
 					break;
 
 				// Re-display in the same place
-				LoadStringRes(text, TextBufferAddr(), TBUFSZ);
-				pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
-							0, textx, texty, GetTagFontHandle(), TXT_CENTER);
+				LoadStringRes(text, _vm->_font->TextBufferAddr(), TBUFSZ);
+				pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+							0, textx, texty, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 				assert(pText); // PrintObj() string produced NULL text
 				MultiSetZPosition(pText, Z_INV_ITEXT);
 			}
@@ -2333,7 +2296,7 @@ static void PrintObjNonPointed(CORO_PARAM, const SCNHANDLE text, const OBJECT *p
 		if (isJapanMode())
 			_ctx->ticks = JAP_TEXT_TIME;
 		else if (pText)
-			_ctx->ticks = TextTime(TextBufferAddr());
+			_ctx->ticks = TextTime(_vm->_font->TextBufferAddr());
 		else
 			_ctx->ticks = 0;
 
@@ -2757,8 +2720,8 @@ static void SetTimer(int timerno, int start, bool up, bool frame) {
  * Shell("cmdline")
  */
 static void Shell(SCNHANDLE commandLine) {
-	LoadStringRes(commandLine, TextBufferAddr(), TBUFSZ);
-	error("Tried to execute shell command \"%s\"", TextBufferAddr());
+	LoadStringRes(commandLine, _vm->_font->TextBufferAddr(), TBUFSZ);
+	error("Tried to execute shell command \"%s\"", _vm->_font->TextBufferAddr());
 }
 
 /**
@@ -3354,16 +3317,16 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 			if (!TinselV0)
 				SetTextPal(GetActorRGB(_ctx->actor));
 			if (TinselV2)
-				LoadSubString(hText, _ctx->sub, TextBufferAddr(), TBUFSZ);
+				LoadSubString(hText, _ctx->sub, _vm->_font->TextBufferAddr(), TBUFSZ);
 			else {
-				LoadStringRes(hText, TextBufferAddr(), TBUFSZ);
+				LoadStringRes(hText, _vm->_font->TextBufferAddr(), TBUFSZ);
 
 				_ctx->y -= _ctx->Toffset;
 			}
 
 			_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
-					TextBufferAddr(), 0, _ctx->x - _ctx->Loffset, _ctx->y - _ctx->Toffset,
-					GetTalkFontHandle(), TXT_CENTER);
+					_vm->_font->TextBufferAddr(), 0, _ctx->x - _ctx->Loffset, _ctx->y - _ctx->Toffset,
+					_vm->_font->GetTalkFontHandle(), TXT_CENTER);
 			assert(_ctx->pText); // talk() string produced NULL text;
 
 			if (IsTopWindow())
@@ -3403,7 +3366,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 			 * Work out how long to talk.
 			 * During this time, reposition the text if the screen scrolls.
 			 */
-			_ctx->ticks = TextTime(TextBufferAddr());
+			_ctx->ticks = TextTime(_vm->_font->TextBufferAddr());
 		}
 
 		if (TinselV2 && _ctx->bSample) {
@@ -3607,20 +3570,6 @@ static void TalkVia(int actor) {
 }
 
 /**
- * Declare a temporary text font.
- */
-static void TempTagFont(SCNHANDLE hFilm) {
-	SetTempTagFontHandle(hFilm);	// Store the font handle
-}
-
-/**
- * Declare a temporary text font.
- */
-static void TempTalkFont(SCNHANDLE hFilm) {
-	SetTempTalkFontHandle(hFilm);	// Store the font handle
-}
-
-/**
  * ThisObject
  */
 static int ThisObject(INV_OBJECT *pinvo) {
@@ -3710,20 +3659,6 @@ static void TryPlaySample(CORO_PARAM, int sample, bool bComplete, bool escOn, in
 }
 
 /**
- * UnDimMusic
- */
-static void UnDimMusic() {
-	_vm->_pcmMusic->unDim(true);
-}
-
-/**
- * unhookscene
- */
-static void UnHookSceneFn() {
-	UnHookScene();
-}
-
-/**
  * Un-define an actor as tagged.
  */
 static void UnTagActorFn(int actor) {
@@ -4586,12 +4521,12 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 
 	case DECTAGFONT:
 		// Common to both DW1 & DW2
-		DecTagFont(pp[0]);
+		_vm->_font->SetTagFontHandle(pp[0]);
 		return -1;
 
 	case DECTALKFONT:
 		// Common to both DW1 & DW2
-		DecTalkFont(pp[0]);
+		_vm->_font->SetTalkFontHandle(pp[0]);
 		return -1;
 
 	case DELICON:
@@ -4611,7 +4546,7 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 
 	case DIMMUSIC:
 		// DW2 only
-		DimMusic();
+		_vm->_pcmMusic->dim(true);
 		return 0;
 
 	case DROP:
@@ -4666,7 +4601,7 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 
 	case FADEIN:
 		// DW2 only
-		FadeIn();
+		FadeInMedium();
 		return 0;
 
 	case FADEMIDI:
@@ -4676,7 +4611,7 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 
 	case FADEOUT:
 		// DW1 only
-		FadeOut();
+		FadeOutMedium();
 		return 0;
 
 	case FRAMEGRAB:
@@ -5477,12 +5412,12 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 
 	case TEMPTAGFONT:
 		// DW2 only
-		TempTagFont(pp[0]);
+		_vm->_font->SetTempTagFontHandle(pp[0]);
 		return -1;
 
 	case TEMPTALKFONT:
 		// DW2 only
-		TempTalkFont(pp[0]);
+		_vm->_font->SetTempTalkFontHandle(pp[0]);
 		return -1;
 
 	case THISOBJECT:
@@ -5535,12 +5470,12 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 
 	case UNDIMMUSIC:
 		// DW2 only
-		UnDimMusic();
+		_vm->_pcmMusic->unDim(true);
 		return 0;
 
 	case UNHOOKSCENE:
 		// Common to both DW1 & DW2
-		UnHookSceneFn();
+		UnHookScene();
 		return 0;
 
 	case UNTAGACTOR:
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 78107ea..4f8ffea 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -43,6 +43,7 @@
 #include "tinsel/events.h"
 #include "tinsel/faders.h"
 #include "tinsel/film.h"
+#include "tinsel/font.h"
 #include "tinsel/handle.h"
 #include "tinsel/heapmem.h"			// MemoryInit
 #include "tinsel/dialogs.h"
@@ -854,6 +855,7 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
 
 TinselEngine::~TinselEngine() {
 	_system->getAudioCDManager()->stop();
+	delete _font;
 	delete _bmv;
 	delete _sound;
 	delete _midiMusic;
@@ -895,6 +897,7 @@ Common::Error TinselEngine::run() {
 	_pcmMusic = new PCMMusicPlayer();
 	_sound = new SoundManager(this);
 	_bmv = new BMVPlayer();
+	_font = new Font();
 
 	// Initialize backend
 	if (getGameID() == GID_DW2) {
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index a99f9e1..6657d0d 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -56,6 +56,7 @@ class MidiDriver;
 class MidiMusicPlayer;
 class PCMMusicPlayer;
 class SoundManager;
+class Font;
 
 typedef Common::List<Common::Rect> RectList;
 
@@ -183,7 +184,6 @@ public:
 	uint32 getFeatures() const;
 	Common::Language getLanguage() const;
 	uint16 getVersion() const;
-	uint32 getFlags() const;
 	Common::Platform getPlatform() const;
 	bool getIsADGFDemo() const;
 	bool isV1CD() const;
@@ -197,6 +197,7 @@ public:
 	MidiMusicPlayer *_midiMusic;
 	PCMMusicPlayer *_pcmMusic;
 	BMVPlayer *_bmv;
+	Font *_font;
 
 	Config *_config;
 


Commit: eed258261a893116a0f5f03a0e5363808812d6dc
    https://github.com/scummvm/scummvm/commit/eed258261a893116a0f5f03a0e5363808812d6dc
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-02-22T18:41:39+02:00

Commit Message:
TINSEL: Merge PrimeBackground() and InitBackground()

Changed paths:
    engines/tinsel/background.cpp
    engines/tinsel/background.h
    engines/tinsel/scene.cpp
    engines/tinsel/tinsel.cpp


diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index 7913548..b8f4472 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -38,27 +38,61 @@ const BACKGND *g_pCurBgnd = NULL;
 
 /**
  * Called to initialize a background.
- * @param pBgnd			Pointer to data struct for current background
  */
+void InitBackground() {
+	// structure for playfields
+	// FIXME: Avoid non-const global vars
+	static PLAYFIELD playfield[] = {
+		{	// FIELD WORLD
+			NULL,		// display list
+			0,			// init field x
+			0,			// init field y
+			0,			// x vel
+			0,			// y vel
+			Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// clip rect
+			false		// moved flag
+		},
+		{	// FIELD STATUS
+			NULL,		// display list
+			0,			// init field x
+			0,			// init field y
+			0,			// x vel
+			0,			// y vel
+			Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// clip rect
+			false		// moved flag
+		}
+	};
+
+	// structure for background
+	static const BACKGND backgnd = {
+		BLACK,			// sky color
+		Common::Point(0, 0),	// initial world pos
+		Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// scroll limits
+		0,				// no background update process
+		NULL,			// no x scroll table
+		NULL,			// no y scroll table
+		2,				// 2 playfields
+		playfield,		// playfield pointer
+		false			// no auto-erase
+	};
 
-void InitBackground(const BACKGND *pBgnd) {
 	int i;			// playfield counter
-	PLAYFIELD *pPlayfield;	// pointer to current playfield
+	PLAYFIELD* pPlayfield;	// pointer to current playfield
 
 	// set current background
-	g_pCurBgnd = pBgnd;
+	g_pCurBgnd = &backgnd;
 
 	// init background sky color
-	SetBgndColor(pBgnd->rgbSkyColor);
+	SetBgndColor(backgnd.rgbSkyColor);
 
 	// start of playfield array
-	pPlayfield = pBgnd->fieldArray;
+	pPlayfield = backgnd.fieldArray;
 
 	// for each background playfield
-	for (i = 0; i < pBgnd->numPlayfields; i++, pPlayfield++) {
+	for (i = 0; i < backgnd.numPlayfields; i++, pPlayfield++) {
 		// init playfield pos
-		pPlayfield->fieldX = intToFrac(pBgnd->ptInitWorld.x);
-		pPlayfield->fieldY = intToFrac(pBgnd->ptInitWorld.y);
+		pPlayfield->fieldX = intToFrac(backgnd.ptInitWorld.x);
+		pPlayfield->fieldY = intToFrac(backgnd.ptInitWorld.y);
 
 		// no scrolling
 		pPlayfield->fieldXvel = intToFrac(0);
diff --git a/engines/tinsel/background.h b/engines/tinsel/background.h
index 418413e..ccad494 100644
--- a/engines/tinsel/background.h
+++ b/engines/tinsel/background.h
@@ -73,13 +73,10 @@ struct BACKGND {
 |*			Background Function Prototypes			*|
 \*----------------------------------------------------------------------*/
 
-void InitBackground(		// called to initialize a background
-	const BACKGND *pBgnd);	// pointer to data struct for current background
+void InitBackground();
 
 void StartupBackground(CORO_PARAM, SCNHANDLE hFilm);
 
-void StopBgndScrolling();	// Stops all background playfields from scrolling
-
 void PlayfieldSetPos(		// Sets the xy position of the specified playfield in the current background
 	int which,		// which playfield
 	int newXpos,		// new x position
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 1b3ff0d..cf90704 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -349,52 +349,6 @@ void EndScene() {
 }
 
 /**
- *
- */
-void PrimeBackground() {
-	// structure for playfields
-	// FIXME: Avoid non-const global vars
-	// TODO: We should simply merge this function with InitBackground
-	//   in order to avoid the static var and the problems associate
-	//   with it.
-	static PLAYFIELD playfield[] = {
-		{	// FIELD WORLD
-			NULL,		// display list
-			0,			// init field x
-			0,			// init field y
-			0,			// x vel
-			0,			// y vel
-			Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// clip rect
-			false		// moved flag
-		},
-		{	// FIELD STATUS
-			NULL,		// display list
-			0,			// init field x
-			0,			// init field y
-			0,			// x vel
-			0,			// y vel
-			Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// clip rect
-			false		// moved flag
-		}
-	};
-
-	// structure for background
-	static const BACKGND backgnd = {
-		BLACK,			// sky color
-		Common::Point(0, 0),	// initial world pos
-		Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// scroll limits
-		0,				// no background update process
-		NULL,			// no x scroll table
-		NULL,			// no y scroll table
-		2,				// 2 playfields
-		playfield,		// playfield pointer
-		false			// no auto-erase
-	};
-
-	InitBackground(&backgnd);
-}
-
-/**
  * Start up the standard stuff for the next scene.
  */
 
@@ -418,7 +372,7 @@ void PrimeScene() {
 	CoroScheduler.createProcess(PID_TAG, PointProcess, NULL, 0);
 
 	// init the current background
-	PrimeBackground();
+	InitBackground();
 }
 
 /**
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 4f8ffea..a14c858 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -76,7 +76,6 @@ extern void CursorProcess(CORO_PARAM, const void *);
 extern void InventoryProcess(CORO_PARAM, const void *);
 
 // In SCENE.CPP
-extern void PrimeBackground();
 extern SCNHANDLE GetSceneHandle();
 
 //----------------- FORWARD DECLARATIONS  ---------------------
@@ -1105,7 +1104,7 @@ void TinselEngine::RestartGame() {
 	DropBackground();	// No background
 
 	// Ditches existing infrastructure background
-	PrimeBackground();
+	InitBackground();
 
 	// Next scene change won't need to fade out
 	// -> reset the count used by ChangeScene


Commit: 64b750ab2eb437239238c0360545da42a8ec6c48
    https://github.com/scummvm/scummvm/commit/64b750ab2eb437239238c0360545da42a8ec6c48
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-02-22T18:41:39+02:00

Commit Message:
TINSEL: Move background related functions into a new Background class

Changed paths:
    dists/msvc/create_msvc.bat
    engines/tinsel/actors.cpp
    engines/tinsel/background.cpp
    engines/tinsel/background.h
    engines/tinsel/bg.cpp
    engines/tinsel/bmv.cpp
    engines/tinsel/cursor.cpp
    engines/tinsel/dialogs.cpp
    engines/tinsel/events.cpp
    engines/tinsel/font.h
    engines/tinsel/move.cpp
    engines/tinsel/pdisplay.cpp
    engines/tinsel/play.cpp
    engines/tinsel/rince.cpp
    engines/tinsel/savescn.cpp
    engines/tinsel/scene.cpp
    engines/tinsel/scroll.cpp
    engines/tinsel/sound.cpp
    engines/tinsel/tinlib.cpp
    engines/tinsel/tinsel.cpp
    engines/tinsel/tinsel.h


diff --git a/dists/msvc/create_msvc.bat b/dists/msvc/create_msvc.bat
index 6746a98..43385a1 100644
--- a/dists/msvc/create_msvc.bat
+++ b/dists/msvc/create_msvc.bat
@@ -55,7 +55,7 @@ goto done
 echo.
 echo Creating project files with all engines enabled (stable and unstable)
 echo.
-create_project ..\.. --enable-all-engines --disable-fluidsynth --msvc
+create_project ..\.. --enable-all-engines --disable-fluidsynth --msvc --build-events --enable-vkeybd --enable-updates --enable-faad --enable-mpeg2
 goto done
 
 :stable
diff --git a/engines/tinsel/actors.cpp b/engines/tinsel/actors.cpp
index 1440fb3..83340ff 100644
--- a/engines/tinsel/actors.cpp
+++ b/engines/tinsel/actors.cpp
@@ -1610,7 +1610,7 @@ void GetActorTagPos(int actor, int *pTagX, int *pTagY, bool bAbsolute) {
 	*pTagY = aTop;
 
 	if (!bAbsolute) {
-		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 		*pTagX -= Loffset;
 		*pTagY -= Toffset;
 	}
diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index b8f4472..8b15c8a 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -23,7 +23,9 @@
 
 #include "tinsel/background.h"
 #include "tinsel/cliprect.h"	// object clip rect defs
+#include "tinsel/font.h"
 #include "tinsel/graphics.h"
+#include "tinsel/multiobj.h"
 #include "tinsel/sched.h"	// process sheduler defs
 #include "tinsel/object.h"
 #include "tinsel/pid.h"	// process identifiers
@@ -31,15 +33,10 @@
 
 namespace Tinsel {
 
-// FIXME: Avoid non-const global vars
-
-// current background
-const BACKGND *g_pCurBgnd = NULL;
-
 /**
  * Called to initialize a background.
  */
-void InitBackground() {
+void Background::InitBackground() {
 	// structure for playfields
 	// FIXME: Avoid non-const global vars
 	static PLAYFIELD playfield[] = {
@@ -80,7 +77,7 @@ void InitBackground() {
 	PLAYFIELD* pPlayfield;	// pointer to current playfield
 
 	// set current background
-	g_pCurBgnd = &backgnd;
+	_pCurBgnd = &backgnd;
 
 	// init background sky color
 	SetBgndColor(backgnd.rgbSkyColor);
@@ -113,17 +110,17 @@ void InitBackground() {
  * @param newYpos		New y position
  */
 
-void PlayfieldSetPos(int which, int newXpos, int newYpos) {
+void Background::PlayfieldSetPos(int which, int newXpos, int newYpos) {
 	PLAYFIELD *pPlayfield;	// pointer to relavent playfield
 
 	// make sure there is a background
-	assert(g_pCurBgnd != NULL);
+	assert(_pCurBgnd != NULL);
 
 	// make sure the playfield number is in range
-	assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
+	assert(which >= 0 && which < _pCurBgnd->numPlayfields);
 
 	// get playfield pointer
-	pPlayfield = g_pCurBgnd->fieldArray + which;
+	pPlayfield = _pCurBgnd->fieldArray + which;
 
 	// set new integer position
 	pPlayfield->fieldX = intToFrac(newXpos);
@@ -140,17 +137,17 @@ void PlayfieldSetPos(int which, int newXpos, int newYpos) {
  * @param pYpos			Returns current y position
  */
 
-void PlayfieldGetPos(int which, int *pXpos, int *pYpos) {
+void Background::PlayfieldGetPos(int which, int *pXpos, int *pYpos) {
 	PLAYFIELD *pPlayfield;	// pointer to relavent playfield
 
 	// make sure there is a background
-	assert(g_pCurBgnd != NULL);
+	assert(_pCurBgnd != NULL);
 
 	// make sure the playfield number is in range
-	assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
+	assert(which >= 0 && which < _pCurBgnd->numPlayfields);
 
 	// get playfield pointer
-	pPlayfield = g_pCurBgnd->fieldArray + which;
+	pPlayfield = _pCurBgnd->fieldArray + which;
 
 	// get current integer position
 	*pXpos = fracToInt(pPlayfield->fieldX);
@@ -162,17 +159,17 @@ void PlayfieldGetPos(int which, int *pXpos, int *pYpos) {
  * @param which			Which playfield
  */
 
-int PlayfieldGetCenterX(int which) {
+int Background::PlayfieldGetCenterX(int which) {
 	PLAYFIELD *pPlayfield; // pointer to relavent playfield
 
 	// make sure there is a background
-	assert(g_pCurBgnd != NULL);
+	assert(_pCurBgnd != NULL);
 
 	// make sure the playfield number is in range
-	assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
+	assert(which >= 0 && which < _pCurBgnd->numPlayfields);
 
 	// get playfield pointer
-	pPlayfield = g_pCurBgnd->fieldArray + which;
+	pPlayfield = _pCurBgnd->fieldArray + which;
 
 	// get current integer position
 	return fracToInt(pPlayfield->fieldX) + SCREEN_WIDTH/2;
@@ -183,17 +180,17 @@ int PlayfieldGetCenterX(int which) {
  * @param which			Which playfield
  */
 
-OBJECT **GetPlayfieldList(int which) {
+OBJECT **Background::GetPlayfieldList(int which) {
 	PLAYFIELD *pPlayfield;	// pointer to relavent playfield
 
 	// make sure there is a background
-	assert(g_pCurBgnd != NULL);
+	assert(_pCurBgnd != NULL);
 
 	// make sure the playfield number is in range
-	assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
+	assert(which >= 0 && which < _pCurBgnd->numPlayfields);
 
 	// get playfield pointer
-	pPlayfield = g_pCurBgnd->fieldArray + which;
+	pPlayfield = _pCurBgnd->fieldArray + which;
 
 	// return the display list pointer for this playfield
 	return &pPlayfield->pDispList;
@@ -205,19 +202,19 @@ OBJECT **GetPlayfieldList(int which) {
  * to scroll each playfield before it is drawn.
  */
 
-void DrawBackgnd() {
+void Background::DrawBackgnd() {
 	int i;			// playfield counter
 	PLAYFIELD *pPlay;	// playfield pointer
 	int prevX, prevY;	// save interger part of position
 	Common::Point ptWin;	// window top left
 
-	if (g_pCurBgnd == NULL)
+	if (_pCurBgnd == NULL)
 		return;		// no current background
 
 	// scroll each background playfield
-	for (i = 0; i < g_pCurBgnd->numPlayfields; i++) {
+	for (i = 0; i < _pCurBgnd->numPlayfields; i++) {
 		// get pointer to correct playfield
-		pPlay = g_pCurBgnd->fieldArray + i;
+		pPlay = _pCurBgnd->fieldArray + i;
 
 		// save integer part of position
 		prevX = fracToInt(pPlay->fieldX);
@@ -254,11 +251,11 @@ void DrawBackgnd() {
 	for (RectList::const_iterator r = clipRects.begin(); r != clipRects.end(); ++r) {
 		// clear the clip rectangle on the virtual screen
 		// for each background playfield
-		for (i = 0; i < g_pCurBgnd->numPlayfields; i++) {
+		for (i = 0; i < _pCurBgnd->numPlayfields; i++) {
 			Common::Rect rcPlayClip;	// clip rect for this playfield
 
 			// get pointer to correct playfield
-			pPlay = g_pCurBgnd->fieldArray + i;
+			pPlay = _pCurBgnd->fieldArray + i;
 
 			// convert fixed point window pos to a int
 			ptWin.x = fracToInt(pPlay->fieldX);
@@ -284,4 +281,33 @@ void DrawBackgnd() {
 	ResetClipRect();
 }
 
+int Background::BgWidth() {
+	assert(_pBG[0]);
+	return MultiRightmost(_pBG[0]) + 1;
+}
+
+int Background::BgHeight() {
+	assert(_pBG[0]);
+	return MultiLowest(_pBG[0]) + 1;
+}
+
+void Background::SetBackPal(SCNHANDLE hPal) {
+	_hBgPal = hPal;
+
+	_font->FettleFontPal(_hBgPal);
+	CreateTranslucentPalette(_hBgPal);
+}
+
+void Background::DropBackground() {
+	_pBG[0] = NULL;	// No background
+
+	if (!TinselV2)
+		_hBgPal = 0;	// No background palette
+}
+
+void Background::ChangePalette(SCNHANDLE hPal) {
+	SwapPalette(FindPalette(_hBgPal), hPal);
+	SetBackPal(hPal);
+}
+
 } // End of namespace Tinsel
diff --git a/engines/tinsel/background.h b/engines/tinsel/background.h
index ccad494..f449a79 100644
--- a/engines/tinsel/background.h
+++ b/engines/tinsel/background.h
@@ -27,7 +27,9 @@
 #include "common/coroutines.h"
 #include "common/frac.h"
 #include "common/rect.h"
+#include "tinsel/anim.h"	// for ANIM
 #include "tinsel/dw.h"	// for SCNHANDLE
+#include "tinsel/object.h"	// for POBJECT
 #include "tinsel/palette.h"	// palette definitions
 
 namespace Tinsel {
@@ -73,40 +75,90 @@ struct BACKGND {
 |*			Background Function Prototypes			*|
 \*----------------------------------------------------------------------*/
 
-void InitBackground();
+#define MAX_BG	10
 
-void StartupBackground(CORO_PARAM, SCNHANDLE hFilm);
+class Font;
 
-void PlayfieldSetPos(		// Sets the xy position of the specified playfield in the current background
-	int which,		// which playfield
-	int newXpos,		// new x position
-	int newYpos);		// new y position
+class Background {
+public:
+	Background(Font *font) : _font(font), _pCurBgnd(nullptr), _hBgPal(0), _BGspeed(0), _hBackground(0), _bDoFadeIn(false), _bgReels(0) {}
 
-void PlayfieldGetPos(		// Returns the xy position of the specified playfield in the current background
-	int which,		// which playfield
-	int *pXpos,		// returns current x position
-	int *pYpos);		// returns current y position
+	void InitBackground();
 
-int PlayfieldGetCenterX(	// Returns the xy position of the specified playfield in the current background
-	int which);		// which playfield
+	void DrawBackgnd();		// Draws all playfields for the current background
 
-OBJECT **GetPlayfieldList(	// Returns the display list for the specified playfield
-	int which);		// which playfield
+	void RedrawBackgnd();	// Completely redraws all the playfield object lists for the current background
 
-void KillPlayfieldList(		// Kills all the objects on the display list for the specified playfield
-	int which);		// which playfield
+	/**
+	 * Called before scene change.
+	 */
+	void DropBackground();
 
-void DrawBackgnd();		// Draws all playfields for the current background
+	void ResetBackground() { _pCurBgnd = nullptr; }
 
-void RedrawBackgnd();	// Completely redraws all the playfield object lists for the current background
+	void StartupBackground(CORO_PARAM, SCNHANDLE hFilm);
 
-OBJECT *GetBgObject();
+	void PlayfieldSetPos(		// Sets the xy position of the specified playfield in the current background
+		int which,		// which playfield
+		int newXpos,		// new x position
+		int newYpos);		// new y position
 
-SCNHANDLE BgPal();
+	void PlayfieldGetPos(		// Returns the xy position of the specified playfield in the current background
+		int which,		// which playfield
+		int* pXpos,		// returns current x position
+		int* pYpos);		// returns current y position
 
-int BgWidth();
+	int PlayfieldGetCenterX(	// Returns the xy position of the specified playfield in the current background
+		int which);		// which playfield
 
-int BgHeight();
+	OBJECT** GetPlayfieldList(	// Returns the display list for the specified playfield
+		int which);		// which playfield
+
+	OBJECT* GetBgObject() { return _pBG[0]; }
+
+	void ChangePalette(SCNHANDLE hPal);
+
+	SCNHANDLE BgPal() { return _hBgPal; }
+
+	void SetDoFadeIn(bool tf) { _bDoFadeIn = tf; }
+
+	bool GetDoFadeIn() { return _bDoFadeIn; }
+
+	/**
+	 * Return the current scene handle.
+	 */
+	SCNHANDLE GetBgroundHandle() { return _hBackground; }
+
+	/**
+	 * Return the width of the current background.
+	 */
+	int BgWidth();
+
+	/**
+	 * Return the height of the current background.
+	 */
+	int BgHeight();
+
+	void SetBackPal(SCNHANDLE hPal);
+
+	int getBgSpeed() { return _BGspeed; }
+
+private:
+	Font *_font;
+
+	// current background
+	const BACKGND *_pCurBgnd;
+
+	SCNHANDLE _hBgPal;	// Background's palette
+	int _BGspeed;
+	SCNHANDLE _hBackground;	// Current scene handle - stored in case of Save_Scene()
+	bool _bDoFadeIn;
+
+public:
+	int _bgReels;
+	POBJECT _pBG[MAX_BG];
+	ANIM	_thisAnim[MAX_BG];	// used by BGmainProcess()
+};
 
 } // End of namespace Tinsel
 
diff --git a/engines/tinsel/bg.cpp b/engines/tinsel/bg.cpp
index e367c49..e98c66f 100644
--- a/engines/tinsel/bg.cpp
+++ b/engines/tinsel/bg.cpp
@@ -42,70 +42,10 @@
 
 namespace Tinsel {
 
-//----------------- LOCAL GLOBAL DATA --------------------
-
-#define MAX_BG	10
-
-// FIXME: Avoid non-const global vars
-static SCNHANDLE g_hBgPal = 0;	// Background's palette
-static POBJECT g_pBG[MAX_BG];
-static ANIM	g_thisAnim[MAX_BG];	// used by BGmainProcess()
-static int g_BGspeed = 0;
-static SCNHANDLE g_hBackground = 0;	// Current scene handle - stored in case of Save_Scene()
-static bool g_bDoFadeIn = false;
-static int g_bgReels;
-
-/**
- * GetBgObject
- */
-OBJECT *GetBgObject() {
-	return g_pBG[0];
-}
-
-/**
- * BackPal
- */
-SCNHANDLE BgPal() {
-	return g_hBgPal;
-}
-
-/**
- * SetDoFadeIn
-*/
-void SetDoFadeIn(bool tf) {
-	g_bDoFadeIn = tf;
-}
-
-/**
- * Called before scene change.
- */
-void DropBackground() {
-	g_pBG[0] = NULL;	// No background
-
-	if (!TinselV2)
-		g_hBgPal = 0;	// No background palette
-}
-
-/**
- * Return the width of the current background.
- */
-int BgWidth() {
-	assert(g_pBG[0]);
-	return MultiRightmost(g_pBG[0]) + 1;
-}
-
-/**
- * Return the height of the current background.
- */
-int BgHeight() {
-	assert(g_pBG[0]);
-	return MultiLowest(g_pBG[0]) + 1;
-}
-
 /**
  * Run main animation that comprises the scene background.
  */
-static void BGmainProcess(CORO_PARAM, const void *param) {
+void BGmainProcess(CORO_PARAM, const void *param) {
 	// COROUTINE
 	CORO_BEGIN_CONTEXT;
 	CORO_END_CONTEXT(_ctx);
@@ -117,7 +57,7 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
 	const MULTI_INIT *pmi;
 
 	// get the stuff copied to process when it was created
-	if (g_pBG[0] == NULL) {
+	if (_vm->_bg->_pBG[0] == NULL) {
 		/*** At start of scene ***/
 
 		if (!TinselV2) {
@@ -127,40 +67,40 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
 			pmi = (const MULTI_INIT *)LockMem(FROM_32(pReel->mobj));
 
 			// Initialize and insert the object, and initialize its script.
-			g_pBG[0] = MultiInitObject(pmi);
-			MultiInsertObject(GetPlayfieldList(FIELD_WORLD), g_pBG[0]);
-			InitStepAnimScript(&g_thisAnim[0], g_pBG[0], FROM_32(pReel->script), g_BGspeed);
-			g_bgReels = 1;
+			_vm->_bg->_pBG[0] = MultiInitObject(pmi);
+			MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _vm->_bg->_pBG[0]);
+			InitStepAnimScript(&_vm->_bg->_thisAnim[0], _vm->_bg->_pBG[0], FROM_32(pReel->script), _vm->_bg->getBgSpeed());
+			_vm->_bg->_bgReels = 1;
 		} else {
 			/*** At start of scene ***/
-			pFilm = (const FILM *)LockMem(g_hBackground);
-			g_bgReels = FROM_32(pFilm->numreels);
+			pFilm = (const FILM *)LockMem(_vm->_bg->GetBgroundHandle());
+			_vm->_bg->_bgReels = FROM_32(pFilm->numreels);
 
 			int i;
-			for (i = 0; i < g_bgReels; i++) {
+			for (i = 0; i < _vm->_bg->_bgReels; i++) {
 				// Get the MULTI_INIT structure
 				pmi = (PMULTI_INIT) LockMem(FROM_32(pFilm->reels[i].mobj));
 
 				// Initialize and insert the object, and initialize its script.
-				g_pBG[i] = MultiInitObject(pmi);
-				MultiInsertObject(GetPlayfieldList(FIELD_WORLD), g_pBG[i]);
-				MultiSetZPosition(g_pBG[i], 0);
-				InitStepAnimScript(&g_thisAnim[i], g_pBG[i], FROM_32(pFilm->reels[i].script), g_BGspeed);
+				_vm->_bg->_pBG[i] = MultiInitObject(pmi);
+				MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _vm->_bg->_pBG[i]);
+				MultiSetZPosition(_vm->_bg->_pBG[i], 0);
+				InitStepAnimScript(&_vm->_bg->_thisAnim[i], _vm->_bg->_pBG[i], FROM_32(pFilm->reels[i].script), _vm->_bg->getBgSpeed());
 
 				if (i > 0)
-					g_pBG[i-1]->pSlave = g_pBG[i];
+					_vm->_bg->_pBG[i-1]->pSlave = _vm->_bg->_pBG[i];
 			}
 		}
 
-		if (g_bDoFadeIn) {
+		if (_vm->_bg->GetDoFadeIn()) {
 			FadeInFast();
-			g_bDoFadeIn = false;
+			_vm->_bg->SetDoFadeIn(false);
 		} else if (TinselV2)
 			PokeInTagColor();
 
 		for (;;) {
-			for (int i = 0; i < g_bgReels; i++) {
-				if (StepAnimScript(&g_thisAnim[i]) == ScriptFinished)
+			for (int i = 0; i < _vm->_bg->_bgReels; i++) {
+				if (StepAnimScript(&_vm->_bg->_thisAnim[i]) == ScriptFinished)
 					error("Background animation has finished");
 			}
 
@@ -170,16 +110,16 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
 		// New background during scene
 		if (!TinselV2) {
 			pReel = (const FREEL *)param;
-			InitStepAnimScript(&g_thisAnim[0], g_pBG[0], FROM_32(pReel->script), g_BGspeed);
-			StepAnimScript(&g_thisAnim[0]);
+			InitStepAnimScript(&_vm->_bg->_thisAnim[0], _vm->_bg->_pBG[0], FROM_32(pReel->script), _vm->_bg->getBgSpeed());
+			StepAnimScript(&_vm->_bg->_thisAnim[0]);
 		} else {
-			pFilm = (const FILM *)LockMem(g_hBackground);
-			assert(g_bgReels == (int32)FROM_32(pFilm->numreels));
+			pFilm = (const FILM *)LockMem(_vm->_bg->GetBgroundHandle());
+			assert(_vm->_bg->_bgReels == (int32)FROM_32(pFilm->numreels));
 
 			// Just re-initialize the scripts.
-			for (int i = 0; i < g_bgReels; i++) {
-				InitStepAnimScript(&g_thisAnim[i], g_pBG[i], pFilm->reels[i].script, g_BGspeed);
-				StepAnimScript(&g_thisAnim[i]);
+			for (int i = 0; i < _vm->_bg->_bgReels; i++) {
+				InitStepAnimScript(&_vm->_bg->_thisAnim[i], _vm->_bg->_pBG[i], pFilm->reels[i].script, _vm->_bg->getBgSpeed());
+				StepAnimScript(&_vm->_bg->_thisAnim[i]);
 			}
 		}
 	}
@@ -190,7 +130,7 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
 /**
  * Runs secondary reels for a scene background
  */
-static void BGotherProcess(CORO_PARAM, const void *param) {
+void BGotherProcess(CORO_PARAM, const void *param) {
 	// COROUTINE
 	CORO_BEGIN_CONTEXT;
 		OBJECT *pObj;
@@ -204,9 +144,9 @@ static void BGotherProcess(CORO_PARAM, const void *param) {
 
 	// Initialize and insert the object, and initialize its script.
 	_ctx->pObj = MultiInitObject(pmi);
-	MultiInsertObject(GetPlayfieldList(FIELD_WORLD), _ctx->pObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pObj);
 
-	InitStepAnimScript(&_ctx->anim, g_pBG[0], FROM_32(pReel->script), g_BGspeed);
+	InitStepAnimScript(&_ctx->anim, _vm->_bg->_pBG[0], FROM_32(pReel->script), _vm->_bg->getBgSpeed());
 
 	while (StepAnimScript(&_ctx->anim) != ScriptFinished)
 		CORO_SLEEP(1);
@@ -215,28 +155,12 @@ static void BGotherProcess(CORO_PARAM, const void *param) {
 }
 
 /**
- * AetBgPal()
- */
-void SetBackPal(SCNHANDLE hPal) {
-	g_hBgPal = hPal;
-
-	_vm->_font->FettleFontPal(g_hBgPal);
-	CreateTranslucentPalette(g_hBgPal);
-}
-
-void ChangePalette(SCNHANDLE hPal) {
-	SwapPalette(FindPalette(g_hBgPal), hPal);
-
-	SetBackPal(hPal);
-}
-
-/**
  * Given the scene background film, extracts the palette handle for
  * everything else's use, then starts a display process for each reel
  * in the film.
  * @param hFilm			Scene background film
  */
-void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
+void Background::StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
 	CORO_BEGIN_CONTEXT;
 	CORO_END_CONTEXT(_ctx);
 
@@ -245,14 +169,14 @@ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
 	const FILM *pfilm;
 	IMAGE *pim;
 
-	g_hBackground = hFilm;		// Save handle in case of Save_Scene()
+	_hBackground = hFilm;		// Save handle in case of Save_Scene()
 
 	pim = GetImageFromFilm(hFilm, 0, NULL, NULL, &pfilm);
 
 	SetBackPal(FROM_32(pim->hImgPal));
 
 	// Extract the film speed
-	g_BGspeed = ONE_SECOND / FROM_32(pfilm->frate);
+	_BGspeed = ONE_SECOND / FROM_32(pfilm->frate);
 
 	// Start display process for each reel in the film
 	CoroScheduler.createProcess(PID_REEL, BGmainProcess, &pfilm->reels[0], sizeof(FREEL));
@@ -262,7 +186,7 @@ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
 			CoroScheduler.createProcess(PID_REEL, BGotherProcess, &pfilm->reels[i], sizeof(FREEL));
 	}
 
-	if (g_pBG[0] == NULL)
+	if (_pBG[0] == NULL)
 		ControlStartOff();
 
 	if (TinselV2 && (coroParam != Common::nullContext))
@@ -271,11 +195,4 @@ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
 	CORO_END_CODE;
 }
 
-/**
- * Return the current scene handle.
- */
-SCNHANDLE GetBgroundHandle() {
-	return g_hBackground;
-}
-
 } // End of namespace Tinsel
diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp
index 69155a9..66d0e81 100644
--- a/engines/tinsel/bmv.cpp
+++ b/engines/tinsel/bmv.cpp
@@ -440,7 +440,7 @@ void BMVPlayer::FettleMovieText() {
 	for (i = 0; i < 2; i++) {
 		if (texts[i].pText) {
 			if (currentFrame > texts[i].dieFrame) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), texts[i].pText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), texts[i].pText);
 				texts[i].pText = NULL;
 			} else {
 				MultiForceRedraw(texts[i].pText);
@@ -480,7 +480,7 @@ void BMVPlayer::BmvDrawText(bool bDraw) {
 				rcPlayClip.top = y;
 				rcPlayClip.right = x+w;
 				rcPlayClip.bottom = y+h;
-				UpdateClipRect(GetPlayfieldList(FIELD_STATUS), &ptWin,	&rcPlayClip);
+				UpdateClipRect(_vm->_bg->GetPlayfieldList(FIELD_STATUS), &ptWin,	&rcPlayClip);
 			}
 		}
 	}
@@ -509,12 +509,12 @@ void BMVPlayer::MovieText(CORO_PARAM, int stringId, int x, int y, int fontId, CO
 	}
 
 	if (texts[index].pText)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), texts[index].pText);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), texts[index].pText);
 
 	LoadSubString(stringId, 0, _vm->_font->TextBufferAddr(), TBUFSZ);
 
 	texts[index].dieFrame = currentFrame + duration;
-	texts[index].pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+	texts[index].pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 						_vm->_font->TextBufferAddr(),
 						0,
 						x, y,
@@ -734,7 +734,7 @@ void BMVPlayer::FinishBMV() {
 	// Ditch any text objects
 	for (i = 0; i < 2; i++) {
 		if (texts[i].pText) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), texts[i].pText);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), texts[i].pText);
 			texts[i].pText = NULL;
 		}
 	}
@@ -1025,7 +1025,7 @@ bool BMVPlayer::DoSoundFrame() {
 void BMVPlayer::CopyMovieToScreen() {
 	// Not if not up and running yet!
 	if (!screenBuffer || (currentFrame == 0)) {
-		DrawBackgnd();
+		_vm->_bg->DrawBackgnd();
 		return;
 	}
 
diff --git a/engines/tinsel/cursor.cpp b/engines/tinsel/cursor.cpp
index c23e4f2..dfd1ca2 100644
--- a/engines/tinsel/cursor.cpp
+++ b/engines/tinsel/cursor.cpp
@@ -121,15 +121,15 @@ static void InitCurTrailObj(int i, int x, int y) {
 
 	// Get rid of old object
 	if (g_ntrailData[i].trailObj != NULL)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
 
 	pim = GetImageFromFilm(g_hCursorFilm, i+1, &pfr, &pmi, &pfilm);// Get pointer to image
-	assert(BgPal()); // No background palette
-	pim->hImgPal = TO_32(BgPal());
+	assert(_vm->_bg->BgPal()); // No background palette
+	pim->hImgPal = TO_32(_vm->_bg->BgPal());
 
 	// Initialize and insert the object, set its Z-pos, and hide it
 	g_ntrailData[i].trailObj = MultiInitObject(pmi);
-	MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
 	MultiSetZPosition(g_ntrailData[i].trailObj, Z_CURSORTRAIL);
 	MultiSetAniXY(g_ntrailData[i].trailObj, x, y);
 
@@ -170,7 +170,7 @@ void SetCursorXY(int newx, int newy) {
 	int	x, y;
 	int	Loffset, Toffset;	// Screen offset
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 	newx -= Loffset;
 	newy -= Toffset;
 
@@ -205,7 +205,7 @@ bool GetCursorXYNoWait(int *x, int *y, bool absolute) {
 
 	if (absolute) {
 		int	Loffset, Toffset;	// Screen offset
-		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 		*x += Loffset;
 		*y += Toffset;
 	}
@@ -267,7 +267,7 @@ void DwHideCursor() {
 
 	for (i = 0; i < g_numTrails; i++) {
 		if (g_ntrailData[i].trailObj != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
 			g_ntrailData[i].trailObj = NULL;
 		}
 	}
@@ -304,7 +304,7 @@ void HideCursorTrails() {
 
 	for (i = 0; i < g_numTrails; i++)	{
 		if (g_ntrailData[i].trailObj != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
 			g_ntrailData[i].trailObj = NULL;
 		}
 	}
@@ -357,7 +357,7 @@ IMAGE *GetImageFromFilm(SCNHANDLE hFilm, int reel, const FREEL **ppfr, const MUL
  */
 void DelAuxCursor() {
 	if (g_AcurObj != NULL) {
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_AcurObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_AcurObj);
 		g_AcurObj = NULL;
 	}
 }
@@ -376,14 +376,14 @@ void SetAuxCursor(SCNHANDLE hFilm) {
 	DelAuxCursor();		// Get rid of previous
 
 	// WORKAROUND: There's no palette when loading a DW1 savegame with a held item, so exit if so
-	if (!BgPal())
+	if (!_vm->_bg->BgPal())
 		return;
 
 	GetCursorXY(&x, &y, false);	// Note: also waits for cursor to appear
 
 	pim = GetImageFromFilm(hFilm, 0, &pfr, &pmi, &pfilm);// Get pointer to image
-	assert(BgPal()); // no background palette
-	pim->hImgPal = TO_32(BgPal());			// Poke in the background palette
+	assert(_vm->_bg->BgPal()); // no background palette
+	pim->hImgPal = TO_32(_vm->_bg->BgPal());			// Poke in the background palette
 
 	g_ACoX = (short)(FROM_16(pim->imgWidth)/2 - ((int16) FROM_16(pim->anioffX)));
 	g_ACoY = (short)((FROM_16(pim->imgHeight) & ~C16_FLAG_MASK)/2 -
@@ -391,7 +391,7 @@ void SetAuxCursor(SCNHANDLE hFilm) {
 
 	// Initialize and insert the auxillary cursor object
 	g_AcurObj = MultiInitObject(pmi);
-	MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_AcurObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_AcurObj);
 
 	// Initialize the animation and set its position
 	InitStepAnimScript(&g_AcurAnim, g_AcurObj, FROM_32(pfr->script), ONE_SECOND / FROM_32(pfilm->frate));
@@ -489,16 +489,16 @@ static void InitCurObj() {
 
 		PokeInPalette(pmi);
 	} else {
-		assert(BgPal()); // no background palette
+		assert(_vm->_bg->BgPal()); // no background palette
 
 		pim = GetImageFromFilm(g_hCursorFilm, 0, &pfr, &pmi, &pFilm);// Get pointer to image
-		pim->hImgPal = TO_32(BgPal());
+		pim->hImgPal = TO_32(_vm->_bg->BgPal());
 
 		g_AcurObj = NULL;		// No auxillary cursor
 	}
 
 	g_McurObj = MultiInitObject(pmi);
-	MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_McurObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_McurObj);
 
 	InitStepAnimScript(&g_McurAnim, g_McurObj, FROM_32(pfr->script), ONE_SECOND / FROM_32(pFilm->frate));
 }
@@ -556,7 +556,7 @@ void CursorProcess(CORO_PARAM, const void *) {
 
 	CORO_BEGIN_CODE(_ctx);
 
-	while (!g_hCursorFilm || !BgPal())
+	while (!g_hCursorFilm || !_vm->_bg->BgPal())
 		CORO_SLEEP(1);
 
 	InitCurObj();
@@ -580,7 +580,7 @@ void CursorProcess(CORO_PARAM, const void *) {
 		for (int i = 0; i < g_numTrails; i++) {
 			if (g_ntrailData[i].trailObj != NULL) {
 				if (StepAnimScript(&g_ntrailData[i].trailAnim) == ScriptFinished) {
-					MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+					MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
 					g_ntrailData[i].trailObj = NULL;
 				}
 			}
@@ -635,9 +635,9 @@ void DwInitCursor(SCNHANDLE bfilm) {
 void DropCursor() {
 	if (TinselV2) {
 		if (g_AcurObj)
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_AcurObj);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_AcurObj);
 		if (g_McurObj)
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_McurObj);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_McurObj);
 
 		g_restart = 0;
 	}
@@ -650,7 +650,7 @@ void DropCursor() {
 
 	for (int i = 0; i < g_numTrails; i++) {
 		if (g_ntrailData[i].trailObj != NULL)		{
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
 			g_ntrailData[i].trailObj = NULL;
 		}
 	}
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index ddc9de9..44202b2 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -1217,7 +1217,7 @@ static void HopAction() {
 static void DumpIconArray() {
 	for (int i = 0; i < MAX_ICONS; i++) {
 		if (g_iconArray[i] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[i]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[i]);
 			g_iconArray[i] = NULL;
 		}
 	}
@@ -1229,7 +1229,7 @@ static void DumpIconArray() {
 static void DumpDobjArray() {
 	for (int i = 0; i < MAX_WCOMP; i++) {
 		if (g_DobjArray[i] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_DobjArray[i]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_DobjArray[i]);
 			g_DobjArray[i] = NULL;
 		}
 	}
@@ -1241,7 +1241,7 @@ static void DumpDobjArray() {
 static void DumpObjArray() {
 	for (int i = 0; i < MAX_WCOMP; i++) {
 		if (g_objArray[i] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_objArray[i]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_objArray[i]);
 			g_objArray[i] = NULL;
 		}
 	}
@@ -1517,15 +1517,15 @@ static void InvLoadGame() {
 		rGame = cd.selBox;
 		cd.selBox = NOBOX;
 		if (g_iconArray[HL3] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
 			g_iconArray[HL3] = NULL;
 		}
 		if (g_iconArray[HL2] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
 			g_iconArray[HL2] = NULL;
 		}
 		if (g_iconArray[HL1] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 			g_iconArray[HL1] = NULL;
 		}
 		RestoreGame(rGame+cd.extraBase);
@@ -1593,19 +1593,19 @@ static bool InvKeyIn(const Common::KeyState &kbd) {
 			* and replace it with freshly edited text.
 			*/
 			if (g_iconArray[HL3] != NULL) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
 				g_iconArray[HL3] = NULL;
 			}
 			g_iconArray[HL3] = ObjectTextOut(
-				GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
+				_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
 				g_InvD[g_ino].inventoryX + cd.box[cd.selBox].xpos + 2,
 				g_InvD[g_ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
 				_vm->_font->GetTagFontHandle(), 0);
 			if (MultiRightmost(g_iconArray[HL3]) > MAX_NAME_RIGHT) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
 				UpdateString(Common::KeyState(Common::KEYCODE_BACKSPACE));
 				g_iconArray[HL3] = ObjectTextOut(
-					GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
+					_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
 					g_InvD[g_ino].inventoryX + cd.box[cd.selBox].xpos + 2,
 					g_InvD[g_ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
 					_vm->_font->GetTagFontHandle(), 0);
@@ -1636,20 +1636,20 @@ static void Select(int i, bool force) {
 
 	// Clear previous selected highlight and text
 	if (g_iconArray[HL2] != NULL) {
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
 		g_iconArray[HL2] = NULL;
 	}
 	if (g_iconArray[HL3] != NULL) {
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
 		g_iconArray[HL3] = NULL;
 	}
 
 	// New highlight box
 	switch (cd.box[i].boxType) {
 	case RGROUP:
-		g_iconArray[HL2] = RectangleObject(BgPal(),
+		g_iconArray[HL2] = RectangleObject(_vm->_bg->BgPal(),
 			(TinselV2 ? HighlightColor() : COL_HILIGHT), cd.box[i].w, cd.box[i].h);
-		MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
 		MultiSetAniXY(g_iconArray[HL2],
 		g_InvD[g_ino].inventoryX + cd.box[i].xpos,
 		g_InvD[g_ino].inventoryY + cd.box[i].ypos);
@@ -1679,7 +1679,7 @@ static void Select(int i, bool force) {
 #endif
 
 			g_iconArray[HL3] = ObjectTextOut(
-				GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
+				_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
 				g_InvD[g_ino].inventoryX + cd.box[i].xpos + 2,
 #ifdef JAPAN
 				g_InvD[g_ino].inventoryY + cd.box[i].ypos + 2,
@@ -1697,8 +1697,8 @@ static void Select(int i, bool force) {
 		break;
 
 	case FRGROUP:
-		g_iconArray[HL2] = RectangleObject(BgPal(), COL_HILIGHT, cd.box[i].w+6, cd.box[i].h+6);
-		MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+		g_iconArray[HL2] = RectangleObject(_vm->_bg->BgPal(), COL_HILIGHT, cd.box[i].w+6, cd.box[i].h+6);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
 		MultiSetAniXY(g_iconArray[HL2],
 		g_InvD[g_ino].inventoryX + cd.box[i].xpos - 2,
 		g_InvD[g_ino].inventoryY + cd.box[i].ypos - 2);
@@ -2276,24 +2276,24 @@ static void InvBoxes(bool InBody, int curX, int curY) {
 		// unhigh-light box (if one was)
 		cd.pointBox = NOBOX;
 		if (g_iconArray[HL1] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 			g_iconArray[HL1] = NULL;
 		}
 	} else if (index != cd.pointBox) {
 		cd.pointBox = index;
 		// A new box is pointed to - high-light it
 		if (g_iconArray[HL1] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 			g_iconArray[HL1] = NULL;
 		}
 		if ((cd.box[cd.pointBox].boxType == ARSBUT && cd.selBox != NOBOX) ||
 ///* I don't agree */ cd.box[cd.pointBox].boxType == RGROUP ||
 		    cd.box[cd.pointBox].boxType == AATBUT ||
 		    cd.box[cd.pointBox].boxType == AABUT) {
-			g_iconArray[HL1] = RectangleObject(BgPal(),
+			g_iconArray[HL1] = RectangleObject(_vm->_bg->BgPal(),
 				(TinselV2 ? HighlightColor() : COL_HILIGHT),
 				cd.box[cd.pointBox].w, cd.box[cd.pointBox].h);
-			MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+			MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 			MultiSetAniXY(g_iconArray[HL1],
 				g_InvD[g_ino].inventoryX + cd.box[cd.pointBox].xpos,
 				g_InvD[g_ino].inventoryY + cd.box[cd.pointBox].ypos);
@@ -2347,7 +2347,7 @@ static void ButtonPress(CORO_PARAM, CONFBOX *box) {
 	// Replace highlight image with normal image
 	pfilm = (const FILM *)LockMem(g_hWinParts);
 	if (g_iconArray[HL1] != NULL)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 	pfilm = (const FILM *)LockMem(g_hWinParts);
 	g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+NORMGRAPH], -1);
 	MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
@@ -2360,7 +2360,7 @@ static void ButtonPress(CORO_PARAM, CONFBOX *box) {
 
 	// Replace normal image with depresses image
 	pfilm = (const FILM *)LockMem(g_hWinParts);
-	MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+	MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 	g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
 	MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
 	MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
@@ -2372,7 +2372,7 @@ static void ButtonPress(CORO_PARAM, CONFBOX *box) {
 
 	// Replace depressed image with normal image
 	pfilm = (const FILM *)LockMem(g_hWinParts);
-	MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+	MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 	g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+NORMGRAPH], -1);
 	MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
 	MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
@@ -2395,7 +2395,7 @@ static void ButtonToggle(CORO_PARAM, CONFBOX *box) {
 
 	// Remove hilight image
 	if (g_iconArray[HL1] != NULL) {
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 		g_iconArray[HL1] = NULL;
 	}
 
@@ -2426,7 +2426,7 @@ static void ButtonToggle(CORO_PARAM, CONFBOX *box) {
 	// New state, depressed image
 	pfilm = (const FILM *)LockMem(g_hWinParts);
 	if (g_iconArray[HL1] != NULL)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 	g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
 	MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
 	MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
@@ -2437,7 +2437,7 @@ static void ButtonToggle(CORO_PARAM, CONFBOX *box) {
 		return;
 
 	// New state, normal
-	MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+	MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 	g_iconArray[HL1] = NULL;
 
 	// Hold normal image for 1 frame
@@ -2448,7 +2448,7 @@ static void ButtonToggle(CORO_PARAM, CONFBOX *box) {
 	// New state, highlighted
 	pfilm = (const FILM *)LockMem(g_hWinParts);
 	if (g_iconArray[HL1] != NULL)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
 	g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+HIGRAPH], -1);
 	MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
 	MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
@@ -2573,11 +2573,11 @@ static OBJECT *AddInvObject(int num, const FREEL **pfreel, const FILM **pfilm) {
 	pim = GetImageFromFilm(invObj->hIconFilm, 0, pfreel, &pmi, pfilm);
 
 	// Poke in the background palette
-	pim->hImgPal = TO_32(BgPal());
+	pim->hImgPal = TO_32(_vm->_bg->BgPal());
 
 	// Set up the multi-object
 	pPlayObj = MultiInitObject(pmi);
-	MultiInsertObject(GetPlayfieldList(FIELD_STATUS), pPlayObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), pPlayObj);
 
 	return pPlayObj;
 }
@@ -2639,7 +2639,7 @@ static void AddBackground(OBJECT **rect, OBJECT **title, int extraH, int extraV,
 	g_RectObject = *rect = TranslucentObject(width, height);
 
 	// add it to display list and position it
-	MultiInsertObject(GetPlayfieldList(FIELD_STATUS), *rect);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), *rect);
 	MultiSetAniXY(*rect, g_InvD[g_ino].inventoryX + NM_BG_POS_X,
 		g_InvD[g_ino].inventoryY + NM_BG_POS_Y);
 	MultiSetZPosition(*rect, Z_INV_BRECT);
@@ -2650,14 +2650,14 @@ static void AddBackground(OBJECT **rect, OBJECT **title, int extraH, int extraV,
 	// Create text object using title string
 	if (textFrom == FROM_HANDLE) {
 		LoadStringRes(g_InvD[g_ino].hInvTitle, _vm->_font->TextBufferAddr(), TBUFSZ);
-		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
+		*title = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 					g_InvD[g_ino].inventoryX + width/2, g_InvD[g_ino].inventoryY + M_TOFF,
 					_vm->_font->GetTagFontHandle(), TXT_CENTER);
 		assert(*title); // Inventory title string produced NULL text
 		MultiSetZPosition(*title, Z_INV_HTEXT);
 	} else if (textFrom == FROM_STRING && cd.ixHeading != NO_HEADING) {
 		LoadStringRes(g_configStrings[cd.ixHeading], _vm->_font->TextBufferAddr(), TBUFSZ);
-		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
+		*title = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 					g_InvD[g_ino].inventoryX + width/2, g_InvD[g_ino].inventoryY + M_TOFF,
 					_vm->_font->GetTagFontHandle(), TXT_CENTER);
 		assert(*title); // Inventory title string produced NULL text
@@ -2681,7 +2681,7 @@ static void AddTitle(POBJECT *title, int extraH) {
 	// Create text object using title string
 	if (g_InvD[g_ino].hInvTitle != (SCNHANDLE)NO_HEADING) {
 		LoadStringRes(g_InvD[g_ino].hInvTitle, _vm->_font->TextBufferAddr(), TBUFSZ);
-		*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
+		*title = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 					g_InvD[g_ino].inventoryX + (width/2)+NM_BG_POS_X, g_InvD[g_ino].inventoryY + NM_TOFF,
 			_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 		assert(*title);
@@ -2702,7 +2702,7 @@ static OBJECT *AddObject(const FREEL *pfreel, int num) {
 	pim = GetImageFromReel(pfreel, &pmi);
 
 	// Poke in the background palette
-	pim->hImgPal = TO_32(BgPal());
+	pim->hImgPal = TO_32(_vm->_bg->BgPal());
 
 	// Horrible bodge involving global variables to save
 	// width and/or height of some window frame components
@@ -2717,7 +2717,7 @@ static OBJECT *AddObject(const FREEL *pfreel, int num) {
 
 	// Set up and insert the multi-object
 	pPlayObj = MultiInitObject(pmi);
-	MultiInsertObject(GetPlayfieldList(FIELD_STATUS), pPlayObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), pPlayObj);
 
 	return pPlayObj;
 }
@@ -2750,9 +2750,9 @@ static void AddBox(int *pi, const int i) {
 			break;
 
 		// Give us a box
-		g_iconArray[*pi] = RectangleObject(BgPal(), TinselV2 ? BoxColor() : COL_BOX,
+		g_iconArray[*pi] = RectangleObject(_vm->_bg->BgPal(), TinselV2 ? BoxColor() : COL_BOX,
 			cd.box[i].w, cd.box[i].h);
-		MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[*pi]);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_iconArray[*pi]);
 		MultiSetAniXY(g_iconArray[*pi], x, y);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT + 1);
 		*pi += 1;
@@ -2762,14 +2762,14 @@ static void AddBox(int *pi, const int i) {
 				(!TinselV2 && (cd.box[i].ixText == USE_POINTER))) {
 			if (cd.box[i].boxText != NULL) {
 				if (cd.box[i].boxType == RGROUP) {
-					g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
+					g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
 #ifdef JAPAN
 							x + 2, y+2, GetTagFontHandle(), 0);
 #else
 							x + 2, y + TYOFF, _vm->_font->GetTagFontHandle(), 0);
 #endif
 				} else {
-					g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
+					g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
 #ifdef JAPAN
 // Note: it never seems to go here!
 							x + cd.box[i].w/2, y+2, GetTagFontHandle(), TXT_CENTER);
@@ -2795,10 +2795,10 @@ static void AddBox(int *pi, const int i) {
 			}
 
 			if (TinselV2 && (cd.box[i].boxType == RGROUP))
-				g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+				g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 						0, x + 2, y + TYOFF, _vm->_font->GetTagFontHandle(), 0, 0);
 			else
-				g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+				g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 					_vm->_font->TextBufferAddr(), 0,
 #ifdef JAPAN
 					x + cd.box[i].w/2, y+2, GetTagFontHandle(), TXT_CENTER);
@@ -2855,7 +2855,7 @@ static void AddBox(int *pi, const int i) {
 			assert(cd.box[i].ixText != USE_POINTER);
 			LoadStringRes(g_configStrings[cd.box[i].ixText], _vm->_font->TextBufferAddr(), TBUFSZ);
 		}
-		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+		g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 			_vm->_font->TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF, _vm->_font->GetTagFontHandle(), TXT_RIGHT);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 		*pi += 1;
@@ -2882,11 +2882,11 @@ static void AddBox(int *pi, const int i) {
 		}
 
 		if (cd.box[i].boxType == TOGGLE2) {
-			g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+			g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 				_vm->_font->TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
 				_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 		} else {
-			g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+			g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 				_vm->_font->TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF,
 				_vm->_font->GetTagFontHandle(), TXT_RIGHT, 0);
 		}
@@ -2921,7 +2921,7 @@ static void AddBox(int *pi, const int i) {
 			assert(cd.box[i].ixText != USE_POINTER);
 			LoadStringRes(g_configStrings[cd.box[i].ixText], _vm->_font->TextBufferAddr(), TBUFSZ);
 		}
-		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+		g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 			_vm->_font->TextBufferAddr(), 0, x+MDTEXT_XOFF, y+MDTEXT_YOFF, _vm->_font->GetTagFontHandle(), TXT_RIGHT);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 		*pi += 1;
@@ -2946,7 +2946,7 @@ static void AddBox(int *pi, const int i) {
 			// Stick in the text
 			assert(cd.box[i].textMethod == TM_INDEX);
 			LoadStringRes(SysString(cd.box[i].ixText), _vm->_font->TextBufferAddr(), TBUFSZ);
-			g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+			g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 				_vm->_font->TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
 				_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 			MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
@@ -2958,7 +2958,7 @@ static void AddBox(int *pi, const int i) {
 			break;
 
 		LoadStringRes(LanguageDesc(g_displayedLanguage), _vm->_font->TextBufferAddr(), TBUFSZ);
-		g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
+		g_iconArray[*pi] = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(), 0,
 				x + cd.box[i].w / 2, y + ROT_YOFF, _vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 		MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
 		*pi += 1;
@@ -3131,7 +3131,7 @@ static void ConstructInventory(InventoryType filling) {
 	// Dispose of anything it may be replacing
 	for (int i = 0; i < MAX_WCOMP; i++) {
 		if (retObj[i] != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), retObj[i]);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), retObj[i]);
 			retObj[i] = NULL;
 		}
 	}
@@ -3411,7 +3411,7 @@ static void AlterCursor(int num) {
 	pim = GetImageFromFilm(g_hWinParts, num, &pfreel);
 
 	// Poke in the background palette
-	pim->hImgPal = TO_32(BgPal());
+	pim->hImgPal = TO_32(_vm->_bg->BgPal());
 
 	SetTempCursor(FROM_32(pfreel->script));
 }
@@ -3718,7 +3718,7 @@ extern void HideConversation(bool bHide) {
 					int Loffset, Toffset;
 
 					GetActorMidTop(g_thisConvActor, &x, &y);
-					PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+					_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 					x -= Loffset;
 					y -= Toffset;
 				} else {
@@ -3773,7 +3773,7 @@ extern void HideConversation(bool bHide) {
 						&& g_thisConvActor) {
 					int Loffset, Toffset;
 
-					PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+					_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 					y = GetActorBottom(g_thisConvActor) - MultiHighest(g_RectObject) +
 						SysVar(SV_CONV_BELOW_Y);
 					y -= Toffset;
diff --git a/engines/tinsel/events.cpp b/engines/tinsel/events.cpp
index 07d3c51..5f2fb56 100644
--- a/engines/tinsel/events.cpp
+++ b/engines/tinsel/events.cpp
@@ -417,7 +417,7 @@ void PlayerEvent(PLR_EVENT pEvent, const Common::Point &coOrds) {
 
 	if (TinselV2 && InventoryActive()) {
 		int x, y;
-		PlayfieldGetPos(FIELD_WORLD, &x, &y);
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &x, &y);
 		EventToInventory(pEvent, Common::Point(coOrds.x - x, coOrds.y - y));
 		return;
 	}
diff --git a/engines/tinsel/font.h b/engines/tinsel/font.h
index a74e7b0..c31a3fe 100644
--- a/engines/tinsel/font.h
+++ b/engines/tinsel/font.h
@@ -31,8 +31,6 @@ namespace Tinsel {
 // Accessed using TextBufferAddr(), this is how big it is:
 #define TBUFSZ	512
 
-class TinselEngine;
-
 class Font {
 public:
 	Font() : _hTagFont(0), _hTalkFont(0), _hRegularTalkFont(0), _hRegularTagFont(0), _tBuffer("") {
diff --git a/engines/tinsel/move.cpp b/engines/tinsel/move.cpp
index 62d0cd9..a431041 100644
--- a/engines/tinsel/move.cpp
+++ b/engines/tinsel/move.cpp
@@ -133,7 +133,7 @@ static int ClickedOnPath(int clickX, int clickY, int *ptgtX, int *ptgtY) {
 		 In a Blocking polygon - try searching down and up.
 		 If still nowhere (for now) give up!
 		 ------------------------------------------------------*/
-		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 		for (i = clickY+1; i < SCREEN_HEIGHT + Toffset; i++) {
 			// Don't leave the path system
@@ -180,7 +180,7 @@ static int ClickedOnRefer(HPOLYGON hRefpoly, int clickX, int clickY, int *ptgtX,
 	int	end;		// Extreme of the scene
 	int	Loffset, Toffset;
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 	*ptgtX = *ptgtY = -1;
 
 	switch (PolySubtype(hRefpoly)) {
@@ -190,7 +190,7 @@ static int ClickedOnRefer(HPOLYGON hRefpoly, int clickX, int clickY, int *ptgtX,
 		break;
 
 	case REF_DOWN:				// Search downwards
-		end = BgHeight();
+		end = _vm->_bg->BgHeight();
 		for (i = clickY+1; i < end; i++)
 			if (InPolygon(clickX, i, PATH) != NOPOLY
 					&& InPolygon(clickX, i, BLOCK) == NOPOLY) {
@@ -211,7 +211,7 @@ static int ClickedOnRefer(HPOLYGON hRefpoly, int clickX, int clickY, int *ptgtX,
 		break;
 
 	case REF_RIGHT:				// Search to the right
-		end = BgWidth();
+		end = _vm->_bg->BgWidth();
 		for (i = clickX+1; i < end; i++)
 			if (InPolygon(i, clickY, PATH) != NOPOLY
 			&& InPolygon(i, clickY, BLOCK) == NOPOLY) {
@@ -252,7 +252,7 @@ static int ClickedOnNothing(int clickX, int clickY, int *ptgtX, int *ptgtY) {
 	int	end;		// Extreme of the scene
 	int	Loffset, Toffset;
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 	switch (g_DefaultRefer) {
 	case REF_DEFAULT:
@@ -266,7 +266,7 @@ static int ClickedOnNothing(int clickX, int clickY, int *ptgtX, int *ptgtY) {
 				return ClickedOnPath(clickX, i, ptgtX, ptgtY);
 			}
 		// Try searching down and up (offscreen).
-		end = BgHeight();
+		end = _vm->_bg->BgHeight();
 		for (i = clickY+1; i < end; i++)
 			if (InPolygon(clickX, i, PATH) != NOPOLY) {
 				return ClickedOnPath(clickX, i, ptgtX, ptgtY);
@@ -285,7 +285,7 @@ static int ClickedOnNothing(int clickX, int clickY, int *ptgtX, int *ptgtY) {
 		break;
 
 	case REF_DOWN:
-		end = BgHeight();
+		end = _vm->_bg->BgHeight();
 		for (i = clickY+1; i < end; i++)
 			if (InPolygon(clickX, i, PATH) != NOPOLY) {
 				return ClickedOnPath(clickX, i, ptgtX, ptgtY);
@@ -300,7 +300,7 @@ static int ClickedOnNothing(int clickX, int clickY, int *ptgtX, int *ptgtY) {
 		break;
 
 	case REF_RIGHT:
-		end = BgWidth();
+		end = _vm->_bg->BgWidth();
 		for (i = clickX + 1; i < end; i++)
 			if (InPolygon(i, clickY, PATH) != NOPOLY) {
 				return ClickedOnPath(i, clickY, ptgtX, ptgtY);
diff --git a/engines/tinsel/pdisplay.cpp b/engines/tinsel/pdisplay.cpp
index 191074a..dc97ee8 100644
--- a/engines/tinsel/pdisplay.cpp
+++ b/engines/tinsel/pdisplay.cpp
@@ -147,16 +147,16 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 				Loffset != _ctx->prevsX || Toffset != _ctx->prevsY) {
 			// kill current text objects
 			if (_ctx->cpText) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->cpText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->cpText);
 			}
 			if (_ctx->cpathText) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->cpathText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->cpathText);
 				_ctx->cpathText = NULL;
 			}
 
 			// New text objects
 			sprintf(PositionString, "%d %d", aniX + Loffset, aniY + Toffset);
-			_ctx->cpText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
+			_ctx->cpText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 						0, CPOSX, POSY, GetTagFontHandle(), TXT_CENTER);
 			if (g_DispPath) {
 				HPOLYGON hp = InPolygon(aniX + Loffset, aniY + Toffset, PATH);
@@ -168,7 +168,7 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 						PolyCornerX(hp, 1), PolyCornerY(hp, 1),
 						PolyCornerX(hp, 2), PolyCornerY(hp, 2),
 						PolyCornerX(hp, 3), PolyCornerY(hp, 3));
-				_ctx->cpathText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
+				_ctx->cpathText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 							0, 4, POSY+ 10, GetTagFontHandle(), 0);
 			}
 
@@ -184,11 +184,11 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 		if (Overrun != _ctx->prevOver) {
 			// kill current text objects
 			if (_ctx->opText) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->opText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->opText);
 			}
 
 			sprintf(PositionString, "%d", Overrun);
-			_ctx->opText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
+			_ctx->opText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 						0, OPOSX, POSY, GetTagFontHandle(), TXT_CENTER);
 
 			// update previous value
@@ -209,12 +209,12 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 					Loffset != _ctx->prevsX || Toffset != _ctx->prevsY) {
 				// Kill current text objects
 				if (_ctx->rpText) {
-					MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->rpText);
+					MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->rpText);
 				}
 
 				// create new text object list
 				sprintf(PositionString, "%d %d", aniX, aniY);
-				_ctx->rpText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
+				_ctx->rpText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 								0, LPOSX, POSY,	GetTagFontHandle(), TXT_CENTER);
 
 				// update previous position
@@ -229,11 +229,11 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 		if (g_bShowString && g_newestString != _ctx->prevString) {
 			// kill current text objects
 			if (_ctx->spText) {
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->spText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->spText);
 			}
 
 			sprintf(PositionString, "String: %d", g_newestString);
-			_ctx->spText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
+			_ctx->spText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 						0, SPOSX, POSY+10, GetTalkFontHandle(), TXT_CENTER);
 
 			// update previous value
@@ -401,7 +401,7 @@ static bool ActorTag(int curX, int curY, HotSpotTag *pTag, OBJECT **ppText) {
 			SaveTaggedPoly(NOPOLY);		// No tagged polygon
 
 			if (*ppText)
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), *ppText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), *ppText);
 
 			if (ActorTagIsWanted(actor)) {
 				GetActorTagPos(actor, &tagX, &tagY, false);
@@ -409,7 +409,7 @@ static bool ActorTag(int curX, int curY, HotSpotTag *pTag, OBJECT **ppText) {
 
 				// May have buggered cursor
 				EndCursorFollowed();
-				*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), g_tagBuffer,
+				*ppText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), g_tagBuffer,
 						0, tagX, tagY, _vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 				assert(*ppText);
 				MultiSetZPosition(*ppText, Z_TAG_TEXT);
@@ -446,22 +446,22 @@ static bool ActorTag(int curX, int curY, HotSpotTag *pTag, OBJECT **ppText) {
 				// Display actor's tag
 
 				if (*ppText)
-					MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), *ppText);
+					MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), *ppText);
 
 				*pTag = ACTOR_HOTSPOT_TAG;
 				SaveTaggedActor(ano);	// This actor tagged
 				SaveTaggedPoly(NOPOLY);	// No tagged polygon
 
-				PlayfieldGetPos(FIELD_WORLD, &tagX, &tagY);
+				_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &tagX, &tagY);
 				LoadStringRes(GetActorTag(ano), _vm->_font->TextBufferAddr(), TBUFSZ);
-				*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+				*ppText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 							0, xtext - tagX, ytext - tagY, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 				assert(*ppText); // Actor tag string produced NULL text
 				MultiSetZPosition(*ppText, Z_TAG_TEXT);
 			} else {
 				// Maintain actor tag's position
 
-				PlayfieldGetPos(FIELD_WORLD, &newX, &newY);
+				_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &newX, &newY);
 				if (newX != tagX || newY != tagY) {
 					MultiMoveRelXY(*ppText, tagX - newX, tagY - newY);
 					tagX = newX;
@@ -511,7 +511,7 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 			// This poly is entitled to be tagged
 			if (hp != GetTaggedPoly()) {
 				if (*ppText) {
-					MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), *ppText);
+					MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), *ppText);
 					*ppText = NULL;
 				}
 				*pTag = POLY_HOTSPOT_TAG;
@@ -535,14 +535,14 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 
 			if (newPoly) {
 				if (*ppText)
-					MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), *ppText);
+					MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), *ppText);
 
 				if (!TinselV2)
 					*pTag = POLY_HOTSPOT_TAG;
 				SaveTaggedActor(0);	// No tagged actor
 				SaveTaggedPoly(hp);	// This polygon tagged
 
-				PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+				_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 				GetTagTag(hp, &hTagtext, &tagx, &tagy);
 
 				int strLen;
@@ -558,7 +558,7 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 					// May have buggered cursor
 					EndCursorFollowed();
 
-					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+					*ppText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 							_vm->_font->TextBufferAddr(), 0, tagx - Loffset, tagy - Toffset,
 							_vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 				} else if (TinselV2) {
@@ -568,11 +568,11 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 						StartCursorFollowed();
 
 					GetCursorXYNoWait(&curX, &curY, false);
-					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+					*ppText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 							0, curX, curY, _vm->_font->GetTagFontHandle(), TXT_CENTER, 0);
 				} else {
 					// Handle displaying the tag text on-screen
-					*ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+					*ppText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 							0, tagx - Loffset, tagy - Toffset,
 						_vm->_font->GetTagFontHandle(), TXT_CENTER);
 					assert(*ppText); // Polygon tag string produced NULL text
@@ -586,18 +586,18 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 					* New feature: Don't go off the side of the background
 					*/
 					shift = MultiRightmost(*ppText) + Loffset + 2;
-					if (shift >= BgWidth())			// Not off right
-						MultiMoveRelXY(*ppText, BgWidth() - shift, 0);
+					if (shift >= _vm->_bg->BgWidth())			// Not off right
+						MultiMoveRelXY(*ppText, _vm->_bg->BgWidth() - shift, 0);
 					shift = MultiLeftmost(*ppText) + Loffset - 1;
 					if (shift <= 0)					// Not off left
 						MultiMoveRelXY(*ppText, -shift, 0);
 					shift = MultiLowest(*ppText) + Toffset;
-					if (shift > BgHeight())			// Not off bottom
-						MultiMoveRelXY(*ppText, 0, BgHeight() - shift);
+					if (shift > _vm->_bg->BgHeight())			// Not off bottom
+						MultiMoveRelXY(*ppText, 0, _vm->_bg->BgHeight() - shift);
 				}
 			} else if (TinselV2 && (*ppText)) {
 				if (!PolyTagFollowsCursor(hp)) {
-					PlayfieldGetPos(FIELD_WORLD, &nLoff, &nToff);
+					_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &nLoff, &nToff);
 					if (nLoff != Loffset || nToff != Toffset) {
 						MultiMoveRelXY(*ppText, Loffset - nLoff, Toffset - nToff);
 						Loffset = nLoff;
@@ -612,7 +612,7 @@ static bool PolyTag(HotSpotTag *pTag, OBJECT **ppText) {
 					}
 				}
 			} else if (!TinselV2) {
-				PlayfieldGetPos(FIELD_WORLD, &nLoff, &nToff);
+				_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &nLoff, &nToff);
 				if (nLoff != Loffset || nToff != Toffset) {
 					MultiMoveRelXY(*ppText, Loffset - nLoff, Toffset - nToff);
 					Loffset = nLoff;
@@ -662,7 +662,7 @@ void TagProcess(CORO_PARAM, const void *) {
 					&& !PolyTag(&_ctx->Tag, &_ctx->pText)) {
 				// Nothing tagged. Remove tag, if there is one
 				if (_ctx->pText) {
-					MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+					MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 					_ctx->pText = NULL;
 
 					if (TinselV2)
@@ -677,7 +677,7 @@ void TagProcess(CORO_PARAM, const void *) {
 			// Remove tag, if there is one
 			if (_ctx->pText) {
 				// kill current text objects
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 				_ctx->pText = NULL;
 				_ctx->Tag = NO_HOTSPOT_TAG;
 			}
diff --git a/engines/tinsel/play.cpp b/engines/tinsel/play.cpp
index a4f5bc8..9d4ca6d 100644
--- a/engines/tinsel/play.cpp
+++ b/engines/tinsel/play.cpp
@@ -83,7 +83,7 @@ static void PokeInPalette(SCNHANDLE hMulFrame) {
 		// get pointer to image
 		pim = (IMAGE *)LockMem(READ_32(pFrame));	// handle to image
 
-		pim->hImgPal = TO_32(BgPal());
+		pim->hImgPal = TO_32(_vm->_bg->BgPal());
 	}
 }
 
@@ -101,7 +101,7 @@ void PokeInPalette(const MULTI_INIT *pmi) {
 		// get pointer to image
 		pim = (IMAGE *)LockMem(READ_32(pFrame));	// handle to image
 
-		pim->hImgPal = TO_32(BgPal());
+		pim->hImgPal = TO_32(_vm->_bg->BgPal());
 	}
 }
 
@@ -496,9 +496,9 @@ static void t1PlayReel(CORO_PARAM, const PPINIT *ppi) {
 	// Set up and insert the multi-object
 	_ctx->pPlayObj = MultiInitObject(pmi);
 	if (!ppi->bTop)
-		MultiInsertObject(GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
 	else
-		MultiInsertObject(GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
 
 	// If co-ordinates are specified, use specified.
 	// Otherwise, use actor's position if there are not embedded co-ords.
@@ -640,9 +640,9 @@ static void t1PlayReel(CORO_PARAM, const PPINIT *ppi) {
 
 	// Ditch the object
 	if (!ppi->bTop)
-		MultiDeleteObject(GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
 	else
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
 
 	if (_ctx->mActor) {
 		if (!_ctx->replaced)
@@ -769,9 +769,9 @@ static void t2PlayReel(CORO_PARAM, int x, int y, bool bRestore, int speed, SCNHA
 	// Set up and insert the multi-object
 	_ctx->pPlayObj = MultiInitObject(_ctx->pmi);
 	if (!bTop)
-		MultiInsertObject(GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
 	else
-		MultiInsertObject(GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
 
 	/*
 	 * More action for moving actors
@@ -917,9 +917,9 @@ static void t2PlayReel(CORO_PARAM, int x, int y, bool bRestore, int speed, SCNHA
 
 	// Ditch the object
 	if (!bTop)
-		MultiDeleteObject(GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
 	else
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
 
 	// Restore moving actor is nessesary
 	if (_ctx->pMover != NULL && _ctx->bPrinciple && !_ctx->bReplaced)
diff --git a/engines/tinsel/rince.cpp b/engines/tinsel/rince.cpp
index 8ed65af..3e98317 100644
--- a/engines/tinsel/rince.cpp
+++ b/engines/tinsel/rince.cpp
@@ -85,7 +85,7 @@ static void CheckBrightness(PMOVER pMover) {
 		else
 			pMover->brightness--;			// ramp down
 
-		DimPartPalette(BgPal(),
+		DimPartPalette(_vm->_bg->BgPal(),
 				pMover->startColor,
 				pMover->paletteLength,
 				pMover->brightness);
@@ -102,10 +102,10 @@ void MoverBrightness(PMOVER pMover, int brightness) {
 	// if BgPal is NULL, and has been changed for ScummVM to a simple assert
 
 	// This is changed from a ProcessGiveWay in DW2 to an assert in ScummVM
-	assert(BgPal());
+	assert(_vm->_bg->BgPal());
 
 	// Do it all immediately
-	DimPartPalette(BgPal(), pMover->startColor, pMover->paletteLength, brightness);
+	DimPartPalette(_vm->_bg->BgPal(), pMover->startColor, pMover->paletteLength, brightness);
 
 	// The actor is probably hidden at this point,
 	pMover->brightness = brightness;
@@ -200,7 +200,7 @@ void SetMoverInEffect(int index, bool tf) {
 void KillMover(PMOVER pMover) {
 	if (pMover->bActive) {
 		pMover->bActive = false;
-		MultiDeleteObject(GetPlayfieldList(FIELD_WORLD), pMover->actorObj);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), pMover->actorObj);
 		pMover->actorObj = NULL;
 		assert(CoroScheduler.getCurrentProcess() != pMover->pProc);
 		CoroScheduler.killProcess(pMover->pProc);
@@ -697,7 +697,7 @@ static void MoverProcessHelper(int X, int Y, int id, PMOVER pMover) {
 	IMAGE *pim;
 
 
-	assert(BgPal()); // Can't start actor without a background palette
+	assert(_vm->_bg->BgPal()); // Can't start actor without a background palette
 	assert(pMover->walkReels[0][FORWARD]); // Starting actor process without walk reels
 
 	InitMover(pMover);
@@ -711,7 +711,7 @@ static void MoverProcessHelper(int X, int Y, int id, PMOVER pMover) {
 
 	// get pointer to image
 	pim = (IMAGE *)LockMem(READ_32(pFrame));	// handle to image
-	pim->hImgPal = TO_32(BgPal());
+	pim->hImgPal = TO_32(_vm->_bg->BgPal());
 //---
 	pMover->actorObj = MultiInitObject(pmi);
 
@@ -719,7 +719,7 @@ static void MoverProcessHelper(int X, int Y, int id, PMOVER pMover) {
 	pMover->actorID = id;
 
 	// add it to display list
-	MultiInsertObject(GetPlayfieldList(FIELD_WORLD), pMover->actorObj);
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), pMover->actorObj);
 	storeActorReel(id, NULL, 0, pMover->actorObj, 0, 0, 0);
 
 	InitStepAnimScript(&pMover->actorAnim, pMover->actorObj, FROM_32(pfilm->reels[0].script), ONE_SECOND / FROM_32(pfilm->frate));
@@ -813,7 +813,7 @@ void T2MoverProcess(CORO_PARAM, const void *param) {
 	pMover->bActive = true;
 
 	// add it to display list
-	MultiInsertObject( GetPlayfieldList(FIELD_WORLD), pMover->actorObj );
+	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), pMover->actorObj);
 
 	InitStepAnimScript(&pMover->actorAnim, pMover->actorObj, pFilm->reels[0].script, ONE_SECOND/pFilm->frate);
 	pMover->stepCount = 0;
diff --git a/engines/tinsel/savescn.cpp b/engines/tinsel/savescn.cpp
index 32ec774..37edf88 100644
--- a/engines/tinsel/savescn.cpp
+++ b/engines/tinsel/savescn.cpp
@@ -51,10 +51,6 @@ namespace Tinsel {
 
 //----------------- EXTERN FUNCTIONS --------------------
 
-// in BG.C
-extern SCNHANDLE GetBgroundHandle();
-extern void SetDoFadeIn(bool tf);
-
 // In DOS_DW.C
 void RestoreMasterProcess(INT_CONTEXT *pic);
 
@@ -107,10 +103,10 @@ static bool g_bNoFade = false;
  */
 void DoSaveScene(SAVED_DATA *sd) {
 	sd->SavedSceneHandle = GetSceneHandle();
-	sd->SavedBgroundHandle = GetBgroundHandle();
+	sd->SavedBgroundHandle = _vm->_bg->GetBgroundHandle();
 	SaveMovers(sd->SavedMoverInfo);
 	sd->NumSavedActors = SaveActors(sd->SavedActorInfo);
-	PlayfieldGetPos(FIELD_WORLD, &sd->SavedLoffset, &sd->SavedToffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &sd->SavedLoffset, &sd->SavedToffset);
 	SaveInterpretContexts(sd->SavedICInfo);
 	sd->SavedControl = ControlIsOn();
 	sd->SavedNoBlocking = GetNoBlocking();
@@ -338,15 +334,15 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
 		// Start up the scene
 		StartNewScene(sd->SavedSceneHandle, NO_ENTRY_NUM);
 
-		SetDoFadeIn(!g_bNoFade);
+		_vm->_bg->SetDoFadeIn(!g_bNoFade);
 		g_bNoFade = false;
-		StartupBackground(Common::nullContext, sd->SavedBgroundHandle);
+		_vm->_bg->StartupBackground(Common::nullContext, sd->SavedBgroundHandle);
 
 		if (TinselV2) {
 			Offset(EX_USEXY, sd->SavedLoffset, sd->SavedToffset);
 		} else {
 			KillScroll();
-			PlayfieldSetPos(FIELD_WORLD, sd->SavedLoffset, sd->SavedToffset);
+			_vm->_bg->PlayfieldSetPos(FIELD_WORLD, sd->SavedLoffset, sd->SavedToffset);
 			SetNoBlocking(sd->SavedNoBlocking);
 		}
 
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index cf90704..9409758 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -54,9 +54,6 @@ namespace Tinsel {
 
 //----------------- EXTERNAL FUNCTIONS ---------------------
 
-// in BG.C
-extern void DropBackground();
-
 // in EFFECT.C
 extern void EffectPolyProcess(CORO_PARAM, const void *);
 
@@ -317,7 +314,7 @@ void EndScene() {
 
 	DropPolygons();		// No polygons
 	DropScroll();	// No no-scrolls
-	DropBackground();	// No background
+	_vm->_bg->DropBackground();	// No background
 	DropMovers();		// No moving actors
 	DropCursor();		// No cursor
 	DropActors();		// No actor reels running
@@ -372,7 +369,7 @@ void PrimeScene() {
 	CoroScheduler.createProcess(PID_TAG, PointProcess, NULL, 0);
 
 	// init the current background
-	InitBackground();
+	_vm->_bg->InitBackground();
 }
 
 /**
diff --git a/engines/tinsel/scroll.cpp b/engines/tinsel/scroll.cpp
index 52ffca8..b52b659 100644
--- a/engines/tinsel/scroll.cpp
+++ b/engines/tinsel/scroll.cpp
@@ -136,7 +136,7 @@ static void NeedScroll(int direction) {
 	int	Loffset, Toffset;
 
 	// get background offsets
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 	switch (direction) {
 	case LEFT:	  /* Picture will go left, 'camera' right */
@@ -247,7 +247,7 @@ static void ScrollImage() {
 	int curX, curY;
 
 	// get background offsets
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 	/*
 	 * Keeping cursor on a tag?
@@ -333,7 +333,7 @@ static void ScrollImage() {
 	if (g_ScrollCursor)
 		AdjustCursorXY(OldLoffset - Loffset, OldToffset - Toffset);
 
-	PlayfieldSetPos(FIELD_WORLD, Loffset, Toffset);
+	_vm->_bg->PlayfieldSetPos(FIELD_WORLD, Loffset, Toffset);
 }
 
 
@@ -356,7 +356,7 @@ static void MonitorScroll() {
 	if (g_oldx == newx && g_oldy == newy)
 		return;
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 	/*
 	 * Approaching right side or left side of the screen?
@@ -420,11 +420,11 @@ void ScrollProcess(CORO_PARAM, const void *) {
 
 	// In Tinsel v2, scenes may play movies, so the background may not always
 	// already be initialized like it is in v1
-	while (!GetBgObject())
+	while (!_vm->_bg->GetBgObject())
 		CORO_SLEEP(1);
 
-	g_ImageH = BgHeight();		// Dimensions
-	g_ImageW = BgWidth();		//  of this scene.
+	g_ImageH = _vm->_bg->BgHeight();		// Dimensions
+	g_ImageW = _vm->_bg->BgWidth();		//  of this scene.
 
 	// Give up if there'll be no purpose in this process
 	if (g_ImageW == SCREEN_WIDTH  &&  g_ImageH == SCREEN_HEIGHT)
@@ -482,7 +482,7 @@ void ScrollTo(int x, int y, int xIter, int yIter) {
 	g_scrollPixelsX = xIter != 0 ? xIter : (TinselV2 ? g_sd.xSpeed : SCROLLPIXELS);
 	g_scrollPixelsY = yIter != 0 ? yIter : (TinselV2 ? g_sd.ySpeed : SCROLLPIXELS);
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);	// get background offsets
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);	// get background offsets
 
 	g_LeftScroll = x - Loffset;
 	g_DownScroll = y - Toffset;
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp
index a13e91f..b198aa8 100644
--- a/engines/tinsel/sound.cpp
+++ b/engines/tinsel/sound.cpp
@@ -373,7 +373,7 @@ bool SoundManager::offscreenChecks(int x, int &y) {
 		return true;
 
 	// convert x to offset from screen center
-	x -= PlayfieldGetCenterX(FIELD_WORLD);
+	x -= _vm->_bg->PlayfieldGetCenterX(FIELD_WORLD);
 
 	if (x < -SCREEN_WIDTH || x > SCREEN_WIDTH) {
 		// A long way offscreen, ignore it
@@ -392,7 +392,7 @@ int8 SoundManager::getPan(int x) {
 	if (x == -1)
 		return 0;
 
-	x -= PlayfieldGetCenterX(FIELD_WORLD);
+	x -= _vm->_bg->PlayfieldGetCenterX(FIELD_WORLD);
 
 	if (x == 0)
 		return 0;
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index a65fa24..c2c9eaf 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -86,9 +86,6 @@ extern bool g_bNoPause;
 
 //----------------- EXTERNAL FUNCTIONS ---------------------
 
-// in BG.CPP
-extern void ChangePalette(SCNHANDLE hPal);
-
 // in PDISPLAY.CPP
 extern void EnableTags();
 extern void DisableTags();
@@ -329,27 +326,27 @@ void Walk(CORO_PARAM, int actor, int x, int y, SCNHANDLE film, int hold, bool ig
 static void DecodeExtreme(EXTREME extreme, int *px, int *py) {
 	int	Loffset, Toffset;
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 	switch (extreme) {
 	case EX_BOTTOM:
 		*px = Loffset;
-		*py = BgHeight() - SCREEN_HEIGHT;
+		*py = _vm->_bg->BgHeight() - SCREEN_HEIGHT;
 		break;
 	case EX_BOTTOMLEFT:
 		*px = 0;
-		*py = BgHeight() - SCREEN_HEIGHT;
+		*py = _vm->_bg->BgHeight() - SCREEN_HEIGHT;
 		break;
 	case EX_BOTTOMRIGHT:
-		*px = BgWidth() - SCREEN_WIDTH;
-		*py = BgHeight() - SCREEN_HEIGHT;
+		*px = _vm->_bg->BgWidth() - SCREEN_WIDTH;
+		*py = _vm->_bg->BgHeight() - SCREEN_HEIGHT;
 		break;
 	case EX_LEFT:
 		*px = 0;
 		*py = Toffset;
 		break;
 	case EX_RIGHT:
-		*px = BgWidth() - SCREEN_WIDTH;
+		*px = _vm->_bg->BgWidth() - SCREEN_WIDTH;
 		*py = Toffset;
 		break;
 	case EX_TOP:
@@ -360,7 +357,7 @@ static void DecodeExtreme(EXTREME extreme, int *px, int *py) {
 		*px = *py = 0;
 		break;
 	case EX_TOPRIGHT:
-		*px = BgWidth() - SCREEN_WIDTH;
+		*px = _vm->_bg->BgWidth() - SCREEN_WIDTH;
 		*py = 0;
 		break;
 	default:
@@ -414,7 +411,7 @@ static void ScrollMonitorProcess(CORO_PARAM, const void *param) {
 			break;
 		}
 
-		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 
 	} while (Loffset != psm->x || Toffset != psm->y);
 
@@ -639,7 +636,7 @@ static void AuxScale(int actor, int scale, SCNHANDLE *rp) {
  * Defines the background image for a scene.
  */
 static void Background(CORO_PARAM, SCNHANDLE bfilm) {
-	StartupBackground(coroParam, bfilm);
+	_vm->_bg->StartupBackground(coroParam, bfilm);
 }
 
 /**
@@ -1378,7 +1375,7 @@ static void KillProcess(uint32 procID) {
 static int LToffset(int lort) {
 	int Loffset, Toffset;
 
-	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+	_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 	return (lort == SCREENXPOS) ? Loffset : Toffset;
 }
 
@@ -1472,7 +1469,7 @@ void Offset(EXTREME extreme, int x, int y) {
 	if (TinselV2)
 		DecodeExtreme(extreme, &x, &y);
 
-	PlayfieldSetPos(FIELD_WORLD, x, y);
+	_vm->_bg->PlayfieldSetPos(FIELD_WORLD, x, y);
 }
 
 /**
@@ -1907,8 +1904,8 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 	// Print the text
 	if (TinselV2) {
 		int Loffset, Toffset;
-		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
-		_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+		_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 			_vm->_font->TextBufferAddr(), 0, x - Loffset, y - Toffset, _vm->_font->GetTagFontHandle(),
 			TXT_CENTER, 0);
 		assert(_ctx->pText);
@@ -1920,8 +1917,8 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 
 	} else if (bJapDoPrintText || (!isJapanMode() && (_vm->_config->_useSubtitles || !_ctx->bSample))) {
 		int Loffset, Toffset;	// Screen position
-		PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
-		_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+		_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 					0, x - Loffset, y - Toffset,
 					TinselV2 ? _vm->_font->GetTagFontHandle() : _vm->_font->GetTalkFontHandle(), TXT_CENTER);
 		assert(_ctx->pText); // string produced NULL text
@@ -1933,14 +1930,14 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 		 */
 		int	shift;
 		shift = MultiRightmost(_ctx->pText) + 2;
-		if (shift >= BgWidth())			// Not off right
-			MultiMoveRelXY(_ctx->pText, BgWidth() - shift, 0);
+		if (shift >= _vm->_bg->BgWidth())			// Not off right
+			MultiMoveRelXY(_ctx->pText, _vm->_bg->BgWidth() - shift, 0);
 		shift = MultiLeftmost(_ctx->pText) - 1;
 		if (shift <= 0)					// Not off left
 			MultiMoveRelXY(_ctx->pText, -shift, 0);
 		shift = MultiLowest(_ctx->pText);
-		if (shift > BgHeight())			// Not off bottom
-			MultiMoveRelXY(_ctx->pText, 0, BgHeight() - shift);
+		if (shift > _vm->_bg->BgHeight())			// Not off bottom
+			MultiMoveRelXY(_ctx->pText, 0, _vm->_bg->BgHeight() - shift);
 	}
 
 	// Give up if nothing printed and no sample
@@ -1995,7 +1992,7 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 
 	// Delete the text
 	if (_ctx->pText != NULL)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 	_vm->_mixer->stopHandle(_ctx->handle);
 
 	CORO_END_CODE;
@@ -2086,7 +2083,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 			else
 				LoadStringRes(hText, _vm->_font->TextBufferAddr(), TBUFSZ);
 
-			_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+			_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 						0, _ctx->textx, _ctx->texty, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 			assert(_ctx->pText); // PrintObj() string produced NULL text
 
@@ -2126,7 +2123,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 					// Give way to non-POINTED-generated text
 					if (g_bNotPointedRunning) {
 						// Delete the text, and wait for the all-clear
-						MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+						MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 						_ctx->pText = NULL;
 
 						while (g_bNotPointedRunning)
@@ -2138,7 +2135,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 
 						// Re-display in the same place
 						LoadStringRes(hText, _vm->_font->TextBufferAddr(), TBUFSZ);
-						_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+						_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 							_vm->_font->TextBufferAddr(), 0, _ctx->textx, _ctx->texty, _vm->_font->GetTagFontHandle(),
 							TXT_CENTER, 0);
 						assert(_ctx->pText);
@@ -2214,7 +2211,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 
 		// Delete the text, if haven't already
 		if (_ctx->pText)
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 
 		// If it hasn't already finished, stop sample
 		if (_ctx->bSample)
@@ -2244,7 +2241,7 @@ static void PrintObjPointed(CORO_PARAM, const SCNHANDLE text, const INV_OBJECT *
 			// Give way to non-POINTED-generated text
 			if (g_bNotPointedRunning) {
 				// Delete the text, and wait for the all-clear
-				MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), pText);
+				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), pText);
 				pText = NULL;
 				while (g_bNotPointedRunning)
 					CORO_SLEEP(1);
@@ -2255,7 +2252,7 @@ static void PrintObjPointed(CORO_PARAM, const SCNHANDLE text, const INV_OBJECT *
 
 				// Re-display in the same place
 				LoadStringRes(text, _vm->_font->TextBufferAddr(), TBUFSZ);
-				pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
+				pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
 							0, textx, texty, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 				assert(pText); // PrintObj() string produced NULL text
 				MultiSetZPosition(pText, Z_INV_ITEXT);
@@ -2545,7 +2542,7 @@ static void Scroll(CORO_PARAM, EXTREME extreme, int xp, int yp, int xIter, int y
 				if (_ctx->thisScroll != g_scrollNumber)
 					CORO_KILL_SELF();
 
-				PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
+				_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 			} while (Loffset != _ctx->x || Toffset != _ctx->y);
 		} else if (TinselV2 && myEscape) {
 			SCROLL_MONITOR sm;
@@ -2684,7 +2681,7 @@ static void SetPalette(SCNHANDLE hPal, bool escOn, int myEscape) {
 	if (escOn && myEscape != GetEscEvents())
 		return;
 
-	ChangePalette(hPal);
+	_vm->_bg->ChangePalette(hPal);
 }
 
 /**
@@ -3310,7 +3307,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 			 */
 			int	xshift, yshift;
 
-			PlayfieldGetPos(FIELD_WORLD, &_ctx->Loffset, &_ctx->Toffset);
+			_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &_ctx->Loffset, &_ctx->Toffset);
 			if ((_ctx->whatSort == IS_SAY) || (_ctx->whatSort == IS_TALK))
 				GetActorMidTop(_ctx->actor, &_ctx->x, &_ctx->y);
 
@@ -3324,7 +3321,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 				_ctx->y -= _ctx->Toffset;
 			}
 
-			_ctx->pText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+			_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
 					_vm->_font->TextBufferAddr(), 0, _ctx->x - _ctx->Loffset, _ctx->y - _ctx->Toffset,
 					_vm->_font->GetTalkFontHandle(), TXT_CENTER);
 			assert(_ctx->pText); // talk() string produced NULL text;
@@ -3387,7 +3384,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 			if (_ctx->pText != NULL) {
 				int	nLoff, nToff;
 
-				PlayfieldGetPos(FIELD_WORLD, &nLoff, &nToff);
+				_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &nLoff, &nToff);
 				if (nLoff != _ctx->Loffset || nToff != _ctx->Toffset) {
 					MultiMoveRelXY(_ctx->pText, _ctx->Loffset - nLoff, _ctx->Toffset - nToff);
 					_ctx->Loffset = nLoff;
@@ -3445,7 +3442,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 		} while (1);
 
 		if (_ctx->pText != NULL) {
-			MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 			_ctx->pText = NULL;
 		}
 		if (TinselV2 && _ctx->bSample)
@@ -3460,7 +3457,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 	if (_ctx->bTalkReel)
 		CORO_INVOKE_2(FinishTalkingReel, _ctx->pActor, _ctx->actor);
 	if (_ctx->pText != NULL)
-		MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
+		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pText);
 
 	if (TinselV2) {
 		if ((_ctx->whatSort == IS_SAY) || (_ctx->whatSort == IS_SAYAT)) {
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index a14c858..cb4ab86 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -64,11 +64,6 @@ namespace Tinsel {
 
 //----------------- EXTERNAL FUNCTIONS ---------------------
 
-// In BG.CPP
-extern void SetDoFadeIn(bool tf);
-extern void DropBackground();
-extern const BACKGND *g_pCurBgnd;
-
 // In CURSOR.CPP
 extern void CursorProcess(CORO_PARAM, const void *);
 
@@ -678,12 +673,12 @@ bool ChangeScene(bool bReset) {
 
 			switch (g_NextScene.trans) {
 			case TRANS_CUT:
-				SetDoFadeIn(false);
+				_vm->_bg->SetDoFadeIn(false);
 				break;
 
 			case TRANS_FADE:
 			default:
-				SetDoFadeIn(true);
+				_vm->_bg->SetDoFadeIn(true);
 				break;
 			}
 		} else
@@ -854,6 +849,7 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
 
 TinselEngine::~TinselEngine() {
 	_system->getAudioCDManager()->stop();
+	delete _bg;
 	delete _font;
 	delete _bmv;
 	delete _sound;
@@ -897,6 +893,7 @@ Common::Error TinselEngine::run() {
 	_sound = new SoundManager(this);
 	_bmv = new BMVPlayer();
 	_font = new Font();
+	_bg = new Background(_font);
 
 	// Initialize backend
 	if (getGameID() == GID_DW2) {
@@ -1013,7 +1010,7 @@ Common::Error TinselEngine::run() {
 	_vm->_config->writeToDisk();
 
 	EndScene();
-	g_pCurBgnd = NULL;
+	_bg->ResetBackground();
 
 	return Common::kNoError;
 }
@@ -1036,7 +1033,7 @@ void TinselEngine::NextGameCycle() {
 		_bmv->CopyMovieToScreen();
 	else
 		// redraw background
-		DrawBackgnd();
+		_bg->DrawBackgnd();
 
 	// Why waste resources on yet another process?
 	FettleTimers();
@@ -1101,10 +1098,10 @@ void TinselEngine::CreateConstProcesses() {
 void TinselEngine::RestartGame() {
 	HoldItem(INV_NOICON);	// Holding nothing
 
-	DropBackground();	// No background
+	_bg->DropBackground();	// No background
 
 	// Ditches existing infrastructure background
-	InitBackground();
+	_bg->InitBackground();
 
 	// Next scene change won't need to fade out
 	// -> reset the count used by ChangeScene
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 6657d0d..7d5f2d7 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -56,6 +56,7 @@ class MidiDriver;
 class MidiMusicPlayer;
 class PCMMusicPlayer;
 class SoundManager;
+class Background;
 class Font;
 
 typedef Common::List<Common::Rect> RectList;
@@ -197,6 +198,7 @@ public:
 	MidiMusicPlayer *_midiMusic;
 	PCMMusicPlayer *_pcmMusic;
 	BMVPlayer *_bmv;
+	Background* _bg;
 	Font *_font;
 
 	Config *_config;


Commit: 0fef57b9242c29b4963bd9ccd7bee66e9203b002
    https://github.com/scummvm/scummvm/commit/0fef57b9242c29b4963bd9ccd7bee66e9203b002
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-02-22T18:41:40+02:00

Commit Message:
TINSEL: Move the current background struct to the heap

Changed paths:
    engines/tinsel/background.cpp
    engines/tinsel/background.h


diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index 8b15c8a..9f98275 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -33,11 +33,17 @@
 
 namespace Tinsel {
 
+Background::Background(Font* font) : _font(font), _pCurBgnd(nullptr), _hBgPal(0), _BGspeed(0), _hBackground(0), _bDoFadeIn(false), _bgReels(0) {
+	for (int i = 0; i < MAX_BG; i++) {
+		_pBG[i] = nullptr;
+		_thisAnim[i].pObject = nullptr;
+	}
+}
+
 /**
  * Called to initialize a background.
  */
 void Background::InitBackground() {
-	// structure for playfields
 	// FIXME: Avoid non-const global vars
 	static PLAYFIELD playfield[] = {
 		{	// FIELD WORLD
@@ -60,8 +66,8 @@ void Background::InitBackground() {
 		}
 	};
 
-	// structure for background
-	static const BACKGND backgnd = {
+	// set current background
+	_pCurBgnd = new BACKGND{
 		BLACK,			// sky color
 		Common::Point(0, 0),	// initial world pos
 		Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),	// scroll limits
@@ -73,23 +79,17 @@ void Background::InitBackground() {
 		false			// no auto-erase
 	};
 
-	int i;			// playfield counter
-	PLAYFIELD* pPlayfield;	// pointer to current playfield
-
-	// set current background
-	_pCurBgnd = &backgnd;
-
 	// init background sky color
-	SetBgndColor(backgnd.rgbSkyColor);
+	SetBgndColor(_pCurBgnd->rgbSkyColor);
 
 	// start of playfield array
-	pPlayfield = backgnd.fieldArray;
+	PLAYFIELD* pPlayfield = _pCurBgnd->fieldArray;
 
 	// for each background playfield
-	for (i = 0; i < backgnd.numPlayfields; i++, pPlayfield++) {
+	for (int i = 0; i < _pCurBgnd->numPlayfields; i++, pPlayfield++) {
 		// init playfield pos
-		pPlayfield->fieldX = intToFrac(backgnd.ptInitWorld.x);
-		pPlayfield->fieldY = intToFrac(backgnd.ptInitWorld.y);
+		pPlayfield->fieldX = intToFrac(_pCurBgnd->ptInitWorld.x);
+		pPlayfield->fieldY = intToFrac(_pCurBgnd->ptInitWorld.y);
 
 		// no scrolling
 		pPlayfield->fieldXvel = intToFrac(0);
diff --git a/engines/tinsel/background.h b/engines/tinsel/background.h
index f449a79..420d0e3 100644
--- a/engines/tinsel/background.h
+++ b/engines/tinsel/background.h
@@ -81,20 +81,21 @@ class Font;
 
 class Background {
 public:
-	Background(Font *font) : _font(font), _pCurBgnd(nullptr), _hBgPal(0), _BGspeed(0), _hBackground(0), _bDoFadeIn(false), _bgReels(0) {}
+	Background(Font* font);
 
 	void InitBackground();
 
 	void DrawBackgnd();		// Draws all playfields for the current background
 
-	void RedrawBackgnd();	// Completely redraws all the playfield object lists for the current background
-
 	/**
 	 * Called before scene change.
 	 */
 	void DropBackground();
 
-	void ResetBackground() { _pCurBgnd = nullptr; }
+	void ResetBackground() {
+		delete _pCurBgnd;
+		_pCurBgnd = nullptr;
+	}
 
 	void StartupBackground(CORO_PARAM, SCNHANDLE hFilm);
 


Commit: ae7f5ff95e6fe1717b1349021a8edc4b2efacdc3
    https://github.com/scummvm/scummvm/commit/ae7f5ff95e6fe1717b1349021a8edc4b2efacdc3
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-02-22T19:16:30+02:00

Commit Message:
TINSEL: Some work on the Japanese version of DW1

Changed paths:
    engines/tinsel/config.cpp
    engines/tinsel/config.h
    engines/tinsel/tinlib.cpp


diff --git a/engines/tinsel/config.cpp b/engines/tinsel/config.cpp
index bd5929f..3c6b37f 100644
--- a/engines/tinsel/config.cpp
+++ b/engines/tinsel/config.cpp
@@ -79,6 +79,9 @@ void Config::writeToDisk() {
 		case TXT_US:
 			lang = Common::EN_USA;
 			break;
+		case TXT_JAPANESE:
+			lang = Common::JA_JPN;
+			break;
 		default:
 			lang = Common::EN_ANY;
 		}
@@ -138,6 +141,9 @@ void Config::readFromDisk() {
 	case Common::EN_USA:
 		_language = TXT_US;
 		break;
+	case Common::JA_JPN:
+		_language = TXT_JAPANESE;
+		break;
 	default:
 		_language = TXT_ENGLISH;
 	}
@@ -169,12 +175,8 @@ void Config::readFromDisk() {
 	}
 }
 
-bool isJapanMode() {
-#ifdef JAPAN
-	return true;
-#else
-	return false;
-#endif
+bool Config::isJapanMode() {
+	return _language == TXT_JAPANESE;
 }
 
 } // End of namespace Tinsel
diff --git a/engines/tinsel/config.h b/engines/tinsel/config.h
index 4f31686..9da9885 100644
--- a/engines/tinsel/config.h
+++ b/engines/tinsel/config.h
@@ -55,11 +55,9 @@ public:
 
 	void writeToDisk();
 	void readFromDisk();
+	bool isJapanMode();
 };
 
-
-extern bool isJapanMode();
-
 } // End of namespace Tinsel
 
 #endif
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index c2c9eaf..2e7ac7e 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -433,7 +433,7 @@ void SetTextPal(COLORREF col) {
  * subtitle speed modification.
  */
 static int TextTime(char *pTstring) {
-	if (isJapanMode())
+	if (_vm->_config->isJapanMode())
 		return JAP_TEXT_TIME;
 	else if (!_vm->_config->_textSpeed)
 		return strlen(pTstring) + ONE_SECOND;
@@ -1897,7 +1897,7 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 	} else {
 		_ctx->time = time * ONE_SECOND;
 		_ctx->myleftEvent = (TinselV2 && !bSustain) ? GetLeftEvents() : 0;
-		if (isJapanMode())
+		if (_vm->_config->isJapanMode())
 			bJapDoPrintText = true;
 	}
 
@@ -1915,7 +1915,7 @@ static void Print(CORO_PARAM, int x, int y, SCNHANDLE text, int time, bool bSust
 		if (IsTopWindow())
 			MultiSetZPosition(_ctx->pText, Z_TOPW_TEXT);
 
-	} else if (bJapDoPrintText || (!isJapanMode() && (_vm->_config->_useSubtitles || !_ctx->bSample))) {
+	} else if (bJapDoPrintText || (!_vm->_config->isJapanMode() && (_vm->_config->_useSubtitles || !_ctx->bSample))) {
 		int Loffset, Toffset;	// Screen position
 		_vm->_bg->PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
 		_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _vm->_font->TextBufferAddr(),
@@ -2074,7 +2074,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
 		}
 
 		// Display the text and set it's Z position
-		if (event == POINTED || (!isJapanMode() && (_vm->_config->_useSubtitles || !_ctx->bSample))) {
+		if (event == POINTED || (!_vm->_config->isJapanMode() && (_vm->_config->_useSubtitles || !_ctx->bSample))) {
 			int	xshift;
 
 			// Get the text string
@@ -2290,7 +2290,7 @@ static void PrintObjNonPointed(CORO_PARAM, const SCNHANDLE text, const OBJECT *p
 		_ctx->took_control = GetControl(CONTROL_OFF);
 
 		// Display for a time, but abort if conversation gets hidden
-		if (isJapanMode())
+		if (_vm->_config->isJapanMode())
 			_ctx->ticks = JAP_TEXT_TIME;
 		else if (pText)
 			_ctx->ticks = TextTime(_vm->_font->TextBufferAddr());
@@ -3004,7 +3004,7 @@ static void StopWalk(int actor) {
 static void Subtitles(int onoff) {
 	assert (onoff == ST_ON || onoff == ST_OFF);
 
-	if (isJapanMode())
+	if (_vm->_config->isJapanMode())
 		return;	// Subtitles are always off in JAPAN version (?)
 
 	_vm->_config->_useSubtitles = (onoff == ST_ON);
@@ -3299,7 +3299,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 		_ctx->bSample = _ctx->bSamples;
 		_ctx->pText = NULL;
 
-		if (isJapanMode()) {
+		if (_vm->_config->isJapanMode()) {
 			_ctx->ticks = JAP_TEXT_TIME;
 		} else if (_vm->_config->_useSubtitles || !_ctx->bSample) {
 			/*
@@ -3496,7 +3496,7 @@ static void TalkAt(CORO_PARAM, int actor, int x, int y, SCNHANDLE text, bool esc
 		if (escOn && myEscape != GetEscEvents())
 			return;
 
-		if (!isJapanMode() && (_vm->_config->_useSubtitles || !_vm->_sound->sampleExists(text)))
+		if (!_vm->_config->isJapanMode() && (_vm->_config->_useSubtitles || !_vm->_sound->sampleExists(text)))
 			SetTextPal(GetActorRGB(actor));
 	}
 
@@ -3514,7 +3514,7 @@ static void TalkAtS(CORO_PARAM, int actor, int x, int y, SCNHANDLE text, int sus
 		if (escOn && myEscape != GetEscEvents())
 			return;
 
-		if (!isJapanMode())
+		if (!_vm->_config->isJapanMode())
 			SetTextPal(GetActorRGB(actor));
 	}
 
@@ -3525,7 +3525,7 @@ static void TalkAtS(CORO_PARAM, int actor, int x, int y, SCNHANDLE text, int sus
  * Set talk font's palette entry.
  */
 static void TalkAttr(int r1, int g1, int b1, bool escOn, int myEscape) {
-	if (isJapanMode())
+	if (_vm->_config->isJapanMode())
 		return;
 
 	// Don't do it if it's not wanted


Commit: 2d36d802f583ec7a01cc8723ce5476af3d9aab4e
    https://github.com/scummvm/scummvm/commit/2d36d802f583ec7a01cc8723ce5476af3d9aab4e
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-02-22T20:04:59+02:00

Commit Message:
TINSEL: Remove unused process IDs

Changed paths:
    engines/tinsel/pid.h


diff --git a/engines/tinsel/pid.h b/engines/tinsel/pid.h
index 6c9d7ee..87948a3 100644
--- a/engines/tinsel/pid.h
+++ b/engines/tinsel/pid.h
@@ -29,22 +29,13 @@ namespace Tinsel {
 #define	PID_DESTROY	0x8000			// process id of any process that is to be destroyed between scenes
 
 #define	PID_EFFECTS	(0x0010 | PID_DESTROY)	// generic special effects process id
-#define	PID_FLASH	(PID_EFFECTS + 1)	// flash color process
-#define	PID_CYCLE	(PID_EFFECTS + 2)	// cycle color range process
-#define	PID_MORPH	(PID_EFFECTS + 3)	// morph process
 #define	PID_FADER	(PID_EFFECTS + 4)	// fader process
-#define	PID_FADE_BGND	(PID_EFFECTS + 5)	// fade background color process
-
-#define	PID_BACKGND	(0x0020 | PID_DESTROY)	// background update process id
 
 #define	PID_MOUSE	0x0030			// mouse button checking process id
 
-#define	PID_JOYSTICK	0x0040			// joystick button checking process id
-
 #define	PID_KEYBOARD	0x0050			// keyboard scanning process
 
 #define	PID_CURSOR	0x0060			// cursor process
-#define	PID_CUR_TRAIL	(PID_CURSOR + 1)	// cursor trail process
 
 #define	PID_SCROLL	(0x0070 | PID_DESTROY)	// scroll process
 
@@ -62,10 +53,6 @@ namespace Tinsel {
 
 #define	PID_REEL	(0x00E0 | PID_DESTROY)	// process for each film reel
 
-#define	PID_MIDI	(0x00F0 | PID_DESTROY)	// process to poll MIDI sound driver
-
-#define PID_BMV		0x0100				// Movie player process
-
 #define PID_BTN_CLICK 0x110				// process to handle mouse button clicks
 
 #define PID_PROCESS	(0x0110 | PID_DESTROY)	// Scene process base




More information about the Scummvm-git-logs mailing list