[Scummvm-git-logs] scummvm master -> 0221bc5c02b695b85d22a4647be0c657623d53f2

bluegr noreply at scummvm.org
Sun Jan 9 15:08:22 UTC 2022


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:
0221bc5c02 TINSEL: Refactor and simplify image handling


Commit: 0221bc5c02b695b85d22a4647be0c657623d53f2
    https://github.com/scummvm/scummvm/commit/0221bc5c02b695b85d22a4647be0c657623d53f2
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2022-01-09T17:07:46+02:00

Commit Message:
TINSEL: Refactor and simplify image handling

This allows us to merge different code paths for Tinsel V1 - V3 and
simplify the relevant code.

- Images are now obtained as a copy via GetImage(), which handles
  endianess internally
- The GetImageFromFilm() / GetImageFromReel() wrappers have been removed
- Direct setting of the image palette has been removed in favor of
  PokeInPalette(). This allows us to make image pointers const
- Struct packing has been removed from the IMAGE class, as we no
  longer cast raw data to image pointers
- There is now a single IMAGE class for all Tinsel versions

Changed paths:
    engines/tinsel/bg.cpp
    engines/tinsel/cursor.cpp
    engines/tinsel/cursor.h
    engines/tinsel/dialogs.cpp
    engines/tinsel/font.cpp
    engines/tinsel/handle.cpp
    engines/tinsel/handle.h
    engines/tinsel/movers.cpp
    engines/tinsel/object.cpp
    engines/tinsel/object.h
    engines/tinsel/play.cpp
    engines/tinsel/text.cpp
    engines/tinsel/tinsel.h


diff --git a/engines/tinsel/bg.cpp b/engines/tinsel/bg.cpp
index 6ac2a8695de..e100ee8aaf4 100644
--- a/engines/tinsel/bg.cpp
+++ b/engines/tinsel/bg.cpp
@@ -164,19 +164,21 @@ void Background::StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
 	CORO_BEGIN_CONTEXT;
 	CORO_END_CONTEXT(_ctx);
 
