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

peterkohaut peterkohaut at users.noreply.github.com
Thu Mar 4 19:46:05 UTC 2021


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

Summary:
e59a470db3 TINSEL: Updated addional drawing routines for v3


Commit: e59a470db31cb88e58bcc61e1f8ea6909c0dc0a6
    https://github.com/scummvm/scummvm/commit/e59a470db31cb88e58bcc61e1f8ea6909c0dc0a6
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2021-03-04T20:45:32+01:00

Commit Message:
TINSEL: Updated addional drawing routines for v3

Implemented playing of films of objects (not movies).
Fixed rendering of the main menu.
Increased the size of parameters of coroutines.

Changed paths:
    common/coroutines.h
    engines/tinsel/background.cpp
    engines/tinsel/background.h
    engines/tinsel/dw.h
    engines/tinsel/graphics.cpp
    engines/tinsel/play.cpp
    engines/tinsel/play.h
    engines/tinsel/tinlib.cpp


diff --git a/common/coroutines.h b/common/coroutines.h
index 924133267a..275ccfa471 100644
--- a/common/coroutines.h
+++ b/common/coroutines.h
@@ -284,7 +284,7 @@ public:
 
 
 /** Size of process-specific information. */
-#define CORO_PARAM_SIZE 32
+#define CORO_PARAM_SIZE 40
 
 /** Maximum number of processes. */
 #define CORO_NUM_PROCESS    100
diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index f0c0ceb4ad..c3b134a4fc 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -44,25 +44,6 @@ Background::Background(Font* font) : _font(font), _pCurBgnd(nullptr), _hBgPal(0)
  * Called to initialize a background.
  */
 void Background::InitBackground() {
-	PLAYFIELD worldPlayfield = {
-	    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
-	};
-	PLAYFIELD statusPlayfield = {
-	    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
-	};
-
 	// set current background
 	_pCurBgnd = new BACKGND();
 	_pCurBgnd->rgbSkyColor = BLACK;
@@ -71,10 +52,25 @@ void Background::InitBackground() {
 	_pCurBgnd->refreshRate = 0;	// no background update process
 	_pCurBgnd->pXscrollTable = nullptr;
 	_pCurBgnd->pYscrollTable = nullptr;
-	_pCurBgnd->fieldArray.push_back(worldPlayfield);
-	_pCurBgnd->fieldArray.push_back(statusPlayfield);
 	_pCurBgnd->bAutoErase = false;
 
+	int numPlayFields = 2;
+	if (TinselV3) {
+		numPlayFields = 9;
+	}
+	for (int i = 0; i < numPlayFields; ++i) {
+		PLAYFIELD playfield = {
+		    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
+		};
+		_pCurBgnd->fieldArray.push_back(playfield);
+	}
+
 	// init background sky color
 	SetBgndColor(_pCurBgnd->rgbSkyColor);
 }
@@ -287,4 +283,17 @@ void Background::ChangePalette(SCNHANDLE hPal) {
 	SetBackPal(hPal);
 }
 
+void Background::WaitForBG(CORO_PARAM) {
+	CORO_BEGIN_CONTEXT;
+	CORO_END_CONTEXT(_ctx);
+
+	CORO_BEGIN_CODE(_ctx);
+
+	while (_pBG[0] == nullptr) {
+		CORO_SLEEP(1);
+	}
+
+	CORO_END_CODE;
+}
+
 } // End of namespace Tinsel
diff --git a/engines/tinsel/background.h b/engines/tinsel/background.h
index bb6660acef..4c91a174f0 100644
--- a/engines/tinsel/background.h
+++ b/engines/tinsel/background.h
@@ -145,6 +145,8 @@ public:
 
 	int getBgSpeed() { return _BGspeed; }
 
+	void WaitForBG(CORO_PARAM);
+
 private:
 	Font *_font;
 
diff --git a/engines/tinsel/dw.h b/engines/tinsel/dw.h
index b0619ad5ad..4285d2fd3c 100644
--- a/engines/tinsel/dw.h
+++ b/engines/tinsel/dw.h
@@ -56,8 +56,8 @@ typedef int HPOLYGON;
 // inventory object handle (if there are inventory objects)
 #define	INV_OBJ_SCNHANDLE (TinselV0 ? (2 << SCNHANDLE_SHIFT) : (1 << SCNHANDLE_SHIFT))
 
