mirror of
https://github.com/scummvm/scummvm.git
synced 2026-05-21 05:40:43 +00:00
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:
committed by
Eugene Sandulenko
parent
97a6076168
commit
48740a2ad1
@@ -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);
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
+579
-512
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user