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

Kirben at users.sourceforge.net Kirben at users.sourceforge.net
Sun Oct 25 15:20:47 CET 2009


Revision: 45370
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45370&view=rev
Author:   Kirben
Date:     2009-10-25 14:20:47 +0000 (Sun, 25 Oct 2009)

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

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

Modified: scummvm/trunk/engines/scumm/base-costume.h
===================================================================
--- scummvm/trunk/engines/scumm/base-costume.h	2009-10-25 08:46:56 UTC (rev 45369)
+++ scummvm/trunk/engines/scumm/base-costume.h	2009-10-25 14:20:47 UTC (rev 45370)
@@ -103,6 +103,8 @@
 	// whether to draw the actor mirrored
 	bool _mirror;
 
+	int _numBlocks;
+
 	// width and height of cel to decode
 	int _width, _height;
 

Modified: scummvm/trunk/engines/scumm/costume.cpp
===================================================================
--- scummvm/trunk/engines/scumm/costume.cpp	2009-10-25 08:46:56 UTC (rev 45369)
+++ scummvm/trunk/engines/scumm/costume.cpp	2009-10-25 14:20:47 UTC (rev 45370)
@@ -86,13 +86,9 @@
 	int step;
 	Codec1 v1;
 
-	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
-		// FIXME: Unknown costume format
-		return 0;
-	}
-
 	const int scaletableSize = 128;
 	const bool newAmiCost = (_vm->_game.version == 5) && (_vm->_game.platform == Common::kPlatformAmiga);
+	const bool pcEngCost = (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine);
 
 	v1.scaletable = smallCostumeScaleTable;
 