-#define FIELD_WORLD	0
-#define FIELD_STATUS	1
+#define FIELD_WORLD		(TinselV3 ? 2 : 0)
+#define FIELD_STATUS	(TinselV3 ? 8 : 1)
 
 #define ZSHIFT 10
 
diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp
index 00dc636e8b..f0f84a5bf8 100644
--- a/engines/tinsel/graphics.cpp
+++ b/engines/tinsel/graphics.cpp
@@ -608,6 +608,114 @@ static void t2WrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool apply
 	}
 }
 
+
+static void t3WrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP) {
+	bool applyClipping = (pObj->flags & DMA_CLIP) != 0;
+	bool horizFlipped = (pObj->flags & DMA_FLIPH) != 0;
+
+	if (pObj->isRLE)
+	{
+		int yClip = applyClipping ? pObj->topClip : 0;
+		if (applyClipping) {
+			pObj->height -= pObj->botClip;
+		}
+
+		for (int y = 0; y < pObj->height; ++y) {
+			uint8 *tempP = destP;
+			int leftClip = applyClipping ? pObj->leftClip : 0;
+			int rightClip = applyClipping ? pObj->rightClip : 0;
+
+			if (horizFlipped) {
+				SWAP(leftClip, rightClip);
+			}
+
+			int x = 0;
+			while (x < pObj->width) {
+				int numPixels = READ_LE_UINT16(srcP);
+				srcP += 2;
+
+				if (numPixels & 0x8000) {
+					numPixels &= 0x7FFF;
+
+					int clipAmount = MIN(numPixels, leftClip);
+					leftClip -= clipAmount;
+					x += clipAmount;
+
+					int runLength = numPixels - clipAmount;
+
+					uint16 color = READ_LE_UINT16(srcP);
+					srcP += 2;
+
+					if ((yClip == 0) && (runLength > 0)) {
+						runLength = MIN(runLength, pObj->width - rightClip - x);
+
+						for (int xp = 0; xp < runLength; ++xp) {
+							if (color != 0b1111100000011111) {
+								WRITE_UINT16(tempP, color);
+							}
+							tempP += (horizFlipped ? -2 : 2);
+						}
+					}
+
+					x += numPixels - clipAmount;
+				} else {
+					int clipAmount = MIN(numPixels, leftClip);
+					leftClip -= clipAmount;
+					srcP += clipAmount * 2;
+					int runLength = numPixels - clipAmount;
+					x += numPixels - runLength;
+
+					for (int xp = 0; xp < runLength; ++xp) {
+						if ((yClip == 0) && (x < (pObj->width - rightClip))) {
+							uint16 color = READ_LE_UINT16(srcP);
+
+							if (color != 0b1111100000011111) {
+								WRITE_UINT16(tempP, color);
+							}
+
+							tempP += (horizFlipped ? -2 : 2);
+						}
+						srcP += 2;
+						++x;
+					}
+				}
+			}
+			// assert(x == pObj->width);
+
+			if (yClip > 0) {
+				--yClip;
+			} else {
+				destP += SCREEN_WIDTH * 2;
+			}
+		}
+		return;
+	}
+
+	if (applyClipping) {
+		srcP += (pObj->topClip * pObj->width * 2);
+
+		pObj->height -= pObj->topClip + pObj->botClip;
+		pObj->width -= pObj->leftClip + pObj->rightClip;
+	}
+
+	for (int y = 0; y < pObj->height; ++y) {
+		uint8 *tempP = destP;
+		srcP += pObj->leftClip * 2;
+		for (int x = 0; x < pObj->width; ++x) {
+			uint16 color = READ_LE_UINT16(srcP);
+			srcP += 2;
+
+			if (color != 0b1111100000011111) { // "zero" for Tinsel 3 - magenta in 565
+				WRITE_UINT16(tempP, color);
+			}
+
+			tempP += 2;
+		}
+		srcP += pObj->rightClip * 2;
+		destP += SCREEN_WIDTH * 2;
+	}
+}
+
 /**
  * Fill the destination area with a constant color
  */
