[Scummvm-cvs-logs] SF.net SVN: scummvm:[40606] scummvm/trunk/engines/tinsel/graphics.cpp

Hkz at users.sourceforge.net Hkz at users.sourceforge.net
Fri May 15 14:46:53 CEST 2009


Revision: 40606
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40606&view=rev
Author:   Hkz
Date:     2009-05-15 12:46:53 +0000 (Fri, 15 May 2009)

Log Message:
-----------
tinsel: fix drawing of some sprites, cursor and fonts in discworld PSX, palette is still wrong though

Modified Paths:
--------------
    scummvm/trunk/engines/tinsel/graphics.cpp

Modified: scummvm/trunk/engines/tinsel/graphics.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/graphics.cpp	2009-05-15 12:41:27 UTC (rev 40605)
+++ scummvm/trunk/engines/tinsel/graphics.cpp	2009-05-15 12:46:53 UTC (rev 40606)
@@ -30,6 +30,7 @@
 #include "tinsel/palette.h"
 #include "tinsel/scene.h"
 #include "tinsel/tinsel.h"
+#include "tinsel/scn.h"
 
 namespace Tinsel {
 
@@ -46,10 +47,10 @@
 
 /**
  * PSX Block list unwinder.
- * Chunk type 0x3 in PSX version of Discworld 1 is compressed, thus we need to decompress
- * it before passing data to drawing functions
+ * Chunk type 0x0003 (CHUNK_CHARPTR) in PSX version of DW 1 & 2 is compressed (original code
+ * calls the compression PJCRLE), thus we need to decompress it before passing data to drawing functions
  */
-uint8* psxBlockListUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
+uint8* psxPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
 	uint32 remainingBlocks = 0;
 
 	uint16 compressionType = 0; // Kind of decompression to apply 
@@ -71,14 +72,6 @@
 	dstIdx = destinationBuffer;
 	remainingBlocks = (imageWidth * imageHeight) / 16;
 
-	controlData = READ_LE_UINT16(srcIdx);
-
-	// Get to index data 
-	if ( (controlData & 0xff) == 0x88) // These images go straight to compressed index data
-		srcIdx += 2;		
-	else  // In this case we have to skip psx CLUT before getting to data
-		srcIdx += 32;
-
 	while (remainingBlocks) { // Repeat until all blocks are decompressed
 		if (!controlBits) {
 			controlData = READ_LE_UINT16(srcIdx);
@@ -223,7 +216,7 @@
  * Straight rendering with transparency support, PSX variant supporting also 4-BIT clut data
  * TODO: finish supporting 4-bit data
  */
-static void PsxWrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool applyClipping, bool fourBitClut, uint32 palStart) {
+static void PsxWrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool applyClipping, bool fourBitClut, uint32 psxSkipBytes, uint32 palStart) {
 	// Set up the offset between destination blocks
 	int rightClip = applyClipping ? pObj->rightClip : 0;
 	Common::Rect boxBounds;
@@ -289,9 +282,9 @@
 				// In case we have a 4-bit CLUT image, blocks are 2x4, then expanded into 4x4
 				const uint8 *p;
 				if (fourBitClut)
-					p = (uint8 *)pObj->charBase + (indexVal << 3);
+					p = (uint8 *)pObj->charBase + psxSkipBytes + (indexVal << 3);
 				else
-					p = (uint8 *)pObj->charBase + (indexVal << 4);
+					p = (uint8 *)pObj->charBase + psxSkipBytes + (indexVal << 4);
 
 				p += boxBounds.top * (fourBitClut ? sizeof(uint16) : sizeof(uint32));
 				for (int yp = boxBounds.top; yp <= boxBounds.bottom; ++yp, p += (fourBitClut ? sizeof(uint16) : sizeof(uint32))) {
@@ -752,7 +745,9 @@
 	uint8 *srcPtr = NULL;
 	uint8 *destPtr;
 
-	bool psxFourBitClut = false; // Used for PSX version, to check if image is in 4-bit CLUT mode
+	bool psxFourBitClut; // Used by Tinsel PSX, true if an image using a 4bit CLUT is rendered
+	bool psxRLEindex; // Used by Tinsel PSX, true if an image is using PJCRLE compressed indexes
+	uint32 psxSkipBytes; // Used by Tinsel PSX, number of bytes to skip before counting indexes for image tiles
 
 	if ((pObj->width <= 0) || (pObj->height <= 0))
 		// Empty image, so return immediately
@@ -770,11 +765,51 @@
 			srcPtr = p + (pObj->hBits & OFFSETMASK);
 			pObj->charBase = (char *)p + READ_LE_UINT32(p + 0x10);
 			pObj->transOffset = READ_LE_UINT32(p + 0x14);
-	
+
 			// Decompress block indexes for Discworld PSX
 			if (TinselV1PSX) {
-				psxFourBitClut = (READ_LE_UINT16(srcPtr) != 0xCC88) ? true : false;
-				srcPtr = psxBlockListUnwinder(pObj->width, pObj->height, srcPtr);
+				uint8 paletteType = *(srcPtr); // if 0x88 we are using an 8bit palette type, if 0x44 we are using a 4 bit PSX CLUT
+				uint8 indexType = *(srcPtr + 1); // if 0xCC indexes for this image are compressed with PCJRLE, if 0xDD indexes are not compressed
+			
+				switch (paletteType) {
+					case 0x88: // Normal 8-bit palette
+						psxFourBitClut = false; 
+						psxSkipBytes = 0;
+						switch (indexType) {
+							case 0xDD: // Normal uncompressed indexes
+								psxRLEindex = false;
+								srcPtr += sizeof(uint16); // Get to the beginning of index data
+								break;
+							case 0xCC: // PJCRLE compressed indexes
+								psxRLEindex = true;
+								srcPtr = psxPJCRLEUnwinder(pObj->width, pObj->height, srcPtr + sizeof(uint16));
+								break;
+							default:
+								error("Unknown PSX index type 0x%.2X", indexType);
+								break;
+						}
+						break;
+					case 0x44: // PSX 4-bit CLUT
+						psxFourBitClut = true;
+						psxSkipBytes = READ_LE_UINT32(p + sizeof(uint32) * 5) << 4; // Fetch number of bytes we have to skip
+						switch (indexType) {
+							case 0xDD: // Normal uncompressed indexes
+								psxRLEindex = false;
+								srcPtr += sizeof(uint16) * 17; // Skip image type and clut, and get to beginning of index data
+								break;
+							case 0xCC: // PJCRLE compressed indexes
+								psxRLEindex = true;
+								srcPtr = psxPJCRLEUnwinder(pObj->width, pObj->height, srcPtr + sizeof(uint16) * 17);
+								break;
+							default:
+								error("Unknown PSX index type 0x%.2X", indexType);
+								break;
+						}
+						break;
+					default:
+						error("Unknown PSX palette type 0x%.2X", paletteType);
+						break;
+				}
 			}
 		}
 
@@ -842,7 +877,7 @@
 		case 0x08:
 		case 0x41:
 		case 0x48:
-			PsxWrtNonZero(pObj, srcPtr, destPtr, typeId >= 0x40, psxFourBitClut, pObj->pPal->posInDAC);
+			PsxWrtNonZero(pObj, srcPtr, destPtr, typeId >= 0x40, psxFourBitClut, psxSkipBytes, pObj->pPal->posInDAC);
 			break;
 
 		case 0x04:
@@ -907,7 +942,7 @@
 
 	// If we were using Discworld PSX, free the memory allocated
 	// for decompressed block indexes.
-	if (TinselV1PSX)
+	if (TinselV1PSX && psxRLEindex)
 		free(srcPtr);
 }
 


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