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

svn-id: r40606
This commit is contained in:
Fabio Battaglia 2009-05-15 12:46:53 +00:00
parent 78bf8c490d
commit 3771f9aef2

View File

@ -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 @@ extern uint8 transPalette[MAX_COLOURS];
/**
* 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 @@ uint8* psxBlockListUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx
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 @@ static void t0WrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool apply
* 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 @@ static void PsxWrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool appl
// 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 @@ void DrawObject(DRAWOBJECT *pObj) {
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 @@ void DrawObject(DRAWOBJECT *pObj) {
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 @@ void DrawObject(DRAWOBJECT *pObj) {
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 @@ void DrawObject(DRAWOBJECT *pObj) {
// If we were using Discworld PSX, free the memory allocated
// for decompressed block indexes.
if (TinselV1PSX)
if (TinselV1PSX && psxRLEindex)
free(srcPtr);
}