[Scummvm-cvs-logs] SF.net SVN: scummvm:[45387] scummvm/trunk/engines/scumm

Kirben at users.sourceforge.net Kirben at users.sourceforge.net
Mon Oct 26 03:45:26 CET 2009


Revision: 45387
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45387&view=rev
Author:   Kirben
Date:     2009-10-26 02:45:26 +0000 (Mon, 26 Oct 2009)

Log Message:
-----------
Add patch from Tobias, for masking support in PCE version of Loom, with minor changes.

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/costume.cpp
    scummvm/trunk/engines/scumm/costume.h
    scummvm/trunk/engines/scumm/gfx.cpp
    scummvm/trunk/engines/scumm/gfx.h
    scummvm/trunk/engines/scumm/resource.cpp

Modified: scummvm/trunk/engines/scumm/costume.cpp
===================================================================
--- scummvm/trunk/engines/scumm/costume.cpp	2009-10-25 23:36:09 UTC (rev 45386)
+++ scummvm/trunk/engines/scumm/costume.cpp	2009-10-26 02:45:26 UTC (rev 45387)
@@ -595,10 +595,11 @@
 	const byte *mask, *src;
 	byte *dst;
 	byte maskbit;
-	uint width, height;
-	byte scaleIndexY;
+	int xPos, yPos;
+	uint color, width, height; //, pcolor;
+	bool masked;
 	int vertShift;
-
+	int xStep;
 	byte block[16][16];
 
 	src = _srcptr;
@@ -608,19 +609,17 @@
 	if (_numBlocks == 0)
 		return;
 
-	scaleIndexY = _scaleIndexY;
-	maskbit = revBitMask(v1.x & 7);
-	mask = v1.mask_ptr + v1.x / 8;
+	xStep = _mirror ? +1 : -1;
 
 	for (uint x = 0; x < width; ++x) {
-		dst = v1.destptr + 16 * x * _out.bytesPerPixel;
+		yPos = 0;
 		for (uint y = 0; y < height; ++y) {
 			vertShift = *src++;
 			if (vertShift == 0xFF) {
-				dst += 16 * _out.pitch;
+				yPos += 16;
 				continue;
 			} else {
-				dst += vertShift * _out.pitch;
+				yPos += vertShift;
 			}
 
 			memset(block, 0, sizeof(block));
@@ -646,18 +645,24 @@
 			}
 
 			for (int row = 0; row < 16; ++row) {
+				xPos = xStep * x * 16;
 				for (int col = 0; col < 16; ++col) {
-					int color = block[row][col];
-					if (color != 0) {
-						if (dst < v1.destptr + _out.w * _out.h * _out.bytesPerPixel) {
-							if (_mirror)
-								dst[col] = color;
-							else
-								dst[-col] = color;
-						}
+					dst = v1.destptr + yPos * _out.pitch + xPos;
+					mask = v1.mask_ptr + yPos * _numStrips + (v1.x + xPos) / 8;
+					maskbit = revBitMask((v1.x + xPos) % 8);
+
+					color = block[row][col];
+					masked = (v1.y + yPos < 0 || v1.y + yPos >= _out.h) || 
+					         (v1.x + xPos < 0 || v1.x + xPos >= _out.w) || 
+							 (v1.mask_ptr && (mask[0] & maskbit));
+
+					if (color && !masked) {
+						*dst = color;
 					}
+
+					xPos += xStep;
 				}
-				dst += _out.pitch;
+				yPos++;
 			}
 		}
 	}
@@ -825,54 +830,10 @@
 
 #define PCE_SIGNED(a) (((a) & 0x80) ? -((a) & 0x7F) : (a))
 
