TOLTECS: Implemented buildColorTransTable (still TODO) and shadow sprite drawing.

This commit is contained in:
Benjamin Haisch 2008-08-13 15:13:22 +00:00 committed by Willem Jan Palenstijn
parent 98ac7885ac
commit 5660ff5148
5 changed files with 90 additions and 14 deletions

View File

@ -166,6 +166,51 @@ void Palette::clearFragments() {
_fragments.clear();
}
void Palette::buildColorTransTable(byte limit, char deltaValue, byte mask) {
// TODO
byte r, g, b;
mask &= 7;
for (int i = 0; i < 256; i++) {
if (deltaValue < 0) {
// TODO
} else {
r = _mainPalette[i * 3 + 0];
g = _mainPalette[i * 3 + 1];
b = _mainPalette[i * 3 + 2];
if (MAX(r, MAX(b, g)) >= limit) {
if ((mask & 1) && r >= deltaValue)
r -= deltaValue;
if ((mask & 2) && g >= deltaValue)
g -= deltaValue;
if ((mask & 4) && b >= deltaValue)
b -= deltaValue;
}
}
int bestIndex = 0;
uint16 bestMatch = 0xFFFF;
for (int j = 0; j < 256; j++) {
byte distance = ABS(_mainPalette[j * 3 + 0] - r) + ABS(_mainPalette[j * 3 + 1] - g) + ABS(_mainPalette[j * 3 + 2] - b);
byte maxColor = MAX(_mainPalette[j * 3 + 0], MAX(_mainPalette[j * 3 + 1], _mainPalette[j * 3 + 2]));
uint16 match = (distance << 8) | maxColor;
if (match < bestMatch) {
bestMatch = match;
bestIndex = j;
}
}
_colorTransTable[i] = bestIndex;
}
}
void Palette::saveState(Common::WriteStream *out) {
// Save currently active palette

View File

@ -64,6 +64,9 @@ public:
uint16 findFragment(int16 id);
void clearFragments();
void buildColorTransTable(byte limit, char deltaValue, byte mask);
byte getColorTransPixel(byte pixel) const { return _colorTransTable[pixel]; }
byte *getMainPalette() { return _mainPalette; }
byte *getAnimPalette() { return _animPalette; }

View File

@ -500,6 +500,15 @@ void Screen::drawSprite(SpriteDrawItem *sprite) {
if (sprite->flags & 0x40) {
// TODO: Shadow sprites
if (sprite->flags & 1) {
SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
} else if (sprite->flags & 2) {
SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
} else {
drawSpriteCore(dest, spriteReader, sprite);
}
} else if (sprite->flags & 0x10) {
// 256 color sprite
drawSpriteCore(dest, spriteReader, sprite);
@ -556,16 +565,25 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
}
if (((sprite->flags & 0x10) && (packet.pixel != 0xFF)) || !(sprite->flags & 0x10) && (packet.pixel != 0)) {
if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
!(sprite->flags & 0x10) && (packet.pixel != 0))
{
if (sprite->flags & 0x40) {
} else if (sprite->flags & 0x10) {
packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
while (packet.count--) {
*dest = _vm->_palette->getColorTransPixel(*dest);
dest += destInc;
}
} else {
packet.pixel += sprite->baseColor - 1;
}
while (packet.count--) {
*dest = packet.pixel;
dest += destInc;
if (sprite->flags & 0x10) {
packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
} else {
packet.pixel += sprite->baseColor - 1;
}
while (packet.count--) {
*dest = packet.pixel;
dest += destInc;
}
}
} else {
dest += packet.count * destInc;
@ -799,12 +817,12 @@ void Screen::drawTalkTextItems() {
if (ch == 0x20) {
x += font.getWidth();
} else {
//drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
drawChar(font, _frontScreen, x, item->rects[j].y, ch, item->color, true);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
}
}
}
}
}
@ -892,7 +910,6 @@ void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint
if (ch <= 0x20) {
x += font.getWidth();
} else {
//drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color, false);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
yadd = -yadd;
@ -918,7 +935,6 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
byte count = charData[0] & 0x0F;
byte flags = charData[0] & 0xF0;
charData++;
lineWidth -= count;
if ((flags & 0x80) == 0) {
if (flags & 0x10) {
memset(dest, color, count);
@ -927,6 +943,7 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
}
}
dest += count;
lineWidth -= count;
}
dest += 640 - charWidth;
}

View File

@ -136,10 +136,20 @@ public:
_curHeight = _sprite->origHeight;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
if ((_sprite->flags & 0x40) || (_sprite->flags & 0x10)) {
if (_sprite->flags & 0x40) {
// shadow sprite
packet.count = _source[0] & 0x7F;
if (_source[0] & 0x80)
packet.pixel = 1;
else
packet.pixel = 0;
_source++;
} else if (_sprite->flags & 0x10) {
// 256-color sprite
packet.pixel = *_source++;
packet.count = *_source++;
} else {
// 16-color sprite
packet.count = _source[0] & 0x0F;
packet.pixel = (_source[0] & 0xF0) >> 4;
_source++;

View File

@ -556,9 +556,10 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
break;
}
case 16:// TODO
case 16:// ok
{
debug(0, "o2_makeTransColorTable");
debug(0, "o2_buildColorTransTable(%d, %d, %d)", arg8(4), (char)arg8(3), arg8(5));
_vm->_palette->buildColorTransTable(arg8(4), (char)arg8(3), arg8(5));
break;
}