aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xengines/pegasus/movie.cpp44
-rwxr-xr-xengines/pegasus/movie.h23
-rwxr-xr-xengines/pegasus/surface.cpp114
-rwxr-xr-xengines/pegasus/surface.h6
4 files changed, 181 insertions, 6 deletions
diff --git a/engines/pegasus/movie.cpp b/engines/pegasus/movie.cpp
index fe152614d2..dbdb63fe52 100755
--- a/engines/pegasus/movie.cpp
+++ b/engines/pegasus/movie.cpp
@@ -202,4 +202,48 @@ void Movie::updateTime() {
}
}
+GlowingMovie::GlowingMovie(const tDisplayElementID id) : Movie(id) {
+ _glowing = false;
+}
+
+void GlowingMovie::draw(const Common::Rect &r) {
+ // Make sure the rectangles are clipped properly, OR guarantee that _bounds will
+ // never fall off the screen.
+ if (_glowing) {
+ Common::Rect bounds;
+ getBounds(bounds);
+
+ copyToCurrentPortTransparentGlow(_movieBox, bounds);
+ } else {
+ Movie::draw(r);
+ }
+}
+
+void GlowingMovie::setBounds(const Common::Rect &r) {
+ Common::Rect bounds;
+ getBounds(bounds);
+
+ if (r != bounds) {
+ // Avoid Movie::setBounds.
+ // clone2727 asks why, but goes along with it
+ Animation::setBounds(r);
+ }
+}
+
+ScalingMovie::ScalingMovie(const tDisplayElementID id) : GlowingMovie(id) {
+}
+
+void ScalingMovie::draw(const Common::Rect &) {
+ // Make sure the rectangles are clipped properly, OR guarantee that _bounds will
+ // never fall off the screen.
+
+ Common::Rect bounds;
+ getBounds(bounds);
+
+ if (_glowing)
+ scaleTransparentCopyGlow(_movieBox, bounds);
+ else
+ scaleTransparentCopy(_movieBox, bounds);
+}
+
} // End of namespace Pegasus
diff --git a/engines/pegasus/movie.h b/engines/pegasus/movie.h
index 704da0e92e..b248cc19d4 100755
--- a/engines/pegasus/movie.h
+++ b/engines/pegasus/movie.h
@@ -75,6 +75,29 @@ protected:
Common::Rect _movieBox;
};
+class GlowingMovie : public Movie {
+public:
+ GlowingMovie(tDisplayElementID);
+ virtual ~GlowingMovie() {}
+
+ virtual void draw(const Common::Rect &);
+
+ void setBounds(const Common::Rect &);
+
+ void setGlowing(const bool);
+
+protected:
+ bool _glowing;
+};
+
+class ScalingMovie : public GlowingMovie {
+public:
+ ScalingMovie(tDisplayElementID);
+ virtual ~ScalingMovie() {}
+
+ virtual void draw(const Common::Rect &);
+};
+
} // End of namespace Pegasus
#endif
diff --git a/engines/pegasus/surface.cpp b/engines/pegasus/surface.cpp
index 69eeb31edf..2bf989588e 100755
--- a/engines/pegasus/surface.cpp
+++ b/engines/pegasus/surface.cpp
@@ -178,10 +178,6 @@ void Surface::copyToCurrentPort(const Common::Rect &srcRect, const Common::Rect
}
void Surface::copyToCurrentPortTransparent(const Common::Rect &srcRect, const Common::Rect &dstRect) const {
- // HACK: Seems we're truncating some color data somewhere...
- uint32 transColor1 = g_system->getScreenFormat().RGBToColor(0xff, 0xff, 0xff);
- uint32 transColor2 = g_system->getScreenFormat().RGBToColor(0xf8, 0xf8, 0xf8);
-
Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getCurSurface();
byte *src = (byte *)_surface->getBasePtr(srcRect.left, srcRect.top);
byte *dst = (byte *)screen->getBasePtr(dstRect.left, dstRect.top);
@@ -192,11 +188,11 @@ void Surface::copyToCurrentPortTransparent(const Common::Rect &srcRect, const Co
for (int x = 0; x < srcRect.width(); x++) {
if (g_system->getScreenFormat().bytesPerPixel == 2) {
uint16 color = READ_UINT16(src);
- if (color != transColor1 && color != transColor2)
+ if (!isTransparent(color))
memcpy(dst, src, 2);
} else if (g_system->getScreenFormat().bytesPerPixel == 4) {
uint32 color = READ_UINT32(src);
- if (color != transColor1 && color != transColor2)
+ if (!isTransparent(color))
memcpy(dst, src, 4);
}
@@ -209,6 +205,112 @@ void Surface::copyToCurrentPortTransparent(const Common::Rect &srcRect, const Co
}
}
+void Surface::copyToCurrentPortTransparentGlow(const Common::Rect &srcRect, const Common::Rect &dstRect) const {
+ // This is the same as copyToCurrentPortTransparent(), but turns the red value of each
+ // pixel all the way up.
+
+ Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getCurSurface();
+ byte *src = (byte *)_surface->getBasePtr(srcRect.left, srcRect.top);
+ byte *dst = (byte *)screen->getBasePtr(dstRect.left, dstRect.top);
+
+ int lineSize = srcRect.width() * _surface->format.bytesPerPixel;
+
+ for (int y = 0; y < srcRect.height(); y++) {
+ for (int x = 0; x < srcRect.width(); x++) {
+ if (g_system->getScreenFormat().bytesPerPixel == 2) {
+ uint16 color = READ_UINT16(src);
+ if (!isTransparent(color))
+ WRITE_UINT16(dst, getGlowColor(color));
+ } else if (g_system->getScreenFormat().bytesPerPixel == 4) {
+ uint32 color = READ_UINT32(src);
+ if (!isTransparent(color))
+ WRITE_UINT32(dst, getGlowColor(color));
+ }
+
+ src += g_system->getScreenFormat().bytesPerPixel;
+ dst += g_system->getScreenFormat().bytesPerPixel;
+ }
+
+ src += _surface->pitch - lineSize;
+ dst += screen->pitch - lineSize;
+ }
+}
+
+void Surface::scaleTransparentCopy(const Common::Rect &srcRect, const Common::Rect &dstRect) const {
+ // I'm doing simple linear scaling here
+ // dstRect(x, y) = srcRect(x * srcW / dstW, y * srcH / dstH);
+
+ Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getCurSurface();
+
+ int srcW = srcRect.width();
+ int srcH = srcRect.height();
+ int dstW = dstRect.width();
+ int dstH = dstRect.height();
+
+ for (int y = 0; y < dstH; y++) {
+ for (int x = 0; x < dstW; x++) {
+ if (g_system->getScreenFormat().bytesPerPixel == 2) {
+ uint16 color = READ_UINT16((byte *)_surface->getBasePtr(
+ x * srcW / dstW + srcRect.left,
+ y * srcH / dstH + srcRect.top));
+ if (!isTransparent(color))
+ WRITE_UINT16((byte *)screen->getBasePtr(x + dstRect.left, y + dstRect.top), color);
+ } else if (g_system->getScreenFormat().bytesPerPixel == 4) {
+ uint32 color = READ_UINT32((byte *)_surface->getBasePtr(
+ x * srcW / dstW + srcRect.left,
+ y * srcH / dstH + srcRect.top));
+ if (!isTransparent(color))
+ WRITE_UINT32((byte *)screen->getBasePtr(x + dstRect.left, y + dstRect.top), color);
+ }
+ }
+ }
+}
+
+void Surface::scaleTransparentCopyGlow(const Common::Rect &srcRect, const Common::Rect &dstRect) const {
+ // This is the same as scaleTransparentCopy(), but turns the red value of each
+ // pixel all the way up.
+
+ Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getCurSurface();
+
+ int srcW = srcRect.width();
+ int srcH = srcRect.height();
+ int dstW = dstRect.width();
+ int dstH = dstRect.height();
+
+ for (int y = 0; y < dstH; y++) {
+ for (int x = 0; x < dstW; x++) {
+ if (g_system->getScreenFormat().bytesPerPixel == 2) {
+ uint16 color = READ_UINT16((byte *)_surface->getBasePtr(
+ x * srcW / dstW + srcRect.left,
+ y * srcH / dstH + srcRect.top));
+ if (!isTransparent(color))
+ WRITE_UINT16((byte *)screen->getBasePtr(x + dstRect.left, y + dstRect.top), getGlowColor(color));
+ } else if (g_system->getScreenFormat().bytesPerPixel == 4) {
+ uint32 color = READ_UINT32((byte *)_surface->getBasePtr(
+ x * srcW / dstW + srcRect.left,
+ y * srcH / dstH + srcRect.top));
+ if (!isTransparent(color))
+ WRITE_UINT32((byte *)screen->getBasePtr(x + dstRect.left, y + dstRect.top), getGlowColor(color));
+ }
+ }
+ }
+}
+
+uint32 Surface::getGlowColor(uint32 color) const {
+ // Can't just 'or' it on like the original did :P
+ byte r, g, b;
+ g_system->getScreenFormat().colorToRGB(color, r, g, b);
+ return g_system->getScreenFormat().RGBToColor(0xff, g, b);
+}
+
+bool Surface::isTransparent(uint32 color) const {
+ // HACK: Seems we're truncating some color data somewhere...
+ uint32 transColor1 = g_system->getScreenFormat().RGBToColor(0xff, 0xff, 0xff);
+ uint32 transColor2 = g_system->getScreenFormat().RGBToColor(0xf8, 0xf8, 0xf8);
+
+ return color == transColor1 || color == transColor2;
+}
+
PixelImage::PixelImage() {
_transparent = false;
}
diff --git a/engines/pegasus/surface.h b/engines/pegasus/surface.h
index c94ccdf0fc..9270de0665 100755
--- a/engines/pegasus/surface.h
+++ b/engines/pegasus/surface.h
@@ -70,6 +70,9 @@ public:
void copyToCurrentPortTransparent(const Common::Rect &) const;
void copyToCurrentPort(const Common::Rect &, const Common::Rect &) const;
void copyToCurrentPortTransparent(const Common::Rect &, const Common::Rect &) const;
+ void copyToCurrentPortTransparentGlow(const Common::Rect &, const Common::Rect &) const;
+ void scaleTransparentCopy(const Common::Rect &, const Common::Rect &) const;
+ void scaleTransparentCopyGlow(const Common::Rect &, const Common::Rect &) const;
virtual void getImageFromPICTFile(const Common::String &fileName);
virtual void getImageFromPICTResource(Common::MacResManager *resFork, uint16 id);
@@ -82,6 +85,9 @@ protected:
private:
void getImageFromPICTStream(Common::SeekableReadStream *stream);
+
+ uint32 getGlowColor(uint32 color) const;
+ bool isTransparent(uint32 color) const;
};
class PixelImage : public Surface {