[Scummvm-cvs-logs] SF.net SVN: scummvm:[45304] scummvm/trunk

Kirben at users.sourceforge.net Kirben at users.sourceforge.net
Wed Oct 21 14:59:10 CEST 2009


Revision: 45304
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45304&view=rev
Author:   Kirben
Date:     2009-10-21 12:59:10 +0000 (Wed, 21 Oct 2009)

Log Message:
-----------
Add patch from Tobias, for graphic support (backgrounds/objects) 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/detection.cpp
    scummvm/trunk/engines/scumm/detection_tables.h
    scummvm/trunk/engines/scumm/gfx.cpp
    scummvm/trunk/engines/scumm/gfx.h
    scummvm/trunk/engines/scumm/palette.cpp
    scummvm/trunk/engines/scumm/resource.cpp
    scummvm/trunk/engines/scumm/scumm.cpp
    scummvm/trunk/engines/scumm/scumm.h
    scummvm/trunk/tools/credits.pl

Modified: scummvm/trunk/engines/scumm/costume.cpp
===================================================================
--- scummvm/trunk/engines/scumm/costume.cpp	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/costume.cpp	2009-10-21 12:59:10 UTC (rev 45304)
@@ -737,6 +737,10 @@
 	return 0;
 }
 
+byte PCEngineCostumeRenderer::drawLimb(const Actor *a, int limb) {
+	return 0;
+}
+
 byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
 	int i;
 	int code;
@@ -804,6 +808,19 @@
 	_loaded.loadCostume(costume);
 }
 
+void PCEngineCostumeRenderer::setPalette(uint16 *palette) {
+	// 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;
 	uint mask, j;
@@ -1024,6 +1041,48 @@
 	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-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/costume.h	2009-10-21 12:59:10 UTC (rev 45304)
@@ -71,6 +71,22 @@
 	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) {}
@@ -128,6 +144,21 @@
 	byte drawLimb(const Actor *a, int limb);
 };
 
+class PCEngineCostumeRenderer : public BaseCostumeRenderer {
+protected:
+	PCEngineCostumeLoader _loaded;
+
+public:
+	PCEngineCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
+
+	void setPalette(uint16 *palette);
+	void setFacing(const Actor *a);
+	void setCostume(int costume, int shadow);
+
+protected:
+	byte drawLimb(const Actor *a, int limb);
+};
+
 class C64CostumeRenderer : public BaseCostumeRenderer {
 protected:
 	C64CostumeLoader _loaded;

Modified: scummvm/trunk/engines/scumm/detection.cpp
===================================================================
--- scummvm/trunk/engines/scumm/detection.cpp	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/detection.cpp	2009-10-21 12:59:10 UTC (rev 45304)
@@ -923,7 +923,7 @@
 		*engine = new ScummEngine_v2(syst, res);
 		break;
 	case 3:
-		if ((res.game.features & GF_OLD256) || res.game.platform == Common::kPlatformPCEngine)
+		if (res.game.features & GF_OLD256)
 			*engine = new ScummEngine_v3(syst, res);
 		else
 			*engine = new ScummEngine_v3old(syst, res);

Modified: scummvm/trunk/engines/scumm/detection_tables.h
===================================================================
--- scummvm/trunk/engines/scumm/detection_tables.h	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/detection_tables.h	2009-10-21 12:59:10 UTC (rev 45304)
@@ -216,7 +216,7 @@
 
 	{"loom", "EGA",      "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_CMS | MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
 	{"loom", "No Adlib", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_CMS,                        0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
-	{"loom", "PC-Engine",    0, GID_LOOM, 3, 0, MDT_NONE,                         GF_AUDIOTRACKS, Common::kPlatformPCEngine, GUIO_NOSPEECH | GUIO_NOMIDI},
+	{"loom", "PC-Engine",    0, GID_LOOM, 3, 0, MDT_NONE,                         GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformPCEngine, GUIO_NOSPEECH | GUIO_NOMIDI},
 	{"loom", "FM-TOWNS",     0, GID_LOOM, 3, 0, MDT_TOWNS,                        GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI},
 	{"loom", "VGA",      "vga", GID_LOOM, 4, 0, MDT_NONE,                         GF_AUDIOTRACKS,             Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI},
 

Modified: scummvm/trunk/engines/scumm/gfx.cpp
===================================================================
--- scummvm/trunk/engines/scumm/gfx.cpp	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/gfx.cpp	2009-10-21 12:59:10 UTC (rev 45304)
@@ -219,6 +219,14 @@
 	memset(&_NES, 0, sizeof(_NES));
 }
 
+GdiPCEngine::GdiPCEngine(ScummEngine *vm) : Gdi(vm) {
+	memset(&_PCE, 0, sizeof(_PCE));
+}
+
+GdiPCEngine::~GdiPCEngine() {
+	free(_PCE.tiles);
+}
+
 GdiV1::GdiV1(ScummEngine *vm) : Gdi(vm) {
 	memset(&_C64, 0, sizeof(_C64));
 }
@@ -258,6 +266,10 @@
 	decodeNESGfx(roomptr);
 }
 
+void GdiPCEngine::roomChanged(byte *roomptr) {
+	decodePCEngineGfx(roomptr);
+}
+
 void GdiV1::roomChanged(byte *roomptr) {
 	for (int i = 0; i < 4; i++){
 		_C64.colors[i] = roomptr[6 + i];
@@ -1411,6 +1423,13 @@
 	}
 }
 
+void GdiPCEngine::prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
+					const int x, const int y, const int width, const int height,
+	                int stripnr, int numstrip) {
+	if (_objectMode) {
+		decodePCEngineObject(ptr, x - stripnr, y, width, height);
+	}
+}
 
 void GdiV2::prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
 					const int x, const int y, const int width, const int height,