@@ -242,7 +238,7 @@
 		if (!use_scaling)
 			skip = -v1.x;
 		if (skip > 0) {
-			if (!newAmiCost && _loaded._format != 0x57) {
+			if (!newAmiCost && !pcEngCost && _loaded._format != 0x57) {
 				v1.skip_width -= skip;
 				codec1_ignorePakCols(v1, skip);
 				v1.x = 0;
@@ -259,7 +255,7 @@
 		if (!use_scaling)
 			skip = rect.right - _out.w;
 		if (skip > 0) {
-			if (!newAmiCost && _loaded._format != 0x57) {
+			if (!newAmiCost && !pcEngCost && _loaded._format != 0x57) {
 				v1.skip_width -= skip;
 				codec1_ignorePakCols(v1, skip);
 				v1.x = _out.w - 1;
@@ -311,6 +307,8 @@
 		procC64(v1, _actorID);
 	} else if (newAmiCost)
 		proc3_ami(v1);
+	else if (pcEngCost)
+		procPCEngine(v1);
 	else
 		proc3(v1);
 
@@ -583,15 +581,92 @@
 	} while (1);
 }
 
+void PCESetCostumeData(byte block[16][16], int index, byte value) {
+	int row = (index % 16);
+	int plane = (index / 16) % 4;
+	int colOffset = (index < 64) ? 8 : 0;
+	for (int i = 0; i < 8; ++i) {
+		int bit = (value >> (7-i)) & 0x1;
+		block[row][i + colOffset] |= bit << plane;
+	}
+}
+
+void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) {
+	const byte *mask, *src;
+	byte *dst;
+	byte maskbit;
+	uint width, height;
+	byte scaleIndexY;
+	int vertShift;
+
+	byte block[16][16];
+
+	src = _srcptr;
+	width = _width / 16;
+	height = _height / 16;
+
+	if (_numBlocks == 0)
+		return;
+
+	scaleIndexY = _scaleIndexY;
+	maskbit = revBitMask(v1.x & 7);
+	mask = v1.mask_ptr + v1.x / 8;
+
+	for (uint x = 0; x < width; ++x) {
+		dst = v1.destptr + 16 * x * _out.bytesPerPixel;
+		for (uint y = 0; y < height; ++y) {
+			vertShift = *src++;
+			if (vertShift == 0xFF) {
+				dst += 16 * _out.pitch;
+				continue;
+			} else {
+				dst += vertShift * _out.pitch;
+			}
+
+			memset(block, 0, sizeof(block));
+
+			int index = 0;
+			while (index < 128) {
+				byte cmd = *src++;
+				int cnt = (cmd & 0x3F) + 1;
+				if (!(cmd & 0xC0)) {
+					for (int i = 0; i < cnt; ++i)
+						PCESetCostumeData(block, index++, 0);
+				} else if (cmd & 0x80) {
+					int value = *src++;
+					for (int i = 0; i < cnt; ++i)
+						PCESetCostumeData(block, index++, value);
+				} else {
+					for (int i = 0; i < cnt; ++i)
+						PCESetCostumeData(block, index++, *src++);
+				}
+			}
+			if (index != 128) {
+				printf("%d\n", index);
+			}
+
+			for (int row = 0; row < 16; ++row) {
+				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 += _out.pitch;
+			}
+		}
+	}
+}
+
 void ClassicCostumeLoader::loadCostume(int id) {
 	_id = id;
 	byte *ptr = _vm->getResourceAddress(rtCostume, id);
 
-	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
-		// FIXME: Unknown costume format
-		return;
-	}
-
 	if (_vm->_game.version >= 6)
 		ptr += 8;
 	else if (_vm->_game.features & GF_OLD_BUNDLE)
@@ -607,6 +682,17 @@
 	_format = ptr[7] & 0x7F;
 	_mirror = (ptr[7] & 0x80) != 0;
 	_palette = ptr + 8;
+
+	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
+		_numColors = 16;
+
+		ptr += 8 + 17;
+		_animCmds = READ_LE_UINT16(ptr) + ptr + 2;
+		_frameOffsets = ptr + 2;
+		_dataOffsets = ptr + 34;
+		return;
+	}
+
 	switch (_format) {
 	case 0x57:				// Only used in V1 games
 		_numColors = 0;
@@ -737,8 +823,49 @@
 	return 0;
 }
 
+#define PCE_SIGNED(a) (((a) & 0x80) ? -((a) & 0x7F) : (a))
+
 byte PCEngineCostumeRenderer::drawLimb(const Actor *a, int limb) {
-	// TODO
+	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;
 }
 
@@ -813,17 +940,9 @@
 	// TODO
 }
 
-void PCEngineCostumeRenderer::setFacing(const Actor *a) {
-	// TODO
-	//_mirror = newDirToOldDir(a->getFacing()) != 0 || _loaded._mirror;
-}
-
-void PCEngineCostumeRenderer::setCostume(int costume, int shadow) {
-	_loaded.loadCostume(costume);
-}
-
 void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
 	const byte *r;
+	const byte *baseptr;
 	uint mask, j;
 	int i;
 	byte extra, cmd;
@@ -837,9 +956,13 @@
 		return;
 	}
 
-	r = _baseptr + READ_LE_UINT16(_dataOffsets + anim * 2);
+	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
+		baseptr = _dataOffsets + anim * 2 + 2;
+	else
+		baseptr = _baseptr;
 
