aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Battaglia2009-05-24 22:10:12 +0000
committerFabio Battaglia2009-05-24 22:10:12 +0000
commiteba025f48f99b1538ebbf71ca5b815e76083b78f (patch)
treec0f11ff5fd2ee8feea5dfe790f02a238d1d205ee
parentc97a1aed74fc54176e0de66fc2b6bbe0767e8de6 (diff)
downloadscummvm-rg350-eba025f48f99b1538ebbf71ca5b815e76083b78f.tar.gz
scummvm-rg350-eba025f48f99b1538ebbf71ca5b815e76083b78f.tar.bz2
scummvm-rg350-eba025f48f99b1538ebbf71ca5b815e76083b78f.zip
tinsel: fix for CLUT palettes in Discworld PSX
svn-id: r40873
-rw-r--r--engines/tinsel/graphics.cpp13
-rw-r--r--engines/tinsel/palette.cpp57
-rw-r--r--engines/tinsel/palette.h6
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