@@ -1617,11 +1636,6 @@
 	// Check whether lights are turned on or not
 	const bool lightsOn = _vm->isLightOn();
 
-	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
-		// FIXME: Image format unknown
-		return;
-	}
-
 	if (_vm->_game.features & GF_SMALL_HEADER) {
 		smap_ptr = ptr;
 	} else if (_vm->_game.version == 8) {
@@ -1632,7 +1646,11 @@
 		assert(smap_ptr);
 	}
 
-	numzbuf = getZPlanes(ptr, zplane_list, false);
+	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
+		numzbuf = 0;
+	} else {
+		numzbuf = getZPlanes(ptr, zplane_list, false);
+	}
 
 	const byte *tmsk_ptr = NULL;
 	if (_vm->_game.heversion >= 72) {
@@ -1729,19 +1747,11 @@
 	// but if e.g. a savegame gets corrupted, we can easily get into
 	// trouble here. See also bug #795214.
 	int offset = -1, smapLen;
-	if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
-		// Length of offsets segment only
+	if (_vm->_game.features & GF_16COLOR) {
 		smapLen = READ_LE_UINT16(smap_ptr);
 		if (stripnr * 2 + 2 < smapLen) {
 			offset = READ_LE_UINT16(smap_ptr + stripnr * 2 + 2);
-			offset += stripnr * 2 + 3;
 		}
-		debug(0, "stripnr %d len %d offset %d", stripnr, smapLen, offset);
-	} else if (_vm->_game.features & GF_16COLOR) {
-		smapLen = READ_LE_UINT16(smap_ptr);
-		if (stripnr * 2 + 2 < smapLen) {
-			offset = READ_LE_UINT16(smap_ptr + stripnr * 2 + 2);
-		}
 		assertRange(0, offset, smapLen-1, "screen strip");
 	} else if (_vm->_game.features & GF_SMALL_HEADER) {
 		smapLen = READ_LE_UINT32(smap_ptr);
@@ -1766,6 +1776,13 @@
 	return false;
 }
 
+bool GdiPCEngine::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height,
+					int stripnr, const byte *smap_ptr) {
+	byte *mask_ptr = getMaskBuffer(x, y, 1);
+	drawStripPCEngine(dstPtr, mask_ptr, vs->pitch, stripnr, y, height);
+	return false;
+}
+
 bool GdiV1::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height,
 					int stripnr, const byte *smap_ptr) {
 	if (_objectMode)
@@ -1865,6 +1882,13 @@
 	drawStripNESMask(mask_ptr, stripnr, y, height);
 }
 