-byte PCEngineCostumeRenderer::drawLimb(const Actor *a, int limb) {
-	int i;
-	int code;
-	const byte *frameptr, *offset;
-	const CostumeData &cost = a->_cost;
-
-	// If the specified limb is stopped or not existing, do nothing.
-	if (cost.curpos[limb] == 0xFFFF || cost.stopped & (1 << limb))
-		return 0;
-
-	// Determine the position the limb is at
-	i = cost.curpos[limb] & 0x7FFF;
-
-	// Get the frame pointer for that limb
-	offset = _loaded._frameOffsets + limb * 2;
-	frameptr = READ_LE_UINT16(offset) + offset + 2;
-
-	// Determine the offset to the costume data for the limb at position i
-	code = _loaded._animCmds[i] & 0x7F;
-
-	// Code 0x7B indicates a limb for which there is nothing to draw
-	if (code != 0x7B) {
-		offset = frameptr + code * 2;
-		_srcptr = READ_LE_UINT16(offset) + offset + 2;
-
-		if (code < 0x79) {
-			int xmoveCur, ymoveCur;
-
-			_numBlocks = _srcptr[0];
-			_width = _srcptr[1] * 16;
-			_height = _srcptr[2] * 16;
-			xmoveCur = _xmove + PCE_SIGNED(_srcptr[3]);
-			ymoveCur = _ymove + PCE_SIGNED(_srcptr[4]);
-			_xmove += PCE_SIGNED(_srcptr[5]);
-			_ymove += PCE_SIGNED(_srcptr[6]);
-			_srcptr += 7;
-
-			return mainRoutine(xmoveCur, ymoveCur);
-		}
-	}
-
-	return 0;
-}
-
 byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
 	int i;
 	int code;
-	const byte *frameptr;
+	const byte *baseptr, *frameptr;
 	const CostumeData &cost = a->_cost;
 
 	// If the specified limb is stopped or not existing, do nothing.
@@ -882,21 +843,36 @@
 	// Determine the position the limb is at
 	i = cost.curpos[limb] & 0x7FFF;
 
+	baseptr = _loaded._baseptr;
+
 	// Get the frame pointer for that limb