@@ -635,29 +743,24 @@ static void WrtConst(DRAWOBJECT *pObj, uint8 *destP, bool applyClipping) {
 static void t3TransWNZ(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP) {
 	bool applyClipping = (pObj->flags & DMA_CLIP) != 0;
 
-	int leftClip = 0;
-	int rightClip = 0;
+	if (applyClipping) {
+		srcP += (pObj->topClip * pObj->width * 2);
 
-	if (applyClipping)
-	{
-		pObj->height -= pObj->topClip;
+		pObj->height -= pObj->topClip + pObj->botClip;
 		pObj->width -= pObj->leftClip + pObj->rightClip;
-
-		leftClip = pObj->leftClip;
-		rightClip = pObj->rightClip;
 	}
 
 	for (int y = 0; y < pObj->height; ++y) {
 		// Get the position to start writing out from
 		uint8 *tempP = destP;
-		srcP += leftClip * 2;
+		srcP += pObj->leftClip * 2;
 		for (int x = 0; x < pObj->width; ++x) {
-			uint32 color = READ_UINT16(srcP); //uint32 for checking overflow in blending
+			uint32 color = READ_LE_UINT16(srcP); //uint32 for checking overflow in blending
 			if (color != 0b1111100000011111) { // "zero" for Tinsel 3 - magenta in 565
 				uint8 srcR, srcG, srcB;
 				t3getRGB(color, srcR, srcG, srcB);
 
-				uint16 dstColor = READ_UINT16(tempP);
+				uint16 dstColor = READ_LE_UINT16(tempP);
 				uint8 dstR, dstG, dstB;
 				t3getRGB(dstColor, dstR, dstG, dstB);
 
@@ -694,7 +797,7 @@ static void t3TransWNZ(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP) {
 			tempP += 2;
 			srcP += 2;
 		}
-		srcP += rightClip * 2;
+		srcP += pObj->rightClip * 2;
 		destP += SCREEN_WIDTH * 2;
 	}
 }
@@ -756,7 +859,7 @@ static void t3WrtAll(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP) {
 	int objWidth = pObj->width;
 
 	if (applyClipping) {
-		srcP += ((pObj->topClip * pObj->width) + pObj->leftClip) * 2;
+		srcP += (pObj->topClip * pObj->width * 2) + (pObj->leftClip * 2);
 
 		pObj->height -= pObj->topClip + pObj->botClip;
 		pObj->width -= pObj->leftClip + pObj->rightClip;
@@ -1030,7 +1133,9 @@ void DrawObject(DRAWOBJECT *pObj) {
 		case 0x51:	// TinselV2, draw sprite with clipping, flipped horizontally
 			assert(TinselV2 || (typeId == 0x01 || typeId == 0x41));
 
-			if (TinselV2)
+			if (TinselV3)
+				t3WrtNonZero(pObj, srcPtr, destPtr);
+			else if (TinselV2)
 				t2WrtNonZero(pObj, srcPtr, destPtr, (typeId & DMA_CLIP) != 0, (typeId & DMA_FLIPH) != 0);
 			else if (TinselV1PSX)
 				PsxDrawTiles(pObj, srcPtr, destPtr, typeId == 0x41, psxFourBitClut, psxSkipBytes, psxMapperTable, true);
diff --git a/engines/tinsel/play.cpp b/engines/tinsel/play.cpp
index 4325448c70..ee67b0606e 100644
--- a/engines/tinsel/play.cpp
+++ b/engines/tinsel/play.cpp
@@ -56,6 +56,8 @@ struct PPINIT {
 
 	uint8	escOn;
 	int32	myescEvent;
+
+	OBJECT** playfield;	// TinselV3, the playfield to insert the film
 };
 
 //----------------- LOCAL GLOBAL DATA --------------------
@@ -684,8 +686,7 @@ static void t1PlayReel(CORO_PARAM, const PPINIT *ppi) {
  * @param hFilm			The 'film'
  * @param column		Column number, first column = 0
  */
-static void t2PlayReel(CORO_PARAM, int x, int y, bool bRestore, int speed, SCNHANDLE hFilm,
-		int column, int myescEvent, bool bTop) {
+static void t2PlayReel(CORO_PARAM, int x, int y, bool bRestore, int speed, SCNHANDLE hFilm, int column, int myescEvent, bool bTop, OBJECT** playfield) {
 	CORO_BEGIN_CONTEXT;
 		bool bReplaced;
 		bool bGotHidden;
@@ -767,8 +768,10 @@ static void t2PlayReel(CORO_PARAM, int x, int y, bool bRestore, int speed, SCNHA
 	/*
 	 * Insert the object
 	 */
-	// Poke in the background palette
-	PokeInPalette(_ctx->pmi);
+	if (!TinselV3) {
+		// Poke in the background palette
+		PokeInPalette(_ctx->pmi);
+	}
 
 	// Set ghost bit if wanted
 	if (_vm->_actor->ActorIsGhost(_ctx->reelActor)) {
@@ -778,10 +781,14 @@ 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(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
-	else
-		MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+	if (TinselV3) {
+		MultiInsertObject(playfield, _ctx->pPlayObj);
+	} else {
+		if (!bTop)
+			MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
+		else
+			MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+	}
 
 	/*
 	 * More action for moving actors
@@ -922,10 +929,15 @@ static void t2PlayReel(CORO_PARAM, int x, int y, bool bRestore, int speed, SCNHA
 	_vm->_actor->NotPlayingReel(_ctx->reelActor, _ctx->filmNumber, column);
 
 	// Ditch the object
-	if (!bTop)
-		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
-	else
-		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+	if (TinselV3) {
+		MultiDeleteObject(playfield, _ctx->pPlayObj);
+	} else {
+		if (!bTop) {
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_WORLD), _ctx->pPlayObj);
+		} else {
+			MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->pPlayObj);
+		}
+	}
 
 	// Restore moving actor is nessesary
 	if (_ctx->pMover != NULL && _ctx->bPrinciple && !_ctx->bReplaced)
@@ -946,7 +958,7 @@ static void PlayProcess(CORO_PARAM, const void *param) {
 
 	if (TinselV2)
 		CORO_INVOKE_ARGS(t2PlayReel, (CORO_SUBCTX, ppi->x, ppi->y, ppi->bRestore, ppi->speed,
-			ppi->hFilm, ppi->column, ppi->myescEvent, ppi->bTop));
+			ppi->hFilm, ppi->column, ppi->myescEvent, ppi->bTop, ppi->playfield));
 	else
 		CORO_INVOKE_1(t1PlayReel, ppi);
 
@@ -975,8 +987,7 @@ void NewestFilm(SCNHANDLE film, const FREEL *reel) {
  * NOTE: The processes are started in reverse order so that the first
  *   column's process kicks in first.
  */
-void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay, bool sfact, bool escOn,
-			  int myescEvent, bool bTop) {
+void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay, bool sfact, bool escOn, int myescEvent, bool bTop, OBJECT** playfield) {
 	assert(hFilm != 0); // Trying to play NULL film
 	const FILM *pFilm;
 
@@ -1004,6 +1015,7 @@ void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay
 	ppi.sf = sfact;
 	ppi.escOn = escOn;
 	ppi.myescEvent = myescEvent;
+	ppi.playfield = playfield;
 
 	// Start display process for each reel in the film
 	for (int i = FROM_32(pFilm->numreels) - 1; i >= 0; i--) {
@@ -1026,16 +1038,15 @@ void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay
 	CORO_END_CODE;
 }
 
-void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int myescEvent, bool bTop) {
-	PlayFilm(coroParam, hFilm, x, y, 0, false, false, false, myescEvent, bTop);
+void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int myescEvent, bool bTop, OBJECT** playfield) {
+	PlayFilm(coroParam, hFilm, x, y, 0, false, false, false, myescEvent, bTop, playfield);
 }
 
 /**
  * Start up a play process for each slave column in a film.
  * Play the first column directly from the parent process.
  */
-void PlayFilmc(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay, bool sfact,
-			   bool escOn, int myescEvent, bool bTop) {
+void PlayFilmc(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay, bool sfact, bool escOn, int myescEvent, bool bTop, OBJECT** playfield) {
 	CORO_BEGIN_CONTEXT;
 		PPINIT ppi;
 		int i;
@@ -1065,6 +1076,7 @@ void PlayFilmc(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool spla
 	_ctx->ppi.sf = sfact;
 	_ctx->ppi.escOn = escOn;
 	_ctx->ppi.myescEvent = myescEvent;
+	_ctx->ppi.playfield = playfield;
 
 	// Start display process for each secondary reel in the film in Tinsel 1,
 	// or all of them in Tinsel 2
diff --git a/engines/tinsel/play.h b/engines/tinsel/play.h
index 01bb10bf21..8cab339558 100644
--- a/engines/tinsel/play.h
+++ b/engines/tinsel/play.h
@@ -39,13 +39,11 @@ struct SOUNDREELS {
 };
 typedef SOUNDREELS *PSOUNDREELS;
 
-void PlayFilm(CORO_PARAM, SCNHANDLE film, int x, int y, int actorid, bool splay, bool sfact, bool escOn,
-			int myescEvent, bool bTop);
+void PlayFilm(CORO_PARAM, SCNHANDLE film, int x, int y, int actorid, bool splay, bool sfact, bool escOn, int myescEvent, bool bTop, OBJECT** playfield);
 
-void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int myescEvent, bool bTop);
+void PlayFilm(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int myescEvent, bool bTop, OBJECT** playfield);
 
-void PlayFilmc(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay, bool sfact,
-			bool escOn, int myescEvent, bool bTop);
+void PlayFilmc(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int actorid, bool splay, bool sfact, bool escOn, int myescEvent, bool bTop, OBJECT** playfield);
 
 void RestoreActorReels(SCNHANDLE hFilm, short reelnum, short z, int x, int y);
 void RestoreActorReels(SCNHANDLE hFilm, int actor, int x, int y);
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 34089a9502..2155c33b75 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -1537,12 +1537,12 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int compit, int acto
 
 	if (compit == 1) {
 		// Play to completion before returning
-		CORO_INVOKE_ARGS(PlayFilmc, (CORO_SUBCTX, hFilm, x, y, actorid, splay, sfact, escOn, myEscape, bTop));
+		CORO_INVOKE_ARGS(PlayFilmc, (CORO_SUBCTX, hFilm, x, y, actorid, splay, sfact, escOn, myEscape, bTop, nullptr));
 	} else if (compit == 2) {
 		error("play(): compit == 2 - please advise John");
 	} else {
 		// Kick off the play and return.
-		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, x, y, actorid, splay, sfact, escOn, myEscape, bTop));
+		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, x, y, actorid, splay, sfact, escOn, myEscape, bTop, nullptr));
 	}
 	CORO_END_CODE;
 }
@@ -1550,8 +1550,7 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int compit, int acto
 /**
  * Play a film
  */
-static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, bool bComplete, int myEscape,
-		bool bTop, TINSEL_EVENT event, HPOLYGON hPoly, int taggedActor) {
+static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int compit, int myEscape, bool bTop, TINSEL_EVENT event, HPOLYGON hPoly, int taggedActor) {
 	CORO_BEGIN_CONTEXT;
 	CORO_END_CONTEXT(_ctx);
 
@@ -1565,6 +1564,10 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, bool bComplete, int
 		return;
 	}
 
+	if (TinselV3) {
+		CORO_INVOKE_0(_vm->_bg->WaitForBG);
+	}
+
 	if (event == TALKING) {
 		int	actor;
 		if (hPoly == NOPOLY) {
@@ -1586,12 +1589,27 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, bool bComplete, int
 		_vm->_actor->SetActorTalkFilm(actor, hFilm);
 	}
 
+	OBJECT** playfield;
+	bool bComplete;
+
+	playfield = nullptr;
+	bComplete = compit;
+
+	if (TinselV3) {
+		bComplete = compit & 0x20;
+		if (bTop) {
+			playfield = _vm->_bg->GetPlayfieldList(FIELD_STATUS);
+		} else {
+			playfield = _vm->_bg->GetPlayfieldList(compit & 0x0F);
+		}
+	}
+
 	if (bComplete) {
 		// Play to completion before returning
-		CORO_INVOKE_ARGS(PlayFilmc, (CORO_SUBCTX, hFilm, x, y, 0, false, false, myEscape != 0, myEscape, bTop));
+		CORO_INVOKE_ARGS(PlayFilmc, (CORO_SUBCTX, hFilm, x, y, 0, false, false, myEscape != 0, myEscape, bTop, playfield));
 	} else {
 		// Kick off the play and return.
-		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, x, y, myEscape, bTop));
+		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, x, y, myEscape, bTop, playfield));
 	}
 
 	CORO_END_CODE;
@@ -2934,7 +2952,7 @@ void Stand(CORO_PARAM, int actor, int x, int y, SCNHANDLE hFilm) {
 		assert(hFilm != 0); // Trying to play NULL film
 
 		// Kick off the play and return.
-		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, x, y, actor, false, 0, false, 0, false));
+		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, x, y, actor, false, 0, false, 0, false, nullptr));
 	}
 
 	CORO_END_CODE;
@@ -3163,7 +3181,7 @@ static void FinishTalkingReel(CORO_PARAM, PMOVER pMover, int actor) {
 		AlterMover(pMover, 0, AR_POPREEL);
 	} else {
 		_vm->_actor->SetActorTalking(actor, false);
-		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, _vm->_actor->GetActorPlayFilm(actor), -1, -1, 0, false, 0, false, 0, false));
+		CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, _vm->_actor->GetActorPlayFilm(actor), -1, -1, 0, false, 0, false, 0, false, _vm->_bg->GetPlayfieldList(FIELD_WORLD)));
 	}
 
 	CORO_END_CODE;