+void GdiPCEngine::decodeMask(int x, int y, const int width, const int height,
+	                int stripnr, int numzbuf, const byte *zplane_list[9],
+	                bool transpStrip, byte flag, const byte *tmsk_ptr) {
+	byte *mask_ptr = getMaskBuffer(x, y, 1);
+	drawStripPCEngineMask(mask_ptr, stripnr, y, height);
+}
+
 void GdiV1::decodeMask(int x, int y, const int width, const int height,
 	                int stripnr, int numzbuf, const byte *zplane_list[9],
 	                bool transpStrip, byte flag, const byte *tmsk_ptr) {
@@ -2567,6 +2591,264 @@
 	}
 }
 
+void readOffsetTable(const byte *ptr, uint16 **table, int *count) {
+	int pos = 0;
+	*count = READ_LE_UINT16(ptr) / 2 + 1;
+	*table = (uint16*)malloc(*count * sizeof(uint16));
+	for (int i = 0; i < *count; i++) {
+		(*table)[i] = READ_LE_UINT16(ptr + pos) + pos + 2;
+		pos += 2;
+	}	
+}
+
+void decodeTileColor(byte cmd, byte *colors, int *rowIndex, int numRows) {
+	colors[(*rowIndex)++] = ((cmd) >> 4) & 0xF;
+	if (*rowIndex < numRows)
+		colors[(*rowIndex)++] = (cmd) & 0xF;
+}
+
+void GdiPCEngine::decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint16 *masks, int dataWidth, int numRows, bool isObject) {
+	int loopCnt;
+	uint16 lastTileData;
+	
+	int rowIndex = 0;
+	if (isObject) {
+		loopCnt = numRows;
+	} else {
+		tiles[rowIndex++] = 0;
+		tiles[numRows - 1] = 0;
+		loopCnt = numRows - 1;
+	}
+	
+	while (true) {
+		uint16 cmd = READ_LE_UINT16(ptr);
+		ptr += 2;
+		if (cmd & 0x8000) {
+			tiles[rowIndex - 1] = cmd  & 0x0FFF;
+		} else if (cmd & 0x4000) {
+			tiles[numRows - 1] = cmd & 0x0FFF;		
+		} else {
+			tiles[rowIndex++] = cmd;
+			lastTileData = cmd;
+			break;
+		}
+	}	
+	
+	while (rowIndex < loopCnt) {
+		byte cmd = *ptr++;
+		int cnt = cmd & 0x1F;
+		
+		if (cmd & 0x80) {
+			for (int i = 0; i < cnt; ++i) {
+				tiles[rowIndex++] = lastTileData;
+			}			
+		} else if (cmd & 0x40) {
+			for (int i = 0; i < cnt; ++i) {
+				++lastTileData;
+				tiles[rowIndex++] = lastTileData;
+			}						
+		} else {
+			for (int i = 0; i < cnt; ++i) {
+				lastTileData = READ_LE_UINT16(ptr);
+				ptr += 2;
+				tiles[rowIndex++] = lastTileData;
+			}
+		}
+	}
+
+	/*
+	 * read palette data
+	 */
+	
+	rowIndex = 0;		
+	byte cmd = *ptr++;
+	if (cmd == 0xFE) {
+		while (rowIndex < numRows) {
+			decodeTileColor(*ptr++, colors, &rowIndex, numRows);
+		}
+	} else {
+		byte lastCmd = cmd;
+		decodeTileColor(cmd, colors, &rowIndex, numRows);
+		while (rowIndex < numRows) {
+			cmd = *ptr++;
+			int cnt = cmd & 0x1F;
+			if (cmd & 0x80) {
+				for (int j = 0; j < cnt; ++j) {
+					decodeTileColor(lastCmd, colors, &rowIndex, numRows);
+				}
+			} else {
+				for (int j = 0; j < cnt; ++j) {
+					cmd = *ptr++;
+					decodeTileColor(cmd, colors, &rowIndex, numRows);
+				}
+				lastCmd = cmd;
+			}
+		}
+	}
+	
+	/*
+	 * read z-order or mask??? 
+	 */
+	
+	if (dataWidth == 0 || numRows < 18) {
+		return;
+	}
+	
+	rowIndex = 0;
+	while (rowIndex < numRows) {
+		cmd = *ptr++;
+		int cnt = cmd & 0x1F;
+		if (cmd & 0x80) {
+			uint16 value;
+			if (cmd & 0x60) {
+				value = (cmd & 0x40) ? 0 : 0xFF;
+			} else if (dataWidth == 1) {
+				value = *ptr++;
+			} else {
+				value = READ_LE_UINT16(ptr);
+				ptr += 2;
+			}
+			for (int i = 0; i < cnt; ++i) {
+				masks[rowIndex++] = value;
+			}
+		} else {
+			for (int i = 0; i < cnt; ++i) {
+				if (dataWidth == 1) {
+					masks[rowIndex++] = *ptr++;
+				} else {
+					masks[rowIndex++] = READ_LE_UINT16(ptr);
+					ptr += 2;
+				}
+			}				
+		}
+	}
+}
+
+void GdiPCEngine::decodePCEngineGfx(const byte *room) {
+	uint16* stripOffsets;
+
+	decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), room));
+
+	const byte* smap_ptr = _vm->findResourceData(MKID_BE('IM00'), room);
+	*smap_ptr++; // roomID
+	int numStrips = *smap_ptr++;
+	int numRows = *smap_ptr++;
+	int dataWidth = *smap_ptr++;
+	*smap_ptr++; // unknown
+	
+	memset(_PCE.nametable, 0, sizeof(_PCE.nametable));
+	memset(_PCE.colortable, 0, sizeof(_PCE.colortable));
+	readOffsetTable(smap_ptr, &stripOffsets, &numStrips);
+	for (int i = 0; i < numStrips; ++i) {
+		const byte *tilePtr = smap_ptr + stripOffsets[i];		
+		decodeStrip(tilePtr, 
+			&_PCE.nametable[i * numRows], 
+			&_PCE.colortable[i * numRows],
+			&_PCE.masktable[i * numRows],
+			dataWidth,
+			numRows,
+			false);
+	}
+	free(stripOffsets);
+}
+
+void GdiPCEngine::decodePCEngineObject(const byte *ptr, int xpos, int ypos, int width, int height) {
+	uint16 *stripOffsets;
+	int numStrips;
+	int numRows = height / 8;
+
+	memset(_PCE.nametableObj, 0, sizeof(_PCE.nametableObj));
+	memset(_PCE.colortableObj, 0, sizeof(_PCE.colortableObj));
+	readOffsetTable(ptr, &stripOffsets, &numStrips);
+	for (int i = 0; i < numStrips; ++i) {
+		const byte *tilePtr = ptr + stripOffsets[i];
+		decodeStrip(tilePtr, 
+			&_PCE.nametableObj[i * numRows], 
+			&_PCE.colortableObj[i * numRows], 
+			&_PCE.masktableObj[i * numRows], 
+			0, // is this true?
+			numRows,
+			true);
+	}
+	free(stripOffsets);
+}
+
+void setTileData(byte *tile, int index, byte byte0, byte byte1) {
+	int row = index % 8;
+	int plane = (index / 8) * 2;
+	int plane02Bit, plane13Bit;
+	for (int col = 0; col < 8; ++col) {
+		plane02Bit = (byte0 >> (7-col)) & 0x1; // plane=0: bit0, plane=2: bit2
+		plane13Bit = (byte1 >> (7-col)) & 0x1; // plane=0: bit1, plane=2: bit3
+		tile[row * 8 + col] |= plane02Bit << (plane + 0);
+		tile[row * 8 + col] |= plane13Bit << (plane + 1);		
+	}
+}
+
+void GdiPCEngine::decodePCEngineTileData(const byte *ptr) {
+	const byte *tilePtr;
+	byte* tile;
+	uint16* tileOffsets;
+	byte byte0, byte1;
+
+	readOffsetTable(ptr, &tileOffsets, &_PCE.numTiles);
+	
+	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++;
+			byte cnt = (cmd & 0x0F) + 1;
+			if (cmd & 0x80) {
+				byte0 = (cmd & 0x10) ? 0 : *tilePtr++;
+				byte1 = (cmd & 0x40) ? 0 : *tilePtr++;
+				while (cnt--) {
+					setTileData(tile, index++, byte0, byte1);
+				}
+			} else {
+				while (cnt--) {
+					byte0 = (cmd & 0x10) ? 0 : *tilePtr++;
+					byte1 = (cmd & 0x40) ? 0 : *tilePtr++;
+					setTileData(tile, index++, byte0, byte1);
+				}
+			}
+		}
+	}
+
+	free(tileOffsets);
+}
+
+// 52, 1: 2 532
+
+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];
+		tile = &_PCE.tiles[tileIdx * 64];
+		paletteIdx = (_objectMode ? _PCE.colortableObj : _PCE.colortable)[stripnr * height + i];
+		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;
+		}
+	}
+}
+
+void GdiPCEngine::drawStripPCEngineMask(byte *dst, int stripnr, int top, int height) const {
+	// TODO
+}
+
 void GdiV1::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) {
 	int charIdx;
 	height /= 8;

Modified: scummvm/trunk/engines/scumm/gfx.h
===================================================================
--- scummvm/trunk/engines/scumm/gfx.h	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/gfx.h	2009-10-21 12:59:10 UTC (rev 45304)
@@ -301,6 +301,47 @@
 	virtual void roomChanged(byte *roomptr);
 };
 
