DIRECTOR: Remove all palette reversing workarounds

All of the builtin palette lookup tables have been reversed, to match
the original layout of the tables in the Director 4 projector executable.
This corresponds with the colour indexing used in Lingo.
Likewise, the code to load palettes from the cast no longer reads the
colours in reverse order, and shiftPalette no longer expects
the start index to be after the end index.

DirectorEngine::transformColor still exists to upgrade to 32-bit colour,
but no longer reverses the palette index.

The missing builtin 16-color palettes from Director 4 have been added.
This commit is contained in:
Scott Percival
2022-12-31 12:40:18 +08:00
committed by Eugene Sandulenko
parent 97a6076168
commit 48740a2ad1
9 changed files with 639 additions and 569 deletions
+9 -9
View File
@@ -866,8 +866,8 @@ Common::String Cast::getVideoPath(int castId) {
PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream) {
uint16 steps = stream.size() / 6;
uint16 index = (steps * 3) - 1;
byte *_palette = new byte[index + 1];
uint16 index = 0;
byte *_palette = new byte[steps * 3];
debugC(3, kDebugLoading, "Cast::loadPalette(): %d steps, %d bytes", steps, (int)stream.size());
@@ -877,15 +877,15 @@ PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream) {
}
for (int i = 0; i < steps; i++) {
_palette[index - 2] = stream.readByte();
stream.readByte();
_palette[index - 1] = stream.readByte();
stream.readByte();
_palette[index] = stream.readByte();
stream.readByte();
index -= 3;
_palette[index + 1] = stream.readByte();
stream.readByte();
_palette[index + 2] = stream.readByte();
stream.readByte();
index += 3;
}
return PaletteV4(0, _palette, steps);
+2 -2
View File
@@ -387,13 +387,13 @@ Graphics::Surface *BitmapCastMember::getMatte(Common::Rect &bbox) {
Common::String BitmapCastMember::formatInfo() {
return Common::String::format(
"initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d",
"initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d, palette: %d",
_initialRect.width(), _initialRect.height(),
_initialRect.left, _initialRect.top,
_boundingRect.width(), _boundingRect.height(),
_boundingRect.left, _boundingRect.top,
getForeColor(), getBackColor(),
_regX, _regY, _pitch, _bitsPerPixel
_regX, _regY, _pitch, _bitsPerPixel, _clut
);
}
+2 -2
View File
@@ -107,8 +107,8 @@ Channel::~Channel() {
DirectorPlotData Channel::getPlotData() {
DirectorPlotData pd(g_director, _sprite->_spriteType, _sprite->_ink, _sprite->_blend, _sprite->getBackColor(), _sprite->getForeColor());
pd.colorWhite = 255;
pd.colorBlack = 0;
pd.colorWhite = 0;
pd.colorBlack = 255;
pd.dst = nullptr;
pd.srf = getSurface();
+1 -1
View File
@@ -106,7 +106,7 @@ void Cursor::readFromCast(Datum cursorCasts) {
if (!cursor) {
*dst = 3;
} else {
*dst = *mask ? 3 : (*cursor ? 1 : 0);
*dst = *mask ? (*cursor ? 0 : 1) : 3;
cursor++;
mask++;
}
File diff suppressed because it is too large Load Diff
+22 -27
View File
@@ -35,15 +35,11 @@ namespace Director {
#include "director/graphics-data.h"
/**
* The sprites colors are in reverse order with respect to the ids in director.
* The palette is in reverse order, this eases the code for loading files.
* All other color ids can be converted with: 255 - colorId.
* Used to upgrade to 32-bit color if required.
**/
uint32 DirectorEngine::transformColor(uint32 color) {
if (_pixelformat.bytesPerPixel == 1)
return 255 - color;
color = 255 - color;
return color;
return _wm->findBestColor(_currentPalette[color * 3], _currentPalette[color * 3 + 1], _currentPalette[color * 3 + 2]);
}
@@ -171,24 +167,23 @@ void DirectorEngine::shiftPalette(int startIndex, int endIndex, bool reverse) {
if (startIndex == endIndex)
return;
if (endIndex > startIndex)
if (startIndex > endIndex)
return;
// Palette indexes are in reverse order thanks to transformColor
byte temp[3] = { 0, 0, 0 };
int span = startIndex - endIndex + 1;
int span = endIndex - startIndex + 1;
if (reverse) {
memcpy(temp, _currentPalette + 3 * endIndex, 3);
memmove(_currentPalette + 3 * endIndex,
_currentPalette + 3 * endIndex + 3,
(span - 1) * 3);
memcpy(_currentPalette + 3 * startIndex, temp, 3);
} else {
memcpy(temp, _currentPalette + 3 * startIndex, 3);
memmove(_currentPalette + 3 * endIndex + 3,
_currentPalette + 3 * endIndex,
memmove(_currentPalette + 3 * startIndex,
_currentPalette + 3 * startIndex + 3,
(span - 1) * 3);
memcpy(_currentPalette + 3 * endIndex, temp, 3);
} else {
memcpy(temp, _currentPalette + 3 * endIndex, 3);
memmove(_currentPalette + 3 * startIndex + 3,
_currentPalette + 3 * startIndex,
(span - 1) * 3);
memcpy(_currentPalette + 3 * startIndex, temp, 3);
}
// Pass the palette to OSystem only for 8bpp mode
@@ -303,7 +298,7 @@ void inkDrawPixel(int x, int y, int src, void *data) {
case kInkTypeCopy: {
if (p->applyColor) {
if (sizeof(T) == 1) {
*dst = src == 0x00 ? p->foreColor : (src == 0xff ? p->backColor : *dst);
*dst = src == 0xff ? p->foreColor : (src == 0x00 ? p->backColor : *dst);
} else {
// TODO: Improve the efficiency of this composition
byte rSrc, gSrc, bSrc;
@@ -328,7 +323,7 @@ void inkDrawPixel(int x, int y, int src, void *data) {
case kInkTypeNotCopy:
if (p->applyColor) {
if (sizeof(T) == 1) {
*dst = src == 0x00 ? p->backColor : (src == 0xff ? p->foreColor : src);
*dst = src == 0xff ? p->backColor : (src == 0x00 ? p->foreColor : src);
} else {
// TODO: Improve the efficiency of this composition
byte rSrc, gSrc, bSrc;
@@ -350,22 +345,22 @@ void inkDrawPixel(int x, int y, int src, void *data) {
}
break;
case kInkTypeTransparent:
*dst = p->applyColor ? (~src & p->foreColor) | (*dst & src) : (*dst & src);
break;
case kInkTypeNotTrans:
*dst = p->applyColor ? (src & p->foreColor) | (*dst & ~src) : (*dst & ~src);
break;
case kInkTypeReverse:
*dst ^= ~(src);
case kInkTypeNotTrans:
*dst = p->applyColor ? (~src & p->foreColor) | (*dst & src) : (*dst & src);
break;
case kInkTypeNotReverse:
case kInkTypeReverse:
*dst ^= src;
break;
case kInkTypeNotReverse:
*dst ^= ~(src);
break;
case kInkTypeGhost:
*dst = p->applyColor ? (src | p->backColor) & (*dst | ~src) : (*dst | ~src);
*dst = p->applyColor ? (~src | p->backColor) & (*dst | src) : *dst | src;
break;
case kInkTypeNotGhost:
*dst = p->applyColor ? (~src | p->backColor) & (*dst | src) : *dst | src;
*dst = p->applyColor ? (src | p->backColor) & (*dst | ~src) : (*dst | ~src);
break;
// Arithmetic ink types
default: {
+19 -10
View File
@@ -52,20 +52,20 @@ void DIBDecoder::destroy() {
void DIBDecoder::loadPalette(Common::SeekableReadStream &stream) {
uint16 steps = stream.size() / 6;
uint16 index = (steps * 3) - 1;
uint16 index = 0;
_paletteColorCount = steps;
_palette = new byte[index + 1];
_palette = new byte[steps * 3];
for (uint8 i = 0; i < steps; i++) {
_palette[index - 2] = stream.readByte();
stream.readByte();
_palette[index - 1] = stream.readByte();
stream.readByte();
_palette[index] = stream.readByte();
stream.readByte();
index -= 3;
_palette[index + 1] = stream.readByte();
stream.readByte();
_palette[index + 2] = stream.readByte();
stream.readByte();
index += 3;
}
}
@@ -99,6 +99,15 @@ bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
_surface = _codec->decodeFrame(subStream);
// For some reason, DIB cast members have the palette indexes reversed
if (bitsPerPixel == 8) {
for (int y = 0; y < _surface->h; y++) {
for (int x = 0; x < _surface->w; x++) {
*(byte *)_surface->getBasePtr(x, y) = 255 - *(byte *)_surface->getBasePtr(x, y);
}
}
}
return true;
}
@@ -243,7 +252,7 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
switch (_bitsPerPixel) {
case 1:
for (int c = 0; c < 8 && x < _surface->w; c++, x++) {
color = (pixels[(((y * _pitch) + x) / 8)] & (1 << (7 - c))) ? 0 : 0xff;
color = (pixels[(((y * _pitch) + x) / 8)] & (1 << (7 - c))) ? 0xff : 0x00;
if (paletted) {
*((byte *)_surface->getBasePtr(x, y)) = color;
} else {
+4 -4
View File
@@ -20,7 +20,7 @@
*/
static byte whitePalette[768] = {
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0 (0x00)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0 (0x00)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 4 (0x04)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 8 (0x08)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 12 (0x0c)
@@ -83,11 +83,11 @@ static byte whitePalette[768] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 240 (0xf0)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 244 (0xf4)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 248 (0xf8)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // 252 (0xfc)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 // 252 (0xfc)
};
static byte blackPalette[768] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 (0x00)
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 (0x00)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4 (0x04)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 (0x08)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12 (0x0c)
@@ -150,7 +150,7 @@ static byte blackPalette[768] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 240 (0xf0)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 244 (0xf4)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 248 (0xf8)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff // 252 (0xfc)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 252 (0xfc)
};
// TODO: Timing here is measured empirically from DOSBox,
+1 -2
View File
@@ -737,7 +737,6 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
return;
// 30 (the maximum) is actually unbounded
int delay = speed == 30 ? 10 : 1000 / speed;
// Palette indexes are in reverse order thanks to transformColor
if (_frames[frameId]->_palette.colorCycling) {
// Cycle the colors of a chosen palette
int firstColor = _frames[frameId]->_palette.firstColor;
@@ -753,7 +752,7 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
g_director->draw();
} else {
// Do a full color cycle in one frame transition
int steps = firstColor - lastColor + 1;
int steps = lastColor - firstColor + 1;
for (int i = 0; i < _frames[frameId]->_palette.cycleCount; i++) {
for (int j = 0; j < steps; j++) {
g_director->shiftPalette(firstColor, lastColor, false);