@@ -3290,7 +3308,7 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 		} else {
 			_vm->_actor->SetActorTalking(_ctx->actor, true);
 			_vm->_actor->SetActorTalkFilm(_ctx->actor, hFilm);
-			CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, -1, -1, 0, false, 0, escOn, myEscape, false));
+			CORO_INVOKE_ARGS(PlayFilm, (CORO_SUBCTX, hFilm, -1, -1, 0, false, 0, escOn, myEscape, false, _vm->_bg->GetPlayfieldList(FIELD_WORLD)));
 		}
 		_ctx->bTalkReel = true;
 		CORO_SLEEP(1);		// Allow the play to come in
@@ -5184,15 +5202,25 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 	case PLAY:
 		// Common to DW1 / DW2 / Noir
 		if (TinselV3) {
-			warning("TODO: Implement PLAY");
+			if (*pResumeState == RES_1 && _vm->_handle->IsCdPlayHandle(pp[0])) {
+				*pResumeState = RES_NOT;
+				if ((pp[0] & 0x10) != 0) {
+					return -4;
+				}
+				return -2;
+			} else if ((pp[0] & 0x10) != 0) {
+				Play(coroParam, pp[-1], pp[-3], pp[-2], pp[0], pic->myEscape, false, pic->event, pic->hPoly, pic->idActor);
+				return -4;
+			}
+			Play(coroParam, pp[-1], -1, -1, pp[0], pic->myEscape, false, pic->event, pic->hPoly, pic->idActor);
 			return -2;
+
 		} if (TinselV2) {
 			pp -= 3;			// 4 parameters
 			if (*pResumeState == RES_1 && _vm->_handle->IsCdPlayHandle(pp[0]))
 				*pResumeState = RES_NOT;
 			else {
-				Play(coroParam, pp[0], pp[1], pp[2], pp[3], pic->myEscape, false,
-						pic->event, pic->hPoly, pic->idActor);
+				Play(coroParam, pp[0], pp[1], pp[2], pp[3], pic->myEscape, false, pic->event, pic->hPoly, pic->idActor);
 			}
 			return -4;
 




More information about the Scummvm-git-logs mailing list