+class GdiPCEngine : public Gdi {
+protected:
+	struct {
+		uint16 nametable[4096], nametableObj[512];
+		byte colortable[4096], colortableObj[512];
+		byte attributes[64], attributesObj[64];
+		uint16 masktable[4096], masktableObj[512];
+		int  objX;
+		bool hasmask;
+		int numTiles;
+		byte* tiles;
+	} _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 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);
+	void drawStripPCEngineMask(byte *dst, int stripnr, int top, int height) const;
+
+	virtual bool drawStrip(byte *dstPtr, VirtScreen *vs,
+					int x, int y, const int width, const int height,
+					int stripnr, const byte *smap_ptr);
+
+	virtual void decodeMask(int x, int y, const int width, const int height,
+	                int stripnr, int numzbuf, const byte *zplane_list[9],
+	                bool transpStrip, byte flag, const byte *tmsk_ptr);
+
+	virtual void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
+					const int x, const int y, const int width, const int height,
+	                int stripnr, int numstrip);
+
+public:
+	GdiPCEngine(ScummEngine *vm);
+	~GdiPCEngine();
+
+	virtual void roomChanged(byte *roomptr);
+};
+
 class GdiV1 : public Gdi {
 protected:
 	/** Render settings which are specific to the C64 graphic decoders. */

Modified: scummvm/trunk/engines/scumm/palette.cpp
===================================================================
--- scummvm/trunk/engines/scumm/palette.cpp	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/palette.cpp	2009-10-21 12:59:10 UTC (rev 45304)
@@ -202,6 +202,67 @@
 		setPalColor( index, ptr[0], ptr[1], ptr[2]);
 }
 
