From eba025f48f99b1538ebbf71ca5b815e76083b78f Mon Sep 17 00:00:00 2001 From: Fabio Battaglia Date: Sun, 24 May 2009 22:10:12 +0000 Subject: tinsel: fix for CLUT palettes in Discworld PSX svn-id: r40873 --- engines/tinsel/graphics.cpp | 13 +++++++---- engines/tinsel/palette.cpp | 57 ++++++++++++++++++++------------------------- engines/tinsel/palette.h | 6 ++++- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp index 26c912a24a..58cfe8f598 100644 --- a/engines/tinsel/graphics.cpp +++ b/engines/tinsel/graphics.cpp @@ -214,9 +214,8 @@ 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 PsxDrawTiles(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool applyClipping, bool fourBitClut, uint32 psxSkipBytes, uint32 palStart, bool transparency) { +static void PsxDrawTiles(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool applyClipping, bool fourBitClut, uint32 psxSkipBytes, byte *psxMapperTable, bool transparency) { // Set up the offset between destination blocks int rightClip = applyClipping ? pObj->rightClip : 0; Common::Rect boxBounds; @@ -300,7 +299,7 @@ static void PsxDrawTiles(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool apply // Extract pixel value from byte byte pixValue = (*(p + (xp / 2)) & (xp % 2 ? 0xf0 : 0x0f)) >> (xp % 2 ? 4 : 0); if (pixValue || !transparency) - *(tempDest + SCREEN_WIDTH * (yp - boxBounds.top) + (xp - boxBounds.left)) = pixValue; + *(tempDest + SCREEN_WIDTH * (yp - boxBounds.top) + (xp - boxBounds.left)) = psxMapperTable[pixValue]; } } } @@ -723,6 +722,7 @@ void UpdateScreenRect(const Common::Rect &pClip) { void DrawObject(DRAWOBJECT *pObj) { uint8 *srcPtr = NULL; uint8 *destPtr; + byte psxMapperTable[16]; 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 @@ -769,6 +769,9 @@ void DrawObject(DRAWOBJECT *pObj) { } break; case 0x44: // PSX 4-bit CLUT + memset(psxMapperTable, 0, 16); + psxPaletteMapper(pObj->pPal, (uint16*)(srcPtr + sizeof(uint16)), psxMapperTable); + psxFourBitClut = true; psxSkipBytes = READ_LE_UINT32(p + sizeof(uint32) * 5) << 4; // Fetch number of bytes we have to skip switch (indexType) { @@ -854,11 +857,11 @@ void DrawObject(DRAWOBJECT *pObj) { switch (typeId) { case 0x01: case 0x41: - PsxDrawTiles(pObj, srcPtr, destPtr, typeId >= 0x40, psxFourBitClut, psxSkipBytes, pObj->pPal->posInDAC, true); + PsxDrawTiles(pObj, srcPtr, destPtr, typeId >= 0x40, psxFourBitClut, psxSkipBytes, psxMapperTable, true); break; case 0x08: case 0x48: - PsxDrawTiles(pObj, srcPtr, destPtr, typeId >= 0x40, psxFourBitClut, psxSkipBytes, pObj->pPal->posInDAC, false); + PsxDrawTiles(pObj, srcPtr, destPtr, typeId >= 0x40, psxFourBitClut, psxSkipBytes, psxMapperTable, false); break; case 0x84: case 0xC4: diff --git a/engines/tinsel/palette.cpp b/engines/tinsel/palette.cpp index 438624b68c..1c5c69252a 100644 --- a/engines/tinsel/palette.cpp +++ b/engines/tinsel/palette.cpp @@ -92,40 +92,33 @@ static int maxDACQ = 0; #endif /** - * Convert Discworld PSX 555 CLUTs to compatible 888 palette + * Map PSX palettes to original palette from resource file */ -COLORREF* psxClutToRGBPal(uint8 *srcClut, int *colours) { - uint8 red, green, blue; - uint16 clutEntry; - int coloursInPalette = 0; - - // Allocate space for the 16 colour destination palette - COLORREF *dstPal = (COLORREF*)calloc(sizeof(COLORREF), 16); - memset(dstPal, 0, 16 * sizeof(COLORREF)); - - for (int idx = 0; idx < 16; idx++) { - clutEntry = READ_LE_UINT16(srcClut); // Read PSX CLUT entry - srcClut += sizeof(uint16); - - if ((clutEntry == 0) && (coloursInPalette == 0)) - continue; - else if ((clutEntry == 0) && (coloursInPalette != 0)) { - *colours = coloursInPalette; - return dstPal; - } else - coloursInPalette++; - - // Extract color data - red = ((clutEntry & 0x1F) * 255) / 31; - green = (((clutEntry & 0x3E0) >> 5) * 255) / 31; - blue = (((clutEntry & 0x7C00) >> 10) * 255) / 31; - - // Write the palette - dstPal[idx] = TINSEL_RGB(red, green, blue); +void psxPaletteMapper(PALQ *originalPal, uint16 *psxClut, byte *mapperTable) { + PALETTE *pal = (PALETTE *)LockMem(originalPal->hPal); + bool colorFound = false; + + for (int j = 0; j < 16; j++) { + if(!(psxClut[j] & 0x8000)) { + for (int i = 0; (i < pal->numColours) && !colorFound; i++) { + // get R G B values in the same way as psx format converters + uint16 psxEquivalent = (uint16)((uint32)(PSXGetRValue(pal->palRGB[i]) >> 3) | + ((PSXGetGValue(pal->palRGB[i]) >> 3) << 5) | + ((PSXGetBValue(pal->palRGB[i]) >> 3) << 10)); + + if (psxEquivalent == psxClut[j]) { + mapperTable[j] = i + 1; + colorFound = true; + } + } + // FIXME: This is just to hack around a bug that causes some text to appear + // black, i still have to find the correct fix for this. + if(psxClut[j] == 0x7EC0 && !colorFound) mapperTable[j] = 197; + colorFound = false; + } else { + mapperTable[j] = 0; + } } - - *colours = coloursInPalette; - return dstPal; } /** diff --git a/engines/tinsel/palette.h b/engines/tinsel/palette.h index ff5ff13f2a..7a74424ba9 100644 --- a/engines/tinsel/palette.h +++ b/engines/tinsel/palette.h @@ -39,6 +39,10 @@ typedef uint32 COLORREF; #define TINSEL_GetGValue(rgb) ((uint8)(((uint16)(FROM_LE_32(rgb))) >> 8)) #define TINSEL_GetBValue(rgb) ((uint8)((FROM_LE_32(rgb))>>16)) +#define PSXGetRValue(rgb) (FROM_LE_32(rgb) & 0x000000f8) +#define PSXGetGValue(rgb) (FROM_LE_32((rgb) >> 8) & 0x000000f8) +#define PSXGetBValue(rgb) (FROM_LE_32((rgb) >> 16) & 0x000000f8) + enum { MAX_COLOURS = 256, //!< maximum number of colours - for VGA 256 BITS_PER_PIXEL = 8, //!< number of bits per pixel for VGA 256 @@ -107,7 +111,7 @@ void ResetPalAllocator(void); // wipe out all palettes void PaletteStats(void); // Shows the maximum number of palettes used at once #endif -COLORREF* psxClutToRGBPal(uint8 *srcClut); // Convert Discworld PSX 555 CLUTs to compatible 888 palette +void psxPaletteMapper(PALQ *originalPal, uint16 *psxClut, byte *mapperTable); // Maps PSX CLUTs to original palette in resource file void PalettesToVideoDAC(void); // Update the video DAC with palettes currently the the DAC queue -- cgit v1.2.3