-	CORO_BEGIN_CODE(_ctx);
-
-	const FILM *pfilm;
-	IMAGE *pim;
-
-	_hBackground = hFilm;		// Save handle in case of Save_Scene()
-
-	pim = _vm->_cursor->GetImageFromFilm(hFilm, 0, NULL, NULL, &pfilm);
+	const FILM *pfilm = (const FILM *)_vm->_handle->LockMem(hFilm);
+	const FREEL *pfr = &pfilm->reels[0];
 
 	if (!TinselV3) {
-		SetBackPal(FROM_32(pim->hImgPal));
+		const MULTI_INIT *pmi = (const MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
+		const FRAME *pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
+		const IMAGE *pim = _vm->_handle->GetImage(READ_32(pFrame));
+		SetBackPal(pim->hImgPal);
+		delete pim;
 	}
 
+	CORO_BEGIN_CODE(_ctx);
+
+	_hBackground = hFilm; // Save handle in case of Save_Scene()
+
 	// Extract the film speed
 	_BGspeed = ONE_SECOND / FROM_32(pfilm->frate);
 
diff --git a/engines/tinsel/cursor.cpp b/engines/tinsel/cursor.cpp
index c00263f4212..47d1733588a 100644
--- a/engines/tinsel/cursor.cpp
+++ b/engines/tinsel/cursor.cpp
@@ -84,23 +84,19 @@ Cursor::Cursor() {
  * it. Also initialize its animation script.
  */
 void Cursor::InitCurTrailObj(int i, int x, int y) {
-	const FREEL *pfr;		// pointer to reel
-	IMAGE *pim;		// pointer to image
-	const MULTI_INIT *pmi;		// MULTI_INIT structure
-
-	const FILM *pfilm;
-
 	if (!_numTrails)
 		return;
 
+	const FILM *pFilm = (const FILM *)_vm->_handle->LockMem(_cursorFilm);
+	const FREEL *pfr = (const FREEL *)&pFilm->reels[i + 1];
+	const MULTI_INIT *pmi = (MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
+
+	PokeInPalette(pmi);
+
 	// Get rid of old object
 	if (_trailData[i].trailObj != NULL)
 		MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _trailData[i].trailObj);
 
-	pim = GetImageFromFilm(_cursorFilm, i+1, &pfr, &pmi, &pfilm);// Get pointer to image
-	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
 	_trailData[i].trailObj = MultiInitObject(pmi);
 	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _trailData[i].trailObj);
@@ -108,7 +104,7 @@ void Cursor::InitCurTrailObj(int i, int x, int y) {
 	MultiSetAniXY(_trailData[i].trailObj, x, y);
 
 	// Initialize the animation script
-	InitStepAnimScript(&_trailData[i].trailAnim, _trailData[i].trailObj, FROM_32(pfr->script), ONE_SECOND / FROM_32(pfilm->frate));
+	InitStepAnimScript(&_trailData[i].trailAnim, _trailData[i].trailObj, FROM_32(pfr->script), ONE_SECOND / FROM_32(pFilm->frate));
 	StepAnimScript(&_trailData[i].trailAnim);
 }
 
@@ -301,41 +297,6 @@ void Cursor::UnHideCursorTrails() {
 	_hiddenTrails = false;
 }
 
-/**
- * Get pointer to image from a film reel. And the rest.
- */
-IMAGE *Cursor::GetImageFromReel(const FREEL *pfr, const MULTI_INIT **ppmi) {
-	const MULTI_INIT *pmi;
-	const FRAME *pFrame;
-
-	pmi = (const MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
-	if (ppmi)
-		*ppmi = pmi;
-
-	pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
-
-	// get pointer to image
-	return (IMAGE *)_vm->_handle->LockMem(READ_32(pFrame));
-}
-
-/**
- * Get pointer to image from a film. And the rest.
- */
-IMAGE *Cursor::GetImageFromFilm(SCNHANDLE hFilm, int reel, const FREEL **ppfr, const MULTI_INIT **ppmi, const FILM **ppfilm) {
-	const FILM *pfilm;
-	const FREEL *pfr;
-
-	pfilm = (const FILM *)_vm->_handle->LockMem(hFilm);
-	if (ppfilm)
-		*ppfilm = pfilm;
-
-	pfr = &pfilm->reels[reel];
-	if (ppfr)
-		*ppfr = pfr;
-
-	return GetImageFromReel(pfr, ppmi);
-}
-
 /**
  * Delete auxillary cursor. Restore animation offsets in the image.
  */
@@ -351,10 +312,11 @@ void Cursor::DelAuxCursor() {
  * Save animation offsets from the image if required.
  */
 void Cursor::SetAuxCursor(SCNHANDLE hFilm) {
-	IMAGE *pim;		// Pointer to auxillary cursor's image
-	const FREEL *pfr;
-	const MULTI_INIT *pmi;
-	const FILM *pfilm;
+	const FILM *pfilm = (const FILM *)_vm->_handle->LockMem(hFilm);
+	const FREEL *pfr = &pfilm->reels[0];
+	const MULTI_INIT *pmi = (const MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
+	const FRAME *pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
+	const IMAGE *pim;
 	int	x, y;		// Cursor position
 
 	DelAuxCursor();		// Get rid of previous
@@ -365,13 +327,14 @@ void Cursor::SetAuxCursor(SCNHANDLE hFilm) {
 
 	GetCursorXY(&x, &y, false);	// Note: also waits for cursor to appear
 
-	pim = GetImageFromFilm(hFilm, 0, &pfr, &pmi, &pfilm);// Get pointer to image
+	pim = _vm->_handle->GetImage(READ_32(pFrame)); // Get pointer to auxillary cursor's image
 	assert(_vm->_bg->BgPal()); // no background palette
-	pim->hImgPal = TO_32(_vm->_bg->BgPal());			// Poke in the background palette
+	PokeInPalette(pmi);
 
-	_auxCursorOffsetX = (short)(FROM_16(pim->imgWidth)/2 - ((int16) FROM_16(pim->anioffX)));
-	_auxCursorOffsetY = (short)((FROM_16(pim->imgHeight) & ~C16_FLAG_MASK)/2 -
-		((int16) FROM_16(pim->anioffY)));
+	_auxCursorOffsetX = (short)(pim->imgWidth / 2 - ((int16) pim->anioffX));
+	_auxCursorOffsetY = (short)((pim->imgHeight & ~C16_FLAG_MASK) / 2 -
+		((int16) pim->anioffY));
+	delete pim;
 
 	// Initialize and insert the auxillary cursor object
 	_auxCursor = MultiInitObject(pmi);
@@ -461,28 +424,17 @@ void Cursor::DoCursorMove() {
  * Initialize cursor object.
  */
 void Cursor::InitCurObj() {
-	const FILM *pFilm;
-	const FREEL *pfr;
-	const MULTI_INIT *pmi;
-	IMAGE *pim;
-
-	if (TinselV2 || TinselV3) {
-		pFilm = (const FILM *)_vm->_handle->LockMem(_cursorFilm);
-		pfr = (const FREEL *)&pFilm->reels[0];
-		pmi = (MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
-
-		if (!TinselV3) {
-			PokeInPalette(pmi);
-		}
-	} else {
-		assert(_vm->_bg->BgPal()); // no background palette
-
-		pim = GetImageFromFilm(_cursorFilm, 0, &pfr, &pmi, &pFilm);// Get pointer to image
-		pim->hImgPal = TO_32(_vm->_bg->BgPal());
+	const FILM *pFilm = (const FILM *)_vm->_handle->LockMem(_cursorFilm);
+	const FREEL *pfr = (const FREEL *)&pFilm->reels[0];
+	const MULTI_INIT *pmi = (MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
 
-		_auxCursor = nullptr;		// No auxillary cursor
+	if (!TinselV3) {
+		PokeInPalette(pmi);
 	}
 
+	if (!TinselV2)
+		_auxCursor = nullptr; // No auxillary cursor
+
 	_mainCursor = MultiInitObject(pmi);
 	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _mainCursor);
 
diff --git a/engines/tinsel/cursor.h b/engines/tinsel/cursor.h
index 84b5fae693b..79067ef3143 100644
--- a/engines/tinsel/cursor.h
+++ b/engines/tinsel/cursor.h
@@ -69,8 +69,6 @@ public:
 	void InitCurObj();
 	void InitCurPos();
 	void DoCursorMove();
-	IMAGE *GetImageFromReel(const FREEL *pfr, const MULTI_INIT **ppmi = nullptr);
-	IMAGE *GetImageFromFilm(SCNHANDLE hFilm, int reel, const FREEL **ppfr = nullptr, const MULTI_INIT **ppmi = nullptr, const FILM **ppfilm = nullptr);
 
 	bool CursorIsFrozen() { return _frozenCursor; }
 	int NumTrails() { return _numTrails; }
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index b7a2c121306..b8a5cfe3594 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -2153,21 +2153,17 @@ void Dialogs::AdjustTop() {
  * Insert an inventory icon object onto the display list.
  */
 OBJECT *Dialogs::AddInvObject(int num, const FREEL **pfreel, const FILM **pfilm) {
-	INV_OBJECT *invObj;    // Icon data
-	const MULTI_INIT *pmi; // Its INIT structure - from the reel
-	IMAGE *pim;            // ... you get the picture
-	OBJECT *pPlayObj;      // The object we insert
+	INV_OBJECT *invObj = GetInvObject(num);
+	const FILM *pFilm = (const FILM *)_vm->_handle->LockMem(invObj->hIconFilm);
+	const FREEL *pfr = (const FREEL *)&pFilm->reels[0];
+	const MULTI_INIT *pmi = (MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
+	OBJECT *pPlayObj; // The object we insert
 
-	invObj = GetInvObject(num);
+	*pfreel = pfr;
+	*pfilm = pFilm;
+	PokeInPalette(pmi);
+	pPlayObj = MultiInitObject(pmi);	// Needs to be initialized after the palette is set
 
-	// Get pointer to image
-	pim = _vm->_cursor->GetImageFromFilm(invObj->hIconFilm, 0, pfreel, &pmi, pfilm);
-
-	// Poke in the background palette
-	pim->hImgPal = TO_32(_vm->_bg->BgPal());
-
-	// Set up the multi-object
-	pPlayObj = MultiInitObject(pmi);
 	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), pPlayObj);
 
 	return pPlayObj;
@@ -2285,27 +2281,28 @@ void Dialogs::AddTitle(POBJECT *title, int extraH) {
  * Insert a part of the inventory window frame onto the display list.
  */
 OBJECT *Dialogs::AddObject(const FREEL *pfreel, int num) {
-	const MULTI_INIT *pmi; // Get the MULTI_INIT structure
-	IMAGE *pim;
+	const MULTI_INIT *pmi = (const MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfreel->mobj));
+	const FRAME *pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
+	const IMAGE *pim;
 	OBJECT *pPlayObj;
 
-	// Get pointer to image
-	pim = _vm->_cursor->GetImageFromReel(pfreel, &pmi);
+	PokeInPalette(pmi);
 
-	// Poke in the background palette
-	pim->hImgPal = TO_32(_vm->_bg->BgPal());
+	pim = _vm->_handle->GetImage(READ_32(pFrame));
 
 	// Horrible bodge involving global variables to save
 	// width and/or height of some window frame components
 	if (num == _TL) {
-		_TLwidth = FROM_16(pim->imgWidth);
-		_TLheight = FROM_16(pim->imgHeight) & ~C16_FLAG_MASK;
+		_TLwidth = pim->imgWidth;
+		_TLheight = pim->imgHeight & ~C16_FLAG_MASK;
 	} else if (num == _TR) {
-		_TRwidth = FROM_16(pim->imgWidth);
+		_TRwidth = pim->imgWidth;
 	} else if (num == _BL) {
-		_BLheight = FROM_16(pim->imgHeight) & ~C16_FLAG_MASK;
+		_BLheight = pim->imgHeight & ~C16_FLAG_MASK;
 	}
 
+	delete pim;
+
 	// Set up and insert the multi-object
 	pPlayObj = MultiInitObject(pmi);
 	MultiInsertObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), pPlayObj);
@@ -2990,16 +2987,13 @@ bool Dialogs::RePosition() {
  * and customise the cursor.
  */
 void Dialogs::AlterCursor(int num) {
-	const FREEL *pfreel;
-	IMAGE *pim;
-
-	// Get pointer to image
-	pim = _vm->_cursor->GetImageFromFilm(_hWinParts, num, &pfreel);
+	const FILM *pFilm = (const FILM *)_vm->_handle->LockMem(_hWinParts);
+	const FREEL *pfr = (const FREEL *)&pFilm->reels[num];
+	const MULTI_INIT *pmi = (MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfr->mobj));
 
-	// Poke in the background palette
-	pim->hImgPal = TO_32(_vm->_bg->BgPal());
+	PokeInPalette(pmi);
 
-	_vm->_cursor->SetTempCursor(FROM_32(pfreel->script));
+	_vm->_cursor->SetTempCursor(FROM_32(pfr->script));
 }
 
 /**
diff --git a/engines/tinsel/font.cpp b/engines/tinsel/font.cpp
index 7939f835230..1ce57002fb6 100644
--- a/engines/tinsel/font.cpp
+++ b/engines/tinsel/font.cpp
@@ -42,23 +42,14 @@ SCNHANDLE Font::GetTalkFontHandle() {
 }
 
 void Font::FettleFontPal(SCNHANDLE fontPal) {
-	IMAGE *pImg;
+	Handle *h = _vm->_handle;
 
 	assert(fontPal);
 	assert(_hTagFont); // Tag font not declared
 	assert(_hTalkFont); // Talk font not declared
 
-	pImg = (IMAGE *)_vm->_handle->LockMem(_vm->_handle->GetFontImageHandle(_hTagFont)); // get image for char 0
-	if (!TinselV2)
-		pImg->hImgPal = TO_32(fontPal);
-	else
-		pImg->hImgPal = 0;
-
-	pImg = (IMAGE *)_vm->_handle->LockMem(_vm->_handle->GetFontImageHandle(_hTalkFont)); // get image for char 0
-	if (!TinselV2)
-		pImg->hImgPal = TO_32(fontPal);
-	else
-		pImg->hImgPal = 0;
+	h->SetImagePalette(h->GetFontImageHandle(_hTagFont), !TinselV2 ? fontPal : 0); // get image for char 0
+	h->SetImagePalette(h->GetFontImageHandle(_hTalkFont), !TinselV2 ? fontPal : 0); // get image for char 0
 
 	if (TinselV2 && SysVar(SV_TAGCOLOR)) {
 		const COLORREF c = _vm->_actor->GetActorRGB(-1);
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 63c89ed6608..029755f57c8 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -26,6 +26,7 @@
 #include "common/memstream.h"
 #include "common/textconsole.h"
 
+#include "tinsel/background.h"
 #include "tinsel/drives.h"
 #include "tinsel/dw.h"
 #include "tinsel/handle.h"
@@ -305,28 +306,28 @@ void Handle::LoadFile(MEMHANDLE *pH) {
  * @return FONT structure
 */
 FONT *Handle::GetFont(SCNHANDLE offset) {
-	byte *fontData = LockMem(offset);
+	byte *data = LockMem(offset);
 	const bool isBE = TinselV1Mac || TinselV1Saturn;
 	const uint32 size = (TinselV3 ? 12 * 4 : 11 * 4) + 300 * 4;	// FONT struct size
-	Common::MemoryReadStreamEndian *fontStream = new Common::MemoryReadStreamEndian(fontData, size, isBE);
+	Common::MemoryReadStreamEndian *stream = new Common::MemoryReadStreamEndian(data, size, isBE);
 
 	FONT *font = new FONT();
-	font->xSpacing = fontStream->readSint32();
-	font->ySpacing = fontStream->readSint32();
-	font->xShadow = fontStream->readSint32();
-	font->yShadow = fontStream->readSint32();
-	font->spaceSize = fontStream->readSint32();
-	font->baseColor = TinselV3 ? fontStream->readSint32() : 0;
-	font->fontInit.hObjImg = fontStream->readUint32();
-	font->fontInit.objFlags = fontStream->readSint32();
-	font->fontInit.objID = fontStream->readSint32();
-	font->fontInit.objX = fontStream->readSint32();
-	font->fontInit.objY = fontStream->readSint32();
-	font->fontInit.objZ = fontStream->readSint32();
+	font->xSpacing = stream->readSint32();
+	font->ySpacing = stream->readSint32();
+	font->xShadow = stream->readSint32();
+	font->yShadow = stream->readSint32();
+	font->spaceSize = stream->readSint32();
+	font->baseColor = TinselV3 ? stream->readSint32() : 0;
+	font->fontInit.hObjImg = stream->readUint32();
+	font->fontInit.objFlags = stream->readSint32();
+	font->fontInit.objID = stream->readSint32();
+	font->fontInit.objX = stream->readSint32();
+	font->fontInit.objY = stream->readSint32();
+	font->fontInit.objZ = stream->readSint32();
 	for (int i = 0; i < 300; i++)
-		font->fontDef[i] = fontStream->readUint32();
+		font->fontDef[i] = stream->readUint32();
 
-	delete fontStream;
+	delete stream;
 
 	return font;
 }
@@ -338,16 +339,16 @@ FONT *Handle::GetFont(SCNHANDLE offset) {
  * @return PALETTE structure
 */
 PALETTE *Handle::GetPalette(SCNHANDLE offset) {
-	byte *palData = LockMem(offset);
+	byte *data = LockMem(offset);
 	const bool isBE = TinselV1Mac || TinselV1Saturn;
 	const uint32 size = 4 + 256 * 4;	// numColors + 256 COLORREF (max)
-	Common::MemoryReadStreamEndian *palStream = new Common::MemoryReadStreamEndian(palData, size, isBE);
+	Common::MemoryReadStreamEndian *stream = new Common::MemoryReadStreamEndian(data, size, isBE);
 
 	PALETTE *pal = new PALETTE();
 
-	pal->numColors = palStream->readSint32();
+	pal->numColors = stream->readSint32();
 	for (int32 i = 0; i < pal->numColors; i++) {
-		pal->palRGB[i] = palStream->readUint32();
+		pal->palRGB[i] = stream->readUint32();
 
 		// get the RGB color model values
 		pal->palette[i * 3] = (byte)(pal->palRGB[i] & 0xFF);
@@ -355,11 +356,49 @@ PALETTE *Handle::GetPalette(SCNHANDLE offset) {
 		pal->palette[i * 3 + 2] = (byte)((pal->palRGB[i] >> 16) & 0xFF);
 	}
 
-	delete palStream;
+	delete stream;
 
 	return pal;
 }
 
+/**
+ * Return an image specified by a SCNHANDLE
+ * Handles endianess internally
+ * @param offset			Handle and offset to data
+ * @return IMAGE structure
+*/
+const IMAGE *Handle::GetImage(SCNHANDLE offset) {
+	byte *data = LockMem(offset);
+	const bool isBE = TinselV1Mac || TinselV1Saturn;
+	const uint32 size = 16; // IMAGE struct size
+
+	Common::MemoryReadStreamEndian *stream = new Common::MemoryReadStreamEndian(data, size, isBE);
+
+	IMAGE *img = new IMAGE();
+
+	img->imgWidth = stream->readSint16();
+	img->imgHeight = stream->readUint16();
+	img->anioffX = stream->readSint16();
+	img->anioffY = stream->readSint16();
+	img->hImgBits = stream->readUint32();
+
+	if (!TinselV3) {
+		img->hImgPal = stream->readUint32();
+	} else {
+		img->isRLE = stream->readSint16();
+		img->colorFlags = stream->readSint16();
+	}
+
+	delete stream;
+
+	return img;
+}
+
+void Handle::SetImagePalette(SCNHANDLE offset, SCNHANDLE palHandle) {
+	byte *img = LockMem(offset);
+	WRITE_32(img + 12, palHandle); // hImgPal
+}
+
 SCNHANDLE Handle::GetFontImageHandle(SCNHANDLE offset) {
 	FONT *font = GetFont(offset);
 	SCNHANDLE handle = font->fontInit.hObjImg;
diff --git a/engines/tinsel/handle.h b/engines/tinsel/handle.h
index 21c6179689d..01d06544347 100644
--- a/engines/tinsel/handle.h
+++ b/engines/tinsel/handle.h
@@ -35,6 +35,7 @@ namespace Tinsel {
 struct FONT;
 struct MEMHANDLE;
 struct PALETTE;
+struct IMAGE;
 
 class Handle {
 public:
@@ -48,6 +49,8 @@ public:
 
 	FONT *GetFont(SCNHANDLE offset);
 	PALETTE *GetPalette(SCNHANDLE offset);
+	const IMAGE *GetImage(SCNHANDLE offset);
+	void SetImagePalette(SCNHANDLE offset, SCNHANDLE palHandle);
 	SCNHANDLE GetFontImageHandle(SCNHANDLE offset);
 	byte *LockMem(SCNHANDLE offset);
 
diff --git a/engines/tinsel/movers.cpp b/engines/tinsel/movers.cpp
index bee493140c8..3c77cc69c44 100644
--- a/engines/tinsel/movers.cpp
+++ b/engines/tinsel/movers.cpp
@@ -718,11 +718,9 @@ static void InitialPathChecks(PMOVER pMover, int xpos, int ypos) {
 }
 
 static void MoverProcessHelper(int X, int Y, int id, PMOVER pMover) {
-	const FILM *pfilm;
-	const MULTI_INIT *pmi;
-	const FRAME *pFrame;
-	IMAGE *pim;
-
+	const FILM *pfilm = (const FILM *)_vm->_handle->LockMem(pMover->walkReels[0][FORWARD]);
+	const MULTI_INIT *pmi = (const MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfilm->reels[0].mobj));
+	const FRAME *pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
 
 	assert(_vm->_bg->BgPal()); // Can't start actor without a background palette
 	assert(pMover->walkReels[0][FORWARD]); // Starting actor process without walk reels
@@ -730,19 +728,11 @@ static void MoverProcessHelper(int X, int Y, int id, PMOVER pMover) {
 	InitMover(pMover);
 	InitialPathChecks(pMover, X, Y);
 
-	pfilm = (const FILM *)_vm->_handle->LockMem(pMover->walkReels[0][FORWARD]);
-	pmi = (const MULTI_INIT *)_vm->_handle->LockMem(FROM_32(pfilm->reels[0].mobj));
-
-//---
-	pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
+	PokeInPalette(pmi);
 
-	// get pointer to image
-	pim = (IMAGE *)_vm->_handle->LockMem(READ_32(pFrame)); // handle to image
-	pim->hImgPal = TO_32(_vm->_bg->BgPal());
-//---
 	pMover->actorObj = MultiInitObject(pmi);
 
-/**/	assert(pMover->actorID == id);
+	assert(pMover->actorID == id);
 	pMover->actorID = id;
 
 	// add it to display list
diff --git a/engines/tinsel/object.cpp b/engines/tinsel/object.cpp
index 40b264a9285..d05a8bffe37 100644
--- a/engines/tinsel/object.cpp
+++ b/engines/tinsel/object.cpp
@@ -298,27 +298,29 @@ void SortObjectList(OBJECT **pObjList) {
  */
 void GetAniOffset(SCNHANDLE hImg, int flags, int *pAniX, int *pAniY) {
 	if (hImg) {
-		const IMAGE *pImg = (const IMAGE *)_vm->_handle->LockMem(hImg);
+		const IMAGE *pImg = _vm->_handle->GetImage(hImg);
 
 		// set ani X
-		*pAniX = (int16) FROM_16(pImg->anioffX);
+		*pAniX = (int16) pImg->anioffX;
 
 		// set ani Y
-		*pAniY = (int16) FROM_16(pImg->anioffY);
+		*pAniY = (int16) pImg->anioffY;
 
 		if (flags & DMA_FLIPH) {
 			// we are flipped horizontally
 
 			// set ani X = -ani X + width - 1
-			*pAniX = -*pAniX + FROM_16(pImg->imgWidth) - 1;
+			*pAniX = -*pAniX + pImg->imgWidth - 1;
 		}
 
 		if (flags & DMA_FLIPV) {
 			// we are flipped vertically
 
 			// set ani Y = -ani Y + height - 1
-			*pAniY = -*pAniY + (FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK) - 1;
+			*pAniY = -*pAniY + (pImg->imgHeight & ~C16_FLAG_MASK) - 1;
 		}
+
+		delete pImg;
 	} else
 		// null image
 		*pAniX = *pAniY = 0;
@@ -370,12 +372,12 @@ OBJECT *InitObject(const OBJ_INIT *pInitTbl) {
 	if (pInitTbl->hObjImg) {
 		int aniX, aniY;		// objects animation offsets
 		PALQ *pPalQ= nullptr;	// palette queue pointer
-		const IMAGE *pImg = (const IMAGE *)_vm->_handle->LockMem(pInitTbl->hObjImg); // handle to image
+		const IMAGE *pImg = _vm->_handle->GetImage(pInitTbl->hObjImg); // handle to image
 
 		if (!TinselV3) {
 			if (pImg->hImgPal) {
 				// allocate a palette for this object
-				pPalQ = AllocPalette(FROM_32(pImg->hImgPal));
+				pPalQ = AllocPalette(pImg->hImgPal);
 
 				// make sure palette allocated
 				assert(pPalQ != NULL);
@@ -384,26 +386,26 @@ OBJECT *InitObject(const OBJ_INIT *pInitTbl) {
 			// assign palette to object
 			pObj->pPal = pPalQ;
 		} else {
-			const IMAGE_T3 *pImgT3 = (const IMAGE_T3 *)pImg;
-
-			if ((pImgT3->colorFlags & 0x0C) == 0) { // bits 0b1100 are used to select blending mode
+			if ((pImg->colorFlags & 0x0C) == 0) { // bits 0b1100 are used to select blending mode
 				pObj->flags = pObj->flags & ~DMA_GHOST;
 			} else {
 				assert((pObj->flags & DMA_WNZ) != 0);
 				pObj->flags |= DMA_GHOST;
 			}
-			pObj->isRLE = pImgT3->isRLE;
-			pObj->colorFlags = pImgT3->colorFlags;
+			pObj->isRLE = pImg->isRLE;
+			pObj->colorFlags = pImg->colorFlags;
 		}
 
 		// set objects size
-		pObj->width  = FROM_16(pImg->imgWidth);
-		pObj->height = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;
+		pObj->width  = pImg->imgWidth;
+		pObj->height = pImg->imgHeight & ~C16_FLAG_MASK;
 		pObj->flags &= ~C16_FLAG_MASK;
-		pObj->flags |= FROM_16(pImg->imgHeight) & C16_FLAG_MASK;
+		pObj->flags |= pImg->imgHeight & C16_FLAG_MASK;
 
 		// set objects bitmap definition
-		pObj->hBits = FROM_32(pImg->hImgBits);
+		pObj->hBits = pImg->hImgBits;
+
+		delete pImg;
 
 		// get animation offset of object
 		GetAniOffset(pObj->hImg, pInitTbl->objFlags, &aniX, &aniY);
@@ -451,16 +453,18 @@ void AnimateObjectFlags(OBJECT *pAniObj, int newflags, SCNHANDLE hNewImg) {
 
 		if (hNewImg) {
 			// get pointer to image
-			const IMAGE *pNewImg = (IMAGE *)_vm->_handle->LockMem(hNewImg);
+			const IMAGE *pNewImg = _vm->_handle->GetImage(hNewImg);
 
 			// setup new shape
-			pAniObj->width  = FROM_16(pNewImg->imgWidth);
-			pAniObj->height = FROM_16(pNewImg->imgHeight) & ~C16_FLAG_MASK;
+			pAniObj->width  = pNewImg->imgWidth;
+			pAniObj->height = pNewImg->imgHeight & ~C16_FLAG_MASK;
 			newflags &= ~C16_FLAG_MASK;
-			newflags |= FROM_16(pNewImg->imgHeight) & C16_FLAG_MASK;
+			newflags |= pNewImg->imgHeight & C16_FLAG_MASK;
 
 			// set objects bitmap definition
-			pAniObj->hBits  = FROM_32(pNewImg->hImgBits);
+			pAniObj->hBits  = pNewImg->hImgBits;
+
+			delete pNewImg;
 		} else {	// null image
 			pAniObj->width  = 0;
 			pAniObj->height = 0;
diff --git a/engines/tinsel/object.h b/engines/tinsel/object.h
index 6689dbe022b..0ceea24cfa3 100644
--- a/engines/tinsel/object.h
+++ b/engines/tinsel/object.h
@@ -55,34 +55,20 @@ enum {
 };
 
 /** structure for image */
-#include "common/pack-start.h"	// START STRUCT PACKING
 struct IMAGE {
-	short imgWidth;		///< image width
-	unsigned short imgHeight;	///< image height
-	short anioffX;		///< image x animation offset
-	short anioffY;		///< image y animation offset
-	SCNHANDLE hImgBits;	///< image bitmap handle
-	SCNHANDLE hImgPal;	///< image palette handle
-} PACKED_STRUCT;
-#include "common/pack-end.h"	// END STRUCT PACKING
-
-/** structure for image in Tinsel 3 */
-#include "common/pack-start.h"	// START STRUCT PACKING
-struct IMAGE_T3 {
-	short imgWidth;		///< image width
-	unsigned short imgHeight;	///< image height
-	short anioffX;		///< image x animation offset
-	short anioffY;		///< image y animation offset
-	SCNHANDLE hImgBits;	///< image bitmap handle
-	short isRLE;		///< if image is using run-length encoding
-	short colorFlags;	///< type of blending
-} PACKED_STRUCT;
-#include "common/pack-end.h"	// END STRUCT PACKING
+	short imgWidth;           ///< image width
+	unsigned short imgHeight; ///< image height
+	short anioffX;            ///< image x animation offset
+	short anioffY;            ///< image y animation offset
+	SCNHANDLE hImgBits;       ///< image bitmap handle
+	SCNHANDLE hImgPal;        ///< image palette handle (Tinsel V1/V2)
+	short isRLE;              ///< if image is using run-length encoding (Tinsel V3)
+	short colorFlags;         ///< type of blending (Tinsel V3)
+};
 
 /** a multi-object animation frame is a list of multi-image handles */
 typedef uint32 FRAME;
 
-
 // object structure
 struct OBJECT {
 	OBJECT *pNext;	///< pointer to next object in list
diff --git a/engines/tinsel/play.cpp b/engines/tinsel/play.cpp
index a704f239fb2..bf05f6c50b1 100644
--- a/engines/tinsel/play.cpp
+++ b/engines/tinsel/play.cpp
@@ -88,17 +88,10 @@ void ResetVarsPlay() {
  * Poke the background palette into an image.
  */
 static void PokeInPalette(SCNHANDLE hMulFrame) {
-	const FRAME *pFrame;		// Pointer to frame
-	IMAGE *pim;		// Pointer to image
-
 	// Could be an empty column
 	if (hMulFrame) {
-		pFrame = (const FRAME *)_vm->_handle->LockMem(hMulFrame);
-
-		// get pointer to image
-		pim = (IMAGE *)_vm->_handle->LockMem(READ_32(pFrame)); // handle to image
-
-		pim->hImgPal = TO_32(_vm->_bg->BgPal());
+		const FRAME *pFrame = (const FRAME *)_vm->_handle->LockMem(hMulFrame);
+		_vm->_handle->SetImagePalette(READ_32(pFrame), _vm->_bg->BgPal());
 	}
 }
 
@@ -106,17 +99,10 @@ static void PokeInPalette(SCNHANDLE hMulFrame) {
  * Poke the background palette into an image.
  */
 void PokeInPalette(const MULTI_INIT *pmi) {
-	FRAME	*pFrame;		// Pointer to frame
-	IMAGE	*pim;			// Pointer to image
-
 	// Could be an empty column
 	if (pmi->hMulFrame) {
-		pFrame = (FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
-
-		// get pointer to image
-		pim = (IMAGE *)_vm->_handle->LockMem(READ_32(pFrame)); // handle to image
-
-		pim->hImgPal = TO_32(_vm->_bg->BgPal());
+		const FRAME *pFrame = (const FRAME *)_vm->_handle->LockMem(FROM_32(pmi->hMulFrame));
+		_vm->_handle->SetImagePalette(READ_32(pFrame), _vm->_bg->BgPal());
 	}
 }
 
diff --git a/engines/tinsel/text.cpp b/engines/tinsel/text.cpp
index 7bf41d4733e..6b88ea87848 100644
--- a/engines/tinsel/text.cpp
+++ b/engines/tinsel/text.cpp
@@ -54,10 +54,12 @@ int StringLengthPix(char *szStr, const FONT *pFont) {
 
 		if (hImg) {
 			// there is a IMAGE for this character
-			const IMAGE *pChar = (const IMAGE *)_vm->_handle->LockMem(hImg);
+			const IMAGE *pChar = _vm->_handle->GetImage(hImg);
 
 			// add width of font bitmap
-			strLen += FROM_16(pChar->imgWidth);
+			strLen += pChar->imgWidth;
+
+			delete pChar;
 		} else
 			// use width of space character
 			strLen += pFont->spaceSize;
@@ -116,7 +118,6 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 	OBJECT *pChar = 0;	// object ptr for the character
 	byte c;
 	SCNHANDLE hImg;
-	const IMAGE *pImg;
 
 	// make sure there is a linked list to add text to
 	assert(pList);
@@ -131,10 +132,11 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 	// get image for capital W
 	SCNHANDLE imgHandle = pFont->fontDef[(int)'W'];
 	assert(imgHandle);
-	pImg = (const IMAGE *)_vm->_handle->LockMem(imgHandle);
 
 	// get height of capital W for offset to next line
-	yOffset = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;
+	const IMAGE *pImg = _vm->_handle->GetImage(imgHandle);
+	yOffset = pImg->imgHeight & ~C16_FLAG_MASK;
+	delete pImg;
 
 	while (*szStr) {
 		// x justify the text according to the mode flags
@@ -166,13 +168,13 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 					pChar = pChar->pSlave = InitObject(pFontInit);
 
 				// convert image handle to pointer
-				pImg = (const IMAGE *)_vm->_handle->LockMem(hImg);
+				const IMAGE *pImg = _vm->_handle->GetImage(hImg);
 
 				// fill in character object
 				pChar->hImg   = hImg;			// image def
-				pChar->width  = FROM_16(pImg->imgWidth);		// width of chars bitmap
-				pChar->height = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;	// height of chars bitmap
-				pChar->hBits  = FROM_32(pImg->hImgBits);		// bitmap
+				pChar->width  = pImg->imgWidth;		// width of chars bitmap
+				pChar->height = pImg->imgHeight & ~C16_FLAG_MASK;	// height of chars bitmap
+				pChar->hBits  = pImg->hImgBits;		// bitmap
 
 				// check for absolute positioning
 				if (mode & TXT_ABSOLUTE)
@@ -233,7 +235,9 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 					pChar = pChar->pSlave;
 
 				// add character spacing
-				xJustify += FROM_16(pImg->imgWidth);
+				xJustify += pImg->imgWidth;
+
+				delete pImg;
 			}
 
 			// finally add the inter-character spacing
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 100e7b95f1f..d0358bc6297 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -110,6 +110,7 @@ typedef bool (*KEYFPTR)(const Common::KeyState &);
 
 #define READ_16(v) (TinselV1Mac || TinselV1Saturn ? READ_BE_UINT16(v) : READ_LE_UINT16(v))
 #define READ_32(v) (TinselV1Mac || TinselV1Saturn ? READ_BE_UINT32(v) : READ_LE_UINT32(v))
+#define WRITE_32(p, v) (TinselV1Mac || TinselV1Saturn ? WRITE_BE_UINT32(p, v) : WRITE_LE_UINT32(p, v))
 #define FROM_16(v) (TinselV1Mac || TinselV1Saturn ? FROM_BE_16(v) : FROM_LE_16(v))
 #define FROM_32(v) (TinselV1Mac || TinselV1Saturn ? FROM_BE_32(v) : FROM_LE_32(v))
 #define TO_32(v)   (TinselV1Mac || TinselV1Saturn ? TO_BE_32(v) : TO_LE_32(v))




More information about the Scummvm-git-logs mailing list