-	frameptr = _loaded._baseptr + READ_LE_UINT16(_loaded._frameOffsets + limb * 2);
+	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
+		baseptr = _loaded._frameOffsets + limb * 2 + 2;
+	frameptr = baseptr + READ_LE_UINT16(_loaded._frameOffsets + limb * 2);
 
 	// Determine the offset to the costume data for the limb at position i
 	code = _loaded._animCmds[i] & 0x7F;
 
 	// Code 0x7B indicates a limb for which there is nothing to draw
 	if (code != 0x7B) {
-		_srcptr = _loaded._baseptr + READ_LE_UINT16(frameptr + code * 2);
+		if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
+			baseptr = frameptr + code * 2 + 2;
+		_srcptr = baseptr + READ_LE_UINT16(frameptr + code * 2);
 
 		if (!(_vm->_game.features & GF_OLD256) || code < 0x79) {
 			const CostumeInfo *costumeInfo;
 			int xmoveCur, ymoveCur;
 
-			if (_loaded._format == 0x57) {
+			if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
+				_numBlocks = _srcptr[0];
+				_width = _srcptr[1] * 16;
+				_height = _srcptr[2] * 16;
+				xmoveCur = _xmove + PCE_SIGNED(_srcptr[3]);
+				ymoveCur = _ymove + PCE_SIGNED(_srcptr[4]);
+				_xmove += PCE_SIGNED(_srcptr[5]);
+				_ymove += PCE_SIGNED(_srcptr[6]);
+				_srcptr += 7;
+			} else if (_loaded._format == 0x57) {
 				_width = _srcptr[0] * 8;
 				_height = _srcptr[1];
 				xmoveCur = _xmove + (int8)_srcptr[2] * 8;

Modified: scummvm/trunk/engines/scumm/costume.h
===================================================================
--- scummvm/trunk/engines/scumm/costume.h	2009-10-25 23:36:09 UTC (rev 45386)
+++ scummvm/trunk/engines/scumm/costume.h	2009-10-26 02:45:26 UTC (rev 45387)
@@ -135,9 +135,6 @@
 	PCEngineCostumeRenderer(ScummEngine *vm) : ClassicCostumeRenderer(vm) {}
 
 	void setPalette(uint16 *palette);
-
-protected:
-	byte drawLimb(const Actor *a, int limb);
 };
 
 class C64CostumeRenderer : public BaseCostumeRenderer {

Modified: scummvm/trunk/engines/scumm/gfx.cpp
===================================================================
--- scummvm/trunk/engines/scumm/gfx.cpp	2009-10-25 23:36:09 UTC (rev 45386)
+++ scummvm/trunk/engines/scumm/gfx.cpp	2009-10-26 02:45:26 UTC (rev 45387)
@@ -225,6 +225,7 @@
 
 GdiPCEngine::~GdiPCEngine() {
 	free(_PCE.tiles);
+	free(_PCE.masks);
 }
 
 GdiV1::GdiV1(ScummEngine *vm) : Gdi(vm) {
@@ -1570,7 +1571,9 @@
 		numzbuf = _numZBuffer;
 		assert(numzbuf <= 9);
 
-		if (_vm->_game.features & GF_SMALL_HEADER) {
+		if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
+			zplane_list[1] = 0;
+		} else if (_vm->_game.features & GF_SMALL_HEADER) {
 			if (_vm->_game.features & GF_16COLOR)
 				zplane_list[1] = ptr + READ_LE_UINT16(ptr);
 			else {
@@ -1646,11 +1649,7 @@
 		assert(smap_ptr);
 	}
 
-	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
-		numzbuf = 0;
-	} else {
-		numzbuf = getZPlanes(ptr, zplane_list, false);
-	}
+	numzbuf = getZPlanes(ptr, zplane_list, false);
 
 	const byte *tmsk_ptr = NULL;
 	if (_vm->_game.heversion >= 72) {
@@ -2611,6 +2610,10 @@
 	int loopCnt;
 	uint16 lastTileData;
 	
+	/*
+	 * read tiles indices
+	 */
+
 	int rowIndex = 0;
 	if (isObject) {
 		loopCnt = numRows;
@@ -2687,7 +2690,7 @@
 	}
 	
 	/*
-	 * read z-order or mask??? 
+	 * read mask indices
 	 */
 	
 	if (dataWidth == 0 || numRows < 18) {
@@ -2728,6 +2731,7 @@
 	uint16* stripOffsets;
 
 	decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), room));
+	decodePCEngineMaskData(_vm->findResourceData(MKID_BE('ZP00'), room));
 
 	const byte* smap_ptr = _vm->findResourceData(MKID_BE('IM00'), room);
 	*smap_ptr++; // roomID
@@ -2795,9 +2799,11 @@
 	
 	free(_PCE.tiles);
 	_PCE.tiles = (byte*)calloc(_PCE.numTiles * 8 * 8, sizeof(byte));
+
 	for (int i = 0; i < _PCE.numTiles; ++i) {
 		tile = &_PCE.tiles[i * 64];
 		tilePtr = ptr + tileOffsets[i];
+
 		int index = 0;
 		while (index < 16) {
 			byte cmd = *tilePtr++;
@@ -2821,21 +2827,61 @@
 	free(tileOffsets);
 }
 
+void GdiPCEngine::decodePCEngineMaskData(const byte *ptr) {
+	const byte *maskPtr;
+	byte* mask;
+	uint16* maskOffsets;
+
+	if (!ptr) {
+		_PCE.numMasks = 0;
+		return;
+	}
+
+	readOffsetTable(ptr, &maskOffsets, &_PCE.numMasks);
+
+	free(_PCE.masks);
+	_PCE.masks = (byte*)malloc(_PCE.numMasks * 8 * sizeof(byte));
+
+	for (int i = 0; i < _PCE.numMasks; ++i) {
+		mask = &_PCE.masks[i * 8];
+		maskPtr = ptr + maskOffsets[i];
+
+		int index = 0;
+		while (index < 8) {
+			byte cmd = *maskPtr++;
+			int cnt = cmd & 0x1F;
+			if (cmd & 0x80) {
+				byte value;
+				if (cmd & 0x60)
+					value = (cmd & 0x40) ? 0x00 : 0xFF;
+				else
+					value = *maskPtr++;
+				for (int j = 0; j < cnt; ++j)
+					mask[index++] = ~value;
+			} else {
+				for (int j = 0; j < cnt; ++j)
+					mask[index++] = ~*maskPtr++;
+			}
+		}
+	}
+
+	free(maskOffsets);
+}
+
 void GdiPCEngine::drawStripPCEngine(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height) {
 	uint16 tileIdx;
 	byte *tile;
 	int paletteIdx, paletteOffset, paletteEntry;
 	height /= 8;
 
-	for (int i = 0; i < height; i++) {
-		tileIdx = (_objectMode ? _PCE.nametableObj : _PCE.nametable)[stripnr * height + i];
+	for (int y = 0; y < height; y++) {
+		tileIdx = (_objectMode ? _PCE.nametableObj : _PCE.nametable)[stripnr * height + y];
 		tile = &_PCE.tiles[tileIdx * 64];
-		paletteIdx = (_objectMode ? _PCE.colortableObj : _PCE.colortable)[stripnr * height + i];
+		paletteIdx = (_objectMode ? _PCE.colortableObj : _PCE.colortable)[stripnr * height + y];
 		paletteOffset = paletteIdx * 16;
 		for (int row = 0; row < 8; row++) {
 			for (int col = 0; col < 8; col++) {
 				paletteEntry = tile[row * 8 + col];
-				// TODO: handle transparency (paletteEntry == 0)
 				dst[col] = paletteOffset + paletteEntry;
 			}
 			dst += dstPitch;
@@ -2844,7 +2890,19 @@
 }
 
 void GdiPCEngine::drawStripPCEngineMask(byte *dst, int stripnr, int top, int height) const {
-	// TODO
+	uint16 maskIdx;
+	height /= 8;
+
+	for (int y = 0; y < height; y++) {
+		maskIdx = (_objectMode ? _PCE.masktableObj : _PCE.masktable)[stripnr * height + y];
+		for (int row = 0; row < 8; row++) {
+			if (_PCE.numMasks > 0)
+				*dst = _PCE.masks[maskIdx * 8 + row];
+			else
+				*dst = 0;
+			dst += _numStrips;
+		}
+	}
 }
 
 void GdiV1::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) {

Modified: scummvm/trunk/engines/scumm/gfx.h
===================================================================
--- scummvm/trunk/engines/scumm/gfx.h	2009-10-25 23:36:09 UTC (rev 45386)
+++ scummvm/trunk/engines/scumm/gfx.h	2009-10-26 02:45:26 UTC (rev 45387)
@@ -308,15 +308,17 @@
 		byte colortable[4096], colortableObj[512];
 		uint16 masktable[4096], masktableObj[512];
 		int  objX;
-		bool hasmask;
 		int numTiles;
+		int numMasks;
 		byte* tiles;
+		byte* masks;
 	} _PCE;
 
 protected:
 	void decodePCEngineGfx(const byte *room);
 	void decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint16 *masks, int dataWidth, int numRows, bool isObject);
 	void decodePCEngineTileData(const byte *ptr);
+	void decodePCEngineMaskData(const byte *ptr);
 	void decodePCEngineObject(const byte *ptr, int xpos, int ypos, int width, int height);
 
 	void drawStripPCEngine(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height);

Modified: scummvm/trunk/engines/scumm/resource.cpp
===================================================================
--- scummvm/trunk/engines/scumm/resource.cpp	2009-10-25 23:36:09 UTC (rev 45386)
+++ scummvm/trunk/engines/scumm/resource.cpp	2009-10-26 02:45:26 UTC (rev 45387)
@@ -1474,6 +1474,8 @@
 		return (0x5053);	// SP
 	case (MKID_BE('TILE')):
 		return (0x4C54);	// TL
+	case (MKID_BE('ZP00')):
+		return (0x505A);	// ZP
 	default:
 		return (0);
 	}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list