+void colorPCEToRGB(uint16 color, byte *r, byte *g, byte *b) {
+	// 3 bits for each color component: 0xgggrrrbbb
+	*b = ((color)      & 0x7) << 5;
+	*r = ((color >> 3) & 0x7) << 5;
+	*g = ((color >> 6) & 0x7) << 5;
+}
+
+void readPalette(const byte **ptr, byte **dest, int numEntries) {
+	byte r, g, b;
+	byte msbs = 0;
+
+	for (int i = 0; i < numEntries; ++i) {
+		if (i % 8 == 0) {
+			// byte contains MSBs (bit 8) for the next 8 bytes
+			msbs = *(*ptr)++;
+		}
+		uint16 msb = (msbs & 0x1) << 8;
+		uint16 paletteEntry = msb | *(*ptr)++;
+		colorPCEToRGB(paletteEntry, &r, &g, &b);
+		*(*dest)++ = r;
+		*(*dest)++ = g;
+		*(*dest)++ = b;
+		msbs >>= 1;
+	}
+}
+
+void ScummEngine::setPCEPaletteFromPtr(const byte *ptr) {
+	byte *dest;
+	byte bgSpriteR, bgSpriteG, bgSpriteB;
+
+	int paletteOffset = *ptr++;
+	int numPalettes = *ptr++;	
+
+	int firstIndex = paletteOffset * 16;
+	int numcolor = numPalettes * 16;
+
+	// the only color over which a background sprite 
+	// (bit 7 of the sprite attributes) will be visible
+	colorPCEToRGB(READ_LE_UINT16(ptr), &bgSpriteR, &bgSpriteG, &bgSpriteB);
+	ptr += 2;
+
+	dest = _currentPalette + firstIndex * 3;
+
+	for (int i = 0; i < numPalettes; ++i) {
+		// entry 0
+		*dest++ = bgSpriteR;
+		*dest++ = bgSpriteG;
+		*dest++ = bgSpriteB;
+
+		// entry 1 - 14
+		readPalette(&ptr, &dest, 14);
+
+		// entry 15: DEFAULT_PALETTE[var3AE3];
+		*dest++ = 6 << 5;
+		*dest++ = 6 << 5;
+		*dest++ = 6 << 5;
+	}
+
+	setDirtyColors(firstIndex, firstIndex + numcolor - 1);
+}
+
 void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) {
 	int firstIndex = 0;
 	int i;
@@ -870,7 +931,11 @@
 
 	_curPalIndex = palindex;
 	pals = getPalettePtr(_curPalIndex, _roomResource);
-	setPaletteFromPtr(pals);
+	if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) {
+		setPCEPaletteFromPtr(pals);
+	} else {
+		setPaletteFromPtr(pals);
+	}
 }
 
 void ScummEngine::setRoomPalette(int palindex, int room) {

Modified: scummvm/trunk/engines/scumm/resource.cpp
===================================================================
--- scummvm/trunk/engines/scumm/resource.cpp	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/resource.cpp	2009-10-21 12:59:10 UTC (rev 45304)
@@ -1472,6 +1472,8 @@
 		return (0x4343);	// CC
 	case (MKID_BE('EPAL')):
 		return (0x5053);	// SP
+	case (MKID_BE('TILE')):
+		return (0x4C54);	// TL
 	default:
 		return (0);
 	}

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2009-10-21 12:59:10 UTC (rev 45304)
@@ -115,6 +115,8 @@
 		_gdi = new Gdi16Bit(this);
 	} else if (_game.platform == Common::kPlatformNES) {
 		_gdi = new GdiNES(this);
+	} else if (_game.platform == Common::kPlatformPCEngine) {
+		_gdi = new GdiPCEngine(this);
 	} else if (_game.version <= 1) {
 		_gdi = new GdiV1(this);
 	} else if (_game.version == 2) {
@@ -613,7 +615,7 @@
 	// All "classic" games (V5 and older) encrypted their data files
 	// with exception of the GF_OLD256 games and the PC-Engine version
 	// of Loom.
-	if (!(_game.features & GF_OLD256) && _game.platform != Common::kPlatformPCEngine)
+	if (!(_game.features & GF_OLD256))
 		_game.features |= GF_USE_KEY;
 
 	resetCursors();
@@ -1280,6 +1282,9 @@
 	} else if (_game.platform == Common::kPlatformNES) {
 		_costumeRenderer = new NESCostumeRenderer(this);
 		_costumeLoader = new NESCostumeLoader(this);
+	} else if (_game.platform == Common::kPlatformPCEngine) {
+		_costumeRenderer = new PCEngineCostumeRenderer(this);
+		_costumeLoader = new PCEngineCostumeLoader(this);
 	} else {
 		_costumeRenderer = new ClassicCostumeRenderer(this);
 		_costumeLoader = new ClassicCostumeLoader(this);

Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/engines/scumm/scumm.h	2009-10-21 12:59:10 UTC (rev 45304)
@@ -1034,6 +1034,7 @@
 
 	void setCurrentPalette(int pal);
 	void setRoomPalette(int pal, int room);
+	void setPCEPaletteFromPtr(const byte *ptr);
 	virtual void setPaletteFromPtr(const byte *ptr, int numcolor = -1);
 	virtual void setPalColor(int index, int r, int g, int b);
 	void setDirtyColors(int min, int max);

Modified: scummvm/trunk/tools/credits.pl
===================================================================
--- scummvm/trunk/tools/credits.pl	2009-10-21 10:00:08 UTC (rev 45303)
+++ scummvm/trunk/tools/credits.pl	2009-10-21 12:59:10 UTC (rev 45304)
@@ -827,6 +827,7 @@
 	  begin_persons();
 		  add_person("Ori Avtalion", "salty-horse", "Subtitle control options in the GUI; BASS GUI fixes");
 		  add_person("Stuart Caie", "", "Decoders for Amiga and AtariST data files (AGOS engine)");
+		  add_person("Tobias Gunkel", "hennymcc", "Graphic support for PCE version of Loom");
 		  add_person("Paolo Costabel", "", "PSP port contributions");
 		  add_person("Thierry Crozat", "criezy", "Support for Broken Sword 1 Macintosh version");
 		  add_person("Martin Doucha", "next_ghost", "CinE engine objectification");


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