[Scummvm-git-logs] scummvm master -> 40501547f42b6202a15582d974d88776d759aacb
stevenhoefel
stevenhoefel at hotmail.com
Fri Apr 10 12:38:28 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
40501547f4 DIRECTOR: Extend Reverse Sprite drawing for shapes and controls.
Commit: 40501547f42b6202a15582d974d88776d759aacb
https://github.com/scummvm/scummvm/commit/40501547f42b6202a15582d974d88776d759aacb
Author: stevenhoefel (stevenhoefel at hotmail.com)
Date: 2020-04-10T22:38:12+10:00
Commit Message:
DIRECTOR: Extend Reverse Sprite drawing for shapes and controls.
Translate 32-bit images into palette-based sprites.
Changed paths:
engines/director/frame.cpp
engines/director/frame.h
engines/director/images.cpp
engines/director/images.h
engines/director/score.cpp
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 02397797c5..145e24805d 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -650,7 +650,7 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
int width = _vm->getVersion() > 4 ? bc->_initialRect.width() : _sprites[i]->_width;
Common::Rect drawRect(x, y, x + width, y + height);
addDrawRect(i, drawRect);
- inkBasedBlit(surface, *(bc->_surface), ink, drawRect);
+ inkBasedBlit(surface, *(bc->_surface), ink, drawRect, i);
}
}
}
@@ -671,9 +671,7 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
byte backColor = sp->_backColor;
int lineSize = sp->_thickness & 0x3;
- // D3 Shared Cast Members don't have these values specified, they're provided when you add
- // them to the score in each movie.
- if (_vm->getVersion() > 3 && spriteType == kCastMemberSprite) {
+ if (_vm->getVersion() >= 3 && spriteType == kCastMemberSprite) {
if (!sp->_cast) {
warning("Frame::renderShape(): kCastMemberSprite has no cast defined");
return;
@@ -698,10 +696,12 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
default:
break;
}
- foreColor = sc->_fgCol;
- backColor = sc->_bgCol;
- lineSize = sc->_lineThickness;
- ink = sc->_ink;
+ if (_vm->getVersion() > 3) {
+ foreColor = sc->_fgCol;
+ backColor = sc->_bgCol;
+ lineSize = sc->_lineThickness;
+ ink = sc->_ink;
+ }
// shapes should be rendered with transparency by default
if (ink == kInkTypeCopy) {
ink = kInkTypeTransparent;
@@ -778,7 +778,7 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
}
addDrawRect(spriteId, shapeRect);
- inkBasedBlit(surface, tmpSurface, ink, shapeRect);
+ inkBasedBlit(surface, tmpSurface, ink, shapeRect, spriteId);
}
@@ -1025,10 +1025,10 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteId, Commo
if (spriteId == _vm->getCurrentScore()->_currentMouseDownSpriteId)
ink = kInkTypeReverse;
- inkBasedBlit(surface, textWithFeatures, ink, Common::Rect(x, y, x + width, y + height));
+ inkBasedBlit(surface, textWithFeatures, ink, Common::Rect(x, y, x + width, y + height), spriteId);
}
-void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect) {
+void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect, uint spriteId) {
// drawRect could be bigger than the spriteSurface. Clip it
Common::Rect t(spriteSurface.w, spriteSurface.h);
t.moveTo(drawRect.left, drawRect.top);
@@ -1052,7 +1052,7 @@ void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics
drawGhostSprite(targetSurface, spriteSurface, drawRect);
break;
case kInkTypeReverse:
- drawReverseSprite(targetSurface, spriteSurface, drawRect);
+ drawReverseSprite(targetSurface, spriteSurface, drawRect, spriteId);
break;
default:
warning("Frame::inkBasedBlit(): Unhandled ink type %d", ink);
@@ -1103,7 +1103,7 @@ void Frame::drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Su
}
}
-void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) {
+void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect, uint16 spriteId) {
Common::Rect srcRect(sprite.w, sprite.h);
if (!target.clip(srcRect, drawRect))
@@ -1113,14 +1113,37 @@ void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::
for (int ii = 0; ii < srcRect.height(); ii++) {
const byte *src = (const byte *)sprite.getBasePtr(srcRect.left, srcRect.top + ii);
byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii);
+ byte srcColor = *src;
for (int j = 0; j < srcRect.width(); j++) {
- if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0)) {
- if (*src != skipColor) {
- *dst ^= _vm->transformColor(*src);
+ if (_sprites[spriteId]->_cast->_type == kCastShape)
+ srcColor = 0x0;
+ else
+ srcColor = *src;
+ uint16 targetSprite = getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii));
+ if ((targetSprite != 0)) {
+ // TODO: This entire reverse colour attempt needs a lot more testing on
+ // a lot more colour depths.
+ if (srcColor != skipColor) {
+ if (_sprites[targetSprite]->_cast->_type != kCastBitmap) {
+ if (*dst == 0 || *dst == 255) {
+ *dst = _vm->transformColor(*dst);
+ } else if (srcColor == 255 || srcColor == 0) {
+ *dst = _vm->transformColor(*dst - 40);
+ } else {
+ *dst = _vm->transformColor(*src - 40);
+ }
+ } else {
+ if (*dst == 0 && _vm->getVersion() == 3 &&
+ ((BitmapCast*)_sprites[spriteId]->_cast)->_bitsPerPixel > 1) {
+ *dst = _vm->transformColor(*src - 40);
+ } else {
+ *dst ^= _vm->transformColor(srcColor);
+ }
+ }
}
- } else if (*src != skipColor) {
- *dst = *src;
+ } else if (srcColor != skipColor) {
+ *dst = _vm->transformColor(srcColor);
}
src++;
dst++;
diff --git a/engines/director/frame.h b/engines/director/frame.h
index fb9cdd253d..1205daef5d 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -94,8 +94,8 @@ private:
void drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
void drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
void drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
- void drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
- void inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect);
+ void drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect, uint16 spriteId);
+ void inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect, uint spriteId);
void addDrawRect(uint16 entityId, Common::Rect &rect);
public:
diff --git a/engines/director/images.cpp b/engines/director/images.cpp
index 7e65d3aa2c..129f393790 100644
--- a/engines/director/images.cpp
+++ b/engines/director/images.cpp
@@ -103,7 +103,7 @@ bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
* BITD
****************************/
-BITDDecoder::BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch) {
+BITDDecoder::BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch, const byte *palette) {
_surface = new Graphics::Surface();
if (pitch < w) {
@@ -133,12 +133,10 @@ BITDDecoder::BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch) {
_surface->create(pitch, h, pf);
_surface->w = w;
- _palette = new byte[256 * 3];
+ _palette = palette;
- _palette[0] = _palette[1] = _palette[2] = 0;
- _palette[255 * 3 + 0] = _palette[255 * 3 + 1] = _palette[255 * 3 + 2] = 0xff;
-
- _paletteColorCount = 2;
+ // TODO: Bring this in from the main surface?
+ _paletteColorCount = 255;
_bitsPerPixel = bitsPerPixel;
}
@@ -152,8 +150,6 @@ void BITDDecoder::destroy() {
delete _surface;
_surface = 0;
- delete[] _palette;
- _palette = 0;
_paletteColorCount = 0;
}
@@ -161,6 +157,42 @@ void BITDDecoder::loadPalette(Common::SeekableReadStream &stream) {
// no op
}
+void BITDDecoder::convertPixelIntoSurface(void* surfacePointer, uint fromBpp, uint toBpp, int red, int green, int blue) {
+ // Initial implementation of 32-bit images to palettised sprites.
+ switch (fromBpp) {
+ case 4:
+ switch (toBpp) {
+ case 1:
+ if (red == 255 && blue == 255 && green == 255) {
+ *((byte*)surfacePointer) = 255;
+ } else if (red == 0 && blue == 0 && green == 0) {
+ *((byte*)surfacePointer) = 0;
+ } else {
+ for (byte p = 0; p < _paletteColorCount; p++)
+ {
+ if (_palette[p * 3 + 0] == red &&
+ _palette[p * 3 + 1] == green &&
+ _palette[p * 3 + 2] == blue)
+ {
+ *((byte*)surfacePointer) = p;
+ }
+ }
+ }
+ break;
+
+ default:
+ warning("BITDDecoder::convertPixelIntoSurface(): conversion from %d to %d not implemented",
+ fromBpp, toBpp);
+ }
+ break;
+
+ default:
+ warning("BITDDecoder::convertPixelIntoSurface(): could not convert from %d to %d",
+ fromBpp, toBpp);
+ break;
+ }
+}
+
bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
int x = 0, y = 0;
@@ -180,26 +212,30 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
}
Common::Array<int> pixels;
-
while (!stream.eos()) {
- int data = stream.readByte();
- int len = data + 1;
- if ((data & 0x80) != 0) {
- len = ((data ^ 0xFF) & 0xff) + 2;
- data = stream.readByte();
- for (int p = 0; p < len; p++) {
- pixels.push_back(data);
- //*((byte *)_surface->getBasePtr(x, y)) = data;
- }
- //data = stream.readByte();
+ // TODO: D3 32-bit bitmap casts seem to just be ARGB pixels in a row and not RLE.
+ // Determine how to distinguish these different types. Maybe stage version.
+ if (_bitsPerPixel == 32) {
+ int data = stream.readByte();
+ pixels.push_back(data);
} else {
- for (int p = 0; p < len; p++) {
+ int data = stream.readByte();
+ int len = data + 1;
+ if ((data & 0x80) != 0) {
+ len = ((data ^ 0xFF) & 0xff) + 2;
data = stream.readByte();
- pixels.push_back(data);
+ for (int p = 0; p < len; p++) {
+ pixels.push_back(data);
+ }
+ } else {
+ for (int p = 0; p < len; p++) {
+ data = stream.readByte();
+ pixels.push_back(data);
+ }
}
+ if (_bitsPerPixel == 32 && pixels.size() % (_surface->w * 3) == 0)
+ stream.readUint16BE();
}
- if (_bitsPerPixel == 32 && pixels.size() % (_surface->w * 3) == 0)
- stream.readUint16BE();
}
if (pixels.size() < (uint32)_surface->w * _surface->h) {
@@ -220,12 +256,11 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
for (y = 0; y < _surface->h; y++) {
for (x = 0; x < _surface->w;) {
switch (_bitsPerPixel) {
- case 1: {
+ case 1:
for (int c = 0; c < 8 && x < _surface->w; c++, x++) {
*((byte *)_surface->getBasePtr(x, y)) = (pixels[(((y * _surface->pitch) + x) / 8)] & (1 << (7 - c))) ? 0 : 0xff;
}
break;
- }
case 8:
// this calculation is wrong.. need a demo with colours.
@@ -243,10 +278,12 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
break;
case 32:
- *((uint32*)_surface->getBasePtr(x, y)) = _surface->format.RGBToColor(
- pixels[((y * _surface->w) * 3) + x],
- pixels[(((y * _surface->w) * 3) + (_surface->w)) + x],
- pixels[(((y * _surface->w) * 3) + (2 * _surface->w)) + x]);
+ convertPixelIntoSurface(_surface->getBasePtr(x, y),
+ (_bitsPerPixel / 8),
+ _surface->format.bytesPerPixel,
+ pixels[(((y * (_surface->w * 4))) + ((x * 4) + 1))],
+ pixels[(((y * (_surface->w * 4))) + ((x * 4) + 2))],
+ pixels[(((y * (_surface->w * 4))) + ((x * 4) + 3))]);
x++;
break;
diff --git a/engines/director/images.h b/engines/director/images.h
index c87796f6a0..8a6c5e7f7a 100644
--- a/engines/director/images.h
+++ b/engines/director/images.h
@@ -61,7 +61,7 @@ private:
class BITDDecoder : public Image::ImageDecoder {
public:
- BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch);
+ BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch, const byte *palette);
~BITDDecoder() override;
// ImageDecoder API
@@ -71,10 +71,11 @@ public:
const byte *getPalette() const override { return _palette; }
void loadPalette(Common::SeekableReadStream &stream);
uint16 getPaletteColorCount() const override { return _paletteColorCount; }
+ void convertPixelIntoSurface(void* surfacePointer, uint fromBpp, uint toBpp, int red, int green, int blue);
private:
Graphics::Surface *_surface;
- byte *_palette;
+ const byte *_palette;
uint8 _paletteColorCount;
uint16 _bitsPerPixel;
};
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a0df293bb5..09ff870567 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -376,7 +376,7 @@ void Score::loadSpriteImages(bool isSharedCast) {
if (w > 0 && h > 0) {
if (_vm->getVersion() < 6) {
- img = new BITDDecoder(w, h, bitmapCast->_bitsPerPixel, bitmapCast->_pitch);
+ img = new BITDDecoder(w, h, bitmapCast->_bitsPerPixel, bitmapCast->_pitch, _vm->getPalette());
} else {
img = new Image::BitmapDecoder();
}
More information about the Scummvm-git-logs
mailing list