-	if (r == _baseptr) {
+	r = baseptr + READ_LE_UINT16(_dataOffsets + anim * 2);
+	if (r == baseptr) {
 		return;
 	}
 
@@ -852,7 +975,9 @@
 	i = 0;
 	do {
 		if (mask & 0x8000) {
-			if (_vm->_game.version <= 3) {
+			if ((_vm->_game.version <= 3) &&
+				!(_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine))
+			{
 				j = *r++;
 
 				if (j == 0xFF)
@@ -1042,48 +1167,6 @@
 	return (a->_cost.curpos[slot] != oldframe);
 }
 
-void PCEngineCostumeLoader::loadCostume(int id) {
-	_id = id;
-	_baseptr = _vm->getResourceAddress(rtCostume, id);
-	_dataOffsets = _baseptr + 2;
-	_numAnim = 0x17;
-}
-
-void PCEngineCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
-	int anim;
-
-	loadCostume(a->_costume);
-
-	anim = 4 * frame + newDirToOldDir(a->getFacing());
-
-	if (anim > _numAnim) {
-		return;
-	}
-
-	a->_cost.curpos[0] = 0;
-	a->_cost.start[0] = 0;
-	a->_cost.end[0] = _dataOffsets[2 * anim + 1];
-	a->_cost.frame[0] = frame;
-}
-
-byte PCEngineCostumeLoader::increaseAnims(Actor *a) {
-	int i;
-	byte r = 0;
-
-	for (i = 0; i != 16; i++) {
-		if (a->_cost.curpos[i] != 0xFFFF)
-			r += increaseAnim(a, i);
-	}
-	return r;
-}
-
-byte PCEngineCostumeLoader::increaseAnim(Actor *a, int slot) {
-	int oldframe = a->_cost.curpos[slot]++;
-	if (a->_cost.curpos[slot] >= a->_cost.end[slot])
-		a->_cost.curpos[slot] = a->_cost.start[slot];
-	return (a->_cost.curpos[slot] != oldframe);
-}
-
 static const byte actorColorsMMC64[25] = {
 	0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7
 };

Modified: scummvm/trunk/engines/scumm/costume.h
===================================================================
--- scummvm/trunk/engines/scumm/costume.h	2009-10-25 08:46:56 UTC (rev 45369)
+++ scummvm/trunk/engines/scumm/costume.h	2009-10-25 14:20:47 UTC (rev 45370)
@@ -71,22 +71,6 @@
 	byte increaseAnim(Actor *a, int slot);
 };
 
-class PCEngineCostumeLoader : public BaseCostumeLoader {
-public:
-	int _id;
-	const byte *_baseptr;
-	const byte *_dataOffsets;
-	byte _numAnim;
-
-	PCEngineCostumeLoader(ScummEngine *vm) : BaseCostumeLoader(vm) {}
-	void loadCostume(int id);
-	void costumeDecodeData(Actor *a, int frame, uint usemask);
-	byte increaseAnims(Actor *a);
-
-protected:
-	byte increaseAnim(Actor *a, int slot);
-};
-
 class C64CostumeLoader : public ClassicCostumeLoader {
 public:
 	C64CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {}
@@ -126,6 +110,8 @@
 
 	void procC64(Codec1 &v1, int actor);
 
+	void procPCEngine(Codec1 &v1);
+
 	byte mainRoutine(int xmoveCur, int ymoveCur);
 };
 
@@ -144,16 +130,11 @@
 	byte drawLimb(const Actor *a, int limb);
 };
 
-class PCEngineCostumeRenderer : public BaseCostumeRenderer {
-protected:
-	PCEngineCostumeLoader _loaded;
-
+class PCEngineCostumeRenderer : public ClassicCostumeRenderer {
 public:
-	PCEngineCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
+	PCEngineCostumeRenderer(ScummEngine *vm) : ClassicCostumeRenderer(vm) {}
 
 	void setPalette(uint16 *palette);
-	void setFacing(const Actor *a);
-	void setCostume(int costume, int shadow);
 
 protected:
 	byte drawLimb(const Actor *a, int limb);

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2009-10-25 08:46:56 UTC (rev 45369)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2009-10-25 14:20:47 UTC (rev 45370)
@@ -1284,7 +1284,7 @@
 		_costumeLoader = new NESCostumeLoader(this);
 	} else if (_game.platform == Common::kPlatformPCEngine) {
 		_costumeRenderer = new PCEngineCostumeRenderer(this);
-		_costumeLoader = new PCEngineCostumeLoader(this);
+		_costumeLoader = new ClassicCostumeLoader(this);
 	} else {
 		_costumeRenderer = new ClassicCostumeRenderer(this);
 		_costumeLoader = new ClassicCostumeLoader(this);


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